Nondominium Documentation
Infrastructure for organization-agnostic, uncapturable, self-governed resources — built on Holochain and ValueFlows.
This page is the hub. Two alternate views of the same corpus: DOCUMENTATION_INDEX.md (annotated guide, with commands and per-area status) and SUMMARY.md (flat linear table of contents).
Getting Started
- TELOS - Project vision, mission, and philosophy
- Requirements - Full requirements document
- Implementation Status - Current development progress
Architecture
- Architecture Components - System design and zome interactions
- NDO v1 Architecture Design - NDO three-layer model
- Zomes Overview - Multi-DNA topology and the Person, Resource, Governance core
- Lobby Zome - Lobby DNA: agent presence and the global group registry
- Group Zome - Group DNA: cloned-cell coordination, membership, soft links, NDO anchors
- hREA Integration - ValueFlows / hREA integration strategy
Requirements
- Agent Ontology - Agent types, identity, affiliation model
- Resource Ontology - Property regimes, lifecycle, governance
- Governance Ontology - Embedded governance, PPR system, validation
- NDO Prima Materia - Normative NDO spec (REQ-NDO-*)
- UI Design - Lobby → Group → NDO navigational hierarchy
Technical Specifications
- Technical Specifications - Zome entries, functions, cross-zome API
- Governance Operator Architecture - State transition pattern
- Governance Implementation Guide - Implementation with code examples
- Cross-Zome API - Zome-to-zome call contracts
- Governance Model - Legacy governance model and decision processes
- Private Participation Receipt - PPR system design
- PPR Security Implementation - PPR security model
- ValueFlows Action Usage - VF action patterns with governance examples
- Protocol Bridge Specifications - Bun bridge for platform integration (Tiki, Odoo)
- UI Architecture - Svelte 5 service and store layer
- API Reference - Complete zome function reference
Development
- Implementation Plan - Phased delivery roadmap
- Development Report - Progress log
- Testing Infrastructure - Sweettest suite guide
- Test Commands - Canonical command reference for every suite
- E2E Test Suite - Playwright against real conductors
- UI README - Frontend dev harness and layout
Applications
- Artcoin - Open-source art economy use case
- Nondominium × Artcoin - Artcoin integration detail
- Distributed Journalism
- ERP Holochain Bridge
- HealthNet
- User Stories - Complete user journey scenarios
Post-MVP
- Unyt Integration - Economic settlement layer
- Flowsta Integration - Cross-app identity and DID
- Resource Transport Flow Protocol
- Full post-MVP set - Versioning, many-to-many flows, digital integrity, DSL
TELOS: Nondominium
Vision
A protocol for resource governance without ownership. Resources participate in Nondominium Object (NDO) lifecycles where rights and responsibilities attach to relationships, not to titles. The goal is infrastructure for commons-based economies that cannot be re-enclosed — not by platform operators, not by nation-states, and not by the project's own developers.
Mission
Build and ship the Holochain hApp and underlying protocol that demonstrates governance-embedded commons management at production scale. Integrate with hREA for ValueFlows semantics. Provide an incremental adoption path so existing organizations (Sensorica, Dolibarr/TikiWiki users, OVN-aligned cooperatives) can participate without wholesale migration.
Philosophy
- Protocol-level economic enforcement over policy-level. CAL-1.0 + AGPLv3 dual license with protocol-level constraints (no re-enclosure, no revocation of nondominium status) baked into governance rules, not documents.
- Three-layer progressive model. Prima Materia (potential, Layer 0) → Specified (designed, Layer 1) → Custodial/Process (instantiated, Layer 2). Coordination overhead matches social complexity; no pre-classification at creation.
- Private Participation Receipts (PPR) as user-sovereign reputation primitive. 16 categories, bilaterally signed, stored as Holochain private entries. No global scoring aggregator, no third-party visibility by default.
- Composability with hREA and ValueFlows, not replacement. NDO entries bridge
to hREA's
EconomicResource/Agenttypes. ValueFlows is the canonical action vocabulary. - Capability-based security via Holochain capability tokens. Access rights are cryptographically issued, field-level scoped, and expire after 30 days maximum.
- Agent-centric data model. All data tied to individual agents' source chains. No shared database. DHT is the coordination layer, not the control layer.
- Embedded governance. Resources carry their own access and transfer rules as
GovernanceRuleentries onResourceSpecification. The governance zome is a state-transition operator, not a policy server.
Operating Principles for the AI
- Prefer correctness over cleverness. This is governance infrastructure for real economic relationships. A wrong validation rule on the DHT cannot be rolled back.
- ValueFlows vocabulary is canonical. If a concept exists in VF (EconomicEvent, Commitment, Claim, VfAction), use VF terminology. Do not invent parallel ontologies.
- The NDO architecture in
documentation/requirements/ndo_prima_materia.mdis load-bearing. Changes to the three-layer model, capability slots, or lifecycle state machine ripple through governance, PPR, and UI. Flag any proposal that touches this document's scope and note the downstream impact. - PPR must remain user-sovereign. Resist any design that aggregates reputation into global scores, centralizes storage, or enables third-party visibility without explicit capability grant.
- UI work uses Svelte 5 runes, UnoCSS, and Melt UI next-gen (
melt). Not shadcn. Not Tailwind utility classes directly in templates. Not Svelte 4 reactive statements ($:). Check themcp__svelteMCP server for current Svelte 5 API. - Consult
REVIEW.mdbefore proposing PR-shaped changes. It explicitly lists patterns to flag. If your proposed code matches a flagged pattern, explain why it is safe before proceeding. - Read
CONTRIBUTING.mdfor branch model and commit conventions (feat/,fix/,refactor/,docs/,chore/prefixes; Conventional Commits scopes).
What This PAI Is NOT For
- General TypeScript or Rust questions disconnected from Nondominium architecture. Use a generic AI session for language-level questions.
- Holochain learning content not specific to this codebase. The
holochain-agent-skillcovers Holochain generally; this TELOS is for Nondominium-specific decisions. - Personal or spiritual contexts. Use a personal-level AI session.
- Speculation about post-MVP integrations (Unyt, Flowsta) without first reading their
integration docs in
documentation/requirements/post-mvp/.
Nondominium Project Documentation Index
Updated: 2026-08-13
Annotated guide to the documentation set. For the topic-grouped hub see README.md; for a flat table of contents see SUMMARY.md.
🎯 Project Overview
Nondominium is a ValueFlows-compliant Holochain application implementing distributed, agent-centric resource management with embedded governance, capability-based security, and cryptographically-secured reputation tracking through Private Participation Receipts (PPRs).
Quick Navigation
- Getting Started - Development setup & quick start
- Architecture - System design & zome interactions
- API Documentation - Complete function reference
- Testing - Test strategy & execution
- Implementation Status - Current development progress
🚀 Getting Started
Prerequisites & Setup
git submodule update --init --recursive # Initialize the hREA submodule (REQUIRED)
nix develop # Enter reproducible environment (REQUIRED)
bun install # Install dependencies
Key Documentation:
- 🎯 TELOS - Project vision, mission, philosophy, and AI operating principles
- 📋 Main README - Complete project overview & setup guide
- 🔧 Development Environment - Development patterns & commands
Essential Commands
# Development
bun run start # Start 2-agent development network with UIs
AGENTS=3 bun run network # Custom agent network
# Testing — Sweettest (Rust, primary)
bun run sweettest # build:happ + all nondominium Sweettest tests
bun run sweettest:only # skip the build step
# Testing — E2E (Playwright + real conductors)
bun run e2e
bun run e2e:ui
# Build
bun run build:zomes # Compile Rust zomes to WASM
bun run build:happ # Build zomes + hREA, pack all DNAs into the .happ bundle
bun run package # Create final .webhapp distribution
Canonical command reference for every suite: TEST_COMMANDS.md.
Note: Tryorama (TypeScript) tests in
tests/are deprecated. All new tests use Sweettest (Rust). Seetests/DEPRECATED.md.
🏗️ Architecture Overview
System Architecture
nondominium implements a Governance-as-Operator architecture that separates data management from business logic enforcement:
- Framework: Holochain HDK ^0.6.0 / HDI ^0.7.0 (Rust + WASM)
- Frontend: SvelteKit 2 + Svelte 5 + TypeScript + Vite 7
- Testing: Sweettest (Rust, primary) — Tryorama (TypeScript) deprecated
- Client: @holochain/client ^0.20.0
- Package Management: Bun for dependency management and build orchestration
Zome Structure
| Zome | Purpose | Key Features |
|---|---|---|
zome_person | Agent identity & access control | Agent profiles & roles, capability-based security, private data sharing workflows, PPR integration & reputation tracking |
zome_resource | Pure data model | EconomicResource & EconomicEvent data structures, resource state management only, cross-zome interface for governance requests, no business logic |
zome_gouvernance | State transition operator | Governance rule evaluation, state transition validation, economic event generation, PPR issuance (16 categories), agent promotion & capability progression |
zome_group | Per-group coordination (cloned cell) | Group profiles, membership, work logs, soft links; one cloned cell per group; all_groups anchor; 13 #[hdk_extern] functions |
zome_lobby | Global group registry (provisioned Lobby DHT) | LobbyAgentProfile presence, GroupAnnouncement group registry; NDO announcements were removed in PR #107 (NDOs are group-scoped) |
Governance-as-Operator Architecture
Key Design Principles:
- Modular Design: Resource zome manages data, governance zome enforces rules
- Swappable Governance: Different governance schemes can be applied to same resources
- Pure Function Governance: Stateless evaluation with deterministic outputs
- Event-Driven State Changes: All transitions generate audit events
- Cross-Zome Interface: Well-defined communication protocol
Documentation:
- Governance Operator Architecture - Technical architecture and design patterns
- Governance Implementation Guide - Detailed implementation with code examples
- Cross-Zome API - Complete API specifications
Key Concepts
- 🔐 Capability-Based Security: Progressive trust model (Simple → Accountable → Primary Accountable Agent)
- 📋 Private Participation Receipts (PPRs): Cryptographic reputation tracking across 16 categories
- 🔄 Economic Processes: Structured workflows (Use, Transport, Storage, Repair) with role-based access
- 🛡️ Private Data Sharing: Request/grant workflows with field-level control and time-limited grants (30-day maximum per
PrivateDataCapabilityMetadata; shorter defaults may apply in UI flows — see person_zome.md)
📚 Core Documentation
Project Requirements
| Document | Description | Status |
|---|---|---|
| Requirements | Complete PRD with modular governance architecture | ✅ Complete |
| NDO Prima Materia | NDO v1.0 normative requirements (REQ-NDO-*, capability slots, Unyt/Flowsta integration, three-layer model) | ✅ Active |
| Agent Ontology | Agent types, affiliation spectrum, identity model, OVN forward map | ✅ Active |
| Resources Ontology | Resource types, property regimes, governance model, OVN forward map | ✅ Active |
| Governance Ontology | Governance architecture, OVN patterns, governance equation, forward map | ✅ Active |
| UI Design | User interface design specifications (source of truth for UI conflicts) | ✅ Complete |
Architecture & Roadmap
| Document | Description | Status |
|---|---|---|
| NDO v1.0 Architecture Design | Dual-DNA architecture, VF 1.0 class mapping, entry type specs, ADRs, migration notes | ✅ Active |
| Lobby DNA Architecture | Original design: Lobby + Group DNAs, NDO extensions, entry types, coordinator APIs, Moss contract, 7 ADRs | ⚠️ Superseded in part — Lobby (#103) and Group (#107) DNAs shipped with the registry model inverted (Lobby registers groups, not NDOs); zomes/lobby_zome.md and zomes/group_zome.md are authoritative |
| hREA Integration Strategy | Cross-DNA call architecture, zome-level integration pattern, migration plan | ✅ Active |
| hREA VF 1.0 Compliance Analysis | Field-by-field audit of hREA main-0.6 against VF 1.0 ontology (~65% compliance) | ✅ Active |
| hREA Strategic Roadmap | Phase 1+2 maintainership proposal: VF 1.0 gap closure and JSON-LD API | ✅ Active |
Technical Specifications
| Document | Description | Status |
|---|---|---|
| Technical Specifications | Detailed data structures, zome functions, cross-zome interfaces | ✅ Complete |
| ADR-010…013 — Per-NDO cells | One cloned cell per NDO, group NdoAnchor discovery, DnaHash bound to Layer 0 via DNA properties | ✅ Active |
| Architecture Overview | Comprehensive system architecture & cross-zome integration | ✅ Complete |
| Governance Operator Architecture | Technical architecture for modular governance design | ✅ Complete |
| Governance Implementation Guide | Detailed implementation guide with code examples | ✅ Complete |
| Cross-Zome API | Complete API specifications for zome communication | ✅ Complete |
| PPR Security Implementation | Security model for reputation system | ✅ Complete |
| Private Participation Receipts | PPR system full specification | ✅ Complete |
| Governance Model (Legacy) | Legacy governance model and decision-making processes | 📦 Reference |
| UI Architecture | Frontend design patterns & component structure | ✅ Complete |
| ValueFlows Action Usage | ValueFlows implementation with governance examples | ✅ Complete |
| Protocol Bridge Specifications | Bun Protocol Bridge architecture for platform integration (Tiki, Odoo) | ✅ Complete |
| API Reference | Complete function reference across all zomes | ✅ Complete |
| Implementation Plan | Development roadmap & phase breakdown | ✅ Complete |
| Implementation Status | Current development progress & completion status | ✅ Current |
Post-MVP Requirements
| Document | Description | Status |
|---|---|---|
| Lobby DNA Requirements | Multi-network federation: Lobby DNA, Group DNA, NDO extensions (REQ-LOBBY-, REQ-GROUP-, REQ-NDO-EXT-*) | ✅ Lobby + Group DNAs shipped (#103, #107); NDO-level extensions in progress (#112) |
| Unyt Integration | Economic settlement, Smart Agreements, RAVE proofs, PPR↔RAVE provenance | 🔄 Post-MVP |
| Flowsta Integration | Cross-app identity (IsSamePersonEntry, FlowstaIdentity, DID, key recovery) | 🔄 Post-MVP |
| NDO Versioning | DAG-based version graph, fork/merge/repair relations, contribution propagation | 🔄 Post-MVP |
| Digital Resource Integrity | Cryptographic integrity verification, Merkle tree, composable architecture | 🔄 Post-MVP |
| Many-to-Many Flows | Multi-custodian custody, shared ownership, resource pools | 🔄 Post-MVP |
| Resource Transport Flow Protocol | Resource transport specifications | 🔄 Post-MVP |
| ValueFlows DSL | Domain-specific language for governance rule authoring | 🔄 Post-MVP |
| Complete Resource Specification | Extended resource specification with full property model | 🔄 Post-MVP |
Testing & Infrastructure
| Document | Description | Status |
|---|---|---|
| Testing Infrastructure | Complete testing strategy & framework details | ✅ Complete |
| Test Commands | Test execution commands & development tips | ✅ Complete |
Applications & Use Cases
| Document | Description |
|---|---|
| Artcoin Integration | Artcoin mapped onto the NDO model (property regimes, roles, custody, PPRs) + implementation status |
| User Story — Artcoin | Art circulation & discovery via venues and individual art lovers |
| User Story — Art Distribution | Multi-venue exhibition tour: custody chain, transport & storage |
| User Story — Art Production | Collaborative art production with shared studio resources (REA edge) |
| User Story — ERP Bridge | ERP bridge integration scenario |
| User Story — Food Basket | Food basket sharing scenario |
| User Story — Material Peer Production | Material peer production scenario |
| User Story — Open Science | Open science commons scenario |
🔧 API Documentation
Full reference: API Reference
Person Zome API
Core Identity & Access Management
create_person()- Create agent profile with discovery anchorsget_person()- Retrieve profile by hashget_all_persons()- Discover all agents via anchor traversalupdate_person()- Update profile with validationdelete_person()- Soft deletion with cleanup
Capability & Security
create_capability_token()- Issue capability tokens with role restrictionsget_agent_capability_level()- Query current trust levelpromote_agent_capability()- Advance trust based on PPR milestones
Private Data Sharing
request_private_data_access()- Request access to specific fieldsgrant_private_data_access()- Grant time-limited access (subject to 30-day maximum enforced in capability metadata)get_private_data()- Retrieve authorized private datarevoke_private_data_access()- Revoke granted permissions
Role Management
assign_role()- Assign roles with validation metadataget_agent_roles()- Query current role assignmentsvalidate_role_requirements()- Check role qualification status
Resource Zome API (Data Model Only)
Resource Specification Management
create_resource_specification()- Define resource types and propertiesget_resource_specification()- Retrieve specification detailsget_all_resource_specifications()- Discover all specificationsupdate_resource_specification()- Modify specifications with validation
Economic Resource Management
create_economic_resource()- Create resource instances with initial stateget_economic_resource()- Retrieve resource current state and historyget_economic_resource_with_state()- Retrieve resource with full state transitionsupdate_operational_state()- UpdateEconomicResource.operational_stateget_my_resources()- Discover resources where calling agent is custodianget_resources_by_specification()- Find resources conforming to specificationget_resources_by_operational_state()- Query resources by operational state
Cross-Zome State Transitions
request_resource_transition()- Request state change through governance evaluationbatch_state_transitions()- Process multiple state transitions efficiently
Governance Zome API (State Transition Operator)
State Transition Evaluation
evaluate_state_transition()- Evaluate governance rules for state changesget_applicable_rules()- Retrieve governance rules for resource/actionevaluate_rule()- Evaluate individual governance rulecheck_agent_permissions()- Verify agent has required permissionsget_agent_roles()- Retrieve agent's current role assignments
Economic Event Generation
generate_economic_event()- Create audit events for state transitionsvalidate_transition_chain()- Validate sequence of state changesget_transition_history()- Retrieve complete audit trail
Governance Rule Management
create_governance_rule()- Create new governance rulesupdate_governance_rule()- Modify existing rulesget_governance_rules()- Retrieve applicable rules
Legacy Commitment Management (PPR System)
create_commitment()- Create commitments with validation rulesget_commitment()- Retrieve commitment detailsfulfill_commitment()- Mark commitments as fulfilled
PPR System
issue_ppr()- Issue Private Participation Receipt (16 categories)get_ppr_summary()- Retrieve reputation summary across categoriesvalidate_ppr_eligibility()- Check qualification requirementsderive_reputation_score()- Calculate cryptographic reputation metrics
Multi-Reviewer Validation
create_validation_workflow()- Set up validation (2-of-3, N-of-M, simple_majority)submit_validation_review()- Submit validation assessmentscheck_validation_consensus()- Determine validation outcomes
Agent Promotion
evaluate_agent_promotion()- Assess readiness for capability advancementpromote_to_accountable_agent()- Promote based on transaction validationpromote_to_primary_accountable_agent()- Promote based on PPR milestones
🧪 Testing Infrastructure
Test Architecture
All new tests use Sweettest (Rust) in dnas/nondominium/tests/src/. Tryorama (TypeScript) tests in tests/ are deprecated.
# Prerequisites
bun run build:happ
# Run all tests
CARGO_TARGET_DIR=target/native-tests cargo test --package nondominium_sweettest
# Run a specific module
CARGO_TARGET_DIR=target/native-tests cargo test --package nondominium_sweettest --test person
# Verbose output
CARGO_TARGET_DIR=target/native-tests cargo test --package nondominium_sweettest -- --nocapture
Shared Setup Utilities
setup_two_agents()— two conductors with nondominium DNAsetup_three_agents()— three conductors with nondominium DNAsetup_dual_dna_two_agents()— two conductors with nondominium + hREA DNAs
Development Tips
- Use
warn!macro in Rust zome functions to log debugging information visible in test output - Use
#[ignore]on tests not yet ready for execution - DHT sync between agents:
await_consistency_20_s([&cell_a, &cell_b]).await.unwrap()(pass the array by value, not&[...])
📊 Implementation Status
✅ Phase 1 Complete: Foundation System
- Person Management: Agent profiles, roles, and basic capability tokens
- Identity System: Pseudonymous identity with public/private separation
- Basic Access Control: Role-based access with validation metadata
- hREA Bridge: Person/ReaAgent bridge for ValueFlows compliance
✅ MVP Complete: Advanced Governance & UI
- Capability-Based Sharing: Complete request/grant workflows with time-limited grants (30-day cap)
- PPR System: 16-category reputation tracking with cryptographic signatures
- Economic Processes: Four structured processes (Use, Transport, Storage, Repair)
- Multi-Reviewer Validation: 2-of-3, N-of-M, and simple majority validation
- Agent Promotion: Progressive trust model with automatic advancement
- NDO Layer 0:
NondominiumIdentitypermanent identity anchor with lifecycle transitions - MVP UI: Lobby → Group → NDO three-level hierarchy, NDO creation, lifecycle browser, fork friction modal
🔄 Phase 2 (In Progress): Economic Processes & PPR Generation
- Economic processes (Use/Transport/Storage/Repair) backend
- PPR receipt generation from Commitment/Claim/Event cycles
- Governance-as-operator full implementation
- Agent promotion workflows
📋 Post-MVP
- Group DNA backend, NDO cell cloning
- PPR reputation UI
- Unyt/Flowsta integrations
- Collective agent types, affiliation spectrum
🔍 Advanced Features
Private Participation Receipt (PPR) System
16 PPR Categories:
Genesis Roles (Network Entry):
- ResourceCreation - Recognition for successful resource contributions
- ResourceValidation - Credit for network validation activities
Core Usage Roles (Custodianship): 3. CustodyTransfer - Outgoing custodian recognition 4. CustodyAcceptance - Incoming custodian validation
Intermediate Roles (Specialized Services): 5. MaintenanceCommitmentAccepted - Maintenance agreement recognition 6. MaintenanceFulfillmentCompleted - Maintenance service completion 7. StorageCommitmentAccepted - Storage service agreement 8. StorageFulfillmentCompleted - Storage service completion 9. TransportCommitmentAccepted - Transport service agreement 10. TransportFulfillmentCompleted - Transport service completion 11. GoodFaithTransfer - Trust-based transfer recognition
Network Governance: 12. DisputeResolutionParticipation - Constructive conflict resolution 13. ValidationActivity - Ongoing validation duties 14. RuleCompliance - Consistent governance adherence
Resource End-of-Life: 15. EndOfLifeDeclaration - Responsible lifecycle management 16. EndOfLifeValidation - Expert validation services
Economic Processes with Role-Based Access
| Process | Description | Required Role | Key Features |
|---|---|---|---|
| Use | Resource utilization without ownership transfer | Accountable Agent | Time-limited access, usage tracking |
| Transport | Resource movement between locations | Primary Accountable Agent | Custody transfer, location tracking |
| Storage | Resource preservation and maintenance | Primary Accountable Agent | Location tracking, condition monitoring |
| Repair | Resource restoration and improvement | Primary Accountable Agent | Quality validation, cost tracking |
Progressive Trust Model
Simple Agent (member)
├── General capability token
├── Can create resources & make first transaction
├── PPR eligibility: ResourceContribution upon validation
└── Promotion: First validated transaction → Accountable Agent
Accountable Agent (stewardship)
├── Restricted capability token
├── Can access resources & validate others
├── PPR eligibility: Service processes & validation
└── Promotion: PPR milestones + role validation → Primary Agent
Primary Accountable Agent (coordination/governance)
├── Full capability token
├── Can hold custody & validate specialized roles
├── PPR eligibility: All 16 categories
└── Advanced: Dispute resolution & end-of-life validation
🔗 External References
Technology Stack
- Holochain - Distributed application framework
- ValueFlows - Economic coordination ontology
- hREA - Holochain implementation of ValueFlows
- @holochain/client - UI client library
- Holochain Playground - Development tools
Development Tools
- hc CLI - Holochain development tool
- Svelte - Frontend framework
- Vite - Build tool and development server
📝 Development Notes
Code Patterns
- Entry Creation: All zomes follow consistent create/get/update/delete patterns
- Anchor Links: Discovery anchors for all major entry types
- Validation: Comprehensive validation with role-based access control
- Privacy: Public/private data separation with capability-based access
Testing Patterns
- Multi-Agent: All tests support 2+ distributed agents
- DHT Sync: Use
await_consistency_20_swith the timeout wrapper - Debug Support: Verbose logging with
warn!macro for Rust debugging - Isolation: Test isolation with proper cleanup between scenarios
Performance Considerations
- WASM Compilation: Rust zomes compiled to WASM for efficiency
- DHT Optimization: Efficient link traversal for discovery operations
- Validation Caching: Role and capability validation caching
- PPR System: Optimized reputation calculation with cryptographic proofs
🔄 Document Maintenance
Last Updated: 2026-05-04 Maintainers: Development Team
Update Process
- Code changes → Update relevant API documentation
- Feature completion → Update implementation status
- Architecture changes → Update architecture overview
- Test additions → Update testing documentation
nondominium - Requirements Document
1. Executive Summary
nondominium is a foundational infrastructure project aimed at enabling a new class of Resources that are organization-agnostic, uncapturable, and natively collaborative. These Resources are governed not by platforms or centralized authorities, but through embedded rules, transparent peer validation, and a comprehensive reputation system.
The project's central goal is to support a true sharing economy, overcoming the structural flaws of centralized platforms (centralization of power, censorship, unsuitable regulations).
Built on the Holochain framework and using the ValueFlows standard, nondominium allows any Agent to interact with these Resources in a permissionless but accountable environment, with automatic reputation tracking through Private Participation Receipts (PPRs).
Optional post-MVP economic ontology: The universal NDO baseline models ValueFlows' Agent and Resource primitives. Applications whose domain includes generative, non-ownable systems may progressively activate Source as a third category (watersheds, rivers, forests, fisheries, knowledge commons) that yields Resources, receives ecological effects, and carries adaptive stewardship governance. Source is not required for ordinary Project NDOs or resource-mutualisation applications. Sources are not owned EconomicResource instances and not intentional Agents. Normative detail: source-ndo-requirements.md (REQ-SOURCE-*); implementation phasing: implementation_plan.md §12.7.
2. Objective & Goals
2.1 Main Objective
Develop a new class of Resources that are:
- Permissionless Access: Anyone can Access Resources under defined governance rules
- Organization Agnostic: Exist independently of any single organization. Not owned or controlled by any single Agent or organization.
- Capture Resistant or Unenclosable: Uncapturable and resilient to monopolization. No Agent or group of Agents can control or delete Resources.
- Self-governed: Rules driven associated directly with the Resources, which govern interactions or Actions that Agents can take, as defined by the system. Roles: Set of Activities or types of interactions that an Agent can perform with respect to the Resource. Also related to Custody (responsibility), maintenance or improvements (obligations). Access control: Rules associated with Roles of Agents, membranes, to grant permissions to interact with Resources in specific ways, Role-related. Is pseudonymous.
- Self-regulated: Peer reviewed, verified and tested (quality control)
- Shareable by Default: Resources are designed for sharing from inception
- Credentials and Reputation-enabled: Built-in accountability through cryptographically-signed participation tracking
- Process-aware: Supporting structured Economic Processes (Use, Transport, Storage, Repair)
- Fully specified: Machine readable in terms of function, design architecture, standards (dimensions, tolerances, quality), etc.
- Composable: Resources can be combined into complex resources, allow fork and remix
- Hard to Clone: Governance, set of rules and incentives to make unnecessary copying of a resource unlikely.
- Lifecycle Managed: Resources have managed lifecycles from creation through validation to end-of-life.
- Traceable: Full provenance and economic activity tracking, affiliation to component resources
2.2 Supporting Goals
- Digital Representation: Define machine-readable, digital, and material Resources as nondominium, implemented as DHT entries on Holochain
- Proof-of-Concept Implementation: Build and test a prototype of a distributed platform supporting Resource sharing under the nondominium property regime
- Governance and Incentive Layer: Implement all ValueFlows Actions and Economic Processes with embedded governance rules
- Identity and Role System: Develop Agent identity infrastructure supporting pseudonymity, credentials, and private entry identification
- Reputation System: Implement Private Participation Receipts (PPRs) for trustworthy, cumulative reputation tracking
- Process Management: Support structured Economic Processes with role-based access control
- Ecological and knowledge commons (optional post-MVP profile): Where an application's domain actually includes a generative system, activate
Source/ Source-NDO so boundary events (extraction, loading, restoration) are recorded on-ledger and govern adaptive access — without imposing Source concepts on simpler Project or resource-sharing applications (REQ-SOURCE-APP-, REQ-SOURCE-)
2.3 Post-MVP capability integrations and application profiles
The current MVP in this repository implements ResourceSpecification, EconomicResource, and GovernanceRule with governance-as-operator patterns as specified elsewhere in this document. Normative requirements for the generic Nondominium Object (NDO) — three-layer model, lifecycle vs operational state, capability slot surface, and typed integration with external operators — live in ndo_prima_materia.md (REQ-NDO-L0 through REQ-NDO-AGENT-08, REQ-NDO-CS-01 through REQ-NDO-CS-15, migration §10).
Optional, pay-as-you-grow integrations and application profiles (communities may adopt any subset):
| Integration | Role | Normative detail | Design stub |
|---|---|---|---|
| Lobby DNA | Multi-network federation: entry point (Lobby DHT) + per-group coordination (Group DHT) + NDO-to-NDO hard links, Contributions, Smart Agreements; dual deployment (standalone + Moss applet) | REQ-LOBBY-, REQ-GROUP-, REQ-NDO-EXT-* | lobby-dna.md / lobby-architecture.md |
| Unyt | Economic settlement (Smart Agreements, RAVE proofs, PPR↔RAVE provenance) | ndo_prima_materia.md §6.6, §11.5; REQ-NDO-CS-07–CS-11 | unyt-integration.md |
| Flowsta | Cross-app identity (Vault IsSamePersonEntry, FlowstaIdentity slot, DID, recovery); Tier 1 (Phase 1) vs Tier 2 (Phase 3) | ndo_prima_materia.md §6.5–6.7, §11.6; REQ-NDO-CS-12–CS-15; REQ-NDO-AGENT-07–08 | flowsta-integration.md |
| Source-NDO application profile | Optional third primitive for applications governing generative ecological or knowledge systems. Not activated for ordinary Project NDOs (e.g. open-hardware design) or mature-resource mutualisation (e.g. sharing a 3D printer) unless the application explicitly needs to govern a generative Source and its boundary effects. | REQ-SOURCE-APP-, REQ-SOURCE-ONT-, REQ-SOURCE-GOV-, REQ-SOURCE-DATA-, REQ-SOURCE-EVENT-; REQ-USER-ST-, REQ-UI-SOURCE-* (§4.6) | source-ndo-requirements.md / source-ndo-paper.md |
Knowledge-base context (ontology, OVN alignment, gap analysis): resources.md, agent.md, governance.md, source-ndo-requirements.md. This PRD remains the anchor for MVP user stories and REQ-USER / REQ-RES / REQ-GOV IDs; NDO-wide REQ-NDO-* IDs are defined in ndo_prima_materia.md §9; Source-NDO REQ-SOURCE-* IDs are defined in source-ndo-requirements.md §8.
3. nondominium Resource Characteristics
The requirements below apply to appropriable Resources (EconomicResource instances under a ResourceSpecification). They do not apply to Sources (generative ecological or knowledge systems modeled as Source-NDOs post-MVP) — see §4.6 and REQ-SOURCE-ONT-02. In Ostrom's SES terms: a Source is the resource system; an EconomicResource is the resource unit extracted or held in custody from it.
nondominium Resources must exhibit the following characteristics:
- REQ-RES-01: Permissionless Access: Anyone can access nondominium Resources under defined governance rules. Post-MVP note: "defined governance rules" must be extensible to include
AffiliationState-based conditions (e.g.min_affiliation: ActiveAffiliate) in addition to role-based conditions; seeREQ-AGENT-03,REQ-AGENT-05, andREQ-GOV-09annotation below. - REQ-RES-02: Organization Agnostic: Resources exist independently of any single organization and are associated with Agents according to their Roles. Post-MVP note: "Agents" must encompass all
AgentEntityTypevariants (Individual, Collective, Project, Network, Bot) — seeREQ-AGENT-01andREQ-AGENT-02;EconomicResource.custodianwill expand fromAgentPubKeytoAgentContext. - REQ-RES-03: Capture Resistant: No Agent or group can control, delete, or monopolize nondominium Resources
- REQ-RES-04: Self-governed: Governance rules are embedded within ResourceSpecifications and enforced programmatically
- REQ-RES-05: Fully Specified: Resources are machine-readable in terms of function, design, standards, and governance rules
- REQ-RES-06: Hard to Clone: Governance, incentives, and reputation systems make unnecessary copying unlikely
- REQ-RES-07: Shareable by Default: Resources are designed for sharing from inception
- REQ-RES-08: Process-Enabled: Resources can be used in structured Economic Processes (Use, Transport, Storage, Repair)
- REQ-RES-09: Lifecycle Managed: Resources have managed lifecycles from creation through validation to end-of-life
- REQ-RES-10: Source Boundary (post-MVP): Generative ecological or knowledge systems (watersheds, rivers, forests, fisheries, open knowledge commons) SHALL NOT be modeled as owned
EconomicResourceinstances with aprimaryAccountablecustodian when their correct ontological category is Source. Such systems SHALL be registered as Source-NDOs (NondominiumIdentity+SourceProfile) withproperty_regimeofNondominiumorCommonPoolonly. Extracted or appropriated units (water m³, fish landed, timber cut) remainEconomicResourceinstances linked to boundary events on the Source. See REQ-SOURCE-ONT-01, REQ-SOURCE-ONT-02, and §4.6.
4. User Roles & Stories
4.1 Simple Agent
A user who can search for nondominium Resources and contribute new ones. Linked to a general capability token.
Identity & Onboarding
- REQ-USER-S-01: As a Simple Agent, I want to use the nondominium hApp with minimal effort and without permission
- REQ-USER-S-02: As a Simple Agent, I want to complete my identity by associating private information (legal name, address, email, photo ID) with my Agent identity, stored as Holochain private entries
Resource Discovery
- REQ-USER-S-03: As a Simple Agent, I want to search for available nondominium Resources and their specifications
- REQ-USER-S-04: As a Simple Agent, I want to search for other Agents, view their public profiles and roles
Resource Creation
- REQ-USER-S-05: As a Simple Agent, I want to create new nondominium Resources with embedded governance rules
- REQ-USER-S-06: As a Simple Agent, I want to interact with Agents interested in accessing my created Resources
First Transaction & Promotion
- REQ-USER-S-07: As a Simple Agent, I want to make my first transaction, transferring my new Resource to an Accountable Agent
- REQ-USER-S-08: As a Simple Agent, I want to become an Accountable Agent after my first transaction is validated
4.2 Accountable Agent
A user who can signal intent to access Resources and participate in governance. Linked to a restricted capability token.
Resource Access
- REQ-USER-A-01: As an Accountable Agent, I want to search for available nondominium Resources and their governance rules
- REQ-USER-A-02: As an Accountable Agent, I want to search for other Agents and view their reputation summaries
- REQ-USER-A-03: As an Accountable Agent, I want to create new nondominium Resources with embedded governance rules
- REQ-USER-A-04: As an Accountable Agent, I want to signal intent to access Resources for specific Economic Processes (Use, Transport, Storage, Repair)
Role & Process Management
- REQ-USER-A-05: As an Accountable Agent, I want to acquire specialized roles (Transport, Repair, Storage) through validation. Conditional post-MVP note: applications that enable the Source-NDO profile add Steward as a validated functional role for generative-system governance (§4.6, REQ-USER-ST-*); other applications do not expose it
- REQ-USER-A-06: As an Accountable Agent, I want to initiate and complete Economic Processes according to my roles
- REQ-USER-A-07: As an Accountable Agent, I want to chain multiple process actions (e.g., transport → repair → transport) in a single commitment
Validation & Governance
- REQ-USER-A-08: As an Accountable Agent, I want to validate new Resources during first access events
- REQ-USER-A-09: As an Accountable Agent, I want to validate Agent identity information and first transactions
- REQ-USER-A-10: As an Accountable Agent, I want to validate Economic Process completions and outcomes
Reputation & Participation
- REQ-USER-A-11: As an Accountable Agent, I want to receive Private Participation Receipts for all my economic interactions
- REQ-USER-A-12: As an Accountable Agent, I want to view my reputation summary and participation history
- REQ-USER-A-13: As an Accountable Agent, I want to cryptographically sign participation claims to ensure authenticity
4.3 Primary Accountable Agent (Custodian)
The agent with physical possession (custodianship) of a material nondominium Resource.
Custodial Responsibilities
- REQ-USER-P-01: As a Primary Accountable Agent, I want all capabilities of an Accountable Agent
- REQ-USER-P-02: As a Primary Accountable Agent, I want to apply governance rules programmatically for access decisions
- REQ-USER-P-03: As a Primary Accountable Agent, I want to manage Resource custody transfers with full audit trails
Advanced Governance
- REQ-USER-P-04: As a Primary Accountable Agent, I want to validate specialized role requests from other Agents
- REQ-USER-P-05: As a Primary Accountable Agent, I want to participate in dispute resolution processes
- REQ-USER-P-06: As a Primary Accountable Agent, I want to initiate Resource end-of-life processes with proper validation
4.4 Agent Ontology Requirements (Post-MVP)
Status: Post-MVP. Gaps identified against the OVN wiki ontology (15 years of commons-based peer production practice). See
documentation/requirements/agent.mdfor the full analysis. Requirements below are design targets for the generic NDO; the current MVP implements individual agents only.
Agent Type Taxonomy
- REQ-AGENT-01: Agent Type Field: Every agent context must carry an
AgentEntityTypediscriminant:Individual,Collective(String),Project(ActionHash),Network(ActionHash),Bot { capabilities, operator },ExternalOrganisation(String). The MVP supportsIndividualonly; all other variants require post-MVP implementation. - REQ-AGENT-02: Collective Agents — Dual-Face Model: Groups, working groups, projects, and network-level entities are composed agents. Each has an agent face (
AgentContextwith the relevantAgentEntityTypevariant) through which it participates in economic events as provider/receiver, and may optionally have a resource face (NondominiumIdentity) as its digital twin. TheActionHashinProject(ActionHash)andNetwork(ActionHash)links the agent face to the resource face. These two faces are ontologically distinct — theNondominiumIdentityis a Resource; theAgentContextis an Agent — and neither replaces the other. Individual agents hold roles in both their own profile and in collective agents' governance. Collective agents may act through multi-signature patterns (N-of-M member authorisation) when performing economic events. - REQ-AGENT-03: Bot/AI Delegation: A
DelegatedAgentrelationship must allow aPersonto authorise an AI agent or bot to act on their behalf within a defined scope of capabilities and for a defined duration.
Affiliation Spectrum
- REQ-AGENT-04: Five-State Affiliation: The system must model the OVN affiliation spectrum — UnaffiliatedStranger, CloseAffiliate, ActiveAffiliate, CoreAffiliate, InactiveAffiliate — as a derived (not stored) property computed algorithmically from PPR activity, recency, and contribution history. Binary "in/out" membership is insufficient for governance decisions.
- REQ-AGENT-05: Affiliation Record: Formal network entry must be formalised as an
AffiliationRecordentry: the agent cryptographically signs acknowledgement of the Terms of Participation (ToP), the Nondominium & Custodian agreement, and the Benefit Redistribution Algorithm. This record is the prerequisite forActiveAffiliatestatus. - REQ-AGENT-06: Configurable Role Taxonomy: The
RoleTypeenum must become configurable at the network level. Communities must be able to define their own role taxonomies rather than relying on the six predefined types (SimpleAgent,AccountableAgent,PrimaryAccountableAgent,Transport,Repair,Storage). Predefined roles become defaults, not constraints. Post-MVP note: Source-enabled applications addStewardas an application-profile role for generative-system governance (§4.6); applications without Sources SHALL NOT expose or require it.
Composable Profile
- REQ-AGENT-07: AgentProfile View: The system must expose a composable
AgentProfilequery that aggregatesPerson,ReputationSummary,PersonRolelist, active commitment count, economic event counts,CapabilitySlotattachments, and network affiliations into a single queryable view. This view is computed from existing DHT data — it is not a new stored entry type. - REQ-AGENT-08: Social Graph: The system must model peer relationships via an
AgentRelationshipbidirectional link type (typed: colleague, collaborator, trusted, voucher), stored privately. Social relations are part of agent wealth in the OVN model and must be legible to governance without being publicly exposed. - REQ-AGENT-09: Network Affiliations: Agents must be able to hold membership in multiple NDO networks simultaneously. Cross-network affiliations must be modelled as typed links from
Personto other NDO instance hashes, enabling agents to be bridge nodes between communities. - REQ-AGENT-10: Needs and Wants: An optional
AgentNeedsWantsprofile extension must allow agents to declare what resources they need and what they can offer, enabling matching at the network level.
Identity, Privacy, and Portability
- REQ-AGENT-11: CapabilitySlot on Agent: The
Personentry hash must serve as a stigmergic attachment surface (analogous to the resource-level CapabilitySlot) for external credential wallets, DID documents, reputation oracles, and professional networks. Agents can attach capabilities to their identity without modifying the corePersonentry. - REQ-AGENT-12: Portable Credentials: The system must support a
PortableCredentialstructure — a cryptographically signed summary of an agent's roles andReputationSummary— that can be verified by other Holochain networks. This implements the OVN requirement for cross-network identity portability. - REQ-AGENT-13: Zero-Knowledge Capability Proofs: Agents must be able to prove capability eligibility (
I have at least N completed maintenance commitments) without revealing the underlying PPR data. ZKP proofs break the false binary between full data disclosure (low privacy) and no disclosure (no accountability). - REQ-AGENT-14: Pseudonymous Participation Mode: The system must support ephemeral participation: an agent contributes under a temporary key without linking to their
Personentry. Contribution is recorded but unlinkable to physical identity. This is the individual-level participation tier in the OVN individual/person model. - REQ-AGENT-15: Sybil Resistance: Network membership must support optional sybil-resistance mechanisms: social vouching (existing agents vouch for new agents), biometric opt-in, or integration with an external Proof-of-Personhood system, configurable per network as a membrane proof.
Promotion Workflow Integrity
- REQ-AGENT-16: Queryable Promotion Requests: The
request_role_promotionfunction must create a real, queryableRolePromotionRequestentry linked to both the requesting agent and an anchor for pending requests — not return a placeholder hash. Promotion requests must be discoverable by authorised approvers.
4.5 MVP UI Requirements
Status: Implemented in the current codebase. See
documentation/specifications/ui_architecture.mdfor design;documentation/IMPLEMENTATION_STATUS.mdfor status.
These requirements govern the Svelte 5 / SvelteKit frontend implemented in the ui/ directory. They derive from documentation/requirements/ui_design.md and the reconciliation decisions documented in GitHub Issue #102 (where conflicts arose, ui_design.md is the source of truth).
Navigational Hierarchy
- REQ-UI-NAV-01: Three-Level Hierarchy: The UI must implement Lobby → Group → NDO as the navigational hierarchy. Users enter via the Lobby, join or create Groups, and access NDOs within a Group context.
- REQ-UI-NAV-02: Group-Scoped NDO Creation: NDOs may only be created from within a Group. There is no global "Create NDO" flow. The
/ndo/newroute must redirect to the relevant Group or provide an explanation. - REQ-UI-NAV-03: Context-Aware Sidebar Link: The "New NDO" Sidebar link must navigate to
/group/{id}?createNdo=1when a Group is selected, or to/ndo/new(explanation) otherwise.
Lobby
- REQ-UI-LOBBY-01: NDO Browser: The Lobby must display all known NDOs in a browse-and-filter grid. Filter chips must allow multi-select across
LifecycleStage,ResourceNature, andPropertyRegimesimultaneously. OR logic applies within each dimension; AND logic applies across dimensions. - REQ-UI-LOBBY-02: Group Sidebar: The Lobby must include a sidebar listing the agent's Groups, with "Create Group" and "Join Group" actions. New or joined Groups must appear immediately and navigate the agent to the Group view.
- REQ-UI-LOBBY-03: Lobby Profile Bar: The Lobby must display the agent's
nicknamefromLobbyUserProfile, or a "Set up profile" CTA if no profile exists.
Identity — Three Levels
- REQ-UI-ID-01: LobbyUserProfile (Level 1): Agents must be prompted to create a
LobbyUserProfile(nickname required; real name, bio, email, phone, address optional) on first Lobby entry. This profile is stored inlocalStorageonly and does not require a DHT write. - REQ-UI-ID-02: GroupMemberProfile (Level 2): On first entry to each Group, agents must be prompted to choose how their
LobbyUserProfiledata is presented to other Group members (anonymous vs. selective disclosure). This choice is stored per-Group inlocalStorage. - REQ-UI-ID-03: Person entry (Level 3): A
Personentry inzome_personis created at most once — on the agent's first DHT-active action (e.g., NDO creation, acceptance of a Commitment). Lobby browsing and Group membership do not require aPersonentry.
Groups (DNA-backed)
- REQ-UI-GRP-01: Group as cloned DNA cell: Groups are DNA-backed (PR #107). Each group is a cloned Group DNA cell (
clone_cell,zome_group) with its own isolated DHT, announced for discovery via the Lobby DNA. TheLobbyService/GroupServiceinterface remained stable across the localStorage→DNA migration so components were not changed. Only the Level 2GroupMemberProfilepresentation choice (REQ-UI-ID-02) remains inlocalStorage. (Originally specified as a localStorage shell; superseded by the Group DNA backend.) - REQ-UI-GRP-02: Invite Links: Groups must support invite links that allow another agent to join by pasting a link. Implemented as a base64-encoded
{ network_seed, group_dna_hash, group_name }payload (?group=<base64>); joining provisions the same-seed clone cell and callsjoin_group. The joined group must appear without a page reload (gossip-retry onget_my_groupwith an invite-payload fallback). - REQ-UI-GRP-03: Group-scoped NdoBrowser: The Group view must display only the NDOs anchored in that Group, using the same filter chip UI as the Lobby NdoBrowser.
- REQ-UI-GRP-06: NDOs are per-cell, anchored per group: Each NDO is its own cloned
ndoDNA cell whoseDnaHashis bound to the immutable Layer 0 classification through DNA properties (ADR-010/ADR-013). A group points at an NDO through anNdoAnchorentry on the group clone cell carrying the full clone coordinates (ndo_dna_hash,network_seed,identity_action_hash) plus cached card fields, so browsing renders from anchors without joining any NDO cell and any member can re-derive, verify, and join the cell from the anchor alone (ADR-011). The anchor is the only pointer the read paths follow: creating an NDO must fail if its anchor cannot be written, and associating an existing NDO with a second Group must write a second anchor there. Onlyname,description, andlifecycle_stagemay be updated on an anchor; the identity coordinates are integrity-immutable. Rationale and constraints:documentation/specifications/adr/ADR-010-013-per-ndo-cells.md. - REQ-UI-GRP-04: DHT-backed member list with self-healing membership: The Group view must list all group members, derived from
GroupMembershipentries on the group clone cell (get_group_members; each member is a membership action's author). Because joining commits membership best-effort over a gossiping DHT, the UI must idempotently reconcile membership when a group is opened (ensureMembership: resolve group hash →is_member→join_groupif missing) so a joined agent reliably appears in every member's list. Cross-member visibility of newly committed memberships is subject to DHT gossip. - REQ-UI-GRP-05: Reactive shared-group items: Changes to shared-group items (members, NDO associations) made by other members must surface in the UI without a manual reload. The MVP satisfies this with a pull model: per-open reconciliation plus a silent refresh on tab focus/visibility and a gentle poll while the group is open. Push-based delivery via Holochain
remote_signalis the documented next step (TODO(signals)); until then, cross-member updates appear within the poll interval, on focus, or on reload.
NDO Management
- REQ-UI-NDO-01: NDO Creation Form: The NDO creation form must include:
name(text),property_regime(select, 7 canonical options — Private, Commons, Collective, Pool, CommonPool, Public, Nondominium — with tooltips),resource_nature(select, 5 options with tooltips),lifecycle_stage(select, 7 creatable-at-registration stages — Ideation through Active; Hibernating and terminal stages are transition-only),description(textarea). Name uniqueness is checked client-side against existing lobby NDOs (warning, not block). - REQ-UI-NDO-02: Initiator Display: The NDO identity panel must display the initiator's
Person.nameas a profile link, or fall back to a truncatedAgentPubKeyif noPersonentry exists. - REQ-UI-NDO-03: Lifecycle Transition: The initiator of an NDO must have access to a lifecycle transition button. The frontend must encode the full valid transition table (mirroring the Rust validation). Special cases:
Deprecatedrequires successor NDO selection;Hibernatingrequires confirmation. - REQ-UI-NDO-04: Transition History: NDO identity panels must show a collapsible transition history panel listing
from_stage,to_stage,agent,timestamp, andevent_hash(with copy-to-clipboard) for each recorded transition. - REQ-UI-NDO-05: Fork Button: An informational "Fork this NDO" button must be accessible to all authenticated users. The fork modal must explain the fork friction concept (negotiation, consensus, post-MVP Unyt stake) and provide a copy-initiator-pubkey CTA. Actual fork submission is post-MVP.
4.6 Source Ontology Requirements (Post-MVP)
Status: Optional post-MVP application profile. Normative REQ-SOURCE-* IDs and full data-model specification live in source-ndo-requirements.md. Academic grounding: source-ndo-paper.md. Implementation phasing: implementation_plan.md §12.7. Source-NDO does not break existing REQ-NDO-* invariants (Layer 0 permanence, PPR privacy model) and is not part of the minimum UI or ontology for every NDO application.
Applicability and progressive activation
Source follows dynamic complexity matching: the application SHALL expose only the primitives required by its actual coordination problem. Agent + Resource remain the baseline. Source is activated only when agents must govern a generative system's condition, boundary flows, regeneration, or assimilation capacity.
Source is normally relevant when:
- the object of governance is a resource system rather than an appropriable unit (e.g. watershed vs water in a tank; fishery vs landed fish);
- extraction, loading, regeneration, or coupled Source condition must be visible on-ledger;
- adaptive stewardship rules must respond to accumulated condition signals.
Source is normally not relevant when:
-
a Project-type NDO coordinates the design of an open-source hardware device; Agents contribute work and the design/artifacts are Resources;
-
an NDO represents a mature, in-use Resource being mutualised, such as a 3D printer shared within or between Groups; Agents, custody, access, maintenance, and Resource events are sufficient;
-
no generative system or Source boundary is itself being governed. Provenance from nature alone does not require Source activation.
-
REQ-SOURCE-APP-01: Optional Application Profile: Source support SHALL be an opt-in application/profile capability, not a mandatory primitive in every NDO creation flow or detail view.
-
REQ-SOURCE-APP-02: Complexity-Matched Activation: Applications SHALL activate Source features only when their domain requires governance of a generative system or its boundary effects. Ordinary Project and resource-mutualisation flows SHALL remain complete using Agent and Resource primitives alone.
-
REQ-SOURCE-APP-03: No Universal UI Burden: Applications that do not enable the Source profile SHALL NOT display Source type selectors, regime-state fields, stewardship workflows, Source coupling graphs, or Source-specific navigation.
-
REQ-SOURCE-APP-04: Progressive Enablement: Enabling Source support SHALL add Source-specific data, governance, and UI modules without changing existing Agent/Resource semantics or requiring existing NDOs to migrate into Source-NDOs.
Ontological position
ValueFlows and REA model Agent (acts, commits, bears responsibility) and Resource (appropriable output). A river, watershed, forest, or fishery fits neither honestly: as EconomicResource it implies ownership; as Agent it imports false intention; omitted entirely, extraction appears as resource-from-nowhere (raise) and depletion vanishes from the ledger.
Source is the third flow endpoint: a generative, non-ownable, partially unknowable system that yields Resources, receives ecological effects, conditions other Sources, and accumulates boundary-event history for adaptive stewardship. Source-NDOs use the same three-layer NDO model; Layer 0 carries a linked SourceProfile; stewardship uses stewardedBy (obligations), not primaryAccountable (ownership).
| Ostrom SES concept | Nondominium mapping |
|---|---|
| Resource system | Source (SourceProfile on Layer 0) |
| Resource unit | EconomicResource |
| Governance system | GovernanceRule + adaptive loop (§6.6) |
| Users / actors | Agents (+ Steward functional role) |
- REQ-SOURCE-ONT-01: The system SHALL recognise
Sourceas a distinct ontological category for flow endpoints in economic events, separable from bothAgentandEconomicResource(vf:SourceValueFlows extension). - REQ-SOURCE-ONT-02: Source-NDOs SHALL NOT require a
primaryAccountableagent.property_regimeSHALL beNondominiumorCommonPoolonly. Governance SHALL reject any rule that assigns Source ownership or alienation. - REQ-SOURCE-ONT-03: The system SHALL support Source-to-Source links (
yields,conditions,providedBy) for hierarchies and ecological coupling (e.g. watershed → river; forest conditions river flow). - REQ-SOURCE-ONT-04: Source-NDOs SHALL be
NondominiumIdentityentries with a linkedSourceProfile, using the permanent Layer 0 hash as the boundary-event ledger anchor.
Data model
- REQ-SOURCE-DATA-01:
SourceProfileSHALL record ecological condition state (current_stock,flux_rate,assimilation_capacity,regime_state,resilience,tipping_threshold), complexity-economics indicators (adaptive_capacity,generative_capacity,dependency_index), classification (source_type,complex_interior), andstewarded_by. Full field spec:source-ndo-requirements.md§4.1. - REQ-SOURCE-DATA-02:
SourceRegimeStateSHALL progress throughPristine → Stable → Stressed → Degraded → Critical → Transformed, with governance-validated transitions (not unilateral writes). - REQ-SOURCE-DATA-03: Layer 1
SourceSpecificationSHOULD support a multidimensional ecological value vector (Sustenance, Regeneration, Resilience, Adaptive Capacity, Generative Capacity, Commons Value, Learning Value).
Black-box principle: Ecological Source interiors are not modeled. Governance operates on observable boundary signals (withdrawals, pollutant loads, monitoring data, community observation) and adapts rules from the accumulated ledger — consistent with complexity-science treatment of SES as partially unknowable (source-ndo-requirements.md §2.4, §5.1).
Steward user stories
The Steward role is a functional stewardship role (obligations without alienation rights), distinct from PrimaryAccountableAgent custody of material Resources.
Source registration and monitoring
- REQ-USER-ST-01: As a Steward, I want to register a Source-NDO (watershed, river, fishery, knowledge commons) with initial condition indicators and named co-stewards, without assigning ownership
- REQ-USER-ST-02: As a Steward, I want to submit monitoring data and qualitative condition observations that update the Source's regime state through governance-validated assessment
- REQ-USER-ST-03: As a Steward, I want to link sub-Sources and coupling relations (watershed yields river; forest conditions river) so ecological structure is legible on the DHT
Boundary events and access
- REQ-USER-ST-04: As an Accountable Agent, I want to record extraction from a Source (provider: Source, receiver: Agent) so depletion is visible against
current_stockor period quota — not as a phantomraise - REQ-USER-ST-05: As an Accountable Agent, I want to record pollutant loading into a Source (receiver: Source) so assimilation capacity debits are visible on-ledger
- REQ-USER-ST-06: As a Steward, I want access affordance rules (quotas, seasonal limits, discharge caps) to adapt when regime state or monitoring indicates stress, through a defined governance process — not only static one-shot rule evaluation
Governance adaptation
- REQ-USER-ST-07: As a Steward, I want to propose
SourceRegimeStatetransitions with evidence and multi-validator approval when ecological interpretation changes - REQ-USER-ST-08: As a Steward, I want precautionary blocking when a proposed boundary event would push the Source past its
tipping_threshold - REQ-USER-ST-09: As a Steward, I want to participate in stewardship succession (transfer of steward obligations) through governance-validated events, without privatising the Source
Source UI requirements (conditional post-MVP profile)
The following requirements apply only when the host application enables the Source-NDO profile. They SHALL NOT expand the default Project or resource-mutualisation UI.
- REQ-UI-SOURCE-01: A Source-enabled NDO creation flow SHALL offer a distinct Source-NDO variant with
property_regimerestricted toNondominium/CommonPool,SourceTypeselection, steward assignment, and optional initial condition fields. The generic NDO form SHALL remain unchanged when Source support is disabled - REQ-UI-SOURCE-02: Source-enabled detail views SHALL display regime state, condition indicators, steward list, and boundary-event history linked to the Layer 0 hash; ordinary Resource and Project detail views SHALL omit these panels
- REQ-UI-SOURCE-03: A Source-enabled application SHALL visualise Source hierarchies and coupling links (watershed → river → resources) when Layer 1/Composition views mature
- REQ-UI-SOURCE-04: Source-enabled applications SHALL provide stewards a dashboard for monitoring obligations, pending regime transitions, and access-affordance rule proposals
5. Economic Process Requirements
5.1 Core Process Types
- REQ-PROC-01: Use Process: Any Accountable Agent can initiate Use processes for accessing Resources without consuming them
- REQ-PROC-02: Transport Process: Only Agents with Transport role can initiate transport processes to move Resources between locations
- REQ-PROC-03: Storage Process: Only Agents with Storage role can initiate storage processes for temporary Resource custody
- REQ-PROC-04: Repair Process: Only Agents with Repair role can initiate repair processes that may change Resource state
5.2 Process Management
- REQ-PROC-05: Process Initiation: Agents must have appropriate roles to initiate specialized processes
- REQ-PROC-06: Process Tracking: All processes must be tracked with status, inputs, outputs, and completion state
- REQ-PROC-07: Process Validation: Process completions must be validated according to process-specific requirements
- REQ-PROC-08: Process Chaining: Agents with multiple roles can chain process actions within a single commitment
- REQ-PROC-09: Process History: Complete audit trail of all processes affecting each Resource
5.3 Source boundary events (Conditional Post-MVP Profile)
Status: Applies only to Source-enabled applications. Requires
vf:Sourceand the Source-NDO data model (§4.6). Boundary events on Sources are economic events where the Source is provider or receiver — distinct from, and unnecessary for, ordinary custody and use processes onEconomicResourceinstances.
- REQ-PROC-10: Source Extraction Recording: Extraction of resource units from a Source (water abstraction, fish harvest, timber cut) SHALL be recorded as boundary
EconomicEvententries with the Source as provider and an Agent as receiver, decrementingSourceProfile.current_stockor period quota — not as unanchoredraiseevents (REQ-SOURCE-EVENT-01, REQ-SOURCE-EVENT-02) - REQ-PROC-11: Source Loading Recording: Discharge, pollutant loading, or waste deposition into a Source SHALL be recorded with the Source as receiver, decrementing
assimilation_capacitywhere applicable (REQ-SOURCE-EVENT-01, REQ-SOURCE-EVENT-02) - REQ-PROC-12: Source Regeneration Recording: Restoration, remediation, or regeneration actions on a Source (reforestation, riparian repair) SHALL be recordable as governance-validated events that may increment stock, flux, assimilation capacity, or resilience indicators (REQ-SOURCE-EVENT-03)
- REQ-PROC-13: Non-Consumptive Source Use: Non-consumptive use of a Source (e.g. hydro flow alteration affecting regime without volume extraction) SHALL be recordable as boundary events affecting
SourceRegimeStateor flux characteristics without implying Resource custody transfer
6. Governance & Validation Requirements
6.1 Resource Lifecycle Management
- REQ-GOV-01: First Resource Requirement: Simple Agents must create at least one Resource before accessing others
- REQ-GOV-02: Resource Validation: New Resources must be validated by Accountable Agents through peer review during first access
- REQ-GOV-03: Agent Validation: Simple Agents must be validated by Accountable Agents during their first transaction to become Accountable Agents. Post-MVP note: this workflow currently assumes individual agents only; post-MVP must support collective agent promotion workflows where the promotee is a Collective/Project/Network NDO and the promoter is its designated
PrimaryAccountableAgentrepresentative (ref G1,REQ-GOV-16). - REQ-GOV-04: Specialized Role Validation: Transport, Repair, and Storage roles require validation by existing role holders
6.2 Validation Schemes
- REQ-GOV-05: Role-Gated Validation: Certain validations are restricted to Agents with specific roles. Post-MVP note:
ValidationReceipt.validatoris currentlyAgentPubKey; post-MVP must acceptAgentContextto allow collective agent and bot validators within their declared scope (ref G1,REQ-GOV-16). - REQ-GOV-06: Multi-Reviewer Validation: Support configurable validation schemes (2-of-3, N-of-M reviewers)
- REQ-GOV-07: Process Validation: Economic Process completions must be validated according to process-specific criteria
6.3 Governance Rules
- REQ-GOV-08: Embedded Rules: ResourceSpecifications must contain embedded governance rules for access and process management. Post-MVP note: Source-NDOs use Layer 1
SourceSpecificationfor boundary definitions, monitoring framework, and access-affordance rule templates; adaptive revision is governed by §6.6 - REQ-GOV-09: Rule Enforcement: Governance rules must be enforced programmatically across all interactions. Post-MVP note: the governance evaluation engine (
evaluate_transition) must be extended to supportAffiliationState-based rule conditions in addition to the current role-membership check. This requires a cross-zome query fromzome_governancetozome_personto derive the requesting agent'sAffiliationStatebefore evaluatingGovernanceRule.rule_data["min_affiliation"]. SeeREQ-AGENT-03,REQ-AGENT-05,implementation_plan.md §3 [G2+Resource], andgovernance-operator-architecture.md §2.1 TODO G2. Source-NDO note: Source governance extends evaluation with an adaptive loop — boundary events accumulate on the Source Layer 0 hash, ecological interpretation feeds rule revision, and revised access affordances condition future boundary events (§6.6). - REQ-GOV-10: Rule Transparency: All governance rules must be publicly visible and machine-readable
6.4 End-of-Life Management
- REQ-GOV-11: End-of-Life Declaration: Resources reaching end-of-life must go through formal decommissioning process
- REQ-GOV-12: End-of-Life Validation: Multiple validators required for end-of-life declarations to prevent abuse
- REQ-GOV-13: Challenge Period: Time-delayed finalization with challenge period for end-of-life declarations
6.5 Affiliation and Collective Governance (Post-MVP)
These requirements depend on post-MVP agent architecture (
REQ-AGENT-01throughREQ-AGENT-07) and theAffiliationState/AffiliationRecordsystem fromagent.md §4.2and§6.4.
-
REQ-GOV-14: Affiliation-Based Governance Access — governance processes gated by
AffiliationStatemust be enforceable viaGovernanceRule.rule_data["min_affiliation"]; the governance operator must cross-zome queryAffiliationStatefromzome_person(refs G2, G6,governance.md §3.6.2) -
REQ-GOV-15: AffiliationRecord Governance Ceremony — signing an
AffiliationRecordmust generate aCommitment/EconomicEvent/Claimcycle inzome_governance, creating an auditable on-chain record of the Terms of Participation (ToP) signing event; this event triggersAffiliationState → ActiveAffiliate(refs G6,governance.md §3.6.3) -
REQ-GOV-16: Collective Agent Governance Participation —
ValidationReceipt, PPRcounterparty,EconomicEvent.provider/receiver, andGovernanceTransitionRequest.requesting_agentmust acceptAgentContextpost-MVP; collective NDO governance requires designated-operator or N-of-M multi-sig patterns (refs G1,governance.md §6.6) -
REQ-GOV-17: Sybil Resistance for Governance — governance-tier role promotion (
AccountableAgent → PrimaryAccountableAgent) must require either N-of-M active affiliate vouching or optional proof-of-personhood membrane proof (refs G9,governance.md §5.3) -
REQ-GOV-18: Pseudonymous Governance Participation — agents must be able to reach
ActiveAffiliatestatus via pseudonymousAgentPubKey(noPersonentry required); pseudonymous agents are blocked from governance roles requiring legal accountability (refs G10,governance.md §5.3)
6.6 Source governance and adaptive stewardship (Conditional Post-MVP Profile)
Status: Applies only to Source-enabled applications. Full REQ-SOURCE-GOV-* set in source-ndo-requirements.md §5.3. Extends governance-as-operator with a cybernetic loop for complex ecological systems — rules adapt as the Source event ledger grows, without modeling ecological interiors (black-box principle). Applications that coordinate Projects or mutualise mature Resources continue to use ordinary governance-as-operator without this loop.
Adaptive governance loop:
boundary events → ledger on Source L0 hash → ecological interpretation
→ governance rule revision → access affordances → conditioned future events
- REQ-SOURCE-GOV-01: Source-NDO governance MUST support adaptive rule revision with maintained rule version history; rules SHALL be updatable through a defined governance process, not only by the initiator
- REQ-SOURCE-GOV-02: Source-NDOs MUST support access affordance rules as quantitative constraints on boundary events (extraction quotas, discharge caps, seasonal limits, minimum restoration per extraction)
- REQ-SOURCE-GOV-03: Governance evaluation for Source boundary events MUST check
SourceRegimeStateand MAY block or require multi-validator approval when an event would approach or exceedtipping_threshold - REQ-SOURCE-GOV-04: Source-NDOs SHOULD support monitoring obligations as a
GovernanceRuleclass: continued access may require condition-data submission that updatesSourceProfileindicators - REQ-SOURCE-GOV-05:
SourceRegimeStatetransitions MUST be governance-validated with evidence and multi-validator approval - REQ-SOURCE-GOV-06: All Source boundary events MUST be recorded as
EconomicEvententries linked to the Source's Layer 0 hash, forming an auditable ledger - REQ-SOURCE-GOV-07: Source-NDOs MUST accept qualitative and community-validated condition signals (narrative observation, indigenous knowledge assessments) as legitimate governance inputs alongside quantitative monitoring
- REQ-SOURCE-GOV-08: Sensitive ecological data attached to Source records SHALL use Holochain private entries with capability-grant access control, following the
PrivatePersonDatamodel
Stewardship vs custody: Sources have no EconomicResource.custodian. Responsibility is expressed through stewardedBy links and the Steward role — obligations to monitor, interpret, and implement governance decisions, without alienation or privatisation rights (REQ-SOURCE-ONT-02; source-ndo-requirements.md §5.4).
7. Private Participation Receipt (PPR) Requirements
7.1 Receipt Generation
- REQ-PPR-01: Bi-directional Issuance: Every economic interaction generates exactly 2 receipts between participating Agents
- REQ-PPR-02: Automatic Generation: PPRs are automatically issued for all Commitment-Claim-Event cycles
- REQ-PPR-03: Cryptographic Integrity: All receipts are cryptographically signed for authenticity
- REQ-PPR-04: Performance Tracking: PPRs include quantitative performance metrics (timeliness, quality, reliability, communication)
7.2 Receipt Categories
- REQ-PPR-05: Resource Creation: Receipts for Resource creation and validation activities
- REQ-PPR-06: Custody Transfer: Receipts for responsible custody transfers and acceptances
- REQ-PPR-07: Service Processes: Receipts for service commitments and fulfillments (Transport, Repair, Storage)
- REQ-PPR-08: Governance Participation: Receipts for validation activities and governance compliance
- REQ-PPR-09: End-of-Life: Enhanced receipt requirements for end-of-life declarations and validations
7.3 Privacy & Security
- REQ-PPR-10: Private Storage: PPRs stored as Holochain private entries accessible only to owning Agent
- REQ-PPR-11: Reputation Derivation: Agents can derive and selectively share reputation summaries from their PPRs
- REQ-PPR-12: Signature Validation: System must validate cryptographic signatures of participation claims
7.4 Privacy Tiers and Cross-Network Portability (Post-MVP)
TODO: The following requirements depend on post-MVP agent architecture (see
REQ-AGENT-12throughREQ-AGENT-15anddocumentation/requirements/agent.mdSections 4.4–4.5).
- REQ-PPR-13: Per-Interaction Privacy Level: Agents must be able to choose their privacy level per interaction type: fully anonymous (no PPRs, no reputation accumulation), pseudonymous (PPRs linked to persistent pseudonym, not physical identity), or named (PPRs linked to public
Personentry). The current model only supports named participation. - REQ-PPR-14: ZKP-Compatible Reputation Sharing: The reputation summary derived from PPRs must be ZKP-compatible, allowing agents to produce proofs of the form "I have at least N claims of type T" without revealing the counterparties, timestamps, or raw scores. This is a prerequisite for privacy-preserving meritocracy — governance access based on contribution without requiring surveillance.
- REQ-PPR-15: Cross-Network Reputation Export: The
ReputationSummarymust be exportable as aPortableCredential(seeREQ-AGENT-12), signed by a Primary Accountable Agent and countersigned by the claim owner, verifiable by receiving networks. Without portability, contribution history cannot flow across organisational boundaries, blocking growth of the P2P ecosystem.
7.5 Source stewardship receipts (Conditional Post-MVP Profile)
Status: Applies only to Source-enabled applications. Uses the existing 16-category PPR taxonomy; Source interactions do not introduce a global reputation aggregator. Stewardship participation remains user-sovereign private entries.
Source-NDO stewardship emphasises these PPR categories (source-ndo-requirements.md §7):
| Category | Source-NDO use |
|---|---|
ResourceCreation | Registration of a new Source-NDO and initial condition assessment |
ValidationActivity | Monitoring submission, condition assessment, governance interpretation |
RuleCompliance | Compliance with extraction quotas, discharge limits, monitoring obligations |
MaintenanceCommitmentAccepted / MaintenanceFulfillmentCompleted | Restoration commitments (reforestation, remediation, riparian repair) |
DisputeResolutionParticipation | Disputes over condition assessment or access affordances |
GoodFaithTransfer | Stewardship succession — transfer of steward obligations |
- REQ-PPR-16: Stewardship PPR Eligibility: Stewardship participation on Source-NDOs (monitoring, restoration, governance interpretation, rule compliance) SHALL generate bilateral PPRs using the existing private-entry model, enabling stewards to accumulate governance standing through contribution to Source health without exposing individual interaction history by default
8. Security & Access Control
8.1 Capability-Based Security
- REQ-SEC-01: Capability Tokens: Use capability tokens to manage access rights (general for Simple Agents, restricted for Accountable Agents)
- REQ-SEC-02: Role-Based Access: Economic Processes enforce role-based access control with validated credentials
- REQ-SEC-03: Cross-Zome Validation: Maintain transactional integrity across zome boundaries
8.2 Privacy Architecture
- REQ-SEC-04: Private Identity: Personal identification information stored as Holochain private entries
- REQ-SEC-05: Private Receipts: Participation receipts stored privately while enabling reputation derivation
- REQ-SEC-06: Selective Disclosure: Agents control what private information to share and with whom. Post-MVP note: sensitive ecological data on Source-NDOs (endangered species locations, sacred sites) follows the same capability-grant model as
PrivatePersonData(REQ-SOURCE-GOV-08)
8.3 Network Security
- REQ-SEC-07: Membrane Validation: DNA membrane controls network entry (permissionless for PoC with validation hooks)
- REQ-SEC-08: Dispute Resolution: Edge-based dispute resolution involving recent interaction partners
- REQ-SEC-09: Reputation Protection: False claims and end-of-life abuse severely impact Agent reputation
9. Technical Architecture Requirements
9.1 Zome Structure
The hApp must be structured with three zomes. Source support, where enabled, SHALL be added as profile-specific modules within these zomes rather than imposed on every application:
zome_person: Agent identity, roles, reputation, and private data management. Source-enabled profile only:Stewardfunctional role (§4.6)zome_resource: Resource specifications, economic resources, and process management (pure data model). Source-enabled profile only:SourceProfile, Source coupling links, and Source-NDO creation extending Layer 0 (§4.6)zome_governance: Validation, commitments, claims, and PPR issuance. Source-enabled profile only: Source-as-provider/receiver onEconomicEventand adaptive Source governance evaluation (§6.6)
9.2 ValueFlows Compliance
- REQ-ARCH-01: REA Model: Implement the Agent–Resource–Event pattern with Economic Processes. Conditional post-MVP extension: Source-enabled applications recognise Source as a third flow endpoint (
vf:Source) so boundary events on generative systems are first-class economic records; other applications remain complete with Agent and Resource (REQ-SOURCE-APP-02, REQ-SOURCE-ONT-01) - REQ-ARCH-02: Standard Actions: Support all relevant ValueFlows actions with nondominium-specific extensions. Source-enabled profile only: boundary events use extraction, loading, non-consumptive use, and regeneration (
raiseon a Source) with Sources as provider or receiver — see REQ-SOURCE-EVENT-* and §5.3 - REQ-ARCH-03: Multi-Layer Ontology: Support Knowledge, Plan, and Observation levels. Source-enabled profile only: Layer 0 =
NondominiumIdentity+SourceProfile; Layer 1 =SourceSpecification; Layer 2 = boundary events, commitments, claims, PPRs (source-ndo-requirements.md§6)
9.3 Modular Governance Architecture
REQ-ARCH-07: Modular Governance: The resource zome operates as a pure data model, while the governance zome operates as a state transition operator. This separation enables independent evolution of data structures and governance rules. Conditional post-MVP note: the Source profile extends the operator with an adaptive ecological loop; the base operator SHALL NOT depend on Source types or require Source configuration.
Business Benefits:
- Swappable Governance: Governance rules can be updated without modifying resource data structures
- Independent Evolution: Data model and governance logic can evolve separately
- Clear Separation of Concerns: Data management separated from business logic enforcement
- Testability: Governance logic can be tested independently of data management
REQ-ARCH-08: Swappable Governance: Governance rules and validation logic must be modifiable without changing the resource data model. Different governance schemes can be applied to the same resource types.
Business Value:
- Future-Proof: System can adapt to new governance requirements without data migration
- Multi-Tenancy: Different governance rules can be applied in different contexts
- Experimentation: New governance approaches can be tested without disrupting existing data
REQ-ARCH-09: Cross-Zome Interface: Well-defined interfaces between resource and governance zomes must support all state transitions while maintaining clear separation of responsibilities.
Interface Requirements:
- State Transition Requests: Resource zome requests state changes from governance zome
- Governance Decisions: Governance zome provides validation and new state decisions
- Event Generation: All state changes must generate corresponding economic events
- Audit Trail: Complete history of governance decisions and state changes
REQ-ARCH-10: Event-Driven State Changes: All resource state changes must generate corresponding economic events to maintain complete ValueFlows compliance and audit trails. Post-MVP note: Source boundary events (extraction, loading, regeneration) and governance-validated SourceProfile indicator updates are economic events anchored to the Source Layer 0 hash (REQ-SOURCE-GOV-06, REQ-ARCH-12).
Event Requirements:
- Complete History: Every state transition must be recorded as an economic event
- Governance Context: Events must include governance decision context
- ValueFlows Compliance: Events must follow ValueFlows standard patterns
- Reputation Integration: Events must support PPR generation for reputation tracking
9.4 Data Integrity
- REQ-ARCH-04: Entry Validation: Comprehensive validation logic in integrity zomes
- REQ-ARCH-05: Link Management: Proper linking between related entries across zomes
- REQ-ARCH-06: State Management: Resource and process state tracking with proper transitions
9.5 Source flow endpoints (Conditional Post-MVP Profile)
These requirements apply only when Source support is enabled. An application satisfying Agent/Resource use cases SHALL NOT need to implement or surface Source endpoints.
- REQ-ARCH-11: vf:Source Extension: A Source-enabled economic event model SHALL support
vf:Sourceas a typed flow endpoint role, enablingEconomicEvententries where a Source is provider (extraction, non-consumptive use) or receiver (loading, pollution) without attributing agency to the Source or ownership viaprimaryAccountable(REQ-SOURCE-ONT-01, REQ-SOURCE-EVENT-01) - REQ-ARCH-12: Source Event Ledger: Boundary events on a Source SHALL anchor to the Source's permanent Layer 0
NondominiumIdentityhash, enabling queryable history of extraction, loading, restoration, and regime-relevant use independent ofEconomicResourcecustody chains (REQ-SOURCE-GOV-06) - REQ-ARCH-13: Source Condition Updates: Updates to
SourceProfileindicators (current_stock,assimilation_capacity,regime_state, etc.) from boundary events SHALL be governance-validated state transitions, not direct writes by extracting or discharging agents (REQ-SOURCE-EVENT-02)
10. Future Enhancements
Phase 2 Requirements
- Advanced governance rule engines with conditional logic
- Automated validation workflows and smart contracts
- Enhanced dispute resolution mechanisms
- Cross-network resource sharing protocols
Phase 3 Requirements
- Integration with external governance systems
- Advanced reputation algorithms and trust networks
- Scalable validation schemes for large networks
- Economic incentive mechanisms and value accounting
- Source-NDO (optional application profile): For applications governing generative systems only —
SourceProfile,vf:Sourceboundary events, adaptive stewardship, and cross-DNA source hierarchies (§4.6, §6.6;implementation_plan.md§12.7)
11. Future Development: Architecture Variants for P2P and Organizational Contexts
11.1 Context Overview
As Nondominium evolves beyond proof-of-concept, two distinct deployment contexts emerge:
- Pure P2P Context: Individual humans directly using Nondominium for peer-to-peer resource sharing
- Organizational Context: Organizations (using ERPs or web platforms like Tiki) accessing Nondominium through bridge services
While the core ValueFlows logic and resource model remain consistent, the governance, identity, and security layers require significant architectural adaptations to serve both contexts effectively.
11.2 Identity & Delegation Requirements
Pure P2P Context
- REQ-FUT-P2P-ID-01: Support direct 1:1 mapping between human individuals and Holochain agent keys
- REQ-FUT-P2P-ID-02: Enable personal device-based key management with biometric or password protection
- REQ-FUT-P2P-ID-03: Support direct agency where the individual is the sole signer and decision-maker
Organizational Context
- REQ-FUT-ORG-ID-01: Support organizational agent identities representing legal entities (e.g., "Acme Corp")
- REQ-FUT-ORG-ID-02: Implement delegation pattern where employee keys can sign on behalf of organizational agents
- REQ-FUT-ORG-ID-03: Support scoped delegations with specific capabilities (e.g., "Transport only", "Use up to $1000 value")
- REQ-FUT-ORG-ID-04: Support time-limited delegations with automatic expiry
- REQ-FUT-ORG-ID-05: Enable immediate delegation revocation (e.g., when employee leaves) without changing organizational identity
- REQ-FUT-ORG-ID-06: Track which delegate performed which action for internal organizational audit
- REQ-FUT-ORG-ID-07: Support delegation hierarchies (e.g., manager delegates to team lead, who delegates to employees)
11.3 Reputation & Accountability Requirements
Pure P2P Context
- REQ-FUT-P2P-REP-01: All reputation (PPRs) accrues directly to the individual agent
- REQ-FUT-P2P-REP-02: Support full reputation portability across contexts and networks
- REQ-FUT-P2P-REP-03: New users start with zero reputation and build it through transactions
Organizational Context
- REQ-FUT-ORG-REP-01: External reputation accrues to the organizational agent, not individual delegates
- REQ-FUT-ORG-REP-02: Support internal attribution linking PPRs to specific delegates (hashed/private)
- REQ-FUT-ORG-REP-03: Enable organizational reputation inheritance for new delegates
- REQ-FUT-ORG-REP-04: Distinguish between organizational performance and individual delegate performance
- REQ-FUT-ORG-REP-05: Support aggregation of delegate performance into organizational reputation metrics
- REQ-FUT-ORG-REP-06: Maintain privacy of internal organizational structure while supporting accountability
11.4 Governance & Decision-Making Requirements
Pure P2P Context
- REQ-FUT-P2P-GOV-01: Support ad-hoc, autonomous decision-making by individuals
- REQ-FUT-P2P-GOV-02: Enable social negotiation of resource access terms
- REQ-FUT-P2P-GOV-03: Support simple template-based governance rules
Organizational Context
- REQ-FUT-ORG-GOV-01: Support policy-driven, automated decision-making based on organizational rules
- REQ-FUT-ORG-GOV-02: Enable automated approval of resource requests based on criteria (e.g., credit score thresholds)
- REQ-FUT-ORG-GOV-03: Support multi-signature requirements for high-value transactions
- REQ-FUT-ORG-GOV-04: Enable threshold-based governance (e.g., 2-of-3 delegates must approve)
- REQ-FUT-ORG-GOV-05: Support integration with organizational policy engines
- REQ-FUT-ORG-GOV-06: Enable organizational administrators to configure governance rules without code changes
11.5 Custody & Ownership Requirements
Pure P2P Context
- REQ-FUT-P2P-OWN-01: Support convergent custody and ownership (same person)
- REQ-FUT-P2P-OWN-02: Handle temporary custody transfers (lending) and permanent ownership transfers (selling/giving)
- REQ-FUT-P2P-OWN-03: Simple custody validation based on physical possession
Organizational Context
- REQ-FUT-ORG-OWN-01: Support divergent custody and ownership (organization owns, employee holds custody)
- REQ-FUT-ORG-OWN-02: Track internal organizational custody transfers without triggering ownership change events
- REQ-FUT-ORG-OWN-03: Support location tracking for organizational resources
- REQ-FUT-ORG-OWN-04: Enable attachment of legal contracts (hashed PDFs) to commitments and events
- REQ-FUT-ORG-OWN-05: Distinguish between internal organizational moves and external transfers
- REQ-FUT-ORG-OWN-06: Support organizational inventory reconciliation with Nondominium state
11.6 Device & Session Management Requirements
Pure P2P Context
- REQ-FUT-P2P-DEV-01: Support personal, single-user devices
- REQ-FUT-P2P-DEV-02: Simple biometric or password-based security
- REQ-FUT-P2P-DEV-03: Keys stored securely on personal devices
- REQ-FUT-P2P-DEV-04: Support standard consumer mobile platforms (iOS, Android)
Organizational Context
- REQ-FUT-ORG-DEV-01: Support shared devices (e.g., warehouse tablets used by multiple employees)
- REQ-FUT-ORG-DEV-02: Enable rapid delegate login/logout on shared devices
- REQ-FUT-ORG-DEV-03: Support BYOD (Bring Your Own Device) with organizational key management
- REQ-FUT-ORG-DEV-04: Integrate with organizational IAM/SSO systems (OAuth, SAML)
- REQ-FUT-ORG-DEV-05: Map organizational authentication tokens to Holochain capability tokens
- REQ-FUT-ORG-DEV-06: Support enterprise device management policies
- REQ-FUT-ORG-DEV-07: Enable remote device key revocation for security
11.7 Bridge Integration Requirements
Organizational Context (ERP/Web Platform Bridges)
- REQ-FUT-ORG-BRG-01: Support RESTful bridge services using Node.js and
@holochain/client - REQ-FUT-ORG-BRG-02: Enable bidirectional synchronization between organizational systems and Nondominium
- REQ-FUT-ORG-BRG-03: Support real-time signal forwarding from Holochain to organizational systems
- REQ-FUT-ORG-BRG-04: Enable batch operations for efficiency in organizational contexts
- REQ-FUT-ORG-BRG-05: Support caching strategies for frequently accessed organizational data
- REQ-FUT-ORG-BRG-06: Enable webhook-based event notification to organizational systems
- REQ-FUT-ORG-BRG-07: Support organizational resource publishing from ERP inventory systems
- REQ-FUT-ORG-BRG-08: Enable organizational authentication mapping (OAuth/session tokens to agent keys)
- REQ-FUT-ORG-BRG-09: Support deployment via Docker containerization for organizational IT environments
- REQ-FUT-ORG-BRG-10: Enable organizational administrators to monitor bridge health and performance
11.8 Architecture Modularity Requirements
- REQ-FUT-ARCH-01: Design modular architecture supporting both P2P and organizational contexts
- REQ-FUT-ARCH-02: Core ValueFlows and resource model must remain context-agnostic. Post-MVP note: Source is an optional extension profile that must not burden organizational bridges or applications that need only Agent/Resource semantics; when enabled, extracted units remain
EconomicResourceand generative systems remain Source-NDOs - REQ-FUT-ARCH-03: Governance and identity layers must support pluggable implementations
- REQ-FUT-ARCH-04: Support seamless interoperability between P2P agents and organizational agents
- REQ-FUT-ARCH-05: Enable organizations to act as agents in the P2P network with equal standing
- REQ-FUT-ARCH-06: Support mixed-mode transactions (P2P individual borrowing from organization)
- REQ-FUT-ARCH-07: Maintain unified reputation and trust framework across contexts
11.9 Privacy & Compliance Requirements
Pure P2P Context
- REQ-FUT-P2P-PRIV-01: Minimize data collection to essential transaction information
- REQ-FUT-P2P-PRIV-02: User controls all personal data disclosure
- REQ-FUT-P2P-PRIV-03: Support pseudonymous participation
Organizational Context
- REQ-FUT-ORG-PRIV-01: Support organizational data retention and audit requirements
- REQ-FUT-ORG-PRIV-02: Enable compliance with organizational security policies
- REQ-FUT-ORG-PRIV-03: Support organizational data export for regulatory compliance
- REQ-FUT-ORG-PRIV-04: Maintain separation between organizational data and public DHT data
- REQ-FUT-ORG-PRIV-05: Support organizational right-to-delete while preserving transaction integrity
11.10 Implementation Priority
Phase 1 (Current): Pure P2P implementation with direct agent-person mapping
Phase 2 (Future Development):
- Delegation pattern implementation
- Organizational reputation aggregation
- Basic bridge service architecture
Phase 3 (Future Development):
- Advanced multi-signature governance
- Enterprise device and session management
- Full IAM/SSO integration
- Production-ready organizational bridges
12. Success Criteria
The nondominium system is successful when:
- Resources remain organization-agnostic and capture-resistant
- Governance is transparent, fair, and community-driven
- Reputation system enables trust without central authority
- Economic Processes support real-world sharing scenarios
- System scales while maintaining decentralized principles
- Privacy is preserved while enabling accountability
- (Conditional post-MVP) Applications whose domain includes generative ecological or knowledge commons can enable Source-NDO so boundary events are visible and stewardship adapts, while Project and mature-resource mutualisation applications remain simple and complete with Agent and Resource primitives
Agent: Ontology, Implementation, and Forward Map
Type: Archive / Knowledge Base Document
Created: 2026-03-11
Relates to: governance.md, resources.md, ndo_prima_materia.md, unyt-integration.md, flowsta-integration.md
Sources: MVP code (zome_person, zome_gouvernance PPR/validation), post-MVP design, OVN wiki — Agent, Identity, Individual profile, Organizational structure
Purpose
This document maps the three states of Agent understanding in the Nondominium / NDO project:
- Implemented — what exists today in the MVP
zome_personand governance-related agent handling - Planned — what is designed in post-MVP documents for agent evolution
- Remaining — what the OVN wiki's 15 years of commons-based peer production practice contains that NDO does not yet plan for
The goal is to ensure the generic NDO agent model is as complete and principled as the OVN ontology, enabling diverse applications (resource-sharing, digital commons, open science, cooperative production) to configure agent behaviour through data, not custom code.
1. Conceptual Foundation: What is an Agent in P2P Complexity Economics?
1.1 Agent vs User — A Critical Distinction
The OVN wiki is unequivocal: "In a p2p context it is not advised to reduce agents or affiliates to users." The word user is appropriate for centralised platforms (Facebook, Uber) where participants have no control over the platform, interact on terms set by the owner, and provide data in exchange for access. An agent, by contrast, is an entity with agency — the capacity to plan and take actions, to own its own data, and to participate in defining the rules of the system it operates within.
This is not merely semantic. The data model follows the ontology: a "user" has an account on a server that another party controls. An agent has a cryptographic key pair that they control, a source chain of their own actions that only they can append to, and relationships with other agents that are maintained on a shared DHT — not a shared database controlled by an operator. Holochain is the first infrastructure natively designed for agent-centric data models. The NDO must take this seriously from the ground up.
1.2 The Agent Type Spectrum

MVP implements Individual only. Post-MVP targets: Collective (working groups, N-of-M signing), Project (AgentContext + linked NondominiumIdentity digital twin), Network (OVN as agent), Bot (capabilities declared, operator accountable). Governance complexity increases rightward.
The OVN wiki defines agents as: "anything that can perform an action. Has agency, i.e. can also plan to take actions. Agents can be individuals, groups, projects, networks. Agents can also be bots, machines (IoT)."
This spectrum is essential. In a P2P complexity economics framework, the system must model:
- Individual agents: human participants, each with a source chain
- Collective agents: groups, working groups, communities — entities with collective agency
- Project/venture agents: temporary organised efforts with their own goals and resources
- Network agents: larger-scale communities (an OVN as a whole is also an agent in its ecosystem)
- Artificial agents: bots, AI models, IoT devices — increasingly significant actors in the commons
The current NDO models only individual agents. This is a significant constraint for the generic NDO project, which aims to support Sensorica-style open value networks where ventures, networks, and partner organisations are themselves agents in economic processes.
1.3 Individual vs Person — The Two Layers of Agent Identity

Individual-type identity: cryptographic key pair, permissionless entry, no disclosure required — like a bus ticket. Person-type identity: created on first DHT-active action, role credentials, PPR history, enables governance and custodianship — like a medical credential. The progression is earned through participation, not granted.
The OVN wiki makes a distinction of deep philosophical and technical importance:
"An individual is the physical you. You exist and therefore you have access to certain things. A person is a representation of the physical you, it is an agent in a socio/economic context."
In practical terms:
- Individual-type identity: exists by virtue of holding a cryptographic key pair. Permissionless access. No disclosure required. Like Bitcoin: you only need keys to transact. This is the foundation of the NDO's permissionless entry model.
- Person-type identity: requires reputation, credentials, or demonstrated capabilities earned through participation. Required for sensitive processes: governance participation, custodianship, specialised service provision.
This two-layer model is not bureaucratic gatekeeping — it is a precise answer to the information-theoretic question: "what does this process require to function well?" Taking the bus requires a ticket, not identification. Performing surgery requires credentials. The NDO must distinguish which processes are ticket-level (individual-type) and which require person-type identity, and build the appropriate mechanisms for each.
In complexity economics terms: forcing all interactions through person-type identity is a high information-overhead solution applied to low-information-need situations. It reduces participation, increases friction, and creates centralisation risks (who issues the credentials?). The OVN model, and therefore the NDO model, reserves person-type identity for the specific processes that genuinely need it.
1.4 Identity ≠ Credentials
The OVN wiki offers a clarifying thought experiment: "When you take the bus you don't need to tell the driver all about yourself before boarding, you just show your ticket, which is the credential required to access the transportation service."
Credentials are context-specific access tokens derived from past actions or present conditions. They are not identity. You can prove you can safely use a 3D printer (credential) without revealing who you are (identity). This distinction, made precise through zero-knowledge proof technology, is the foundation for privacy-preserving participation in P2P systems.
The implications for NDO agent design: the system should be designed so that agents prove what they can do through minimally-revealing credentials, not by revealing who they are through full identity disclosure. This is currently only partially implemented: the PPR system generates verifiable contribution records (a form of capability credential), but there is no ZKP layer to share them without revealing the underlying data.
1.5 Agent as Network Node: Social Capital and Interconnection
The OVN wiki's individual profile description captures a dimension of agents often overlooked in technical implementations: an agent's profile includes "social relations (connections with other agents), which can be seen as social capital, may be shared in context / processes, part of the wealth structure of a network" and "network affiliations."
Social capital — the value embedded in relationships and network position — is an intangible resource that the NDO system should make legible, not obscure. In complexity economics, information flows through social networks, and an agent's connectivity is a measure of their access to collective intelligence. The individual profile should capture relational wealth, not just transactional history.
1.6 The Long Tail of Agent Engagement
From the governance archive, the OVN operates with a 1-9-90 engagement distribution: 1% core (entrepreneurial, high commitment), 9% active contributors, 90% occasional participants. This is not a design flaw — it is universal in open networks. The agent model must be designed for this reality.
An agent system designed only for the 1% (assuming high engagement, rich profiles, continuous participation) will exclude the 99% who should still be able to participate meaningfully at their actual engagement level. The affiliation model (unaffiliated → close → active → core) is the OVN's answer to this: design for the full spectrum, not just the core.
2. Current Implementation (MVP)
2.0 Three-Level Identity Model (UI)
The MVP UI introduces three distinct identity layers that reflect the Lobby → Group → NDO hierarchy defined in ui_design.md. These layers are intentionally separate: they allow progressive disclosure of personal information and defer DHT costs until the agent acts.
Level 1 — Lobby (UI-only, localStorage)
LobbyUserProfile is the outermost, lightest identity layer. It is never written to the DHT.
| Field | Required | Notes |
|---|---|---|
nickname | Yes | Displayed in the Lobby profile bar and Group profile |
realName | No | Optional; user controls whether it is shared in groups |
bio | No | Optional |
email | No | Optional |
phone | No | Optional |
address | No | Optional |
- Stored in
localStorageunder the keyndo_lobby_profile_v1. - Written to
app.context.lobbyUserProfile(Svelte$state) on every page load. - Created via
UserProfileForm.svelte(modal on first launch; page-mode for editing). - Exists before any
PersonDHT entry is created. An agent can browse the Lobby anonymously (no profile) or under a pseudonym (nickname only).
Level 2 — Group (GroupMemberProfile, localStorage presentation + Group DNA membership)
Groups are DNA-backed: each group is a cloned Group cell (clone_cell with unique network_seed). GroupProfile and membership live on the group DHT via zome_group (create_group, join_group, get_group_members). The Lobby DNA announces groups for discovery (announce_group).
GroupMemberProfile is a per-group presentation choice derived from LobbyUserProfile. It controls how much of the Lobby profile the agent consents to show other group members. It is not the same as DHT membership — it is a UI-only disclosure layer.
| Field | Type | Notes |
|---|---|---|
isAnonymous | boolean | If true, the agent appears only by pseudonym |
shownFields | (keyof LobbyUserProfile)[] | Fields from LobbyUserProfile the agent explicitly consents to share |
- Stored in
localStorageunderndo_group_profiles_v1, keyed by groupnetwork_seed(not inGroupProfileentry). - Prompted via
GroupProfileModal.svelteon first entry to each group. - NDO-level pseudonymity: an agent may browse the Lobby with no profile, join groups under a nickname-only presentation (Level 2 anonymous), and defer creating a
Personentry until a DHT-active economic action (Level 3).
Level 3 — NDO / Agent (DHT, zome_person)
Person is the public, on-chain agent profile. It is created when the agent performs their first DHT-active action — creating an NDO, joining an NDO, or accepting a commitment. This layer corresponds to the "person-type identity" described in §1.3.
- Written to the NDO's DHT via
create_personinzome_person. - Linked to the agent's
AgentPubKeythrough Holochain's source chain. - Required for governance participation, custodianship, and specialised service provision.
- Discoverable by other agents via the
all_personsanchor.
This three-level model enables permissionless browsing (Level 1 not required), group participation under a pseudonym (Level 2), and full economic participation (Level 3), without conflating disclosure requirements across contexts.
Cross-reference:
ui_design.mdMVP section describes the intended UI flow. Implementation lives inapp.context.svelte.ts(lobbyUserProfile),lobby.service.ts(Group DNA +saveGroupMemberProfile),group.service.ts(getMembers, SoftLinks),UserProfileForm.svelte,GroupProfileModal.svelte, andSidebar.svelte.
2.1 The Two-Layer Identity Model in Code
The NDO MVP implements the individual/person distinction at the data model level:
Individual layer — the Holochain AgentPubKey:
- Cryptographic key pair generated locally by the agent
- Source chain is agent-owned and agent-controlled
- Permissionless network entry (
validate_agent_joiningreturnsValidateCallbackResult::Validunconditionally) - No disclosure required for basic read access to the DHT
Person layer — the Person entry (public) + PrivatePersonData entry (private):
#![allow(unused)] fn main() { pub struct Person { pub name: String, pub avatar_url: Option<String>, pub bio: Option<String>, } pub struct PrivatePersonData { pub legal_name: String, pub email: String, pub phone: Option<String>, pub address: Option<String>, pub emergency_contact: Option<String>, pub time_zone: Option<String>, pub location: Option<String>, } }
Person entries are the public identity anchor — discoverable via the AllPersons anchor, versioned (via PersonUpdates links), and permanently immutable once created (validate_delete_person returns Invalid). They cannot be deleted: consistent with the OVN principle that contribution records and identity anchors must be permanent.
PrivatePersonData is a Holochain private entry stored only on the agent's source chain, accessible to others only through explicit capability grants.
2.2 The Capability-Based Private Data System
The MVP implements a sophisticated field-level capability sharing system for private data:
PrivateDataCapabilityMetadata: tracks each capability grant issued by an agent:
granted_to,granted_by,fields_allowed(subset of: email, phone, location, time_zone, emergency_contact, address)context: why the access was grantedexpires_atwith a hard-coded 30-day maximum durationcap_secret: stored locally for revocation
RevokedGrantMarker: explicit revocation record (important because Holochain native capability revocation is silent — this creates an auditable revocation trail)
FilteredPrivateData: the view of private data after capability filtering — what the other agent actually sees given their access level
This system implements the OVN principle of "absolute privacy by default" with agent-controlled selective disclosure. The legal_name field is notably never shared (not in allowed_fields), preserving the individual/person separation at the field level.
2.3 The Role System — Four Capability Levels
The MVP implements a six-role system across two dimensions:
Governance tiers (progressive trust levels):
SimpleAgent(member) — permissionless entry; basic participationAccountableAgent(coordination) — validated private identity; can validate others; can initiate process commitmentsPrimaryAccountableAgent(governance) — highest trust; can promote agents; can approve governance decisions
Functional service roles (validated competencies):
Transport,Repair,Storage(stewardship level)
Capability level hierarchy: member < stewardship < coordination < governance
The promotion workflow is a cross-zome interaction:
SimpleAgent → Accountable:
1. Agent calls request_role_promotion("Accountable Agent")
2. System validates private data exists (legal_name, email required)
3. Cross-zome call: governance.validate_agent_for_promotion()
4. Accountable/Primary agent approves: approve_role_promotion()
5. Cross-zome call: governance.validate_agent_identity() (with first_resource_hash)
6. Role entry created and linked to Person
Accountable → Primary:
1. Requires PPR milestones (governance_claims in ReputationSummary)
2. Specialized role validation for functional roles
3. Governance-level approver required
The promotion workflow correctly implements the OVN's "access to governance is earned through contribution" principle. Simple agents exist (permissionless) but cannot act as validators or custodians without establishing person-type identity.
2.4 Multi-Device Agent Architecture
The MVP's most technically sophisticated agent-layer contribution: a clean many-to-many Agent ↔ Person relationship model.
AgentPersonRelationship: explicitly models the link between a cryptographic key (AgentPubKey) and a persistent identity (Person hash):
relationship_type:Primary(initial device),Secondary(additional devices),Device(dedicated device agents)
Device entry: tracked per physical device with device_id, device_name, device_type (mobile/desktop/tablet/web/server), registration, last-active timestamps, and revocable DeviceStatus.
Bidirectional links: AgentToPerson (key to identity) and PersonToAgents (identity to all associated keys) enable multi-device coordination without leaking any of the devices' keys.
This is a forward-looking implementation: one person may use Nondominium from a phone, a desktop, and a shared lab computer. Each device has its own key. All keys are controlled by the same person. The Person is the persistent socio-economic identity; AgentPubKeys are the session-level cryptographic instruments.
2.5 What the MVP Does Well
- The individual/person dual layer correctly implements OVN's identity model: permissionless individual access + earned person-type credentials
- Permanent identity anchors (Person entries cannot be deleted): enforces the OVN principle that contribution history cannot be retroactively erased
- Field-level capability grants with 30-day expiry and explicit revocation are privacy-first by design, consistent with the OVN's "absolute privacy by default" principle
- Multi-device architecture is pragmatic and technically sound — most systems ignore this, resulting in brittle single-key identities
- The cross-zome promotion workflow is correctly designed: role assignment requires governance validation, not just peer-to-peer agreement
- Functional roles as validated competencies (not just trust levels) introduce the credential concept correctly, even if without portability
2.6 Known Gaps in the MVP
| Gap | OVN relevance | Impact |
|---|---|---|
| Only individual agents | OVN: groups, projects, networks, bots are also agents | Cannot model collective agency, AI participants, or network-level actors |
| Person profile is minimal (name/avatar/bio) | OVN: profile contains contributions, roles, artifacts, social relations, affiliations | Cannot produce a rich agent profile for governance or contribution accounting |
| No contribution aggregation in profile | OVN: profile is "window into the past" and "predictive tool" | ReputationSummary is separate; not discoverable as part of agent profile |
| No credential portability | OVN: profile must be portable across networks | Roles and PPRs are local to this DNA instance |
| Roles are closed (6 predefined) | OVN: roles emerge from community needs | Communities cannot define their own role taxonomies |
| No zero-knowledge proofs | OVN: "prove capability without providing access to data" | Agents must reveal private data to prove eligibility |
| No affiliation types | OVN: unaffiliated / close / active / core / inactive spectrum | Cannot model the long tail of engagement; all non-members look the same |
| No social graph | OVN: social relations are part of profile / social capital | Cannot surface network wealth or organisational reach |
| No agent type taxonomy | OVN: individual, group, project, network, bot | Everything is modeled as an individual human |
| Promotion is partially stubbed | request_role_promotion returns a placeholder hash | Promotion requests cannot be queried or tracked |
| Legal_name is never shared | Appropriate for most use cases but inflexible | Cannot support cases where legal identity sharing is required (e.g., insurance, legal agreements) |
| No cross-app identity or DID | OVN: portable profile across networks; agents as bridge nodes between OVNs | Agents cannot prove they are the same person on another Holochain app; reputation and roles stay local to this DNA. Planned: FlowstaIdentity CapabilitySlot on Person hash, W3C DID via Flowsta agent linking (ndo_prima_materia.md Section 6.7) |
| No deterministic key recovery | Permanent Person and PPR model assume long-lived signing keys | Device loss can strand the agent from their source chain and private entries. Planned: Flowsta Vault BIP39 recovery, auto-backup, CAL-compliant export (ndo_prima_materia.md Section 6.7) |
3. Post-MVP Roadmap
3.1 Collective Agents and Their Digital Twins

Agent face: AgentContext with member agents, acts as provider/receiver in economic events, accumulates PPRs. Resource face: NondominiumIdentity — permanent anchor, lifecycle, specification, governance rules. The Project(ActionHash) in AgentEntityType bridges them. Neither face replaces the other — they are ontologically distinct.
A collective entity — a project-as-organisation, a cooperative, an open value network — has two distinct ontological faces in the Nondominium model. These faces are different roles the same real-world entity plays, and they must not be collapsed into one.
The agent face is the AgentContext carrying the relevant AgentEntityType variant (Collective, Project, Network). Through this face the collective participates in economic events as provider or receiver, holds commitments, accumulates reputation, and may be the primary_accountable on shared resources. Collective agents of this kind are composed agents or group agents: their actions may require N-of-M authorisation from individual member agents (multi-signature pattern — forward design, post-MVP). This is how REA-ontology-compliant collective economic agency works — it is distinct from the physical thing the collective creates or represents.
The resource face is the NondominiumIdentity — the collective's digital twin as a Nondominium Object. NDOs are Resources, and the resource face of a collective carries its permanent identity anchor, property regime, lifecycle stage, specification (what the collective IS — its mission, assets, rules of participation), and governance rules (how agents interact with it). The resource face does not have agency; it records which agents are associated and under what terms.
The ActionHash inside AgentEntityType::Project(ActionHash) and AgentEntityType::Network(ActionHash) links the agent face to the resource face: it points to the NondominiumIdentity that is the collective's digital twin. The two faces are thus connected by this hash reference.
| Agent face | Resource face | |
|---|---|---|
| Entry type | AgentContext | NondominiumIdentity |
| Role in economic events | Provider / receiver | — (no agency) |
| Accumulates | Reputation (PPRs, EconomicEvents) | Contribution records (individual agents who contributed) |
| Can hold custody | Yes — via AgentContext as primary_accountable | No |
| Has lifecycle/spec/governance | — | Yes — LifecycleStage, ResourceSpecification, GovernanceRules |
| Permanent / immutable | No | Yes — NondominiumIdentity is permanent |
An individual agent can hold a PersonRole in both their own profile and in a collective's governance. Cross-agent capability grants enable a collective's AgentContext to act on behalf of its members (with appropriate authorisation).
A Collective(String) agent (e.g. a working group or committee) may not yet have an associated NDO — its agent face exists independently of any resource face. Attaching a resource face (creating an associated NondominiumIdentity) is optional and done when the collective's digital representation as a Resource becomes useful.
When a collective does have an associated NDO, the NDO's three-layer structure (Identity + Specification + Process) applies to the collective's resource face — not to the collective as an agent:
- NDO Identity layer = the collective's permanent identity anchor (name, regime, nature, creation record)
- NDO Specification layer = the collective's documented form (mission, assets, governance rules for how agents interact with it)
- NDO Process layer = the economic activity around the collective as a resource (contributions, agreements, events involving the collective-as-resource)
The LifecycleStage at registration can be any non-suspend, non-terminal stage (Ideation through Active) so the resource face can anchor an already mature or in-use NDO (e.g. a stable shared tool), not only an emerging project. Profiles or wizards may suggest a narrower subset for specific organisation types — for example a short-lived working group often stays in emergence — but that is UX guidance, not an ontology constraint on NondominiumIdentity. Hibernating, Deprecated, and EndOfLife remain transition-only after creation. The PropertyRegime and ResourceNature fields on NondominiumIdentity remain applicable to the collective's resource face: a working group's shared knowledge base is a Commons/Digital NDO; a collectively owned workshop maps to a Collective or Pool physical NDO in the UI's seven-regime model.
3.2 CapabilitySlot on Agent Identity
The NDO CapabilitySlot surface (from ndo_prima_materia.md) can be extended to agent identities: an agent's Person entry hash becomes a stigmergic attachment point for external applications — credential wallets, reputation oracles, DID documents, professional networks — without modifying the core Person entry. This is the agent-level equivalent of the resource-level CapabilitySlot.
Flowsta Auth (ndo_prima_materia.md Section 6.7) is the first specified implementation: a FlowstaIdentity CapabilitySlot from the Person entry hash to an IsSamePersonEntry (dual-signed attestation: NDO agent key + Flowsta Vault key), yielding a W3C DID (did:flowsta:uhCAk...) without changing the Person schema. Full architecture, two-tier identity authority, and integration phases are summarised in Section 3.5 below.
3.3 Composable Profile Aggregator
A post-MVP AgentProfile view that composes:
Person(public identity)ReputationSummary(derived from PPRs)PersonRolelist- Participation statistics (economic event counts by category)
- Capability slot attachments (external credentials, DIDs)
This view is not stored as a new entry type — it is computed from existing DHT data. But exposing it as a queryable composite is the key step toward the OVN individual profile model.
3.4 Credential Portability via Holochain Membrane Proofs
Post-MVP: a mechanism to export cryptographically signed summaries of an agent's role assignments and ReputationSummary that can be verified by other Holochain networks. This implements the OVN requirement for portable identity: a person's contribution track record in one community should be recognisable in another.
Flowsta agent linking provides a cross-app identity anchor (DID) so ReputationSummary and participation history can be attributed across Flowsta-linked apps; full PortableCredential structures (this document, Section 6.5) remain the NDO-native export path — the two are complementary (ndo_prima_materia.md Section 6.7, PPR cross-app attribution).
3.5 Flowsta Integration (flowsta-integration.md)
Decentralized identity and authentication for Holochain apps: agent linking commits IsSamePersonEntry on this DNA via flowsta-agent-linking zomes; FlowstaIdentity CapabilitySlot on the agent's Person entry hash points to that attestation. Tier 1 (Flowsta Phase 1): permissionless self-attestation (trust signal; REQ-NDO-CS-12/CS-13). Tier 2 (Flowsta Phase 3): governance can require a valid Flowsta link for sensitive transitions (e.g. PrimaryAccountableAgent promotion, high-value custody) via IdentityVerification-style rules (REQ-NDO-CS-14/CS-15). Flowsta Vault: BIP39 recovery, encrypted auto-backups, CAL-aligned export — addressing the gap between permanent Person/PPR anchors and real-world key loss. OAuth-only path (@flowsta/auth): consistent DID across web apps while the app keeps its own Holochain keys (Flowsta docs "Option 1"); Vault path ("Option 2") is the one that produces IsSamePersonEntry on the NDO DHT. See ndo_prima_materia.md Section 6.7 and Section 11.6; see also resources.md Section 3.8 for resource-ontology cross-links.
4. OVN Agent Ontology: 15 Years of Practice
4.1 Agent Type Taxonomy
The OVN wiki classifies agents into four primary types:
| Agent type | Examples | NDO support |
|---|---|---|
| Individual | Human participants, affiliates | ✅ Implemented (Person + AgentPubKey) |
| Group/Collective | Working groups, committees | ❌ Gap: no collective agent type |
| Project/Venture | An open hardware project, a design sprint | ❌ Gap: ventures are implicit in resources, not agents |
| Network | An OVN as an entity in the ecosystem | ❌ Gap: no network-level agent |
| Artificial | Bots, AI models, IoT devices | ❌ Gap: no bot/machine agent type |
In the REA model used by Sensorica, economic agents can represent:
- An individual
- A project/venture (another network or autonomous open business unit)
- Another network (cross-OVN interactions)
- A traditional organisation (partner, supplier, funder)
The NDO currently only models the individual case. For the generic NDO to support Sensorica-style operations, at minimum group/collective and project/venture agent types are needed.
Complexity economics note: The omission of collective agents is not just an inconvenience — it makes it impossible to model the actual economic events in many commons-based peer production contexts. When Sensorica licenses a sensor to a university, the economic agents are Sensorica (a network) and the university (a traditional organisation), not individual humans. Without collective agent types, the economic model is systematically misrepresented.
4.2 The Affiliation Spectrum

Five states: UnaffiliatedStranger → CloseAffiliate → ActiveAffiliate (governance gate, requires AffiliationRecord signing) → CoreAffiliate (algorithmically determined from PPR rate) → InactiveAffiliate (contribution history preserved). Re-engagement via new contributions. AffiliationState is derived from DHT data — never stored.
The OVN wiki defines five affiliation states that capture the long tail of participation:
Unaffiliated: anonymous; accesses public information only; no obligations; not known by affiliates.
Close affiliate: not yet contributed in a trackable way; known by some affiliates; can access database and some activities; no formal obligations but respects OVN's assets.
Active affiliate: has logged contributions in the NRP-CAS AND is recognised by the community; has access to OVN infrastructure, governance, and production assets; must adhere to the Benefit Redistribution Algorithm and affiliation conditions.
Core affiliate: algorithmically selected from active affiliates based on contribution + reputation; special privileges within specific projects or ventures; status is dynamic (in/out based on contribution; can expire through inactivity).
Inactive affiliate: previously contributed, currently inactive; access to some activities; can re-engage by contributing again.
Formal affiliation: becoming an active affiliate formally consists of:
- Acknowledging the Affiliate Handbook
- Acknowledging the Nondominium & Custodian agreement
- Signing the "Acknowledgement of Knowledge Commons" agreement
- Signing the Benefit Redistribution Algorithm agreement
The NDO currently has only two states: joined (has a Person entry) and not joined. There is no modelling of engagement depth, affiliation conditions, formal affiliation agreements, or the core/active/close/inactive spectrum. This means the system cannot algorithmically determine who should participate in a governance decision (active affiliates only? core affiliates? anyone with a Person entry?), cannot manage the onboarding process, and cannot track affiliation lifecycle.
4.3 The Individual Profile as Composable Aggregate
The OVN wiki defines the individual profile as "a digital environment that aggregates information and data about Agents." Key properties:
Composable: can contain roles, reputation, contributions, artifacts, social relations, network affiliations, credentials, available assets, needs/wants.
Standard format: portable across contexts.
Non-transferable: cannot be reassigned from one individual to another (analogous to soul-bound tokens). The link to the physical self must be unique.
Portable: "An individual can participate in more than one OVN simultaneously... enables the individual to transport his/her reputation and credentials from one cluster of economic activities to another."
Owner-controlled: the agent controls what is shared, with whom, for what purpose, and for how long. But crucially: some parts are write-protected — "applications can write data about contributions, roles, and reputation, which cannot be deleted by the affiliate in question." This is exactly what the NDO implements with immutable Person entries and private-but-signed PPRs. The profile owner cannot delete their contribution history, but controls what they reveal.
Predictive: "can be used as a predictive tool, to judge if a future action or relation would be beneficial."
Agency-extended: "The individual profile can even have agency in the digital world. It can be AI-enhanced to act on behalf of the real agent in some circumstances, sign contracts based on predefined rules."
The NDO currently splits what should be the individual profile across at least four separate concepts: Person, PrivatePersonData, ReputationSummary, and PersonRole. These are correct building blocks but lack the composable aggregation layer that would make the profile a genuine OVN individual profile.
4.4 Identity Architecture: SSI, DIDs, VCs, ZKP
The OVN wiki synthesises the state of the art in decentralised identity:
Self-Sovereign Identity (SSI): The individual controls their own identity data; no third party can revoke or modify it without the individual's consent. Roles in the SSI ecosystem: issuer (issues credentials), wallet (stores and provides), validator (requests and obtains), revoker.
Decentralised Identifiers (DIDs): W3C-standardised unique identifiers for individuals and organisations that are independent of any centralised registry, resolved through decentralised systems. DIDs enable "a direct, encrypted channel for p2p communication" and portability from one transport or security context to another.
Verifiable Credentials (VCs): "Sets of claims about an agent of which the provenance and immutability can be proved." ZKP-compatible: an agent can prove "I have a credential that satisfies condition X" without revealing the credential's full contents.
Soul-bound tokens: non-transferable, non-sellable reputation tokens. The OVN wiki references these as one potential mechanism for non-transferable credentials. The NDO's Person entries (non-deletable) and PPRs (bilaterally signed, private) are soul-bound-like, but not interoperable with external VC/DID ecosystems.
Portability challenge: "I can gain some credentials based on activities in one organization/context and have that, or only a part of it, being recognized in another context." This is the core portability requirement. The technical path: ZKP-based proofs from Holochain source chains that can be verified by other Holochain networks or other distributed systems.
Near-term bridge — Flowsta: Flowsta supplies W3C DIDs and dual-signed agent linking (IsSamePersonEntry on the NDO DHT, ndo_prima_materia.md Section 6.7) so the same human can be recognised across Holochain conductors without shared DNA. PrivateParticipationClaim entries remain non-transferable and bound to the local AgentPubKey; reputation summaries can nevertheless be attributed to a DID for cross-app trust — the same distinction as resources.md Section 4.6 (attribution portability is not claim transferability). REQ-NDO-AGENT-08 positions the Flowsta DID as the cross-network identity anchor for portable credentials. ZKP/VC layers remain the longer-term path for minimally revealing proofs at scale.
The identity insurance alternative: the OVN wiki cites Vinay Gupta's proposal that what P2P systems need is not reputation but restorative justice — insurance that compensates you if an agent acts in bad faith. "If I present you with proof that I am insured against bad conduct, and you trust my insurer will pay, REPUTATION is suddenly a whole bunch less important." This is a provocative alternative to the PPR approach: rather than tracking reputation to prevent bad actors, use economic backstops to make bad acting unprofitable. The NDO's Unyt Smart Agreement integration could potentially implement this pattern.
4.5 Privacy vs Network Efficiency
The OVN wiki frames this as a genuine tension with no universal solution: an agent's contribution history can improve network efficiency (matching to tasks, governance access, trust in new interactions) but also creates a privacy risk (triangulation of physical identity, de-platforming vulnerability).
The OVN wiki's resolution: "the agent must be given the choice, allow an individual profile to be formed from past activity or not, weighing the pros and cons, the benefits and the potential harm." The NDO's private-but-derivable PPR system partially implements this: agents sign PPRs (opting into accountability) but control how their ReputationSummary is shared. The gap is that there is currently no mechanism for an agent to participate partially — all PPRs follow the same model.
A more complete implementation would allow agents to choose their privacy level per interaction:
- Full anonymity: no PPRs, no reputation accumulation, no access to governance
- Pseudonymous: PPRs linked to a persistent pseudonym, not to physical identity
- Named: PPRs linked to public Person entry
This spectrum maps to the OVN's individual/person identity model: individual-level participation (anonymous), person-level participation (reputation-accumulating), and fully identified participation (legal accountability for high-trust processes).
4.6 Agent Profile and Network Wealth

An agent participating in Sensorica, a Fab Lab, and a Research Collective simultaneously is a bridge node — carrying trust, information, and potential collaboration across network boundaries. Multi-membership and cross-network reputation (via FlowstaIdentity DID) are themselves a form of network wealth.
The OVN wiki's individual profile description includes something not present in most technical systems: network affiliations as a form of organisational wealth. "The information about affiliations can be used... to assess the organic reach into other organisational contexts, beyond the immediate zone of influence of the context. This allows surfacing of a new form of network wealth, its influence or degree of connectivity with other networks within the ecosystem, provided by the number of relations extending from the context network to other networks, through agents."
An agent who participates in multiple OVNs is a bridge node — a carrier of information, trust, and potential collaboration across network boundaries. This agent's profile is not just a personal record; it is a piece of the network's connective tissue. Making this visible makes the network's resilience and reach legible.
The NDO currently has no social graph and no multi-network affiliation model. An agent is either in this network or not. The generic NDO should model the OVN's insight that agents are simultaneously nodes in multiple overlapping networks, and that this multi-membership is itself a form of value.
5. Gap Analysis
5.1 Mapped — OVN concepts implemented or planned in NDO
| OVN concept | NDO implementation | Status |
|---|---|---|
| Individual/person identity distinction | AgentPubKey (individual) + Person entry (person-type) | ✅ Implemented |
| Permissionless individual-level access | validate_agent_joining unconditional pass | ✅ Implemented |
| Owner-controlled private data with selective disclosure | PrivatePersonData + field-level capability grants | ✅ Implemented |
| Non-transferable, non-deletable identity anchor | Person entries are permanent (delete validation returns Invalid) | ✅ Implemented |
| Earned access to sensitive processes | Role promotion requiring private data validation | ✅ Implemented |
| Contribution history write-protected from owner | Bilaterally signed PPRs cannot be unilaterally deleted | ✅ Implemented |
| Multi-device support | Agent-Person many-to-many relationship model | ✅ Implemented |
| Capability expiry and explicit revocation | 30-day max grants + RevokedGrantMarker | ✅ Implemented |
| Composable profile building blocks | Person + PrivatePersonData + PersonRole + ReputationSummary | ✅ Partial (separate, not aggregated) |
| Functional role credentials | Transport / Repair / Storage validated competency roles | ✅ Implemented |
| Cross-app identity / DID (agent) | FlowstaIdentity CapabilitySlot + Flowsta agent linking (ndo_prima_materia.md Section 6.7) | 🔄 Planned (post-MVP) |
| Agent key recovery (Vault) | Flowsta Vault BIP39, auto-backup, CAL export (ndo_prima_materia.md Section 6.7) | 🔄 Planned (post-MVP) |
5.2 Partial — concepts present in OVN and partially covered in NDO
| OVN concept | NDO partial coverage | Gap |
|---|---|---|
| Affiliation spectrum | Joined (has Person) vs not joined | No close/active/core/inactive states; no affiliation conditions |
| Active affiliate = contribution + recognition | SimpleAgent → Accountable promotion is contribution-gated | Recognition is informal; no algorithmic determination of active affiliate status |
| Core affiliate = algorithmically selected | PPR-based ReputationSummary provides the data | No algorithm using PPR data to compute core affiliate status |
| Portability | Roles and PPRs are local | No export mechanism; no VC/DID interoperability yet. Planned: cross-app attribution via Flowsta DID + FlowstaIdentity slot (ndo_prima_materia.md Section 6.7); NDO-native PortableCredential export (this document, Section 6.5) remains complementary |
| Privacy vs efficiency trade-off | Agents can share ReputationSummary selectively | No per-interaction privacy level choice; no pseudonymous participation mode |
| Agent-controlled profile sections | Private data share controlled | No mechanism to protect some sections while exposing others; no correction mechanism for contributions |
5.3 Missing — OVN concepts not yet planned in NDO
| OVN concept | Gap description | Proposed resolution |
|---|---|---|
| Agent type taxonomy (individual, group, project, network, bot) | Only individual agents exist | Model collective agents as NDOs with their own governance; add AgentType to person context |
| Composable individual profile | Profile is split across unconnected entries | Build AgentProfile as a composable view aggregating Person, PPR summary, roles, capability slots, affiliations |
| Social graph (social capital, network relations) | No peer relationships modeled | Add AgentRelationship link type: bidirectional, typed (colleague, collaborator, trusted, etc.), private |
| Network affiliations | Only single-network membership | Model cross-network affiliations as links from Person to other NDO instances |
| Affiliation conditions (formal ToP agreements) | No affiliation ceremony | Add AffiliationRecord: a hash-referenced acknowledgement of Terms of Participation + benefit redistribution agreement |
| Affiliation lifecycle (active/core/close/inactive) | Binary in/out membership | Derive affiliation state algorithmically from PPR activity + recency; expose as queryable status |
| Zero-knowledge capability proofs | Must reveal raw data to prove eligibility | Integrate ZKP library or ZKP-compatible VC layer; allow prove_capability(condition) without data disclosure |
| Credential portability (across networks) | Roles and PPRs are local | Flowsta W3C DID + FlowstaIdentity CapabilitySlot on Person hash as cross-network identity anchor (REQ-NDO-AGENT-08, ndo_prima_materia.md Section 6.7); and define a PortableCredential structure: signed summary of roles + PPR statistics, verifiable by other Holochain networks |
| Sybil resistance mechanism | No proof-of-personhood | Optional Tier 2 governance requirement for verified Flowsta identity (REQ-NDO-CS-14) for high-trust roles; complements social vouching (existing agents vouch for new agents), biometric opt-in, or Proof-of-Personhood integration as optional membrane proof |
| Pseudonymous participation mode | Contribution always linked to AgentPubKey | Allow ephemeral agents (agent contributes under a temporary key without linking to Person); contribution is recorded but unlinkable to physical identity |
| Agent AI/bot delegation | Agents must act manually | Define a DelegatedAgent relationship: a Person can authorise an AI agent to act on their behalf within defined scope |
| Needs and wants in profile | Not modeled | Add AgentNeedsWants as an optional profile extension: what resources the agent needs and what they can offer; enables matching |
6. Forward Map: Generic NDO Agent Architecture
6.1 Agent Type as Configuration, Not Hard-Code
Rather than adding parallel code paths for each agent type, the generic NDO should treat agent type as a configuration property:
#![allow(unused)] fn main() { pub enum AgentEntityType { Individual, // Human participant Collective(String), // Group/working group (name/description) Project(ActionHash), // Project NDO this agent represents Network(ActionHash), // Network NDO this agent represents Bot { capabilities: Vec<String>, operator: AgentPubKey }, // AI/bot with declared capabilities ExternalOrganisation(String), // Traditional org (name, for partner modelling) } pub struct AgentContext { pub agent_type: AgentEntityType, pub person_hash: Option<ActionHash>, // None for bots/external orgs pub created_at: Timestamp, pub network_seed: String, // Which NDO network this context belongs to } }
Individual agents have AgentEntityType::Individual with a linked Person. Collective agents (working groups, projects) reference an NDO hash. Bots have no Person but have declared capabilities and a responsible operator.
6.2 Affiliation State as a Derived Property
Rather than storing affiliation state (which would need maintenance and could become inconsistent), derive it algorithmically from existing DHT data:
affiliation_state(agent) = f(
person_exists(agent), // Boolean
contributions_count(agent), // From economic events
last_contribution_timestamp(agent), // Recency from economic events
reputation_summary.total_claims, // From PPRs
affiliation_record_exists(agent), // Has the agent signed the ToP?
governance_claims_count(agent) // From PPRs
)
→ UnaffiliatedStranger | CloseAffiliate | ActiveAffiliate |
CoreAffiliate | InactiveAffiliate
CoreAffiliate is algorithmically determined: an active affiliate whose PPR contribution rate in the past N days exceeds a configurable threshold becomes a core affiliate. This implements the OVN governance equation: governance access as benefit derived from contribution activity.
6.3 Composable AgentProfile View
The aggregated individual profile, computed on demand:
#![allow(unused)] fn main() { pub struct AgentProfile { // Identity layer pub agent_pub_key: AgentPubKey, pub person: Option<Person>, pub affiliation_state: AffiliationState, // Capability layer pub roles: Vec<PersonRole>, pub capability_level: String, // member/stewardship/coordination/governance pub capability_slots: Vec<CapabilitySlotInfo>, // External credential attachments; includes FlowstaIdentity → IsSamePersonEntry; optional resolved flowsta_did for UI (`ndo_prima_materia.md` Section 6.7) // Reputation layer (derived, selectively shared) pub reputation_summary: Option<ReputationSummary>, pub economic_reliability_score: Option<f64>, // For Unyt credit limit // Participation layer pub active_commitments_count: u32, pub economic_events_count: u32, pub resource_custodianships_count: u32, // Social layer (optional, agent-controlled) pub network_affiliations: Vec<NetworkAffiliation>, pub peer_vouches: Option<u32>, // Number of vouches from trusted peers // Temporal pub joined_at: Option<Timestamp>, pub last_active_at: Option<Timestamp>, } }
This profile is not an entry type — it is a query result, composed from existing entries. The agent controls which sections are exposed by granting access to the constituent entries.
6.4 Affiliation Record — The Terms of Participation Bridge
A lightweight mechanism to record formal affiliation:
#![allow(unused)] fn main() { pub struct AffiliationRecord { pub agent: AgentPubKey, pub network_id: String, // Which NDO network pub documents_acknowledged: Vec<DocumentAck>, // Hash + title of each ToP document pub signed_at: Timestamp, pub signature: Signature, // Agent signs the affiliation record pub witness: Option<AgentPubKey>, // Optional vouching agent } pub struct DocumentAck { pub document_hash: String, // Hash of the document text pub document_title: String, pub document_version: String, } }
When an agent creates their first Person entry, the UI prompts them to acknowledge the network's Terms of Participation. The acknowledgement is cryptographically signed and stored as an AffiliationRecord. This bridges the OVN's formal affiliation ceremony with the NDO's digital infrastructure.
6.5 Portable Credential Summary
A structure that can be shared with other Holochain networks as proof of contribution and capability:
#![allow(unused)] fn main() { pub struct PortableCredential { pub issuing_network: String, // DNA hash of the issuing network pub agent: AgentPubKey, pub credential_type: PortableCredentialType, pub claims: PortableCredentialClaims, pub issued_at: Timestamp, pub valid_until: Option<Timestamp>, pub issuer_signature: Signature, // Signed by a Primary Accountable Agent pub agent_signature: Signature, // Countersigned by the agent } pub enum PortableCredentialType { RoleCredential(String), // "Accountable Agent in network X" ReputationCredential, // Aggregated reputation score CompetencyCredential(String), // "Certified 3D printer operator" AffiliationCredential, // "Active affiliate of network X since date" } }
A receiving network can verify the issuer_signature against the issuing network's DNA hash, establishing a cryptographic chain of trust without requiring centralized credential issuers.
Receiving networks may correlate credentials with a Flowsta DID when the issuer also records a FlowstaIdentity link on the agent's Person hash — improving interoperability without making PPR entries themselves transferable.
7. Complexity Economics Justification: Why Each Agent Concept Matters
Agent type taxonomy matters because economic models must faithfully represent economic actors. In Sensorica's actual operations, the entities performing actions are networks, ventures, and partner organisations — not just individuals. Flattening these to individual-human agents produces systematically inaccurate economic accounting. Benkler's P2P advantage — that P2P systems can process more information and model more finely-grained reality — is lost when the agent model is coarser than the actual social structure.
The affiliation spectrum matters because governance decisions made by binary "in/out" membership are weaker than those made by graded participation-aware membership. The governance equation (contribution history → governance access) requires a nuanced engagement model as input. If everyone is either "in" or "out," the governance equation reduces to "everyone who joined gets an equal vote," which ignores the 1-9-90 engagement reality. The result is either oligarchy (the 1% who do all the work decide everything while the 90% technically could override them) or paralysis (decisions require the majority of a population that mostly isn't paying attention).
ZKP capability proofs matter because the current privacy-accountability model forces a false binary: either share raw data (low privacy, high accountability) or share nothing (high privacy, no accountability). Zero-knowledge proofs break this binary. An agent can prove "I have at least 10 completed maintenance commitments" without revealing who the counterparties were, what the resources were, or what the exact performance scores were. This is the technical foundation for privacy-preserving meritocracy — governance access based on contribution without requiring surveillance.
Credential portability matters because the value of contribution data is severely limited if it only functions within a single application instance. An experienced Sensorica contributor who joins a new OVN should be able to leverage their track record. Without portability, every new commons requires starting from zero, creating massive friction to growth of the P2P ecosystem. Benkler's model of the peer production advantage assumes information flows across organisational boundaries — credential portability is the mechanism that makes this flow possible.
Cross-app identity (Flowsta) matters for the same reason credential portability matters: agents who participate in multiple OVNs or hApps are bridge nodes (Section 4.6). Without a verifiable same-person link across conductors, every network treats them as a stranger; sybil pressure and cold-start friction repeat. Flowsta's permissionless Tier 1 keeps overhead low for casual participants; Tier 2 lets communities demand verified identity only where Bar-Yam-style complexity matching says it is worth the coordination cost (high-trust governance, high-value custody).
The composable individual profile matters because an agent's full profile — their roles, contributions, social relations, affiliations, capabilities — is the information substrate for most governance and economic decisions in the commons. If this information is scattered across disconnected entries with no composable view, the information cost of making well-informed decisions is high. Bar-Yam's complexity matching principle: the governance system's access to information about participants must match the complexity of the participation patterns it is trying to govern.
Collective agent types matter because commons-based peer production is fundamentally about collectives. Modelling it as a collection of individual agents without collective agency misses the emergent properties of collaboration. A working group is not just the sum of its members — it has its own identity, its own resource access, its own reputation, and its own governance. Without collective agent types, the NDO cannot model the holonic structure of OVNs: the fact that every entity is simultaneously a whole and a part of a larger whole.
This is a living document. Section 5.3 should be converted into formal requirements as the generic NDO project begins. Section 6 describes design directions, not final specifications. The OVN wiki pages at Agent, Identity, Individual profile, and Organizational structure remain authoritative references for agent design in peer production systems.
Resources: Ontology, Implementation, and Forward Map
Type: Archive / Knowledge Base Document
Created: 2026-03-11
Last updated: 2026-06-16 (synced with NDO Layer 0 + federation code)
Relates to: ndo_prima_materia.md, versioning.md, digital-resource-integrity.md, unyt-integration.md, flowsta-integration.md, IMPLEMENTATION_STATUS.md
Sources: MVP code (zome_resource, zome_gouvernance), shared types (crates/shared/src/types.rs), NDO coordinator (dnas/nondominium/zomes/coordinator/zome_resource/src/ndo_identity.rs), federation modules (zome_gouvernance hard_link.rs, contribution.rs, agreement.rs), post-MVP design documents, OVN wiki — Resource, OVN wiki — Resource type
Purpose
This document maps the three states of Resource understanding in this Nondominium / NDO project:
- Implemented — what exists today in the MVP
zome_resourceandzome_gouvernancecodebases (including NDO Layer 0 and federation extensions) - Planned — what is designed in the post-MVP requirements documents
- Remaining — what the OVN wiki's 15 years of commons-based peer production practice contains that NDO does not yet plan to implement, and which should inform the generic NDO design
The goal is to ensure that the generic NDO — which will be built as a standalone hApp and then instantiated by Nondominium and other projects — represents a complete and principled resource ontology, not an accidental by-product of a single use-case.
1. Conceptual Foundation: Resources in P2P Complexity Economics
Before mapping what is and is not implemented, it is necessary to establish what a Resource is in the theoretical context this project operates within. The OVN wiki defines resources from the REA (Resources, Events, Agents) ontology and extends it through 15 years of Sensorica practice. The NDO builds further on this.
1.1 Beyond REA Primitives
In standard REA accounting, a Resource is simply an entity that has economic value and can be tracked as it flows through Events performed by Agents. This is a correct but minimal definition — adequate for accounting, inadequate for governance.
In peer production, a resource is also:
- An information carrier: it encodes design intent, provenance, contribution history, and quality evidence
- A coordination node: agents discover it, express intent to use it, negotiate access, and coordinate around it
- A trust anchor: its history of use (how it has been treated, maintained, transacted) is evidence about the agents who interacted with it
- An economic attractor: governance rules embedded in a resource determine who can access it (to improve / develop use, maintain it), and therefore shape the economic topology of the network around it.
This richer conception changes the design requirements fundamentally. A Resource is not merely a record in a ledger — it is a socially embedded DHT object with its own identity, governance constitution, and economic role.
1.2 The Tragedy of the Commons Solved by Embedded Governance
Hardin's "tragedy of the commons" (1968) argued that shared resources are inevitably depleted because individual agents have incentives to overuse. His solution was privatisation or central regulation. Ostrom's work (Governing the Commons, 1990) empirically refuted this: communities have sustainably governed shared resources for centuries through embedded, peer-enforced rules — without privatisation and without central authorities.
The NDO is, architecturally, an implementation of Ostrom's finding. The GovernanceRule entries embedded in ResourceSpecifications are exactly the "locally evolved institutions" that Ostrom identified as the mechanism of successful commons governance. The peer validation of economic events, PPR generation, and role-based access control are the "monitoring and sanctioning" mechanisms she observed.
This theoretical grounding is not academic decoration. It justifies specific design choices: governance rules must be embedded in the resource (not in a separate administrative system), enforcement must be peer-based (not authority-based), and participation in governance must generate reputational stake for participants.
1.3 Rivalrous vs. Non-Rivalrous: The Governance Fork
Benkler (The Wealth of Networks, 2006) identifies the rivalry or non-rivalry of a resource as the primary determinant of optimal governance strategy:
- Non-rivalrous resources (digital designs, methods, documentation, software): can be copied and shared at near-zero marginal cost. Restricting access does not preserve the resource — it only reduces total value creation. Default governance: open access, attribution-based, copy-left.
- Rivalrous resources (physical tools, equipment, spaces, materials): use by one agent excludes others. Restricting access is necessary to prevent overuse and ensure maintenance. Default governance: Ostromian embedded rules, reputation-gated access, stewardship requirements.
This distinction has profound implications for NDO Resource modeling. A resource's governance defaults, access rules, lifecycle requirements, and Unyt integration patterns should all differ based on rivalry. The current implementation does not model rivalry explicitly — this is a fundamental gap. - ToDo
1.4 Complexity Matching: Governance Overhead Must Match Resource Complexity
Bar-Yam's complexity matching principle states that the governance complexity of a system must match the complexity of the challenges it manages. Applied to resources:
- A simple idea (Layer 0 only,
Ideationlifecycle stage) requires near-zero governance overhead - A design file shared across a network requires moderate governance (attribution, versioning, integrity)
- A physical CNC machine used by 50 agents requires substantial governance (access rules, maintenance scheduling, custody chains, reliability tracking)
The NDO's three-layer model (ndo_prima_materia.md) directly implements this principle. LifecycleStage on Layer 0 is implemented (10 stages, integrity-validated transitions); governance overhead can now be matched to maturity for NDO identity. This document still argues the forward map needs further refinement — OperationalState split, rivalry/scope classification, and Layers 1 & 2 activation — to model the full spectrum of resource types in practice.
1.5 Resources as Social Infrastructure
The OVN wiki goes further than REA in recognising intangible resources: social capital, trust, community sense, governance knowledge, competencies, synergy. These are not commodifiable — they cannot be transferred, traded, or priced. But they are inputs to productive processes and outputs of participation.
In complexity economics terms: these intangibles are the emergent properties of the social system. They cannot be designed in; they arise from the right conditions. But they can be cultivated, protected, and damaged. A governance system that only models material and digital resources is blind to a large fraction of the actual value that flows in peer production communities.
The NDO does not need to track intangible resources in the same way it tracks a bicycle or a CAD file. But it must be aware of them — as a category of resource type — to avoid designing governance mechanisms that damage them.
1.6 Source: the Third Category
The REA ontology that underpins ValueFlows operates with two primitives: Agent and Resource. The resource classification work in sections 1.1–1.5 implicitly accepts this duality. But 15 years of OVN practice and a growing literature on socio-ecological systems accounting reveal a case where neither primitive is adequate: generative ecological systems — watersheds, rivers, forests, fisheries, atmospheric assimilation capacity — that yield resources, receive ecological effects, and condition future possibilities without being ownable, intentional, or inventoriable in the standard sense.
The academic paper source-ndo-paper.md demonstrates with Occam's razor that modelling a watershed under Nondominium governance without a Source primitive requires three active ontological fictions and leaves four economic relations inexpressible. Adding one new primitive removes all seven distortions.
Source is a third ontological category: a generative, non-ownable, partially unknowable system that:
- yields Resources (a river yields cubic metres of water when abstracted)
- receives ecological effects (a river receives heavy-metal discharge)
- conditions other Sources (a forest conditions river flow and resilience)
- accumulates a historical ledger of boundary events for adaptive governance
Sources are represented in the Nondominium architecture as Source-NDOs: NondominiumIdentity entries with PropertyRegime::Nondominium (or CommonPool), a linked SourceProfile extension for condition indicators, and a stewardedBy relation instead of primaryAccountable. No agent owns a Source; stewards carry obligations to maintain the event ledger and adapt governance rules as the source ledger grows.
This is the cybernetic governance loop: boundary events accumulate → stewards interpret conditions → governance rules adapt → access affordances change → future events are conditioned. It extends the governance-as-operator pattern from complicated (rule-evaluable) to complex (adaptive, signal-based) governance contexts.
Normative requirements for Source-NDO are in source-ndo-requirements.md. This subsection is an ontological framing note; the detailed data model, governance patterns, and ValueFlows extension (vf:Source) are in that document.
2. Current Implementation (MVP)
2.1 Entry Types in zome_resource Integrity
The MVP implements four entry types in zome_resource integrity, plus shared NDO enums in crates/shared/src/types.rs (imported by both integrity and coordinator zomes):
NondominiumIdentity (NDO Layer 0 — ✅ implemented, PR #80/#84)
#![allow(unused)] fn main() { pub struct NondominiumIdentity { pub name: String, pub initiator: AgentPubKey, pub property_regime: PropertyRegime, pub resource_nature: ResourceNature, pub lifecycle_stage: LifecycleStage, pub created_at: Timestamp, pub description: Option<String>, pub successor_ndo_hash: Option<ActionHash>, // set once on Deprecated (REQ-NDO-LC-06) pub hibernation_origin: Option<LifecycleStage>, // set on → Hibernating; cleared on resume } }
The original create_ndo action hash is the stable Layer 0 identity for all time. property_regime, resource_nature, and lifecycle_stage live on Layer 0 (not on ResourceSpecification or EconomicResource). Only lifecycle_stage, successor_ndo_hash (once), and hibernation_origin (Hibernating transitions) may change after creation; all other fields are integrity-validated as immutable. Deletes are always invalid (permanent tombstone at EndOfLife).
Coordinator API: create_ndo, get_ndo, get_all_ndos, get_my_ndos, update_lifecycle_stage, get_ndos_by_lifecycle_stage, get_ndos_by_nature, get_ndos_by_property_regime — see ndo_identity.rs.
Shared enums on Layer 0 (defined in crates/shared/src/types.rs):
#![allow(unused)] fn main() { pub enum LifecycleStage { Ideation, Specification, Development, Prototype, Stable, Distributed, Active, Hibernating, Deprecated, EndOfLife, } pub enum PropertyRegime { Private, Commons, Collective, Pool, CommonPool, Public, Nondominium, } pub enum ResourceNature { Physical, Digital, Service, Hybrid, Information, } }
Doc/code consistency:
PropertyRegimehas seven canonical variants in Rust and the UI (Private,Commons,Collective,Pool,CommonPool,Public,Nondominium). See §2.6.ResourceNaturein code addsServiceandInformationbeyond the three-variant design inndo_prima_materia.md; forward-map variantsSpace,Method, andCurrency(§6.2) are not yet in code.
ResourceSpecification (Layer 1 — ✅ activated, PR #132)
#![allow(unused)] fn main() { pub struct ResourceSpecification { pub name: String, pub description: String, pub category: String, pub image_url: Option<String>, pub tags: Vec<String>, pub is_active: bool, /// Visibility / discovery scope. Project-scoped specs skip the global anchor. pub scope: ResourceScope, /// Immutable pointer to the Layer 0 NondominiumIdentity this spec activates. pub ndo_identity_hash: ActionHash, /// The NDO action the author observed when activating Layer 1. Integrity /// cannot walk an update chain forward deterministically, so the author names /// the state they saw and validation resolves it backward to the identity. pub ndo_state_hash: ActionHash, } }
This is the knowledge layer in ValueFlows terminology: the type or template of a resource. It corresponds to the OVN concept of "Resource Type" — an abstract representation that groups interchangeable concrete instances.
EconomicResource
#![allow(unused)] fn main() { pub struct EconomicResource { pub quantity: f64, pub unit: String, pub custodian: AgentPubKey, // TODO (G1, REQ-AGENT-02): replace with AgentContext post-MVP // to support Collective, Project, Network, and Bot agents as // Primary Accountable Agents. Currently assumes individual agent. pub current_location: Option<String>, pub operational_state: OperationalState, } }
This is the observation layer: a specific instance of a resource at a point in time, held by a specific custodian.
GovernanceRule (typed as of PR #132)
#![allow(unused)] fn main() { pub struct GovernanceRule { pub rule_data: RuleData, // tagged enum, replaces the rule_type/rule_data string pair pub enforced_by: Option<String>, // role required to enforce this rule /// Direct pointer to Layer 0 — required for constraint evaluation context. pub ndo_identity_hash: ActionHash, /// Denormalized from Layer 0 (immutable source) — enables zero-DHT-read validation. pub property_regime: PropertyRegime, pub resource_nature: ResourceNature, pub rivalry_override: Option<Rivalry>, } pub enum RuleData { AccessRequirement(AccessRequirementData), UsageLimit(UsageLimitData), TransferCondition(TransferConditionData), MaintenanceSchedule(MaintenanceScheduleData), } }
Economic rules governing access and use. The former untyped rule_type: String / rule_data: String pair is gone: RuleData is a tagged enum with a typed payload per variant, and GovernanceRuleType is derived from the discriminant rather than stored. Rules are checked against their NDO's classification by the predicates in crates/shared/src/constraints.rs — Hard violations are rejected at integrity, Soft violations return as advisory warnings. Definitions: crates/shared/src/rule_data.rs.
OperationalState (enum on EconomicResource) — ✅ implemented (REQ-NDO-OS-01)
PendingValidation | Available | Reserved | InTransit | InStorage | InMaintenance | InUse
LifecycleStage is implemented on NondominiumIdentity (see above). Operational condition cycles on the instance independently of lifecycle maturity — e.g. an Active-stage NDO can have an InMaintenance economic resource instance.
2.2 Link Graph
The link types model resource discovery and navigation:
Legacy resource/spec links (zome_resource):
- Anchor links for global discovery (
AllResourceSpecifications,AllEconomicResources,AllGovernanceRules) - Hierarchical links (
SpecificationToResource,SpecificationToGovernanceRule) - Agent-centric links (
CustodianToResource,AgentToOwnedSpecs,AgentToManagedResources) - Faceted search links (
SpecsByCategory,ResourcesByLocation,ResourcesByOperationalState,RulesByType) - Governance links (
ResourceToValidation) - Update chain links (for Holochain's append-only update pattern)
NDO Layer 0 links (✅ implemented, PR #80/#84):
AllNdos— global anchor at path"ndo_identities"→ allNondominiumIdentityaction hashesAgentToNdo— initiatorAgentPubKey→ NDOs they createdNdoByLifecycleStage— path"ndo.lifecycle.{Stage}"→ NDOs at that stage (moved on transition)NdoByNature— path"ndo.nature.{Nature}"→ NDOs of that nature (immutable after creation)NdoByPropertyRegime— path"ndo.regime.{Regime}"→ NDOs under that regime (immutable after creation)NdoToSuccessor— deprecated NDO → successorNondominiumIdentity(REQ-NDO-LC-06)NdoToTransitionEvent— NDO → triggeringEconomicEventaction hash (REQ-NDO-L0-05; link only, cross-zome event validation deferred)
Layer 1 activation (✅ implemented, PR #132):
NdoToSpecification— NDO identity hash →ResourceSpecification, created on everycreate_resource_specification.Not yet implemented:
NDOToProcess(Layer 2 activation perndo_prima_materia.md§4).
2.3 What the MVP Does Well
- Permanent Layer 0 identity anchor —
NondominiumIdentitywith field-level immutability and integrity-validated lifecycle state machine (forward chain, Hibernating resume, Deprecated + successor, EndOfLife tombstone) - Faceted NDO discovery — global, per-agent, and categorization anchors by lifecycle stage, nature, and property regime
- Clean separation of specification (type/template) from resource (instance) — consistent with ValueFlows Knowledge/Observation layering
- Single-custodian model is appropriate for the current Artcoin/simple sharing use case
- GovernanceRule linked to ResourceSpecification rather than EconomicResource is architecturally correct: rules belong to the type, not the instance
- The anchor link pattern enables permissionless discovery
- Cross-NDO federation primitives — typed hard links, peer-validated contributions, and benefit-redistribution agreements in
zome_gouvernance(PR #103; see §2.5)
2.4 Known Gaps in the MVP
| Gap | Impact | Status / planned fix |
|---|---|---|
ResourceState conflates lifecycle and operational dimensions | ✅ OperationalState on EconomicResource (REQ-NDO-OS-01); governance-operator transitions deferred (REQ-NDO-OS-02–05) | |
✅ PropertyRegime on NondominiumIdentity (see §2.6 — seven variants) | ||
✅ ResourceNature on NondominiumIdentity (5 variants in code; see §2.6) | ||
GovernanceRule.rule_data is untyped JSON string | ✅ Typed RuleData enum (#132) — four variants with typed payloads, classification predicates enforced Hard/Soft; EconomicAgreement / IdentityVerification rule families remain post-MVP | |
PendingValidation | ✅ LifecycleStage (10 stages) on Layer 0 with full transition validation | |
| Single custodian only | Cannot model shared tools, collective custody, resource pools | 🔄 Many-to-many flows (post-MVP) |
✅ NondominiumIdentity Layer 0 — stable action hash independent of spec updates | ||
| No full versioning DAG | Cannot track all design-evolution relations (fork, merge, repair, augment) | 🔄 Partial via NdoHardLink (§2.5); full DAG in versioning.md |
| No digital integrity | Cannot verify downloaded digital resource data | 🔄 Digital Resource Integrity (post-MVP) |
| No rivalry/non-rivalry modeling | Governance defaults are the same for all resource types | Gap — see Section 5 |
| No scope classification | Cannot determine network-wide vs. project-specific visibility | Gap — see Section 5 |
| No resource reliability | No way to track a tool's track record independent of custodian reputation | Gap — see Section 5 |
| No cross-app identity or DID | Agents cannot prove identity across Holochain apps or networks; reputation is local to this DHT; no key recovery mechanism | 🔄 FlowstaIdentity CapabilitySlot on Person entry hash (ndo_prima_materia.md Section 6.7) |
| No agent key recovery | If agent loses device, signing key (and all private entries/PPRs) are inaccessible; no deterministic key regeneration | 🔄 Flowsta Vault BIP39 recovery phrases; auto-backup; CAL-compliant data export (ndo_prima_materia.md Section 6.7) |
| Layer 2 not linked to Layer 0 | Process activity not activated via NDOToProcess | 🔄 ndo_prima_materia.md §4 (Layer 1 activated via NdoToSpecification, #132) |
| Governance-as-operator for lifecycle transitions | Transitions validated in integrity zome only; no automatic EconomicEvent generation | 🔄 REQ-NDO-LC-02, REQ-NDO-LC-03, REQ-NDO-LC-07 |
2.5 Federation, versioning & contribution layer (zome_gouvernance, ✅ PR #103)
Beyond zome_resource, the governance zome implements NDO federation and contribution primitives that partially address versioning, composability, and OVN contribution tracking:
NdoHardLink — typed cross-NDO (cross-DNA) relationships:
#![allow(unused)] fn main() { pub enum NdoLinkType { Component, DerivedFrom, Supersedes } pub struct NdoHardLink { pub from_ndo_identity_hash: ActionHash, pub to_ndo_dna_hash: DnaHash, pub to_ndo_identity_hash: ActionHash, pub link_type: NdoLinkType, pub fulfillment_hash: ActionHash, // EconomicEvent backing this link // ... } }
Partial coverage of the versioning DAG (versioning.md): DerivedFrom and Supersedes map to evolution/supersession relations; Component supports composable/fractal resource architecture. Not a full DAG (no ForkedFrom, MergedFrom, RepairedFrom, etc.).
Contribution — peer-validated work on an NDO (ValueFlows Work/Modify semantics):
#![allow(unused)] fn main() { pub struct Contribution { pub provider: AgentPubKey, pub action: VfAction, pub ndo_identity_hash: ActionHash, pub validated_by: Vec<AgentPubKey>, // min 1 AccountableAgent pub effort_quantity: Option<f64>, // optional cross-DNA WorkLog reference (Group DNA) // ... } }
Agreement — benefit redistribution clauses on an NDO (partial Unyt/BRD primitive):
#![allow(unused)] fn main() { pub struct Agreement { pub ndo_identity_hash: ActionHash, pub version: u32, pub clauses: Vec<BenefitClause>, pub primary_accountable: Vec<AgentPubKey>, // ... } }
Coordinator modules: hard_link.rs, contribution.rs, agreement.rs. Sweettest coverage in dnas/nondominium/tests/src/governance/mod.rs. Not yet wired to Unyt RAVE validation or full upstream contribution propagation.
2.6 Doc/code consistency notes (reconciliation recommended)
| Topic | Code (ground truth) | Other docs | Recommendation |
|---|---|---|---|
PropertyRegime variant count | 7 variants in crates/shared/src/types.rs, integrity validation, shared-types, and UI | Protocol and UI expose all seven | Keep docs/UI/code in lockstep; Source-NDOs remain restricted to Nondominium / CommonPool only |
ResourceNature variants | Physical, Digital, Service, Hybrid, Information (5) | This doc §6.2 forward map adds Space, Method, Currency; ndo_prima_materia.md specifies 3 | Treat code's 5 variants as implemented; forward-map additions remain post-MVP |
| Lifecycle governance | Initiator-only update_lifecycle_stage (MVP) | REQ-NDO-LC-07 role-based authorization | Defer to governance-as-operator integration |
| Transition events | NdoToTransitionEvent link optional; transition_event_hash often null in UI | REQ-NDO-LC-03 automatic EconomicEvent generation | Backend Phase 2.3 |
3. Post-MVP Roadmap
The following improvements are designed in the post-MVP documentation. Items marked ✅ Implemented are live in the codebase; others remain planned or partial. Full specifications are in the referenced documents.
3.1 NDO Three-Layer Model (ndo_prima_materia.md)
The most significant architectural change. Replaces the flat ResourceSpecification + EconomicResource model with a progressive three-layer structure:
- Layer 0 — NondominiumIdentity: ✅ Implemented (PR #80/#84). A permanent, immutable identity anchor. The genesis entry whose action hash becomes the stable identifier for the resource across its entire existence. Contains
name,description,initiator,property_regime,resource_nature,lifecycle_stage,created_at,successor_ndo_hash,hibernation_origin. Never voided — serves as the tombstone at end of life. - Layer 1 — ResourceSpecification (activated by the
NdoToSpecificationlink): ✅ Implemented (PR #132). The form of the resource — design, typed governance rules, scope.create_resource_specificationwrites the link and the spec carriesndo_identity_hash/ndo_state_hash, so a spec can no longer exist without an NDO parent. Activation is gated to lifecycle stagesSpecificationthroughActive. Digital asset manifests (REQ-NDO-L1-06) remain post-MVP. - Layer 2 — Process (activated by
NDOToProcesslink): 🔄 Not started. The activity around the resource — EconomicEvents, Commitments, Claims, PPRs. Activated when multi-agent coordination begins. ValueFlows cycle exists inzome_gouvernancebut is not yet linked to NDO identity viaNDOToProcess.
This model directly implements the complexity matching principle: coordination overhead grows with actual social complexity, not at resource creation. The three-layer structure describes the resource face of any entity — including collective entities. When a collective (project-organisation, cooperative, network) has an associated NDO, that NDO is its digital twin as a Resource: its permanent identity, lifecycle, specification, and governance. The collective also has an agent face (AgentContext) through which it participates in economic events. These are distinct — see agent.md §3.1 for the dual-face model.
3.2 Property Regime and Resource Nature
✅ Implemented on NondominiumIdentity (shared crate + integrity validation). Canonical Rust definitions:
#![allow(unused)] fn main() { pub enum PropertyRegime { Private, // Full rights bundle; individual ownership Commons, // Non-rivalrous shared resource; governance via licensing/attribution Collective, // Cooperative/collective ownership Pool, // Pool of shareables: rivalrous shared resources; custody/scheduling/maintenance CommonPool, // Rivalrous consumable resource; governance via quota/depletion rules Public, // Public/governmental stewardship; open-access; non-alienable by the public body Nondominium, // Uncapturable by design; contribution-based access; no alienation permitted } pub enum ResourceNature { Physical, // Material objects, equipment, consumables Digital, // Software, data, design files, documents Service, // Software services, knowledge assets (extends spec's 3-variant set) Hybrid, // Digital twin of a physical resource Information, // Knowledge assets, data sets (extends spec's 3-variant set) } }
These enums are part of NondominiumIdentity (Layer 0) — they classify the resource at creation and remain stable across its lifecycle (integrity-enforced). The PropertyRegime enum is reconciled from the OVN property regime taxonomy (§4.4.3) — see §4.4.6 for the full analysis.
Consistency: Protocol and UI both expose all seven
PropertyRegimevariants. Regime-driven governance enforcement (transfer-rights, no-alienation guards) is Phase B — see §4.4.4–§4.4.5 andimplementation_plan.md.
3.3 LifecycleStage and OperationalState
LifecycleStage — ✅ Implemented on NondominiumIdentity (10 stages, integrity-validated state machine, initiator-only updates in MVP):
Ideation → Specification → Development → Prototype →
Stable → Distributed → Active →
Hibernating → Deprecated → EndOfLife
Hibernating records hibernation_origin and resumes to that stage. Deprecated requires successor_ndo_hash (REQ-NDO-LC-06). EndOfLife is terminal.
OperationalState — ✅ Implemented on EconomicResource (7 states; update_operational_state, get_resources_by_operational_state). Governance-zome transition enforcement (REQ-NDO-OS-02–03) remains deferred.
Each lifecycle transition should be governance-validated (the governance zome as state transition operator), generate an economic event, and create a lifecycle history audit trail (REQ-NDO-LC-02/03). Today: integrity zome validates transitions; automatic EconomicEvent generation and governance-as-operator evaluation are deferred.
3.4 Versioning (versioning.md)
🔄 Partially implemented via NdoHardLink (NdoLinkType: Component, DerivedFrom, Supersedes) in zome_gouvernance (PR #103). Cross-DNA hard links support federation-scale composition and supersession.
Full DAG-based version graph (typed relations: EvolvedFrom, ForkedFrom, MergedFrom, RepairedFrom, AugmentedFrom, PortedToPlatform) and OVN-compliant contribution propagation upstream through the version graph remain planned — see versioning.md.
3.5 Digital Resource Integrity (digital-resource-integrity.md)
Cryptographic integrity verification for digital resources: SHA-256 content addressing per 64KB chunk, Merkle tree structure for selective verification, composable/fractal resource architecture (atomic → component → composite), supply chain transparency.
3.6 Many-to-Many Flows (many-to-many-flows.md)
Extension of the single-custodian model to shared custody with weights and roles, one-to-many/many-to-one/many-to-many custody transfers, resource pools, co-custodian delegation.
3.7 Unyt Integration (unyt-integration.md)
🔄 Planned (post-MVP). Economic settlement layer via Unyt Smart Agreements and RAVEs. EconomicAgreement GovernanceRule type, RAVE validation as state transition precondition, PPR↔RAVE provenance chain, reputation-derived credit limits.
Partial primitive:
Agreement+BenefitClauseentries exist inzome_gouvernance(PR #103) as a benefit-redistribution data model on NDO identity hashes. Not yet wired to Unyt cells, RHAI scripts, or RAVE validation.
3.8 Flowsta Integration (flowsta-integration.md)
🔄 Planned (post-MVP). Decentralized identity and authentication layer via Flowsta agent linking. FlowstaIdentity CapabilitySlot on Person entry hash, providing W3C DID (did:flowsta:uhCAk...) without modifying the Person entry schema. Two-tier identity authority: Tier 1 (permissionless attestation via CapabilitySlot link) and Tier 2 (governance-enforced identity verification for role promotions and high-value transitions). Flowsta Vault provides BIP39 key recovery and auto-backup for agent data resilience (CAL-compliant). PPR ReputationSummary becomes attributable to a cross-app DID, enabling portable reputation across Flowsta-linked Holochain apps.
4. OVN Resource Ontology: 15 Years of Practice
The OVN wiki (Resource, Resource type) represents the distilled understanding of commons-based peer production at Sensorica. This section synthesises its key concepts in the context of NDO design, with complexity economics justifications.
4.1 Resource Primitives (Greg Cassel / OVN)
The OVN wiki adopts Greg Cassel's resource primitive taxonomy: mental resources, identity, physical resources, and media resources. This is broader than REA.
Mental resources — thoughts, feelings, ideas, knowledge that exists in agents' minds. Cannot be modelled directly in a DHT system (they are in the agent's head, not on a public ledger), but they are inputs to productive processes. In NDO terms: mental resources become visible when an agent creates an Ideation-stage NDO (Layer 0 only), which is the externalization of a mental resource into a public intent. The Ideation lifecycle stage is precisely the mechanism by which mental resources enter the observable network.
Identity — the capacity to distinguish agents and resources. In NDO terms: the NondominiumIdentity entry is the identity resource for every NDO object. Agent identity is handled by zome_person.
Physical resources — material objects with physical properties. NDO's Physical nature classification and the full custody/maintenance/transport/repair process suite cover this category.
Media resources — information superimposed on mediums: signs, signals, streams, messages, items, channels. This maps to NDO's Digital nature classification but is richer: the OVN taxonomy distinguishes between a design file (media item) and the channel through which it is shared (media channel). NDO currently does not make this distinction — a Digital resource could be either.
Complexity economics note: Mental resources and media resources are both non-rivalrous. Their governance implications differ from physical resources. Encoding this distinction at the resource type level is prerequisite to correct governance defaults.
4.2 Value Chain Maturity
The OVN wiki characterises resources by their stage of development:
| OVN stage | Description | NDO LifecycleStage equivalent |
|---|---|---|
| Idea | Documented, contextualised intent | Ideation |
| Design | Formalised in CAD, SPICE, etc. | Specification, Development |
| Study | Documented R&D | Development, Prototype |
| Prototype | Tangible, somewhat functional | Prototype |
| Usable artifact | Ready-to-use product | Stable, Distributed, Active |
The NDO LifecycleStage enum covers and extends this taxonomy with the addition of post-operational stages (Hibernating, Deprecated, EndOfLife) that OVN implies but does not formally enumerate. The NDO model is thus more complete in this dimension.
Complexity economics note: A resource's governance complexity should match its value-chain maturity. An Ideation-stage resource (someone's declared intent) requires near-zero governance. A Stable design that is being distributed for fabrication requires full governance, integrity verification, and versioning. The NDO's pay-as-you-grow layer activation model directly implements this — it is why the three-layer model is correct.
4.3 Production Process Resource Types
The OVN wiki classifies what production processes need:
| OVN type | Description | NDO coverage |
|---|---|---|
| Human labor | Time spent working | Not modeled as a resource type; covered by PPR participation records |
| Usables | Non-consumed inputs (tools, equipment) | Physical resources in NDO |
| Consumables | Depleted inputs (glue, components) | Physical resources in NDO; quantity tracking covers depletion |
| Space | Physical or virtual locations | Not explicitly modeled as a resource type |
| Method | Protocol, recipe, sequence | Not modeled as a resource type |
| Currency | Symbolic value exchange system | Not modeled as a resource type; partially addressed by Unyt integration |
The most significant gaps here are Method (documented processes, recipes, protocols) and Space (physical locations with governance, scheduling, and access control needs). Both are important in commons-based peer production settings.
Method resources are particularly interesting in the NDO context: a fabrication method (how to assemble a CNC machine) is a non-rivalrous digital resource — it can be copied freely. But it is also a governance-bearing resource: it defines the conditions under which physical resources should be used, encoding safety requirements, quality standards, and attribution requirements. In NDO terms, a Method would be a Digital NDO whose Layer 1 specification includes both the documented process and governance rules referencing it.
Space resources are rivalrous (only one person can use the CNC machine bay at a time) and require scheduling/booking mechanics that the current NDO does not model. A future generic NDO should be able to express temporal availability as a dimension of resource governance.
4.4 Property Regimes
4.4.1 What Property Is
The OVN wiki opens its treatment of property with a definition that reorients the entire concept away from legal formalism: "Property is about the relationship between agents and things. These relationships are institutionalized, meaning that they are codified as norms or rules or laws, are made public and are widely accepted by everyone in a social setting."
Property is not an object — it is a bundle of rights and obligations connecting a subject (agent) to an object (resource). Bentham identified four key classes of stakeholder rights in this bundle:
| Right | Description | NDO mapping |
|---|---|---|
| Use | Exclusive or otherwise — the right to interact with the resource | Role-gated VfAction execution; GovernanceRule access_requirement |
| Usufruct | The fruits of use — the right to benefit from what the resource produces | Benefit redistribution algorithm; PPR-based credit distribution |
| Management | The right to define how the resource is governed | GovernanceRule creation; role-gated rule modification |
| Custody/Stewardship | The right and obligation to maintain and protect the resource | EconomicResource.custodian; custody transfer protocols |
These four rights are not always bundled together. A Simple Agent may have Use rights without Management rights. A maintenance specialist has Custody rights for the duration of a repair without having Management rights. The NDO's role system and GovernanceRule architecture partially implements this unbundling, but without explicit modelling of which rights each role confers.
4.4.2 Goods Typology: The Excludability × Rivalry Matrix

Ostrom's four quadrants: Common-Pool Resources (high rivalry, low excludability → CommonPool regime), Private Goods (high/high → Private), Public Goods (low/low → Commons/Nondominium), Club/Toll Goods (low rivalry, high excludability → Collective/Pool). Goods type describes intrinsic characteristics; PropertyRegime describes the chosen governance arrangement.
Before classifying property regimes, Ostrom (following Samuelson) establishes a goods typology based on two independent axes:
- Excludability: can non-payers or non-members be excluded from use?
- Rivalry (subtractability): does one agent's use reduce availability for others?
| Low excludability | High excludability | |
|---|---|---|
| Low subtractability | Public goods (open knowledge, broadcast) | Toll / Club goods (private park, cable TV, software) |
| High subtractability | Common-pool resources (fisheries, physical tools) | Private goods (equipment owned by one person) |
Critically: goods types exist independently of property regimes. A common-pool resource (high subtractability, low excludability) can be owned as government property, private property, community property, or no-one's property. The goods type characterises the resource's physical or informational nature; the property regime characterises the social arrangement governing it.
This distinction matters for the NDO: ResourceNature and Rivalry describe the intrinsic characteristics of the resource. PropertyRegime describes the chosen governance arrangement. They are orthogonal fields.
4.4.3 The Full Property Regime Taxonomy
The OVN wiki distinguishes more regime types than the current NDO plan. All are important for the generic NDO:
| Regime | Rivalry | Excludability | Description | NDO coverage |
|---|---|---|---|---|
| Private | Any | High | Owned by one agent; full rights bundle; protected by a higher authority (or by Nondominium design) | Private |
| Public | Any | Low | Under public/governmental stewardship: open-access, non-alienable by the public body. Distinct from Commons (community-governed) and Nondominium (cryptographically uncapturable). Enables modelling libraries, parks, municipal infrastructure, and other publicly stewarded assets without collapsing them into Commons | Public |
| Commons | Non-rivalrous | Low | Pool of tangible but immaterial resources (designs, knowledge, software) with use governance (licences, attribution). Technically can be privatised through governance capture | Commons |
| Pool of Shareables | Rivalrous | Medium | Tangible material resources intended for sharing within a network; individually governed by property regime and intrinsic characteristics; designed for preservation and perpetual access | Pool |
| Common-pool resource | Rivalrous | Low | Mostly consumables, governed in bulk with rules for prevention of depletion; community-managed quotas | CommonPool |
| Collective / cooperative | Rivalrous | High | Cooperative/collective ownership by a defined membership | Collective |
| Condominium | Rivalrous | High | Resource divided into privately owned parts with collective governance of the whole (infrastructure, integrity, shared structures) | Not planned (can be added as a future variant) |
| Nondominium | Any | High (by design) | Requires extremely high costs of control, making it virtually uncontrollable by any entity — not even nation states. Does not need external protection because no actor can capture it. Examples: Bitcoin network, open seas, indigenous forest commons | Nondominium |
| Toll goods (club goods) | Non-rivalrous | High | Excludable but non-rivalrous up to a point (congestion); fee-based or membership-based access | Not planned (can be added as a future variant) |
The critical distinctions for the NDO:
Commons ≠ Pool of Shareables: The OVN wiki makes an important distinction. Commons are immaterial (non-rivalrous) resources — sharing a design file costs nothing and excludes no one. Pool of Shareables are material (rivalrous) — sharing a 3D printer requires scheduling, maintenance, and custody transfer. These have different governance requirements and should map to different PropertyRegime variants.
Commons ≠ Public: Commons are community-governed shared resources that can be captured through governance capture. Public denotes resources under public/governmental stewardship — open-access and non-alienable by policy of the stewarding public body, but not cryptographically uncapturable. A municipal library catalog or a publicly stewarded workshop is Public; a community knowledge commons is Commons.
Commons ≠ Nondominium / Public ≠ Nondominium: In the OVN model:
- Commons: governed resources with shared stewardship; theoretically, governance capture could privatise a commons (a bad actor could modify the governance rules to extract exclusive control)
- Public: public-body stewardship with open-access and non-alienation by policy; the stewarding body remains a social/legal actor, not a cryptographic guarantee
- Nondominium: uncapturable by design — no one can assert ownership, no organisation can enclose them. The property regime exists independently of governance rules: even if governance rules were to declare individual ownership, the cryptographic architecture makes it technically unenforceable
The NDO's architecture (append-only DHT, no admin key, agent-centric source chains) is a Nondominium implementation at the infrastructure level. This should be formally reflected in the data model.
Nondominium is defined by cost of capture, not by intent: The OVN wiki is precise — "The conditions for it to exist is to have extremely high costs of control, making it virtually uncontrollable by any entity, not even by nation states." This is a technical condition, not a legal or normative one. The NDO's PropertyRegime::Nondominium variant should encode a validation constraint: a resource declared as Nondominium must have governance rules that do not permit ownership assignment or transfer, and the system should reject GovernanceRule updates that attempt to add such rules. Phase A exposes semantic helpers (is_uncapturable, permits_ownership_transfer); Phase B wires these into the governance operator.
4.4.4 Property Regime Determines Possible Economic Models
The OVN wiki makes a point that is central to the NDO's relationship with Unyt: "once the property regime is fixed, only a limited number of motivation and incentive models are possible on top of that (call it economic model or business model). In turn, this determines people's values and behaviour within that organization."
This has direct architectural implications:
| PropertyRegime | Allowable economic models | Unyt implications |
|---|---|---|
Private | Full market (buy/sell/rent/lend); individual benefit capture | Smart Agreement can specify price, rental, usage fees |
Commons | Attribution-based; copyleft/open source | Smart Agreement triggers on share events, not sale events |
Collective | Cooperative benefit sharing; membership-gated alienation | Smart Agreement can encode member buy-in / exit; ownership transfer among members |
Pool | Scheduling-based access; contribution-weighted priority; insurance/maintenance pools | Smart Agreement triggers on custody transfer; maintenance settlement. Post-MVP: access eligibility should also gate on AffiliationState ≥ ActiveAffiliate (TODO G2) |
CommonPool | Quota-based; depletion taxes; collective replenishment | Smart Agreement governs extraction rate |
Public | Open-access under public stewardship; non-alienable by the public body | Smart Agreement may govern access fees or usage conditions but cannot assign private ownership |
Nondominium | Contribution-based; access is earned but not purchased; no alienation | Smart Agreement can distribute benefits of use but cannot assign ownership. Post-MVP: high-stakes access should gate on AffiliationState ≥ ActiveAffiliate or CoreAffiliate (TODO G2) |
The PropertyRegime on NondominiumIdentity should therefore be a hard constraint on which GovernanceRules and Unyt Smart Agreements are valid for that resource. The governance zome should enforce this: an attempt to attach a sale Smart Agreement to a Nondominium resource must be rejected.
4.4.5 Property and Distribution — Transfer Rights

Seven PropertyRegime variants × four transfer types (Ownership, Custody, Use Rights, Benefit). Nondominium blocks ownership transfer architecturally. Public blocks ownership transfer by public-stewardship policy. Pool allows temporary custody scheduling. Commons blocks ownership but allows stewardship. Enforced by governance zome validation (Phase B).
The OVN wiki observes: "Distribution is a change in status, a transfer of rights and obligations associated with that thing... Distribution is not possible without the notion of property."
In the NDO, different property regimes enable different types of transfers:
| Regime | Ownership transfer | Custody transfer | Use rights transfer | Benefit transfer |
|---|---|---|---|---|
Private | ✅ Full alienation | ✅ | ✅ | ✅ |
Collective | ✅ Among members | ✅ | ✅ | ✅ |
Commons | ❌ | ✅ (stewardship) | ✅ | ✅ (attribution) |
Pool | ❌ (stays in pool) | ✅ (temporary custody) | ✅ (scheduled) | ✅ |
CommonPool | ❌ | ✅ (extraction) | ✅ (quota-limited) | ✅ |
Public | ❌ (non-alienable by public body) | ✅ (stewardship) | ✅ | ✅ (public benefit) |
Nondominium | ❌ (architecturally impossible) | ✅ | ✅ | ✅ |
The current NDO models custody transfer well (through EconomicResource.custodian and TransferCustody VfAction). It does not model ownership transfer, benefit transfer, or the regime-specific restrictions on which transfers are valid. The governance zome should enforce regime-appropriate transfer restrictions.
4.4.6 OVN Analysis and NDO PropertyRegime Reconciliation
The OVN wiki identifies eight property regime types (§4.4.3 table). The NDO forward map (§6.3) selects the seven regimes that are architecturally relevant to the generic NDO:
#![allow(unused)] fn main() { pub enum PropertyRegime { Private, // Full rights bundle; individual ownership Commons, // Non-rivalrous shared resource; governance via licensing/attribution Collective, // Cooperative/collective ownership Pool, // Pool of shareables: rivalrous shared resources; custody/scheduling/maintenance CommonPool, // Rivalrous consumable resource; governance via quota/depletion rules Public, // Public/governmental stewardship; open-access; non-alienable by the public body Nondominium, // Uncapturable by design; contribution-based access; no alienation permitted } }
Mixed is removed — mixed regimes should be expressed as compound governance rules on top of a primary regime, not as a separate enum variant (which conveys no information about what the mix contains). Individual is renamed to Private to align with OVN property vocabulary. Public is included so publicly stewarded assets (libraries, parks, municipal infrastructure) can be modelled without collapsing them into Commons or Nondominium. Condominium and TollGoods are omitted from the initial generic NDO — they can be added as future variants if communities require them.
Complexity economics note: The OVN wiki states: "Property regime is not merely a legal classification, it shapes the entire economic topology of flows. A resource under the Nondominium regime cannot be enclosed, which is a stronger guarantee than a Commons resource (which can theoretically be privatised through governance capture)." This is precisely the Bar-Yam complexity matching principle applied to governance: the information requirements for different property regimes are vastly different. A Private resource can be governed by simple bilateral contracts. A Public resource requires non-alienation under public stewardship without claiming cryptographic uncapturability. A Nondominium resource requires cryptographic enforcement of uncapturability — human agreements are insufficient. The NDO's Holochain DHT architecture provides the technical foundation for Nondominium governance at scale; encoding the regime explicitly in the data model closes the loop between the technical guarantee and the social norm.
4.5 Accessibility, Availability, and Rivalry
The OVN wiki provides three orthogonal classification axes that NDO does not yet model:
Accessibility (who can access the resource):
- Free: public, no restrictions
- Protected/regulated: requires credentials — skill, role, reputation, or payment. In the NDO, "credentialed" access encompasses:
- Role-based: existing
RoleTypemembership, enforced by GovernanceRuleenforced_byfield - AffiliationState-based (post-MVP, TODO G2): derived from participation history via
AffiliationRecordentries — e.g.ActiveAffiliateorCoreAffiliatetier. Not declared but computed; harder to game than assigned roles - PortableCredential-based (post-MVP, TODO G8): cross-network verifiable claims from allied networks, enabling recognition of contribution history that happened elsewhere
- ZKP-based (post-MVP, TODO G7): privacy-preserving proofs of the form "I have ≥ N claims of type T" without revealing raw scores, counterparties, or timestamps — prerequisite for governance access without surveillance
- FlowstaIdentity-based (post-MVP): cross-app identity via
FlowstaIdentityCapabilitySlot on the agent'sPersonentry hash pointing to a dual-signedIsSamePersonEntry(Vault agent linking). Tier 1 (REQ-NDO-CS-12/CS-13) is a voluntary trust signal; Tier 2 (REQ-NDO-CS-14/CS-15) lets governance require a valid link for high-value or high-risk resource access — sybil resistance and cross-network accountability without revealing private PPR data
- Role-based: existing
- Formally restricted: requires formal approval procedures
This maps to governance rule patterns in NDO but is not a first-class property. Encoding it explicitly would allow the system to set appropriate governance defaults and UI affordances automatically.
Availability (how much is there):
- Abundant: near-zero marginal reproduction cost (ideas, designs, documents)
- Scarce: high marginal reproduction cost (physical tools, equipment, materials)
And the related distinction:
- Rivalrous: access by one agent excludes others
- Non-rivalrous: multiple agents can access simultaneously without exclusion
This is the most critical missing dimension in the NDO plan. Rivalry determines optimal governance strategy more directly than any other property. Non-rivalrous resources should default to open access (information wants to be free); rivalrous resources require access scheduling, usage tracking, and maintenance governance. The generic NDO should model rivalry explicitly as a first-class EconomicResource property.
Complexity economics note: Benkler's entire argument for commons-based peer production rests on the distinction between rivalrous and non-rivalrous resources. A P2P governance system that does not formally model this distinction will produce governance rules that are either too restrictive for non-rival resources (inefficient) or too permissive for rival resources (destructive).
4.6 Transferability
| OVN transferability | Description | NDO coverage |
|---|---|---|
| Transferable | Can change ownership (currency, consumables) | Custody transfer in EconomicResource; ownership transfer in EconomicEvents |
| Non-transferable | Cannot be sold or given (social capital, reputation) | PPRs are non-transferable by design (cryptographic linkage to agent key) |
| Shareable | Commons / pool items — shared without ownership transfer | GovernanceRules can encode this but it is not a first-class classification |
The OVN wiki makes an important observation: allowing non-transferable assets (like reputation) to be transferred would destroy their value — "allowing this would in fact destroy the reputation system, as its meaning would be called into question." This is why Nondominium PPRs are cryptographically linked to the generating agent's key pair and cannot be assigned to another agent.
Flowsta's FlowstaIdentity CapabilitySlot introduces an important nuance: PPR reputation becomes attributable across apps (via a verified W3C DID) without becoming transferable. The DID is a stable cross-app reference key — other Flowsta-linked apps can verify that a given reputation history belongs to a specific cross-app identity — but the underlying PrivateParticipationClaim entries remain cryptographically bound to the generating agent's key pair on this DHT. Attribution portability and claim transferability are orthogonal: the former enables cross-network trust signals; the latter remains forbidden to preserve the integrity of the reputation system.
Complexity economics note: Transferability determines what kind of market or exchange system applies to a resource. Non-transferable resources require non-market coordination mechanisms (gifting, contribution tracking, reputation systems). The NDO already enforces non-transferability of PPRs at the cryptographic level. Extending this concept to other resources (should a method always be shareable? should equipment ever be non-transferable? these are governance questions) requires transferability to be a formal property.
4.7 Scope
The OVN wiki classifies resources by the domain they can affect:
| Scope | Description | Examples |
|---|---|---|
| Project / Venture | Benefit mostly the specific project team | A bespoke chemical solution for a single R&D project |
| Network | Benefit the entire organisational network | A shared lab space, the network website |
| Public | Commons accessible to the entire world | Open source designs, documented methods |
This dimension is completely absent from the current NDO data model. Its importance for the generic NDO is significant: visibility, discovery, and governance rules for a network-scoped resource should differ from those of a public resource. A public design file should be discoverable globally; a project-scoped resource should only be visible to project participants.
4.8 Source
The OVN wiki tracks resource provenance:
| Source | Description |
|---|---|
| OVN | Created within the network; part of commons/nondominium/pool |
| Partners | Contributed by allied networks with possible use restrictions |
| Purchased | Acquired through market exchange; property of the network |
In the NDO, this is modelled as a ResourceSource enum on NondominiumIdentity (Layer 0, see §6.1). It matters for governance (a purchased resource may still be owned by its buyer and not be a true nondominium) and for attribution (OVN-sourced resources carry contribution history; purchased resources do not).
4.9 Reliability
The OVN wiki identifies reliability as a property of material usables — distinct from, but analogous to, agent reputation:
"Material resources, mostly usables, should have a parameter of reliability, which is related to the risk associated with their use... Is that piece of equipment going to break during the fabrication process? Is that sensor going to present accurate data?"
This is currently absent from the NDO model. A resource can have high-quality custodians (good PPR scores) but be itself unreliable (it breaks frequently, produces defective outputs, or presents safety risks). Resource reliability should be:
- Accumulated from economic events: repair events, usage incidents, quality validation failures
- Independent of custodian reputation: a reliable agent can custody an unreliable tool
- A governance input: unreliable resources may require pre-access inspection, reduced access frequency, or mandatory insurance
Complexity economics note: In information theory, reliability is a measure of signal-to-noise ratio. A governance system that cannot distinguish reliable from unreliable resources is processing high-noise information — it cannot direct maintenance effort, access restrictions, or replacement decisions to where they are most needed.
4.10 Intangibles as Resources
The OVN wiki provides the most extensive taxonomy in the entire resource ontology for intangibles, identifying:
- Brand (network and deliverable identity)
- Social capital (opening markets, driving campaigns)
- Group dynamics (energising and animating a community)
- Member/customer loyalty
- Synergy (linking ventures in value systems)
- Internal structure and relationships (weaving agent networks)
- Incentive systems (designing and embedding incentives)
- Competencies (individual skill, group know-how)
- Cultural values (maintaining and evolving culture)
- Governance resources (decision-making knowledge and mechanisms)
- Trust (trust by members in the network, in its metrics, in its fairness)
- Sense of community
These cannot be traded, transferred, or precisely measured. But they are:
- Outputs of participation (being part of a well-functioning community increases social capital)
- Inputs to production (communities with high trust and good governance outperform those without)
- Destroyable by bad governance (surveillance capitalism, governance capture, and unfair systems all erode intangibles)
For the generic NDO, the implication is: do not model intangible resources as DHT entries. Instead, design the system's governance and participation architecture so that positive interactions generate intangibles as emergent properties. The PPR system, the reputation-credit loop, the transparent governance architecture, the permissionless access — these are design choices that cultivate social capital, trust, and community sense without attempting to track them as assets. The NDO should be consciously designed as an intangible resource producer, not just a material resource tracker.
5. Gap Analysis
5.1 Mapped — OVN coverage implemented or planned in NDO
| OVN concept | NDO implementation | Status |
|---|---|---|
| Resource Type (specification/instance distinction) | ResourceSpecification + EconomicResource | ✅ Implemented |
| NDO Layer 0 identity anchor | NondominiumIdentity + discovery anchors | ✅ Implemented (PR #80/#84) |
| Property regimes (Private, Commons, Collective, Pool, CommonPool, Public, Nondominium) | PropertyRegime enum on Layer 0 | ✅ Implemented (7 variants; UI exposes all 7) |
| Value chain maturity stages | LifecycleStage enum (10 stages) on Layer 0 | ✅ Implemented |
| Embedded governance rules | GovernanceRule entries linked to ResourceSpecification | ✅ Implemented (weakly typed) |
| Physical resource custody | EconomicResource.custodian, custody transfer | ✅ Implemented (single custodian, assumed individual agent — gap: collective agent custodianship not supported; TODO G1) |
| Multi-custodian / shared custody | Many-to-many flows | 🔄 Planned |
| Capture resistance | DHT architecture + Holochain's append-only model + Layer 0 permanence | ✅ Architectural property |
| Digital resources (composable, integrity) | Digital Resource Integrity | 🔄 Planned |
| Versioning / DAG evolution | NdoHardLink (Component/DerivedFrom/Supersedes) + versioning.md full DAG | 🔄 Partial (NdoHardLink ✅; full DAG planned) |
| Contribution tracking | PPR system, Contribution entry, Layer 2 EconomicEvents | ✅ Implemented (PPR structures + Contribution; Layer 2 NDO link pending) |
| OVN license / contribution propagation | Contribution + versioning upstream propagation | 🔄 Partial (Contribution ✅; upstream propagation not) |
| Benefit redistribution / economic agreements | Agreement + BenefitClause on NDO identity | 🔄 Partial (data model ✅; Unyt/RAVE wiring not) |
| Economic settlement | Unyt integration | 🔄 Planned (post-MVP) |
| Cross-app identity / DID | FlowstaIdentity CapabilitySlot via Flowsta agent linking (ndo_prima_materia.md Section 6.7) | 🔄 Planned (post-MVP) |
| Agent key recovery | Flowsta Vault BIP39 recovery, auto-backup, CAL-compliant data export | 🔄 Planned (post-MVP) |
5.2 Partial — concepts present in OVN and partially covered in NDO
| OVN concept | NDO partial coverage | Gap |
|---|---|---|
| Resource nature (physical/digital/media) | ResourceNature enum on Layer 0 (Physical, Digital, Service, Hybrid, Information) | Missing Mental analog (represented by Ideation-stage NDOs); media channel vs. media item distinction absent; forward-map Space/Method/Currency (§6.2) not in code |
| Operational vs lifecycle state | LifecycleStage on Layer 0 ✅; OperationalState on EconomicResource ✅ | Governance-operator operational transitions (REQ-NDO-OS-02–03) deferred |
| Governance of access (role-based) | Role-based enforced_by in GovernanceRule | Rule types are untyped strings; no first-class accessibility classification |
| Material/Immaterial behavior | Physical vs. Digital/Information/Service nature | No formal rivalrous/non-rivalrous property |
| Method as resource | Digital or Information nature covers some cases | No dedicated Method variant or template/recipe entry type |
| Property regime: Nondominium vs. Commons vs. Public | Distinct variants in PropertyRegime (§6.3) | ✅ Resolved — no-enclosure (Nondominium) distinct from community stewardship (Commons) and public-body stewardship (Public) |
| Transferability | Custody transfer + PPR non-transferability | No formal transferability classification on resources |
| Reliability | Not modelled at resource level | PPR tracks agent quality, not resource condition/reliability |
| NDO three-layer activation | Layer 0 ✅ | Layers 1 & 2 link types (NDOToSpecification, NDOToProcess) not implemented |
5.3 Missing — OVN concepts not yet planned in NDO
These represent the forward agenda for the generic NDO design:
| OVN concept | Gap description | Proposed resolution |
|---|---|---|
| Rivalrous / Non-rivalrous | Fundamental governance fork not modelled; all resources treated equivalently | Add rivalry: Rivalrous | NonRivalrous field to NondominiumIdentity (Layer 0, see §6.1); derive governance defaults from this property |
| Resource scope (Project / Network / Public) | Visibility and governance should differ by scope; not modelled | Add ResourceScope enum to NondominiumIdentity; drive discovery anchor selection from scope |
| Resource source (OVN / Partner / Purchased) | Provenance matters for attribution and governance | Add ResourceSource enum to NondominiumIdentity |
| Space as resource type | Physical spaces need scheduling, booking, temporal availability | Add Space to ResourceNature (§6.2 forward map); not in code — design temporal availability governance patterns |
| Method / Recipe as resource type | Process documentation is a resource with its own governance | Add Method to ResourceNature (§6.2 forward map); not in code — link methods to the physical resources they govern |
| Currency as resource type | Currencies (including Unyt Base Units) are resources in the OVN model | Add Currency to ResourceNature (§6.2 forward map); not in code — Unyt Alliance represents a currency resource |
| Resource reliability | A tool's track record (failure rate, repair history) is independent of custodian reputation | Add reliability_score: Option<f64> derived from EconomicEvents (repair, incident PPRs); update on each Repair/Maintenance event |
| Accessibility classification | Free / Protected / Restricted as a first-class property | Add Accessibility enum; governance defaults derived from this |
| Transferability classification | Formal encoding of transferable / non-transferable / shareable | Add Transferability enum; informs custody transfer governance |
| Nondominium as distinct PropertyRegime | Nondominium (no-enclosure guarantee) ≠ Commons (shared stewardship) | Resolved in §6.3 — Nondominium variant added to PropertyRegime with validation that no governance rule can assert or transfer ownership |
| Affiliation-gated resource access | Role membership alone is insufficient for high-stakes access to rivalrous resources — participation quality (affiliation tier) should also gate access. GovernanceRule currently evaluates only role membership, not derived AffiliationState | Extend GovernanceRule.rule_data schema with min_affiliation field (e.g. "min_affiliation": "ActiveAffiliate"); extend governance operator evaluate_transition to cross-zome query AffiliationState from zome_person (refs G2, REQ-AGENT-03, REQ-AGENT-05) |
| Cross-app identity verification | No mechanism for an agent to prove they are the same person across multiple Holochain apps or external systems. PPR reputation is local to this DHT; no cross-network trust signal | Add FlowstaIdentity CapabilitySlot on Person hash (ndo_prima_materia.md Section 6.7, REQ-NDO-CS-12). Governance rules can require Tier 2–validated Flowsta linking for high-value access (REQ-NDO-CS-14, Flowsta Phase 3). Flowsta DID provides the cross-app identity anchor for portable credentials (REQ-NDO-AGENT-08) |
| Collective agent custodianship | EconomicResource.custodian is currently AgentPubKey, assuming individual agent. Collective, Project, Network, and Bot agents (G1) should also be valid custodians | Replace AgentPubKey with AgentContext (union type) across EconomicResource.custodian, TransitionContext.target_custodian, and NondominiumIdentity.initiator (ref G1, REQ-AGENT-02) |
| Intangibles | Social capital, trust, competencies — not tracked but should be preserved | Design principle: NDO governance architecture should cultivate intangibles as emergent properties, not track them as entries |
| Source as ontological primitive | Generative ecological systems (watersheds, fisheries, forests) and knowledge commons fit neither Agent nor Resource faithfully. Modelling them as resources requires false primaryAccountable ownership; omitting them leaves depletion and ecological loading invisible | Introduce Source as a typed NDO specialization: SourceProfile entry linked to Layer 0, stewardedBy relation replacing custodian, vf:Source ValueFlows extension for flow endpoints. See source-ndo-requirements.md |
6. Forward Map: Generic NDO Resource Ontology
Based on the gap analysis, the generic NDO should extend its resource classification to the following model. This is a design proposal, not a requirements document — it will be refined as the generic NDO project begins.
6.1 Extended NondominiumIdentity (Layer 0)
Implementation status: Core Layer 0 fields (
name,description,initiator,property_regime,resource_nature,lifecycle_stage,created_at,successor_ndo_hash,hibernation_origin) are ✅ implemented. Classification fields below marked NEW are forward-map additions not yet in code.
#![allow(unused)] fn main() { pub struct NondominiumIdentity { // Existing fields pub name: String, pub description: Option<String>, pub initiator: AgentPubKey, pub lifecycle_stage: LifecycleStage, pub created_at: Timestamp, // Classification fields (drive governance defaults) pub property_regime: PropertyRegime, // existing pub resource_nature: ResourceNature, // extended pub rivalry: Rivalry, // NEW pub scope: ResourceScope, // NEW pub source: ResourceSource, // NEW pub accessibility: Accessibility, // NEW pub transferability: Transferability, // NEW } }
6.2 Extended ResourceNature
Implementation status: Code implements
Physical, Digital, Service, Hybrid, Information(see §2.1). Forward-map variantsSpace,Method, andCurrencybelow are not yet in code.
#![allow(unused)] fn main() { pub enum ResourceNature { Physical, // ✅ Material objects: tools, equipment, consumables Digital, // ✅ Software, data, design files, documents Service, // ✅ Software services, knowledge assets (in code, not in original forward map) Hybrid, // ✅ Digital twin of a physical resource Information,// ✅ Knowledge assets, data sets (in code, not in original forward map) Space, // 🔄 Physical or virtual locations with temporal availability Method, // 🔄 Documented process, recipe, protocol Currency, // 🔄 Symbolic value exchange system (including Unyt Alliance Base Units) // Note: Mental resources are represented by Ideation-stage NDOs, not a separate type } }
6.3 Extended PropertyRegime
Implementation status: All seven variants below are ✅ in Rust (
crates/shared/src/types.rs) and ✅ exposed in the UI (packages/shared-types, creation form, filters, badges).
#![allow(unused)] fn main() { pub enum PropertyRegime { Private, // Full rights bundle; individual ownership (renamed from Individual per OVN vocabulary) Commons, // Non-rivalrous shared resource; governance via licensing/attribution Collective, // Cooperative/collective ownership Pool, // Pool of shareables: rivalrous shared resources; custody/scheduling/maintenance CommonPool, // Rivalrous consumable resource; governance via quota/depletion rules Public, // Public/governmental stewardship; open-access; non-alienable by the public body Nondominium, // Uncapturable by design; contribution-based access; no alienation permitted } }
6.4 New Classification Enums
#![allow(unused)] fn main() { pub enum Rivalry { Rivalrous, // Use by one agent excludes others; access governance required NonRivalrous, // Multiple agents can access simultaneously; open access preferred } pub enum ResourceScope { Project, // Benefits mostly the specific project/venture team Network, // Benefits the entire organisational network Public, // Commons accessible to the entire world } pub enum ResourceSource { Network, // Created within the network (OVN/nondominium) Partner, // Contributed by allied networks (may have use restrictions) Purchased, // Acquired through market exchange Donated, // Gifted with conditions } pub enum Accessibility { Free, // Open access, no restrictions Credentialed, // Requires role, reputation, or demonstrated skill Gated, // Requires formal application and approval } pub enum Transferability { Transferable, // Ownership can change (exchange, gifting) NonTransferable, // Cannot be exchanged or gifted (reputation, social capital) Shareable, // Pool/commons items: shared without ownership transfer } }
6.5 Resource Reliability (Layer 2 derived property)
Resource reliability should be derived from Layer 2 EconomicEvents rather than stored as a static field — it is an emergent property of the resource's history, not a declared attribute:
reliability_score ← derived from:
- Repair event frequency (more repairs = lower reliability)
- Maintenance completion rate (scheduled vs. emergency maintenance ratio)
- Incident reports (damage, failure, safety events)
- Quality validation results (passed vs. failed inspections)
This score accumulates over time and is queryable from the governance zome alongside the custodian's ReputationSummary. A resource reliability score and a custodian reputation score together give a complete picture of a resource interaction's risk profile.
6.6 Governance Defaults from Classification

Three classification axes (ResourceNature, Rivalry, PropertyRegime) determine which governance rule templates apply. Digital + NonRivalrous + Commons → open access + copy-left. Physical + Rivalrous + Pool → credentialed access + custody transfer + maintenance schedule. Defaults are starting points overridable by community GovernanceRule entries on Layer 1.
The power of explicit resource classification is that it enables automatic governance defaults. The generic NDO should define a GovernanceDefaultsEngine that derives appropriate starting governance rule templates from the classification:
| Nature | Rivalry | Property | Governance defaults |
|---|---|---|---|
| Digital | NonRivalrous | Commons | Open access, copy-left attribution, versioning required |
| Digital | NonRivalrous | Nondominium | Open access, attribution, no enclosure possible |
| Physical | Rivalrous | Pool | Credentialed access, custody transfer required, maintenance schedule |
| Physical | Rivalrous | Nondominium | Permissionless access under rules, peer validation, PPR required |
| Space | Rivalrous | Pool | Booking/scheduling, temporal access governance |
| Method | NonRivalrous | Commons | Open access, execution tracking, version-linked |
| Currency | NonRivalrous | Network | Defined by Unyt Alliance configuration |
These defaults are starting points — communities override them through the GovernanceRule entries on Layer 1. But having well-considered defaults dramatically reduces the governance design burden for community members setting up new resources.
TODO (G2, G7, G8 — post-MVP): The
Credentialed accessdefaults shown forPool(Physical/Rivalrous/Pool) andNondominiumrows above will eventually support three additional credential dimensions beyond role membership:
AffiliationState-based gating (G2): the governance operator querieszome_personfor the requesting agent's derived affiliation tier and compares it to themin_affiliationcondition inGovernanceRule.rule_dataPortableCredentialacceptance (G8): governance rules can declare which external credential types they accept, enabling cross-network access without re-joining- ZKP-compatible evaluation (G7): reputation proofs are verified without revealing raw PPR scores or counterparties
FlowstaIdentityTier 1 (Flowsta Phase 1; REQ-NDO-CS-12, REQ-NDO-CS-13): Agents can attach aFlowstaIdentityslot on theirPersonhash to a validIsSamePersonEntry(Vault dual-signed attestation), making a DID discoverable and enabling cross-app attribution of reputation — withoutAffiliationRecord,PortableCredential, or ZKP infrastructure. The governance zome does not enforce Tier 1 (ndo_prima_materia.mdSection 6.7).FlowstaIdentityTier 2 (Flowsta Phase 3; REQ-NDO-CS-14, REQ-NDO-CS-15): Governance rules can require a valid Flowsta link (per REQ-NDO-CS-15 checks) for credentialed access to resources that need sybil resistance or cross-network accountability — same phase and pattern as Unyt governance-operator enforcement (ndo_prima_materia.mdSection 6.7).The AffiliationState, PortableCredential, and ZKP dimensions above require the
AffiliationRecordentry type (REQ-AGENT-05), cross-zomeAffiliationStatequeries, and/or ZKP proof infrastructure — all post-MVP. Flowsta Tier 1 is the exception among trust signals: voluntary linking can ship in Flowsta Phase 1 without those dependencies. Flowsta Tier 2 enforcement requires Flowsta Phase 3 (zome_gouvernancechanges), not Phase 1.
7. Complexity Economics Justification: Why Each Classification Matters
Rivalry matters because it determines the fundamental economic logic. Non-rivalrous resources exhibit positive sum dynamics — sharing them creates more value, never less. Rivalrous resources exhibit zero-sum dynamics in the short term — access by one agent genuinely prevents access by another. Conflating these in a governance system produces either over-restriction (damaging information flows) or under-restriction (depleting physical commons). No other classification has more direct governance consequences.
Scope matters because it determines information propagation. Benkler's analysis of networked information environments shows that scope determines who needs to know about a resource for it to produce value. A method that benefits the entire world should propagate globally; a specialised tool scoped to one project should not create noise in the global discovery layer. Scope-driven discovery anchors reduce the information overhead of the global DHT.
Property regime matters because it encodes the relationship between the resource and its community. A Nondominium resource cannot be captured, enclosed, or removed from the commons — this is a hard guarantee built into its governance validation rules. A Commons resource can be governed into restriction by its stewards. Individual-owned resources can be withheld. The economic consequences of each regime are profound and should be permanent attributes of the resource's identity, not mutable governance settings.
Reliability matters because it is information. In a P2P system with no central quality control, agents making decisions about which resources to access, which tools to borrow, which methods to follow, need reliable information about the track record of those resources. A resource with a high failure rate imposes hidden costs on the network — missed deadlines, wasted materials, unsafe working conditions. Making reliability visible and queryable converts hidden costs into explicit governance inputs.
Resource nature and method resources matter because the governance architecture for a documented protocol is fundamentally different from the governance architecture for a physical tool. A method (recipe, process, protocol) is non-rivalrous, can be forked and adapted, should be versioned and attributed, and its quality affects every physical process it governs. Modelling methods as first-class resources enables the network to track method provenance, quality, and evolution — and to connect method quality to the physical resource outcomes produced using those methods.
Intangibles matter negatively — as a design constraint. The OVN wiki's extensive treatment of intangibles is a warning: governance systems that ignore social capital, trust, and community sense will inadvertently destroy them through surveillance, commodification, or capture. The NDO's design choices (peer validation rather than central authority, private PPRs rather than public scoring, permissionless access rather than gatekeeping) are intangible-preserving choices. They should be recognised as such, so that future design decisions are evaluated against the same standard.
Source as third ontological category matters because omitting it makes ecological commons invisible to the economic ledger. Without Source, depletion events appear as raise (resource-from-nowhere), ecological loading disappears entirely, and the false fiction of an owning agent must be maintained for every watershed and fishery under Nondominium governance. The governance-as-operator architecture is exactly suited to Source-NDOs: the event ledger accumulates boundary signals, stewards interpret them, governance rules adapt, and future access is conditioned by source health — a cybernetic loop that implements adaptive governance for complex ecological systems. This matters because the single most important use case for the Nondominium property regime in natural commons is ecological: fisheries, watersheds, forests. A governance system that cannot model these without distortion is unsuitable for the most important commons of all.
This is a living document. As the generic NDO project begins, the gap analysis in Section 5.3 should be converted into formal requirements. The forward map in Section 6 should be reviewed against the actual NDO project scope and prioritised accordingly. The OVN wiki at ovn.world remains the authoritative reference for community-validated resource ontology concepts.
Governance: Ontology, Implementation, and Forward Map
Type: Archive / Knowledge Base Document
Created: 2026-03-11
Relates to: ndo_prima_materia.md, unyt-integration.md, flowsta-integration.md, resources.md, agent.md
Sources: MVP code (zome_gouvernance, zome_person), post-MVP design documents, OVN wiki — Governance
Purpose
This document maps the three states of Governance understanding in the Nondominium / NDO project:
- Implemented — what exists today in the MVP
zome_gouvernanceandzome_personcodebases - Planned — what is designed in post-MVP requirements documents
- Remaining — what the OVN wiki's 15 years of commons-based peer production practice contains that NDO does not yet plan to implement
The goal is to ensure that the generic NDO — built as a standalone hApp — represents a principled, complete governance architecture that can support diverse communities and use cases through configuration, not custom code.
1. Conceptual Foundation: Governance in P2P Complexity Economics
1.1 What Governance Is (and Is Not)
The OVN wiki defines governance as "a means of direct influence for an organization." More structurally, it has three core functions:
- Selection — choosing among alternatives; decision-making
- Enforcement — enacting and reinforcing choices
- Adaptation — sensing, feedback, and evolving the rules
In traditional organisations, governance is largely concentrated: a small group selects, enforces, and adapts. In P2P open networks, all three functions must be distributed across a large, permeable, changing set of participants — without centrally controlled bottlenecks. This is not a political preference; it is an information-theoretic necessity. Bar-Yam's complexity matching principle: the governance system's complexity must match the organisational complexity it manages. As the network grows and its challenges diversify, only distributed governance can keep pace.
1.2 Embedded Governance and Stigmergy
The most important governance concept for the NDO is embedded governance: engineering the environment so that desirable behaviour is facilitated and undesirable behaviour is made impossible or costly, rather than relying on policing.
The OVN wiki describes this precisely: "Embedded governance (or immanent governance) is about engineering the environment in which actions are deployed to direct, channel or shape action, to take away the possibility of undesirable or less desirable action alternatives."
In practice: instead of writing a rule "you must not transfer a resource without a validated custodian," make it technically impossible to record a custody transfer without a prior commitment accepted by an accountable agent, based on enbedded rules, following validation. The rule is in the architecture, not in a policy document that humans can ignore.
This is also stigmergy in the complexity economics sense: governance through environmental modification. Ants do not follow written rules — their collective behaviour emerges from pheromone trails (environmental signals) that individual agents respond to locally. The NDO's capability slot surface (Layer 0 stigmergic attachment) is exactly this: governance emerges from what agents choose to attach to resources, without central coordination.
The same stigmergic attachment pattern applies to agent identity anchors: a FlowstaIdentity capability slot on the agent's Person entry hash (ndo_prima_materia.md Section 6.5 defines the Person attachment surface; Section 6.7 specifies Flowsta). Tier 1 is permissionless at the DHT level; Tier 2 is when a community turns that signal into a hard governance precondition via typed GovernanceRule mechanisms (Flowsta Phase 3).
The distinction between soft and hard embedded governance matters:
- Hard embedded: cryptographic impossibility of the prohibited action (Holochain validation rules, capability tokens)
- Soft embedded: social norms encoded as discoverable defaults (GovernanceRules marked as required, reputation consequences)
The NDO primarily uses hard embedded governance (Holochain integrity zomes are cryptographic) with soft embedded governance at the application layer (GovernanceRules are data that agents must choose to enforce in their coordinator logic).
1.3 Governance as Signal Processing, Not Rule Enforcement
The OVN wiki makes a critical distinction: OVN governance is not "rules-based, but rather signal-based, as norms emerge in real time from agent preferences, in context." Rules assume a known, closed world. Signals are the governance of complex, open, evolving systems.
In complexity economics terms: the adjacent possible (Kauffman) is never fully knowable. Rules written today cannot anticipate tomorrow's edge cases. The governance architecture must support emergence — agents should be able to propose and enact new norms through their behaviour, not just comply with pre-written rules.
This has direct implications for NDO design: the governance layer should expose proposing, voting, and adapting mechanisms as first-class capabilities, not just enforcement mechanisms. The current MVP focuses almost entirely on enforcement. Adaptation is barely present. Proposal is absent.
1.4 The REA Governance Parallel
The OVN wiki makes a structural proposal with deep implications: "Architecture governance in a way that it becomes compatible with the organizational and economic model architecture. REA is used to model the economic reality of the network, use the same structure to describe governance."
This means: governance events are EconomicEvents. Governance policies are Resources. Governance actors are Agents. The Policy/Scheduling/Accountability layers of REA are the governance architecture, not just the economic architecture.
The implication: the NDO's zome_gouvernance — which already models EconomicEvents, Commitments, and Claims — should be the natural home for governance events as well. A decision to grant a role is a governance EconomicEvent. A governance proposal is a Commitment. The decision outcome is a Claim. This unification is not complete in the current codebase but is architecturally supported.
1.5 Holonic Multi-Scale Governance
The OVN is fractal: ventures nest in networks, networks nest in networks-of-networks. Each level has its own governance concerns, while sharing protocols and standards. The NDO, as a holon (simultaneously whole and part), needs governance that is self-similar across scales — the same primitives should work at the instance level, the network level, and the federation level.
The OVN wiki defines three governance layers:
- Network-of-networks (ecosystem): protocols, standards, interoperability
- Network (commons community): shared resources, roles, benefit distribution
- Venture (project): specific work, specific benefit distribution
Currently the NDO implements only resource-level governance (single resource interactions, agent roles, process validation). Network and federation-level governance are absent.
1.6 Ostrom's Principles as NDO Architecture
Elinor Ostrom's 8 principles for governing commons (Governing the Commons, 1990) provide a design checklist for the NDO governance architecture:
| Ostrom's Principle | NDO implementation |
|---|---|
| 1. Clearly defined boundaries (who is in) | Role system: SimpleAgent / AccountableAgent / PrimaryAccountable + functional roles |
| 2. Match rules to local conditions | GovernanceRules embedded in ResourceSpecifications (per-resource rules) |
| 3. Collective choice arrangements | Gap: No formal participation in rule-making by affected agents |
| 4. Monitoring (observation of rules and resources) | EconomicEvents + PPR system provides comprehensive audit trail |
| 5. Graduated sanctions | Gap: PPR system tracks rule compliance, but sanctions are informal |
| 6. Conflict-resolution mechanisms | Gap: Only a PPR category exists; no dispute resolution process |
| 7. Minimal recognition of rights | Architectural property: Holochain permissionless access |
| 8. Nested enterprises (multi-scale) | Gap: Only single-level governance; no nested structure |
2. Current Implementation (MVP)
2.1 Governance-as-Operator Architecture
The most important architectural choice in the MVP is the separation of data from governance logic:
zome_resource: pure data model — creates and storesResourceSpecification,EconomicResource,GovernanceRuleentries without enforcing any business logiczome_gouvernance: state transition operator — the resource zome requests transitions, the governance zome evaluates the applicable rules and approves or rejects them
This is the REQ-ARCH-07 design. It means governance logic can evolve without touching the data model, different governance schemes can be applied to the same resource types, and governance is independently testable.
This architecture is the NDO's most principled contribution to governance design — it directly implements the OVN insight that governance must be compatible with the economic model (REA), because governance and economics are handled by the same zome operating on the same entry types.
2.2 VfAction System (16 Actions)
The VfAction enum defines all possible economic actions, and by extension, all possible governance-relevant state transitions:
Standard ValueFlows actions: Transfer, Move, Use, Consume, Produce, Work, Modify, Combine, Separate, Raise, Lower, Cite, Accept
Nondominium-specific extensions: InitialTransfer (first transaction by a Simple Agent, triggering role promotion), AccessForUse (access request triggering governance evaluation), TransferCustody (custody-specific transfer preserving nondominium property regime)
Each action has semantic methods: requires_existing_resource(), creates_resource(), modifies_quantity(), changes_custody(). This is the deontic layer — actions are typed by their governance implications.
2.3 Commitment / EconomicEvent / Claim Cycle
The MVP implements the core ValueFlows observation cycle:
Commitment (intent + obligation)
└─ EconomicEvent (what actually happened)
└─ Claim (link: this event fulfills that commitment)
This is the planning → observation bridge. Commitments are governance artifacts: they are the declared intent of an agent, time-bound, linking provider and receiver for a specific VfAction on a specific resource. The claim verifies fulfillment. The entire chain is auditable on the DHT.
This cycle is both governance and economics — consistent with the OVN wiki's REA governance parallel.
2.4 Validation System
ValidationReceipt: a peer-issued record that a specific item (resource, event, agent identity) was validated by a specific agent, with an approval decision, type, notes, and timestamp.
ResourceValidation: a multi-agent validation workflow for a specific resource, with configurable schemes ("2-of-3", "simple_majority", "N-of-M"). Tracks current vs. required validator counts and aggregate status.
The validation system implements the monitoring and graduated sanction aspects of Ostrom's principles: it is the mechanism by which the community collectively validates that resources, agents, and processes meet the network's standards before they gain access to higher-trust activities.
Validation functions in the coordinator:
validate_new_resource: validates a resource being added to the networkvalidate_agent_identity: validates an agent's private identity data for role promotionvalidate_specialized_role: validates a request for Transport, Repair, or Storage rolescreate_resource_validation: creates a multi-agent validation workflowcheck_validation_status: queries whether required validators have approved
2.5 The PPR System: 16 Categories, Bilateral Cryptographic Signatures
The Private Participation Receipt (PPR) system is the most complete governance mechanism in the MVP. It generates cryptographically signed, private receipts grounded in ValueFlows commitments and events.
In the MVP, each recorded economic interaction uses a single provider and a single receiver on the DHT (one-to-one ValueFlows pattern). For that interaction, the PPR model is pairwise bilateral: each party holds a receipt that names the other as counterparty, and two coordinated receipts capture the same underlying event from both sides (private-participation-receipt.md — “two receipts per action”). This is bilateral accountability per interacting pair, not a single shared “group receipt.”
Broader participation topologies (one-to-many, many-to-one, and many-to-many custody transfers, shared co-custodianship, resource pools, and delegation among co-custodians) are specified as post-MVP extensions to EconomicEvent / Commitment and to how PPRs are issued and attributed when several providers or receivers are involved (post-mvp/many-to-many-flows.md §1–2, Phase 5, REQ-MMF-19–22). Until that work lands, interactions that socially involve more than two agents must still be represented as sequences or combinations of one-to-one events and pairwise PPRs, or omitted from structured monitoring (see gaps in Sections 2.8 and 6 of this document and implementation_plan.md (many-to-many / AgentContext)).
PrivateParticipationClaim entry structure:
#![allow(unused)] fn main() { pub struct PrivateParticipationClaim { pub fulfills: ActionHash, // References the Commitment pub fulfilled_by: ActionHash, // References the EconomicEvent pub claimed_at: Timestamp, pub claim_type: ParticipationClaimType, // One of 16 categories pub performance_metrics: PerformanceMetrics, pub bilateral_signature: CryptographicSignature, // Both parties sign pub counterparty: AgentPubKey, pub resource_hash: Option<ActionHash>, pub notes: Option<String>, } }
The 16 ParticipationClaimType categories across 5 groups:
| Group | Categories | Governance role |
|---|---|---|
| Genesis | ResourceCreation, ResourceValidation | Network entry, contribution tracking |
| Core custody | CustodyTransfer, CustodyAcceptance | Custody chain accountability |
| Services | MaintenanceCommitmentAccepted, MaintenanceFulfillmentCompleted, StorageCommitmentAccepted, StorageFulfillmentCompleted, TransportCommitmentAccepted, TransportFulfillmentCompleted, GoodFaithTransfer | Service economy accountability |
| Governance | DisputeResolutionParticipation, ValidationActivity, RuleCompliance | Governance participation tracking |
| End-of-life | EndOfLifeDeclaration, EndOfLifeValidation | Lifecycle management accountability |
PerformanceMetrics structure with weighted components:
timeliness(weight 0.25)quality(weight 0.30)reliability(weight 0.25)communication(weight 0.20)overall_satisfaction(additional signal)
Bilateral cryptographic signatures: for each pairwise PPR, the issuing agent's view and the counterparty's agreement are both reflected in the receipt design (mutual attestation to the claim). This is not merely authentication — it is mutual accountability for that two-party slice of the interaction. Multi-party flows will need extended signing and distribution rules (see many-to-many-flows.md Phase 3 and §4.5).
ReputationSummary: a derived, privacy-preserving aggregate that agents can selectively share. Counts by category, average performance, time period. The agent controls what they reveal; the summary proves they have a track record without revealing individual interactions.
The PPR system is the NDO's most direct implementation of Ostrom's monitoring principle. It is also the input to the governance equation (access to governance = f(contribution history)).
2.6 Role System and Capability-Based Access
RoleType enum: SimpleAgent, AccountableAgent, PrimaryAccountableAgent, Transport, Repair, Storage
The first three are governance tiers (graduated trust levels). The last three are functional roles (validated competencies for specific processes).
Role assignment is tracked in PersonRole entries (in zome_person), created by assigned_by agents with appropriate governance tier. Role transitions (SimpleAgent → Accountable, Accountable → Primary) require:
- Private identity validation by existing AccountableAgents
- Completion of first validated transaction (for Simple → Accountable)
- PPR milestones and specialist role validation (for Accountable → Primary)
Capability-based access (Holochain native): capability tokens gate cross-zome calls and agent-to-agent requests. The NDO extends this with:
PrivateDataCapabilityMetadata: tracks field-level access grants with 30-day maximum expiryRevokedGrantMarker: explicit revocation record (Holochain capability revocation does not leave a trace by default)
This is the access control layer of the deontic ontology: permissions are cryptographically issued and cryptographically revoked, not relying on runtime checks.
TODO (G1, REQ-AGENT-01, REQ-AGENT-02 — post-MVP): The role system and all governance workflows assume
AgentPubKeyas the requestor. Specifically:RoleTypeis assigned to individual agents only;ValidationReceipt.validated_byis a singleAgentPubKey; PPRcounterpartyis anAgentPubKey; andGovernanceTransitionRequest.requesting_agentis anAgentPubKey. Collective, Project, Network, and Bot agents (AgentEntityTypefromagent.md §6.1) cannot currently hold roles, participate in validation schemes, sign PPRs, or act as governance requestors. Post-MVP, role assignment must acceptAgentContext(a union of individual and collective agent references). Delegation rules for collective signing authority must be defined — e.g., a designatedPrimaryAccountableAgentrepresentative key for the collective NDO, or an N-of-M multi-sig from its member agents. Seeimplementation_plan.md §3 [G1+Resource]andagent.md §3.1.
2.7 What the MVP Does Well
- Governance-as-operator is the correct architectural pattern: clear separation of data model and governance logic, enabling swappable governance
- VfAction semantics — typed actions with governance implications — are a principled approach to deontic governance encoding
- Pairwise bilateral cryptographic PPRs are a novel and strong accountability mechanism; stronger than reputation systems that rely on one-sided ratings
- Multi-scheme validation (
"2-of-3","N-of-M") supports configurable collective decisions at the resource validation level - Graduated role tiers implement Ostrom's "clearly defined boundaries" principle
- Private-yet-derivable reputation (PPR → ReputationSummary) correctly addresses the privacy/accountability tension
2.8 Known Gaps in the MVP
| Gap | Impact | Status |
|---|---|---|
| No governance proposal mechanism | Agents cannot propose changes to GovernanceRules; changes require developer update | Planned indirectly via GovernanceRule update functions |
| No collective decision making | Only binary validation schemes; no conviction voting, quadratic voting, etc. | Gap |
| No dispute resolution process | Only a PPR category for dispute resolution participation; no actual mechanism | Gap |
| Governance tiers create de facto hierarchy | The Simple/Accountable/Primary tier system, while non-coercive, concentrates governance influence | Structural design tension |
| No metagovernance | Who can change the governance rules? No formal mechanism | Gap |
| No temporal governance | Rules don't expire; decisions don't sunset | Gap |
| No governance layers | Only venture-level governance; no network or federation layer | Gap |
| No registries | No formal lists of validated agents, active ventures, legitimate proposals | Gap |
| Governance rules untyped | rule_type and rule_data are free strings; no schema enforcement | Planned fix in ndo_prima_materia.md |
| No offchain governance bridge | No mechanism to record offchain decisions as DHT artifacts | Gap |
| ReputationSummary not used for governance weight | PPRs accumulate but don't mechanically influence governance access | Planned via Unyt credit limit integration |
| No affiliation spectrum in governance access | All validated agents treated equivalently; governance cannot enforce "active affiliates only" conditions; the 1-9-90 participation distribution is acknowledged conceptually but not implemented | Gap — requires AffiliationState (G2) cross-zome query from the governance operator; see agent.md §4.2, resources.md §4.5 |
| No collective agent governance participation | Collective, Project, Network, and Bot agents (G1) cannot hold roles, sign PPRs, or act as validators; economic events between a project and an organisation cannot be correctly modelled | Gap — requires AgentContext extension across role assignment, PPR issuance, and validation receipt; see agent.md §4.1 |
| No governance-enforced cross-app identity | Communities cannot cryptographically require a verified same-person link (W3C DID / IsSamePersonEntry) before high-trust transitions | Planned: IdentityVerification-style GovernanceRule + FlowstaIdentity slot checks (ndo_prima_materia.md Section 6.7, REQ-NDO-CS-14, REQ-NDO-CS-15) |
| No sybil resistance for governance | Multiple source chains controlled by one physical person can dilute validation quorums, game role promotion, or accumulate disproportionate PPR counts | Gap — requires social vouching (N existing active affiliates vouch for a new agent) or optional proof-of-personhood (G9); see agent.md §5.3. Planned complement (not replacement): optional Tier 2 Flowsta identity checks for high-trust roles (REQ-NDO-CS-14, ndo_prima_materia.md Section 6.7) |
| No pseudonymous governance participation | Pseudonymous or anonymous agents cannot accumulate PPRs or earn governance access without linking contributions to a persistent identity | Gap — by current design; pseudonymous participation mode (G10) is a post-MVP option with a defined affiliation path; see agent.md §4.5 |
3. Post-MVP Roadmap
3.1 Governance-as-Operator Extended to LifecycleStage
The prima-materia model introduces two orthogonal state dimensions, both governed by the governance zome acting as state transition operator:
LifecycleStage(10 stages onNondominiumIdentity): the maturity/evolutionary phase of the resource. Each transition requires a valid economic event and a role-authorized request. Examples:Prototype → Stable(peer validation),Active → EndOfLife(challenge period).OperationalState(7 states onEconomicResource): the current process acting on a resource instance. Transitions are triggered by process events: a transportMoveevent setsInTransit; its completion clears it back toAvailable. Transport, storage, and maintenance are processes — they do not advanceLifecycleStage.
Both dimensions generate auditable lifecycle history via EconomicEvent entries, extending the governance-as-operator pattern to cover the complete resource state model.
3.2 EconomicAgreement GovernanceRule Type (Unyt Integration)
The EconomicAgreement GovernanceRule type (see unyt-integration.md) adds programmable economic governance to the existing rule set. Unyt Smart Agreements (RHAI scripts) become governance rules — specifying not just who may act but what economic consequence follows. This is a direct implementation of the OVN's connection between governance and the economic model.
Identity verification for cross-app identity follows the same structural pattern: a discoverable CapabilitySlot (Tier 1) plus an enforceable GovernanceRule (Tier 2) — detailed in Section 3.7 (Flowsta).
3.3 NDO Capability Slot Surface (Stigmergic Governance)
The CapabilitySlot surface (Section 6 of ndo_prima_materia.md) enables stigmergic governance at the NDO level. Any agent can attach governance tools (a GovernanceDAO slot, a dispute resolution hApp, a voting tool) to any NDO's Layer 0 identity hash without modifying the NDO entry. Governance infrastructure attaches to resources, not the other way around.
That same ndo_prima_materia.md Section 6 also defines the Person entry hash as a capability surface for agents (e.g. FlowstaIdentity); as rules mature, the governance operator may read both resource Layer 0 attachments and agent identity attachments when evaluating transitions — without prescribing every MOSS tool in the DNA.
3.4 Many-to-Many Governance Consent
Multi-custodian consent mechanisms (from many-to-many-flows.md): when a resource has multiple custodians, governance decisions that affect it require multi-party consent. This brings network-level governance down to the resource level.
3.5 Reputation-Weighted Governance (via Unyt)
The PPR → Unyt credit limit feedback loop (unyt-integration.md Section 7) is the governance equation in practice: contribution history determines economic access, and economic access determines which governance interactions are available. This is not yet explicit governance weighting, but it creates the data foundation for it.
When both Unyt and Flowsta are adopted, a Flowsta DID (via a valid Tier 1 FlowstaIdentity slot and IsSamePersonEntry) can anchor cross-app attribution of the same reputation signals that inform Unyt credit limits (ndo_prima_materia.md Section 6.7, Section 11.6).
3.6 Agent Ontology Impacts on Governance-as-Operator (Post-MVP)
The expanded agent ontology from agent.md introduces three structural changes to the governance-as-operator architecture that must be addressed in the post-MVP generic NDO:
3.6.1 AgentContext as Requestor (TODO G1, REQ-AGENT-02)
The GovernanceTransitionRequest.requesting_agent: AgentPubKey field (see governance-operator-architecture.md §2.1) must be extended to requesting_agent: AgentContext post-MVP. AgentContext is a union that accommodates Individual, Collective, Project, Network, Bot, and ExternalOrganisation agent types (see agent.md §6.1). The governance evaluation functions validate_agent_permissions and validate_agent_for_promotion must be extended to handle each type. For Bot and collective agents, the signing authority is the operator: AgentPubKey declared in AgentEntityType::Bot, or the designated PrimaryAccountableAgent representative of the collective NDO. Multi-sig patterns (N-of-M from collective NDO members) are an alternative for high-stakes governance actions. See Section 6.6 of this document for the full collective agent governance pattern.
3.6.2 AffiliationState as Governance Condition (TODO G2, REQ-AGENT-03, REQ-AGENT-05)
The governance operator must support min_affiliation conditions in GovernanceRule.rule_data. When a GovernanceRule contains a min_affiliation field (e.g. "min_affiliation": "ActiveAffiliate"), the operator must:
- Cross-zome call
zome_personto retrieve the requesting agent'sAffiliationRecordentries - Derive the agent's current
AffiliationState(UnaffiliatedStranger | CloseAffiliate | ActiveAffiliate | CoreAffiliate | InactiveAffiliate) - Compare the state against the
min_affiliationthreshold and block the transition if the agent does not meet it
This is the mechanism by which the governance equation (Section 4.4, Section 6.4) becomes operationally enforceable — not merely a conceptual aspiration. Without this cross-zome query, the governance equation has no runtime implementation. See resources.md §5.3 (Affiliation-gated resource access) and implementation_plan.md §3 [G2+Resource].
3.6.3 AffiliationRecord as Governance Ceremony (TODO G6, REQ-AGENT-05)
Signing an AffiliationRecord — the formal Terms of Participation ceremony — is itself a governance event in the ValueFlows sense. Using the existing Commitment/EconomicEvent cycle:
- The agent creates a
Commitmententry: "I commit to the Terms of Participation, Nondominium & Custodian agreement, and Benefit Redistribution Algorithm" - The act of signing the
AffiliationRecordentry with the agent's key constitutes the fulfillingEconomicEvent - A
Claimlinks the two, creating an auditable on-chain record of the affiliation ceremony
The AffiliationRecord entry hash then becomes the evidence that the agent's AffiliationState function returns ActiveAffiliate. This is what transitions the agent from CloseAffiliate (knows the network, not yet committed) to ActiveAffiliate (has formally committed, gains governance access). No separate "activation" function is needed — the AffiliationState derivation reads the presence or absence of the AffiliationRecord directly from the DHT.
3.7 Flowsta Integration — Identity Verification Governance (flowsta-integration.md)
Parallel to Unyt (ndo_prima_materia.md Section 6.6 vs 6.7): Unyt combines a UnytAgreement capability slot with an endorsed EconomicAgreement GovernanceRule and, at full enforcement, a RAVE proof on the transition request. Flowsta combines a FlowstaIdentity capability slot on the agent's Person entry hash (target: an IsSamePersonEntry action hash committed by flowsta-agent-linking zomes) with an endorsed IdentityVerification rule (or equivalent typed rule): transitions that the rule scopes (e.g. PrimaryAccountableAgent promotion, high-value TransferCustody) are blocked unless Tier 2 validation passes (REQ-NDO-CS-15: slot present, IsSamePersonEntry includes requestor key, not revoked).
Tier 1 — permissionless attestation (REQ-NDO-CS-12, REQ-NDO-CS-13): FlowstaIdentity is a SlotType variant; any agent may attach a slot pointing at a valid IsSamePersonEntry. The governance zome does not require this for baseline participation.
Tier 2 — governance requirement (REQ-NDO-CS-14, REQ-NDO-CS-15): When an applicable rule is in force, evaluation shall verify: (a) a FlowstaIdentity capability slot exists from the requestor's Person hash; (b) the referenced IsSamePersonEntry includes the requestor's AgentPubKey as one of the two signing parties; (c) the link has not been revoked via the Flowsta coordinator's revoke_link (ndo_prima_materia.md Section 6.7).
Implementation locus (planned, not MVP): In ndo_prima_materia.md, Flowsta Phase 3 extends the same governance-operator / evaluate_transition_request story as Unyt Phase 3 — unified transition evaluation that reads typed rules and cross-zome / cross-cell evidence. Today's MVP stores GovernanceRule as rule_type / rule_data strings in zome_resource (no enum yet) and uses separate coordinator paths such as validate_agent_for_promotion and validate_agent_for_custodianship for private-field checks, without Flowsta or IdentityVerification enforcement. Tier 2 identity checks are specified to fold into that unified evaluation as the generic NDO matures.
PPR and reputation: With a verified slot, ReputationSummary is attributable to a cross-app DID (REQ-NDO-AGENT-08; prima Section 6.7). Attribution (same person across apps) is not claim transferability (PrivateParticipationClaim entries remain bound to local keys) — the same distinction as resources.md §4.6.
Complementarity: Flowsta answers who is who; Unyt answers who owes what. Communities may adopt one, both, or neither (ndo_prima_materia.md Section 6.7, Flowsta and Unyt). See resources.md §3.8 for resource-ontology cross-links and agent.md §3.5 for the agent-facing tier summary.
Traceability: ndo_prima_materia.md Section 11.6 (Flowsta integration in the requirements matrix).
3.8 Adaptive Governance for Source-NDOs (source-ndo-requirements.md)
Status: 🔄 Post-MVP — designed. No Rust implementation yet. See
source-ndo-requirements.mdfor normative requirements;source-ndo-paper.mdfor academic justification.
The governance-as-operator pattern meets complex ecological systems. For project-type NDOs, governance rules are fixed at design time and evaluated on each transition request. For Source-NDOs — watersheds, rivers, fisheries, forests — rules must adapt as the source's condition changes. This is not a relaxation of governance rigor; it is a deeper application of it.
The cybernetic governance loop:
Boundary events (extraction, discharge, restoration)
↓ accumulated on Source Layer 0 hash as EconomicEvent entries
Ecological interpretation (scientists, stewards, monitoring systems)
↓ update SourceProfile.regime_state, resilience, tipping_threshold
Governance rule adaptation (GovernanceRule entries revised or replaced)
↓ evaluated by governance-as-operator on subsequent transition requests
Access affordances (extraction quotas, discharge limits, monitoring obligations)
↓ condition future events
(loop)
This loop extends — but does not break — the governance-as-operator architecture. The governance zome still evaluates rules on transition requests; the new dimension is that rules can change via a validated rule-revision process (REQ-SOURCE-GOV-01), and the rule evaluation also reads SourceProfile.regime_state to apply precautionary blocks near tipping_threshold (REQ-SOURCE-GOV-03).
Black-box epistemics. Unlike complicated resource governance (where rules can be fully specified from adequate knowledge), complex ecological governance must operate on partial information. The complex_interior: true flag on SourceProfile makes this epistemological stance machine-readable: the governance system governs observable peripheral events (what crosses the source boundary) rather than claiming to model the interior. This is Ashby's law of requisite variety applied to governance: the complexity of the governance system must match the complexity of the system it regulates — but for a complex system, matching that complexity means acknowledging and operating with irreducible uncertainty.
New governance concepts introduced:
| Concept | Description |
|---|---|
| Adaptive rule revision | GovernanceRules on Source-NDOs may be revised through a multi-validator governance process as ecological interpretation changes. Rule version history is preserved. |
| Precautionary governance | Events that would push current stock below tipping_threshold may be blocked or escalated to multi-validator review. |
| Monitoring obligations | Agents who extract from or discharge into a Source may be required to submit condition data as a precondition for continued access. |
| Stewardship role | A new functional role (Steward) carries obligations (monitoring, ledger maintenance, rule revision) without conferring property rights. No steward owns a Source-NDO. |
| SourceRegimeState | A machine-readable ecological condition classifier (Pristine → Stable → Stressed → Degraded → Critical → Transformed), governance-validated on transition. |
Ostrom's principles applied to Source governance. Source-NDO governance implements all eight of Ostrom's design principles for commons governance (see §1.6 of this document), extending them to complex ecological systems:
| Ostrom's principle | Source-NDO implementation |
|---|---|
| Clearly defined boundaries | Source boundaries (spatial, temporal, flow endpoints) defined at Layer 1 |
| Match rules to local conditions | SourceRegimeState-conditional rules; adaptive loop matches rules to current ecological condition |
| Collective choice arrangements | Multi-validator rule revision; steward community governance of GovernanceRule updates |
| Monitoring | Monitoring obligations as GovernanceRule type; event ledger as audit trail |
| Graduated sanctions | regime_state-dependent access restrictions; escalating precaution toward tipping_threshold |
| Conflict resolution | DisputeResolutionParticipation PPR category; existing NDO dispute mechanisms |
| Minimal recognition of rights | Holochain permissionless access; stewardship without ownership |
| Nested enterprises | Source hierarchy links (yields, conditions); watershed-level governance over river-level NDOs |
Relation to existing governance architecture. Source-NDO governance does not introduce a new governance engine. It extends the existing governance-as-operator architecture with:
- An additional evaluation input:
SourceProfile.regime_state(cross-entry read by governance zome). - A new
GovernanceRuleclass: monitoring obligation rules. - A rule-revision governance process: multi-validator approval required for GovernanceRule updates on Source-NDOs.
- A new functional role:
Steward(alongside the existing governance tiers).
All existing mechanisms — PPRs, capability tokens, validation receipts, ValueFlows events — apply unchanged to Source-NDO interactions.
Traceability: source-ndo-requirements.md §5 (REQ-SOURCE-GOV-01 through REQ-SOURCE-GOV-08).
4. OVN Governance Ontology: 15 Years of Practice
4.1 Governance Layers
The OVN wiki defines three governance layers, each with different concerns:
Network-of-networks layer (ecosystem governance):
- Protocols and standards for cross-network interoperability
- Role and reputation portability across organisational boundaries — planned: W3C DIDs plus
FlowstaIdentity/IsSamePersonEntryas a near-term cross-network identity anchor (REQ-NDO-AGENT-08,ndo_prima_materia.mdSection 6.7), with Verifiable Credentials and ZKP proofs as longer-term depth (seeagent.md§4.4) - Content management standards enabling effective cross-network documentation
- Custodian agreements, exchange firm mandates
Network layer (commons community governance):
- Resource access governance (tools, spaces, brand, infrastructure)
- Access to network-level governance participation
- Benefit distribution algorithm and governance equation
- Protocols for contribution accounting and transactions within the network
Venture layer (project governance):
- Benefit distribution for specific projects (regulated by benefit redistribution algorithm)
- Autonomous governance within the network's meta-rules
The NDO currently implements only venture-layer governance. The generic NDO must support all three, using the same primitives at each scale.
Complexity economics note: Multi-scale governance that uses self-similar primitives is not just architecturally elegant — it is functionally necessary. A governance system that only works at one scale cannot adapt to the fractal structure of real OVN communities. The holonic NDO structure (each NDO is both a whole and a part) requires holonic governance.
4.2 Governance Components
Governing bodies: Committees, offices, working groups. The OVN wiki notes that functions like "leadership," "coordination," and "accountability" should be seen as processes that can be distributed or embodied, not as roles necessarily held by specific individuals. The NDO's role system partially addresses this, but does not model governing body structures.
Registries: Formal lists used in governance processes — list of affiliates, list of events, list of legitimate funding proposals, list of ventures, list of digital services. Registries enable algorithmic governance: "only those included in the registry of affiliates will be considered for participating" in a decision. The NDO has anchor-based discovery links but no governance-specific registries.
Decision making: The OVN wiki lists multiple decision-making mechanisms: Free initiative, Red flag, Lazy democracy, Advice process, Voluntary subordination. None of these are implemented in the NDO beyond binary approval/rejection in validation schemes.
Body of agreements: Smart contracts + paper contracts + hybrid. Currently the NDO has GovernanceRules (programmable, onchain) and Commitments (onchain). Missing: integration with paper/legal agreements (even as hash references), and the hybrid model between onchain enforcement and offchain human processes.
People, environment, purpose: The OVN draws on constitutional theory: People (who is in and how they interact), Environment (external pressures on the organisation), Purpose (the attractor that orients governance). In NDO terms: People = agent system; Environment = DHT and surrounding ecosystem; Purpose = the nondominium property regime embedded in the DNA. These are correct architecturally but not explicitly modeled as governance artifacts.
4.3 Governance Processes
The OVN wiki lists five governance processes for how decisions get made:
| Process | Description | NDO support |
|---|---|---|
| Free initiative | Any agent can act without prior approval within their scope | Partially: permissionless network entry; role-gated process initiation |
| Red flag | Any agent can signal concern about a proposed action | Gap: No signal mechanism for concerns |
| Lazy democracy | Proposals pass by default unless someone objects | Gap: Not implemented |
| Advice process | Must consult affected parties before acting | Gap: Not implemented |
| Voluntary subordination | Agents voluntarily follow decisions they didn't make | Partially: governance-as-operator (agents accept system rules by participating) |
The processes are not mutually exclusive. Different types of decisions warrant different processes. The generic NDO should support configurable governance process assignment per decision type.
4.4 Access to Governance and the Governance Equation
The OVN wiki identifies a key design problem in open systems: the long tail distribution of participation. A typical OVN has a 1-9-90 structure: 1% are core participants (entrepreneurial, high commitment), 9% are active contributors, 90% are occasional participants. The governance system must be sensitive to this — it cannot treat all participants equally without producing either governance paralysis (too inclusive) or oligarchy (too exclusive).
The governance equation maps contribution history to governance access:
governance_access = f(past_contributions, future_commitments)
Past contributions are measured through contribution accounting (PPRs in NDO). Future commitments are pledges of future work (Commitments in NDO). Access to governance is seen as a benefit — one of the outputs of participation in the commons, alongside economic benefits and social benefits.
The OVN affiliation spectrum (agent.md §4.2) is the operational definition of this equation — the concrete mechanism by which participation depth maps to governance tier:
UnaffiliatedStranger/CloseAffiliate→ individual-level access only: permissionless DHT reads, basic VfActions; no governance participationActiveAffiliate→ governance participation unlocked: validation, proposal submission, dispute resolutionCoreAffiliate→ elevated governance weight: rule amendment, role promotion, registry management; algorithmically determined from PPR contribution rate above a configurable thresholdInactiveAffiliate→ reduced access: prior contributions preserved and visible; governance weight suspended until re-engagement
The AffiliationRecord entry (G6) is the formal on-ramp that transitions an agent from CloseAffiliate to ActiveAffiliate. It is a governance event in the ValueFlows sense: the agent creates a Commitment (I commit to the Terms of Participation, the Nondominium & Custodian agreement, and the Benefit Redistribution Algorithm), fulfils it by signing the AffiliationRecord entry on-chain, and a Claim links the two. From that moment, the agent's AffiliationState derivation function (which reads DHT data, not a stored field) returns ActiveAffiliate, and the governance gate opens.
Post-MVP, ZKP proofs (G7) enable agents to prove their affiliation tier to other governance participants without revealing which network they are affiliated with, their full contribution history, or the identity of their counterparties. An agent can prove "I am at least an ActiveAffiliate with ≥ N governance claims" without disclosing the raw PPR data. This is the privacy-preserving meritocracy design: governance access based on contribution without requiring surveillance of the agent's full history.
Flowsta and complexity matching: Tier 1 (permissionless FlowstaIdentity attestation) keeps friction low for the long tail of occasional participants. Tier 2 (REQ-NDO-CS-14, ndo_prima_materia.md Section 6.7) lets communities require Tier 2–validated Flowsta linking only where Bar-Yam-style complexity matching justifies the coordination cost — e.g. PrimaryAccountableAgent promotion or high-stakes custody — without mandating Flowsta for every agent.
Non-binary decision making: The OVN wiki proposes mechanisms beyond yes/no voting: conviction voting (continuous preference posting, updated over time), quadratic voting (cost of additional votes grows quadratically, preventing concentration), rank choice (preference ordering across alternatives). These are described as composable — basic decision-making patterns that can be combined into more complex governance recipes.
Complexity economics note: The governance equation is an application of Benkler's observation that P2P systems can process more granular information than market or hierarchical systems. Instead of binary in/out, the governance system can weight participation based on the richness of contribution history, producing governance decisions that reflect actual contribution patterns rather than crude majority rules.
4.5 Embedded Governance — Onchain and Offchain
The OVN wiki's most practically important governance insight for NDO: the distinction between:
- Governance of the OVN: meta-rules about how the network behaves; control resides outside/above the automated system
- Governance through the OVN: automated execution through smart contracts, self-enforcing agreements
This maps to:
- Offchain governance (governance of): the community's agreements about rules, maintained in documents and social processes; what the DNA is designed to implement
- Onchain governance (governance through): the actual HDI validation rules, capability tokens, GovernanceRules; what the DNA implements and enforces automatically
The OVN wiki is explicit: "What cannot be automated? Human issues: interpersonal problems, emotions, etc. cannot be automated." Metagovernance — discussions about the rules, proposals for new rules, architectural decisions — requires human process. The NDO should provide hooks for metagovernance without trying to automate it.
Sensorica's current governance is described as "mostly offchain (written in documents), although some governance aspects are embedded within the infrastructure." The NDO project represents the transition toward more onchain governance, with Nondominium as "the resource transfer and flow engine... designed as an organization-agnostic system that embeds governance rules directly within resource definitions."
Complexity economics note: The question of how much to automate is itself a governance decision. Full automation produces a rigid, brittle system that cannot adapt to unforeseen situations. Full human process is slow and expensive. The optimal point depends on the community and context — which is why the NDO should support configurable automation depth, not hard-code a single approach.
4.6 Stigmergy and Governance
The OVN wiki treats stigmergy as a governance mechanism, not just an implementation pattern. "Stigmergic governance relies on embedded governance, meaning that the effect of these fundamental principles are complemented by the properties of the environment."
The key insight: governance can be reduced to a small number of principles embedded in the environment, with complex collective behaviour emerging from individual responses to environmental signals. Ants build nests of extraordinary complexity without written rules — just a few genetic principles and an environment they modify collectively.
For the NDO: the fundamental governance principles should be encoded into the DHT structure (Holochain validation rules, capability tokens, the VfAction semantics). The specific governance recipes for different communities should emerge from how those communities configure and extend the environment (GovernanceRules, CapabilitySlot attachments, role definitions). The system should not need a comprehensive rulebook — it needs a well-designed environment.
The OVN's description of stigmergy as "governance focused on attention — governing our collective attention" is relevant: capability slots and anchor links are both mechanisms for directing agents' attention to what is relevant, allowing them to coordinate without central direction.
4.7 Deontic Ontology
The OVN wiki explicitly calls for a deontic ontology integrated with REA: "Fundamental concepts and relations that allow us to speak about decisions, rules, norms, obligation and permission." The core operators are Obligation and Permission, from which Access (to benefits or resources) can be derived.
In NDO terms:
Permission→ capability tokens + role-gated validation + GovernanceRuleenforced_byObligation→ Commitment entries (a declared obligation to perform a VfAction by a due date)Access→ derived: agent has capability token AND meets GovernanceRule conditions → access granted
The current NDO implements these concepts but does not name them using deontic vocabulary. The generic NDO should formalise the deontic layer as first-class governance entries, not as implicit properties of other entry types.
A deontic governance entry might look like:
#![allow(unused)] fn main() { pub struct DeonticRule { pub operator: DeonticOperator, // Obligation | Permission | Prohibition pub applies_to: AgentRole, // Who this rule applies to pub regarding: ActionOrResource, // What action or resource it concerns pub conditions: Vec<Condition>, // Preconditions for the rule to apply pub enforced_by: GovernanceLayer, // Venture | Network | Federation pub expires_at: Option<Timestamp>, } }
This would replace the current untyped GovernanceRule with a formally typed deontic structure.
Planned first typed rule families alongside that migration include EconomicAgreement (Unyt settlement / RAVE path) and IdentityVerification (Flowsta FlowstaIdentity + IsSamePersonEntry path) — both specified in ndo_prima_materia.md Sections 6.6–6.7 while MVP code still uses rule_type / rule_data strings in zome_resource.
4.8 Temporal Governance
The OVN wiki identifies several temporal dimensions of governance:
- Decision expiry: decisions can have expiration dates, not just single-moment validity
- Evaluation triggers: decisions can include evaluation conditions that, if triggered, initiate review or revision
- Past-looking and forward-looking governance access: both contribution history and future commitments count
- Preference voting as continuous process: agents update preferences over time, building an ongoing governance profile
The NDO currently has only one temporal governance mechanism: capability grant expiry (30-day maximum for private data access grants). This is correct but minimal. The generic NDO should support temporal governance more broadly.
4.9 Constitution and the Governance of Governance
The OVN wiki discusses whether OVNs should have constitutions. Its conclusion: traditional constitutions (for closed, bounded organisations) don't map well to open, fractal networks. But the concept of a constitutive infrastructure — "all of that organization's implementations of the constitutive function" — is useful.
The constitutive infrastructure of an NDO community is:
- The DNA validation rules (hard-coded, very difficult to change)
- The global GovernanceRules (encoded in the DHT, updatable through governance)
- The community agreements (offchain, referenced but not enforced by the DNA)
The governance surface — the mechanisms through which the constitutive infrastructure can be modified — is a critical design element. In the OVN model, this includes: who can propose a rule change, what deliberation process applies, how changes are ratified, and how they are recorded.
The NDO has no formal governance surface. Rule changes require developer intervention (DNA upgrades) or are limited to per-resource GovernanceRule updates (controlled by role-gated validation). This is a fundamental gap for any community that needs to evolve its own rules.
5. Gap Analysis
5.1 Mapped — OVN concepts implemented or planned in NDO
| OVN concept | NDO implementation | Status |
|---|---|---|
| Governance-as-operator (embedded rules) | zome_gouvernance as state transition operator | ✅ Implemented |
| Deontic permission system | Capability tokens + role-gated validation | ✅ Implemented |
| Deontic obligation system | Commitment entries with due dates | ✅ Implemented |
| Access from Permission | Role-gated VfAction execution | ✅ Implemented |
| Monitoring and accountability | PPR system (16 categories; pairwise bilateral for MVP one-to-one events; multi-party issuance post-MVP per post-mvp/many-to-many-flows.md) | ✅ Implemented |
| Graduated trust / bounded membership | SimpleAgent → Accountable → Primary tiers | ✅ Implemented |
| Multi-scheme collective validation | ResourceValidation with "2-of-3", "N-of-M" | ✅ Implemented |
| Governance equation (contribution → access) | PPR → role promotion; Unyt credit limit feedback | ✅ Partial (promotion path); 🔄 Planned (credit/weight) |
| Embedded governance in resources | GovernanceRule entries in ResourceSpecifications | ✅ Implemented (weakly typed) |
| Typed governance rules | GovernanceRuleType enum (incl. EconomicAgreement, IdentityVerification / Flowsta) | 🔄 Planned (ndo_prima_materia.md §6.6–6.7, unyt-integration.md, flowsta-integration.md) |
| Stigmergic governance surface | CapabilitySlot surface (Layer 0) | 🔄 Planned (ndo_prima_materia.md) |
| Economic governance (Smart Agreements) | Unyt EconomicAgreement GovernanceRule | 🔄 Planned (unyt-integration) |
| End-of-life governance (challenge period) | REQ-GOV-11 through REQ-GOV-13 | 🔄 Planned (requirements.md) |
| Privacy-preserving accountability | Private PPRs + derivable ReputationSummary | ✅ Implemented |
AffiliationRecord entry (formal ToP ceremony) | agent.md §6.4 forward design; uses the existing Commitment/EconomicEvent cycle for the signing ceremony; AffiliationState is derived from its presence on the DHT | 🔄 Planned (post-MVP, G6, REQ-AGENT-05) |
| Affiliation-gated resource governance | GovernanceRule.rule_data["min_affiliation"] condition evaluated by the governance operator; cross-zome AffiliationState query from zome_person; blocks state transitions for agents below the threshold | 🔄 Planned (post-MVP, G2 — see resources.md §5.3, implementation_plan.md §3 [G2+Resource]) |
| Governance-enforced identity verification | IdentityVerification rule + FlowstaIdentity slot validation (REQ-NDO-CS-14, REQ-NDO-CS-15; W3C DID + IsSamePersonEntry; ndo_prima_materia.md Section 6.7) | 🔄 Planned (post-MVP) |
| Cross-app identity anchor for portable governance signals | Stable DID + dual-signed attestation; portable credential attribution (REQ-NDO-AGENT-08) | 🔄 Planned (post-MVP) |
5.2 Partial — concepts present in OVN and partially covered in NDO
| OVN concept | NDO partial coverage | Gap |
|---|---|---|
| Openness / equipotentiality | Permissionless network entry + role-gated governance | No formal mechanism to EARN governance access beyond role promotion |
| Transparency | All rules and events are public DHT entries | PPRs are private; no holoptism mechanism for governance state |
| Decentralisation | Agent-centric Holochain validation | Role tiers create de facto power concentration |
| Emergent governance | Holochain peer validation is emergent | Rules are still designed; no mechanism for rules to emerge from agent behaviour |
| Free initiative | Within role scope, agents can act unilaterally | No explicit free initiative declaration or scope definition |
| Voluntary subordination | Agents accept system rules by joining | No mechanism to formally express "I subordinate to this decision I opposed" |
| Body of agreements | GovernanceRules (onchain) | No paper/legal agreement model; no hybrid onchain/offchain agreements |
| Temporal governance | Capability grant expiry (30 days max) | No expiry on GovernanceRules; no evaluation triggers on decisions |
| Metagovernance | GovernanceRule update with role validation | No proposal mechanism; no formal deliberation; no ratification process |
5.3 Missing — OVN concepts not yet planned in NDO
| OVN concept | Gap description | Proposed resolution |
|---|---|---|
| Governance layers (venture / network / federation) | Only venture-level governance exists | Model governance scope as a property of GovernanceRules and registries; use NDO's holonic composition to nest governance |
| Decision-making processes (free initiative, red flag, lazy democracy, advice process) | No process models beyond binary validation | Add GovernanceProcess as a configurable entry type; composable decision patterns |
| Governing bodies (committees, working groups) | Not modeled | Model as a specialised NDO (a governing body is itself an NDO with its own governance and membership) |
| Registries (affiliate lists, venture lists, legitimate proposal lists) | Only anchor-based discovery links | Add Registry entry type: a governance-managed list of validated entries |
| Non-binary decision making (conviction voting, quadratic voting, rank choice) | Only binary approve/reject | Modular vote aggregation patterns in a GovernanceProcess framework |
| Red flag / concern signaling | No mechanism for agents to raise concerns about proposed actions | Add GovernanceConcern entry: a signal from any agent about a resource action or governance decision |
| Governance of governance (metagovernance surface) | Rule changes require developer intervention or role-gated updates only | Define a formal governance amendment process as a GovernanceProcess type |
| Long tail awareness (1-9-90 structure) | All validated agents treated equivalently in governance | Participation-weighted governance access (governance equation formally implemented) |
| Holonic multi-scale governance | Only single-level governance | Governance primitives should work at venture, network, and federation scales using the same structures |
| Temporal governance (rule expiry, decision evaluation triggers) | Only capability grant expiry | Add expires_at and evaluation_trigger to GovernanceRules and governance decisions |
| Offchain governance bridge | No way to record offchain decisions as DHT artifacts | Add GovernanceRecord entry: a hash of an offchain document/decision with metadata, linking offchain and onchain governance |
| Constitution / Governance surface | No formal description of who can change what rules | Implement a GovernanceConstitution entry at the DNA level: a hash-referenced document + amendment process |
| Affiliation-based governance access gating | Governance processes cannot enforce "active affiliates only" conditions; all agents with any role receive the same governance access regardless of participation depth | Extend GovernanceRule.rule_data schema with min_affiliation field; extend governance operator evaluate_transition to cross-zome query AffiliationState from zome_person; block transitions below threshold (refs G2, G6, agent.md §4.2, resources.md §5.3) |
| Collective agent governance participation | Validation schemes, PPR issuance, and role assignment all require AgentPubKey; collective, network, and bot agents cannot act as governance participants; economic events between organisations cannot be correctly modelled | Extend GovernanceTransitionRequest.requesting_agent and ValidationReceipt.validated_by to accept AgentContext; define delegation rules for collective signing authority — designated operator key or N-of-M from collective NDO members (ref G1, agent.md §4.1, Section 6.6 of this document) |
| Sybil resistance in governance | Multiple source chains controlled by one physical person can dilute validation quorums, inflate role promotion counts, or accumulate disproportionate PPR governance_claims | Optional Tier 2 Flowsta identity checks (REQ-NDO-CS-14, ndo_prima_materia.md Section 6.7) for high-trust role or transition classes — complementary to social vouching (N existing active affiliates vouch for a new agent before first governance-tier role promotion) and optional proof-of-personhood as a membrane condition (ref G9, agent.md §5.3) |
| Pseudonymous governance participation | Pseudonymous or anonymous agents cannot accumulate PPRs or earn governance access without linking contributions to a persistent Person identity; the privacy/efficiency trade-off has no intermediate option | Design a pseudonymous affiliation path: PPRs issued to a persistent pseudonymous AgentPubKey (no Person entry required); pseudonymous agents can reach ActiveAffiliate status through contribution; blocked from governance roles that require legal accountability (e.g. dispute resolution involving off-chain agreements); see agent.md §4.5 (ref G10) |
6. Forward Map: Generic NDO Governance Architecture
6.1 Governance as REA — The Unified Model
The most important design principle for the generic NDO: governance events are EconomicEvents. The unified model:
GovernanceRule (knowledge layer) → ResourceSpecification analog
GovernanceRecord (planning layer) → Commitment analog
GovernanceDecision (observation layer) → EconomicEvent analog
This means:
- Proposing a rule change = creating a
GovernanceRecord(a Commitment-like intent) - Deliberation = Commitments from affected agents (support/oppose)
- Decision =
GovernanceDecision(EconomicEvent-like outcome) - Implementation = updated
GovernanceRuleentries - Accountability =
ValidationReceipton the implementation + PPR for governance participants
This is not a new subsystem — it is the existing ValueFlows cycle applied to the governance domain. The governance zome already handles this cycle for resource governance. Extending it to meta-governance is architecturally natural.
6.2 Governance Process as Configurable Entry
#![allow(unused)] fn main() { pub struct GovernanceProcess { pub name: String, // "lazy_democracy", "advice_process", etc. pub applies_to: GovernanceScope, // Venture | Network | Federation pub decision_type: DecisionType, // RuleAmendment | RoleGrant | ResourceAccess | ... pub participation_required: Vec<ParticipantSpec>, // Who must participate pub quorum: QuorumSpec, // Minimum participation threshold pub threshold: ThresholdSpec, // What counts as a decision (majority, supermajority, etc.) pub timeline: GovernanceTimeline, // Deliberation + decision + implementation windows pub veto_period: Option<Duration>, // Optional lazy democracy reversal window pub expires_at: Option<Timestamp>, // Sunset clause } }
Communities configure which governance process applies to which decision type. The generic NDO provides a library of composable process patterns (from the OVN vocabulary); each NDO instantiation selects and configures its governance recipe.
6.3 Registry Model
Registries are governance-managed lists. They are themselves NDO resources (a registry is a resource with its own governance rules):
#![allow(unused)] fn main() { pub struct Registry { pub name: String, // "ValidatedAgents", "ActiveVentures", "LegitimateProposals" pub scope: GovernanceScope, // Which governance layer manages this registry pub entry_type: RegistryEntryType, // What kind of entries it contains pub admission_process: GovernanceProcess, // How entries are added pub removal_process: GovernanceProcess, // How entries are removed pub is_public: bool, // Whether the registry is publicly readable } }
The registry mechanism enables algorithmic governance: "only agents in the ValidatedAgents registry may participate in the next decision." This moves governance from relying on per-decision ad hoc membership determination to managed, auditable lists.
6.4 Participation-Weighted Governance (The Governance Equation)
The OVN governance equation implemented as a cross-zome computation:
governance_weight = f(
affiliation_state, // PREREQUISITE GATE (from agent.md §6.2)
// < ActiveAffiliate → weight = 0 (blocked)
// = ActiveAffiliate → weight computed normally
// = CoreAffiliate → weight × core_multiplier
// = InactiveAffiliate → weight = 0 (suspended)
reputation_summary.average_performance, // quality of past contributions
reputation_summary.governance_claims, // governance participation depth
reputation_summary.custody_claims, // resource stewardship depth
unyt_credit_capacity, // economic standing in commons
active_commitments_count // forward-looking engagement
)
The affiliation_state input is derived (not stored) from existing DHT data by zome_person using the formula in agent.md §6.2:
affiliation_state(agent) = f(
person_exists(agent),
affiliation_record_exists(agent), // AffiliationRecord (G6) signed on-chain?
contributions_count(agent), // from EconomicEvents
last_contribution_timestamp(agent), // recency window check
reputation_summary.total_claims,
governance_claims_count(agent)
)
The affiliation_state gate ensures that the governance equation's contribution data is only evaluated after the formal affiliation ceremony (AffiliationRecord, G6) is complete. An agent with high PPR scores but no signed AffiliationRecord remains at CloseAffiliate and cannot participate in governance — they must formally commit to the network's terms before their contributions are recognised as governance standing. This prevents incidental interactions (browsing the DHT, casual transactions) from accumulating governance weight without commitment.
This weight determines:
- Vote weight in non-binary decision mechanisms
- Thresholds for initiating certain governance processes
- Access to higher-trust governance functions (dispute resolution, rule amendment)
Critically: the weight function is itself a GovernanceRule, configurable by communities. Different communities weight contribution dimensions differently. The core_multiplier and the recency window for InactiveAffiliate detection are also governance-configurable parameters.
Note: the inclusion of unyt_credit_capacity as an input creates a feedback loop (PPR → reputation → Unyt credit → governance weight → more governance participation → more PPRs). To prevent runaway accumulation, the weight function should apply dampening — e.g., logarithmic scaling of the credit capacity input — so that marginal increases in credit produce diminishing governance weight returns.
Communities may also (configurably) treat Tier 2–validated FlowstaIdentity (or simply presence of a Tier 1 DID link for softer signals) as an additional input for high-trust governance processes — aligned with PPR reputation attributable to a DID (ndo_prima_materia.md Section 6.7) — without requiring a new field in the sketch above.
6.5 Offchain Governance Bridge
A minimal mechanism for linking offchain human decisions to the onchain governance record:
#![allow(unused)] fn main() { pub struct GovernanceRecord { pub document_hash: String, // Hash of the offchain document (PDF, markdown, etc.) pub document_uri: Option<String>, // Where to find the document pub record_type: OffchainRecordType, // Agreement | Policy | Decision | Constitution pub ratified_by: Vec<AgentPubKey>, // Agents who have ratified this record pub effective_at: Timestamp, pub supersedes: Option<ActionHash>, // Previous version of this record pub scope: GovernanceScope, } }
This is the bridge between the OVN's offchain governance reality (most governance today is documents and social processes) and the onchain aspiration. Agents ratify offchain documents by signing GovernanceRecord entries — creating a cryptographic commitment to the offchain text without requiring full onchain implementation of its processes.
6.6 Collective Agent Governance Patterns (Post-MVP)
The expanded agent ontology (agent.md §3.1, §4.1`) enables working groups, projects, networks, and bots to act as governance participants. Three structural patterns cover the main cases:
Pattern 1 — Collective agents as NDOs
A working group, project, or network is itself an NDO with its own governance layer (Identity + Specification + Process). When a collective NDO participates in external governance — signing a ValidationReceipt, acting as a GovernanceTransitionRequest.requesting_agent, or being a PPR counterparty — it does so through a designated representative: the PrimaryAccountableAgent of the collective NDO, whose AgentPubKey acts on the collective's behalf. Governance decisions affecting the collective (e.g., approving a resource access request it submitted) require internal governance within that collective NDO before the external signature is issued. This nests governance holonically: venture → network → federation, all using the same VfAction/Commitment/EconomicEvent primitives.
Pattern 2 — Multi-sig validation for collective actors
When a governance process requires approval from a collective agent (e.g., a working group must validate a new resource), the ResourceValidation scheme must support AgentContext references in its required_validators field. Two implementation options:
- Designated operator: the collective NDO has nominated a single
PrimaryAccountableAgentwhose signature counts as the collective's approval. Simple but creates a governance bottleneck at the operator. - Member threshold: the governance scheme accepts approval from N-of-M individual agents who are current active members of the collective NDO. More resilient but requires the validator set to be dynamically resolved from the collective NDO's membership links at validation time.
Both options require the GovernanceProcess entry (Section 6.2) to declare which pattern applies per decision_type. The ResourceValidation.required_validators field transitions from Vec<AgentPubKey> to Vec<AgentContext> post-MVP.
Pattern 3 — Bot / AI agent governance scope
Bot agents (AgentEntityType::Bot { capabilities, operator }) can participate in governance only within the scope declared in their capabilities vector. Examples:
- A bot may be authorised to sign
ValidationReceiptentries for automated integrity checks (e.g., a digital resource hash validation bot) — but not for role promotions or rule amendments, which require human judgment. - A bot may be authorised to issue
EconomicEvententries for automated processes (e.g., a scheduler bot recording that a storage commitment has been fulfilled on time) — but not for dispute resolution.
The operator: AgentPubKey in the Bot type is the governance-responsible party: all bot actions are attributed to the operator for accountability purposes, and any PPRs generated by bot interactions list the operator as the accountable counterparty. Bot governance_claims in the ReputationSummary do not contribute to the operator's affiliation_state — they are tracked separately under the bot's own AgentContext with a governance_weight = 0 gate (bots cannot accumulate governance standing independent of their human operator).
TODO (G1, G11 — post-MVP): Implement
AgentContexttype, extendGovernanceTransitionRequest,ValidationReceipt, and PPRcounterpartyfields to acceptAgentContext. DefineBotdelegation scope enforcement in the governance operator'svalidate_agent_permissionsfunction. Seeimplementation_plan.md §3 [G1+Resource]andagent.md §5.3 (DelegatedAgent).
7. Complexity Economics Justification: Why Each Governance Concept Matters
Governance layers matter because the OVN is fractal. A governance architecture that only works at one scale (venture) cannot coordinate the network-level and federation-level decisions that determine the ecosystem's evolution. Governance without scale awareness will centralise at whichever scale is most powerful, undermining the decentralisation that makes peer production competitive with capitalist alternatives.
Decision processes (advice process, lazy democracy, etc.) matter because different types of decisions have different optimal deliberation speeds. Time-sensitive operational decisions need fast, local authority (free initiative). Rule-changing decisions need wide deliberation and consent. Treating all decisions equally produces either paralysis (everything goes through full deliberation) or autocracy (important decisions get made without consultation). The composable governance process library is the infrastructure for decision-appropriate governance.
Non-binary decision making matters because voting aggregates preferences by throwing away information. A community where 60% support a proposal and 40% strongly oppose it is very different from one where 60% support and 40% mildly prefer an alternative. Binary voting cannot distinguish these — it just says "60% win." Conviction voting (continuous preference updating), quadratic voting (cost-weighted expression), and rank choice (preference ordering) all recover more information from the deliberation process. In complexity economics terms: higher-resolution preference aggregation produces better decisions because it uses more of the information that participants possess.
Registries matter for the same reason that formal membership distinctions matter in Ostrom's commons governance: without a clear definition of who is in the community, governance processes cannot be bounded, quorums cannot be calculated, and the accountability chain cannot be closed. The OVN's long tail distribution means that simple "everyone who has ever participated" definitions produce governance bodies so large and diffuse that decisions become impossible. Algorithmically managed registries — updated by governance, not by developer deployment — solve this.
The governance equation matters because access to governance should not be arbitrary (cooptation, seniority, formal appointment) in a P2P system. Benkler's observation about peer production's information advantage is applicable: distributed contribution data is richer than any centralised assessment of "who is a responsible governance participant." The PPR system generates this data as a byproduct of ordinary participation. Using it to weight governance access converts participation history into governance standing automatically — without administrative overhead.
The offchain bridge matters because full onchain governance is a fiction. Human communities have always and will always need spaces for informal conversation, emotional resolution, and contextual judgment that no smart contract can replicate. The OVN wiki is explicit: "Human issues: interpersonal problems, emotions, etc. cannot be automated." A governance architecture that ignores its own offchain complement will be gamed by agents who understand that the informal layer always overrides the formal. Acknowledging and linking the offchain layer makes the full governance stack legible, auditable, and improvable.
Temporal governance matters because all rules become outdated. A GovernanceRule written for a community of 10 becomes inappropriate for a community of 1000. A decision made under one set of conditions may be harmful under new conditions. Sunset clauses and evaluation triggers are the governance equivalent of software unit tests: they force the community to consciously re-evaluate whether rules still serve their purpose, rather than allowing dead rules to accumulate and complicate the governance landscape.
Cross-app identity (Flowsta) matters for governance for the same reason credential portability and network-layer reputation matter in the OVN model: agents who participate in multiple OVNs or hApps are bridge nodes between networks. Without a verifiable same-person link across conductors, each network treats them as a stranger and must re-derive trust from zero; sybil pressure and cold-start friction repeat at every boundary. Flowsta Tier 1 keeps overhead low for casual participants; Tier 2 applies Flowsta link validation only where complexity matching says the coordination cost is justified (ndo_prima_materia.md Section 6.7, REQ-NDO-CS-14).
This is a living document. The gap analysis in Section 5.3 should be converted into formal requirements as the generic NDO project begins. The forward map in Section 6 describes design directions, not final specifications. Major external capability integrations (Unyt, Flowsta) are traced in ndo_prima_materia.md Sections 6.6–6.7 and Sections 11.5–11.6. The OVN wiki at ovn.world remains the authoritative reference for peer production governance practice.
Nondominium Prima Materia
Status: Normative architecture document — Layer 0 implemented in MVP; Layers 1–2, capability slots, and full governance-as-operator lifecycle remain post-MVP targets
Created: 2026-03-10
Last updated: 2026-06-16
Authors: Nondominium project
Relates to: post-mvp/many-to-many-flows.md, post-mvp/ndo-versioning.md, post-mvp/digital-resource-integrity.md, post-mvp/unyt-integration.md, post-mvp/flowsta-integration.md, lobby-dna.md, post-mvp/project-type-ndo-specifications.md, post-mvp/source-ndo-requirements.md
Implementation reference: documentation/IMPLEMENTATION_STATUS.md (NDO Layer 0 ✅ PR #80; NDO DNA extensions ✅ PR #103; Layers 1 & 2 ❌)
Table of Contents
- What is the Prima Materia?
- Complexity Economics as Architectural Foundation
- Complexity Oriented Programming
- The Three-Layer Model: The Prima Materia
- Resource State Model — Lifecycle & Operational State
- The Surface of Attachment — Capability Slots
- Design Patterns
- DHT Data Structures
- Requirements (including §9.0 Implementation Status)
- Migration from Current Architecture
- Relationship to Other Post-MVP Work
1. What is the Prima Materia?
In medieval alchemy, the prima materia is the primordial, undifferentiated substance that underlies all matter — the formless potential from which everything is made. Before a substance becomes gold, lead, or salt, it passes through the prima materia: an essential, minimal state that carries the capacity to become anything. The alchemists were not simply mystifying chemistry. They were describing a pattern: complex things begin as nearly nothing, and their nature reveals itself progressively through process.
This document borrows that metaphor deliberately. A Nondominium Object (NDO) is the prima materia of the Nondominium system: a minimal DHT structure that carries the potential to become any kind of resource — digital or physical, simple or composite, idea or fabricated artifact — and that grows in structure and function as the resource it represents grows in complexity and social embeddedness.
1.1 The Gap in the Legacy Model — and What Remains
The original flat resource model consisted of two primary entry types:
ResourceSpecification— the type or template of a resource: name, description, category, governance rulesEconomicResource— an instance of a resource: quantity, unit, custodian, location, state
That model is well-grounded in the ValueFlows standard and works well for resources that already exist in a stable, operational form. Its fundamental limitation was that it represented being, not becoming: there was no first-class object for a resource from ideation through archival memory — no placeholder for an idea not yet designed, a project in active development, a design under peer review before any physical instance exists, an artifact in hibernation (distinct from end-of-life), or a record that persists as institutional memory after activity has ceased.
Partially addressed — Layer 0 (MVP, implemented PR #80): NondominiumIdentity is the permanent Layer 0 anchor. It carries LifecycleStage (Ideation through EndOfLife, including Hibernating and Deprecated), PropertyRegime, and ResourceNature. An NDO can be created at Ideation with name and intent only; lifecycle transitions are integrity-validated and discoverable by stage, nature, and regime. The UI implements Lobby → Group → NDO creation and lifecycle transition against this entry type. See documentation/IMPLEMENTATION_STATUS.md §NDO Layer 0.
Still outstanding (this document remains the normative target for these gaps):
- Layer 2 not activated: process entries are not yet linked to Layer 0 via
NDOToProcess. Layer 1 is activated (#132):create_resource_specificationwrites anNdoToSpecificationlink and the spec carries its Layer 0 pointers, so a spec can no longer be created without an NDO parent. Specification assets are still not attached viaDigitalAssetcapability slots (REQ-NDO-L1-06). - Specification richness: Structured project-type know-how bundles (
post-mvp/project-type-ndo-specifications.md) are post-MVP requirements only — the MVPResourceSpecificationentry remains a thin summary (name, description, category, tags). ResourceStateconflation:OnResolved (data layer):EconomicResourceEconomicResource.operational_stateusesOperationalState; lifecycle maturity lives onNondominiumIdentity.lifecycle_stage. Governance-zome transition ownership (REQ-NDO-OS-02/03) remains deferred.- Governance-as-operator for lifecycle: MVP allows only the NDO
initiatorto callupdate_lifecycle_stage. Governance-validated transitions, role authorization per Section 5.3, and automaticEconomicEventgeneration on each transition (REQ-NDO-LC-02, REQ-NDO-LC-03) remain deferred.
The three-layer prima materia model closes the original gap progressively: Layer 0 addresses identity and lifecycle becoming; Layers 1 (form) and 2 (process) will complete the model when linked and enriched as specified in Sections 4 and 9.
1.2 The Intent of the Prima Materia
The prima materia defines a minimal DHT object that:
- Exists as a placeholder from the moment of conception — before the lifecycle phases of design, specification, as well as before any physical instantiation
- Grows in structure progressively — gaining specification, governance rules, assets, and process infrastructure as the resource matures
- Carries a permanent, stable identity — a content-addressed anchor that persists through all transformations, including end-of-life
- Provides a surface of attachment for capabilities that cannot be anticipated in advance — external hApps, governance tools, fabrication queues, issue trackers
- Represents the full lifecycle — from the first spark of an idea to archival tombstone
1.3 The Key Example: Nondominium Itself
The Nondominium hApp is itself an NDO, of a digital type (a computer program). It began as an idea (Ideation), passed through design (Specification), prototype implementation (Development → Prototype), and is now moving toward its first stable release. Its assets are code on GitHub (the location). Its process is the collaborative work of contributors. Its governance rules will be embedded in the code. Its identity is stable across all versions.
When someone starts a hardware design project for a shared CNC machine, they create an NDO (the identity first). When they publish design files and documentation for distributed fabrication (3D models, bill of materials, manuals, etc.), Layer 1 (Specification) is activated. When contributors begin working, Layer 2 (Process) is activated. When the design is mature and being fabricated by many, all three layers are fully active. When the design becomes obsolete, Layers 1 and 2 are archived, but the NDO identity remains — a permanent record that the thing existed, who created it, and what happened to it.
MVP today: Group-scoped
create_ndocreates Layer 0 only. Layer 1 and Layer 2 activation links are not yet in the codebase; lifecycle stage on Layer 0 can still advance independently (see §5.3). Know-how bundle requirements for project-type NDOs are specified inpost-mvp/project-type-ndo-specifications.md.
2. Complexity Economics as Architectural Foundation
The three-layer design of the NDO is not an arbitrary architectural preference. It is a direct consequence of applying complexity economics to the problem of representing resources in a decentralized peer-to-peer system. Three theoretical pillars justify the design.
2.1 Bar-Yam: Complexity Matching
Yaneer Bar-Yam's central thesis in Complexity Rising is that a system's behavioral complexity must match the complexity of the challenges it faces. When the environment's complexity exceeds a system's adaptive capacity, the system fails. Hierarchical command-and-control structures have cognitive ceilings — there is only so much complexity a centralized decision-maker can handle. As the environment grows more complex, decentralized, networked systems with distributed decision-making become necessary.
Applied to DHT data design, this principle has a direct corollary: do not pre-classify a resource at creation time. At the moment a resource is conceived, its full lifecycle complexity is unknowable. A project started as a personal experiment may become a global standard. A community tool may be adopted and fabricated by thousands of people, communities and networks. A hardware design may spawn dozens of forks and regional variants. Committing to a fixed classification at t=0 is the data equivalent of hierarchical overreach — assuming a knowledge of the future that no agent possesses.
The OVN computational model (ovn.world) demonstrates this formally: Finite State Machines, the computational model underlying most fixed-classification systems, require a number of states that grows exponentially with social complexity — quickly reaching numbers exceeding the atoms in the observable universe for even modestly complex communities. FSMs are not inadequate; they are categorically incompatible with governing complex human systems. A resource data model built on fixed state at creation is an FSM in disguise.
The solution is the adjacent possible (Kauffman): at any moment, only the next step is visible. The NDO model respects this by making layer activation a response to rising environmental complexity, not a commitment made at genesis.
2.2 Benkler: Information Opportunity Costs
Yochai Benkler's analysis of commons-based peer production (Coase's Penguin, 2002; The Wealth of Networks, 2006) identifies the primary economic advantage of P2P coordination as lower information opportunity costs. Markets and managerial hierarchies are informationally lossy — they filter, aggregate, and approximate the rich information available in a distributed network. P2P systems process this information with lower loss because agents at the edges of the network can sense and act on local information directly, without routing it through central aggregators.
In the NDO context, this principle justifies the pay-as-you-grow structure of layer activation. Each layer carries a coordination overhead:
- Layer 0 (Identity) has near-zero coordination cost: one agent creates one entry.
- Layer 1 (Specification) has moderate cost: governance rules must be written, assets attached, peer review coordinated.
- Layer 2 (Process) has the highest cost: economic events must be recorded, commitments tracked, PPRs issued, multi-agent consent coordinated.
In a hierarchical system, all resources would bear the full overhead of the richest representation, regardless of their current needs. Benkler's insight says this is wasteful — it imposes coordination costs that exceed the information value returned. The NDO model matches coordination cost to actual coordination demand: a tool lent between neighbors needs no Process layer; a shared fabrication standard being actively developed by a distributed network needs all three.
2.3 Morin: The Seven Principles of Complexity
Edgar Morin's seven principles of complex thought, applied in the Sensorica complexity economics framework, provide a philosophical grounding for the NDO's structure. Each principle finds direct expression in the design:
| Morin's Principle | Expression in the NDO |
|---|---|
| Systemic (interdependence) | Every NDO exists in relation to agents, processes, and other NDOs; its identity is defined by its links, not its content alone |
| Holographic (part reflects whole) | Every NDO carries the full three-layer potential, regardless of its current activation state |
| Retroactive (feedback loops) | Lifecycle stage changes are triggered by economic events (outputs of the system feeding back as inputs) |
| Recursive (products as producers) | A project-type NDO (representing a resource in development, going through life stages from idea to design, to prototype, to stable) produces NDOs representing its outputs; Nondominium-the-hApp produces Nondominium-as-resource |
| Dialogical (antagonisms coexist) | The NDO holds the tension between resource and agent, between digital and physical, between stability (identity) and change (process), between public (spec) and private (governance) |
| Reintroduction of the subject | Agent motivation and contribution are first-class: PPRs, custody, and contribution tracking are built into the NDO's process layer |
| Ecology of action | No action guarantees its outcome; the NDO's stigmergic capability surface allows unforeseen capabilities to attach — the system is never fully knowable from the source code alone |
2.4 Holonic Structure
The NDO is a holon in the sense used by the OVN model: an entity that is simultaneously a whole in itself and a part of a larger whole. Arthur Koestler coined the term holon to describe systems where every level of organization is both complete and a component. Holonic systems are characteristic of living organisms, ecosystems, and complex economies.
An NDO is:
- A whole: it has its own identity, specification, and process — it is a complete self-describing object
- A part: it is embedded in networks of other NDOs. for example, a project-type NDO contains Resource NDOs, which contain Design NDOs, which reference Component NDOs
This recursive self-similarity is what makes the NDO fractal. Each NDO carries the same structural potential; the difference between a sub-component and a top-level project is only one of social context and activation state, not of structural type.
See fractal composablity and fractal-composable-resource-architecture.md
3. Complexity Oriented Programming
The NDO's design embodies a programming paradigm that does not yet have a formal name but is emerging in practice. We call it Complexity Oriented Programming (COP).
3.1 The Reductive Paradigm and Its Limits
All dominant programming paradigms share a common epistemological assumption: complexity is a problem to be eliminated through abstraction.
- Object-Oriented Programming (OOP) encapsulates complexity behind interfaces, hiding internal state
- Functional Programming (FP) eliminates side effects, reducing programs to pure transformations
- Procedural programming linearizes execution, replacing concurrency with sequence
These strategies are powerful for building closed, bounded systems where the programmer can anticipate all relevant states in advance. But they break down when applied to open, complex, emergent systems — precisely the kind of systems that P2P infrastructure must support.
The failure mode is always the same: the abstraction boundary becomes a wall that the system's actual complexity cannot respect. Side effects leak through interfaces. State escapes encapsulation. The linear pipeline encounters a feedback loop it was not designed to handle. The FSM reaches a state it was not designed to represent.
3.2 Complexity Oriented Programming: The Inversion
COP inverts the reductive assumption. Instead of hiding complexity through abstraction, COP models complexity faithfully and works with it as the primary material. The vocabulary shifts:
| Reductive Paradigm | Complexity Oriented Programming |
|---|---|
| Single source of truth | Distributed state with coherence protocols |
| Deterministic pipelines | Adaptive feedback architectures |
| Contained side effects | Typed relational events flowing through a graph |
| Static type at creation | Dynamic layer activation in response to context |
| Closed system design | Conditions designed for emergence |
The epistemological shift is from programmer as god (designs a closed, fully known system) to programmer as ecologist (designs conditions, observes what arises). The system is never fully knowable from the source code alone.
3.3 Where COP Already Exists
COP is not invented here — it is being discovered simultaneously in several places:
- Holochain's agent-centric model: there is no global state machine. Each agent runs local validation rules, and global coherence emerges from the aggregate of local actions. The DHT is not designed; it arises.
- ValueFlows/REA: the economic model is not a state machine but a flow of events. Resources do not "have states" in the FSM sense — they accumulate economic events that describe what has happened to them. The past is permanent; the present is an interpretation of the past.
- Actor model concurrency: concurrent entities with private state communicating through asynchronous messages — the distributed system coordinates without shared mutable state.
- Reactive/dataflow systems (FRP, signals): time and context are primary, not afterthoughts. Computation is driven by the flow of values through a graph, not by sequential instruction execution.
- Cellular automata: global patterns emerge from purely local rules. Complexity at the macro level is not programmed; it is grown.
3.4 The NDO as a COP Primitive
The NDO is the fundamental COP primitive in the Nondominium system. Its design embodies COP in every structural choice:
- Layer activation is not a state machine transition — it is a response to rising environmental complexity, designed to allow emergence rather than constrain it
- Capability slots are not predefined interfaces — they are typed relational events that flow through the DHT link graph, allowing unforeseen tools to attach without modifying the NDO entry
- Lifecycle transitions are not deterministic state machine edges — they are feedback arcs driven by economic events (agents' actions feeding back into the resource's representation of itself)
- The tombstone at end of life is not a deletion — it is the permanent memory that the system was alive, respecting the append-only nature of the DHT as a feature, not a constraint
The honest challenge of COP, noted in the complexity_oriented_programming archive: tooling. Debuggers, type systems, and unit tests all assume reducibility. COP requires new verification paradigms — closer to simulation and formal methods than conventional testing. The Nondominium testing strategy relies on Sweettest (Rust, multi-agent) for backend validation; legacy Tryorama tests in tests/ are deprecated.
4. The Three-Layer Model: The Prima Materia
The prima materia is realized in the NDO as a three-layer structure, where each layer corresponds to a different register of complexity and is activated independently in response to the resource's current context.

Layer 0 (NondominiumIdentity) is always present — implemented in MVP. Layer 1 (ResourceSpecification via NDOToSpecification) and Layer 2 (Process via NDOToProcess) are normative targets not yet wired in code; each layer adds overhead only when the environment demands it.
4.1 The Brain Architecture Analogy

The triune brain evolved in layers: brainstem (always active) → cerebellum (coordination) → cortex (higher cognition, optional). The NDO mirrors this: Layer 0 (permanent anchor) → Layer 1 (specification) → Layer 2 (process). Each layer adds complexity only when the environment demands it.
The human brain provides the most vivid structural analogy. It did not evolve as a single organ — it evolved in layers, each built on and coupled to the previous:
- The brainstem handles vital functions: breathing, heartbeat, arousal. It is always active. The organism cannot survive without it. It is the oldest evolutionary layer.
- The cerebellum handles coordination, posture, and procedural memory — the form of the body's activity. It evolved on top of the brainstem and is coupled to it, but can be understood as a distinct functional layer.
- The cortex handles higher cognition, agency, and deliberate action. It evolved on top of the cerebellum and is the most recently evolved layer. It is situational — not all cognitive tasks require cortical engagement.
This is also a manifestation of path dependency in evolution.
These layers do not replace each other. They are coupled and co-active. The cortex does not work without the brainstem. But the brainstem can sustain basic life without the cortex (as in the case of brain death with brainstem function preserved). And at death, the cortex goes first.
The NDO mirrors this exactly:
┌─────────────────────────────────────────────────────────────────┐
│ Layer 2 — PROCESS │
│ (cortex: agency, higher cognition, multi-agent economic work) │
│ Activated situationally. Deactivated at hibernation / EOL. │
├─────────────────────────────────────────────────────────────────┤
│ Layer 1 — SPECIFICATION │
│ (cerebellum: coordination, form, replication) │
│ Activated when form needs to be shared. Archived at EOL. │
├─────────────────────────────────────────────────────────────────┤
│ Layer 0 — IDENTITY │
│ (brainstem: vital functions, always on, the tombstone) │
│ Always active. The last thing standing. Never voided. │
└─────────────────────────────────────────────────────────────────┘
4.2 Layer 0: Identity — The Permanent Anchor
Layer 0 is the prima materia in its most essential form. It is the minimum viable NDO — the smallest structure that gives a resource a stable, cryptographically-anchored identity in the DHT.
Status: ✅ Implemented in MVP (zome_resource integrity + coordinator ndo_identity.rs; UI via Group-scoped NDO creation and lifecycle transition modals). Layers 1 and 2 remain post-MVP (see §1.1).
Structure (as implemented in dnas/nondominium/zomes/integrity/zome_resource/src/lib.rs):
#![allow(unused)] fn main() { pub struct NondominiumIdentity { pub name: String, pub initiator: AgentPubKey, pub property_regime: PropertyRegime, pub resource_nature: ResourceNature, pub lifecycle_stage: LifecycleStage, pub created_at: Timestamp, pub description: Option<String>, /// Set once when entering `Deprecated` (REQ-NDO-LC-06); also linked via `NdoToSuccessor`. pub successor_ndo_hash: Option<ActionHash>, /// Set on → `Hibernating` (records pre-pause stage); cleared on resume from hibernation. pub hibernation_origin: Option<LifecycleStage>, } }
Shared enums live in crates/shared/src/types.rs. PropertyRegime has seven variants (Private, Commons, Collective, Pool, CommonPool, Public, Nondominium); ResourceNature includes Physical, Digital, Service, Hybrid, and Information. The UI (packages/shared-types and creation/filter controls) exposes all seven PropertyRegime options.
Key properties:
- The original
create_ndoaction hash is the permanent, stable Layer 0 identity — a namespace that future layers and capability slots link to (REQ-NDO-L0-02). - It is never deleted — integrity validation rejects all deletes (
validate_delete_nondominium_identity); Holochain's append-only model plus explicit validation ensures the identity remains readable as a tombstone atEndOfLife(REQ-NDO-L0-03, REQ-NDO-L0-06). - Immutable after creation:
name,initiator,property_regime,resource_nature,created_at, anddescriptioncannot change on update. This is stricter than a free-text “living description”; editorial history belongs in Layer 1 or process records post-MVP. - Mutable on lifecycle update only:
lifecycle_stage— integrity-validated state machine (§5.3); forward chain is monotonic (no skipping stages);Hibernatingand terminal transitions (Deprecated,EndOfLife) have special rules.successor_ndo_hash— set exactly once when enteringDeprecated; must reference an existing DHT record (REQ-NDO-LC-06).hibernation_origin— set when enteringHibernating, cleared when resuming to the recorded origin stage.
- Authorization (MVP): only the
initiatormay callupdate_lifecycle_stage. Full governance-as-operator role checks (REQ-NDO-LC-07) and automaticEconomicEventgeneration per transition (REQ-NDO-LC-03) are deferred;NdoToTransitionEventlinks exist for future wiring. - Discovery: global and faceted anchors —
AllNdos,AgentToNdo,NdoByLifecycleStage,NdoByNature,NdoByPropertyRegime(REQ-NDO-L0-07). The Lobby/Group UI browses and filters NDOs on these dimensions.
When Layer 0 exists alone (typical today — Layers 1 & 2 not yet linked):
- A stub registration at
Ideation: “this thing exists; I intend to develop it” (UI default initial stage). - An identity carrying full classification (
property_regime,resource_nature,lifecycle_stage) before any linkedResourceSpecificationor process entries. - A tombstone at
EndOfLife(or archived identity atDeprecatedwith successor): Layer 0 remains; upper layers are design targets, not yet activated in code. - The minimal representation of an idea that has not yet been designed — sufficient for discovery and lifecycle progression without Layer 1 assets.
4.3 Layer 1: Specification — The Form
Status: 🔄 Post-MVP (not activated in code). Legacy
ResourceSpecificationentries exist inzome_resourcebut are not linked to Layer 0 viaNDOToSpecification. Project-type know-how bundles are specified inpost-mvp/project-type-ndo-specifications.md.
Layer 1 is activated when a resource has a form that needs to be communicated to others — when the resource is ready to be described, shared, peer-reviewed, or replicated.
Activation mechanism: Creation of an NDOToSpecification link from the Layer 0 identity hash to a ResourceSpecification entry.
Layer 1 carries:
- Design intent and description (what the resource is)
- Governance rules (who can access it and how)
- Assets: files, 3D models, code references, digital integrity manifests, documentation links
- Tags and categories for discovery
When to activate Layer 1:
- The resource has a design worth sharing with others
- Distributed fabrication is intended (the spec is the product)
- Peer review or validation of the design is needed
- The resource needs to be discoverable by category or tag
When Layer 1 becomes dormant:
- The resource enters hibernation or end of life
- The specification is archived (
is_active: false) - The
NDOToSpecificationlink remains readable (DHT is append-only), but no new updates are made to the spec
The design file as the product: In the distributed fabrication context (cosmolocal production), the Layer 1 specification is the product in the most meaningful sense. When a hardware design reaches Stable lifecycle stage, anyone with a 3D printer and the fabrication spec can produce a local instance. The spec is not documentation for a product — it is the shareable, replicable artifact. This is the nondominium model's most radical departure from capitalist product logic.
4.4 Layer 2: Process — The Activity
Status: 🔄 Post-MVP (not activated in code).
EconomicEvent,Commitment, andClaimexist inzome_gouvernancebut are not linked to NDO identity viaNDOToProcess. Federation extensionsNdoHardLink,Contribution, andAgreement(#103) provide partial cross-NDO process semantics; see §11.7.
Layer 2 is activated when there is active multi-agent economic work around the resource — when contributions are being tracked, custody is being transferred, use events are being recorded, or commitments are being made.
Activation mechanism: Creation of an NDOToProcess link from the Layer 0 identity hash to a ValueFlows Process entry.
Layer 2 carries:
EconomicEventrecords of all actions taken on or with the resourceCommitmentrecords of agents' intentions to perform future actionsClaimrecords linking commitments to fulfilling eventsPrivateParticipationClaim(PPR) records issued to participants- Labor contribution tracking for OVN-compliant attribution
When to activate Layer 2:
- A second agent becomes involved (multi-agent coordination begins)
- Development work begins in earnest and contributions need to be tracked
- Custody transfers are required
- Use events or resource access need to be recorded
- PPRs need to be issued (any economically accountable interaction)
When Layer 2 becomes dormant:
- The process concludes: all commitments are fulfilled or cancelled, all events are finalized
- The resource enters hibernation (process paused, not terminated)
- End of life: process is formally concluded with terminal events
4.5 Layer Composition Across the Lifecycle
graph TD
L0["Layer 0: Identity\n(always active)"]
L1["Layer 1: Specification\n(activated when form exists)"]
L2["Layer 2: Process\n(activated for active work)"]
subgraph ideation ["Ideation"]
L0_i[Layer 0 only]
end
subgraph design ["Specification / Design"]
L0_d[Layer 0]
L1_d[Layer 1 activated]
L0_d --> L1_d
end
subgraph dev ["Development / Active"]
L0_v[Layer 0]
L1_v[Layer 1]
L2_v[Layer 2 activated]
L0_v --> L1_v --> L2_v
end
subgraph hib ["Hibernation"]
L0_h[Layer 0]
L1_h["Layer 1 (dormant)"]
L2_h["Layer 2 (dormant)"]
L0_h --> L1_h -.-> L2_h
end
subgraph eol ["End of Life"]
L0_e["Layer 0 (tombstone)"]
L1_e["Layer 1 (archived)"]
L2_e["Layer 2 (concluded)"]
L0_e --> L1_e -.-> L2_e
end
ideation --> design --> dev --> hib --> eol
5. Resource State Model: Two Orthogonal Dimensions
Implementation snapshot (MVP):
LifecycleStageis implemented onNondominiumIdentity(10 stages, integrity-validated transitions, initiator-only authorization in the coordinator).OperationalStateis implemented onEconomicResource(7 states, custodian-initiated updates viaupdate_operational_state, faceted discovery viaResourcesByOperationalState). Governance-zome ownership of operational transitions (REQ-NDO-OS-02/03) remains deferred.
The legacy ResourceState enum conflated two independent dimensions. The NDO requires their explicit separation:
LifecycleStage— the maturity or evolutionary phase of the resource as an artefact. Advances rarely and (mostly) irreversibly, driven by significant events (design completion, peer validation, fabrication, end-of-life declaration). Lives on theNondominiumIdentity(Layer 0).OperationalState— what process is currently acting on a specific resource instance. Cycles frequently as processes begin and end. Managed by the governance zome. Lives on theEconomicResourceinstance (Layer 2).
The key distinction: transport, storage, and maintenance are processes that can apply to a resource at any lifecycle stage. A Prototype can be InTransit (moved between R&D labs). An Active resource can be InStorage, InTransit, or InMaintenance simultaneously with its lifecycle stage. These are not lifecycle milestones — they are transient operational conditions.
5.1 LifecycleStage Enum
Lives on NondominiumIdentity. Describes what the resource has become, not what is happening to it right now.
#![allow(unused)] fn main() { pub enum LifecycleStage { // --- Emergence Phase --- Ideation, // Placeholder: name and intent only. Layer 0 alone. Specification, // Design/requirements being written. Layer 1 activating. Development, // Active construction, prototyping. Layers 0+1+2 active. Prototype, // PoC exists, not production-ready. Layers 0+1+2 active. // --- Maturity Phase --- Stable, // Production-ready, design is replicable. All layers active. Distributed, // Being actively fabricated/used across the network. // --- Operation Phase --- Active, // In normal use. All layers active. // --- Suspension --- Hibernating, // Not end-of-life — dormant. Layers 1+2 dormant, L0 active. // --- Terminal --- Deprecated, // Superseded by a newer version. Links to successor. EndOfLife, // Concluded. L0 tombstone, L1 archived, L2 concluded. } }
Note:
MaintenanceandReservedare not lifecycle stages — they describe transient operational conditions and belong inOperationalState(Section 5.4).
5.2 Lifecycle → Layer Activation Table
Normative target: Layer activation via
NDOToSpecification/NDOToProcesslinks is not yet enforced in code. Today, lifecycle stage advances on Layer 0 independently; the table below describes intended coupling once Layers 1 and 2 are wired.
| Lifecycle Stage | Layer 0 | Layer 1 | Layer 2 | Notes |
|---|---|---|---|---|
Ideation | Active | — | — | Pure stub: name + property regime |
Specification | Active | Activating | — | Spec being written, governance rules defined |
Development | Active | Active | Active | Multi-agent contributions begin |
Prototype | Active | Active | Active | PoC exists, process ongoing |
Stable | Active | Active | Active | Spec is production-ready |
Distributed | Active | Active | Active | Use events flowing |
Active | Active | Active | Active | Normal operation; OperationalState cycles independently |
Hibernating | Active | Dormant | Dormant | Identity preserved; no new events |
Deprecated | Active | Archived | Concluded | Successor NDO linked |
EndOfLife | Active (tombstone) | Archived | Concluded | Permanent record only |
At any stage from
Developmentonward, theOperationalState(Section 5.4) may be any value independently of the lifecycle stage.
5.3 Lifecycle Transitions and Governing Events
Each transition between lifecycle stages shall be driven by a VfAction economic event, validated by the governance zome acting as state transition operator (REQ-ARCH-07). MVP today: transitions are validated in the integrity zome (validate_update_nondominium_identity); the initiator may call update_lifecycle_stage without a cross-zome governance evaluation. Optional transition_event_hash creates an NdoToTransitionEvent link when provided, but the referenced EconomicEvent is not yet validated cross-zome. Role-based authorization in the table below is target behaviour (REQ-NDO-LC-07), not current enforcement.
stateDiagram-v2
[*] --> Ideation : "NondominiumIdentity created"
%% Forward maturity chain (monotonic, no skipping)
Ideation --> Specification : "Produce (spec created)"
Specification --> Development : "Work (contributions begin)"
Development --> Prototype : "Produce (PoC delivered)"
Prototype --> Stable : "Accept (peer validated)"
Stable --> Distributed : "Transfer (first fabrication)"
Distributed --> Active : "Use (operational)"
%% Suspend — any non-terminal stage may enter Hibernating
Ideation --> Hibernating : "Lower"
Specification --> Hibernating : "Lower"
Development --> Hibernating : "Lower"
Prototype --> Hibernating : "Lower"
Stable --> Hibernating : "Lower"
Distributed --> Hibernating : "Lower"
Active --> Hibernating : "Lower (activity paused)"
%% Resume — always returns to the stage that was paused (hibernation_origin)
Hibernating --> Ideation : "Raise (to origin)"
Hibernating --> Specification : "Raise (to origin)"
Hibernating --> Development : "Raise (to origin)"
Hibernating --> Prototype : "Raise (to origin)"
Hibernating --> Stable : "Raise (to origin)"
Hibernating --> Distributed : "Raise (to origin)"
Hibernating --> Active : "Raise (to origin)"
%% Terminal — any non-terminal stage may deprecate or end
Hibernating --> Deprecated : "Cite (successor declared)"
Active --> Deprecated : "Cite (superseded)"
Deprecated --> EndOfLife : "Consume (formally concluded)"
Active --> EndOfLife : "Consume (formally concluded)"
Hibernating is a memory-preserving pause. The
hibernation_originfield records the stage that was active before enteringHibernating. On resume ("Raise"), the resource returns to exactly that stage — not necessarilyActive. This means a resource paused atSpecificationresumes atSpecification, preserving the integrity of the maturity chain.The Mermaid above shows representative "Raise" arrows; in practice, the valid resume target is always
hibernation_origin, enforced by the integrity zome.
Transition authorization by role (target — REQ-NDO-LC-07; MVP: initiator only):
| Transition | Authorized by |
|---|---|
| Ideation → Specification | Initiator (Layer 0 creator) |
| Specification → Development | Initiator or any Accountable Agent with contribution |
| Development → Prototype | Custodian + governance validation |
| Prototype → Stable | Multi-agent peer validation (configurable N-of-M) |
| Stable → Distributed | Custodian |
| Distributed → Active | Custodian |
| Any → Hibernating | Current custodian(s) |
| Hibernating → {origin stage} | Current custodian(s) |
| Any → Deprecated | Custodian + declaration of successor NDO |
| Any → EndOfLife | Custodian + challenge period (see REQ-GOV-11 to REQ-GOV-13) |
5.4 OperationalState Enum
Status: ✅ Implemented (data layer).
EconomicResource.operational_stateusesOperationalState.ResourcesByOperationalStatereplaces legacyResourcesByState. Lifecycle faceting remains onNdoByLifecycleStage(Layer 0). Governance-zome transition rules (REQ-NDO-OS-02/03) remain deferred.
Lives on EconomicResource (Layer 2). Describes what process is currently acting on a specific resource instance. Set and cleared by the governance zome when processes begin and end.
#![allow(unused)] fn main() { pub enum OperationalState { // Default — no active process. Available, // A Commitment exists for a future process; no active Event yet. // Cleared when the Event is created or the Commitment is cancelled. Reserved, // A transport process is active (a TransferCustody or Move Event is open). // Valid at any LifecycleStage (a Prototype may be InTransit between labs). InTransit, // A storage service commitment is active. // Valid at any LifecycleStage. InStorage, // A repair or maintenance process is active (a Modify Event is open). // Valid at any LifecycleStage; does NOT advance the lifecycle. InMaintenance, // Actively being used (a Use Event is open). InUse, // Awaiting peer validation before becoming Available. // Initial state for newly created EconomicResource instances. PendingValidation, } }
OperationalState transitions (governed by the governance zome, triggered by EconomicEvents):
| Trigger | From | To |
|---|---|---|
EconomicResource created | — | PendingValidation |
| Peer validation approved | PendingValidation | Available |
| Commitment accepted | Available | Reserved |
| Commitment cancelled | Reserved | Available |
Transport process begins (Move / TransferCustody event) | Available or Reserved | InTransit |
Transport process completes (Accept event) | InTransit | Available |
| Storage process begins | Available or Reserved | InStorage |
| Storage process completes | InStorage | Available |
Maintenance process begins (Modify event) | Available | InMaintenance |
Maintenance process completes (Accept event) | InMaintenance | Available |
Use begins (Use event opened) | Available | InUse |
| Use ends | InUse | Available |
OperationalStatetransitions do not advanceLifecycleStage. A resource that completes a repair cycle returns toOperationalState::Availableat the sameLifecycleStageit had before.
6. The Surface of Attachment — Capability Slots
Implementation snapshot:
CapabilitySlotlinks and theSlotTypeenum are not yet inzome_resource. Federation extensionsNdoHardLink,Contribution, andAgreement(#103) inzome_gouvernanceprovide a partial cross-NDO attachment and process record — related in purpose but structurally distinct from the stigmergicCapabilitySlotpattern defined here. Unyt and Flowsta integrations (§6.6–6.7) remain post-MVP.
A central requirement of the NDO is that it must not need to anticipate all future capabilities at design time. Like Discord channels to which anyone can add integrations, or like the MOSS Weave Interaction Pattern where hApps can link to any Weave Asset, the NDO must provide a surface of attachment for capabilities that do not yet exist.
6.1 The COP Principle of the Attachment Surface

Any agent freely attaches capability slots (GovernanceDAO, UnytAgreement, FlowstaIdentity, custom operators) to the NDO's Layer 0 identity hash without modifying the NDO entry itself — pure stigmergy: coordination through environmental modification, not central authority.
In COP terms: you cannot design the attachment surface in advance. The DHT link space is the surface. Any agent, any hApp, any future tool that knows the Layer 0 identity hash can create a link from that hash to whatever it needs to attach. The NDO entry itself does not change.
This is stigmergy in the complexity economics sense: indirect coordination through the environment. Ants coordinate the construction of a nest not by communicating plans but by leaving pheromone trails (environmental modifications) that other ants respond to. The NDO's Layer 0 hash is the pheromone trail — any agent can respond to it by attaching capabilities.
6.2 Stigmergic Link Channels
The attachment mechanism uses typed DHT links with structured link tags:
NDO_identity_hash →[LinkType: CapabilitySlot, tag: { slot_type, author, attached_at }]→ capability_target_hash
Predefined slot type vocabulary (extensible):
| Slot Type | Description | Typical target |
|---|---|---|
Documentation | Human-readable docs, wiki, manuals | Wiki entry hash or external URI |
IssueTracker | Bug reports, feature requests | Issue tracker hApp cell hash |
FabricationQueue | Distributed manufacturing requests | Fabrication process hash |
GovernanceDAO | Governance proposals and voting | DAO hApp cell hash |
VersionGraph | Version history and forks | Versioned entity hash (see post-mvp/ndo-versioning.md) |
DigitalAsset | Files, 3D models, code, manifests | Asset manifest hash |
WeaveWAL | Moss/Weave Asset Link | WAL (Weave Asset Locator) |
FlowstaIdentity | Cross-app identity attestation | IsSamePersonEntry action hash |
UnytAgreement | Programmable economic terms governing value flows triggered by resource interactions | Unyt Smart Agreement entry hash (cross-cell reference) |
CustomApp | Any other hApp integration | Any hash, labelled by consumer |
6.3 MOSS / Weave Integration
The Weave Interaction Pattern defines an open standard for creating, searching, linking, and organizing "social space units" — precisely what an NDO is. MOSS integration works as follows:
- The NDO is declared as a Weave Asset by creating a
WeaveWALcapability slot pointing to the asset's WAL - Other MOSS tools (issue trackers, document editors, governance DAOs, fabrication queues) can attach to the NDO's Layer 0 hash via the Weave protocol without modifying the NDO entry
- As the NDO gains lifecycle stages, MOSS tools can respond to those transitions — a fabrication queue tool might automatically activate when the NDO reaches
Stable
6.4 Governance of the Attachment Surface
Status: ❌ Not implemented for
CapabilitySlottrust filtering. The rules below describe target governance behaviour once capability slots land inzome_resource.
The stigmergic surface is permissionless at the DHT level — any agent can create a capability link. But the governance layer determines which links are trusted and surfaced to other agents, versus which are ignored or filtered:
- Links created by the initiator or custodians are trusted by default
- Links created by Accountable Agents are conditionally trusted
- Links created by unknown agents are filtered until governance validation
- The governance zome can validate capability attachments using the same
validate_new_resourcepattern already in place
This mirrors the approach taken in the wider complex systems literature: edge-based sensing and attachment is permissionless (lower information opportunity costs), while trust propagation and filtering happens through distributed consensus rather than centralized gatekeeping.
6.5 CapabilitySlot on Agent Identity (Post-MVP)
TODO (G15 — Agent CapabilitySlot): The stigmergic attachment pattern described in this section applies equally to agent identities. The
Personentry hash is itself a stable, permanent identity anchor — analogous to theNondominiumIdentityLayer 0 hash — and should serve as a surface of attachment for external capabilities:
- DID documents (W3C Decentralised Identifiers)
- Verifiable Credential wallets
- Reputation oracles from other networks
- Professional credential registries
- Social graph exports
An agent's
Personentry hash →CapabilitySlot→ external capability target, using the sameCapabilitySlotTag/SlotTypepattern defined in Section 8.3. This enables credential portability and DID interoperability without modifying the corePersonentry schema.See
documentation/archives/agent.md§3.2 andREQ-AGENT-11.Flowsta Auth (Section 6.7) provides the first concrete implementation of this pattern: a
FlowstaIdentitycapability slot linking thePersonhash to anIsSamePersonEntry— a dual-signed cryptographic attestation that the agent's NDO key and their Flowsta Vault key belong to the same person. This gives every agent a W3C DID (did:flowsta:uhCAk...) without modifying thePersonentry schema.
6.6 Economic Agreement Slots — Unyt Integration
A detailed analysis of the UnytAgreement slot type, its relationship to the governance layer, and the three-phase integration path.
Why Unyt Is a Capability, Not a Layer

Simple resources (Ideation/Specification) need zero economic overhead. Moderate resources (Active, distributed) benefit from GovernanceRules and custody tracking. Complex, high-value rivalrous resources justify Unyt Smart Agreements and RAVE proofs. Pay-as-you-grow.
The prima materia model has three structural layers. It might seem natural to propose a fourth — an "Economic Layer" — for payment and value-flow infrastructure. This would be the wrong architecture.
The COP principle of pay-as-you-grow is explicit: impose only the coordination overhead that the resource's current social complexity demands. Not all resources need payment infrastructure. A bicycle lent between neighbours does not need a Unyt Smart Agreement. A shared CNC machine used by fifty contributors under a usage-fee model does. Imposing economic infrastructure at NDO creation — making it structural — would repeat the reductive paradigm mistake that the three-layer model was designed to avoid. It would be a fixed classification at t=0 of a future that no agent can know.
Unyt belongs in the capability surface for the same reason that governance DAOs, fabrication queues, and issue trackers do: it is an economic operator that some resources need and others do not, and its attachment should emerge from the network's actual practice rather than be prescribed by the programmer.
The UnytAgreement slot type has one property that other slot types do not: it is governance-enforceable. A Documentation link is informational — the governance zome does not condition state transitions on it. A UnytAgreement link, when endorsed through a GovernanceRule of type EconomicAgreement, becomes a precondition for transition approval. This makes it a hybrid: permissionless at the attachment surface, authoritative at the governance layer.
Two-Tier Economic Authority
The UnytAgreement capability slot operates at two tiers.
Tier 1 — Permissionless Proposal (CapabilitySlot)
Any Accountable Agent can attach a Unyt Smart Agreement to any NDO by creating a CapabilitySlot link of type UnytAgreement. This is an assertion: "I believe this agreement should govern interactions with this resource." The governance zome does not enforce it. Other agents can read it as a proposal, a community suggestion, or a pricing signal. Multiple competing proposals may coexist.
This tier respects the stigmergic principle: lower information opportunity costs, permissionless economic expression, no gatekeeping on proposals.
Tier 2 — Governance Endorsement (GovernanceRule)
When the NDO's custodian — or a community governance process — formally endorses a Unyt Smart Agreement by creating a GovernanceRule entry of type EconomicAgreement, the agreement becomes enforceable. State transitions that trigger it (Access, CustodyTransfer, service processes) require the requesting agent to provide a valid Unyt RAVE as proof of economic settlement before the governance zome approves the transition.
The capability slot (Tier 1) and the governance rule (Tier 2) are independent but complementary: the slot makes the agreement discoverable; the rule makes it mandatory.
graph TD
Agent["Any Accountable Agent"]
Custodian["Custodian / Governance Process"]
NDO["NDO Identity Hash (Layer 0)"]
Unyt["Unyt Smart Agreement\n(on Unyt DHT)"]
GovRule["GovernanceRule\n(EconomicAgreement type)\n— Layer 1 asset —"]
Transition["State Transition Request\n(AccessForUse, CustodyTransfer, etc.)"]
GovZome["Governance Zome\n(state transition operator)"]
RAVE["Unyt RAVE\n(proof of settlement)"]
PPR["PrivateParticipationClaim (PPR)\n+ settlement_rave_hash"]
Agent -->|"CapabilitySlot link\n(Tier 1: permissionless proposal)"| NDO
NDO -.->|"links to"| Unyt
Custodian -->|"GovernanceRule\n(Tier 2: endorsed terms)"| GovRule
GovRule -->|"linked from ResourceSpecification\n(Layer 1)"| NDO
Transition -->|"includes rave_hash"| GovZome
GovZome -->|"validates EconomicAgreement rule"| GovRule
GovZome -->|"validates RAVE against Unyt DHT"| RAVE
GovZome -->|"on approval, issues"| PPR
PPR -->|"settlement_rave_hash"| RAVE
Unyt Smart Agreement as Economic GovernanceRule
The current GovernanceRule entry in zome_resource carries rule_type, rule_data (JSON-encoded), and an optional enforced_by role requirement. The Unyt integration adds a new rule_type variant and a corresponding structured rule_data schema:
#![allow(unused)] fn main() { // New variant in GovernanceRuleType enum (zome_resource integrity) pub enum GovernanceRuleType { // ... existing rule types ... EconomicAgreement, // rule_data: JSON-serialized EconomicAgreementRuleData } // rule_data schema for EconomicAgreement rules #[derive(Serialize, Deserialize)] pub struct EconomicAgreementRuleData { pub unyt_alliance_id: String, // Network seed of the Unyt Alliance pub smart_agreement_hash: String, // Entry hash of the Unyt Smart Agreement pub trigger_actions: Vec<VfAction>, // Which VfActions trigger this agreement pub settlement_window_secs: u64, // Max time between RAVE execution and transition request pub note: Option<String>, // Human-readable description of the economic terms } }
When the governance zome encounters an EconomicAgreement rule during a state transition evaluation, it executes the following validation sequence:
- Confirms that the transition's
VfActionis in the rule'strigger_actionslist - Requires a
rave_hashfield in the transition request payload - Queries the Unyt DHT (via cross-DNA
call()) to retrieve and validate the RAVE - Confirms the RAVE was executed within the declared
settlement_window_secs - Confirms the RAVE's inputs match the transition context (resource identity, provider, receiver, quantity or duration)
- Only then approves the state transition and issues the PPR
This makes the governance zome's approval conditional on cryptographic proof of economic settlement — the resource does not move (physically, digitally, or in custody) until the agreed value has flowed.
Value Flow Patterns
Four standard patterns map the most common resource-interaction economics onto Unyt's Smart Agreement library:
| Pattern | Trigger VfAction | Unyt Agreement Template | Economic logic |
|---|---|---|---|
| Access Fee | AccessForUse | Conditional Forward | User pre-pays; access granted on RAVE |
| Service Billing | Work (fulfilled Claim) | Proof-of-Service | Provider paid on validated Claim |
| Revenue Sharing | Transfer | Aggregate Payment | Proceeds split: custodian / protocol / creator |
| Custody Bond | TransferCustody | Conditional Forward (escrowed) | Bond held; returned on clean handoff with PPR |
These map directly to the Smart Agreement templates in the Unyt Smart Agreement Library. The Conditional Forward template is the workhorse for access and custody patterns; Aggregate Payment and Proof of Service serve billing and revenue distribution.
The templates use RHAI scripting — the same logic that currently drives Unyt's DePIN billing (Log → Invoice → Agreement → Settlement). For Nondominium, the "log" is the Nondominium Commitment + Claim + ValidationReceipt chain; the invoice is implicit in the EconomicAgreementRuleData; the settlement is the RAVE.
PPR and RAVE: A Complete Provenance Chain
When a state transition is approved with a valid RAVE, the PrivateParticipationClaim generated for the interaction carries the RAVE hash as an optional field:
#![allow(unused)] fn main() { pub struct PrivateParticipationClaim { // ... existing fields ... pub settlement_rave_hash: Option<String>, // Unyt RAVE hash, if economic settlement occurred } }
This creates a complete, cross-verifiable provenance chain:
Commitment
└─ (fulfilled by) EconomicEvent
└─ (generates) PrivateParticipationClaim (PPR)
└─ settlement_rave_hash → Unyt RAVE
└─ (verifiable on Unyt DHT: inputs, outputs, agreement, executor)
The PPR is the participation proof: who did what, at what quality, in which role. The RAVE is the economic proof: what value flowed, to whom, under what rules, verified by Unyt peers. Together, they constitute a full, mutually-reinforcing record of a resource interaction that neither system alone can provide.
This linkage also feeds back into the credit system: agents whose PPRs consistently carry RAVEs (meaning they reliably execute their economic obligations) earn higher reputation scores, which in turn increases their Unyt credit limits (see post-mvp/unyt-integration.md). Reputation and credit become two readings of the same underlying participation data.
The Resource as Economic Actor
When an NDO has an endorsed EconomicAgreement governance rule, it becomes a self-pricing, self-settling economic actor. No platform intermediary determines what the resource costs, no rent is extracted by infrastructure owners, and no contract enforcement requires a legal system. The community that embedded the rule in the resource's Layer 1 specification determines the economic terms, and Unyt enforces them cryptographically among peers.
This is the nondominium model's deepest departure from platform economics. Platform platforms capture value by positioning themselves between resource and user — Airbnb between host and guest, Uber between driver and passenger. In the NDO model, the "platform" is the DHT itself: owned by no one, accessible to everyone, governed by the rules the community wrote into the resource. The resource is simultaneously a physical or digital artifact, a governance system, and an economic agent.
In complexity economics terms: the resource has become a holon with economic agency. Not only does it exist within the economic web (participating in ValueFlows events), it actively shapes the economic flows that run through it — enforcing its own terms, rewarding its stewards, and settling its debts, all without human intermediation.
Integration Path
The Unyt integration is structured as three independent phases, each delivering immediate value and requiring no rollback of prior work.
Phase 1 — Capability Surface Extension (no zome structural changes required)
Add UnytAgreement(String) to the SlotType enum. Any Accountable Agent can now attach a proposed Unyt Smart Agreement to any NDO. The governance zome does not enforce these links — they are informational, discoverable proposals. This phase delivers: economic expression in the network (market pricing signals without enforcement), tooling foundations (UIs can surface proposed payment terms), and community standard-setting (the network can develop shared pricing conventions before enforcement is added).
Phase 2 — Governance Rule Extension (zome_resource changes only)
Add EconomicAgreement to the GovernanceRuleType enum and define the EconomicAgreementRuleData schema. Custodians can now formally endorse a Unyt Smart Agreement by creating a GovernanceRule entry. The governance zome reads these rules but does not yet enforce them at transition time — Phase 2 makes the endorsement discoverable and legible to the network without yet conditioning transitions on RAVEs. This phase delivers: governance-layer economic declarations, tooling for custodians to set and communicate official payment terms, and the data structure foundation for Phase 3.
Phase 3 — Governance Zome Integration (zome_gouvernance changes)
The governance zome's evaluate_transition_request function is extended to: (a) check for EconomicAgreement governance rules when processing relevant VfAction events; (b) require a rave_hash in transition requests when such a rule exists; (c) validate the RAVE via cross-DNA call to the Unyt cell; (d) link the RAVE hash into the generated PPR via settlement_rave_hash. This phase delivers: full enforcement, automatic settlement, and the complete PPR↔RAVE provenance chain. The NDO becomes a fully self-pricing economic actor.
6.7 Identity and Authentication Slots — Flowsta Integration
A detailed analysis of the FlowstaIdentity slot type, its relationship to the agent identity surface (Section 6.5), and the three-phase integration path.

Tier 1: any agent voluntarily attaches a FlowstaIdentity slot (permissionless trust signal). Tier 2: governance rules can require a valid Flowsta link for high-trust transitions (e.g. PrimaryAccountableAgent promotion). The dual-signed IsSamePersonEntry on the NDO DHT yields a W3C DID without modifying the Person entry schema.
Why Flowsta Is a Capability, Not a Layer
The prima materia model has three structural layers. It might seem natural to propose cross-app identity as a mandatory component of Layer 0 — to require every agent to complete Flowsta Vault linking before they can participate. This would be the wrong architecture.
The COP principle of pay-as-you-grow is explicit: impose only the coordination overhead that the resource's current social complexity demands. Not all communities need cross-app identity. A neighbourhood tool-sharing network may operate perfectly well with Holochain-native AgentPubKey identifiers and locally-earned PPR reputation. A multi-network fabrication coalition spanning multiple Holochain apps — where contributors participate in design, fabrication, logistics, and economic settlement across separate DHTs — needs verifiable cross-app identity to prevent sybil fragmentation and enable reputation portability.
Imposing Flowsta at agent registration — making it structural — would repeat the reductive paradigm mistake that the three-layer model was designed to avoid. It would be a fixed classification at t=0 of a future that no agent can know: whether this particular agent will ever need cross-app identity, whether this particular community will ever span multiple networks.
Flowsta belongs in the capability surface for the same reason that Unyt does: it is an identity operator that some communities need and others do not, and its attachment should emerge from the network's actual practice rather than be prescribed by the programmer.
IsSamePersonEntry: The Cross-App Attestation
Flowsta's agent linking mechanism creates a cryptographic attestation — IsSamePersonEntry — on the NDO's DHT that proves two Holochain agent keys belong to the same person. The attestation is committed via the flowsta-agent-linking zomes (flowsta-agent-linking-integrity and flowsta-agent-linking-coordinator), which are added to the NDO's DNA manifest.
The 78-byte signing payload:
- Bytes 0–38: First agent public key (39 bytes: 3-byte prefix + 32-byte Ed25519 key + 4-byte checksum)
- Bytes 39–77: Second agent public key (same format)
- Both keys are sorted lexicographically for canonical ordering
- Both agents sign this payload: the NDO agent key signs via the local conductor, and the Flowsta Vault agent key signs via the Vault's lair keystore
Verification properties:
- Purely cryptographic: Ed25519 signature verification on the dual-signed payload — no shared DNA, no API dependency, no central authority needed for verification
- Any agent on the NDO DHT can verify the attestation by checking both signatures against the embedded public keys
- Purpose-specific: Flowsta Vault computes the signing payload itself and displays it to the user for approval — apps cannot trick the Vault into signing arbitrary data
- Revocable: either party can revoke the link via the
revoke_linkzome function - Each Flowsta user carries a W3C DID:
did:flowsta:uhCAk...(ordid:key:z6Mk...), providing a standards-compliant cross-app identifier
Two-Tier Identity Authority
The FlowstaIdentity capability slot operates at two tiers, paralleling the Unyt two-tier model (Section 6.6).
Tier 1 — Permissionless Attestation (CapabilitySlot)
Any agent can link a Flowsta identity to their Person entry by creating a CapabilitySlot link of type FlowstaIdentity, pointing to the IsSamePersonEntry action hash. This is an assertion: "I have completed Vault agent linking (dual-signed attestation)." The governance zome does not enforce it at Tier 1. Other agents can read it as a trust signal — a voluntarily disclosed cross-app identity. Multiple agents may have Flowsta links; some may not.
This tier respects the stigmergic principle: lower information opportunity costs, permissionless identity expression, no gatekeeping on attestation.
Tier 2 — Governance Requirement (GovernanceRule / Role Promotion)
When a community's governance rules require verified cross-app identity — for example, as a precondition for PrimaryAccountableAgent role promotion, or for custody transfer of high-value resources — the governance zome can condition role transitions on the presence of a verified FlowstaIdentity capability slot on the agent's Person hash. The verification checks:
- A
FlowstaIdentityCapabilitySlot link exists from the agent'sPersonhash - The target
IsSamePersonEntrycontains the agent'sAgentPubKeyas one of the two signing parties - The attestation has not been revoked
The capability slot (Tier 1) makes the identity discoverable; the governance rule (Tier 2) makes it mandatory for specific actions.
graph TD
Agent["Agent on NDO DHT"]
Vault["Flowsta Vault\n(local Holochain conductor + lair)"]
PersonHash["Person Entry Hash\n(agent identity anchor)"]
FlowstaSlot["FlowstaIdentity\nCapabilitySlot link"]
ISP["IsSamePersonEntry\n(dual-signed 78-byte attestation)\non NDO DHT"]
DID["W3C DID\ndid:flowsta:uhCAk..."]
OtherApp["Other Flowsta-Linked\nHolochain App"]
PPR["PrivateParticipationClaim"]
RepSummary["ReputationSummary\n(cross-app attributable)"]
GovRule["GovernanceRule\n(IdentityVerification type)"]
RolePromotion["Role Promotion\n(PrimaryAccountableAgent)"]
Agent -->|"has"| PersonHash
Agent -->|"runs"| Vault
PersonHash -->|"CapabilitySlot link\n(Tier 1: permissionless)"| FlowstaSlot
FlowstaSlot -->|"points to"| ISP
ISP -->|"dual-signed by"| Vault
ISP -->|"carries"| DID
DID -.->|"verifiable by"| OtherApp
PPR -->|"attributed to"| DID
PPR -->|"aggregated into"| RepSummary
RepSummary -.->|"portable via DID"| OtherApp
GovRule -->|"Tier 2: requires\nFlowstaIdentity slot"| RolePromotion
RolePromotion -->|"checks"| FlowstaSlot
PPR Cross-App Attribution
When an agent has linked a Tier 1 FlowstaIdentity slot to a valid, non-revoked IsSamePersonEntry, their PPR ReputationSummary becomes attributable to a cross-app DID. (This is cryptographic attestation via Vault dual-signing — not the same as Tier 2 governance enforcement in Phase 3.) This creates the foundation for portable reputation without requiring full Verifiable Credential infrastructure:
- Other Flowsta-integrated apps can query whether an agent has a linked NDO identity by checking their own DHT for an
IsSamePersonEntrycontaining the same Flowsta Vault key - The DID serves as the stable key for reputation aggregation across apps — a single DID may accumulate PPR histories from multiple independent Holochain networks
- Agents control disclosure: the
FlowstaIdentityslot is voluntary (Tier 1), and PPR summaries are already selectively shared via existing capability grants - This is the practical path toward
REQ-NDO-AGENT-08(Portable Credentials): the DID provides the identity anchor; the PPR provides the participation record; selective disclosure provides the privacy control
The cross-app attribution chain is:
Person entry (NDO DHT)
└─ FlowstaIdentity CapabilitySlot → IsSamePersonEntry
└─ carries DID: did:flowsta:uhCAk...
└─ same DID resolvable on other Flowsta-linked apps
└─ PPR ReputationSummary attributable to DID across apps
Recovery and Backup via Vault
Flowsta Vault provides recovery infrastructure that the NDO currently lacks:
- BIP39 recovery phrases: Deterministic Ed25519 keypair regeneration from a 24-word mnemonic. If an agent loses their device, they can regenerate the same key pair on a new device using their recovery phrase.
- Auto-backups: Encrypted snapshots every 60 minutes (up to 10 timestamped snapshots per app), working while the Vault is locked (after first unlock in a session). Oldest snapshots are auto-rotated.
- Full data export: Decrypted private entries and cryptographic keys can be exported, compliant with the Cryptographic Autonomy License (CAL).
This aligns with the NDO's design principle that identity must persist through all transformations. The non-deletable, append-only nature of Person entries and PPRs assumes the agent retains access to their signing key — a guarantee the current NDO architecture cannot make. Vault's deterministic key regeneration ensures that the permanent records the NDO creates remain accessible to their authors across device loss and hardware failure.
CAL alignment: The Cryptographic Autonomy License requires that users can always get a copy of their own data plus the cryptographic keys needed for independence from any particular service provider. Vault's full data export — including decrypted private entries and cryptographic keys — satisfies this requirement directly, and positions NDO communities for CAL-compliant distribution.
Flowsta and Unyt: Complementary Capabilities
Flowsta and Unyt are the two external capability integrations defined for the NDO. They are complementary and independent:
- Flowsta answers who is who — cross-app identity, DID, recovery, authentication
- Unyt answers who owes what to whom — credits, debits, settlement, economic closure
An NDO community may adopt one, both, or neither. When both are active, they reinforce each other: an agent's Flowsta DID provides the stable identity across Unyt Alliances, and their Unyt credit limit (derived from PPR reputation) is attributable to that DID (via Tier 1 link / IsSamePersonEntry, and optionally Tier 2–gated processes). The agent is simultaneously identifiable, accountable, and economically active — without any platform intermediary.
Integration Path
The Flowsta integration is structured as three independent phases, each delivering immediate value and requiring no rollback of prior work.
Phase 1 — Capability Surface Extension (no core zome structural changes required)
Add FlowstaIdentity to the SlotType enum. Add flowsta-agent-linking-integrity and flowsta-agent-linking-coordinator zomes to the DNA manifest (dna.yaml). Install @flowsta/holochain SDK in the frontend. Any agent can now link their Flowsta identity to their Person entry via a FlowstaIdentity capability slot. This phase delivers: cross-app identity expression in the network (trust signals without enforcement), DID attachment to agent profiles, and the foundation for Vault-backed key recovery.
Phase 2 — Frontend and UX Integration (UI changes only)
Add a "Link Flowsta Identity" flow in the person/profile management UI. Display linked Flowsta DIDs on agent profiles. Show Flowsta verification badges on agents in search results and governance views. Integrate Vault backup API for agent data resilience (@flowsta/holochain backup functions: startAutoBackup, backupToVault, retrieveFromVault, listVaultBackups). This phase delivers: user-facing identity management, visible trust indicators, and data resilience.
Phase 3 — Governance-Enforced Identity Verification (zome_gouvernance changes)
Add IdentityVerification variant to GovernanceRuleType (or use existing rule mechanisms). Governance rules can now require a FlowstaIdentity slot as a precondition for role promotions (e.g., PrimaryAccountableAgent) or for high-value custody transfers. The governance zome validates the IsSamePersonEntry signature chain — checking that the FlowstaIdentity slot exists, that the target IsSamePersonEntry contains the agent's AgentPubKey, and that the attestation has not been revoked — before approving the conditioned transition. This phase delivers: governance-enforced identity verification, sybil resistance for high-trust roles, and the bridge between permissionless participation and accountable governance.
7. Design Patterns
The NDO embodies six named design patterns. These patterns are architectural idioms that recur throughout the system and should guide implementation decisions.
Implementation snapshot: Pattern 1 (Identity Anchor) and Pattern 5 (Tombstone, Layer 0 only) are reflected in MVP code. Pattern 4 is partially reflected in the UI (default
Ideationcreation, lifecycle progression). Patterns 2, 3, and 6 depend on link types not yet inzome_resource. FederationNdoHardLink(#103) is a related cross-NDO attachment mechanism inzome_gouvernance, distinct from Pattern 6'sCapabilitySlotsurface.
Pattern 1: Identity Anchor
Status: ✅ Implemented (MVP) —
create_ndo, discovery anchors, immutable delete rejection.
Intent: Give every resource a stable, cryptographically-secure identity anchor that persists through all transformations, including end of life.
Structure: The NondominiumIdentity genesis entry. Its action hash is the stable namespace for all other entries and links. Nothing else in the system references a resource by any other handle.
Rationale: In complex adaptive systems, identity must be decoupled from form. A person's identity persists even as their body, beliefs, and relationships change. A corporation's identity persists through restructuring. The NDO's identity must persist through design changes, custody transfers, version forks, and end of life. Content-addressing in Holochain makes this natural: the action hash of the genesis entry never changes.
Holochain idiom:
#![allow(unused)] fn main() { // Layer 0 creation — returns the stable identity hash let ndo_hash = create_entry(&EntryTypes::NondominiumIdentity(identity))?; // Everything else links to ndo_hash }
Pattern 2: Complexity-Matched Layer Activation
Status: 🔄 Partial —
NdoToSpecification(Layer 1) is in code as of #132;NDOToProcess(Layer 2) is not.
Intent: Activate only the structural complexity that the current coordination environment demands. Do not pay coordination costs in advance of need.
Structure: Layer activation via link creation. Layer 1 activates when the NdoToSpecification link is created. Layer 2 activates when the NDOToProcess link is created. Both can be created retroactively, at any lifecycle stage the target layer's gate permits: Layer 1 accepts Specification through Active (Section 5.2), and the Layer 2 gate is not yet enforced.
Rationale: Benkler's information opportunity cost analysis: overhead that exceeds the value of the coordination it enables is pure waste. A tool being lent between friends does not need a full ValueFlows process. A community hardware standard being developed across fifty fabrication networks does. The NDO model allows the system's complexity to grow with the resource's social complexity, not ahead of it.
Holochain idiom:
#![allow(unused)] fn main() { // Activate Layer 1 — link identity to specification create_link(ndo_hash, spec_hash, LinkTypes::NDOToSpecification, ())?; // Activate Layer 2 — link identity to process create_link(ndo_hash, process_hash, LinkTypes::NDOToProcess, ())?; }
Pattern 3: Holonic Composition
Status: 🔄 Post-MVP —
NDOToComponentnot yet in code. Seepost-mvp/fractal-composable-resource-architecture.md.
Intent: Allow NDOs to contain other NDOs, creating fractal hierarchies where every level has the same structural potential.
Structure: NDOToComponent links from a parent NDO's identity hash to child NDO identity hashes. A Project NDO links to Resource NDOs. A Resource NDO links to Design NDOs. A Design NDO links to Component NDOs.
Rationale: Morin's holographic principle and the fractal composable resource architecture (documented in post-mvp/digital-resource-integrity.md). In complex systems, the same structure appears at every scale. The NDO's three-layer potential is the same whether the resource is an atomic component or a composable object.
Holochain idiom:
#![allow(unused)] fn main() { // Link parent NDO to child NDO create_link( parent_ndo_hash, child_ndo_hash, LinkTypes::NDOToComponent, LinkTag::new(component_role.as_str()), // e.g., "required", "optional", "alternative" )?; }
Pattern 4: Progressive Disclosure
Status: 🔄 Partial (UI) — creation form defaults to
Ideation; full layer-aware archetypes await L1/L2 activation.
Intent: Present resources at the appropriate level of complexity for the current context, without exposing structural complexity that is not yet active.
Structure: Three starting archetypes that correspond to common initialization states, presented as UI choices that set the initial lifecycle stage. These are starting configurations, not permanent classifications.
| Archetype | Layers active | Lifecycle stage | Use when |
|---|---|---|---|
| Stub | L0 only | Ideation | Registering an intention |
| Open Design | L0 + L1 | Specification | Sharing a design |
| Active Project | L0 + L1 + L2 | Development | Starting work with collaborators |
Rationale: Kauffman's adjacent possible — present only what is currently achievable. An agent creating their first NDO should not be confronted with the full complexity of the three-layer model. The system should reveal its depth progressively as the resource's context demands it.
Pattern 5: Tombstone
Status: ✅ Partial (MVP) — Layer 0 is never deleted;
EndOfLifeandDeprecatedstages work. Layer 1/2 archival (specis_active, terminal events) awaits L1/L2 implementation.
Intent: Preserve permanent identity records for all resources that have ever existed, including those that have reached end of life, been deprecated, or been abandoned.
Structure: At end of life, only Layer 0 remains active. Layers 1 and 2 are archived (spec is_active: false, process concluded with terminal EconomicEvent). The identity entry is never deleted.
Rationale: The DHT is append-only — this is not a limitation, it is a feature. The permanent memory of what resources existed, who created them, and what happened to them is institutional knowledge. Tombstones enable:
- OVN-compliant contribution tracking even after a project ends
- Versioning lineage that traces forks back to their origins
- Historical record for the network
Holochain idiom:
#![allow(unused)] fn main() { // End-of-life transition — archive layers update_entry(spec_hash, &ResourceSpecification { is_active: false, ..spec })?; // Create terminal EconomicEvent for Layer 2 create_entry(&EntryTypes::EconomicEvent(EconomicEvent { action: VfAction::Consume, lifecycle_transition: Some(LifecycleStage::EndOfLife), .. }))?; // Layer 0 NondominiumIdentity is NOT deleted — it becomes the tombstone }
Pattern 6: Stigmergic Capability Attachment
Status: 🔄 Post-MVP —
CapabilitySlotlink type not inzome_resource. See §6 implementation note for federation partial (NdoHardLink).
Intent: Allow any agent or external hApp to attach capabilities to an NDO without modifying the NDO entry, without requiring permission from the NDO's custodian, and without needing to have been anticipated by the NDO's designer.
Structure: CapabilitySlot links from the Layer 0 identity hash to capability targets. Link tags carry the slot type, author, and attachment timestamp. Governance layer filters trusted vs untrusted links.
Rationale: Morin's ecology of action: no action guarantees its outcome. The capabilities that will be most useful to attach to a resource cannot be known at creation time. The attachment surface must be open. Centralized gatekeeping of capabilities (requiring permission from the NDO custodian before attaching) would impose coordination costs that violate Benkler's information opportunity cost principle.
Holochain idiom:
#![allow(unused)] fn main() { let slot_tag = CapabilitySlotTag { slot_type: SlotType::IssueTracker, attached_at: sys_time()?, }; create_link( ndo_identity_hash, issue_tracker_cell_hash, LinkTypes::CapabilitySlot, LinkTag::new(serde_json::to_vec(&slot_tag)?), )?; }
8. DHT Data Structures
8.1 NondominiumIdentity Entry (Layer 0)
#![allow(unused)] fn main() { #[hdk_entry_helper] #[derive(Clone, PartialEq)] pub struct NondominiumIdentity { pub name: String, pub initiator: AgentPubKey, // TODO (G1, REQ-AGENT-02): replace with AgentContext post-MVP pub property_regime: PropertyRegime, pub resource_nature: ResourceNature, pub lifecycle_stage: LifecycleStage, pub created_at: Timestamp, pub description: Option<String>, // immutable after creation (MVP) pub successor_ndo_hash: Option<ActionHash>, // set once on Deprecated (REQ-NDO-LC-06) pub hibernation_origin: Option<LifecycleStage>, // set on → Hibernating; cleared on resume } }
8.2 Supporting Enums
#![allow(unused)] fn main() { #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] pub enum PropertyRegime { Private, // Full rights bundle; individual ownership Commons, // Non-rivalrous shared resource; governance via licensing/attribution Collective, // Cooperative/collective ownership Pool, // Pool of shareables: rivalrous shared resources; custody/scheduling/maintenance CommonPool, // Rivalrous consumable resource; governance via quota/depletion rules Public, // Public/governmental stewardship; open-access; non-alienable by the public body Nondominium, // Uncapturable by design; contribution-based access; no alienation permitted } // Canonical definition: crates/shared/src/types.rs / documentation/requirements/resources.md §6.3 #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] pub enum ResourceNature { Physical, // Material objects, equipment, spaces Digital, // Software, data, design files, documents Service, // Software services, knowledge-as-service assets Hybrid, // Digital twin of a physical resource, or physical+digital bundle Information, // Knowledge assets, datasets, documented methods } // MVP canonical definition: crates/shared/src/types.rs (5 variants). // Post-MVP forward map may add Space, Method, Currency — see documentation/archives/resources.md §6.2. #[derive(Clone, PartialEq, Debug, Serialize, Deserialize, Default)] pub enum LifecycleStage { // Emergence #[default] Ideation, Specification, Development, Prototype, // Maturity Stable, Distributed, // Operation Active, // Suspension Hibernating, // Terminal Deprecated, EndOfLife, } }
8.3 Capability Slot Link Tag
#![allow(unused)] fn main() { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct CapabilitySlotTag { pub slot_type: SlotType, pub attached_at: Timestamp, pub label: Option<String>, // Human-readable label for this specific slot } #[derive(Clone, Debug, Serialize, Deserialize)] pub enum SlotType { Documentation, IssueTracker, FabricationQueue, GovernanceDAO, VersionGraph, DigitalAsset, WeaveWAL, FlowstaIdentity, // Flowsta agent-linking attestation (IsSamePersonEntry action hash) UnytAgreement(String), // Unyt Alliance network seed identifier (empty string = sandbox default) CustomApp(String), // Extensible: custom slot type identified by string } }
8.4 Link Types — Implemented vs Planned
Implemented in zome_resource integrity (MVP — PR #80):
#![allow(unused)] fn main() { // Layer 0 discovery and lifecycle (actual enum names in code) AllNdos, // Path "ndo_identities" → NondominiumIdentity action hashes AgentToNdo, // initiator AgentPubKey → NondominiumIdentity NdoByLifecycleStage, // Path "ndo.lifecycle.{Stage:?}" → NondominiumIdentity NdoByNature, // Path "ndo.nature.{Nature:?}" → NondominiumIdentity NdoByPropertyRegime, // Path "ndo.regime.{Regime:?}" → NondominiumIdentity NdoToSuccessor, // deprecated NDO → successor NondominiumIdentity (REQ-NDO-LC-06) NdoToTransitionEvent, // NDO → EconomicEvent (link only; cross-zome event validation deferred) // Layer 1 activation and operational state (MVP — PR #132) NdoToSpecification, // NondominiumIdentity → ResourceSpecification (Layer 1 activation) ResourcesByOperationalState, // Path "resources.operational.{State:?}" → EconomicResource }
Legacy resource links (SpecificationToResource, ResourcesByLocation, etc.) remain for pre-NDO ResourceSpecification / EconomicResource flows. ResourcesByState was replaced by ResourcesByOperationalState in #132.
Planned additions (post-MVP — not yet in LinkTypes enum):
#![allow(unused)] fn main() { NDOToProcess, // NondominiumIdentity → Process (Layer 2 activation) NDOToComponent, // NondominiumIdentity → NondominiumIdentity (holonic composition) CapabilitySlot, // NondominiumIdentity → capability target (typed by tag) NDOLifecycleHistory, // NondominiumIdentity → LifecycleEvent (audit trail alternative/complement to NdoToTransitionEvent) ResourcesByLifecycleStage, // NDO-facing complement to ResourcesByOperationalState (REQ-NDO-OS-06) }
Implemented in zome_gouvernance (federation — PR #103): NdoToHardLinks, HardLinkByType (for NdoHardLink entries). See §11.7.
8.5 NondominiumIdentity Updates
Layer 0 entries may be updated only for lifecycle-related fields. Identity, classification, and descriptive fields are immutable after creation. This preserves the identity anchor property: the content of the NDO changes as little as possible, while the DHT link graph around it grows freely.
MVP permitted updates (integrity zome validate_update_nondominium_identity):
| Field | When |
|---|---|
lifecycle_stage | Valid forward transition (or Hibernating resume via hibernation_origin) |
hibernation_origin | Set when entering Hibernating; cleared on resume |
successor_ndo_hash | Set once when transitioning to Deprecated (REQ-NDO-LC-06) |
#![allow(unused)] fn main() { // Coordinator input (zome_resource — actual MVP struct name) pub struct UpdateLifecycleStageInput { pub original_action_hash: ActionHash, pub new_stage: LifecycleStage, pub successor_ndo_hash: Option<ActionHash>, // required when new_stage == Deprecated pub transition_event_hash: Option<ActionHash>, // creates NdoToTransitionEvent link when Some; // EconomicEvent validation deferred cross-zome } }
REQ-NDO-L0-05 target: every lifecycle update shall reference a validated triggering
EconomicEvent. MVP accepts an optional hash and creates the link without cross-zome proof.
8.6 Holonic Composition Diagram
graph TB
ProjectNDO["Project NDO\n(Layer 0: identity)\n(Layer 1: project spec)\n(Layer 2: process)"]
ResourceNDO["Resource NDO\n(Layer 0: identity)\n(Layer 1: design spec)\n(Layer 2: use process)"]
ComponentNDO["Component NDO\n(Layer 0: identity)\n(Layer 1: component spec)\n(Layer 2: none yet)"]
AssetNDO["Asset NDO (digital)\n(Layer 0: identity)\n(Layer 1: manifest)\n(Layer 2: none)"]
ProjectNDO -->|"NDOToComponent\n(required)"| ResourceNDO
ResourceNDO -->|"NDOToComponent\n(required)"| ComponentNDO
ResourceNDO -->|"NDOToComponent\n(optional)"| AssetNDO
ComponentNDO -->|"CapabilitySlot\n(DigitalAsset)"| AssetNDO
8.7 Agent Context Entry (Post-MVP)
TODO (G1 — AgentEntityType): The NDO three-layer model currently focuses on resource representation. For the generic NDO to support commons-based peer production as practised in OVNs (where ventures, networks, and partner organisations are also economic agents), the agent layer needs an equivalent minimal identity structure. The following is a forward-design proposal, not yet implemented. See
documentation/archives/agent.md§6.1 andREQ-AGENT-01.
#![allow(unused)] fn main() { // Post-MVP: AgentContext entry type (companion to Person, or standalone for non-human agents) #[hdk_entry_helper] pub struct AgentContext { pub agent_type: AgentEntityType, pub person_hash: Option<ActionHash>, // None for bots and external organisations pub created_at: Timestamp, pub network_seed: String, // Which NDO network this context belongs to } pub enum AgentEntityType { Individual, // Human participant with a Person entry Collective(String), // Working group / committee (name/description) Project(ActionHash), // Project NDO this agent entity represents Network(ActionHash), // Network NDO this agent entity represents Bot { // AI agent or IoT device capabilities: Vec<String>, operator: AgentPubKey, // Responsible human operator }, ExternalOrganisation(String), // Traditional org (for partner modelling) } }
Design principles:
Individualagents haveAgentEntityType::Individualwith a linkedPersonentryCollective,Project, andNetworkagents are composed agents (group agents).Project(ActionHash)andNetwork(ActionHash)carry anActionHashpointing to theNondominiumIdentitythat is the collective's resource face — its digital twin as a Nondominium Object. TheAgentContextitself is the agent face through which the collective participates in economic events. These are ontologically distinct: theNondominiumIdentityis a Resource; theAgentContextis an Agent. Neither replaces the other. ACollective(String)agent may not yet have an associated NDO; its agent face exists independently of any resource face.Botagents have noPersonbut have declared capabilities and a responsible human operator; their actions are attributed to the operator for PPR purposesExternalOrganisationagents model traditional partners/suppliers without requiring them to run a Holochain node
Derived affiliation state (computed from existing DHT data, not stored):
affiliation_state(agent) = f(
person_exists(agent), // Boolean
affiliation_record_exists(agent), // Has agent signed ToP?
contributions_count(agent), // From economic events
last_contribution_timestamp(agent), // Recency
reputation_summary.total_claims, // From PPRs
governance_claims_count(agent) // From PPRs
)
→ UnaffiliatedStranger | CloseAffiliate | ActiveAffiliate | CoreAffiliate | InactiveAffiliate
9. Requirements
9.0 Implementation Status Matrix
Normative requirements below remain valid as design targets. Status reflects the codebase as of 2026-06 (see documentation/IMPLEMENTATION_STATUS.md).
| Track | Status | Notes |
|---|---|---|
Layer 0 (NondominiumIdentity, discovery, lifecycle validation) | ✅ MVP (#80) | Initiator-only transitions; optional NdoToTransitionEvent |
Layer 1 activation (NdoToSpecification) | ✅ MVP (#132) | Created on every create_resource_specification; spec carries ndo_identity_hash + ndo_state_hash and a lifecycle gate |
Layer 2 activation (NDOToProcess) | ❌ Post-MVP | Governance events exist unlinked to NDO identity |
OperationalState split | ✅ Data layer | operational_state on EconomicResource; ResourcesByOperationalState; governance-operator transitions deferred |
| Governance-as-operator lifecycle (REQ-NDO-LC-02/03/07) | 🔄 Partial | Integrity validation only; no role-gated governance zome path |
CapabilitySlot surface (zome_resource) | ❌ Post-MVP | Unyt / Flowsta slot types specified, not coded |
Federation (NdoHardLink, Contribution, Agreement) | ✅ MVP (#103) | zome_gouvernance; distinct from CapabilitySlot |
| Lobby / Group DNA UI shell | ✅ MVP | Group-scoped NDO creation; localStorage + Group DNA per IMPLEMENTATION_STATUS |
| Agent ontology (§9.7) | ❌ Post-MVP | Individual agents only |
Legend: ✅ implemented · 🔄 partial · ❌ not started
9.1 Layer 0 — Identity Requirements
- REQ-NDO-L0-01 ✅: The system shall support the creation of a
NondominiumIdentityentry as the minimal representation of any Nondominium Object, requiring onlyname,initiator,property_regime,resource_nature,lifecycle_stage,created_at, and an optionaldescription. - REQ-NDO-L0-02 ✅: The action hash of the
NondominiumIdentitygenesis entry shall be the stable, permanent identity of the NDO for its entire existence and shall never be voided or replaced. - REQ-NDO-L0-03 ✅: A
NondominiumIdentityentry shall never be deletable by any agent or governance action. Its permanent presence in the DHT is a design guarantee, not a policy choice. - REQ-NDO-L0-04 ✅ (MVP scope): After creation, only lifecycle-related fields may be updated:
lifecycle_stage,hibernation_origin, andsuccessor_ndo_hash(the latter set once onDeprecated). All other fields (name,initiator,property_regime,resource_nature,description,created_at) are immutable. - REQ-NDO-L0-05 🔄: Every update to
lifecycle_stageshall reference a validEconomicEventaction hash as the triggering transition event. MVP: optionaltransition_event_hashcreatesNdoToTransitionEventlink without cross-zome event validation. - REQ-NDO-L0-06 ✅: At end of life (
LifecycleStage::EndOfLife), theNondominiumIdentityentry shall remain fully readable and discoverable, serving as a tombstone. - REQ-NDO-L0-07 ✅: The system shall support discovery of NDOs by
lifecycle_stage,resource_nature, andproperty_regimevia DHT path-based anchors.
9.2 Layer 1 — Specification Requirements
Status: 🔄 Partial (MVP, #132) — activation, the Layer 0 pointer pair, and the lifecycle gate are in code; asset attachment (REQ-NDO-L1-06) and role-gated activation remain post-MVP. Project-type know-how bundles:
post-mvp/project-type-ndo-specifications.md.
- REQ-NDO-L1-01 ✅: Layer 1 shall be activated by creating an
NdoToSpecificationlink from the NDO identity hash to aResourceSpecificationentry. No modification of theNondominiumIdentityentry is required for activation. The specification additionally carriesndo_identity_hash(the immutable Layer 0 pointer) andndo_state_hash(the NDO action the author observed), because integrity validation cannot resolve "the latest state" by walking an update chain forward. - REQ-NDO-L1-02 ✅: Layer 1 may be activated at any lifecycle stage from
SpecificationthroughActive, matching the activation table in Section 5.2.Ideationis excluded (an idea has no form to specify yet), andHibernating,Deprecated, andEndOfLifeare excluded as suspended or terminal. Retroactive activation is fully supported for any NDO that has reachedSpecification. - REQ-NDO-L1-03: Multiple
ResourceSpecificationentries may be linked to one NDO identity, representing version evolution. The most recent link shall be considered the canonical Layer 1 specification. - REQ-NDO-L1-04: When Layer 1 enters dormant state (hibernation or end of life), the specification shall be marked
is_active: false. TheNDOToSpecificationlink shall remain readable. - REQ-NDO-L1-05:
GovernanceRuleentries shall continue to be linked toResourceSpecificationentries as currently implemented. They are considered Layer 1 assets. - REQ-NDO-L1-06: Digital asset references (files, 3D models, code, integrity manifests) shall be attached to the NDO via
CapabilitySlotlinks of typeDigitalAsset, not embedded in theResourceSpecificationentry.
9.3 Layer 2 — Process Requirements
Status: ❌ Post-MVP for
NDOToProcess. Partial:NdoHardLink,Contribution,Agreementinzome_gouvernance(#103).
- REQ-NDO-L2-01 ❌: Layer 2 shall be activated by creating an
NDOToProcesslink from the NDO identity hash to a ValueFlowsProcessentry. - REQ-NDO-L2-02: Layer 2 may be activated at any lifecycle stage at or after
Specification. - REQ-NDO-L2-03: All
EconomicEvent,Commitment,Claim, andPrivateParticipationClaimentries associated with an NDO shall be linked through the active Layer 2 process. - REQ-NDO-L2-04: When a process concludes (all commitments fulfilled or cancelled), a terminal
EconomicEventwithVfAction::Consumeshall be recorded, formally concluding Layer 2. - REQ-NDO-L2-05: A new Layer 2 process may be activated for the same NDO after a previous process has concluded (e.g., a second development cycle after hibernation).
- REQ-NDO-L2-06:
EconomicResourceentries (physical instances of the resource) shall be linked to the NDO via the Layer 2 process, not directly to the Layer 0 identity.
9.4 Lifecycle and Operational State Requirements
LifecycleStage Requirements
- REQ-NDO-LC-01 ✅: The system shall implement the
LifecycleStageenum as defined in Section 5.1 on theNondominiumIdentityentry. The legacyResourceStateenum onEconomicResourcehas been replaced byOperationalState(REQ-NDO-OS-01). - REQ-NDO-LC-02 🔄: Lifecycle stage transitions shall be validated by the governance zome acting as state transition operator, consistent with
REQ-ARCH-07(governance-as-operator). MVP: integrity zome validation + initiator-only coordinator. - REQ-NDO-LC-03 🔄: Each lifecycle transition shall generate a corresponding
EconomicEventwith the triggeringVfAction, creating an auditable lifecycle history. MVP: optionaltransition_event_hashlink; automatic event generation deferred. - REQ-NDO-LC-04 ✅: The
Hibernatingstage shall be clearly distinguished fromDeprecatedandEndOfLife. A hibernating resource may be reactivated; deprecated and end-of-life resources may not be reactivated. - REQ-NDO-LC-05 ❌: Transition to
EndOfLifeshall respect the challenge period defined inREQ-GOV-13. - REQ-NDO-LC-06 ✅: The
Deprecatedstage shall require a link to a successor NDO identity hash. Deprecation without a declared successor is not permitted. - REQ-NDO-LC-07 ❌: The governance zome shall enforce the authorized role for each lifecycle transition as defined in Section 5.3.
OperationalState Requirements
Status: ✅ REQ-NDO-OS-01 and REQ-NDO-OS-06 implemented (data layer). REQ-NDO-OS-02 through REQ-NDO-OS-05 (governance-operator enforcement) remain deferred.
- REQ-NDO-OS-01 ✅: The system shall implement the
OperationalStateenum as defined in Section 5.4 on theEconomicResourceentry, replacing the process-related dimension of the legacyResourceStateenum. - REQ-NDO-OS-02:
OperationalStatetransitions shall be managed exclusively by the governance zome. The resource zome stores the field; only the governance zome may initiate valid transitions. - REQ-NDO-OS-03: Each
OperationalStatetransition shall correspond to an open or completedEconomicEvent. The governance zome shall reject state transitions for which no corresponding event exists. - REQ-NDO-OS-04:
OperationalStateandLifecycleStageare orthogonal. AnOperationalStatetransition shall never cause aLifecycleStagetransition, and vice versa. - REQ-NDO-OS-05: The
InTransit,InStorage, andInMaintenancestates may occur at anyLifecycleStageat or afterDevelopment. The system shall not restrict these states to any specific lifecycle stage. - REQ-NDO-OS-06 ✅: The legacy
ResourcesByStatelink type is replaced byResourcesByOperationalStatefor EconomicResource faceted queries. Lifecycle faceting remains onNdoByLifecycleStage(Layer 0).
Note (code): Governance zome state transition logic for operational states (REQ-NDO-OS-02/03) remains a follow-up. See Section 10.3 for the legacy migration map.
9.5 Capability Surface Requirements
Status: ❌ Post-MVP for
CapabilitySlotinzome_resource. Unyt / Flowsta phased integration paths in §6.6–6.7.
- REQ-NDO-CS-01 ❌: The system shall support
CapabilitySlotlinks from any NDO identity hash to any DHT hash or external reference, using theCapabilitySlotTagstructure defined in Section 8.3. - REQ-NDO-CS-02: Any Accountable Agent shall be able to create a
CapabilitySlotlink to any NDO, without requiring permission from the NDO's custodian. Permissionless attachment at the DHT level is a design guarantee. - REQ-NDO-CS-03: The governance zome shall support validation of
CapabilitySlotlinks, allowing custodians and Accountable Agents to mark specific slots as trusted or untrusted. - REQ-NDO-CS-04: The system shall support all
SlotTypevariants defined in Section 8.3, includingCustomApp(String)for extensibility. - REQ-NDO-CS-05: The
WeaveWALslot type shall be supported as the integration point for MOSS/Weave tools, enabling NDOs to appear as Weave Assets. - REQ-NDO-CS-06: The capability surface shall remain open across all lifecycle stages, including
HibernatingandEndOfLife. Historical attachments on archived NDOs shall remain readable. - REQ-NDO-CS-07: The system shall support a
UnytAgreement(String)slot type in theSlotTypeenum, where the String carries the Unyt Alliance network seed. The target of aUnytAgreementcapability slot link shall be a Unyt Smart Agreement entry hash (cross-cell reference). - REQ-NDO-CS-08: Any Accountable Agent shall be able to create a
UnytAgreementcapability slot on any NDO (Tier 1: permissionless proposal). The governance zome shall not require validation of Tier 1UnytAgreementslots beyond the standard capability surface governance defined in REQ-NDO-CS-03. - REQ-NDO-CS-09: The
GovernanceRuleTypeenum inzome_resourceintegrity shall support anEconomicAgreementvariant. AGovernanceRuleentry of this type shall carryEconomicAgreementRuleDataas itsrule_data, including:unyt_alliance_id,smart_agreement_hash,trigger_actions(list ofVfActionvalues),settlement_window_secs, and an optionalnote. - REQ-NDO-CS-10: When the governance zome processes a state transition whose
VfActionmatches atrigger_actionsentry in an endorsedEconomicAgreementgovernance rule, the transition request shall be required to include arave_hash. The governance zome shall validate the RAVE against the Unyt DHT (via cross-DNA call) before approving the transition. - REQ-NDO-CS-11: When a state transition is approved in the presence of a valid
EconomicAgreementrule, thePrivateParticipationClaimgenerated for all participating agents shall include thesettlement_rave_hashfield referencing the validated Unyt RAVE. This field shall beNonefor all transitions where no economic agreement was triggered. - REQ-NDO-CS-12: The system shall support a
FlowstaIdentityslot type in theSlotTypeenum. The target of aFlowstaIdentitycapability slot link shall be anIsSamePersonEntryaction hash committed by theflowsta-agent-linkingcoordinator zome. - REQ-NDO-CS-13: Any agent shall be able to create a
FlowstaIdentitycapability slot on their ownPersonentry hash (Tier 1: permissionless attestation). The governance zome shall not require validation of Tier 1FlowstaIdentityslots beyond the standard capability surface governance defined in REQ-NDO-CS-03. - REQ-NDO-CS-14: The governance zome shall support an
IdentityVerificationgovernance rule type (or equivalent mechanism) that conditions role promotions or high-value state transitions on the presence of a verifiedFlowstaIdentitycapability slot on the requesting agent'sPersonentry hash (Tier 2: governance requirement). - REQ-NDO-CS-15: When verifying a
FlowstaIdentityslot for Tier 2 governance enforcement, the governance zome shall validate that: (a) aFlowstaIdentityCapabilitySlot link exists from the agent'sPersonhash; (b) the targetIsSamePersonEntrycontains the agent'sAgentPubKeyas one of the two signing parties; (c) the attestation has not been revoked via therevoke_linkfunction of theflowsta-agent-linkingcoordinator.
9.6 Migration Requirements
- REQ-NDO-MIG-01: All new resources created after the introduction of the NDO model shall begin with a
NondominiumIdentitycreation as their first action. - REQ-NDO-MIG-02: Existing
ResourceSpecificationentries created before the NDO model shall be retroactively anchored to a newNondominiumIdentityentry. This operation shall be additive (no existing entries are modified or deleted). - REQ-NDO-MIG-03 ✅: The legacy
ResourceStateenum is replaced byOperationalStateonEconomicResourceandLifecycleStageonNondominiumIdentity. Retroactive anchoring of legacy records (Phase 2) still uses the migration table in Section 10.3. - REQ-NDO-MIG-04: Existing
EconomicResourceentries shall not require migration. They shall be linked to the new NDO model via Layer 2 process links when the NDO is retroactively created. - REQ-NDO-MIG-05: The migration shall be implemented as a one-time migration coordinator function, not as a permanent API change, to avoid polluting the steady-state code with migration logic.
9.7 Agent Architecture Requirements (Post-MVP)
Status: Post-MVP. Gaps identified against the OVN wiki ontology (15 years of commons-based peer production practice). See
documentation/archives/agent.mdfor the full analysis. The current MVP implements individual agents only. Requirements below are design targets for the generic NDO.
- REQ-NDO-AGENT-01: Agent Type Taxonomy: The system shall support an
AgentEntityTypediscriminant on every agent context, distinguishing at minimum:Individual,Collective,Project,Network,Bot, andExternalOrganisation(see Section 8.7 for the proposed data structure). The MVP's implicit individual-only model is insufficient for commons-based peer production where ventures and networks are first-class economic actors. - REQ-NDO-AGENT-02: Collective Agents — Dual-Face Model: Groups, working groups, projects, and network-level entities are composed agents. Each has an agent face (
AgentContextwith the relevantAgentEntityTypevariant) through which it participates in economic events, and may optionally have a resource face (NondominiumIdentity) as its digital twin. TheActionHashinProject(ActionHash)andNetwork(ActionHash)links the agent face to the resource face. These two faces are ontologically distinct — theNondominiumIdentityis a Resource; theAgentContextis an Agent — and neither replaces the other. Collective agents may act through multi-signature patterns (N-of-M member authorisation) when performing economic events. - REQ-NDO-AGENT-03: Affiliation Spectrum: The system shall derive the OVN affiliation state (UnaffiliatedStranger, CloseAffiliate, ActiveAffiliate, CoreAffiliate, InactiveAffiliate) algorithmically from existing DHT data — PPR contribution history, recency, and
AffiliationRecordexistence. Affiliation state shall not be stored as a separate entry (which would require maintenance and risk inconsistency). The derivation function is defined in Section 8.7. - REQ-NDO-AGENT-04: AffiliationRecord: The system shall support an
AffiliationRecordentry for formal network onboarding: the agent cryptographically signs acknowledgement of the network's Terms of Participation, Nondominium & Custodian agreement, and Benefit Redistribution Algorithm. TheAffiliationRecordis the machine-readable prerequisite forActiveAffiliatestatus. - REQ-NDO-AGENT-05: Composable AgentProfile View: The system shall expose a composable
AgentProfilequery assembling identity, capability, reputation, participation, social, and temporal data into a single queryable output. This view shall be computed from existing DHT data — it is not a new stored entry type. Agents control which sections are exposed by granting access to constituent entries. - REQ-NDO-AGENT-06: Social Graph: The system shall model peer relationships via an
AgentRelationshipbidirectional link type (typed: colleague, collaborator, trusted, voucher), stored as private links. Social relations are part of agent wealth in the OVN model and must be accessible to governance without being publicly discoverable. - REQ-NDO-AGENT-07: CapabilitySlot on Agent Identity: The
Personentry hash shall serve as a stigmergic attachment surface for external credential wallets, DID documents, and reputation oracles, using the sameCapabilitySlotlink pattern defined in Section 6 for NDO resources. See Section 6.5 for the forward design. Flowsta'sFlowstaIdentitycapability slot (Section 6.7) provides the first concrete implementation: a DID-backed, dual-signed attestation attachable to thePersonhash without schema modification. - REQ-NDO-AGENT-08: Portable Credentials: The system shall support a
PortableCredentialstructure — bilaterally signed by an issuer (PrimaryAccountableAgent) and the credential owner — verifiable by other Holochain networks. Types:RoleCredential,ReputationCredential,CompetencyCredential,AffiliationCredential. This is the technical mechanism for cross-network identity portability required by the OVN model. Flowsta's W3C DID (did:flowsta:uhCAk...) provides the cross-network identity anchor required for credential portability. When combined with theFlowstaIdentitycapability slot, portable credentials become attributable to a verified cross-app identity.
10. Migration from Current Architecture
10.1 Current Architecture Overview
The Nondominium zome architecture runs two parallel resource tracks:
Track A — NDO Layer 0 (MVP, #80): new NDOs created via create_ndo with NondominiumIdentity, facet discovery, and lifecycle transitions.
Track B — Legacy resource model (still present): pre-NDO and parallel flows using:
ResourceSpecification (zome_resource)
↓ SpecificationToResource
EconomicResource (zome_resource)
- custodian: AgentPubKey
- operational_state: OperationalState { PendingValidation, Available, Reserved, InTransit, InStorage, InMaintenance, InUse }
↑ LifecycleStage lives on NondominiumIdentity (Track A); governance-zome transition rules (REQ-NDO-OS-02/03) deferred
GovernanceRule (zome_resource)
(linked from ResourceSpecification via SpecificationToGovernanceRule)
EconomicEvent (zome_gouvernance)
- provider: AgentPubKey
- receiver: AgentPubKey
- resource_inventoried_as: ActionHash → EconomicResource
NdoHardLink / Contribution / Agreement (zome_gouvernance — federation #103)
New Group-scoped NDO creation uses Track A. Track B remains for existing specs/instances until Layer 1/2 linking and migration (§10.4) complete.
10.2 Migration Mapping
graph LR
subgraph current ["Current Architecture"]
RS[ResourceSpecification]
ER[EconomicResource]
GR[GovernanceRule]
RS -->|SpecificationToResource| ER
RS -->|SpecificationToGovernanceRule| GR
end
subgraph ndoModel ["NDO Three-Layer Model"]
L0[NondominiumIdentity\nLayer 0]
L1[ResourceSpecification\nLayer 1]
L2[Process\nLayer 2]
L2E[EconomicResource\nInstance]
GR2[GovernanceRule\nLayer 1 asset]
L0 -->|NDOToSpecification| L1
L0 -->|NDOToProcess| L2
L2 -->|ProcessToResource| L2E
L1 -->|SpecToGovernanceRule| GR2
end
RS -->|"maps to"| L1
ER -->|"maps to"| L2E
GR -->|"maps to"| GR2
Detailed mapping table:
| Current construct | NDO model | Change type | Notes |
|---|---|---|---|
ResourceSpecification | Layer 1 (ResourceSpecification) | No structural change | Gains NDOToSpecification link from Layer 0 |
EconomicResource | Layer 2 artifact (resource instance) | No structural change | Linked via Process, not directly to NDO |
Legacy ResourceState enum | LifecycleStage + OperationalState enums | ✅ Split complete (data layer) | See migration map below — governance-operator enforcement deferred (REQ-NDO-OS-02/03) |
GovernanceRule | Layer 1 asset | No structural change | Still linked from ResourceSpecification |
EconomicEvent | Layer 2 component | No structural change | Now linked through Process entry |
Commitment / Claim | Layer 2 components | No structural change | Now linked through Process entry |
| (none) | NondominiumIdentity | New | Root Layer 0 entry for all resources |
| (none) | NDOToSpecification link | New | Layer 1 activation link |
| (none) | NDOToProcess link | New | Layer 2 activation link |
| (none) | NDOToComponent link | New | Holonic composition |
| (none) | CapabilitySlot link | New | Stigmergic capability attachment |
| (none) | LifecycleStage transitions | New | Governed by zome_gouvernance (maturity dimension) |
| (none) | OperationalState transitions | New | Governed by zome_gouvernance (process dimension) |
10.3 Legacy ResourceState Migration Map
Historical ResourceState values (pre-split) map to the two orthogonal dimensions. Each legacy variant maps to a (LifecycleStage, OperationalState) pair:
Current ResourceState | → LifecycleStage | → OperationalState | Migration notes |
|---|---|---|---|
PendingValidation | Prototype | PendingValidation | Resource not yet peer-validated; both dimensions set simultaneously |
Active | Active | Available | The common case; lifecycle is Active, no process currently running |
Maintenance | (unchanged — keep existing stage) | InMaintenance | Maintenance is a process, not a lifecycle milestone; LifecycleStage is preserved |
Retired | Deprecated or EndOfLife | Available | Determine lifecycle by whether a successor NDO exists; operational state is Available (no active process) |
Reserved | (unchanged — keep existing stage) | Reserved | Pre-allocation is an operational condition; LifecycleStage is preserved |
The pre-operational stages (Ideation, Specification, Development) have no equivalent in the current model and will apply only to newly created NDOs.
10.4 Migration Strategy
The migration is strictly additive — no existing entries are modified or deleted. The append-only nature of the DHT is respected throughout.
Phase 1 — Forward compatibility (partially complete):
- ✅ New NDOs created via
create_ndobegin withNondominiumIdentity(Group-scoped UI) - ❌
NDOToSpecificationandNDOToProcesslink types not yet added - ✅
LifecycleStageonNondominiumIdentity; ✅OperationalStateonEconomicResource(REQ-NDO-OS-01) - ✅
ResourcesByOperationalStatereplaces legacyResourcesByState(REQ-NDO-OS-06)
Phase 2 — Retroactive anchoring (migration coordinator):
- For each existing
ResourceSpecificationentry, create aNondominiumIdentityentry and the correspondingNDOToSpecificationlink - The
NondominiumIdentityis created by the original author of theResourceSpecification(or by a designated migration agent) - Map legacy pre-split state values to
(LifecycleStage, OperationalState)pairs using the migration table in Section 10.3 - Link existing
EconomicResourceinstances to the new NDO via a retroactive Process entry
Phase 3 — Cleanup (optional, post-migration):
- ✅
ResourceStateremoved from code;OperationalStateonEconomicResource(no production DHT back-compat shim) - Update the UI to show
LifecycleStageandOperationalStatevocabulary separately (partial — NDO lifecycle UI done; economic-resource operational badges in ResourcesTab) - Activate capability slots for resources that have associated external assets
What is not required:
- No deletion of any existing entries
- No update to any existing
ResourceSpecificationorEconomicResourceentries - No data migration (existing data remains valid in both old and new reading code)
11. Relationship to Other Post-MVP Work
11.1 Many-to-Many Flows
post-mvp/many-to-many-flows.md defines shared custody and multi-party resource transfers. In the NDO model:
- Shared custody (co-custodians) is expressed at Layer 0: the
NondominiumIdentitycarries a reference to shared custodianship state, or the governance zome maintains co-custodian records linked from the identity hash - Multi-party transfer events (
REQ-MMF-06throughREQ-MMF-14) are Layer 2EconomicEventrecords with multiple providers/receivers - The Layer 0 identity hash provides the stable anchor for all custodian-to-resource links across custody transfers
11.2 Versioning
post-mvp/ndo-versioning.md defines a DAG of versions for resources. In the NDO model:
- The
R-VERS-01requirement for "base identity vs version nodes" maps directly to the NDO: Layer 0 is the base identity;ResourceSpecificationversions linked viaNDOToSpecificationare the version nodes - The version DAG is expressed as a
VersionGraphcapability slot linking the NDO identity to a versioning system - Fork relationships (
ForkedFrom,EvolvedFrom) are expressed betweenResourceSpecificationentries linked to (potentially different) NDO identities - The
Deprecatedlifecycle stage with a mandatory successor link implements theR-VERS-01base identity continuity requirement
11.3 Digital Resource Integrity
post-mvp/digital-resource-integrity.md defines cryptographic integrity manifests for digital resources. In the NDO model:
- Digital asset manifests are attached to the NDO via
CapabilitySlotlinks of typeDigitalAsset - The fractal composable resource architecture (atomic → component → composite) maps directly to the Holonic Composition Pattern: each component is itself an NDO, with
NDOToComponentlinks expressing the assembly hierarchy - The
VersionGraphcapability slot integrates with manifest-backed versions (R-VERS-DIG-01)
11.4 MOSS / Weave Integration
The Weave Interaction Pattern defines how hApps create, search, link, and organize social space units into complex social fabric. The NDO is the fundamental social space unit in Nondominium:
- Layer 0 identity hash → declared as a Weave Asset via
WeaveWALcapability slot - MOSS tools (governance DAOs, fabrication queues, issue trackers) attach via the stigmergic capability surface without requiring NDO entry modifications
- Lifecycle stage transitions can be signaled to MOSS via Holochain signals, allowing MOSS tools to respond dynamically to NDO state changes
11.5 Unyt Integration
post-mvp/unyt-integration.md defines Unyt as the transactional layer for Nondominium — peer-to-peer accounting infrastructure built on Holochain, providing currencies, Smart Agreements, and agent-centric value flows. In the NDO model, Unyt integrates at three points:
- Capability surface:
UnytAgreementslot type (Section 6.6) is the permissionless attachment point — any agent can propose economic terms for any NDO - Layer 1:
GovernanceRuleentries of typeEconomicAgreementcarry endorsed Unyt Smart Agreement references as Layer 1 assets, sitting alongside other governance rules in the resource's specification - Layer 2: RAVE hashes (Recorded Agreement Verifiably Executed) link into
PrivateParticipationClaimentries viasettlement_rave_hash, binding economic settlement records to participation records in the Layer 2 process
The NDO three-layer model and Unyt are architecturally complementary: the NDO tracks what happens (resource events, custody, quality, lifecycle); Unyt tracks who owes what to whom (credits, debits, settlement). The governance zome is the bridge that conditions resource state transitions on proof of economic settlement, making the resource itself the enforcement mechanism for its own economic terms.
The PPR system and Unyt credit limits form a feedback loop: agents' ReputationSummary (derived from their accumulated PPRs) feeds into the Unyt Compute Credit Limit Agreement, making participation history the collateral for economic access in the commons network. This is the primary mechanism by which the Nondominium commons becomes self-sustaining without platform intermediaries or administrative overhead.
11.6 Flowsta Integration
post-mvp/flowsta-integration.md defines Flowsta as the identity and authentication layer for the NDO — decentralized authentication built on Holochain, providing cross-app identity linking, W3C DIDs, and zero-knowledge privacy. In the NDO model, Flowsta integrates at three points:
- Capability surface:
FlowstaIdentityslot type (Section 6.7) is the permissionless Tier 1 attachment point — any agent can link theirPersonentry to a Vault dual-signedIsSamePersonEntry, making their cross-app DID discoverable (no governance enforcement at this tier) - Agent identity (G15): The
FlowstaIdentityslot is the first concrete implementation of thePersonCapabilitySlotpattern defined in Section 6.5 — a DID-backed attestation attached to the agent's identity anchor without modifying thePersonentry schema - Governance enforcement (Tier 2, Phase 3):
IdentityVerificationgovernance rules can condition role promotions and high-value transitions on aFlowstaIdentityslot that passes REQ-NDO-CS-15 validation (validIsSamePersonEntry, requestor key included, not revoked), bridging permissionless participation and accountable governance
The NDO three-layer model and Flowsta are architecturally complementary: the NDO tracks who does what (participation, custody, quality, reputation via PPRs); Flowsta tracks who is who (cross-app identity, DID, recovery). The capability slot mechanism is the bridge that connects an agent's local DHT identity to their portable, cross-app identity without requiring any core entry schema changes.
Flowsta Vault's BIP39 recovery and auto-backup mechanisms address a gap in the current NDO architecture: agent key recovery. The non-deletable, append-only nature of Person entries and PPRs assumes the agent retains access to their signing key. Vault's deterministic key regeneration from a 24-word mnemonic ensures that the permanent records the NDO creates remain accessible to their authors across device loss and hardware failure.
11.7 Lobby DNA Integration
Status: 🔄 Partial.
NdoHardLink,Contribution, andAgreemententry types and anchors are implemented inzome_gouvernance(#103). Full Lobby DNA + Group DNA federation UI and descriptor sync remain in progress — seelobby-dna.mdandIMPLEMENTATION_STATUS.md.
lobby-dna.md defines the multi-network federation layer that sits above the NDO DHT: a public Lobby DHT (permissionless agent and NDO descriptor registry), per-group Group DHTs (invite-only coordination spaces), and three extensions to the existing NDO DNA (zome_gouvernance).
The Lobby layer connects to the NDO three-layer model at specific points:
- Layer 0 (
NondominiumIdentity) as the NDO's public identity anchor: TheNdoDescriptorentry in the Lobby DHT mirrors the Layer 0 identity fields (name,lifecycle_stage,property_regime,resource_nature) and references the Layer 0 hash (ndo_identity_hash). The Lobby provides the discovery surface; Layer 0 is the authoritative source of truth. - Layer 2 (
EconomicEvent/Commitment/Claim) as the hard-link gate:NdoHardLinkentries are created only on validatedEconomicEventfulfillment — the same Layer 2 cycle that governs all NDO state changes. The Lobby's soft links (planning intent) become NDO-level hard links only through the existing governance-as-operator path. Agreementas Layer 2 benefit-distribution governance: TheAgreemententry type added tozome_gouvernanceextends the NDO's Layer 2 process layer with benefit-distribution rules, activated post-MVP by Unyt RAVEs (see §11.5).Contributionas a peer-validated Layer 2 work record: ValidatedContributionentries record work done on the NDO at the Layer 2 observation level, with optional cross-DHT references to informal Group-levelWorkLogentries for audit purposes.
Deployment modes: The Lobby DNA is designed for dual deployment — standalone hApp (Lobby DNA + Group DNA + NDO DNA, all managed by one conductor) and Moss/Weave Tool applet (Moss handles agent invites and identity at the surface; Nondominium owns the NDO layer). The NDO DNA is identical in both modes.
See lobby-dna.md for normative requirements (REQ-LOBBY-, REQ-GROUP-, REQ-NDO-EXT-*) and specifications/post-mvp/lobby-architecture.md for full schema, coordinator APIs, pipelines, UI, Moss contract, and 7 ADRs.
11.8 Source-NDO Integration
Status: 🔄 Post-MVP — designed. No Rust implementation yet. Normative requirements in
source-ndo-requirements.md. Academic justification insource-ndo-paper.md.
Source-NDO introduces Source as a third ontological primitive — neither Agent nor Resource — to represent generative ecological systems (watersheds, rivers, forests, fisheries) and knowledge commons that yield resources, receive ecological effects, and condition future possibilities without being ownable or intentional.
How Source-NDO fits the three-layer model:
- Layer 0 (
NondominiumIdentity): Source-NDOs usePropertyRegime::NondominiumorCommonPoolandResourceNature::PhysicalorInformation. The Layer 0 hash is the stable anchor for the source's event ledger. A linkedSourceProfileextension entry carries condition indicators:current_stock,flux_rate,assimilation_capacity,regime_state,resilience,tipping_threshold,stewarded_by(replacesprimaryAccountable). - Layer 1 (
SourceSpecification): Boundary conditions, monitoring framework, ecological value vector, stakeholder map. Activated when governance framework formalisation begins. - Layer 2: All boundary events (extraction, loading, non-consumptive use, regeneration) recorded as
EconomicEvententries against the Source Layer 0 hash. The governance-as-operator loop is cybernetic: events accumulate → stewards interpret conditions →GovernanceRuleentries are revised → access affordances change → future events are conditioned.
ValueFlows extension required: vf:Source as a typed flow endpoint role, distinct from vf:Agent and vf:EconomicResource, allowing provider and receiver fields in EconomicEvent to reference Source-NDOs directly. This is the single extension needed; all other ValueFlows semantics apply unchanged. See valueflows-1.0-compliance.md for the compliance note.
Key architectural invariants:
- Source-NDOs use the same governance-as-operator pattern. The difference is that governance rules must be adaptable (Source condition changes trigger rule revision) rather than fixed at creation. This extends the governance zome with an adaptive governance loop.
PropertyRegime::NondominiumandCommonPoolare the only valid regimes; governance SHALL reject GovernanceRule entries that attempt to assert ownership of a Source-NDO.- No
primaryAccountable— thestewardedBy: Vec<AgentPubKey>relation carries obligations (monitoring, ledger maintenance, governance rule revision), not property rights. - Source-to-Source links (
yields,conditions,providedBy) are native DHT link types, enabling representation of source hierarchies (watershed → river) and ecological coupling (forest conditions river flow).
COP alignment: Source-NDO is a direct application of the black-box principle (Ashby 1956; Snowden & Boone 2007): complex ecological systems cannot be fully modelled; governance must be enacted on observable periphery (boundary events), not on claimed interior knowledge. The complex_interior: true flag on SourceProfile makes this epistemological stance machine-readable.
This document is the normative NDO architecture reference. Layer 0 is implemented in MVP (NondominiumIdentity, lifecycle validation, discovery — PR #80). Layers 1 and 2, the capability slot surface, operational-state split, and full governance-as-operator lifecycle remain post-MVP targets documented here for incremental delivery. The legacy ResourceSpecification + EconomicResource + GovernanceRule model coexists until migration (Section 10) links retroactive anchors and activates layer links. Federation extensions (NdoHardLink, Contribution, Agreement — PR #103) are partial Layer 2 semantics in zome_gouvernance. See documentation/IMPLEMENTATION_STATUS.md for the live checklist.
Lobby DNA: Multi-Network Federation Requirements
Status: Partially implemented — Lobby DNA and NDO federation extensions landed in PR #103;
Group DNA in progress (#101); MVP UI uses a localStorage group shell until Group DNA ships
Created: 2026-04-14
Last updated: 2026-05-23
Authors: Nondominium project
Relates to: ndo_prima_materia.md, flowsta-integration.md, unyt-integration.md,
many-to-many-flows.md, ../requirements.md §2.3, ../ui_design.md (MVP Lobby → Group → NDO UI),
../../IMPLEMENTATION_STATUS.md, ../../implementation_plan.md §12.6
Table of Contents
- Purpose and scope
- Background: the multi-network problem
- Architecture overview
- Lobby DNA requirements
- Group DNA requirements
- NDO DNA extension requirements
- Cross-cutting requirements
- Governance layers
- Integration requirements
- Current state vs planned enforcement
1. Purpose and scope
This document specifies requirements for the Lobby DNA layer: the multi-network federation infrastructure that allows Nondominium agents to discover, join, coordinate around, and compose multiple independent NDO networks (each its own DHT) through a unified entry point.
It defines three new DNA-level components and one extension to the existing NDO DNA:
- Lobby DNA (
zome_lobby): public registry for agents and NDO descriptors. - Group DNA (
zome_group): per-group coordination space (invite-only, per-DHT). - NDO DNA extensions: new entry types in
zome_gouvernancefor hard links, contributions, and smart agreements.
This document is the normative requirements anchor. The companion architecture specification
lives in documentation/specifications/post-mvp/lobby-architecture.md.
2. Background: the multi-network problem
The MVP NDO hApp operates as a single DHT: all agents, resources, and governance events share one network. As OVN (Open Value Network) communities grow, several problems emerge:
- An agent participating in multiple OVN communities (Sensorica, Open Source Ecology, etc.) must manage separate identities and has no unified workspace for coordinating across them.
- A Project NDO (e.g. an electronic device) needs to formally incorporate component NDOs (power supply, enclosure) in a way that is intrinsic to the DHT and OVN-license compliant.
- Communities need discovery mechanisms that are not a public free-for-all (spam risk) but also not so private that new agents cannot find communities to join.
- Work done at the group coordination level (informal logs) must have a clear pathway to becoming a validated Contribution recorded on the NDO DHT.
These gaps are addressed by the Lobby DNA layer defined in this document.
3. Architecture overview
Three-layer DHT model
Lobby DHT (public registry, canonical network_seed)
|
|-- Group DHTs (per-group, invite-only, one DHT per group)
| |-- Work logs, soft links, membership
|
|-- NDO DHTs (per-NDO, constitutional, one DHT per NDO)
|-- Resources, events, contributions, hard links, smart agreements
Governance hierarchy (strictly ordered)
NDO governance (constitution, supersedes all)
|
Group governance (coordination, agents only)
|
Lobby (no governance, permissionless registry)
Two link tiers
Soft links live in the Group DHT:
- Created by any group member, permissionless
- Invisible to the target NDO
- Represent planning and coordination intent
- Subject only to group governance
Hard links (NdoHardLink) live in the NDO DHT:
- Created only on validated EconomicEvent Fulfillment
- Require Accountable Agent authorization
- Represent structural reality (what has actually been incorporated)
- Intrinsic to the NDO, OVN-license compliant
- Immutable and permanent
Agent identity layers
One physical agent produces multiple pubkeys across DHT layers. The Lobby, Group, and NDO layers each hold a distinct identity record for the same person:
LobbyAgentProfile(Lobby DHT) — ecosystem-wide public handle. One per agent, never modified by NDO joins. Stable cross-community identity anchor.Person(NDO DHT,zome_person) — constitutional identity within one specific NDO. A freshAgentPubKeyis created per NDO join; thePersonentry records roles, PPRs, and private data for that community.GroupMembership.ndo_pubkey_map(Group DHT) — the MVP bridge linkinglobby_pubkeyto the per-NDO pubkeys, enabling cross-DHT identity resolution without Flowsta. Post-MVP, FlowstaIsSamePersonEntrysupersedes this (REQ-LOBBY-INT-01).
For the full identity-layer diagram and implementer guidance, see
documentation/specifications/post-mvp/lobby-architecture.md §2 "Agent identity layers".
Groups vs organization-NDOs
Groups and organization-NDOs are distinct concepts that must not be conflated:
- A Group (Lobby layer) is a coordination space for agents. It has no
NondominiumIdentity, no Layer 0 lifecycle, no PPRs, and cannot hold resource custody. It governs agents only: membership, work logs, and soft links. - An organization-NDO (NDO layer) is a
NondominiumIdentityrepresenting a collective entity. It has its own lifecycle,Agreement,AccountableAgents, and can accumulate Contributions and reputation. Post-MVP it can hold resource custody (AgentContext, REQ-AGENT-02). - A group typically creates and coordinates around an organization-NDO but does not become it. The two are always separate entities at separate DHT layers.
- An agent does not need to be in a group to contribute to an organization-NDO. Group membership governs group-layer coordination only; NDO participation is governed by the NDO's own rules.
For the comparative table and worked example, see
documentation/specifications/post-mvp/lobby-architecture.md §2 "Groups vs organization-NDOs".
4. Lobby DNA Requirements
Implementation note (PR #103, revised by PR #107): The Lobby is a separate DNA (
dnas/lobby/), not a zome inside the nondominium DNA. Thelobbyrole inworkdir/happ.yamluses canonicalnetwork_seed: "nondominium-lobby-v1". PR #103 initially shippedLobbyAgentProfileplus anNdoAnnouncementregistry; PR #107 removed the NDO registry (NdoAnnouncement,announce_ndo,get_all_ndo_announcements,update_ndo_announcement) and replaced it with the group registry: entry types are nowLobbyAgentProfileandGroupAnnouncement, with coordinator APIsupsert_lobby_agent_profile,get_lobby_agent_profile,announce_group,get_my_group_announcements,get_all_group_announcements. NDOs are group-scoped; the NDO-per-cell design (issue #112) resurrects the descriptor idea as the group-levelNdoAnchor. Authoritative reference:documentation/zomes/lobby_zome.md.
4.1 Agent profile
- REQ-LOBBY-01: Any agent may register a public
LobbyAgentProfilein the Lobby DHT containing a handle, optional avatar, and optional bio. Registration is permissionless. Status: ✅ Implemented (upsert_lobby_agent_profile). - REQ-LOBBY-02: An agent may update only their own profile. Profiles cannot be deleted (permanent identity anchors in the Lobby DHT). Status: ✅ Implemented (update chain + delete rejected in integrity zome).
- REQ-LOBBY-03: Agent profiles are discoverable via a global anchor
(
Path("lobby.agents")). Status: ✅ Implemented (AllLobbyAgentslink type,get_all_lobby_agents).
4.2 NDO descriptor registry
Normative name: NdoDescriptor. Initially implemented as NdoAnnouncement in PR #103,
then removed in PR #107: the Lobby became a group registry and NDO visibility became
group-scoped. The descriptor concept survives at group level as NdoAnchor (issue #112),
which carries the same clone coordinates (name, DnaHash, network_seed, Layer 0 identity hash,
lifecycle_stage, property_regime, resource_nature) inside each group cell.
- REQ-LOBBY-04: Any agent may register an
NdoDescriptor/NdoAnnouncemententry in the Lobby DHT for an NDO they initiated. The descriptor contains: NDO name, DnaHash, network_seed, Layer 0 identity hash, lifecycle_stage, property_regime, resource_nature, and description. Status: ⚠️ Superseded — removed from the Lobby in PR #107; fulfilled at group scope byNdoAnchor(#112). A future Lobby-level NDO index remains an explicit option. - REQ-LOBBY-05: Only the registrant may update a descriptor. Descriptors cannot be
deleted (mirroring the permanent nature of NondominiumIdentity in the NDO DHT).
Status: ⚠️ Superseded — see REQ-LOBBY-04; anchor updates are author-gated in
zome_group. - REQ-LOBBY-06: The only mutable field on a descriptor after registration is
lifecycle_stage, which mirrors transitions on the NDO'sNondominiumIdentity. Status: ⚠️ Superseded —NdoAnchorallows cached descriptor sync (name, description, lifecycle_stage) while its identity coordinates stay immutable. - REQ-LOBBY-07: Descriptors are discoverable via global anchors and categorization paths
by lifecycle stage, resource nature, and property regime.
Status: 🔄 Partial — global anchor (
lobby.ndos) and lifecycle paths (lobby.ndo.lifecycle.{stage}) ✅; nature and property-regime facet anchors not yet implemented (client-side filtering only in MVP UI). - REQ-LOBBY-08: Anti-spam: registration requires a valid
DnaHashreferencing an actual NDO cell. Ghost registrations (no deployed DNA) are detectable by peers who attempt to connect and find no DHT. Status: 🔄 Partial —ndo_dna_hashis stored but not cryptographically verified at registration time; social detection only.
4.3 Discovery model
- REQ-LOBBY-09: NDO descriptors are publicly discoverable in the Lobby DHT without any group membership or invitation. Status: ✅ Implemented at DNA level; MVP UI browse still uses resource zome + local groups.
- REQ-LOBBY-10: Groups are NOT publicly discoverable. Group membership is invite-only. Agents discover groups through personal connections and out-of-band invite codes. Status: ✅ By design — Group DNA not public; MVP uses localStorage invite encoding.
- REQ-LOBBY-11: Canonical Lobby network seed (
"nondominium-lobby-v1") is hardcoded in the hApp bundle to ensure all deployments share one global registry. Status: ✅ Implemented inworkdir/happ.yamllobby role modifiers.
5. Group DNA Requirements
Current state: Group DNA (
zome_group_integrity+zome_group_coordinator) is not yet in the repository (issue #101). The MVP UI implements the Lobby → Group → NDO navigation hierarchy with a localStorage shell (GroupDescriptorinndo_groups_v1) perui_design.mdand REQ-UI-GRP-01.LobbyService.getMyGroups()reads/writes localStorage;associateNdoWithGroupingroup.store.svelte.tsappends NDO hashes locally with a TODO for Group DHT propagation once DNA lands. The Lobby coordinator'sget_my_groupsreturns a solo-workspace stub until real membership exists on the Group DHT.
5.1 Group structure
- REQ-GROUP-01: Each Group occupies its own DHT, instantiated with a unique network seed (the invite code or a random seed on creation). This provides natural isolation and makes group creation computationally non-trivial (anti-spam).
- REQ-GROUP-02: On first launch, an agent's conductor automatically creates a "group-of-one" personal workspace. This solo group can later expand to accommodate new members without any structural migration.
- REQ-GROUP-03: Groups are flat: no recursive group nesting, no groups of groups. The Lobby is the only shared coordination layer above groups.
- REQ-GROUP-04: A
GroupDescriptorentry is created by the founding agent (progenitor) and is immutable after creation.
5.2 Membership
- REQ-GROUP-05: Group membership is invite-only. Joining requires a valid invite code (or, when running inside Moss, the Moss invite system).
- REQ-GROUP-06: A
GroupMembershipentry records the joining agent's Group DHT pubkey and their per-NDO pubkey map (Vec<NdoPubkeyEntry>), following the MossAppletToJoinedAgentidentity pattern. - REQ-GROUP-07: An agent may update their
ndo_pubkey_mapafter joining a new NDO DHT (i.e. after installing a new NDO clone cell). This is the MVP cross-DHT identity bridge. - REQ-GROUP-08: Group members can look up the NDO-DHT pubkey of any other group member for a given NDO, enabling cross-DHT agent resolution without Flowsta (MVP).
5.3 Work logs
- REQ-GROUP-09: Any group member may create a
WorkLogentry referencing an NDO, a process context, a description, and optional effort hours. Work logs are informal and pre-contribution; they are invisible to the NDO. - REQ-GROUP-10: Work logs serve as the group-level input to the contribution validation
pipeline: an AccountableAgent of the NDO reviews the work log and, if accepted, promotes
it to a
Contributionentry on the NDO DHT.
5.4 Soft links
- REQ-GROUP-11: Any group member may create a
SoftLinkentry pointing to any NDO, without requiring that NDO's permission. Soft links are invisible to the target NDO. - REQ-GROUP-12: A soft link has one of three purposes:
Incorporation(planning to structurally incorporate the target NDO into a parent NDO),Use(using the NDO as a tool or equipment), orMonitoring(observing the NDO lifecycle). These map to VfAction valuesCombine | Use | Citerespectively (see architecture specSoftLink.planned_action). - REQ-GROUP-13: A soft link may optionally reference a
Commitmentaction hash in the target NDO's DHT, associating the planning intent with a formal economic commitment. - REQ-GROUP-14: When an Incorporation soft link's associated Commitment is fulfilled (i.e. a hard link is created on the NDO DHT), the group deletes the soft link and displays it as "promoted" in the UI.
- REQ-GROUP-15: Only the link creator or the group progenitor may delete a soft link.
5.5 Group governance
- REQ-GROUP-16: Groups have their own governance rules, stored as
GroupGovernanceRuleentries. MVP: governance rules are flat string key-value pairs. - REQ-GROUP-17: Group governance governs group-internal concerns only: membership, coordination norms, and soft link management. Group governance does NOT govern contributions, benefit distribution, or smart agreements (these belong to NDO governance).
- REQ-GROUP-18: NDO governance supersedes group governance. If an NDO's governance rules conflict with a group's rules, the NDO rules take precedence for any action on that NDO.
6. NDO DNA Extension Requirements
Implementation note (PR #103): Entry types and coordinator modules exist in
zome_gouvernance. Sweettest coverage indnas/nondominium/tests/src/governance/mod.rs(create_and_get_ndo_hard_linkpasses; Agreement and Contribution tests are#[ignore]pending AccountableAgent role setup in test harness). Full AccountableAgent enforcement on create paths awaits governance-as-operator (#41–#44) and complete promotion workflows.
6.1 Hard NDO-to-NDO links
- REQ-NDO-EXT-01: The NDO DNA (zome_gouvernance) shall support a
NdoHardLinkentry type representing a permanent, validated structural relationship between two NDOs. Status: ✅ Implemented. - REQ-NDO-EXT-02: A
NdoHardLinkmay only be created by an agent holding theAccountableAgentorPrimaryAccountableAgentrole in the originating NDO. Status: 🔄 Partial — coordinator validates caller identity; full cross-zome role check deferred to governance-as-operator. - REQ-NDO-EXT-03: Every
NdoHardLinkmust reference a validEconomicEventfulfillment hash in the originating NDO's DHT. This fulfillment is the cryptographic proof that the incorporation actually occurred. Status: ✅ Implemented (create_ndo_hard_linkverifies record decodes asEconomicEvent). - REQ-NDO-EXT-04:
NdoHardLinkentries are immutable: no updates or deletions are permitted after creation. Hard links represent permanent historical reality (OVN license requirement). Status: ✅ Implemented (integrity zome). - REQ-NDO-EXT-05: Three
NdoLinkTypevalues are supported:Component(target is a structural component of the source),DerivedFrom(source was forked/adapted from target),Supersedes(source replaces target in the network). Status: ✅ Implemented. - REQ-NDO-EXT-06: Hard links are publicly discoverable on the NDO DHT via
NdoToHardLinksanchor links and filterable by type. Status: ✅ Implemented (get_ndo_hard_links,get_ndo_hard_links_by_type).
Design note — two-stage NdoHardLink deployment
NdoHardLink uses the same struct in both stages. No breaking change occurs between Stage 2
and Stage 3. The fields to_ndo_dna_hash: DnaHash and to_ndo_identity_hash: ActionHash
change only in value, not in meaning:
Stage 2 (pre-Lobby DNA, clone_limit: 0): Both the source and target NDOs live in the
same nondominium cell. to_ndo_dna_hash equals the shared nondominium DNA hash.
to_ndo_identity_hash is the target NDO's NondominiumIdentity action hash. Resolving the
link requires no cross-cell call — both hashes are local to the same DHT.
Stage 3 (post-Lobby DNA, clone_limit: 1024): Each NDO has its own cloned cell with a
unique DnaHash (because each clone has a unique network_seed). to_ndo_dna_hash is the
target NDO cell's unique hash. The UI resolves the link by connecting to
CellId(to_ndo_dna_hash, agent_pubkey) and calling get_ndo(to_ndo_identity_hash). The
Lobby's NdoDescriptor provides a human-readable index but is not required for resolution.
See documentation/specifications/post-mvp/lobby-architecture.md §6.1 for the full entry
struct and §7.1 for the incorporation pipeline.
6.2 Contributions
- REQ-NDO-EXT-07: The NDO DNA shall support a
Contributionentry type representing a peer-validated record of work done on the NDO. Status: ✅ Implemented (validate_contribution, discovery queries). - REQ-NDO-EXT-08: A Contribution is created by any agent but must be validated by at
least one
AccountableAgentof the NDO. Thevalidated_byfield records all validating agents. Status: 🔄 Partial — schema and API exist; AccountableAgent enforcement in tests still#[ignore]. - REQ-NDO-EXT-09: A Contribution may optionally reference a
WorkLogentry in a Group DHT (stored asDnaHash + ActionHash) for audit purposes. This reference is not validated on-chain (cross-DHT references are informational only). Status: ✅ Schema fieldswork_log_group_dna_hash,work_log_action_hashonContribution; Group DHT not yet available. - REQ-NDO-EXT-10: When a work log is validated as a Contribution, the contributing
agent's pubkey is discoverable via
AgentToContributionslinks, making them appear in the NDO's contributor list. Status: ✅ Implemented (AgentToContributions,NdoToContributionslinks). - REQ-NDO-EXT-11: A Contribution may optionally reference an
EconomicEventfulfillment hash when the work resulted in a structural change (i.e. hard link creation). Status: ✅ Optionalfulfillsfield onContribution.
6.3 Smart agreements
Entry type name: Agreement (aligned with VF vocabulary vf:Agreement); referred to as
"smart agreements" in this document to emphasise their benefit-distribution role.
- REQ-NDO-EXT-12: The NDO DNA shall support an
Agreemententry type defining benefit distribution rules for the NDO. Smart agreements are created and updated only by agents holding theAccountableAgentrole. Status: ✅ Implemented (create_agreement,update_agreement,get_current_agreement). - REQ-NDO-EXT-13: A
Agreementcontains a list ofBenefitClauseentries, each specifying a beneficiary (agent or component NDO), a share percentage, and a benefit type (Monetary,GovernanceWeight, orAccessRight). Status: ✅ Implemented. - REQ-NDO-EXT-14: Smart agreements are versioned. Each update creates a new entry linked
to the previous via
AgreementUpdates. The full version history is preserved for audit purposes. Status: ✅ Implemented. - REQ-NDO-EXT-15: When a
NdoHardLinkof typeComponentis created, the originating NDO's smart agreement should be updated to include a cascade benefit rule to the component NDO, implementing the OVN license benefit cascade. (Automated post-MVP via Unyt; manual in MVP.) Status: ❌ Not automated — manual process only; Unyt integration post-MVP. - REQ-NDO-EXT-16:
BeneficiaryRefsupports bothAgent(AgentPubKey)andNdoComponent { ndo_dna_hash, ndo_identity_hash }, allowing benefits to flow recursively through the NDO composition graph. Status: ✅ Implemented in shared types / integrity zome.
7. Cross-cutting Requirements
7.1 Dual deployment
- REQ-XCUT-01: The Nondominium hApp shall run as a standalone application (Lobby DNA + Group DNA + NDO DNA, all managed by one conductor) AND as a single Moss/The Weave Tool applet (Nondominium Lobby appears as one tile in the Moss sidebar; Moss handles agent invites and identity at the surface level). Status: 🔄 Partial — standalone bundle includes lobby + nondominium + hrea roles; Group DNA and Moss WeApplet not yet present.
- REQ-XCUT-02: The NDO DNA is not modified between standalone and Moss deployments. The Lobby and Group DNAs are either used directly (standalone) or delegated to Moss equivalents (Moss integration). Status: ✅ NDO DNA unchanged; Moss path not implemented.
7.2 Resources are organization-agnostic
- REQ-XCUT-03: NDO resources (EconomicResource, NondominiumIdentity) are groups- and organizations-agnostic. A Group does not own an NDO. Multiple groups may soft-link to the same NDO. The NDO's governance is independent of any group that references it.
7.3 Solo agent model
- REQ-XCUT-04: A solo agent who has not joined any multi-member group appears in the UI as an individual Agent. Internally, they operate via an auto-created group-of-one. This group-of-one can grow to accommodate new members without any structural migration.
8. Governance Layers
8.1 NDO governance (constitutional layer)
NDO governance is defined by the NDO's GovernanceRule entries and the AccountableAgent
role set. It governs:
- Who may create hard NDO-to-NDO links (AccountableAgents only)
- Who may validate contributions (AccountableAgents only)
- Who may create and update smart agreements (AccountableAgents only)
- What EconomicEvent actions are valid for the NDO
- NDO lifecycle stage transitions
NDO governance supersedes group governance for all actions that affect NDO state.
8.2 Group governance (coordination layer)
Group governance is defined by GroupGovernanceRule entries. MVP: flat key-value rules.
It governs:
- Who may join the group (invite code validation)
- Who may create or delete soft links
- Coordination norms and cultural rules
Group governance does NOT govern contributions, benefit distribution, or smart agreements.
8.3 Lobby (no governance)
The Lobby DHT is permissionless. Any agent may register a profile or NDO descriptor. The only implicit governance is the requirement that a registered NDO descriptor references an actual deployed DNA (discoverable by peers who attempt to connect).
9. Integration Requirements
9.1 Flowsta (post-MVP, Phase 1+3)
- REQ-LOBBY-INT-01: Post-MVP, the MVP cross-DHT identity mechanism (per-NDO pubkey
map in
GroupMembership) shall be superseded by FlowstaIsSamePersonEntryattestations, enabling cross-conductor and cross-device identity federation. - REQ-LOBBY-INT-02:
GroupMembership.ndo_pubkey_mapis forward-compatible: the Flowsta DID can be added as an additional field without breaking existing records. - See
flowsta-integration.mdfor full Flowsta requirements (REQ-NDO-CS-12 through CS-15).
9.2 Unyt (post-MVP)
- REQ-LOBBY-INT-03: Post-MVP,
Agreementrules withBenefitType::Monetaryshall be activated via Unyt: validated Contributions trigger RAVE events, and NdoHardLink creation triggers benefit cascade through the NDO composition graph. - REQ-LOBBY-INT-04: The Lobby shall support monetary contributions to NDOs via Unyt (agents can donate to an NDO from the Lobby without joining a group).
- See
unyt-integration.mdfor full Unyt requirements.
9.3 Many-to-many flows (post-MVP)
- REQ-LOBBY-INT-05: NdoHardLink creation currently requires a single AccountableAgent signature. Post-MVP, multi-party consent for structural incorporation shall be supported per REQ-MMF-* (many-to-many-flows.md).
10. Current State vs Planned Enforcement
Last reconciled with the codebase, 2026-07-19.
10.1 What is implemented
| Layer | Status | Notes |
|---|---|---|
| Lobby DNA | ✅ PR #103, revised #107 | dnas/lobby/ — LobbyAgentProfile + GroupAnnouncement (group registry); lobby role in happ.yaml with network_seed: "nondominium-lobby-v1"; Sweettest (lobby_sweettest, 5 tests) |
| Group DNA | ✅ PR #107 | dnas/group/ — GroupProfile, GroupMembership, WorkLog, SoftLink; group role (deferred: true, clone_limit: 64); Sweettest (group_sweettest, 13 tests) |
| DHT-backed group UI | ✅ PR #111 | createCloneCell group provisioning, invite links, DHT member list, NDO association (SoftLink at the time, NdoAnchor since PR #128); multi-agent web harness (scripts/launch-happ.mjs) |
| NDO-per-cell UI cutover | ✅ Issue #110 / PR #128 | createNdo provisions an NDO cell + NdoAnchor instead of a shared-DHT entry + SoftLink; lobby and group NDO grids render from anchors; a peer derives and joins the cell from anchor coordinates |
| NDO federation extensions | ✅ PR #103 | NdoHardLink, Contribution, Agreement in zome_gouvernance; coordinator APIs + partial Sweettest |
| NDO Layer 0 | ✅ PR #80 | NondominiumIdentity on the shared nondominium DHT |
| NDO DNA + NdoAnchor | ✅ Issue #112 / PR #128 | ndo role (deferred: true, clone_limit: 512) bundling existing resource + governance WASMs; NdoAnchor in zome_group with clone coordinates; one NDO = one cloned cell, DnaHash bound to Layer 0 via DNA properties (ADR-013) |
10.2 In progress or not started
| Layer | Status | Notes |
|---|---|---|
| Lobby profile UI sync | 🔄 Issue #106 / PR #114 | Profile bar + fire-and-forget upsert_lobby_agent_profile |
| Moss WeApplet | ❌ | ui/src/we-applet.ts contract specified in architecture doc; not in repo |
| Facet discovery (nature / regime) | ❌ | REQ-LOBBY-07 nature and property-regime path anchors not in Lobby DNA (NDO announcements removed; facets now group-scoped via anchors) |
| Governance-as-operator | ❌ | #41–#44 — blocks full AccountableAgent enforcement on Contribution / Agreement / hard links |
10.3 Planned next steps
- NDO-per-cell (#112 + amended #110) — backend anchor plumbing, then UI cutover.
- Per-LinkType validation (#85) — scope extended to lobby, group, and ndo DNAs.
- Governance-as-operator (#41–#44) — the operator evaluates inside each NDO cell.
- Post-MVP — cross-cell reputation aggregation, optional Lobby-level NDO index, Moss WeApplet, Flowsta identity bridge.
The companion architecture specification
(documentation/specifications/post-mvp/lobby-architecture.md) remains the detailed schema,
coordinator API, pipeline, UI, Moss contract, and ADR reference for remaining work.
For OVN-scale motivation (bridge nodes, multi-community agents, holonic layers) and the
normative NDO requirements that this document extends, see ndo_prima_materia.md §6, §8,
and §11. For the companion architecture design, see
documentation/specifications/post-mvp/lobby-architecture.md.
Nondominium UI Design Vision
MVP
This section describes the minimalistic UI for MVP Layer 0 — NDO Identity (stable anchor; only lifecycle_stage evolves after creation; REQ-NDO-L0-*). The MVP UI implements the concepts of Lobby, Groups, and NDO view.

Lobby discovers Groups (via GroupAnnouncement in the shared Lobby DHT) — not NDOs. Groups discover NDOs via NdoAnchor entries in each Group's own cloned-cell DHT, and each NDO is itself a cloned ndo cell (ADR-010 model A). The Lobby's NdoBrowser shows only NDOs from the agent's own groups, not a global public registry. NDOs can only be created from within a Group. Identity: localStorage nickname → per-group profile → Person DHT entry on first NDO action.
Lobby
The Lobby is a permissionless digital environment that anyone can join. It is the persistent outer shell of the application, always visible regardless of which route is active.
Implemented:
- Persistent left sidebar present on all routes, containing:
- Browse NDOs link → root page (
/) listing all unique NDOs across all the user's groups, with filter chips (Lifecycle Stage, Resource Nature, Property Regime) - Groups list — links to each group the user has created or joined (
/group/:id) - + New Group — inline form: user enters a group name and confirms; they become the group creator
- → Join Group — inline form: user pastes an invite code or link
- My Profile / Edit profile — at the bottom of the sidebar; opens the profile modal
- Browse NDOs link → root page (
- First-time profile modal — triggered automatically on first app launch when no lobby profile exists; requires at least a nickname; all other fields (real name, bio, email) are optional and stored in
localStorage
Groups
Groups are organizational contexts for NDOs. A user can create a solo Group or join an existing one. Groups are DNA-backed: each group is a cloned Group DNA cell (clone_cell, zome_group) with its own isolated DHT, announced for discovery via the Lobby DNA. Only the Level 2 presentation choice (GroupMemberProfile — anonymous vs. selected fields) remains in localStorage; membership and NDO associations live on the DHT (GroupMembership and NdoAnchor entries).
Implemented:
- Group panel (
/group/:id): shows group name, list of NDO cards, member list, and a "Create NDO" button - Group profile prompt: on first visit to a group the user is asked how they wish to present themselves (anonymous / custom); stored in
localStorage - NDO cards in group: each card shows name, lifecycle-stage badge, property-regime badge, resource-nature badge, and description excerpt; clicking a card navigates to the NDO detail page
- Switching groups: navigating from one group to another correctly reloads the group name and NDO list
- Invite links (multi-member groups):
generateInviteLinkencodes{ network_seed, group_dna_hash, group_name }as?group=<base64>; Sidebar and GroupView expose "Copy invite";joinGroupprovisions the clone cell and callsjoin_group - Group members from DHT:
MemberListis wired togroupService.getMembers(cellId)on the group clone cell (each member is the action author of aGroupMembershipentry linked from the group hash) - Reactive join: a joined group appears in the sidebar immediately.
joinGrouppollsget_my_group(fetchGroupProfileWithRetry) to absorb DHT gossip latency, and falls back to an invite-payloadGroupDescriptorif the profile has not yet synced, so no page reload is needed.TODO(signals): replace polling with a Holochain remote signal once available. - Membership self-heal: because
joinGroup's membership commit is best-effort (it can take the payload-fallback path before the group profile gossips, and thejoin_groupcall is non-fatal), opening a group runs an idempotentlobbyService.ensureMembership(groupId)(resolve group hash →is_member→join_groupif missing). This guarantees a joined agent is eventually a committed member and appears in everyone's member list, even if the original join missed. - Pull-based reactivity for shared items: while a group is open,
GroupViewsilently re-fetches it (members + NDOs viagroupStore.refreshCurrentGroup()) on tab focus / visibility change and on a gentle ~8s poll (paused when the tab is hidden). New items gossiped from other members therefore surface without a manual reload.TODO(signals): replace this pull layer with Holochain remote signals (focus/poll kept only as an offline/missed-signal fallback).
Not yet implemented:
- Group-level governance
- Push-based reactivity via Holochain signals (currently pull-based: focus + poll + per-open reconciliation). Cross-member changes appear within the poll interval / on focus / on reload rather than instantly.
NDO Creation
NDOs can only be created from within a Group. The "Create NDO" button in a Group panel opens a creation form. NDO identity data is stored on the Holochain DHT as a NondominiumIdentity (Layer 0) entry; the action_hash of that entry is the NDO's permanent stable identity.
Implemented fields:
| Field | Control | Notes |
|---|---|---|
name | text input | required; uniqueness warning shown if name already exists in the lobby |
property_regime | select | 7 variants: Private, Commons, Collective, Pool, CommonPool, Public, Nondominium; tooltip per option |
resource_nature | select | 5 variants: Physical, Digital, Service, Hybrid, Information; tooltip per option |
lifecycle_stage | select | seven creatable-at-registration stages: Ideation, Specification, Development, Prototype, Stable, Distributed, Active (matches create_ndo validation); Hibernating and terminal stages (Deprecated, EndOfLife) are not selectable here — only via lifecycle transitions after registration |
description | textarea | optional |
Note: PropertyRegime is protocol-canonical at seven variants (including Collective, Pool, and Public). The UI creation form, filters, and badges expose all seven. See the Rust
PropertyRegimeenum incrates/shared/src/types.rsandLifecycleStagefor current canonical values.
NDO View
Clicking an NDO card navigates to /ndo/:hash.
Implemented:
- NDO name displayed in header (populated immediately from in-memory cache on card click; refreshed from DHT in the background)
- Truncated hash shown below the name
- Detail card: labeled fields for Description, Property Regime, Resource Nature, Lifecycle Stage, and Created date
- Identity badges: lifecycle-stage color badge, property-regime badge, resource-nature badge
- Lifecycle transition button (visible to NDO initiator only): advances the lifecycle stage
- Join NDO button — placeholder; toggles inline "Coming soon"; no backend call yet
- Associate with a group button — always shown in the header; opens a modal that lists groups the user has created or joined that are not already linked to this NDO (multi-select); if the user has no groups, the modal explains that case; confirming writes associations to
localStorage(ndo_groups_v1keyed like other group data — seegroup.store.svelte.ts); the NDO card then appears in the selected group(s) - Fork this NDO button — opens the fork friction modal; visible only when the Holochain conductor is connected and the UI has resolved the user's agent key
- Tabs: Resources, Governance, Composition, Activity (stubs for post-MVP content)
Browse NDOs
Implemented:
- "Browse NDOs" in sidebar → root page showing all unique NDOs from all groups the user has created or joined
- Filter chips by Lifecycle Stage, Resource Nature, and Property Regime (7 variants)
- NDO cards with name, badges, description excerpt, and truncated hash
- "No NDOs yet" state when the user has no groups or no NDOs
User / Agent Identity
At the Lobby level the User can be anyone. At this level the User creates a Lobby Profile, stored in localStorage. At the Group level the User also has a profile, linked to the Lobby profile but customizable per group. As the User creates or links to an NDO, their identity is distilled into a Holochain Agent (as implemented in zome_person). Since NDOs are public and permissionless, no personal information is revealed at the NDO level — only a pseudonymous agent key address is shown. Access to personal data (e.g. PPR — Personal Participation Receipts) is selective and governed by the Governance zome.
Implemented:
- First-time Lobby profile modal:
nicknamerequired;realName,bio,emailoptional; stored inlocalStorage - "Edit profile" in sidebar for returning users
- Group profile prompt on first group visit: user can choose how to present themselves (anonymous or with selected fields from their Lobby profile)
- Agent public key shown on the NDO initiator line when Holochain is connected
MVP ToDos
Status (2026-06): All eight MVP ToDos below are implemented. Groups are DNA-backed via cloned Group cells (
clone_cell,zome_group); NDO lists useNdoAnchorentries on the group DHT (per-NDO cells, ADR-010/011 — seedocumentation/specifications/adr/ADR-010-013-per-ndo-cells.md). Join NDO is UI + API contract only (backend stub).
-
Multi-member groups — invite link✅generateInviteLinkencodes{network_seed, group_dna_hash, group_name}; Sidebar and GroupView expose copy-invite;joinGroupprovisions clone cell and callsjoin_group. -
NDO fork friction✅ForkNdoModal.sveltedisplays negotiation → consensus → Unyt stake notice before copy-pubkey CTA. -
NDO detail page — DHT refresh reliability✅/ndo/[hash]callsresource.getNdo(hash)directly viagetNdoDescriptorForSpecActionHash; cache is fallback only. -
Group member list✅MemberListwired togroupService.getMembers(cellId)from group clone cell. -
Browse NDOs onboarding✅NdoBrowserempty state distinguishes no-groups vs no-NDOs with create/join CTAs. -
Update✅ Three-tier identity model documented (§2.0); Level 2 profiles remain localStorage; groups are DHT-backed.agent.md -
NDO–Group association DHT propagation✅create_ndo_anchoron the group cell; lobby/group NDO lists resolve fromNdoAnchors. (Originally shipped ascreate_soft_link; superseded by anchors when NDOs moved to their own cells.) -
Join NDO✅ UI flow inNdoView.svelte; API contract indocumentation/zomes/resource_zome.md § NDO membership (planned);joinNdo/getNdoMembersstub inndo.service.ts.
Perspectives (Next)
A Perspective is a lens on the DHT data. Each Perspective answers one question, "what is the Agent doing?", and is built around one base primitive. Navigation means "swimming in the ocean" of that primitive, then adding layers progressively (e.g. from a resource: which communities use it → which are local → who uses it → which organization owns it). The Agent is always in exactly one Perspective and can jump between them (see Cross-Perspective Navigation). There are four Perspectives:
| Perspective | Question it answers | Base primitive |
|---|---|---|
| 📦 Resource | What can I use, borrow, offer or manage? | Resource (NDO) |
| 👥 Agent | Who can I connect or collaborate with? | Agent (incl. Groups) |
| 🧭 Intelligence | Where should I allocate my time and resources strategically? | Projects and organizations, incl. those outside the Agent's current sphere |
| 🛠️ Work | What do I engage in today, and with whom? | Process / work item, in the context of a resource, project or group |
📦 Resource Perspective
Resource-centric view of the DHT.
- Use cases: find a resource to use or borrow; offer a resource (by creating a new NDO); manage resources the Agent owns, custodies or maintains.
- Progressive layers: communities using the resource → which are local (map tool) → who uses it → which organization owns it.
- Sources: included to the extent a Resource is linked to a Source (e.g. a gallon of water from a river). A Source view presents the Source as a shared surface (a "digital twin" of, say, a river) to which data is attached (scientific studies, flow, planned withdrawals), so that all parties see the same information and rules of use can emerge from it. See
post-mvp/source-ndo-requirements.md. - Expanded resource view: shows linked Agents and their capacity (e.g. Custodian, Repair agent). Clicking one jumps to the Agent Perspective.
resource_view:
focus_filter: resource_type | nature | regime | lifecycle_stage
group_by: category | status | source
layers: [communities, local_map, users, owner_org]
layout: cluster_hierarchy
👥 Agent Perspective
Agent-centric view of the DHT. Groups are a type of Agent and appear in results.
- Use cases: find Agents by skills; invite Agents to collaborate on a project; discover Groups and decide to join them.
- Profile: communities, projects, skills and reputation in one view.
- Navigation: hop from link to link through the relationship graph (collaborations, shared groups, roles on resources).
- Tools: map (e.g. world distribution of a skill); chat to contact an Agent directly (possibly through the Capability Surface).
agent_view:
focus_filter: skills | collaboration_potential | group_membership
relationship_mapping: trust_network
layout: network_graph
🧭 Intelligence Perspective (formerly Role Perspective)
Strategic decision-support view. Helps the Agent decide where to allocate time and resources. Unlike the Work Perspective, it gathers information from outside the Agent's current sphere of activity, and doubles as a personal dashboard.
- Personalised filtering: by the Agent's role, skills, reputation (PPR) and past interactions.
- Navigable contexts: Groups, project-type NDOs and other collaboration contexts, including ones the Agent has not joined.
- AI assistant (MCP): an agent that knows the Agent's profile, exposed through an MCP server, suggests fitting projects (e.g. already-funded projects if income is needed; high-potential, no-revenue projects if the Agent wants to give 5–10% of their time to them).
- Stage-aware assessment: expected benefit and impact are weighed by project stage (early, in development, near completion), mapped from
lifecycle_stage. - Project-declared benefits: assessments rely on the benefits a project publishes itself. These are declared in the project-type NDO specification (
post-mvp/project-type-ndo-specifications.md), which therefore needs a benefits field. - Time-allocation simulation: e.g. "10% on high-impact projects, 10% on social impact, the rest on revenue-generating ones" → the assistant shows matching opportunities. Other simulations (benefit-redistribution algorithms) and the map are also invocable.
- Direct actions: subscribe to a community, become a member, attach to a project.
intelligence_view:
focus_filter: role_fit | skills_match | reputation | past_interactions
scope: outside_current_activity
assistant: mcp_agent
tools: [allocation_simulation, redistribution_simulation, map, chat]
layout: ranked_opportunities
🛠️ Work Perspective (new)
Process-centric view of the Agent's active engagements. "Work" means engaging in processes, in the context of a resource, project or group ("what can I do in this group today?").
- Project list: all project-type NDOs the Agent has subscribed to or contributed to. Selecting one opens its collaboration tools. Group- and resource-level contexts are also available.
- Per-project tools: kanban board, tasks, planning; commit to work, take a task, log contributions; coordinate with other Agents on the development of the NDO.
- Stigmergic signals across projects: which projects are active or need attention, invitations to contribute, calls for decision-making. These help the Agent choose what to work on today.
- Joining: a project joined from the Intelligence Perspective lands here. In the Work perspective, also provide access to the 3 layers of Valueflow layers (knowledge, plan and observation).
work_view:
focus_filter: subscribed | contributed
contexts: [project, group, resource]
panels: [project_list, kanban, planning, contributions, signals]
priority_order: attention_needed | invitations | activity
layout: project_workspace
🧰 Tools (cross-perspective)
Tools are not Perspectives; they can be invoked from any Perspective and applied to that Perspective's data.
- Geographic map: maps Resources, Agents, Groups or Projects, depending on where it is opened.
- Chat: direct contact with an Agent, available in several Perspectives.
- Others: simulations, kanban (Work), filters and search.
Cross-Perspective Navigation
Perspectives are connected by contextual jumps carrying the current entity (resource, agent, project, group) along.
| From | Trigger | To |
|---|---|---|
| Work | "Discover new projects" action | Intelligence |
| Intelligence | Join a discovered project | Work (project opens in context) |
| Resource | Click a linked Agent (Custodian, Repair agent, ...) in the expanded resource view | Agent (that Agent's profile and connections) |
| Agent | Click a resource linked to the Agent | Resource |
| Agent / Intelligence | Join a discovered Group | Work or Group panel |
Return path: every jump pushes an entry on a navigation trail (breadcrumb across Perspectives, e.g. Resource: Drill press → Agent: Alice → Groups). A persistent "Back to
Perspective switcher: always visible; besides switching manually, the UI offers contextual hints (a button or badge) when another Perspective is relevant to the current task.
Perspectives ToDos
Status: imminent work (next after the MVP ToDos above). Start with the navigation skeleton, then fill each Perspective incrementally; Perspectives that depend on missing backend data ship first as thin, filtered views over existing Lobby / Group / NDO data.
- Perspective switcher — persistent shell control (Resource · Agent · Intelligence · Work) and one route per Perspective; the current Browse NDOs page becomes the seed of the Resource Perspective.
- Navigation trail — cross-Perspective history stack with breadcrumb and "Back to
"; restores filters and scroll of the origin view. - Contextual jumps — implement the jump table above (linked Agent → Agent Perspective, Work ↔ Intelligence, joined project → Work), plus contextual "you may want Perspective X" hints.
- Resource Perspective — extend NDO expanded view with linked Agents and their capacity (Custodian, Repair agent, ...); offer/create NDO entry point; progressive layers; Sources as linked context (Source view later).
- Agent Perspective — Agent profile view (pseudonymous, per the identity model), connected Agents and graph hopping, skills search, Group discovery via Lobby announcements.
- Intelligence Perspective — first version: ranked discovery of Groups and project-type NDOs outside the Agent's current sphere, filtered by role / skills / reputation / past interactions, with stage-aware assessment and direct actions (subscribe, join, attach); tool slot for simulations; MCP assistant follows.
- Work Perspective — project list (subscribed or contributed), per-project workspace (kanban, tasks, commit / take task / log contribution), stigmergic attention signals; group and resource contexts.
- Tools registry — perspective-agnostic tool host; Geographic map as the first tool, chat next, invocable from any Perspective.
Dependencies / open points
- Project-type NDO: how a project is identified (e.g. a
resource_nature/ NDO type marker) must be decided before Work and Intelligence can filter on it. - Project-declared benefits: stored in the project-type NDO specification; the specification document must add this field before Intelligence can assess benefits.
- Skills, reputation, past interactions: depend on Person data and PPR zome functions still in progress; use placeholders until then.
- Stigmergic signals and invitations: need push reactivity (Holochain remote signals,
TODO(signals)); pull-based polling as interim. - Per-Perspective data scope: Resource and Work read the Agent's own groups; Agent and Intelligence need cross-group / Lobby-level discovery beyond the current "own groups only" rule.
Technical mapping: documentation/specifications/ui_architecture.md § 16.
Layer 0 Release Cut: Resource Perspective
Status: prototyped in
nondominium-design-system, not yet ported to the app. Prototype:/scenarios/resource-perspective(components inpackages/ndo-ui/src/components/patterns/perspectives/, copy registry inpackages/ndo-ui/src/domain/coming-next.ts).
For the Layer 0 release only the Resource Perspective is live, and only with what Layer 0 can do honestly. Everything else is visible, labelled "Soon", and explained instead of hidden.
Where it sits: Lobby stays the outermost layer, Groups the second, and the Perspective switcher lives inside the Group page. At Layer 0 every Perspective is scoped to the current group. Breadcrumb: Lobby › <Group> › Resource › <NDO>.
Live at Layer 0 (Resource Perspective):
- NDO cards, search, stage / nature / regime filters, sort, and an ownership scope (All · Created by me · Joined by me).
- Create NDO from the group page, NDO view, Join NDO, Associate with a group, Fork, Copy NDO link (also per card).
- Lifecycle transition for the initiator (the only mutable Layer 0 field), with transition history.
- Group features unchanged: copy invite link, member list.
Visible but "Coming next" (a "Soon" badge; clicking opens the same popup, built from one registry, and the user stays where they are):
| Area | Items |
|---|---|
| Perspectives | Agent, Intelligence, Work (switcher entries) |
| NDO view tabs | Resources, Governance, Composition, Activity (Overview is the live tab) |
| Access actions | Use, Borrow, Offer, Transfer, Transfer custody (Offer's popup offers a shortcut to Create NDO) |
| Service processes | Transport, Store, Repair |
| Governed transitions | A disabled "Advance stage" for non-initiators, explaining how governed transitions will work |
| Jump points | Clicking an agent (initiator, group member) explains the future jump to the Agent Perspective and the return path |
The registry also holds copy for the Unyt stake step of Fork and for the Source view; neither is wired to a control yet.
Why the access actions and processes are listed: VfAction and the Transport / Repair / Storage roles already model them in the backend (see resources.md, governance.md); the UI shows them so people see how the NDO will eventually be used.
Open questions: popup versus inline explainer per tab; whether Offer should go straight to the creation form; whether Layer 1/2 forms stay reachable behind a dev flag for internal testing.
Port to the nondominium app (not yet)
Decision: the prototype stays in
nondominium-design-systemuntil the design is validated. Do not port yet; these are the ToDos for when it is.
- Perspectives host in the Group page — replace the
NdoBrowserblock inGroupView.sveltewithGroupPerspectivesView(switcher + Resource Perspective); the Lobby is untouched. - State — add
currentPerspectivetoapp.context.svelte.ts(Resource only live; the trail comes with the full Perspectives work). - NDO view — tabs (Overview live; the others open the Coming-next popup), access-action and process buttons, Copy NDO link, locked "Advance stage" for non-initiators, agent jump-point popups.
- Shared copy — adopt the
coming-nextregistry andComingNextPopup/SoonBadgefrom@nondominium/ndo-ui; no per-component copy. - Card actions — per-card "Copy link" and the scope chips (Created by me / Joined by me) need
myAgentKeyand the joined list from the app context. - Replica re-sync — after the port, re-copy the app files into
src/lib/replica/in the design system socheck:fidelitypasses (the replica is a copy and is never improved by hand). - E2E — adjust the Playwright specs under
ui/tests/for create NDO, join, associate, fork, and add cases for the Coming-next popups, scope chips and the locked transition.
Post MVP
This section is about UI improvements after a functional MVP. The visual language below (layers, entities, proximity) is applied on top of the Perspectives defined above.
Core Design Philosophy
- Perspective-centric design: Interface adapts to agent's role and context
- Landscape as fundamental pattern: Natural spatial metaphor for resource organization
- Parallax 3D depth: Isometric perspective with 3-4 layers creating intuitive navigation
- Horizontal navigation: Primary movement left-right through parallax layers
- Intuitive interaction: Natural gestures and spatial awareness
- Symbolic representation: Resources/entities as round icons with peripheral state indicators
Three-Layer Depth System
🔬 Micro Layer (z-index: 300)
- Purpose: Detailed resource view (modal/overlay)
- Trigger: Click/tap on resource entity
- Opacity: 1.0, no blur
- Content: Full resource details, actions, history
- Navigation: Close to return to meso, or jump to related entities
🎯 Meso Layer (z-index: 200) - DEFAULT
- Purpose: Contextual workspace, agent's primary focus
- Scope: Local context relevant to agent's role/location
- Opacity: 0.9-1.0, no blur
- Content: 10-20 most relevant resources/entities (4-5 on screen, but we can circle them while staying in meso view)
- Interaction: Full interactive capabilities
🌍 Macro Layer (z-index: 100)
- Purpose: Global landscape, broader system context
- Scope: All entities less directly related to agent
- Opacity: 0.4-0.7, 2-4px blur
- Content: Overview of entire resource network
- Interaction: Hover preview, click to refocus meso layer
Visual Design System
Entity Representation
.resource-entity {
shape: circle | rounded-square | hexagon;
size: calc(proximity_score * base_size);
background: resource_type_color;
border: 2px solid state_color;
/* Peripheral indicators */
.state-badges: action_indicators[];
.glow-effect: urgency_level;
.pulse-animation: activity_state;
}
State Indicators
- 🟢 Available/Healthy: Ready for use, optimal condition
- 🟡 Needs Attention: Maintenance required, low priority
- 🔴 Critical/Blocked: Urgent action needed, system risk
- 🔵 In Use/Reserved: Currently engaged, not available
- ⚪ Dormant/Archive: Inactive, background status
- 🟣 Pending: Awaiting approval/assignment
Concentric Layout Pattern
- Center: Agent's current focus/role context
- Inner Ring: High-relevance resources (meso layer)
- Outer Ring: Background context (macro layer, blurred)
- Smooth Transitions: Elastic zoom and pan between layers
Proximity Calculation Algorithm
function calculateProximity(entity, agent_context) {
const weights = {
role_relevance: 0.4, // Match to agent's role/skills
geographic_distance: 0.2, // Physical/logical proximity
interaction_frequency: 0.2, // Historical engagement
temporal_urgency: 0.1, // Time-sensitive needs
governance_access: 0.1, // Permission/capability level
};
const proximity_score =
weights.role_relevance * entity.roleMatch(agent_context.role) +
weights.geographic_distance *
(1 - entity.distance(agent_context.location)) +
weights.interaction_frequency *
entity.interactionHistory(agent_context.id) +
weights.temporal_urgency * entity.urgencyScore() +
weights.governance_access * entity.accessLevel(agent_context.capabilities);
return Math.min(1.0, Math.max(0.0, proximity_score));
}
// Layer assignment
function assignLayer(proximity_score) {
if (proximity_score >= 0.7) return "micro_candidate";
if (proximity_score >= 0.4) return "meso";
return "macro";
}
Dynamic View Composition
Filter System
const meso_composition = {
keywords: ["maintenance", "urgent", "mechanical"],
tags: ["infrastructure", "public"],
date_range: "last_30_days",
proximity_threshold: 0.6,
max_entities: 20,
sort_by: "urgency_desc",
};
Adaptive Personalization
- Learning: System learns from agent's interaction patterns
- Preferences: Custom color themes, entity sizes, layout density
- Context Switching: Quick perspective toggles based on current task
Navigation Patterns
Primary Navigation (Horizontal)
- Left/Right Scrolling: Move through perspective layers
- Parallax Effect: Different scroll speeds per layer (macro slower than meso)
- Momentum Scrolling: Natural deceleration with bounce effects
- Breadcrumb Trail: Visual path showing navigation history
Secondary Navigation (Vertical)
- Zoom In: Meso → Micro (entity details)
- Zoom Out: Meso → Macro (broader landscape)
- Elastic Transitions: Smooth scaling with momentum physics
- Quick Return: One-click return to default meso view
Interaction Gestures
- Click/Tap: Open micro view or refocus meso
- Double-Click: Quick action (depends on entity type)
- Long Press: Context menu with available actions
- Pinch/Zoom: Layer transition control
- Swipe: Navigate between related entities
Use Case Examples
🌲 Forester Agent Example
Role: Forest maintenance specialist Meso View: Trees/forest sections under their responsibility
- Focus: Trees needing attention (disease, damage, scheduled maintenance)
- Layout: Geographic clusters by forest section
- Priority: Health status and maintenance urgency
Micro View: Individual tree details
- Health metrics, species info, maintenance history
- Available actions: Schedule maintenance, mark for removal, update status
Macro View: Entire forest ecosystem
- All forest resources beyond immediate responsibility
- Ability to see broader patterns and request assistance
🔧 Maintenance Coordinator Example
Role: Equipment and infrastructure maintenance Meso View: Equipment requiring maintenance within their jurisdiction
- Priority filter: Critical systems first, then scheduled maintenance
- Status indicators: Operational, needs attention, critical failure
- Timeline view: Maintenance schedules and deadlines
🏗️ Resource Allocation Agent Example
Role: Optimizing resource distribution across projects Meso View: Available resources and current allocations
- Filter by: Resource type, availability, location, project needs
- Visual flow: Resource movement between projects
- Optimization indicators: Efficiency metrics, bottlenecks
Responsive Design Considerations
Mobile Adaptation
- Single Layer Focus: Simplified view with layer swipe transitions
- Larger Touch Targets: Minimum 44px touch areas for entities
- Simplified Indicators: Essential state information only
- Gesture Navigation: Swipe for layers, tap for details
Desktop Enhancement
- Full Parallax Experience: All three layers simultaneously visible
- Keyboard Shortcuts: Layer navigation, entity selection, quick actions
- Multi-Selection: Batch operations on multiple entities
- Rich Hover States: Detailed tooltips and preview information
Accessibility Features
- High Contrast Mode: Enhanced visual differentiation
- Screen Reader Support: Semantic markup and ARIA labels
- Keyboard Navigation: Full functionality without mouse
- Motion Preferences: Respect user's motion sensitivity settings
Technical Implementation Notes
- Rendering: Canvas-based or WebGL for smooth 3D transitions
- Data Binding: Real-time updates from Holochain DHT
- Performance: Virtualized rendering for large entity sets
- Caching: Intelligent prefetching based on proximity scores
- State Management: Maintain layer states and user preferences
Community-Specific Implementations
Above the base Perspectives, a group or network can use Nondominium for its own purposes (e.g. water stewardship, where Source becomes central; an artists' network). The universal ValueFlows vocabulary stays underneath as the background engine, but the UI adapts to each community's culture, because a single universal language alienates users. Adaptation happens in this order:
- Terminology: a per-community dictionary of how processes and resources are named (with translation to the ValueFlows base).
- Workflows: how processes chain together (artists and engineers do not sequence work the same way).
- Visuals: look and feel.
This builds on the modular interface already formalized by the Surface / Surface Attachment (capability slots); the link between those slots and community-specific implementations remains to be specified.
Future Reflection: Higher-Level Interoperability (parked)
Not part of the current UI scope. Open questions for later:
- Context-aware events: the same gesture can be economic in one context and relational in another (e.g. care work at a hospital vs. at home). How can a UI and its events know their context, keeping a clear but permeable boundary between contexts? AD4M's perspectives and languages are a candidate substrate.
- Other ontologies alongside Nondominium: e.g. a family-oriented layer (FamilyDAO, genogram-based) as a separate project that may exchange data with the economic layer.
- Limits of contribution tracking in relational settings (families, eco-villages, housemates): too much economic logic can damage relationships.
Complete Resource Specification — Design Record
Status: Phase B implemented (2026-08-11). Predicate library (
constraints.rs), typedRuleData, Layer-0 pointers / denormalized fields onGovernanceRule/ResourceSpecification/Commitment/EconomicEvent, Hard integrity enforcement, Soft advisory via parallelevaluate_state_transition, and dry-run query fns are in code. Remaining open items from §5: funnel vs parallel (defaulted to parallel; TODO documented),Networkscope ==Publicat anchors, one-spec-per-NDO uniqueness best-effort only.This document is Phase B of the split named in
zome_resource_integrity::validate_create_nondominium_identity— "Phase A: all seven PropertyRegime variants are accepted at creation... Regime-driven governance enforcement... is Phase B." Historical design rationale below is retained; Current code status lines mark what landed.
Relates to: ndo_prima_materia.md, resources.md (§4.4.3–§4.4.6, §6), governance.md (§1.2, §4.1), specifications.md (§3.2, §5)
Sources cross-checked: crates/shared/src/types.rs, crates/shared/src/lib.rs, dnas/nondominium/zomes/integrity/zome_resource/src/lib.rs, dnas/nondominium/zomes/integrity/zome_gouvernance/src/lib.rs, dnas/nondominium/zomes/coordinator/zome_gouvernance/src/{commitment,economic_event}.rs
0. Why a predicate library instead of a rules matrix
The starting problem: a resource's classification (ResourceNature, PropertyRegime, lifecycle maturity) should determine which governance rules and actions are coherent — e.g. Move doesn't apply to a Digital resource; a Nondominium resource can't have a rule that assigns ownership. The first instinct — a lookup table of (nature, regime, action) → allowed — was rejected: it forces every future addition to touch an ever-growing matrix, it can't express "warn but allow" vs. "block," and it duplicates the same regime/nature checks the enums already half-encode via helper methods like is_uncapturable().
The chosen approach instead: small, composable constraint predicates — pure functions of (classification, proposed thing) → Option<violation> — assembled at each call site. This is the CDD/COP position that governance coherence is an emergent property of composing simple rules, not a property you can pre-enumerate in a table. New predicates append to a list; nothing else changes.
1. Decision log
Each entry: the decision, the reasoning, what was rejected and why, and current code status.
1.1 Rivalry derivation moves from PropertyRegime to ResourceNature
Decision. is_rivalrous() is removed from PropertyRegime (or demoted to a documented "default posture" helper, not authoritative). Authoritative rivalry derivation becomes a method on ResourceNature, with an explicit Option<Rivalry> override field for the cases nature gets wrong.
Reasoning. resources.md §4.4.3 is explicit that goods-type properties (rivalry, excludability) and property regime are orthogonal: "goods types exist independently of property regimes... ResourceNature and Rivalry describe the intrinsic characteristics of the resource. PropertyRegime describes the chosen governance arrangement." The current code contradicts its own documentation: PropertyRegime::is_rivalrous() classifies Nondominium as categorically non-rivalrous. That's wrong for a physical Nondominium resource — a community 3D printer under a Nondominium regime is still rivalrous; only one agent can print at a time. ResourceNature is a much better predictor: physical/hybrid things are rivalrous by default, digital/information things aren't. Service is genuinely ambiguous (a consultation slot is rivalrous; documented advice is not) — hence the override.
Rejected alternative. Keep deriving from PropertyRegime, treat the Nondominium-physical case as an acceptable simplification. Rejected because it's not a simplification, it's an actual falsehood the moment a physical Nondominium resource exists, which the roadmap explicitly anticipates (shared physical tools under Nondominium governance are a first-class use case, not an edge case).
Schema.
#![allow(unused)] fn main() { // crates/shared/src/types.rs #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] pub enum Rivalry { Rivalrous, NonRivalrous } impl ResourceNature { pub fn default_rivalry(&self) -> Rivalry { match self { ResourceNature::Physical | ResourceNature::Hybrid => Rivalry::Rivalrous, ResourceNature::Digital | ResourceNature::Information => Rivalry::NonRivalrous, ResourceNature::Service => Rivalry::NonRivalrous, // ambiguous default; override expected } } } }
NondominiumIdentity gains rivalry_override: Option<Rivalry> — immutable after creation, same tier as property_regime/resource_nature (not one of the three conditionally-mutable fields lifecycle_stage/successor_ndo_hash/hibernation_origin already documented in the struct's own comments).
Current code status. ✅ Implemented. Rivalry enum, ResourceNature::default_rivalry(), demoted PropertyRegime::is_rivalrous() docs, and immutable rivalry_override on NondominiumIdentity (+ create_ndo / shared-types).
1.2 No Transferability field — decompose into what's actually regime-gated
Decision. Do not add a stored Transferability field. Ownership-transfer permission is already answered by PropertyRegime::permits_ownership_transfer()/is_uncapturable() (already in code, currently unused — see the _regime_semantics_hook placeholder). Custody-transfer, use-rights-transfer, and benefit-transfer remain ordinary governance-rule policy, not resource classification.
Reasoning. Checking resources.md §4.4.5's transfer-rights matrix cell by cell: across all seven PropertyRegime variants, only the ownership column is actually regime-determined (Private/Collective permit it, the other five don't). Custody, use-rights, and benefit transfer are "✅" for every single regime in that matrix — meaning regime carries zero discriminating information for those three transfer types. A Transferability field encoding four transfer-type flags would be storing three constants and one already-derivable fact.
Rejected alternative. A TransferabilityProfile { ownership, custody, use_rights, benefit } struct on Layer 0. Rejected because three of its four fields would never vary — that's not a classification, that's dead weight that looks like it means something and doesn't.
Current code status. Correctly not implemented (nothing to undo — this was a "don't build it" decision, and nothing has been built).
1.3 The predicate library lives in crates/shared, ungated
Decision. New module crates/shared/src/constraints.rs, added to crates/shared/src/lib.rs outside the #[cfg(feature = "coordinator")] gate (same tier as types and the existing pub mod validation), so it compiles for integrity zomes, coordinator zomes, and native test crates with zero hdk/hdi dependency.
Reasoning. Confirmed against the actual lib.rs: validation (the closest existing analog — pure string/URL/email checks) is deliberately ungated; everything gated behind coordinator uses hdk::prelude::* for cross-zome calls. The constraint predicates need to run inside zome_resource_integrity's validate() callback, which cannot depend on hdk (integrity zomes use hdi only) — so they must be pure Rust with no hdk/hdi imports, following exactly the validation module's existing pattern. This also means the same function, unchanged, becomes reusable later (Stage 6) as the implementation behind a UI dry-run query, and is trivially unit-testable without any Holochain test harness.
Schema.
#![allow(unused)] fn main() { // crates/shared/src/constraints.rs — pure, no hdk/hdi imports use crate::types::{PropertyRegime, ResourceNature, LifecycleStage, Rivalry, VfAction}; #[derive(Clone, Debug, PartialEq)] pub struct ResourceClassification { pub resource_nature: ResourceNature, pub property_regime: PropertyRegime, /// `None` at call sites that haven't fetched it and don't need to (see §1.6). pub lifecycle_stage: Option<LifecycleStage>, pub rivalry_override: Option<Rivalry>, } impl ResourceClassification { pub fn effective_rivalry(&self) -> Rivalry { self.rivalry_override.clone().unwrap_or_else(|| self.resource_nature.default_rivalry()) } } #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub enum ConstraintSeverity { Hard, Soft } #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct ConstraintViolation { pub rule_id: &'static str, pub message: String, pub severity: ConstraintSeverity, } pub fn has_hard_violation(violations: &[ConstraintViolation]) -> bool { violations.iter().any(|v| v.severity == ConstraintSeverity::Hard) } }
Current code status. ✅ Implemented. crates/shared/src/constraints.rs (ungated) with ResourceClassification, ConstraintSeverity, ConstraintViolation, has_hard_violation, and action/rule predicates.
1.4 Hard vs Soft maps to integrity vs coordinator, not zome_resource vs zome_gouvernance
Decision. Severity determines which layer enforces a predicate, not which zome:
- Hard → integrity-zome
validate(), wherever the relevant entry type actually lives. Unconditional, cryptographically enforced, can't be bypassed by calling a different coordinator function. - Soft → coordinator function only.
ValidateCallbackResultis a binaryValid/Invalid(String)— there is structurally no way for an integrity callback to return "accepted, but here's a warning." Only a coordinator return type can carry non-blocking feedback.
Reasoning. This was a real course-correction from an earlier "Hard→zome_resource, Soft→zome_gouvernance" framing that doesn't survive contact with the actual entry ownership: zome_resource has no entry type that carries a VfAction (Commitment/EconomicEvent are zome_gouvernance entries per the confirmed integrity zome). So a Hard capture-resistance check on an action (check_capture_resistance, below) is necessarily enforced inside zome_gouvernance_integrity, not zome_resource. What does land in zome_resource is the Hard check on a rule definition (GovernanceRule is confirmed to be a zome_resource entry). The zome split observed in earlier discussion was a byproduct of this deeper rule, not the rule itself — restating it this way generalizes correctly to new predicates without re-deriving the reasoning each time.
Current code status. N/A (this is an architectural principle, not code).
1.5 RuleData replaces rule_type: String + rule_data: String
Decision. GovernanceRule.rule_type: String and rule_data: String are replaced by a single tagged enum rule_data: RuleData, with GovernanceRuleType derived from the enum's variant via a rule_type() method rather than stored separately.
Reasoning. The confirmed current validate_create_governance_rule only checks that both strings are non-empty — there is no schema enforcement at all, exactly matching resources.md's own gap listing ("GovernanceRule.rule_data is untyped JSON string... no schema enforcement, no tooling support, no peer validation of rule semantics"). A separate stored rule_type field alongside a variant-per-rule-type RuleData enum would be two sources of truth for the same fact, permanently — the enum's own discriminant already is the type.
Schema.
#![allow(unused)] fn main() { // crates/shared/src/rule_data.rs — ungated, pure #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] pub enum GovernanceRuleType { AccessRequirement, UsageLimit, TransferCondition, MaintenanceSchedule } #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] pub enum RuleData { AccessRequirement(AccessRequirementData), UsageLimit(UsageLimitData), TransferCondition(TransferConditionData), MaintenanceSchedule(MaintenanceScheduleData), } impl RuleData { pub fn rule_type(&self) -> GovernanceRuleType { match self { RuleData::AccessRequirement(_) => GovernanceRuleType::AccessRequirement, RuleData::UsageLimit(_) => GovernanceRuleType::UsageLimit, RuleData::TransferCondition(_) => GovernanceRuleType::TransferCondition, RuleData::MaintenanceSchedule(_) => GovernanceRuleType::MaintenanceSchedule, } } } #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] pub enum Accessibility { Free, Credentialed, Gated } #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] pub struct AccessRequirementData { pub accessibility: Accessibility, pub required_role: Option<String>, pub min_affiliation: Option<String>, } #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] pub struct UsageLimitData { pub max_duration_hours: Option<f64>, pub max_quantity_per_period: Option<f64>, pub period_days: Option<u32>, } #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] pub enum TransferType { Ownership, Custody, UseRights, Benefit } #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] pub struct TransferConditionData { pub transfer_type: TransferType, pub requires_validation: bool, pub validator_role: Option<String>, } #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] pub struct MaintenanceScheduleData { pub interval_days: u32, pub required_role: Option<String> } }
Current code status. ✅ Implemented. crates/shared/src/rule_data.rs with GovernanceRuleType, tagged RuleData, and payload structs; GovernanceRule.rule_data: RuleData.
1.6 GovernanceRule denormalizes Layer 0's immutable fields; the entry-vs-context split this forces
Decision. GovernanceRule gains ndo_identity_hash: ActionHash (direct pointer to Layer 0) plus denormalized copies of property_regime, resource_nature, and rivalry_override — all three chosen because they're immutable on NondominiumIdentity. lifecycle_stage is deliberately not denormalized because it's mutable and would drift.
Reasoning. This lets validate_create_governance_rule run check_rule_data_permitted with zero DHT reads — pure computation over the entry's own fields. Denormalizing a mutable field onto a different permanent entry would create exactly the staleness risk Stage 3 was designed to avoid (the copy silently becomes wrong the moment the source changes and nothing re-syncs it). This is why ResourceClassification.lifecycle_stage had to become Option<LifecycleStage> (§1.3) rather than required: check_rule_data_permitted's two current checks (ownership-transfer permission, gated-accessibility-vs-Nondominium) only read property_regime — they never needed lifecycle_stage at all, so forcing this call site to fetch it just to fill a required struct field would reintroduce a DHT read that buys nothing.
A generalization worth stating explicitly, since it recurred at every later stage: denormalize only immutable fields onto a different entry; read mutable ones live, at the point of validation, via must_get_valid_record. This rule was re-derived independently for ResourceSpecification (§1.7) and for Commitment/EconomicEvent (§1.8) — it's the load-bearing principle of this whole document's enforcement design, not a one-off Stage 3 detail.
Schema.
#![allow(unused)] fn main() { pub struct GovernanceRule { pub rule_data: RuleData, // was: rule_type: String, rule_data: String pub enforced_by: Option<String>, pub ndo_identity_hash: ActionHash, // NEW pub property_regime: PropertyRegime, // NEW — denormalized, immutable source pub resource_nature: ResourceNature, // NEW — denormalized, immutable source pub rivalry_override: Option<Rivalry>, // NEW — denormalized, immutable source } }
Predicate + call site.
#![allow(unused)] fn main() { // crates/shared/src/constraints.rs pub fn check_rule_data_permitted(ctx: &ResourceClassification, rule_data: &RuleData) -> Vec<ConstraintViolation> { match rule_data { RuleData::TransferCondition(t) if t.transfer_type == TransferType::Ownership => { if ctx.property_regime.permits_ownership_transfer() { return vec![]; } vec![ConstraintViolation { rule_id: "ownership_transfer_not_permitted_by_regime", message: format!("{:?} does not permit ownership-transfer rules.", ctx.property_regime), severity: if ctx.property_regime.is_uncapturable() { ConstraintSeverity::Hard } else { ConstraintSeverity::Soft }, }] } RuleData::AccessRequirement(a) if a.accessibility == Accessibility::Gated => { if ctx.property_regime.is_uncapturable() { vec![ConstraintViolation { rule_id: "gated_access_contradicts_permissionless_regime", message: "Nondominium resources must remain permissionless (REQ-RES-01); \ 'Gated' access creates a discretionary chokepoint.".to_string(), severity: ConstraintSeverity::Soft, }] } else { vec![] } } _ => vec![], } } }
#![allow(unused)] fn main() { // zome_resource_integrity/src/lib.rs — validate_create_governance_rule, revised fn validate_create_governance_rule(rule: &GovernanceRule, _author: &AgentPubKey) -> ExternResult<ValidateCallbackResult> { let ctx = ResourceClassification { resource_nature: rule.resource_nature.clone(), property_regime: rule.property_regime.clone(), lifecycle_stage: None, // not needed by current predicates; zero-DHT-read preserved rivalry_override: rule.rivalry_override.clone(), }; let violations = check_rule_data_permitted(&ctx, &rule.rule_data); if has_hard_violation(&violations) { let msg = violations.iter().filter(|v| v.severity == ConstraintSeverity::Hard) .map(|v| format!("[{}] {}", v.rule_id, v.message)).collect::<Vec<_>>().join("; "); return Ok(ValidateCallbackResult::Invalid(msg)); } Ok(ValidateCallbackResult::Valid) } }
Same shape must be added to validate_update_governance_rule, currently a no-op ("For Phase 1, allow updates").
Note on the "gated-accessibility-vs-Nondominium" check's severity. It's Soft, not Hard, deliberately: it's a declared-intent contradiction (someone wrote a Gated rule on a Nondominium resource), not a mechanically-verifiable-and-blockable fact the way ownership-transfer permission is (that one has a Hard branch specifically when the regime is is_uncapturable(), because cryptographic uncapturability really is a hard architectural guarantee the code can enforce; general non-Nondominium regime mismatches stay Soft because they're policy preferences, not architecture).
Current code status. ✅ Implemented. GovernanceRule carries ndo_identity_hash + denormalized immutable classification fields; create/update validators run check_rule_data_permitted and reject Hard violations.
1.7 Scope moves to Layer 1 (ResourceSpecification), not Layer 0 — and needs its own immutable pointer field
Decision. ResourceScope { Project, Network, Public } is a mutable field on ResourceSpecification, not NondominiumIdentity. ResourceSpecification also gains ndo_identity_hash: ActionHash (immutable after creation) and one new link type, NdoToSpecification (Layer 0 → Layer 1 only; no reverse link needed).
Reasoning — why Layer 1, not Layer 0 (as resources.md §6.1's own forward-map sketch originally placed it). Scope is revisable: a Project-scoped design tool can mature into a Public commons resource without anything about its foundational identity (nature, regime) changing. That's the same mutability profile as lifecycle_stage, not property_regime/resource_nature — Layer 0 is reserved for facts frozen at creation (per the file's own extensive immutability enforcement in validate_update_nondominium_identity); Scope doesn't belong there.
Reasoning — why ndo_identity_hash must be a field, not just resolved via the link. Integrity zomes should not rely on get_links for anything that needs to be deterministic — a validating peer may not yet have gossiped every relevant link, so link-based lookups are a known, accepted-but-real limitation for validation-time correctness. must_get_valid_record(some_hash) on a hash known in advance (a field) is the sanctioned deterministic read; get_links is not. Since the lifecycle-gate check below (§1.7.1) needs to reliably resolve "which NDO does this spec belong to" during ResourceSpecification's own entry validation, that pointer has to already be sitting in the entry, not discoverable only via a link traversal.
Given the field exists, a reverse SpecificationToNdo link would be redundant — the field already answers "given a spec, find its NDO" with one get(), cheaper than a link traversal. Only one link direction is needed: NdoToSpecification (Layer 0 → Layer 1), for "given an NDO, find its spec."
1.7.1 New constraint: Layer 1 can't outrun Layer 0's own claimed maturity
Decision. Creating a ResourceSpecification is rejected (Hard) if the linked NDO's lifecycle_stage is Ideation, Hibernating, Deprecated, or EndOfLife.
Reasoning. LifecycleStage::Specification is already documented (in the enum's own doc comments and resources.md) as the stage at which "Layer 1 activating." Allowing a brand-new ResourceSpecification to attach to an Ideation-stage NDO would let Layer 1 exist for a resource that hasn't itself claimed to be ready for it — directly contradicting the three-layer model's entire premise that coordination overhead should track actual maturity, not the reverse. Excluding Hibernating/Deprecated/EndOfLife too: Hibernating's own semantics ("Layer 0 active; Layers 1+2 dormant but recoverable") implies Layer 1 should already exist before hibernating, not be newly created during it; Deprecated/EndOfLife are terminal, so activating a new specification for a resource already being retired doesn't make sense.
Where this validates, and why not at the CreateLink op. An earlier pass considered validating this at NdoToSpecification's CreateLink op. Rejected in favor of validating inside validate_create_resource_spec (an entry-creation validator) instead, for two concrete reasons: (1) this file's own OpRecord::CreateLink { .. } arm is currently an explicit // TODO(next-pr) stub with unhandled field shape — building on top of unfinished, unverified plumbing adds risk for no benefit; (2) validating at entry-creation reuses the per-entry-type dispatch this file already has for every other entry (validate_create_resource_spec, validate_create_economic_resource, etc.), rather than introducing a second, structurally different validation path.
Schema and validator.
#![allow(unused)] fn main() { #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] pub enum ResourceScope { Project, Network, Public } pub struct ResourceSpecification { pub name: String, pub description: String, pub category: String, pub image_url: Option<String>, pub tags: Vec<String>, pub is_active: bool, pub scope: ResourceScope, // NEW — mutable pub ndo_identity_hash: ActionHash, // NEW — immutable after creation } }
#![allow(unused)] fn main() { fn validate_create_resource_spec(spec: &ResourceSpecification, _author: &AgentPubKey) -> ExternResult<ValidateCallbackResult> { // ...existing name/description checks (unchanged)... let ndo_record = must_get_valid_record(spec.ndo_identity_hash.clone())?; let ndi: NondominiumIdentity = ndo_record.entry().to_app_option() .map_err(|e| wasm_error!(WasmErrorInner::Guest(format!("{:?}", e))))? .ok_or(wasm_error!(WasmErrorInner::Guest("Linked NDO entry not found".into())))?; let ineligible = matches!(ndi.lifecycle_stage, LifecycleStage::Ideation | LifecycleStage::Hibernating | LifecycleStage::Deprecated | LifecycleStage::EndOfLife); if ineligible { return Ok(ValidateCallbackResult::Invalid(format!( "Cannot activate Layer 1 while the NDO is {:?}.", ndi.lifecycle_stage ))); } Ok(ValidateCallbackResult::Valid) } }
validate_update_resource_spec (currently a no-op, "For Phase 1, allow updates") needs one addition: reject any update where new_entry.ndo_identity_hash != original.ndo_identity_hash — a spec must never be silently reparented to a different NDO. scope and the other fields remain freely updatable for Phase 1, consistent with the existing comment's stated intent.
A caveat to state plainly, not paper over. Should an NDO ever have more than one ResourceSpecification? No — subsequent revisions should go through the existing ResourceSpecificationUpdates link chain, not a second create_resource_specification call. Enforcing "no second spec for this NDO" mechanically would need a get_links-based uniqueness check inside validation, which carries the same non-determinism caveat as above — a best-effort deterrent, not a guarantee. Worth documenting as a known, accepted limitation rather than claiming airtight uniqueness.
1.7.2 Scope's discovery consequence is partial, and honestly so
Decision. create_resource_specification conditionally skips adding the spec to the global AllResourceSpecifications anchor when scope == Project. That's the full extent of what zome_resource alone can enforce.
Reasoning. The fuller promise in resources.md §4.7 — "a project-scoped resource should only be visible to project participants" — reaches into the Group DNA, a physically separate DNA from nondominium (per ui_architecture.md §7.2, group↔NDO association is a SoftLink created from the UI layer, ndo.service.ts, on the group clone cell, not on anything zome_resource owns). No DNA can validate or enforce facts about a different DNA's link state. So Scope::Project's real meaning here is: real stored data + local anchor-gating inside this DNA + an advisory signal the UI/service layer is expected to respect when deciding whether to also register in the Lobby-wide view — not a guarantee zome_resource makes unilaterally. Network scope is honestly weaker still: no network-layer governance/federation anchor exists yet (governance.md §4.1's own gap table confirms this), so at the DHT-anchor level it currently behaves identically to Public until that infrastructure exists.
Current code status. ✅ Implemented. ResourceScope on ResourceSpecification; immutable ndo_identity_hash; NdoToSpecification link; lifecycle-gate + no-reparent validators; Project skips global anchor (Network behaves as Public at anchors — documented gap).
1.8 Action-execution enforcement needs a Layer 0 pointer on Commitment/EconomicEvent, and a cross-zome interface that doesn't exist yet
Decision. Commitment and EconomicEvent (both zome_gouvernance entries) each gain ndo_identity_hash: ActionHash. The Hard-severity action predicates (check_capture_resistance, check_transport_applicability, composed as check_action_permitted) are enforced inside zome_gouvernance_integrity's validate_create_commitment/validate_create_economic_event (new validators — currently these entry types have no dedicated validation logic at all beyond PrivateParticipationClaim/NdoHardLink/Contribution/Agreement, confirmed in the integrity validate() dispatch). Soft-severity results additionally surface through a new GovernanceTransitionRequest/GovernanceTransitionResult coordinator-level interface, which — confirmed against commitment.rs/economic_event.rs — must be built from scratch, not "wired into."
Reasoning for the field. Same principle as §1.6/§1.7: resolving classification via EconomicResource → ResourceSpecification.ndo_identity_hash → NondominiumIdentity would be a two-hop chain through a link (SpecificationToResource) that, per the confirmed current struct, EconomicResource doesn't even carry as a field — the relationship exists only as a link, which is worse for integrity-time determinism than the already-flagged link-reliance concern in §1.7. Giving Commitment/EconomicEvent their own direct ndo_identity_hash, mirroring GovernanceRule and ResourceSpecification, avoids the multi-hop resolution and keeps every place that needs Layer-0 context consistent: a direct pointer, not an inferred chain.
Predicates (unchanged from earlier design, now correctly scoped to zome_gouvernance_integrity).
#![allow(unused)] fn main() { pub fn check_transport_applicability(ctx: &ResourceClassification, action: &VfAction) -> Option<ConstraintViolation> { let is_move = matches!(action, VfAction::Move); let is_non_physical = matches!(ctx.resource_nature, ResourceNature::Digital | ResourceNature::Information); if is_move && is_non_physical { return Some(ConstraintViolation { rule_id: "no_transport_for_non_physical_nature", message: format!("Transport (Move) does not apply to a {:?} resource.", ctx.resource_nature), severity: ConstraintSeverity::Soft, }); } None } pub fn check_capture_resistance(ctx: &ResourceClassification, action: &VfAction) -> Option<ConstraintViolation> { if !ctx.property_regime.is_uncapturable() { return None; } let forbidden = matches!(action, VfAction::Transfer | VfAction::Consume | VfAction::Lower); if forbidden { return Some(ConstraintViolation { rule_id: "nondominium_no_unilateral_capture", message: format!("{:?} is not permitted on a Nondominium resource (REQ-RES-03).", action), severity: ConstraintSeverity::Hard, }); } None } pub fn check_action_permitted(ctx: &ResourceClassification, action: &VfAction) -> Vec<ConstraintViolation> { [check_capture_resistance(ctx, action), check_transport_applicability(ctx, action)] .into_iter().flatten().collect() } }
Integrity enforcement (new — both Commitment and EconomicEvent, deliberately, not just events).
#![allow(unused)] fn main() { // zome_gouvernance_integrity — new validators, wired into the existing OpEntry::CreateEntry dispatch fn validate_create_economic_event(event: &EconomicEvent, _author: &AgentPubKey) -> ExternResult<ValidateCallbackResult> { let ndi = fetch_ndo_classification(&event.ndo_identity_hash)?; // helper: must_get_valid_record + decode let hard: Vec<_> = check_action_permitted(&ndi, &event.action).into_iter() .filter(|v| v.severity == ConstraintSeverity::Hard).collect(); if !hard.is_empty() { return Ok(ValidateCallbackResult::Invalid( hard.iter().map(|v| format!("[{}] {}", v.rule_id, v.message)).collect::<Vec<_>>().join("; ") )); } Ok(ValidateCallbackResult::Valid) } // validate_create_commitment: identical shape, applied to Commitment.action }
Applying the Hard check to Commitment (intent) as well as EconomicEvent (what happened) is deliberate: blocking the intent to Transfer a Nondominium resource is strictly better than letting the commitment through and only failing at fulfillment — this is exactly the "take away the possibility of undesirable action alternatives" embedded-governance principle already stated in governance.md §1.2.
Coordinator-level Soft feedback — genuinely new interface, not existing plumbing.
#![allow(unused)] fn main() { // zome_gouvernance/src/lib.rs (io types) — new pub struct GovernanceTransitionRequest { pub action: VfAction, pub resource: EconomicResource, pub ndo_identity_hash: ActionHash, pub requesting_agent: AgentPubKey, pub context: TransitionContext, } pub struct GovernanceTransitionResult { pub success: bool, pub new_resource_state: Option<EconomicResource>, pub economic_event: Option<EconomicEvent>, pub validation_receipts: Vec<ValidationReceipt>, pub rejection_reasons: Option<Vec<String>>, pub next_steps: Option<Vec<String>>, pub advisory_warnings: Option<Vec<String>>, // NEW — Soft violations; distinct from next_steps, // which implies the caller must still act } #[hdk_extern] pub fn evaluate_state_transition(request: GovernanceTransitionRequest) -> ExternResult<GovernanceTransitionResult> { let ndi: NondominiumIdentity = nondominium_shared::call_resource_zome("get_ndo", &request.ndo_identity_hash)?; let ctx = ResourceClassification { resource_nature: ndi.resource_nature.clone(), property_regime: ndi.property_regime.clone(), lifecycle_stage: Some(ndi.lifecycle_stage.clone()), rivalry_override: ndi.rivalry_override.clone(), }; let (hard, soft): (Vec<_>, Vec<_>) = check_action_permitted(&ctx, &request.action) .into_iter().partition(|v| v.severity == ConstraintSeverity::Hard); if !hard.is_empty() { return Ok(GovernanceTransitionResult { success: false, rejection_reasons: Some(hard.iter().map(|v| format!("[{}] {}", v.rule_id, v.message)).collect()), new_resource_state: None, economic_event: None, validation_receipts: vec![], next_steps: None, advisory_warnings: None, }); } // ...rule evaluation / event generation (net-new; nothing to reuse yet)... Ok(GovernanceTransitionResult { success: true, advisory_warnings: (!soft.is_empty()).then(|| soft.iter().map(|v| format!("[{}] {}", v.rule_id, v.message)).collect()), rejection_reasons: None, next_steps: None, new_resource_state: None, economic_event: None, validation_receipts: vec![], // filled in by real logic }) } }
external_local_call/call_resource_zome already exist in crates/shared/src/lib.rs (confirmed) — the cross-zome call above uses real, existing plumbing, not a hypothetical.
Open question this document cannot resolve on its own. propose_commitment, claim_commitment, and log_economic_event (confirmed current signatures) return plain { commitment_hash, commitment } / { event_hash, event, ppr_claims } structs, not GovernanceTransitionResult. If these remain the actual entry points agents call (as opposed to routing everything through evaluate_state_transition), advisory_warnings has no return-type home on those paths, and each would need the same { ..., advisory_warnings } extension individually. The Hard gate is safe regardless (it lives in integrity validation, which fires no matter which coordinator function got there) — only the Soft/advisory-warning UX depends on this. Resolving it requires a decision on whether evaluate_state_transition becomes the single funnel these existing functions call internally, or a parallel path — genuinely open, not something to resolve unilaterally here.
Current code status. ✅ Implemented. ndo_identity_hash on Commitment/EconomicEvent; create validators enforce Hard action predicates; GovernanceTransitionRequest/Result + parallel evaluate_state_transition; dry-run check_action_constraints / check_rule_data_constraints. Funnel of write paths remains open (TODO in transition.rs).
2. Consolidated schema diff (all stages, one view)
| Type | File | Change | Breaking? |
|---|---|---|---|
PropertyRegime | crates/shared/src/types.rs | Remove/demote is_rivalrous() | No (method removal — check all current callers first) |
ResourceNature | crates/shared/src/types.rs | Add default_rivalry() | No (additive method) |
(new) Rivalry | crates/shared/src/types.rs | New enum | N/A |
NondominiumIdentity | zome_resource_integrity | + rivalry_override: Option<Rivalry> | Yes — new required-shape field on an existing entry type (see §4) |
(new) ResourceClassification, ConstraintViolation, ConstraintSeverity | crates/shared/src/constraints.rs (new file) | New pure predicate library | N/A |
GovernanceRule | zome_resource_integrity | rule_type: String + rule_data: String → rule_data: RuleData; + ndo_identity_hash, property_regime, resource_nature, rivalry_override | Yes — field replacement, not additive |
(new) RuleData, GovernanceRuleType, payload structs | crates/shared/src/rule_data.rs (new file) | New typed rule schema | N/A |
ResourceSpecification | zome_resource_integrity | + scope: ResourceScope, ndo_identity_hash: ActionHash | Yes — new non-optional field |
(new) NdoToSpecification | zome_resource_integrity LinkTypes | New link type | No (additive to enum) |
Commitment | zome_gouvernance_integrity | + ndo_identity_hash: ActionHash | Yes |
EconomicEvent | zome_gouvernance_integrity | + ndo_identity_hash: ActionHash | Yes |
(new) GovernanceTransitionRequest/Result | zome_gouvernance coordinator | New cross-zome interface | N/A (new, not replacing) |
Five rows are marked breaking in a way that isn't a simple additive #[serde(default)]-style change (the pattern already used successfully for successor_ndo_hash/hibernation_origin on NondominiumIdentity) — because a non-optional ActionHash field has no sensible default, and rule_type/rule_data: String → RuleData is a type replacement, not an addition. This is Stage 7's actual subject — see §4, now resolved: direct breaking replacement, no migration shim, for all five.
3. Enforcement architecture summary
Rule-definition coherence (GovernanceRule.rule_data)
→ zome_resource_integrity::validate_create/update_governance_rule
→ check_rule_data_permitted(ctx, rule_data) [zero DHT reads; ctx built from denormalized fields]
→ Hard → ValidateCallbackResult::Invalid (unconditional)
→ Soft → currently unsurfaced at this layer (integrity can't warn) — see §6 for the UI-facing route
Action-execution coherence (Commitment.action / EconomicEvent.action)
→ zome_gouvernance_integrity::validate_create_commitment/economic_event
→ check_action_permitted(ctx, action) [ctx built via must_get_valid_record(ndo_identity_hash)]
→ Hard → ValidateCallbackResult::Invalid (unconditional; fires regardless of coordinator entry point)
→ Soft → not blocked here (same integrity-callback limitation)
zome_gouvernance coordinator::evaluate_state_transition (NEW)
→ same check_action_permitted, same ctx (fetched via cross-zome call to zome_resource::get_ndo)
→ Hard → GovernanceTransitionResult{ success: false, rejection_reasons }
→ Soft → GovernanceTransitionResult{ success: true, advisory_warnings }
4. Migration strategy for GovernanceRule and the other breaking changes — Stage 7
Reframing from the original single-entry-type framing. This started as "GovernanceRule's migration strategy" alone. Tracing every breaking change in §2 makes clear it's actually one policy decision needed for four struct changes (five, counting NondominiumIdentity.rivalry_override): GovernanceRule (§1.6), ResourceSpecification (§1.7), Commitment and EconomicEvent (§1.8) all add non-optional fields or replace typed fields with no sensible default — none of them can use the #[serde(default)] pattern already proven on NondominiumIdentity's successor_ndo_hash/hibernation_origin, because that pattern only works for genuinely additive optional fields, and three of these four changes aren't that shape. (rivalry_override: Option<Rivalry> on NondominiumIdentity could technically use the #[serde(default)] trick since it's already Option-shaped — but per the decision below, that trick is no longer needed for any of the five.)
The question this document could not resolve on its own. Whether any currently-running network — a shared dev conductor, a testnet, anything beyond ephemeral local hc sandbox instances that get reset — holds real GovernanceRule/ResourceSpecification/Commitment/EconomicEvent entries anyone needs preserved. Every one of these entry types is independently described in the project's own documentation as effectively unused placeholder scaffolding (GovernanceRule.rule_data explicitly called "completely untyped... ToDo" in resources.md; ResourceSpecification described as "legacy resource/spec links"; propose_commitment/log_economic_event carrying literal // TODO: In Phase 2 comments for basic authorization) — but that was an assumption about deployment state, not a fact derivable from source code alone, so it required explicit confirmation rather than being decided unilaterally.
Decision (confirmed 2026-08-11, developer-confirmed on this document, line above). No currently-running network holds GovernanceRule/ResourceSpecification/Commitment/EconomicEvent/NondominiumIdentity data that needs to be preserved. Option (a) — direct breaking replacement — is adopted for all five struct changes, executed together as one coordinated pre-launch schema revision rather than five separate migrations:
NondominiumIdentitygainsrivalry_override: Option<Rivalry>directly (§1.1).GovernanceRule.rule_type: String+rule_data: Stringare replaced in place byrule_data: RuleData, plus the three new denormalized fields (§1.6).ResourceSpecificationgainsscope: ResourceScopeandndo_identity_hash: ActionHashdirectly (§1.7).CommitmentandEconomicEventeach gainndo_identity_hash: ActionHashdirectly (§1.8).
Concretely, this means: no #[serde(default)] legacy-field shims, no dual-field transition period, no V2 entry types. Existing entries of these five types in any local hc sandbox DHT become undeserializable after the change — accepted, since none hold data worth preserving. This mirrors how NondominiumIdentity itself was introduced originally (a genuinely new struct via PR #80/#84), not a migration from something older.
Options (b) dual-field transition and (c) new V2 entry type remain documented (not deleted) as the fallback path for any future breaking change to these same five entry types, made after real data exists on a shared network. At that point this section's precedent no longer applies and the decision must be re-made against the then-current deployment state.
5. Carried-forward open items
Migration policy for the five breaking schema changes— resolved, see §4: option (a), direct breaking replacement, confirmed no real data at stake.- Whether
propose_commitment/claim_commitment/log_economic_eventroute throughevaluate_state_transitionor remain parallel paths — defaulted to parallel in Phase B; Soft UX usesevaluate_state_transition/ dry-run queries. Funnel remains a documented TODO intransition.rs. Network-scope discovery has no real mechanism yet — behaves asPublicuntil network-layer federation exists; documented as a known gap, not solved here (§1.7.2). Still open.- Best-effort, not guaranteed, uniqueness for "one
ResourceSpecificationper NDO" (§1.7.1) — aget_links-based check, inherently non-deterministic under gossip timing. Still open.
6. UI query surface for resolved constraints
Decision. Expose the pure predicates as read-only, non-mutating coordinator query functions, rather than porting the logic to TypeScript. The UI calls these before attempting the real write, to preemptively show blocking errors and non-blocking warnings in creation/editing forms.
Reasoning. crates/shared/src/constraints.rs's deliberate purity (§1.3 — no hdk/hdi dependency) means a #[hdk_extern] wrapper around them is nearly trivial plumbing, and there is exactly one implementation shared by three consumers: integrity validation (direct import), UI dry-run query (thin coordinator wrapper), and unit tests (direct import, no Holochain harness needed). Porting the same logic to TypeScript would create a second implementation that can silently drift from the Rust source of truth — the one thing this whole predicate-based design was built to avoid (a duplicated, driftable table).
Two separate query functions, mirroring the two predicate groups — not one combined endpoint (avoiding the same "kitchen sink" problem ResourceClassification itself had to be fixed for in §1.6):
#![allow(unused)] fn main() { // zome_resource coordinator — new #[derive(Serialize, Deserialize)] pub struct CheckRuleDataConstraintsInput { pub property_regime: PropertyRegime, pub resource_nature: ResourceNature, pub rivalry_override: Option<Rivalry>, pub rule_data: RuleData, } #[hdk_extern] pub fn check_rule_data_constraints(input: CheckRuleDataConstraintsInput) -> ExternResult<Vec<ConstraintViolation>> { let ctx = ResourceClassification { resource_nature: input.resource_nature, property_regime: input.property_regime, lifecycle_stage: None, rivalry_override: input.rivalry_override, }; Ok(check_rule_data_permitted(&ctx, &input.rule_data)) } }
#![allow(unused)] fn main() { // zome_gouvernance coordinator — new #[derive(Serialize, Deserialize)] pub struct CheckActionConstraintsInput { pub property_regime: PropertyRegime, pub resource_nature: ResourceNature, pub rivalry_override: Option<Rivalry>, pub action: VfAction, } #[hdk_extern] pub fn check_action_constraints(input: CheckActionConstraintsInput) -> ExternResult<Vec<ConstraintViolation>> { let ctx = ResourceClassification { resource_nature: input.resource_nature, property_regime: input.property_regime, lifecycle_stage: None, rivalry_override: input.rivalry_override, }; Ok(check_action_permitted(&ctx, &input.action)) } }
Why the input takes raw classification facts, not an existing entry hash. The most valuable use case is hypothetical — a rule-authoring form should be able to show "here's what would go wrong" while the agent is still filling out NdoCreateModal.svelte or a rule-editing form, before any NondominiumIdentity/GovernanceRule entry exists to fetch. A hash-based signature would only work for editing existing entries, missing the creation-time case entirely.
TypeScript mirror types (in packages/shared-types, alongside the existing PropertyRegime/NdoDescriptor types per specifications.md §7.1): ConstraintSeverity ('Hard' | 'Soft'), ConstraintViolation { rule_id: string; message: string; severity: ConstraintSeverity }. These carry no logic — just the shape needed to render the zome's JSON response; they cannot drift into duplicated logic the way a ported predicate function could.
Current code status. ✅ Implemented. check_rule_data_constraints (resource) and check_action_constraints (governance) plus TS mirror types in packages/shared-types. Svelte form wiring remains indicative / out of scope for Phase B.
UI call sites (indicative, not exhaustive — the specific components would need their own review pass):
- A rule-editing UI, once one exists, calling
check_rule_data_constraintswith the NDO's knownproperty_regime/resource_natureplus the draftedRuleDataas the agent edits it — Hard violations disable submit, Soft violations show as inline warnings. - Wherever action proposals are initiated (
propose_commitment/log_economic_eventtriggers) callingcheck_action_constraintsthe same way. NdoCreateModal.svelteneeds no round-trip for theService-nature rivalry ambiguity specifically — that's a static fact derivable fromResourceNaturealone (Servicehas no confident default), so a client-side lookup/copy hint suffices without a server call.
Debouncing/memoizing these calls client-side is a normal Svelte 5 $effect concern, not a protocol design question.
7. Sound implementation order
Given the dependency chain traced through §1–§6, a coherent build order (not a timeline — no estimates implied):
- §1.1 Rivalry —
Rivalryenum,ResourceNature::default_rivalry(),NondominiumIdentity.rivalry_override. Independent of everything else; unblocks all downstreamResourceClassificationusage. - §1.3 Predicate library skeleton —
crates/shared/src/constraints.rswithResourceClassification,ConstraintViolation,ConstraintSeverity, andhas_hard_violation. No predicates yet; just the shared vocabulary. - §1.5
RuleData—crates/shared/src/rule_data.rs. Independent of the predicate library itself, but predicates in step 4 depend on its types existing. - §1.6
check_rule_data_permitted+GovernanceRuleschema + integrity wiring — the first end-to-end enforcement path, and the simplest one (zero DHT reads), making it the best first proof that the whole architecture works before committing to the heavier §1.8 cross-zome path. - §1.7
ResourceSpecificationschema +NdoToSpecificationlink + lifecycle-gate validator — independent of step 4's predicates; can be built in parallel once step 1 lands. - §1.8
check_action_permitted+Commitment/EconomicEventschema +zome_gouvernance_integritywiring — depends on step 1 (Rivalry) and step 2 (predicate vocabulary); the heaviest step, since it also requires the first realmust_get_valid_record-based cross-entry read in a hot validation path. - §1.8
GovernanceTransitionRequest/evaluate_state_transition— net-new coordinator interface; can start once step 6's Hard gate exists, since the Hard gate protects correctness regardless of which coordinator surface is used, buying time to resolve the "single funnel vs. parallel paths" open question (§5, item 2) without blocking on it. §4 Migration decision— resolved (§4: option (a), direct breaking replacement, confirmed no real persisted data on any running network). No longer a gate in front of steps 4–6; each of those steps applies its struct change directly, with no#[serde(default)]shim, dual-field period, orV2type.- §6 UI query functions — depend only on steps 2–3 (the pure predicate functions) and can be built in parallel with 4–7 once those exist, since they're thin wrappers with no dependency on the entry-schema changes themselves.
With step 8 resolved, the sequence 1 → 2 → 3 → 4 → 5 → 6 → 7 (with 9 parallelizable alongside 4–7) is now fully unblocked and ready to execute in order.
Digital Resource Integrity - High-Level Requirements
Problem Statement
The nondominium system must provide cryptographic proof that downloaded resource data is identical to the original data uploaded to the Holochain DHT. This ensures trust in resource exchange and prevents unauthorized modifications during storage and transmission.
Core Requirements
R1: Cryptographic Integrity Verification
The system shall provide mathematical proof that downloaded data matches the original uploaded data.
Acceptance Criteria:
- Users can verify that any downloaded resource is identical to the original
- Verification process works even if data is stored by multiple unknown agents
- Any modification to data is immediately detectable
- Verification can be performed without trusting storage providers
R2: Distributed Storage with Guarantees
The system shall store resource data across multiple Holochain agents while maintaining integrity.
Acceptance Criteria:
- Files are split into chunks for distributed storage
- Each chunk is cryptographically addressed by its content hash
- Data can be retrieved even if some storage agents are offline
- Storage failures do not compromise data integrity
R3: Efficient Verification Process
The system shall allow users to verify resource integrity efficiently.
Acceptance Criteria:
- Verification can be performed without downloading entire resources
- Users can verify specific portions of large resources
- Verification process completes within acceptable time limits
- Users receive clear success/failure feedback on verification
R4: Manifest-Based Organization
The system shall use manifests to organize and describe resource data.
Acceptance Criteria:
- Each resource has a manifest describing its structure and integrity
- Manifests contain metadata about files and their organization
- Manifests are themselves cryptographically verifiable
- Manifest format supports multiple files and complex resources
R5: Composable Resource Architecture
The system shall support hierarchical resource compositions where parent resources are assembled from child resources.
Acceptance Criteria:
- Resources can reference other resources as components with specified quantities
- Each component maintains independent integrity verification and trust status
- Parent resource integrity depends on component integrity with dependency rules
- Component replacements trigger appropriate re-verification of affected parent assemblies
- Support for required, optional, and alternative components with different verification levels
R6: Fractal Verification Process
The system shall provide recursive verification that cascades through resource hierarchies.
Acceptance Criteria:
- Verify complete resource tree from leaf components to root assembly
- Identify specifically which components failed verification in hierarchical context
- Allow partial verification of subsystems without full assembly verification
- Component integrity changes propagate trust/verification status up through parent assemblies
- Support for "trusted component" status that simplifies verification of dependent assemblies
R7: Component Dependency Management
The system shall manage dependencies between components with version compatibility and substitution rules.
Acceptance Criteria:
- Version compatibility matrices defining which component versions can work together
- Required vs optional vs alternative component classification with clear rules
- Component substitution rules that specify verification implications for replacements
- Assembly upgrade paths that maintain verification continuity and trust propagation
R8: Selective Component Verification
The system shall allow users to verify specific components or subsystems efficiently.
Acceptance Criteria:
- Verify only critical components for time-sensitive operations with reduced scope
- Component-level verification status caching to avoid redundant verifications
- Trust propagation from previously verified components to parent assemblies
- Impact analysis showing which parent assemblies are affected by component changes
R9: Component Supply Chain Transparency
The system shall provide transparency into component origins, manufacturing processes, and assembly relationships.
Acceptance Criteria:
- Component provenance tracking through complete assembly hierarchy
- Manufacturer and supplier verification at component level with cryptographic proofs
- Integration with external supply chain verification systems and standards
- Component recall and replacement notifications that affect dependent assemblies
Verification Process Requirements
Phase 1: Resource Discovery & Composition Analysis
User Action: Request a resource from the DHT
System Responsibilities:
- Retrieve the resource manifest from the DHT
- Verify the manifest's cryptographic signature
- Analyze resource composition:
- Identify if resource is atomic or composite
- Load component manifests recursively for composite resources
- Build complete component dependency tree
- Check version compatibility between components
- Present comprehensive manifest metadata including:
- File list, sizes, and hashes
- Component breakdown with integrity status
- Dependency relationships and version constraints
- Critical vs optional component classification
- Obtain user consent to proceed with download
Phase 1A: Component Integrity Pre-Check (Composite Resources)
System Responsibilities:
- Verify availability of all required components
- Check component verification status and trust levels
- Identify any missing, corrupted, or incompatible components
- Present component integrity summary before download
- Allow user to proceed with available components or wait for missing ones
Phase 2: Hierarchical Chunk Verification During Download
User Action: Download the resource data
System Responsibilities:
- For atomic resources: Retrieve and verify individual chunks as before
- For composite resources:
- Download component resources in dependency order
- For each component: verify its chunks and integrity according to its verification level
- Track component verification status independently
- Real-time integrity feedback:
- Show component-by-component verification progress
- Flag individual component failures without stopping entire download
- Continue with available components while troubleshooting failed ones
- Dependency validation:
- Verify component compatibility during assembly
- Check that required components are present before marking assembly complete
- Handle optional component absences gracefully
Phase 3: Complete Assembly Verification
User Action: After download completes, request full verification
System Responsibilities:
- For atomic resources: Verify complete resource against manifest's Merkle root
- For composite resources:
- Verify individual component integrity (already done in Phase 2)
- Verify assembly integrity:
- Validate component quantities and relationships
- Check assembly rules and constraints
- Verify no required components are missing
- Validate optional component selections
- Generate hierarchical verification results:
- ✅ FULLY VERIFIED: All components and assembly validated
- ⚠️ PARTIALLY VERIFIED: Core components verified, optional issues present
- ❌ ASSEMBLY FAILED: Critical components missing or incompatible
- ❌ COMPONENT CORRUPTED: One or more components failed verification
- Detailed component reporting:
- Show exact component verification status
- Identify which components failed and why
- Provide impact analysis on parent assembly
Phase 4: Hierarchical Integrity Reporting
User Action: Request verification report
System Responsibilities:
- Generate comprehensive hierarchical verification report:
- Component breakdown with individual integrity status
- Assembly verification results with dependency analysis
- Verification timestamps for each component and assembly
- Trust propagation analysis showing how component trust affects assembly
- Supply chain transparency:
- Component provenance information
- Manufacturer and supplier verification status
- Version compatibility analysis
- Substitution and upgrade recommendations
- Audit trail maintenance:
- Store verification results at component and assembly levels
- Maintain component dependency history
- Enable verification proof sharing for component sub-assemblies
- Impact analysis tools:
- Show which parent assemblies are affected by component changes
- Provide upgrade and maintenance recommendations
- Support compliance reporting for regulatory requirements
User Experience Requirements
UX1: Clear Feedback During Verification
The system shall provide users with real-time feedback during the verification process.
Requirements:
- Progress indicator showing verification status
- Clear messaging about which chunks are being verified
- Immediate notification of any verification failures
- Estimated time remaining for verification
UX2: Hierarchical Verification Options
The system shall offer users flexibility in verification approaches for complex resource assemblies.
Options:
- Quick Verify: Verify only critical components and core assembly
- Full Verify: Verify all components, chunks, and complete assembly hierarchy
- Selective Verify: Verify specific components, files, or chunks at any level
- Component Verify: Verify only selected components without full assembly
- Background Verify: Run verification in background with progress notifications
- Trust-Based Verify: Skip verification of pre-trusted components and assemblies
- Supply Chain Verify: Include manufacturer and supplier verification in verification process
UX3: Hierarchical Error Handling and Recovery
The system shall handle verification failures gracefully at component and assembly levels.
Requirements:
- Component-level error reporting: Clear error messages explaining which components failed verification
- Assembly impact analysis: Show how component failures affect parent assemblies
- Graceful degradation: Continue with available components while handling failed ones
- Component substitution assistance: Suggest alternative components when available
- Automatic retry mechanisms: Retry failed components and chunks with different sources
- Recovery recommendations: Provide step-by-step guidance for resolving verification issues
- Partial assembly support: Allow use of partially verified assemblies with clear warnings
Integration Requirements
I1: ValueFlows Compatibility
The system shall integrate seamlessly with existing ValueFlows resource management.
Requirements:
- Integrity metadata stored with ResourceSpecification entries
- Resource transfers include integrity verification steps
- Economic events can depend on successful verification
- Reputation systems consider verification success rates
I2: Governance Integration
The system shall respect existing governance rules and access controls.
Requirements:
- Verification operations respect capability-based permissions
- Audit trails for all verification activities
- Resource owners can set verification requirements
- Verification failures can trigger governance actions
I3: Standards Compliance
The system shall follow relevant industry standards for digital integrity.
Requirements:
- Compatibility with IOPA (Internet of Production Alliance) standards
- Support for common cryptographic standards (SHA-256, Merkle trees)
- Documentation of verification processes for compliance audits
- Extensible design for future standard updates
Performance Requirements
P1: Verification Speed
- Individual chunk verification: <100ms per chunk
- Full resource verification: <10 seconds for typical resources
- Verification report generation: <1 second
- Concurrent verification support for multiple resources
P2: Storage Efficiency
- Manifest overhead: <1% of total resource size
- Chunk size optimization for DHT performance
- Efficient data structures for verification metadata
- Minimal additional storage for verification data
P3: Network Efficiency
- Parallel chunk retrieval for faster downloads
- Optimized chunk location algorithms
- Caching strategies for frequently accessed resources
- Bandwidth-efficient verification protocols
Security Requirements
S1: Cryptographic Security
- Use industry-standard cryptographic algorithms (SHA-256)
- Proper random number generation for cryptographic operations
- Protection against collision attacks through hash algorithms
- Regular security reviews of cryptographic implementations
S2: Access Control
- Verification operations respect existing access permissions
- Audit trails for all integrity-related operations
- Protection against unauthorized modification of verification data
- Secure storage of cryptographic keys and certificates
S3: Data Privacy
- Optional encryption for sensitive resource data
- Privacy-preserving verification options when possible
- Compliance with data protection regulations
- User control over verification data sharing
Success Metrics
Technical Metrics
- Verification success rate: >99.9%
- False positive rate: <0.01%
- Verification time within performance requirements
- Resource availability with integrity guarantees
User Experience Metrics
- User satisfaction with verification process
- Trust levels in resource integrity system
- Adoption rate of verification features
- Support requests related to verification issues
Business Metrics
- Reduced disputes over resource integrity
- Increased trust in resource exchanges
- Compliance with industry regulations
- Competitive advantage through robust integrity guarantees
Technical Context (for Implementation Reference)
Storage Architecture
- File Chunking: Resources split into 64KB chunks for DHT distribution
- Content Addressing: Each chunk addressed by its SHA-256 hash
- Manifest System: Resource manifests organize chunks and provide integrity metadata
- Merkle Trees: Hierarchical hash structure enables efficient selective verification
- Component References: Manifests can reference other resource manifests as components
- Assembly Hierarchies: Support for unlimited nesting depth in resource compositions
Cryptographic Foundation
- Hash Algorithm: SHA-256 for chunk and resource verification
- Tree Structure: Merkle trees for efficient integrity proofs
- Signature Scheme: Holochain's built-in cryptographic signatures
- Validation: Multi-level verification (chunk → file → resource → component → assembly)
- Trust Propagation: Cryptographic proof chaining through component hierarchies
- Component Signatures: Individual component verification proofs that combine into assembly proofs
Composability Architecture
- Atomic Resources: Base resources with no sub-components (files, data chunks)
- Component Resources: Resources that can be used as parts of larger assemblies
- Composite Resources: Assemblies built from multiple component resources
- Assembly Rules: Constraints and requirements for valid component combinations
- Version Matrices: Compatibility rules defining which component versions work together
- Substitution Rules: Allowable component replacements with verification implications
Integration Points
- ResourceSpecification: Enhanced with component references and assembly rules
- Governance Zome: Access control and audit trail integration for component operations
- Economic Events: Verification-dependent transaction flows for component exchanges
- Reputation Systems: Agent reliability based on component and assembly verification history
- Supply Chain Integration: External manufacturer and supplier verification systems
- Standards Compliance: IOPA and other manufacturing standards for component assemblies
This requirements document provides the foundation for implementing a comprehensive digital resource integrity system that ensures trust and reliability in the nondominium resource exchange ecosystem.
Fractal Composable Resource Architecture
Created: 2025-12-11 Status: ARCHIVAL - Conceptual Design Complete Context: Digital Resource Integrity System for nondominium Holochain Application
Architecture Overview
The Fractal Composable Resource Architecture enables unlimited nesting depth in resource compositions, supporting complex manufacturing and digital fabrication scenarios where resources are built from other resources in recursive patterns.
Core Concepts
1. Resource Classification
Atomic Resources
- Definition: Base resources with no sub-components
- Examples: Individual files, data chunks, basic manufacturing components
- Characteristics:
- No component references
- Direct integrity verification
- Single-level manifest structure
- Content-addressed storage
Component Resources
- Definition: Resources designed to be used as parts of larger assemblies
- Examples: Standardized parts, reusable modules, manufacturing sub-components
- Characteristics:
- Can be referenced by parent resources
- Independent verification status
- Version compatibility requirements
- Substitution rules defined
Composite Resources
- Definition: Assemblies built from multiple component resources
- Examples: Complex products, manufacturing assemblies, multi-file datasets
- Characteristics:
- References to component resources
- Assembly rules and constraints
- Hierarchical dependency management
- Multi-level verification requirements
2. Component Relationship Types
Required Components
- Definition: Essential components that must be present for assembly to function
- Verification: Assembly fails verification if required components missing
- Impact: Critical for assembly integrity and functionality
- Examples: Critical structural components, essential data files
Optional Components
- Definition: Non-essential components that enhance functionality
- Verification: Assembly can be partially verified without optional components
- Impact: Missing optional components result in "PARTIALLY VERIFIED" status
- Examples: Optional features, supplementary data, enhancement modules
Alternative Components
- Definition: Multiple options available for fulfilling a component role
- Verification: Any valid alternative satisfies assembly requirements
- Impact: Substitution rules define verification implications
- Examples: Compatible parts from different manufacturers, alternative data formats
3. Hierarchical Composition Patterns
Linear Assembly Pattern
Final Assembly
├── Component A (Required)
│ └── Sub-component A1 (Required)
├── Component B (Required)
└── Component C (Optional)
└── Sub-component C1 (Alternative to C2)
└── Sub-component C2 (Alternative to C1)
Modular Pattern
Product Assembly
├── Core Module (Required)
│ ├── Controller Component (Required)
│ └── Power Component (Required)
├── Feature Module A (Optional)
│ └── Sensor Component (Required for Module A)
└── Feature Module B (Optional)
└── Actuator Component (Required for Module B)
Fractal Pattern
Complex System
├── Subsystem Alpha (Required)
│ ├── Assembly Alpha-1 (Required)
│ │ ├── Component Alpha-1a (Required)
│ │ └── Component Alpha-1b (Alternative to Alpha-1c)
│ │ └── Component Alpha-1c (Alternative to Alpha-1b)
│ └── Assembly Alpha-2 (Optional)
└── Subsystem Beta (Required)
└── Component Beta-1 (Required)
4. Version Compatibility System
Version Matrices
- Purpose: Define which component versions can work together
- Structure: Compatibility rules between component versions
- Validation: Assembly verification includes version compatibility checks
- Evolution: Support for component upgrades with compatibility preservation
Compatibility Types
- Exact Match: Specific version required
- Minor Version Compatible: Same major version, compatible minor versions
- Major Version Compatible: Cross-major version compatibility defined
- Custom Rules: Complex compatibility relationships defined by manufacturers
Version Conflict Resolution
- Prevention: Compatibility checks prevent invalid assemblies
- Resolution: Automatic or manual resolution of version conflicts
- Migration: Defined upgrade paths between incompatible versions
- Notification: Alert users to compatibility issues during assembly
5. Substitution System Architecture
Substitution Rules
- Definition: Allowable component replacements with verification implications
- Categories:
- Direct Replacement: Fully compatible with no verification impact
- Conditional Replacement: Compatible under specific conditions
- Qualified Replacement: Requires additional verification steps
- Incompatible Replacement: Not allowed in current assembly
Verification Impact Assessment
- No Impact: Replacement doesn't affect assembly verification status
- Re-verify Required: Assembly needs re-verification after replacement
- Partial Verification: Only affected components need re-verification
- Full Verification: Complete assembly re-verification required
Substitution Tracking
- History: Complete record of all component substitutions
- Audit Trail: Who authorized substitution and when
- Impact Analysis: Which assemblies affected by substitution
- Rollback: Ability to reverse substitutions if needed
6. Assembly Rules and Constraints
Structural Constraints
- Quantity Requirements: Specific numbers of each component type
- Spatial Relationships: Physical positioning requirements (for manufacturing)
- Connection Rules: How components can be connected together
- Order Dependencies: Required assembly sequences
Behavioral Constraints
- Performance Requirements: Minimum performance characteristics
- Safety Requirements: Safety-critical component requirements
- Regulatory Compliance: Industry-specific compliance requirements
- Quality Standards: Minimum quality criteria for components
Validation Rules
- Pre-assembly Validation: Checks before assembly creation
- Runtime Validation: Ongoing checks during operation
- Post-assembly Validation: Final verification after assembly completion
- Maintenance Validation: Periodic verification during assembly lifecycle
Verification Architecture
1. Hierarchical Verification Process
Verification Levels
- Level 1 - Chunk Verification: Individual data chunk integrity
- Level 2 - File Verification: Individual file integrity within components
- Level 3 - Component Verification: Complete component resource integrity
- Level 4 - Assembly Verification: Component relationships and assembly rules
- Level 5 - System Verification: Complete hierarchical system integrity
Verification Strategies
- Bottom-Up: Start with leaf components and work up to root assembly
- Top-Down: Start with root assembly and work down to components
- Selective: Verify only specific components or subsystems
- Incremental: Verify only changed components and affected assemblies
Verification Results Propagation
Component Status → Assembly Impact → System-Level Consequence
─────────────────────────────────────────────────────────────
VERIFIED → NO IMPACT → SYSTEM REMAINS VERIFIED
CORRUPTED → RE-VERIFY → SYSTEM RE-VERIFICATION NEEDED
MISSING → PARTIAL VERIFIED → SYSTEM PARTIALLY VERIFIED
INCOMPATIBLE → ASSEMBLY FAILED → SYSTEM VERIFICATION FAILED
2. Trust Propagation System
Trust Levels
- FULL TRUST: Component completely verified and trusted
- CONDITIONAL TRUST: Component trusted under specific conditions
- PARTIAL TRUST: Component partially verified with limitations
- NO TRUST: Component not verified or trusted
Trust Propagation Rules
- Upward Propagation: Component trust affects parent assembly trust
- Downward Influence: Assembly requirements affect component trust needs
- Lateral Impact: Component changes affect sibling components
- System-wide Effects: Critical component failures affect entire system
Trust Optimization
- Caching: Store verification results to avoid redundant verification
- Incremental Updates: Update only affected trust relationships
- Selective Verification: Skip verification of fully trusted components
- Trust Inheritance: Parent assembly trust inherits from component trust
3. Performance Optimization Strategies
Verification Parallelization
- Component-level Parallelism: Verify multiple components simultaneously
- Chunk-level Parallelism: Verify multiple chunks within components simultaneously
- Assembly-level Parallelism: Verify multiple assemblies simultaneously
- Hierarchical Parallelism: Parallel verification at multiple hierarchy levels
Selective Verification Optimization
- Critical Path: Verify only components in critical assembly paths
- Risk-based Verification: Prioritize high-risk components
- User-defined Priorities: Allow users to specify verification priorities
- Adaptive Verification: Adjust verification based on usage patterns
Caching Strategies
- Component Verification Cache: Store component verification results
- Chunk Hash Cache: Cache frequently accessed chunk hashes
- Assembly Rule Cache: Cache assembly validation rule results
- Trust Relationship Cache: Store trust propagation results
Manufacturing Integration Patterns
1. Supply Chain Transparency
Component Provenance
- Origin Tracking: Complete history of component origin and movement
- Manufacturer Verification: Cryptographic proof of manufacturer identity
- Quality Certifications: Integration with external quality certification systems
- Regulatory Compliance: Tracking of regulatory compliance status
Supply Chain Events
- Manufacturing Events: Record of component manufacturing processes
- Transport Events: Tracking of component movement through supply chain
- Quality Events: Recording of quality checks and certifications
- Modification Events: Tracking of any modifications or repairs
Transparency Interfaces
- Supplier Portals: Interfaces for suppliers to provide provenance data
- Verification APIs: APIs for external verification system integration
- Compliance Reporting: Automated generation of compliance reports
- Audit Support: Tools for regulatory and quality audits
2. Quality Assurance Integration
Quality Metrics Integration
- Component Quality Metrics: Integration with component quality measurement systems
- Assembly Quality Metrics: Aggregated quality metrics for assemblies
- Process Quality Metrics: Integration with manufacturing process quality systems
- Continuous Improvement: Quality metrics feedback for process improvement
Quality Validation
- Specification Compliance: Verification against component specifications
- Standards Compliance: Verification against industry standards
- Regulatory Compliance: Verification against regulatory requirements
- Customer Requirements: Verification against customer-specific requirements
3. Maintenance and Lifecycle Management
Maintenance Tracking
- Maintenance History: Complete record of maintenance activities
- Component Lifecycle: Tracking of component aging and replacement needs
- Predictive Maintenance: Integration with predictive maintenance systems
- Warranty Management: Tracking of warranty status and claims
Lifecycle Events
- Installation Events: Recording of component installations
- Replacement Events: Tracking of component replacements
- Decommissioning Events: Recording of component end-of-life
- Recycling Events: Tracking of component recycling and disposal
Implementation Considerations
1. Data Structure Design
Component References
ComponentReference {
component_id: ResourceHash
quantity: Number
required: Boolean
alternatives: [ResourceHash]
version_constraints: VersionMatrix
substitution_rules: SubstitutionRules
verification_level: VerificationLevel
}
Assembly Definitions
AssemblyDefinition {
assembly_id: ResourceHash
components: [ComponentReference]
assembly_rules: AssemblyRules
constraints: Constraints
verification_requirements: VerificationRequirements
trust_requirements: TrustRequirements
}
Verification Status
VerificationStatus {
resource_id: ResourceHash
verification_level: VerificationLevel
status: VerificationResult
timestamp: Timestamp
verified_by: AgentPubKey
trust_level: TrustLevel
dependencies: [ResourceHash]
dependents: [ResourceHash]
}
2. Algorithm Complexity
Verification Algorithm Complexity
- Time Complexity: O(n) where n is number of components in hierarchy
- Space Complexity: O(h) where h is height of assembly hierarchy
- Network Complexity: O(m) where m is number of chunks across all components
- Optimization: Parallel verification reduces effective complexity
Trust Propagation Complexity
- Propagation Time: O(d) where d is dependency depth
- Update Complexity: O(k) where k is number of affected relationships
- Consistency Maintenance: O(1) for incremental updates
- Scalability: Designed for large-scale assembly hierarchies
3. Error Handling and Recovery
Error Classification
- Component Errors: Individual component verification failures
- Assembly Errors: Assembly rule violations
- System Errors: System-wide verification failures
- Network Errors: Network-related verification issues
Recovery Strategies
- Component Recovery: Retry failed component verification from alternative sources
- Assembly Recovery: Graceful degradation with partial assembly functionality
- System Recovery: System-wide recovery with backup and restore mechanisms
- Network Recovery: Adaptive network strategies for chunk retrieval
Future Evolution Paths
1. Advanced Manufacturing Integration
- IoT Device Integration: Direct verification from manufacturing IoT devices
- Real-time Monitoring: Continuous integrity monitoring during operation
- Digital Twin Integration: Integration with digital twin systems
- AI-powered Optimization: Machine learning for verification optimization
2. Cross-Platform Standardization
- Industry Standards: Contribution to industry standards for resource integrity
- Interoperability: Integration with other manufacturing platforms
- Protocol Standardization: Standard protocols for cross-system verification
- Certification Programs: Certification programs for compliance verification
3. Advanced Verification Techniques
- Zero-Knowledge Proofs: Privacy-preserving verification techniques
- Quantum-resistant Cryptography: Future-proof cryptographic approaches
- Homomorphic Verification: Verification of encrypted data without decryption
- Blockchain Integration: Cross-blockchain verification and provenance tracking
Derived Work
Concepts from this document — fractal composition taxonomy (Atomic/Component/Composite), hierarchical trust propagation, and verification as a fractal process — have been integrated into the Complexity Driven Development methodology and AI skill:
- Methodology:
nondominium-design-system/.cursor/skills/complexity-oriented-programming/methodology.md - AI Skill:
nondominium-design-system/.cursor/skills/complexity-oriented-programming/SKILL.md
Status: CONCEPTUAL DESIGN COMPLETE - READY FOR TECHNICAL SPECIFICATION Next Phase: Implementation Planning and Holochain Zome Architecture Design Confidence Level: HIGH - Comprehensive architecture coverage achieved
Many-to-Many and Multi-Party Resource Flows (Post-MVP)
This document defines the plan and requirements for extending Nondominium beyond one-to-one custody transfers. The approach is to extend the ValueFlows model (EconomicEvent, Commitment, and related structures) to support multiple providers and multiple receivers, rather than using workarounds such as bundling pairwise events.
These requirements are post-MVP and will be developed after the first Nondominium proof-of-concept.
1. Context and Goals
1.1 Current State (MVP)
- EconomicResource has a single
custodian: AgentPubKey. - EconomicEvent and Commitment have single
provider: AgentPubKeyandreceiver: AgentPubKey. - Transfer patterns: Only one-to-one custody transfers are supported.
- PPR: Exactly two receipts per interaction (one per agent in the pair).
1.2 Target State (Post-MVP)
- Support one-to-one, one-to-many, many-to-one, and many-to-many custody and transfer patterns.
- Support resource pools (multiple resources under mixed regimes) transferred to one or many agents, with all current custodians of any resource in the pool required to consent.
- Support shared custody with optional weights and roles per custodian.
- Support delegation among co-custodians (e.g. one custodian holds legal responsibility or facility-management role).
- Extend ValueFlows data structures and semantics to n-ary participants; keep PPR issuance rules well-defined for multi-party flows.
1.3 Design Principle
Extend ValueFlows, do not work around it. EconomicEvent and Commitment (and any dependent types) shall be extended to allow multiple providers and/or multiple receivers where the domain requires it. Compatibility with existing one-to-one flows shall be preserved (e.g. single-provider/single-receiver as a special case).
2. Use Cases and Transfer Patterns
2.1 One-to-Many (Current Custodian Adds Co-Custodians)
- Example: Agent A is custodian of a physical space. A transfers custody so that A, B, C, D are all co-custodians (co-stewards). B, C, D can use and co-manage the space.
- Pattern: One provider (A), many receivers (A, B, C, D) or (B, C, D) if A relinquishes.
- Applies to: Shared spaces, shared digital resources (e.g. shared wallet, shared document list).
2.2 Many-to-One (All Co-Custodians Transfer to One Agent)
- Example: Agents B, C, D share custody of a CNC machine. The machine needs repair. All three must agree and co-sign a custody transfer to the repair agent R for a limited time.
- Pattern: Many providers (B, C, D), one receiver (R).
- Applies to: Repair, storage, or any handover that requires full consent of current co-custodians.
2.3 Many-to-Many (One Group Hands Over to Another Group)
- Example: B, C, D are co-custodians of a CNC in a makerspace. They transfer custody to another group E, F, G in a different makerspace, who will share responsibility. All of B, C, D agree; custody becomes E, F, G.
- Pattern: Many providers (B, C, D), many receivers (E, F, G).
- Applies to: Equipment handovers between groups, shared digital assets.
2.4 Pool Transfers (Multiple Resources, Mixed Regimes)
- Example: A pool contains resources under various property regimes. The entire pool is transferred to one agent or to a group. Every agent who is custodian or co-custodian of any resource in the pool must sign the transaction.
- Pattern: Many providers (all custodians across the pool), one or many receivers.
- Applies to: Bundled asset transfers, project handovers.
2.5 Delegation Among Co-Custodians
- Example: A physical space has co-custodians A, B, C, D. Legal responsibility (relationship with municipality or landlord) is delegated to one of them (e.g. A), not all. A can perform certain actions (sign contracts, represent to authority) on behalf of the group.
- Requirement: The system must support roles and delegation within the set of custodians so that specific actions can be restricted to a delegate without requiring every co-custodian to sign each time.
3. Plan (Implementation Phases)
Phase 1: Data Model and Shared Custody
- Extend EconomicResource or introduce SharedCustody so that a resource can have multiple custodians with optional weights and roles.
- Define ResourcePool (optional) for grouping resources for pool transfers.
- Ensure backward compatibility: resources with a single custodian continue to work as today.
Phase 2: ValueFlows Extension (Events and Commitments)
- Extend EconomicEvent to support:
providers: Vec<AgentPubKey>andreceiver: AgentPubKey, orproviders: Vec<AgentPubKey>andreceivers: Vec<AgentPubKey>(full n-to-m).
- Extend Commitment similarly (multiple providers, multiple receivers).
- Define validation rules: when multiple providers are present, policy may require that all (or a weighted threshold) have agreed before the event is valid.
- Keep Claim and EconomicEvent linkage clear (one Commitment fulfilled by one EconomicEvent; the event itself may be n-ary).
Phase 3: Multi-Party Consent and Execution
- Introduce multi-party consent for transfers that change custody when there are multiple current custodians:
- Either encode consent in the Commitment/Event (e.g. list of signatories), or
- Introduce a lightweight CustodyTransferProposal (or equivalent) that collects signatures and, when satisfied, creates the EconomicEvent and updates custody.
- Define execution semantics: when all required providers have signed, custody is updated and the event is recorded.
Phase 4: Delegation (Resource-Scoped)
- Introduce ResourceDelegation (or equivalent): which agent(s) may perform which actions on behalf of which co-custodians for a given resource or pool.
- Roles (e.g.
legal_delegate,facility_manager) and optional allowed_actions. - Governance checks: before executing an action, verify either direct custodianship or a valid delegation for that action.
Phase 5: PPR Distribution for Multi-Party Flows
- Define how Private Participation Receipts are generated when providers and/or receivers are multiple:
- Which agents receive PPRs.
- How to attribute responsibility (e.g. delegate vs full group, weights).
- Extend PPR structures as needed (e.g.
on_behalf_of,role_context) so reputation and OVN accounting can attribute correctly. - Ensure backward compatibility: one-to-one flows still produce exactly two PPRs as today.
Phase 6: Pool Transfers and Cross-Resource Consent
- Implement pool transfer flows: gather all custodians of all resources in the pool, require their consent, then create events and update custody for each resource (or define a single composite event type for pools).
- Define how PPRs are distributed when a pool is transferred (per resource, per agent, or aggregated as specified).
4. Requirements
4.1 Shared Custody and Weights/Roles
- REQ-MMF-01 – Multiple Custodians: The system shall support resources for which more than one agent holds custody (co-custodians).
- REQ-MMF-02 – Backward Compatibility: Resources with a single custodian shall remain supported and behave as in the current MVP (single
custodianor single-member shared custody). - REQ-MMF-03 – Weights (Optional): For resources with multiple custodians, the system shall support optional weights (e.g. shares) per custodian for responsibility, benefit, or voting.
- REQ-MMF-04 – Roles (Optional): For resources with multiple custodians, the system shall support optional roles per custodian (e.g.
legal_delegate,facility_manager) to support delegation of specific actions to one or a subset of custodians. - REQ-MMF-05 – Thresholds (Optional): The system shall support optional threshold rules (e.g. "transfers require consent of custodians representing ≥ 80% of weight") for multi-party decisions.
4.2 ValueFlows Extension (Events and Commitments)
- REQ-MMF-06 – Multiple Providers: EconomicEvent and Commitment shall support multiple providers (e.g.
providers: Vec<AgentPubKey>), with single-provider as a special case. - REQ-MMF-07 – Multiple Receivers: EconomicEvent and Commitment shall support multiple receivers (e.g.
receivers: Vec<AgentPubKey>), with single-receiver as a special case. - REQ-MMF-08 – ValueFlows Compliance: Extensions shall remain consistent with ValueFlows vocabulary and semantics; where the standard does not define n-ary flows, Nondominium shall define a minimal, documented extension.
- REQ-MMF-09 – Validation of n-ary Events: The system shall validate that all required providers (or a defined subset/threshold) have consented before an EconomicEvent involving multiple providers is considered valid and executed.
- REQ-MMF-10 – Claim-Event Linkage: Each Commitment shall still be fulfilled by at most one EconomicEvent; that event may reference multiple providers and/or multiple receivers.
4.3 Transfer Patterns
- REQ-MMF-11 – One-to-Many Transfer: The system shall support custody transfers from one agent to a set of agents (one-to-many), including the case where the original custodian remains in the set (co-stewardship).
- REQ-MMF-12 – Many-to-One Transfer: The system shall support custody transfers from a set of agents to one agent (many-to-one), requiring consent of all current custodians (or a defined threshold).
- REQ-MMF-13 – Many-to-Many Transfer: The system shall support custody transfers from a set of agents to another set of agents (many-to-many), with consent and execution semantics clearly defined.
- REQ-MMF-14 – Pool Transfers: The system shall support transfers of a pool of resources to one or more agents, where every custodian (or co-custodian) of any resource in the pool must consent (or meet a defined threshold) before the transfer is executed.
4.4 Delegation Among Co-Custodians
- REQ-MMF-15 – Resource-Scoped Delegation: The system shall support delegation of specific actions (e.g. sign contract, represent to municipality) to one or more agents on behalf of the co-custodians of a resource or pool.
- REQ-MMF-16 – Delegation Roles: Delegation shall be expressible with role labels (e.g.
legal_delegate,facility_manager) and optional allowed_actions so that only delegated actions can be performed by the delegate without full co-custodian consent. - REQ-MMF-17 – Delegation Revocation: Delegation shall be revocable; revocation shall not require changing the set of co-custodians.
- REQ-MMF-18 – Governance Check: Before executing an action that affects a resource with multiple custodians, the system shall verify that the acting agent is either a custodian or a valid delegate for that action.
4.5 PPR Distribution and Attribution
- REQ-MMF-19 – PPR for Multi-Party Events: The system shall define and implement rules for issuing Private Participation Receipts when an EconomicEvent has multiple providers and/or multiple receivers.
- REQ-MMF-20 – Attribution Semantics: PPR issuance shall support clear attribution of responsibility (e.g. which agents are credited or debited for the interaction), including optional weights and roles (e.g. delegate vs full group).
- REQ-MMF-21 – Delegation Context in PPR: When an action is performed by a delegate on behalf of co-custodians, PPRs shall carry context (e.g.
on_behalf_of,role_context) so that reputation and OVN accounting can attribute correctly to both the delegate and the group. - REQ-MMF-22 – Backward Compatibility of PPR: One-to-one flows shall continue to generate exactly two PPRs per interaction as in the current MVP; multi-party flows shall have a documented, deterministic PPR distribution rule.
4.6 Integration and Consistency
- REQ-MMF-23 – Governance-as-Operator: Multi-party transfers and delegation shall integrate with the existing governance-as-operator architecture (resource zome requests transitions; governance zome evaluates and authorizes).
- REQ-MMF-24 – Economic Processes: Use, Transport, Storage, and Repair processes shall be extensible to multi-party custody where applicable (e.g. many-to-one transfer to repair agent).
- REQ-MMF-25 – Digital and Material: The same transfer patterns and delegation model shall apply to both material and digital resources (e.g. shared wallet, shared document list).
4.7 Documentation and Interoperability
- REQ-MMF-26 – Extension Documentation: The ValueFlows extensions (n-ary providers/receivers, shared custody, delegation) shall be documented for interoperability and potential upstream contribution to ValueFlows or related standards.
- REQ-MMF-27 – Migration Path: The design shall allow a clear migration path from current one-to-one-only data to the extended model without breaking existing records.
5. Relationship to Other Post-MVP Work
- Versioning (see
versioning.md): Versioning of resources and of the Nondominium hApp is independent but complementary; multi-party flows may apply to versioned resources and to forks. - Future architecture (P2P vs organizational) (see
requirements.mdsection 11): Delegation in many-to-many flows aligns with organizational delegation (org → employee); resource-scoped delegation is a subset that can share concepts and data structures. - Digital Resource Integrity (see
digital-resource-integrity.md): Shared custody and pool transfers may involve resources with integrity manifests; verification and attribution should remain consistent.
6. Post-MVP Status
These requirements are explicitly post-MVP. The first Nondominium proof-of-concept will implement only one-to-one custody transfers. Implementation of many-to-many flows, shared custody with weights/roles, resource-scoped delegation, and extended PPR distribution will follow in a later phase, in line with the plan above.
Versioning (Post-MVP)
Versioning in Nondominium is about variations of a Resource over time and across forks, and about expressing affiliations and evolutions of both:
- Material resources (physical instances and their designs)
- Digital resources (software, documents, CAD, manifests)
- The Nondominium hApp itself, treated as a versioned Application Resource
This capability is explicitly post-MVP / future development. The first proof-of-concept will operate without full versioning semantics; these requirements describe how we want to extend the system later.
More on the OVN license: https://github.com/Sensorica/ovn-license/tree/v2.0
More on the OVN model: https://ovn.world/
1. Goals & Scope
-
G1 – Unified Versioning Model: Provide a single conceptual model that applies to:
- Material resources (and their designs)
- Digital resources (code, documentation, CAD, manifests)
- The Nondominium hApp (application as a resource)
-
G2 – Affiliation & Evolution Graph: Represent resource evolution as a directed acyclic graph (DAG) of versions, including:
- Linear evolution (v1 → v2 → v3)
- Forks (branches)
- Merges (reconciling branches)
- Special relations (repair, augmentation, porting to a platform)
-
G3 – OVN-Compliant Contribution Propagation: Extend versioning beyond Git semantics to include:
- Explicit tracking of who contributed to which version
- Propagation of contribution value upstream in the version graph, in line with the OVN model and license.
-
G4 – Non-Breaking Addition: Implement versioning as an additional layer on top of existing:
EconomicResource/ResourceSpecification- Digital Resource Integrity manifests
- Governance and PPR system
2. High-Level Requirements
2.1 Versioned Entity Model
-
R-VERS-01 – Base Identity vs Version Nodes
The system shall distinguish between:- A base identity (“Versioned Entity”) that persists through its versions
- Individual version nodes that represent specific states or variants
-
R-VERS-02 – Common Model for All Resource Types
The same versioning model shall support:- Material resource instances (e.g. “CNC #42”)
- Material resource designs (specifications, assemblies)
- Digital resources (software releases, CAD, documents)
- Application-level resources (Nondominium hApp itself)
-
R-VERS-03 – DAG of Versions
The system shall represent versions as nodes in a DAG (no cycles), supporting:InitialversionsEvolvedFrom(linear changes)ForkedFrom(branches)MergedFrom(multiple parents)RepairedFrom,AugmentedFrom,PortedToPlatform, etc.
2.2 Material Resources
-
R-VERS-MAT-01 – Structural Changes as Versions
For material resources, the system shall create new version nodes when there are structural or functional changes, such as:- Significant repairs
- Augmentations (e.g. a stool to which one adds a backrest)
- Upgrades (e.g. new motor, new controller)
-
R-VERS-MAT-02 – Simple Updates vs Versions
Non-structural updates (quantity, location, temporary states) shall continue to use existingEconomicResourceUpdatesand do not create new version nodes. -
R-VERS-MAT-03 – Instance vs Design
The system shall distinguish:- Versioning of the generic design (
ResourceSpecification) - Versioning of a specific instance (
EconomicResource) and must be able to link both graphs when appropriate.
- Versioning of the generic design (
2.3 Digital Resources
-
R-VERS-DIG-01 – Manifest-Backed Versions
Each digital resource version shall be associated with a digital integrity manifest (Merkle root, chunk hashes, etc.) as specified in the Digital Resource Integrity requirements. -
R-VERS-DIG-02 – Git Alignment (Optional)
When a resource is developed in Git or a similar VCS, the versioning model shall be able to:- Store a reference to the Git commit/tag
- Use Git semantics (branches, merges) as hints for version DAG construction
-
R-VERS-DIG-03 – Composite Digital Resources
The system shall support composite digital resources whose versions depend on versions of sub-resources (libraries, modules, CAD sub-assemblies), aligning with the fractal/composable architecture.
2.4 Nondominium hApp as a Resource
-
R-VERS-APP-01 – Application as Versioned Entity
The Nondominium hApp shall be modeled as a Versioned Entity of type “Application”, with:- A base identity (“Nondominium hApp”)
- A set of
ResourceVersionnodes representing releases (e.g.v1.0.0,v2.0.0-org).
-
R-VERS-APP-02 – Release Versioning
Each release version of the hApp shall:- Reference its hApp manifest and/or DNA/Web hApp bundles
- Have a semantic version label (e.g.
v1.3.0-org) - Be linked via
EvolvedFrom,ForkedFrom, etc. to previous versions
-
R-VERS-APP-03 – Forks & Flavors
Forks of Nondominium (e.g. pure P2P vs ERP/Tiki-focused variants) shall:- Be created as new branches in the version DAG (or as new entities that
ForkedFromthe original) - Maintain affiliation links required by the OVN license
- Be created as new branches in the version DAG (or as new entities that
-
R-VERS-APP-04 – Compatibility Metadata
Application versions shall be able to describe:- Supported deployment contexts (Pure P2P, Organizational, Mixed)
- Compatibility ranges for data formats and bridge protocols.
3. Version Graph & Affiliation Semantics
-
R-VERS-GRAPH-01 – Typed Relations
The system shall support typed relations between versions, at minimum:InitialEvolvedFromForkedFromMergedFromRepairedFromAugmentedFromPortedToPlatform(e.g. port to Tiki, ERP, other UI)
-
R-VERS-GRAPH-02 – Multiple Parents
Version nodes shall support multiple parents (merge scenarios). -
R-VERS-GRAPH-03 – Traversal
The system shall allow:- Traversal from a version to its ancestors (provenance)
- Traversal from a version to its descendants (evolution paths)
- Extraction of full affiliation trees for OVN accounting.
4. Contribution Propagation (OVN Model)
-
R-VERS-OVN-01 – Version-Level Contributions
The system shall be able to attach contribution records to specific versions, indicating:- Who contributed (Agent)
- In what role (e.g. design, implementation, repair, integration, translation)
- Links to relevant PPRs (Private Participation Receipts)
-
R-VERS-OVN-02 – Upstream Propagation
OVN accounting processes shall be able to:- Walk the version graph upstream from a given version
- Aggregate contribution information according to OVN rules
- Respect the OVN license, ensuring appropriate recognition and value flow to previous contributors.
-
R-VERS-OVN-03 – License Integrity
Versioning shall not allow “cutting off” affiliation; all forks and derived versions must retain:- Links to their ancestors
- References to the OVN license and model.
5. Integration with Existing Nondominium Architecture
-
R-VERS-INT-01 – Non-Breaking Addition
Versioning shall be implemented as an additional zome / module (e.g.zome_versioning) that:- References existing entries (
EconomicResource,ResourceSpecification, manifests, etc.) - Does not change the core data model of existing zomes.
- References existing entries (
-
R-VERS-INT-02 – Event-Triggered Version Creation
Certain EconomicEvents (e.g. repair, augmentation, major upgrade, new hApp release) shall be able to trigger:- Creation of a new version node
- Linking to the corresponding process and PPRs.
-
R-VERS-INT-03 – ValueFlows Compatibility
Version information shall:- Integrate cleanly with ValueFlows concepts (Resources, Events, Agents)
- Respect the Knowledge / Plan / Observation layering.
-
R-VERS-INT-04 – Digital Resource Integrity Alignment
For digital resources, versioning shall:- Reuse the manifest-based integrity model
- Allow verification of specific versions through their manifests and Merkle roots.
6. UX & API Considerations (High-Level, Post-MVP)
-
R-VERS-UX-01 – Human-Friendly Version View
Users shall be able to:- See a version history and fork graph for a given resource
- Distinguish between minor updates and major forks.
-
R-VERS-UX-02 – Semantic Version Actions
Beyond “update resource”, the UI/API shall support actions like:- “Declare new version (repair/augmentation)”
- “Fork this resource / fork Nondominium”
- “Merge branches” (where appropriate).
-
R-VERS-UX-03 – OVN-Aware Attribution View
Users shall be able to:- Inspect who contributed to which versions
- Understand how contributions propagate across forks and merges.
7. Post-MVP Status
- These requirements are explicitly post-MVP and will be addressed after the first Nondominium proof-of-concept is complete.
- Early implementation steps will likely focus on:
- Treating the Nondominium hApp itself as a versioned Application Resource
- Adding basic version tracking for key digital resources (code, manifests, critical designs)
- Gradually extending to full material resource versioning and OVN-aware contribution propagation.
Nondominium itself is a Resource. People will be able to fork Nondominium to create versions that better match their use, within the constraints of the OVN license, and this versioning architecture is designed to make those forks explicit, accountable, and economically integrated.
author:
- Max Wardeh copyright: link: "https://creativecommons.org/licenses/by/4.0/" text: Creative Commons Attribution 4.0 International License type: CC-BY date: day: 26 month: 01 year: 22 journal: publisher-name: Internet of Production Alliance title: Internet of Production Alliance link-citations: true title: Open Know-How Specification
1. Introduction
Open Know-How is all about sharing knowledge on how to make things. With dozens of open hardware organisations and over 80 content-hosting platforms and thousands of designers sharing open hardware designs, there is little consistency as to how know-how is documented or shared. Makers struggle to locate what they need, not knowing which platform to find it, what the intended use is and therefore struggle to adapt designs. Whilst the knowledge is 'open', it is not freely flowing in the spirit that open-ness suggests.
The objective of this specification is to improve the open-ness of know-how for making hardware by improving the discoverability, portability and translatability of knowledge.
Knowledge, unlike data or information, is tacit. Documentation and representation of knowledge can take different forms for different types of hardware and audience, and specifying how knowledge is represented can limit innovation and usability in different contexts. Therefore, this specification introduces a maturity model for increasing specifications for knowledge. The intent is that a designer or platform can choose to adopt this specification appropriately, rather than an over-prescriptive approach that deters adoption. Later iterations of this standard will include specifications for different representations of knowledge, but at this stage the scope is limited to supporting the discoverability of open hardware regardless of where it resides on the World Wide Web.
1.1. A conceptual model for the maturity of interoperable Open Know-How
This specification introduces a progressive approach to making knowledge about hardware interoperable. Through the maturity levels defined in the table below.
+------------------------+---+ | Maturity Level | * | | | * | | | D | | | e | | | s | | | c | | | r | | | i | | | p | | | t | | | i | | | o | | | n | | | * | | | * | +========================+===+ | Level 1: \ | A | | Discoverable Know-How | l | | | l | | | o | | | w | | | s | | | k | | | n | | | o | | | w | | | - | | | h | | | o | | | w | | | t | | | o | | | b | | | e | | | d | | | i | | | s | | | c | | | o | | | v | | | e | | | r | | | e | | | d | | | , | | | i | | | n | | | d | | | e | | | x | | | e | | | d | | | a | | | n | | | d | | | l | | | i | | | n | | | k | | | e | | | d | | | t | | | o | | | u | | | s | | | i | | | n | | | g | | | m | | | e | | | t | | | a | | | - | | | d | | | a | | | t | | | a | | | a | | | b | | | o | | | u | | | t | | | t | | | h | | | e | | | t | | | h | | | i | | | n | | | g | | | a | | | n | | | d | | | t | | | h | | | e | | | l | | | o | | | c | | | a | | | t | | | i | | | o | | | n | | | o | | | f | | | k | | | n | | | o | | | w | | | - | | | h | | | o | | | w | | | . | +------------------------+---+ | Level 2: \ | P | | Portable Know-How | r | | | o | | | v | | | i | | | d | | | e | | | s | | | a | | | f | | | o | | | r | | | m | | | a | | | t | | | a | | | n | | | d | | | s | | | t | | | r | | | u | | | c | | | t | | | u | | | r | | | e | | | f | | | o | | | r | | | k | | | n | | | o | | | w | | | - | | | h | | | o | | | w | | | s | | | o | | | t | | | h | | | a | | | t | | | i | | | t | | | i | | | s | | | r | | | e | | | p | | | r | | | e | | | s | | | e | | | n | | | t | | | e | | | d | | | i | | | n | | | a | | | c | | | o | | | n | | | s | | | i | | | s | | | t | | | e | | | n | | | t | | | f | | | o | | | r | | | m | | | a | | | t | | | a | | | n | | | d | | | c | | | a | | | n | | | b | | | e | | | e | | | a | | | s | | | i | | | l | | | y | | | m | | | o | | | v | | | e | | | d | | | b | | | e | | | t | | | w | | | e | | | e | | | n | | | p | | | l | | | a | | | t | | | f | | | o | | | r | | | m | | | s | | | . | +------------------------+---+ | Level 3: \ | S | | Distributed Know-How | u | | | p | | | p | | | o | | | r | | | t | | | s | | | i | | | n | | | t | | | e | | | r | | | o | | | p | | | e | | | r | | | a | | | b | | | i | | | l | | | i | | | t | | | y | | | , | | | c | | | r | | | e | | | a | | | t | | | i | | | o | | | n | | | a | | | n | | | d | | | a | | | g | | | g | | | r | | | e | | | g | | | a | | | t | | | i | | | o | | | n | | | o | | | f | | | k | | | n | | | o | | | w | | | - | | | h | | | o | | | w | | | a | | | b | | | o | | | u | | | t | | | a | | | t | | | h | | | i | | | n | | | g | | | b | | | y | | | d | | | i | | | f | | | f | | | e | | | r | | | e | | | n | | | t | | | d | | | e | | | s | | | i | | | g | | | n | | | e | | | r | | | s | | | a | | | n | | | d | | | m | | | a | | | k | | | e | | | r | | | s | | | w | | | i | | | t | | | h | | | o | | | u | | | t | | | c | | | e | | | n | | | t | | | r | | | a | | | l | | | i | | | s | | | e | | | d | | | c | | | o | | | n | | | t | | | r | | | o | | | l | | | o | | | f | | | t | | | h | | | e | | | k | | | n | | | o | | | w | | | - | | | h | | | o | | | w | | | . | +------------------------+---+
The mandatory aspects of this specification are kept to a minimum to lessen the friction for those who want to make their know-how discoverable. The intent behind the maturity model as presented is that the more of the recommended and permissive aspects of this specification that are adopted, the more open the know-how becomes.
To support the use of know-how by speakers of different languages, translation of Know-How is accommodated at all maturity levels.
1.2. About the authors
1.2.1. Development of specification
This specification has been developed by members of the Open Know-How Working Group, part of the MakerNet Alliance, and supported by the Shuttleworth Foundation. The following have contributed directly towards the development of this standard:
+-------------------------+---+ | Name | * | | | * | | | O | | | r | | | g | | | a | | | n | | | i | | | s | | | a | | | t | | | i | | | o | | | n | | | * | | | * | +=========================+===+ | Jérémy Bonvoisin | U | | | n | | | i | | | v | | | e | | | r | | | s | | | i | | | t | | | y | | | o | | | f | | | B | | | a | | | t | | | h | +-------------------------+---+ | Richard Bowman | U | | | n | | | i | | | v | | | e | | | r | | | s | | | i | | | t | | | y | | | o | | | f | | | B | | | a | | | t | | | h | +-------------------------+---+ | Andre Maia Chagas | T | | | h | | | e | | | U | | | n | | | i | | | v | | | e | | | r | | | s | | | i | | | t | | | y | | | o | | | f | | | S | | | u | | | s | | | s | | | e | | | x | | | , | | | M | | | o | | | z | | | i | | | l | | | l | | | a | | | F | | | e | | | l | | | l | | | o | | | w | | | 1 | | | 8 | | | / | | | 1 | | | 9 | +-------------------------+---+ | Kaspar Emanuel | K | | | i | | | t | | | s | | | p | | | a | | | c | | | e | | | . | | | o | | | r | | | g | +-------------------------+---+ | Martin Häuer | O | | | S | | | E | | | G | | | e | | | r | | | m | | | a | | | n | | | y | +-------------------------+---+ | Brynmor John | F | | | i | | | e | | | l | | | d | | | R | | | e | | | a | | | d | | | y | +-------------------------+---+ | Andrés Barreiro | W | | | i | | | k | | | i | | | f | | | a | | | c | | | t | | | o | | | r | | | y | +-------------------------+---+ | Kshitiz Khanal | K | | | a | | | t | | | h | | | m | | | a | | | n | | | d | | | u | | | L | | | i | | | v | | | i | | | n | | | g | | | L | | | a | | | b | | | s | +-------------------------+---+ | Andrew Lamb (Chair) | F | | | i | | | e | | | l | | | d | | | R | | | e | | | a | | | d | | | y | | | , | | | S | | | h | | | u | | | t | | | t | | | l | | | e | | | w | | | o | | | r | | | t | | | h | | | F | | | e | | | l | | | l | | | o | | | w | +-------------------------+---+ | Anna Lowe | M | | | a | | | n | | | u | | | f | | | a | | | c | | | t | | | u | | | r | | | i | | | n | | | g | | | C | | | h | | | a | | | n | | | g | | | e | +-------------------------+---+ | Jenny Molloy | U | | | n | | | i | | | v | | | e | | | r | | | s | | | i | | | t | | | y | | | o | | | f | | | C | | | a | | | m | | | b | | | r | | | i | | | d | | | g | | | e | +-------------------------+---+ | Neil Noble | e | | | x | | | - | | | P | | | r | | | a | | | c | | | t | | | i | | | c | | | a | | | l | | | A | | | c | | | t | | | i | | | o | | | n | +-------------------------+---+ | Nathan Parker | M | | | a | | | k | | | e | | | r | | | N | | | e | | | t | | | . | | | W | | | o | | | r | | | k | +-------------------------+---+ | Jon Schull | e | | | - | | | N | | | a | | | b | | | l | | | e | +-------------------------+---+ | Balthas Seibold | G | | | I | | | Z | +-------------------------+---+ | Julian Stirling | U | | | n | | | i | | | v | | | e | | | r | | | s | | | i | | | t | | | y | | | o | | | f | | | B | | | a | | | t | | | h | +-------------------------+---+ | Emilio Velis | A | | | p | | | p | | | r | | | o | | | p | | | e | | | d | | | i | | | a | +-------------------------+---+ | Michael Weinberg | O | | | p | | | e | | | n | | | S | | | o | | | u | | | r | | | c | | | e | | | H | | | a | | | r | | | d | | | w | | | a | | | r | | | e | | | A | | | s | | | s | | | o | | | c | | | i | | | a | | | t | | | i | | | o | | | n | | | ( | | | O | | | S | | | H | | | W | | | A | | | ) | +-------------------------+---+ | Tobey Wenzel | D | | | o | | | c | | | u | | | b | | | r | | | i | | | c | | | k | | | s | +-------------------------+---+ | Diderik van Wingerden | T | | | h | | | i | | | n | | | k | | | - | | | i | | | n | | | n | | | o | | | v | | | a | | | t | | | i | | | o | | | n | | | . | | | c | | | o | | | m | +-------------------------+---+
1.2.2. Technical authoring
Technical authoring for version 1 has been undertaken by Barbal Limited.
2. Scope
This specification provides a mechanism for exchanging know-how for making things. It aligns with the Open Source Hardware Definition [1] and other efforts to standardise approaches for documenting how to make things.
This version specifies the approach to Open Know-How Level 1 by providing a schema for providing metadata in a consistent format and a mode of information exchange enabling indexing and discovery of open hardware by stakeholders.
The intended audience is:
-
Designers who publish their documentation in self-hosted or generic file repositories
-
Platforms that provide tools for designers to publish their documentation online
-
Platforms that aggregate, index or link to open hardware designs
3. Terms and definitions
3.1. know-how
knowledge for how to make a thing
Note: Whilst know-how can be tacit, this specification is concerned with know-how represented in documentation, drawings, digital models, source code and other media
3.2. design
specification of the thing in terms of its form and functionality
3.3. designer
person who produces designs and/or know-how for making things
3.4. make
manufacture, construct, assemble, print, configure, compile or create using another method
3.5. maker
person who makes using know-how
3.6. platform
website or web application that provides tools for hosting or processing know-how
3.7. thing
physical item defined by know-how
3.7.1. derivative
thing where the know-how is based on modifications to the know-how for another thing
3.7.2. original
thing from which the know-how a derivative or variant is created
3.7.3. sub-thing
thing that is used as a component, part or module of another thing
3.7.4. variant
sub-version of a thing which has specific documentation compiled to support that specific variant
Example: Where a component of a thing can be printed, cast or whittled and the original documentation contains making instructions for each. The variant documentation only contains making instructions for that specific variant.
Note: Does not include translations (which are handled separately) nor adapted versions of the same know-how (e.g. published in alternative formats).
3.8. user
person who uses the made thing
4. Specification for Open Know-How Level 1 -- Discoverable Know-How
4.1. Introduction
This section specifies a mechanism for making know-how discoverable. It describes a schema for meta-data relating to designs and the location of associated know-how through a manifest.
Mandatory and recommended provisions are made along with other fields that are defined. A template is provided to aid production of the manifest.
4.2. Method of information exchange -- the Open Know-How Manifest
The Open Know-How Manifest accompanies the Know-How that is documented in structured or unstructured formats. The purpose is to allow automated indexings of key properties about the thing and to identify and link to the associated documentation.
The manifest shall be used to define a version of the thing. A separate manifest should be produced for each new version, variant or derivative of the thing.
The manifest should be revised when any of the properties it defines are changed.
4.3. Structure of the Open Know-How Manifest as a file
4.3.1. Format
Where the manifest is contained in a file, the Open Know-How Manifest uses the YAML v1.2 format [2].
Note: YAML has been selected as the file format for its ease of producing and reading by people.
Encoding shall be UTF-8.
The character set shall be Unicode.
4.3.2. Filename
The file containing the manifest shall begin with "okh".
The file extension shall be ".yml".
Example: "okh.yml"
The thing's name may be included in the filename, prefixed with a hyphen.
Example: "okh-thingname.yml"
4.3.3. Declaration
The manifest shall be declared by including the following as line 1 and 2:
%Open Know-How Manifest 1.0
---
4.3.4. Absolute and relative links
Where a field requires a link to an external resource or path, absolute or relative paths may be used.
Relative paths shall be relative to the location of the Open Know-How Manifest in the documentation repository.
Absolute paths shall include the full path to the resource including the protocol.
Paths shall use forward slashes.
4.3.5. Location of the manifest
Where a file repository is used, the manifest should be stored in the root folder.
Where a platform does not use a file repository, the manifest should be linked to from the Project Homepage.
4.4. Embedding manifest information in a web page
Where platforms choose to adopt the manifest by embedding the schema into pages, rather than producing a separate manifest file, the schema presented in this section may be applied as a microformat within the page HTML using classes.
To declare the open know-how schema, apply the "open-know-how v0-1"
classes to the parent HTML element.
Where this approach is adopted, the manifest content shall be contained within a single web page. A manifest shall not be distributed across more than one page.
4.5. Manifest metadata
4.5.1. Date created
Fieldname: date-created
Purpose: Indicates the date the manifest was originally created.
Format: YYYY-MM-DD
4.5.2. Date last updated
Fieldname: date-updated
Purpose: Indicates the date the manifest was last edited.
Format: YYYY-MM-DD
4.5.3. Manifest content originator
Fieldname: manifest-author
Purpose: States the person who has created and is responsible for the content in the manifest.
Note: As the manifest can be automatically generated, this relates only to the content of the manifest and not the production of the manifest itself.
Format:
manifest-author:
name: [value] # Text
affiliation: [value] # Text
email: [value] # Email address
Rules: The name field is required. Other fields are optional.
4.6. Descriptive properties
4.6.1. Title
Fieldname: title
Purpose: A title to identify the thing.
Format: Text.
Rules: Required.
4.6.2. Description
Fieldname: description
Purpose: Describes the thing.
Format: Paragraph.
Rules: Required.
4.6.3. Intended use
Fieldname: indended-use
Purpose: Informs the maker for what purpose the designer intends the thing to be used. In particular, make reference to the context and type of users.
Format: Paragraph.
Rule: Recommended.
4.6.4. Keywords
Fieldname: keywords
Purpose: Provides a small number of terms that can be used to help identify.
Format: Array of text.
Rule: At least one keyword is recommended.
4.6.5. Project Homepage
Fieldname: project-link
Purpose: Where the thing or associated project has a web presence that is separate from the documentation (e.g. a marketing page), links to the web resource.
Format: Absolute path.
Rules: At least one of the project-link or documentation-homefields
is required.
4.6.6. Health and safety notice
Fieldname: health-safety-notice
Purpose: Highlight health and safety risks and/or necessary precautions that the maker should be aware of as part of the decision to make the thing.
Format: Paragraph
Rules: Not an exhaustive list of all risks associated with the thing, but a summary of the most important risks and hazards associated with making, using, maintaining or disposing. Knowledge of such issues could influence the decision to make the thing.
4.6.7. Primary contact
Fieldname: contact
Purpose: Provides a point of contact for people who wish to discuss the thing.
Format:
contact:
name: [value] # Text
affiliation: [value] # Text
email: [value] # Email address
social: # Lists other web-presences through which contact can be made
- platform: [value] # Text
user-handle: [value] # Text
Rules: Where used, provide at least one email address or social media user handle.
4.6.8. Contributors
Fieldname: contributors
Purpose: Credits the contributors to the know-how. May include people
who designed, produced documentation, tested the documentation by
making, reviewed and/or edited documentation, or made another
contribution as deemed valued by the project or manifest-author.
Format: List of contributors
contributors:
- name: [value] # Text
affiliation: [value] # Text
email: [value] # Email address
Rules: Recommended. A name is required for each contributor listed.
4.6.9. Image
Fieldname: image
Purpose: Provides a graphical representation of the thing.
Format: Absolute or relative path to image file.
Rule: Recommended.
4.6.10. Thing version
Fieldname: version
Purpose: Defines the version of the thing that is represented by this manifest.
Format: Text.
4.6.11. Stage of development
Fieldname: development-stage
Purpose: Indicates the maturity of the design and documentation development.
Format: Text
Note: The Open Know-How Working Group intends to develop recommended values for this field to support commonality across manifest files. This is likely to be made by reference to a external standard.
4.6.12. Has been made
Fieldname: made
Purpose: Indicates whether the thing has been made and verifies that it is makeable.
Format: Boolean -- "true" or "false"
4.6.13. Has been made independently
Fieldname: made-independently
Purpose: Indicates whether the thing has been made using the documentation by someone who was not a contributor to the design or documentation and, therefore, verifies that the documentation is sufficient to make the thing.
Format: Boolean -- "true" or "false"
4.6.14. Standards used
Fieldname: standards-used
Purpose: Indicates any standards that have been used in developing the design or documentation.
Format: Array of arrays.
standards-used:
- standard-title: [value] # Required where used | Title of the standard used in developing the design or documentation
publisher: [value] # Publisher of the standard
reference: [value] # Reference indentifier of the standard (e.g. ISO 9001)
certification: # If certification has been granted confirming compliance with the standard
- certifier: [value] # Individual or organisation granting the certification. Use "Self" for self-certification
date-awarded: [value] # Date certification was granted
link: [value] # Link to evidence of certification (e.g. certificate). Use an an absolute path to an external resource or an absolute or relative path to evidence within the documentation.
Rules: Do not list standards to be used by the maker or user, instead these should be referenced in the relevant documentation.
4.6.15. Derivative of
Fieldname: derivative-of
Purpose: Where the thing is a derivative of a different thing (e.g. the documentation has been forked), links to the original thing.
Format:
derivative-of:
title: [value] # text | Title of the original
manifest: [value] # URL - Absolute path | OKH manifest location
web: [value] # URL - Absolute path | web presence location
Rules: Where derivative-of used, the title sub-field is required.
4.6.16. Variant of
Fieldname: variant-of
Purpose: Where the thing is a variant, links to the original.
Format:
variant-of:
title: [value] # text | Title of the original
manifest: [value] # URL - Absolute path | OKH manifest location
web: [value] # URL - Absolute path | web presence location
4.6.17. Sub-thing
Fieldname: sub
Purpose: Where the design uses sub-components, sub-assemblies etc that are also available as open know-how, links to the documentation.
Format: List of sub-things
sub:
title: [value] # text | Title of the original
manifest: [value] # URL - Absolute path | OKH manifest location
web: [value] # URL - Absolute path | web presence location
License information
4.6.18. License
Fieldname: License
Purpose: States the licenses under which the thing is made available.
Format:
license:
hardware: [value]
documentation: [value]
software: [value]
Rules: At least one license is required. All three license types are recommended. The format should be an SPDX identifier [3]. See https://spdx.org/licenses/
4.6.19. Licensor
Fieldname: licensor
Purpose: States who is licensing the thing.
Format:
licensor:
name: [value] # text
affiliation: [value] # text
email: [value] # email address
4.8. Documentation
4.8.1. Entry point to documentation
Fieldname: documentation-home
Purpose: Provides a URL entry point to the documentation.
Format: Absolute path.
Rules: At least one of the project-link or documentation-homefields
is required.
4.8.2. Documentation archive
Fieldname: archive-download
Purpose: Links to a location from which the full documentation can be downloaded as an archive (e.g. zip file).
Format: Absolute or relative path.
4.8.3. Design Files
Fieldname: design-files
Purpose: Links to design files.
Format: Absolute or relative path.
design-files:
- path: [value] # Absolute or relative path
title: [value] # text
Rules: Recommended. May either refer to a location in which files are stored or can list and link to design files individually. In the former case, the title field is not required.
4.8.4. Schematics
Fieldname: schematics
Purpose: Links to schematics. Includes all types of engineering drawings.
Format: Absolute or relative path
schematics:
- path: [value] # Absolute or relative path
title: [value] # text
4.8.5. Bill of Materials
Fieldname: bom
Purpose: Links to the bill of materials.
Format: Absolute or relative path.
Rules: Recommended. Should be provided as a single file.
4.8.6. List of Tools
Fieldname: tool-list
Purpose: Links to a list of tools required to make the thing.
Format: Absolute or relative path.
Rules: Recommended. Should be provided as a single file.
4.8.7. Assembly Instructions
Fieldname: making-instructions
Purpose: Links to the making instructions, e.g. assembly instructions.
Format:
making-instructions:
- path: [value] # Absolute or relative path
title: [value] # text
Rules: Recommended. May include more than one assembly instructions, e.g. where the instructions are provided in different formats.
4.8.8. Manufacturing files
Fieldname: manufacturing-files
Purpose: Links to the manufacturing files, such as 3D printing files.
Format:
manufacturing-files:
- path: [value] # Absolute or relative path
title: [value] # text
Rules: Recommended where applicable.
4.8.9. Risk Assessment
Fieldname: risk-assessment
Purpose: Links to the risk assessment.
Format:
risk-assessment:
- path: [value] # Absolute or relative path
title: [value] # text
Rules: Recommended. May include more than one, e.g. where different assessments cover different aspects or making, operation, maintenance and disposal.
4.8.10. Tool settings and documentation
Fieldname: tool-settings
Purpose: Links to settings for tools and machines.
Format:
tool-settings:
- path: [value] # Absolute or relative path
title: [value] # text
Rules: Recommended where applicable. May include more than one.
4.8.11. Quality control instructions
Fieldname: quality-instructions
Purpose: Links to instructions for testing and/or quality management.
Format:
quality-instructions:
- path: [value] # Absolute or relative path
title: [value] # text
Rules: Recommended. May include more than one.
4.8.12. Operating instructions
Fieldname: operating-instructions
Purpose: Links to instructions for operating the thing.
Format:
operating-instructions:
- path: [value] # Absolute or relative path
title: [value] # text
Rules: Recommended.
4.8.13. Maintenance instructions
Fieldname: maintenance-instructions
Purpose: Links to instructions for maintaining the thing.
Format:
maintenance-instructions:
- path: [value] # Absolute or relative path
title: [value] # text
Rules: Recommended.
4.8.14. Disposal instructions
Fieldname: disposal-instructions
Purpose: Links to instructions for disposing the thing at the end of its life.
Format:
disposal-instructions:
- path: [value] # Absolute or relative path
title: [value] # text
Rules: Recommended.
4.8.15. Software
Fieldname: software
Purpose: Links to source code repository or software executables used by the thing.
Format:
software:
- path: [value] # Absolute or relative path
title: [value] # text
Rules: Recommended where applicable. May include more than one.
4.9. Language and translation
4.9.1. General
Language shall be declared as defined in BCP 47 [4], which prescribes the format for identifying languages as the ISO 639 [5] codes for representing languages followed by the ISO 3166 [6] code for the region in which the language is used. Use the Alpha-2 code for each where available.
4.9.2. Manifest Language
Fieldname: manifest_language
Purpose: States the language in which the manifest has been produced.
Format: [language-code]-[region]
Rule: ISO 639 [5] language code. Use the Alpha-2 code where available. Optionally, the ISO 3166 [6] country code may be included as per BCP 47 [4].
4.9.3. Documentation Language
Fieldname: documentation_language
Purpose: States the language in which the documentation has been produced.
Format: [language-code]-[region]
Rule: ISO 639 [5] language code. Use the Alpha-2 code where available. Optionally, the ISO 3166 [6] country code may be included as per BCP 47 [4].
4.9.4. Translated Manifest
Fieldname: manifest-is-translation
Purpose: Where this manifest is a translation of another, links to the original.
Format:
manifest-is-translation:
title: [value] # text | Title of the original
manifest: [value] # URL - Absolute path | OKH manifest location
web: [value] # URL - Absolute path | web presence location
lang: [language]-[region] # language of original
4.9.5. Translated Documentation
Fieldname: documentation-is-translation
Purpose: Where this manifest references documentation that is translated, links to the original.
documentation-is-translation:
title: [value] # text | Title of the original
manifest: [value] # URL - Absolute path | OKH manifest location
web: [value] # URL - Absolute path | web presence location
lang: [language]-[region] # language of original
4.10. Extending the manifest schema
The manifest schema may be extended where this specification is not sufficient to meet the needs of the project.
When extending the schema, only siblings may be added to defined fields. New children shall not be added to fields where a child is not already defined.
Users are encouraged to share any extension of the schema with the Open Know-How Working Group so that it can be considered for future revisions of this specification.
4.11. Version management of the manifest
This specification does not include provision for version management of the manifest. The context of the file from the HTTP headers, repository or page hosting the manifest can give information relating to revision or status of the manifest relative to other versions that can be located on the world wide web.
4.12. Template
%Open know-how manifest 0.1
---
# The content of this manifest file is licensed under a Creative Commons Attribution 4.0 International License.
# Licenses for modification and distribution of the hardware, documentation, source-code, etc are stated separately.
# Remove any fields that are not used. Comments (beginning with '#') may also be removed.
# Manifest metadata
date-created: [value] # YYYY-MM-DD
date-updated: [value] # YYYY-MM-DD
manifest-author:
name: [value] # required | text
affiliation: [value] # text
email: [value] # email address
manifest-language: [language-code]-[region]
documentation-language: [language-code]-[region]
manifest-is-translation:
title: [value] # text | Title of the original
manifest: [value] # URL - Absolute path | OKH manifest location
web: [value] # URL - Absolute path | web presence location
lang: [language]-[region] # language of original
documentation-is-translation:
title: [value] # text | Title of the original
manifest: [value] # URL - Absolute path | OKH manifest location
web: [value] # URL - Absolute path | web presence location
lang: [language]-[region] # language of original
# Properties
title: [value] # required | text | A title to identify the thing
description: | # required | paragraph
[value]
intended-use: | # recommended | Paragraph
[value]
keywords: # At least one keyword is recommended | text array
- [keyword 1]
- [keyword 2]
project-link: [value] # At least project-link or documentation-home is required, otherwise recommended | absolute path URL
health-safety-notice: | # paragraph
[value]
contact:
name: [value] # text
affiliation: [value] # text
email: [value] # email address
social:
- platform: [value] # text
user-handle: [value] # text
contributors: # recommended
- name: [contributor 1] # text
affiliation: [value] # text
email: [value] # email address
image: [value] # recommended | absolute or relative path
version: [value] # text
development-stage: [value] # text
made: [true/false] # boolean - true or false
made-independently: [true/false] # boolean - true or false
standards-used:
- standard-title: [value] # Required where used | Title of the standard used in developing the design or documentation
publisher: [value] # Publisher of the standard
reference: [value] # Reference indentifier of the standard (e.g. ISO 9001)
certification: # If certification has been granted confirming compliance with the standard
- certifier: [value] # Individual or organisation granting the certification. Use "Self" for self-certification
date-awarded: [value] # Date certification was granted
link: [value] # Link to evidence of certification (e.g. certificate). Use an an absolute path to an external resource or an absolute or relative path to evidence within the documentation.
derivative-of:
title: [value] # text | Title of the original
manifest: [value] # URL - Absolute path | OKH manifest location
web: [value] # URL - Absolute path | web presence location
variant-of:
title: [value] # text | Title of the original
manifest: [value] # URL - Absolute path | OKH manifest location
web: [value] # URL - Absolute path | web presence location
sub:
title: [sub 1] # text | Title of the original
manifest: [value] # URL - Absolute path | OKH manifest location
web: [value] # URL - Absolute path | web presence location
# License
license: # At least one license is required | The format should be an SPDX identifier. See https://spdx.org/licenses/hardware: [value] # recommended | The license under which the hardware is released
hardware: [value] # recommended | The license under which the documentation is released
documentation: [value] # recommended | The license under which the documentation is released
software: [value] # recommended where software is used | The license under which the software is released
licensor:
name: [value] # text
affiliation: [value] # text
email: [value] # email address
# Documentation
documentation-home: [value] # At least one of the project-link or documentation-home fields is required | absolute path
archive-download: [value] # Absolute or relative path
design-files: # recommended
- path: [value] # Absolute or relative path
title: [value] # text
schematics: # recommended where applicable
- path: [value] # Absolute or relative path
title: [value] # text
bom: [value] # recommended | absolute or relative path | Direct the maker to the Bill of Materials
tool-list: [value] # recommended | absolute or relative path | Direct the maker to a list of tools required to make the thing
making-instructions: # recommended
- path: [value] # Absolute or relative path
title: [value] # text
manufacturing-files: # recommended where applicable
- path: [value] # Absolute or relative path
title: [value] # text
risk-assessment: # recommended
- path: [value] # Absolute or relative path
title: [value] # text
tool-settings: # recommended where applicable
- path: [value] # Absolute or relative path
title: [value] # text
quality-instructions:
- path: [value] # Absolute or relative path
title: [value] # text
operating-instructions: # recommended
- path: [value] # Absolute or relative path
title: [value] # text
maintenance-instructions: [value] # recommended
- path: [value] # Absolute or relative path
title: [value] # text
disposal-instructions: [value] # recommended
- path: [value] # Absolute or relative path
title: [value] # text
software: # recommended where applicable | Source code or executable software that the thing uses
- path: [value] # Absolute or relative path
title: [value] # text
# User defined Fields
# Include any custom / extended fields here
5. Governance of this Specification
The Open Know-How Specification is governed by the Open Know-How Working Group.
Changes to the Specification are proposed in StandardsRepo.
Changes are voted on during meetings of the Open Know-How Working Group.
Proposers should consult the Working Group prior to proposing changes so that members can contribute to the development of proposals. This can increase the likelihood of the group accepting changes to the specification.
6. Bibliography
[1] Open Source Definition, Open Source Hardware Association, https://www.oshwa.org/definition/
[2] YAML Version 1.2, Oren Ben-Kiki, Clark Evans, Ingy döt Net, https://yaml.org/spec/1.2/spec.html
[3] SPDX License List, https://spdx.org/licenses/
[4] BCP 47 Tags for Identifying Languages, IETF, https://tools.ietf.org/html/bcp47
[5] Codes for the Representation of Names of Languages, Library of Congress, http://www.loc.gov/standards/iso639-2/php/code_list.php
[6] Country Codes -- ISO 3166, ISO, https://www.iso.org/iso-3166-country-codes.html
Note: Country codes as listed in ISO 3166 can be found using the ISO Online Browsing Platform https://www.iso.org/obp/ui/#search
Project-Type NDO Specifications (Post-MVP)
Status: Post-MVP Requirements
Created: 2026-06-16
Relates to: ndo_prima_materia.md, resources.md, open-know-how-iopa.md, digital-resource-integrity.md, ndo-versioning.md, fractal-composable-resource-architecture.md
Sibling NDO type: source-ndo-requirements.md — Source-NDO covers generative ecological systems (watersheds, rivers, forests) that yield resources and receive ecological effects. Where project-type NDOs specify design intent, Source-NDOs specify generative ecological conditions. Both use the NDO three-layer model and governance-as-operator pattern; Source-NDOs add an adaptive cybernetic governance loop and the vf:Source ValueFlows extension.
External references: OSHWA — Best Practices for Open Source Hardware 1.0, Open Know-How Specification (IOPA)
1. Problem Statement
A project-type NDO is a resource in development: an idea, design, prototype, or mature specification moving through LifecycleStage from Ideation toward Stable or Distributed. It may represent:
- a digital resource in development (software, digital book, CAD library), or
- a material resource in development (electronic board, sensor, furniture, tool).
For material project-type NDOs, the NDO on the DHT is not the physical artefact — it is the digital representation of that resource. When the design reaches Stable or Distributed, the specification bundle (blueprints, 3D models, fabrication instructions, user manual, BOM, firmware, etc.) is the shareable product in the cosmolocal sense described in ndo_prima_materia.md §4.3: anyone with the spec and appropriate fabrication capacity can produce a local instance.
Today the MVP ResourceSpecification entry carries only name, description, category, tags, and image URL. It does not model the structured know-how bundle that open hardware communities (OSHWA) and the Internet of Production Alliance (Open Know-How) have converged on as best practice, nor does it connect that bundle to NDO Layer 1 activation, DigitalAsset capability slots, or integrity manifests.
This document defines post-MVP requirements for how project-type NDOs shall represent mature specifications — synthesizing OSHWA sharing practices, Open Know-How Level 1 discoverability, and the Nondominium three-layer resource model.
2. Scope
2.1 In scope
- Layer 1 specification packages for project-type NDOs (
ResourceNature:Physical,Digital,Hybrid, and optionallyInformationfor pure documentation products). - Progressive completeness requirements matched to
LifecycleStage(complexity matching). - Mapping of OSHWA and Open Know-How artifact types to NDO data structures.
- Integrity, versioning, composability, and licensing requirements for specification assets.
- Governance preconditions for lifecycle transitions that claim fabrication-readiness (
Stable,Distributed).
2.2 Out of scope
- Layer 2 process tracking, PPR issuance, and custody of physical instances (
EconomicResource) — covered by existing governance andmany-to-many-flows.md. - Full Open Know-How Level 2 (portable structured bundles) and Level 3 (distributed aggregation) implementation — referenced as forward targets; Level 1 discoverability is the MVP target for this specification track.
- UI/wizard implementation details — see
ui_design.mdandspecifications/ui_architecture.md. - Replacing or duplicating
complete-resource-specification.md(extended property model for all NDO types); this document focuses on project-in-development specification bundles.
2.3 Normative dependencies
| ID | Requirement source |
|---|---|
| REQ-NDO-L1-01 – REQ-NDO-L1-06 | Layer 1 activation and asset attachment (ndo_prima_materia.md §9.2) |
| REQ-NDO-LC-01 – REQ-NDO-LC-07 | Lifecycle transitions (ndo_prima_materia.md §9.4) |
| REQ-NDO-CS-01 – REQ-NDO-CS-06 | Capability slot surface |
| R1 – R9 | Digital Resource Integrity (digital-resource-integrity.md) |
| R-VERS-* | Version DAG (ndo-versioning.md) |
3. Conceptual Model
3.1 Project-type NDO as specification carrier
flowchart TB
subgraph L0 ["Layer 0 — NondominiumIdentity"]
ID[name, property_regime, resource_nature, lifecycle_stage]
end
subgraph L1 ["Layer 1 — Specification (activated)"]
RS[ResourceSpecification]
GR[GovernanceRule entries]
PKG[SpecificationPackage metadata]
end
subgraph Assets ["Digital assets (CapabilitySlot: DigitalAsset)"]
OKH[Open Know-How manifest]
SRC[Original design files]
AUX[Auxiliary / export files]
BOM[Bill of materials]
DOC[Instructions and manuals]
SW[Software / firmware]
INT[Integrity manifest]
PHO[Photos / renderings]
end
subgraph L2 ["Layer 2 — Process (when active)"]
EV[EconomicEvents, Commitments, PPRs]
end
L0 -->|NDOToSpecification| RS
RS --> GR
RS --> PKG
L0 -->|CapabilitySlot DigitalAsset| Assets
L0 -->|NDOToProcess| L2
- Layer 0 holds immutable identity and lifecycle maturity (
LifecycleStage). - Layer 1 holds human-readable summary (
ResourceSpecification), embedded governance, and structured SpecificationPackage metadata describing the know-how bundle. - Digital assets (files, manifests, external repo pointers) attach via
DigitalAssetcapability slots on the Layer 0 hash (REQ-NDO-L1-06), not as opaque blobs insideResourceSpecification. - Layer 2 records contribution and validation activity around the evolving specification; it does not replace the specification bundle.
3.2 Original vs auxiliary design files (OSHWA)
Following OSHWA best practices, the system shall distinguish:
| Class | Role | NDO rule |
|---|---|---|
| Original design files | Native editable sources (CAD, KiCad, Inkscape, repo source tree) | Required for Stable physical/hybrid NDOs claiming open-source hardware status; auxiliary formats never substitute |
| Auxiliary design files | Interchange, manufacturing-ready, or view-only exports (STEP, STL, Gerber, PDF schematic) | Recommended; enables fabrication and review without proprietary tools |
| Documentation sources | Editable instructions (Markdown, wiki, ODT), not PDF-only | Recommended; supports fork and remix |
3.3 Open Know-How maturity alignment
Open Know-How defines progressive openness (open-know-how-iopa.md §1.1):
| OKH level | Intent | NDO mapping (post-MVP target) |
|---|---|---|
| Level 1 — Discoverable | Metadata manifest indexes know-how location | SpecificationPackage + OKH-compatible manifest as a DigitalAsset; DHT discovery via Layer 0 anchors |
| Level 2 — Portable | Consistent structured bundle format | Export/import of full specification package between NDO instances (future) |
| Level 3 — Distributed | Federated aggregation without central control | Cross-network indexing via Lobby / federation DNA (future) |
REQ-PROJ-SPEC- requirements below implement Level 1* as the baseline, with hooks for Level 2/3.
3.4 Sub-components and fractal composition
Material specifications rarely stand alone. A desk may reference open legs, a sensor board may reference an MCU module. Following the fractal composable resource model (fractal-composable-resource-architecture.md) and Open Know-How sub / derivative-of / variant-of fields:
- Sub-assemblies that are themselves maintained as open know-how shall be linked as child NDOs via
NDOToComponent(or equivalent) links, not duplicated inline. - Derivatives and variants shall use the version DAG (
ndo-versioning.md) withForkedFrom,EvolvedFrom, or OKH-aligned variant manifests.
4. SpecificationPackage Structure
The SpecificationPackage is post-MVP structured metadata attached to Layer 1. It describes what artifacts exist, where they live, and how complete the bundle is — without embedding file bytes in the DHT entry.
4.1 Core metadata (Open Know-How Level 1 — mandatory subset)
The following fields align with Open Know-How manifest §4.5–4.8. At minimum, a discoverable project specification shall expose:
| Field | OKH field | Required when |
|---|---|---|
| Title | title | Layer 1 active |
| Description | description | Layer 1 active |
| Documentation entry | documentation-home or project-link | Layer 1 active |
| Version label | version | Prototype and later |
| Development stage | development-stage | maps to LifecycleStage |
| License block | license (SPDX: hardware, documentation, software) | Stable and later |
| Language | manifest_language, documentation_language | recommended always |
Recommended OKH fields the NDO should support in SpecificationPackage or linked manifest:
indended-use,keywords,image,health-safety-notice,contact,contributorsmade,made-independently(fabrication verification flags)standards-used,derivative-of,variant-of,subdate-created,date-updated,manifest-author
4.2 Documentation artifact slots (OSHWA + OKH)
Each artifact type is a typed slot in the specification package, pointing to one or more DigitalAsset capability targets:
| Slot type | OSHWA element | OKH field | Physical | Digital | Hybrid |
|---|---|---|---|---|---|
Overview | Overview / introduction | (in description) | ✓ | ✓ | ✓ |
OriginalDesignFiles | Original design files | design-files | ✓ | ✓ (source) | ✓ |
AuxiliaryDesignFiles | Auxiliary / export files | schematics, manufacturing-files | ✓ | ✓ (build artifacts) | ✓ |
BillOfMaterials | BOM | bom | ✓ | optional | ✓ |
ToolList | (in making instructions) | tool-list | ✓ | ✓ (build deps) | ✓ |
MakingInstructions | Instructions — making | making-instructions | ✓ | ✓ (build) | ✓ |
OperatingInstructions | Instructions — using | operating-instructions | ✓ | ✓ (user docs) | ✓ |
MaintenanceInstructions | (OSHWA) | maintenance-instructions | ✓ | ✓ | ✓ |
DisposalInstructions | (OKH) | disposal-instructions | ✓ | — | ✓ |
DesignRationale | Design rationale | (documentation) | recommended | recommended | recommended |
SoftwareFirmware | Software and firmware | software | if applicable | ✓ | ✓ |
QualityInstructions | (OKH) | quality-instructions | recommended | recommended | recommended |
RiskAssessment | (OKH) | risk-assessment | recommended | optional | recommended |
ToolSettings | (OKH) | tool-settings | if applicable | — | if applicable |
Photos | Photos | image (+ gallery assets) | recommended | optional | recommended |
ArchiveDownload | (OKH) | archive-download | recommended | recommended | recommended |
IntegrityManifest | (NDO) | — | ✓ at Stable+ | ✓ at Stable+ | ✓ at Stable+ |
OpenKnowHowManifest | (OKH) | okh.yml | recommended | recommended | recommended |
4.3 Bill of materials requirements (OSHWA)
When a BOM is provided:
- It shall be a separate artifact (not inferred solely from CAD).
- Each line shall be mappable to design reference designators where applicable.
- Fields shall support at minimum: reference designator, description, part number, supplier(s), quantity, optional unit cost.
- BOM format shall be machine-readable (CSV, spreadsheet, or structured JSON) in addition to any human-readable export.
4.4 Software and firmware (OSHWA)
When the resource includes programmable logic:
- Source code shall be linked (repository URL or content-addressed archive), with build instructions.
- Build dependencies and toolchain versions shall be documented.
- Software license shall be declared separately (SPDX) in the license block.
- Firmware binary releases, if distributed, shall be content-addressed and listed in the integrity manifest.
4.5 Licensing (OSHWA + OKH)
The specification package shall declare licenses using SPDX identifiers for up to three channels:
hardware/ design files (e.g.CERN-OHL-2.0-W,CERN-OHL-2.0-P,Solderpad-2.1)documentation(e.g.CC-BY-4.0,CC-BY-SA-4.0)software(e.g.Apache-2.0,GPL-3.0-only)
Licenses with NC (non-commercial) or ND (no derivatives) clauses shall not be accepted for NDOs under PropertyRegime::Nondominium or Commons when governance claims open-source hardware compliance (aligned with OSHWA and Open Source Hardware Definition).
5. Lifecycle-Progressive Completeness
Specification burden shall match social complexity (resources.md §1.4, ndo_prima_materia.md §2.3). The governance zome may enforce minimum package completeness on lifecycle transitions.
5.1 Minimum artifacts by lifecycle stage
| LifecycleStage | Layer 1 | Minimum specification content |
|---|---|---|
Ideation | optional | Layer 0 only; name + intent in description |
Specification | activating | Title, description, intended use; draft design pointers optional |
Development | active | Original design files or documented repo; WIP BOM encouraged |
Prototype | active | Original design files, auxiliary exports for primary fabrication path, BOM, making instructions (WIP acceptable), version label |
Stable | active | Full fabrication package (see §5.2); integrity manifest; licenses; operating instructions |
Distributed | active | Stable requirements + evidence of independent fabrication (made-independently) or peer validation record |
Active | active | Stable package maintained; change control via versioning (REQ-NDO-L1-03) |
Hibernating | dormant | Package frozen; is_active: false on spec; assets remain readable |
Deprecated / EndOfLife | archived | Package archived; successor NDO link if deprecated |
5.2 Stable material resource — “complete representation” definition
For a project-type material NDO at LifecycleStage::Stable or later, a complete digital representation shall include all of the following unless explicitly marked not applicable (N/A) with governance-approved rationale:
- Overview — general-audience introduction with photo or rendering
- Original design files — editable sources for every custom part (CAD, PCB, drawings)
- Auxiliary manufacturing files — at least one fabrication-ready export per custom part (e.g. STL, Gerber, DXF)
- Bill of materials — separate, reference-designator-aligned BOM
- Making instructions — fabrication and assembly, tools required, special processes noted
- Operating instructions — setup, use, safety notices (
health-safety-noticesummary at minimum) - Software/firmware — if any; otherwise explicit
N/A - License block — SPDX for design, documentation, and software channels
- Integrity manifest — content-addressed manifest per
digital-resource-integrity.mdcovering all bundled assets - Version identifier — correlates spec bundle with physical instances and OKH manifest
Recommended additions: maintenance instructions, quality/test instructions, design rationale, photos from multiple build stages, archive-download zip of full bundle.
5.3 Stable digital resource — “complete representation” definition
For Digital resource_nature at Stable:
- Source repository or archive (original design files)
- Build/install instructions (making instructions equivalent)
- User/documentation (operating instructions equivalent)
- Dependency manifest (analogous to BOM: lockfiles, requirements.txt, etc.)
- License block and integrity manifest
- Version identifier
5.4 Hybrid resources
Hybrid NDOs (resource_nature: Hybrid) shall satisfy both §5.2 and §5.3 for the physical and digital aspects, with explicit linkage between digital twin assets and physical fabrication assets (e.g. firmware version ↔ PCB revision).
6. NDO Architecture Mapping
6.1 Entry and link types (proposed)
#![allow(unused)] fn main() { /// Structured index of know-how artifacts for a project-type NDO. /// Linked from ResourceSpecification; does not embed file bytes. pub struct SpecificationPackage { pub spec_version: String, // package schema version pub okh_manifest_hash: Option<ActionHash>, // DigitalAsset target pub artifact_index: Vec<ArtifactRef>, pub completeness: CompletenessReport, pub license: LicenseBlock, pub fabrication_evidence: FabricationEvidence, pub created_at: Timestamp, pub updated_at: Timestamp, } pub struct ArtifactRef { pub slot: SpecificationArtifactType, pub digital_asset_slot: ActionHash, // CapabilitySlot link hash pub title: Option<String>, pub format: Option<String>, // e.g. "kicad", "step", "csv" pub is_original: bool, // true = OSHWA "original design file" } pub struct LicenseBlock { pub hardware: Option<String>, // SPDX pub documentation: Option<String>, pub software: Option<String>, pub licensor: Option<String>, } pub struct FabricationEvidence { pub made: bool, pub made_independently: bool, pub validation_receipt: Option<ActionHash>, } }
Existing types retained:
ResourceSpecification— summary discovery fields (name, description, category, tags).GovernanceRule— access, validation, and transition rules on the spec.CapabilitySlot+DigitalAsset— content pointers and integrity manifests.NDOToSpecification— Layer 1 activation (REQ-NDO-L1-01).NDOToComponent— fractal child NDO references.
6.2 Open Know-How manifest interchange
- The system should accept an
okh.yml(Open Know-How Manifest 1.0) as aDigitalAsset, parse it intoSpecificationPackage, and/or generateokh.ymlfrom DHT state for export. - Field names shall follow OKH YAML schema (
open-know-how-iopa.md§4.3–4.9) to maximize portability (OKH Level 1). development-stagein OKH manifests shall map toLifecycleStagevia a published translation table maintained in implementation docs.
6.3 Integrity and storage
- Every file bundle claiming
Stableor later shall have a Digital Resource Integrity manifest (R1–R4) attached as aDigitalAsset. - Large files shall use chunked, content-addressed storage (R2); the DHT stores manifests and capability slot pointers, not bulk binaries.
- Composite products shall use fractal verification (R5–R9): child NDO components verify independently; parent assembly manifest references child manifest roots.
6.4 Versioning
- Each materially changed specification bundle shall create a new
ResourceSpecification+SpecificationPackagepair linked under the same Layer 0 identity (REQ-NDO-L1-03). - Version DAG relations (
EvolvedFrom,ForkedFrom) shall align with OKHderivative-of/variant-ofmetadata. - Physical instances (
EconomicResource) created from a spec shall record theResourceSpecificationaction hash (and package version) they conform to.
7. Requirements
7.1 Specification package core
- REQ-PROJ-SPEC-01: The system shall support a
SpecificationPackageentry type linked toResourceSpecificationon Layer 1 activation, indexing all know-how artifacts for a project-type NDO without embedding file content in the entry. - REQ-PROJ-SPEC-02: The system shall classify specification artifacts using typed slots aligned with OSHWA best-practice elements and Open Know-How documentation fields (§4.2 table).
- REQ-PROJ-SPEC-03: All file, repository, and manifest pointers shall be attached via
CapabilitySlotlinks of typeDigitalAsseton the Layer 0NondominiumIdentityhash (REQ-NDO-L1-06);SpecificationPackageshall reference those slots by hash. - REQ-PROJ-SPEC-04: The system shall distinguish original design files from auxiliary design files in
ArtifactRef.is_originaland enforce that auxiliary files never satisfy original-file requirements alone (OSHWA).
7.2 Metadata and discoverability (Open Know-How Level 1)
- REQ-PROJ-SPEC-05: Every active Layer 1 project specification shall expose at minimum: title, description, and documentation entry URL (
documentation-homeorproject-linkequivalent). - REQ-PROJ-SPEC-06: The system should support import and export of Open Know-How Manifest 1.0 (
okh.yml) as aDigitalAsset, bidirectionally mapped toSpecificationPackagefields. - REQ-PROJ-SPEC-07:
SpecificationPackageshall recordmanifest_languageanddocumentation_languageusing BCP 47 language tags when provided. - REQ-PROJ-SPEC-08: Keywords, intended use, health/safety notice, contact, and contributors shall be storable in
SpecificationPackageor linked OKH manifest per OKH §4.5–4.6.
7.3 Material resource bundles
- REQ-PROJ-SPEC-10: For
ResourceNature::PhysicalorHybridNDOs atLifecycleStage::Stableor later, the specification package shall include: overview, original design files, auxiliary manufacturing files, BOM, making instructions, operating instructions, and license block (§5.2). - REQ-PROJ-SPEC-11: BOM shall be a separate artifact with reference-designator alignment to design files when the design uses reference designators (OSHWA).
- REQ-PROJ-SPEC-12: Making instructions shall link to tool lists and, where applicable, tool settings, quality/test instructions, and risk assessments (OKH recommended fields).
- REQ-PROJ-SPEC-13: Maintenance and disposal instructions shall be supported as optional artifact slots; governance templates for
PoolandCommonPoolregimes should recommend them.
7.4 Digital resource bundles
- REQ-PROJ-SPEC-20: For
ResourceNature::DigitalNDOs atLifecycleStage::Stableor later, the specification package shall include: source repository or archive, build/install instructions, user documentation, dependency manifest, license block, and integrity manifest (§5.3). - REQ-PROJ-SPEC-21: Software/firmware source shall include build procedure documentation sufficient for an independent developer to reproduce binaries (OSHWA software section).
7.5 Licensing
- REQ-PROJ-SPEC-30:
SpecificationPackage.licenseshall use SPDX identifiers for hardware/design, documentation, and software channels (OKH §4.6.18). - REQ-PROJ-SPEC-31: Governance shall reject lifecycle promotion to
StableforPropertyRegime::NondominiumorCommonsNDOs whose license block includes NC or ND SPDX qualifiers on design or documentation channels.
7.6 Integrity and verification
- REQ-PROJ-SPEC-40: Specification bundles at
Stableor later shall reference a Digital Resource Integrity manifest (digital-resource-integrity.mdR1–R4) covering allDigitalAssetfiles in the package. - REQ-PROJ-SPEC-41: Peer validation of a new resource (
REQ-GOV-02) shall verify integrity manifest presence and successful manifest signature check before approvingPrototype → Stabletransitions for physical/hybrid NDOs. - REQ-PROJ-SPEC-42:
FabricationEvidence.made_independentlyshall be settable only with a linkedValidationReceiptor documented independent-build attestation approved by governance rules.
7.7 Composability and provenance
- REQ-PROJ-SPEC-50: Sub-assemblies available as separate open know-how shall be referenced via
NDOToComponentlinks to child NDO identities, with OKH-alignedsubmetadata inSpecificationPackage(not duplicated file trees). - REQ-PROJ-SPEC-51: Forks and variants shall link to predecessor NDOs or specification versions via the version DAG (
ndo-versioning.md) and OKHderivative-of/variant-offields. - REQ-PROJ-SPEC-52:
SpecificationPackageshall recordstandards-usedreferences (OKH §4.6.14) when design or documentation follows external standards (ISO, OSHWA certification, etc.).
7.8 Lifecycle governance integration
- REQ-PROJ-SPEC-60: The governance zome shall evaluate
SpecificationPackage.completenessagainst stage-specific minimums (§5.1) when processingupdate_lifecycle_stagetransitions. - REQ-PROJ-SPEC-61: Transition to
Stableshall be blocked if required artifact slots for the NDO'sresource_natureare missing or lack trustedDigitalAssetattachments. - REQ-PROJ-SPEC-62: Transition to
Distributedshall requireStablecompleteness plus fabrication evidence (madetrue) and eithermade_independentlyor multi-reviewer validation perResourceValidationscheme. - REQ-PROJ-SPEC-63: Transition to
SpecificationorDevelopmentshall not require full Stable bundles (pay-as-you-grow); only metadata sufficient for discovery and collaboration.
7.9 Hosting and distribution practices (OSHWA process)
- REQ-PROJ-SPEC-70:
SpecificationPackageshould support linking to version-controlled repositories (Git) asDigitalAssettargets, with commit/tag references recorded in the package version field. - REQ-PROJ-SPEC-71: Published physical instances derived from the spec should be able to record the specification version on the instance record for traceability (OSHWA distribution: match physical object to design version).
- REQ-PROJ-SPEC-72: UI and export tools should support generating an
archive-downloadasset (full bundle zip) with embeddedokh.ymlfor offline sharing (OKH §4.8.2).
7.10 Completeness reporting
- REQ-PROJ-SPEC-80:
SpecificationPackage.completenessshall compute a machine-readable report: required vs present vsN/Awaived slots, per lifecycle stage profile. - REQ-PROJ-SPEC-81: Discovery queries shall expose completeness percentage and missing slot types for Lobby / Group NDO browsers (feeds REQ-UI-LOBBY-01 filter semantics).
8. Governance Defaults by Property Regime
Aligned with resources.md §4.4.4 and §6.6:
| PropertyRegime | Stable-stage emphasis |
|---|---|
Commons / Nondominium | Full open bundle; reciprocal or permissive OS licenses; attribution in contributors |
Private | Complete spec for authorized fabricators; governance may restrict DigitalAsset capability grants |
Pool / CommonPool | Stable spec plus maintenance/disposal instructions; access gated by role and (post-MVP) affiliation |
Collective | Spec co-maintained; N-of-M validation for Stable promotion |
9. Relationship to Agent Model
Project-type NDOs often correspond to Project collective agents (REQ-NDO-AGENT-02): the agent face participates in economic events; the resource face (this NDO) carries the specification bundle. Contributors credited in OKH contributors should map to PPR-traceable participation in Layer 2, but contributor lists in the spec package are documentary — authoritative contribution history remains in PPRs and economic events.
10. Implementation Phasing (informative)
| Phase | Deliverable |
|---|---|
| Phase A | SpecificationPackage entry + artifact slot enum; manual DigitalAsset attachment; completeness report (no governance enforcement) |
| Phase B | OKH manifest import/export; integrity manifest requirement; governance blocks on → Stable |
| Phase C | Fractal child NDO links; version DAG integration; Distributed fabrication evidence |
| Phase D | OKH Level 2 portable bundle export; federated discoverability (OKH Level 3) |
11. Traceability Matrix
| External source | NDO requirement IDs |
|---|---|
| OSHWA — Overview | REQ-PROJ-SPEC-02, -10 |
| OSHWA — Original / auxiliary design files | REQ-PROJ-SPEC-04, -10 |
| OSHWA — BOM | REQ-PROJ-SPEC-02, -11 |
| OSHWA — Software/firmware | REQ-PROJ-SPEC-02, -21 |
| OSHWA — Photos | REQ-PROJ-SPEC-02 |
| OSHWA — Instructions (make, use, rationale) | REQ-PROJ-SPEC-02, -10, -12 |
| OSHWA — Licensing | REQ-PROJ-SPEC-30, -31 |
| OKH — Manifest metadata | REQ-PROJ-SPEC-05 – -08 |
| OKH — Documentation fields §4.8 | REQ-PROJ-SPEC-02, -12, -13 |
OKH — sub, derivative-of, variant-of | REQ-PROJ-SPEC-50, -51 |
| OKH — Maturity Level 1 | REQ-PROJ-SPEC-05, -06 |
| NDO Layer 1 | REQ-NDO-L1-01 – -06, REQ-PROJ-SPEC-01, -03 |
| Digital Resource Integrity | REQ-PROJ-SPEC-40, -41 |
| Complexity matching / lifecycle | REQ-PROJ-SPEC-60 – -63, §5 |
12. Sibling NDO Type: Source-NDO
A Source-NDO is a sibling specification type that governs generative ecological systems (watersheds, rivers, forests, fisheries) and knowledge commons rather than design artefacts in development. While project-type NDOs specify design intent — what a thing is supposed to be and how to fabricate it — Source-NDOs specify generative ecological conditions: what a source yields, what effects it receives, how its condition evolves, and how governance rules must adapt as its event ledger accumulates.
Key differences:
| Dimension | Project-type NDO | Source-NDO |
|---|---|---|
| Represents | Resource in development (design → production) | Generative ecological system (watershed, fishery) |
| Layer 1 content | SpecificationPackage — OSHWA/OKH artifacts | SourceSpecification — boundary conditions, monitoring framework |
| Governance pattern | Rule evaluation at transition request | Adaptive cybernetic loop: events → interpretation → rule revision → conditioned events |
| Custodian | primaryAccountable (custody, not ownership) | stewardedBy — stewardship obligations, no ownership |
| PropertyRegime | Any | Nondominium or CommonPool only |
| ValueFlows extension | Standard VF events | vf:Source flow endpoint role |
Normative requirements for Source-NDO are in source-ndo-requirements.md.
This is a normative post-MVP requirements document. Implementation shall not contradict ndo_prima_materia.md REQ-NDO- IDs. When OSHWA or Open Know-How standards update, §4 field mappings should be revised without changing the underlying NDO architectural invariants (Layer 0 identity, Layer 1 spec + DigitalAsset slots, governance-as-operator).*
Resource Transport/Flow Protocol (RTP-FP) Specification
Version: 0.2
Date: 2026-08-06
Status: 🔄 Post-MVP — conceptual specification. Grounded in implemented NDO Layer 0 + OperationalState foundations; the transport/flow process layer (Layer 2 activation, EconomicProcess, governance-as-operator transitions) is not yet wired in code.
Framework: Holochain HDK ^0.6.0 / HDI ^0.7.0, hREA ValueFlows
License: CAL-1.0 + AGPLv3 (project dual license)
Relates to:
ndo_prima_materia.md— NDO three-layer model,LifecycleStage,OperationalState, capability slots (REQ-NDO-L0/L1/L2, REQ-NDO-OS-*)../requirements.md— Economic Process (REQ-PROC-), PPR (REQ-PPR-), governance (REQ-GOV-*) requirements../../specifications/specifications.md—EconomicEvent,EconomicResource, PPR data structures, governance-as-operator interfacesource-ndo-requirements.md/source-valueflows-integration.md—Sourceprimitive andvf:Sourceboundary flowsmany-to-many-flows.md— shared custody, resource pools, multi-party transfers../../IMPLEMENTATION_STATUS.md/../../implementation_plan.md— current build state and phasing
Abstract
The Resource Transport/Flow Protocol (RTP-FP) is a multi-dimensional protocol designed to facilitate low-friction resource flows in commons-based economies. Unlike static transfer protocols focused on ownership change, RTP-FP emphasizes the continuous movement, mutualization, and co-stewardship of shared resources throughout their complete lifecycle.
RTP-FP is not a new subsystem. It is a semantic layer over primitives that already exist (or are specified) in the Nondominium architecture: the NDO three-layer model, the OperationalState machine on EconomicResource, ValueFlows EconomicEvent/Commitment/Claim cycles, the Private Participation Receipt (PPR) system, the governance-as-operator pattern, and — where the flow originates in a generative system — the Source/vf:Source boundary-flow extension. This document maps the "transport" mental model onto those primitives and records what is implemented versus planned.
0. Alignment with Current Implementation
RTP-FP describes a Layer 2 (Process) concern over NDOs. It depends on foundations that are already built and on activation work that is in progress or planned. This section is the authoritative status anchor; the rest of the document uses the status markers ✅ implemented, 🔄 partial/prototype, ❌ not implemented.
| RTP-FP building block | Canonical primitive | Status | Source |
|---|---|---|---|
| Resource identity anchor | NondominiumIdentity (NDO Layer 0) | ✅ Implemented | ndo_prima_materia.md §4; IMPLEMENTATION_STATUS.md |
| Transport/flow status of an instance | OperationalState on EconomicResource (7 states) | ✅ Data layer (REQ-NDO-OS-01) | crates/shared/src/types.rs; resources.md §2.1 |
| Maturity phase of the resource design | LifecycleStage on Layer 0 (10 stages) | ✅ Implemented | ndo_prima_materia.md §5 |
| Movement/custody events | EconomicEvent + 16 VfAction variants | ✅ Implemented | specifications.md §3.3.1 |
| Single custodian | EconomicResource.custodian: AgentPubKey | ✅ Implemented (individual only) | specifications.md §3.2.3 |
| Intent → observation cycle | Commitment → EconomicEvent → Claim | ✅ Implemented | specifications.md §3.3 |
| Accountability receipts | 16 ParticipationClaimType PPR categories | 🔄 Prototype | requirements.md §7.2 |
| Transport/Storage/Repair/Use as processes | EconomicProcess + role gating | ❌ Not implemented end-to-end | IMPLEMENTATION_STATUS.md; REQ-PROC-01..09 |
| Legal-dimension transitions | Governance-as-operator (Request→Evaluate→Apply) | ❌ Not implemented (REQ-NDO-OS-02..05) | specifications.md §3; resources.md §2.4 |
| Layer 2 activation (process ↔ NDO) | NDOToProcess link | ❌ Post-MVP (REQ-NDO-L2-01) | ndo_prima_materia.md §4 |
| Layer 1 activation (spec/assets ↔ NDO) | NDOToSpecification, DigitalAsset slots | 🔄 In progress (REQ-NDO-L1-01/06) | ndo_prima_materia.md §4 |
| Flow originating in a generative system | Source/SourceProfile, vf:Source, Extract | ❌ Post-MVP (REQ-SOURCE-*) | source-ndo-requirements.md; source-valueflows-integration.md |
| Cross-NDO/federated flows | NdoHardLink, Contribution, Agreement | ✅ Implemented (#103) | resources.md §2.5 |
Design consequence. Transport is a process running on an instance, so it belongs to OperationalState (transient condition) and Layer 2 (EconomicEvent/Commitment/Claim), not to LifecycleStage (design maturity on Layer 0). Moving a Prototype-stage NDO's instance does not advance it toward Stable; it only sets that instance InTransit. This orthogonality (REQ-NDO-OS-01) is load-bearing for the whole protocol.
1. Fundamental Concepts
1.1 Transport vs Transfer Paradigm
Traditional Transfer Protocol:
- Linear ownership change: A → B
- Static endpoint focus
- Private ownership model
- Single transaction view
Resource Transport/Flow Protocol:
- Multi-dimensional flow: A ↔ Network ↔ B ↔ Network...
- Continuous lifecycle perspective
- Commons-based stewardship (custody, not ownership; preserves the
Nondominium/Pool/CommonPoolproperty regimes) - Multi-agent participation view
In ValueFlows terms, "transfer" is the Transfer action (ownership + custody change); RTP-FP privileges TransferCustody (custody change preserving the property regime), Move (location change, same custodian), and AccessForUse (access without custody change). Ownership-changing Transfer remains available but is the exception, not the default, for commons resources.
1.2 Core Principles
- Non-Linear Resource Flows: Resources participate in circulation within commons networks rather than one-way supply chains.
- Custodial Stewardship: Resources have custodians, not owners, with responsibilities and benefits. Custody is recorded on
EconomicResource.custodianand changed viaTransferCustody/CustodyTransferevents. - Multi-Dimensional Tracking: Simultaneous tracking across physical, custodial, value, legal, and information dimensions — each mapped to a concrete primitive (§2).
- Lifecycle Completeness: End-to-end management from creation (
Ideation/PendingValidation) through decommissioning (EndOfLife), spanning bothLifecycleStageandOperationalState. - Low-Friction Movement: Minimal transaction overhead for shared-resource circulation, achieved through implicit validation, bilateral receipts, and role-gated processes.
2. Multi-Dimensional Resource Flow Model
2.1 Five Transport Dimensions
Each dimension is a view over existing primitives, not a separate ledger. The table below is the reconciliation of the original RTP-FP dimensions with the current data model.
| Dimension | What it tracks | Canonical primitive(s) | Status |
|---|---|---|---|
| Physical | Location, transport condition of an instance | EconomicResource.current_location + OperationalState (InTransit, InStorage) + Move/VfAction events | ✅ data layer; ❌ transition enforcement |
| Custodial | Who holds the resource, custody history | EconomicResource.custodian + TransferCustody/CustodyTransfer/CustodyAcceptance events + PPR | ✅ single custodian; 🔄 many-to-many post-MVP |
| Value | Condition, utility, reliability over time | OperationalState (InMaintenance, InUse) + derived reliability_score (from repair/maintenance events) | ✅ operational; 🔄 reliability derivation post-MVP |
| Legal | Rights/permissions shifting | GovernanceRule (Layer 1) evaluated by governance-as-operator; capability tokens | 🔄 rules persisted; ❌ operator enforcement |
| Information | Docs, provenance, maintenance records | DHT links; Layer 1 DigitalAsset capability slots; NdoHardLink provenance; PPR history | 🔄 Layer 1 activation in progress |
2.1.1 Physical Dimension
- Definition: Resource movement through space.
- Primitive:
OperationalState::InTransit/InStorageon theEconomicResource, pluscurrent_location: Option<String>, updated byMove(location change, same custodian) orTransfer/TransferCustody(location + custody change)EconomicEvents. - Note: External telemetry (GPS/RFID/IoT) is an ingestion source that populates
current_locationor triggers state changes; it is not itself on the DHT. It maps to REQ-FUT-ORG-BRG-* bridge concerns.
2.1.2 Custodial Dimension
- Definition: Resource changes custodian/steward.
- Primitive:
EconomicResource.custodianmutated through aTransferCustodyevent; provenance captured by theCustodianToResourcelink and theEconomicEventhistory. Multi-custodian / shared-custody flows are post-MVP (many-to-many-flows.md). - Accountability: each custody handoff issues bilateral PPRs (
CustodyTransfer/CustodyAcceptance) — see §5.
2.1.3 Value Dimension
- Definition: The resource's condition/utility transforms through use and service.
- Primitive:
OperationalState::InUse/InMaintenance, plus (post-MVP) a derivedreliability_scoreaccumulated from repair/maintenance/incident events (resources.md§6.5). The design of the resource lives in Layer 1ResourceSpecification; the condition of an instance lives on theEconomicResource.
2.1.4 Legal Dimension
- Definition: Rights and responsibilities shift as the resource flows.
- Primitive:
GovernanceRuleentries (Layer 1, linked toResourceSpecification) evaluated by the governance-as-operator (request_resource_transition→evaluate_state_transition→ apply). Access is gated by capability tokens and role checks. Post-MVP, rules may also gate onAffiliationState(REQ-GOV-14) and, for generative systems, onSourceRegimeState(REQ-SOURCE-GOV-03). - Status:
GovernanceRulepersistence is implemented; the operator that enforces transitions onOperationalStateis not yet built (REQ-NDO-OS-02..05).
2.1.5 Information Dimension
- Definition: Data and metadata that travel with the resource.
- Primitive: DHT link architecture — Layer 1
DigitalAssetcapability slots for files/manifests (REQ-NDO-L1-06),NdoHardLink(DerivedFrom/Component/Supersedes) for provenance, and the resource'sEconomicEvent/PPR history for maintenance and custody records. Digital integrity (chunked SHA-256/Merkle) is specified indigital-resource-integrity.md.
2.2 Non-Linear Flow Patterns
Traditional Supply Chain:
Producer → Distributor → Retailer → Consumer
↓ ↓ ↓ ↓
Linear Static Point-to-Point Endpoint
Resource Flow Network:
Agent A ↔ Resource Hub ↔ Agent C
↕ ↕ ↕
Resource Resource Resource
Pool Alpha Pool Beta Pool Gamma
↕ ↕ ↕
Agent B ↔ Resource Hub ↔ Agent D
Dynamic, Circular, Multi-path Resource Circulation
Where a flow originates in a generative system (a watershed, forest, fishery, or knowledge commons), the "producer" node is a Source-NDO, not an agent, and the first hop is an Extract boundary event rather than a Produce (§6).
3. Protocol Architecture
3.1 Holochain Integration
3.1.1 DNA / Zome Distribution
zome_person: Agent identity, roles, custodial relationships, private data, PPR storage.zome_resource: NDO Layer 0 identity (NondominiumIdentity),ResourceSpecification,EconomicResource+OperationalState,GovernanceRulepersistence (pure data model).zome_gouvernance:EconomicEvent,Commitment,Claim,ValidationReceipt, PPR issuance, and (planned) the governance-as-operator that evaluates transitions and generates events.
3.1.2 DHT Architecture Benefits
- Agent-Centric Views: Each agent maintains their own perspective (source chain) of resource flows.
- Multi-Source Truth: No single point of failure; distributed peer validation.
- Cross-DNA Coordination: Federated flows across group/lobby DNAs via
NdoHardLinkand the Lobby DNA. - Privacy Preservation: PPRs are private entries; public validation via
ValidationReceipt.
3.2 NDO Layer Placement
RTP-FP operates across all three NDO layers, but its "moving parts" are Layer 2:
- Layer 0 (
NondominiumIdentity) — the permanent identity the flow is about; carriesLifecycleStage,PropertyRegime,ResourceNature. Always present. ✅ - Layer 1 (
ResourceSpecificationviaNDOToSpecification) — the design,GovernanceRules (legal dimension), andDigitalAssetslots (information dimension). Activation in progress (REQ-NDO-L1-01/06). 🔄 - Layer 2 (Process via
NDOToProcess) — the transport/storage/repair/use activity:Commitment,EconomicEvent,Claim, PPR.EconomicResourceinstances attach through Layer 2 (REQ-NDO-L2-06). ❌ activation post-MVP.
A transport journey is therefore a Layer 2 process over one NDO identity, mutating one or more EconomicResource instances' OperationalState.
3.3 OperationalState — The Canonical Transport State Machine
The transport/flow status the original RTP-FP called "transport status" is the implemented OperationalState enum on EconomicResource (REQ-NDO-OS-01):
PendingValidation → Available → Reserved → InTransit → Available
↘ ↘ InStorage → Available
↘ InMaintenance→ Available
↘ InUse → Available
- A transport process typically drives
Available → Reserved → InTransit → Available(at the new custodian/location). - Storage and repair drive
→ InStorage/→ InMaintenanceand back. OperationalStateis orthogonal toLifecycleStage: anActive-stage NDO can have anInMaintenanceinstance; aPrototypecan beInTransit.
Governance-as-operator dependency (❌ not implemented). Each OperationalState transition should be requested by an agent, evaluated against Layer 1 GovernanceRules by zome_gouvernance, applied to the EconomicResource, and recorded as an EconomicEvent (REQ-NDO-OS-02..05, REQ-ARCH-10). Today update_operational_state mutates state directly without operator evaluation; wiring the operator is a prerequisite for the legal dimension.
4. Protocol Operations
4.1 Resource Lifecycle Phases
RTP-FP phases span two orthogonal axes. The table maps each RTP-FP phase to LifecycleStage (Layer 0, design maturity) and OperationalState (instance condition).
| RTP-FP phase | LifecycleStage (Layer 0) | OperationalState (instance) |
|---|---|---|
| Genesis — network entry | Ideation → Specification → … | PendingValidation → Available |
| Active use — circulation | Active / Distributed | Reserved / InTransit / InUse |
| Service — maintenance/enhancement | (unchanged) | InStorage / InMaintenance |
| End-of-life — decommissioning | Deprecated → EndOfLife | terminal (instance retired) |
4.1.1 Genesis Phase — Network Entry
- NDO Layer 0 creation (
create_ndo); optional Layer 1 activation (NDOToSpecification) when a spec exists. - First
EconomicResourceinstance created atPendingValidation; peer validation (validate_new_resource) moves it toAvailable. - Genesis PPRs:
ResourceCreation(creator) +ResourceValidation(validator).
4.1.2 Active Use Phase — Resource Circulation
- Custody transfers (
TransferCustody) and location moves (Move) between agents. OperationalStatecyclesAvailable ↔ Reserved ↔ InTransit ↔ InUse.- Usage and condition monitoring feed the value dimension.
4.1.3 Service Phase — Maintenance & Enhancement
- Transport → repair → transport → storage chains executed by role-holding agents (
Transport,Repair,Storage). - Drives
InTransit/InMaintenance/InStorage. Note: these are specified asEconomicProcesstypes (REQ-PROC-02/03/04) but are not yet implemented end-to-end.
4.1.4 End-of-Life Phase — Responsible Decommissioning
EndOfLifedeclaration with multi-validator confirmation and a challenge period (REQ-GOV-11/12/13).- PPRs:
EndOfLifeDeclaration+EndOfLifeValidation. - Layer 0 survives as a permanent tombstone; only
lifecycle_stagereflects termination.
4.2 Low-Friction Design Patterns
4.2.1 Implicit Resource Validation
- For trusted agents, resource validation rides on agent validation; no separate validation receipts for standard transfers. PPR-based reliability substitutes for per-transfer inspection.
4.2.2 Bilateral Receipt Generation
- Exactly 2 PPRs per economic interaction (REQ-PPR-01), one per counterparty, bilaterally signed. In the MVP one-to-one model this is pairwise-bilateral; multi-party issuance is post-MVP (
many-to-many-flows.md).
4.2.3 Good-Faith Transfers
- Custody handed to a service provider on the strength of an accepted
Commitment, with minimal validation overhead and an atomic commitment/fulfillment cycle. PPR:GoodFaithTransfer.
5. PPR Integration
RTP-FP uses the canonical 16 ParticipationClaimType categories (requirements.md §7.2) — it does not define new receipt types. The transport-relevant subset:
| Flow event | Provider-side PPR | Receiver-side PPR |
|---|---|---|
| Resource creation + validation | ResourceCreation | ResourceValidation |
| Custody handoff | CustodyTransfer | CustodyAcceptance |
| Transport service (commit) | TransportCommitmentAccepted | GoodFaithTransfer |
| Transport service (fulfill) | TransportFulfillmentCompleted | CustodyAcceptance |
| Storage service | StorageCommitmentAccepted | StorageFulfillmentCompleted |
| Maintenance/repair service | MaintenanceCommitmentAccepted | MaintenanceFulfillmentCompleted |
| Governance/validation activity | ValidationActivity / RuleCompliance | — |
| End-of-life | EndOfLifeDeclaration | EndOfLifeValidation |
Properties (unchanged from the PPR system): private entries, never globally aggregated, bilaterally signed, weighted PerformanceMetrics (timeliness 0.25, quality 0.30, reliability 0.25, communication 0.20). Reputation is derived by the owning agent as a ReputationSummary and selectively shared.
5.1 Role Chaining Support
- Multi-role agents (e.g.
Transport+Repair+Storage) can chain actions (receive → transport → repair → transport → deliver) within a single commitment (REQ-USER-A-07), with intermediateOperationalStatetransitions self-managed and each leg generating its own bilateral PPRs.
6. Source-Originated Flows (Post-MVP)
Status: ❌ Post-MVP. Depends on the
Source/vf:Sourceextension (source-ndo-requirements.md,source-valueflows-integration.md). Not required for ordinary flows between agents.
When a flow originates in or discharges into a generative system (watershed, forest, fishery, knowledge commons), the endpoint is a Source-NDO, not an agent. RTP-FP extends to boundary flows as follows.
6.1 Boundary Events
EconomicEvent gains two additive optional fields (Option B in source-valueflows-integration.md §2.2):
#![allow(unused)] fn main() { pub source_provider: Option<ActionHash>, // Source Layer 0 hash (extraction / non-consumptive use) pub source_receiver: Option<ActionHash>, // Source Layer 0 hash (loading / pollution) }
Integrity rule: exactly one of { provider, source_provider } set on the initiating side (same for the receiver). Agent↔Agent events are unchanged.
| Boundary flow | Action | Endpoint | Effect on SourceProfile |
|---|---|---|---|
| Extraction (water, timber, fish) | Extract (proposed 17th VfAction) | source_provider = Source | debits current_stock / period quota |
| Loading / pollution | Produce with source_receiver | source_receiver = Source | debits assimilation_capacity |
| Regeneration / restoration | Raise on the Source | source_receiver = Source | credits stock / resilience |
| Non-consumptive use | Use with source_provider | source_provider = Source | affects regime_state, no stock change |
Until Extract lands, Lower on the Source plus Raise/Transfer on the derived Resource is an acceptable interim mapping (source-valueflows-integration.md §2.8).
6.2 Transport of Source-Yielded Resources
The extracted quantity becomes an ordinary EconomicResource instance the moment it is inventoried; from there the standard RTP-FP dimensions and OperationalState machine apply. The transport journey of extracted units is agent↔agent; only the first hop (the extraction) touches the Source. This keeps depletion visible on the Source ledger while reusing the entire transport/custody/PPR machinery downstream.
6.3 Adaptive Governance Coupling
For Source-originated flows the legal dimension is adaptive (REQ-SOURCE-GOV-01..08): boundary events accumulate on the Source Layer 0 hash → stewards interpret condition → GovernanceRules and access affordances (quotas, seasonal limits) are revised → future extraction/transport requests are re-evaluated. Precautionary blocking applies near tipping_threshold (REQ-SOURCE-GOV-03). Stewardship uses stewardedBy / the Steward role, never custodian/ownership.
7. Data Structures
Important: The structs below are design-level projections, not literal Holochain entry types. RTP-FP does not introduce a
ResourceFlowEvententry. The persisted entries are the existingEconomicEvent,EconomicResource(withOperationalState),Commitment,Claim,PrivateParticipationClaim, and (post-MVP)SourceProfile. The projections describe how a client composes a "flow view" by reading those entries plus their links.
7.1 Persisted primitive — EconomicEvent (ground truth)
#![allow(unused)] fn main() { // zome_gouvernance (specifications.md §3.3.1; +source fields per source-valueflows-integration.md §2.2) pub struct EconomicEvent { pub action: VfAction, // 16 variants (+ proposed Extract) pub provider: AgentPubKey, // XOR source_provider (post-MVP) pub receiver: AgentPubKey, // XOR source_receiver (post-MVP) pub resource_inventoried_as: ActionHash, // the EconomicResource pub affects: ActionHash, // the EconomicResource affected pub resource_quantity: f64, pub event_time: Timestamp, pub note: Option<String>, // Post-MVP Source boundary endpoints: pub source_provider: Option<ActionHash>, // Source Layer 0 hash pub source_receiver: Option<ActionHash>, // Source Layer 0 hash } }
7.2 Persisted primitive — EconomicResource with OperationalState
#![allow(unused)] fn main() { // zome_resource (specifications.md §3.2.3; resources.md §2.1) pub struct EconomicResource { pub conforms_to: ActionHash, // Layer 1 ResourceSpecification pub quantity: f64, pub unit: String, pub custodian: AgentPubKey, // single custodian (many-to-many post-MVP) pub current_location: Option<String>, // physical dimension pub operational_state: OperationalState, // transport/flow status } pub enum OperationalState { PendingValidation, Available, Reserved, InTransit, InStorage, InMaintenance, InUse, } }
7.3 Design-level projection — Flow View (client-composed)
#![allow(unused)] fn main() { // NOT an entry. Composed by a client/read model from the entries above + links + PPRs. pub struct ResourceFlowView { pub ndo_identity: ActionHash, // Layer 0 NondominiumIdentity pub lifecycle_stage: LifecycleStage, // Layer 0 maturity pub instance: ActionHash, // EconomicResource pub operational_state: OperationalState, // physical/value dimension pub custodian: AgentPubKey, // custodial dimension pub custody_history: Vec<ActionHash>, // TransferCustody EconomicEvents pub applicable_rules: Vec<ActionHash>, // Layer 1 GovernanceRule (legal dimension) pub information_links: Vec<ActionHash>, // DigitalAsset slots, NdoHardLinks (info dimension) pub participation_receipts: Vec<ActionHash>, // owning agent's PPRs pub source_origin: Option<ActionHash>, // Source Layer 0 hash if boundary-originated } }
8. Security & Governance
8.1 Cryptographic Security
- Bilaterally signed PPRs; private entries with public
ValidationReceipts. - Agent identity via Holochain source chains; capability-token-gated zome functions (
general_access/restricted_access). - Append-only, tamper-evident audit trail (Layer 0 permanence + event history).
8.2 Governance Mechanisms
- Governance-as-operator evaluates transitions against Layer 1
GovernanceRules (❌ enforcement pending). - Multi-validator schemes (
2-of-3,N-of-M) for critical operations (REQ-GOV-06). - Challenge periods for end-of-life and disputed transitions (REQ-GOV-13).
- Role-based access and validated functional credentials (
Transport/Repair/Storage). - Post-MVP:
AffiliationState-gated access (REQ-GOV-14) and, for Sources,SourceRegimeState-conditional precautionary rules (REQ-SOURCE-GOV-03).
8.3 Attack-Vector Mitigation
- End-of-life abuse: multi-validator + challenge period.
- Monopolization: usage-pattern analysis over event history; property-regime constraints (no alienation of
Nondominium). - Sybil resistance: agent validation, social vouching, optional Tier-2 identity (post-MVP, REQ-GOV-17).
- Double-custody prevention: commitment tracking + single-custodian invariant (until many-to-many lands with explicit weights).
9. Use Cases & Applications
9.1 Tool Libraries & Makerspaces
Tool sharing with maintenance scheduling, custody handoff PPRs, and usage-based cost distribution. Pool property regime; OperationalState cycles Available ↔ Reserved ↔ InUse ↔ InMaintenance.
9.2 Transportation Pools
Vehicle sharing and fleet management with route/segment tracking (InTransit), maintenance cost allocation, and environmental-impact records.
9.3 Equipment Rental & Sharing
Industrial equipment networks with condition monitoring (value dimension → reliability), liability management (legal dimension → GovernanceRule), and cross-organizational optimization.
9.4 Digital Resource Commons
Software/service and knowledge sharing. Digital/Information nature, Commons/Nondominium regimes; Layer 1 DigitalAsset slots + digital integrity manifests carry the information dimension. Non-rivalrous, so "transport" collapses to access/replication rather than custody handoff.
9.5 Ecological Commons (Source-Originated)
Water abstraction, timber, or fisheries: extraction is a boundary Extract event on a Source-NDO (§6); downstream distribution reuses the full transport machinery. Adaptive stewardship governs quotas.
10. Future Extensions
10.1 Advanced Features
- Reputation-weighted routing/allocation, predictive maintenance from reliability scores.
- Governance-as-operator with typed
GovernanceRules (EconomicAgreementvia Unyt,IdentityVerificationvia Flowsta). - Cross-DNA / cross-network interoperability via federation primitives and portable credentials.
10.2 Protocol Evolution
- Many-to-many custody (weighted shared custody, resource pools, co-custodian delegation).
- Resource-type-specific and region-specific rule modules.
- Full
Source/vf:Sourceactivation with adaptive stewardship.
11. Implementation Roadmap
Aligned with implementation_plan.md phases. RTP-FP itself is an extended post-MVP specification; it becomes fully realizable only once Layer 2 activation and the governance operator land.
| RTP-FP milestone | Prerequisite (implementation_plan) | Status |
|---|---|---|
| M0 — Foundations (identity, operational state, events, PPR prototype) | Phase 1 (Foundation) + OperationalState data layer | ✅ Delivered |
M1 — Layer 1 activation (NDOToSpecification, GovernanceRule link, DigitalAsset slots) | Phase 2 (Layer 1) | 🔄 In progress |
M2 — Process layer & governance operator (EconomicProcess, NDOToProcess, request_resource_transition/evaluate_state_transition, operational-state transitions generate events) | Phase 2/3 (Layer 2 + governance-as-operator) | ❌ Planned |
| M3 — Full PPR issuance for transport chains (transport/storage/repair categories on real commitment cycles) | Phase 3 (PPR) | ❌ Planned |
| M4 — Many-to-many flows (shared custody, pools) | Post-MVP (many-to-many-flows.md) | ❌ Planned |
M5 — Source-originated flows (vf:Source, Extract, adaptive stewardship) | Post-MVP (source-ndo-requirements.md, §12.7) | ❌ Planned |
12. Conclusion
The Resource Transport/Flow Protocol reframes resource movement from static, ownership-based transfer to dynamic, commons-based flow. Its contribution is semantic and integrative: it maps the five transport dimensions onto primitives that already exist in Nondominium (OperationalState, EconomicEvent/Commitment/Claim, PPR, GovernanceRule, the NDO three-layer model) and onto those that are specified for generative systems (Source/vf:Source).
Concretely, RTP-FP is a Layer 2 process concern driving the OperationalState machine on EconomicResource instances, evaluated by the governance-as-operator against Layer 1 rules, and made accountable by the bilateral PPR system. As Layer 1 activation completes and the process layer and governance operator are wired, this specification becomes directly implementable rather than aspirational.
This specification is a living document. It will evolve as Layer 1/Layer 2 activation, the governance operator, many-to-many flows, and the Source primitive are implemented. Status markers in this document should be updated against IMPLEMENTATION_STATUS.md as work lands.
PLANNING THE PAPER
We are going to lay out 3 interlocking structures:
- Thematic structure (what are we talking about)
- Pragmatic structure (why are we talking about this and that, and in this order)
- Logical and emotional structure (what is the argument, how do we deploy it and what emotions do we want to instill to the reader.)
We are going to overlay these structures together below. For every bullet point, we are going to separate the structural components using the “|” character, composed as: thematic element | pragmatic element | logical and/or emotional element.
Text in square brackets “[...]” are more granular instructions for you, the AI agent that works on the text.
The final text will be built from this 3 layer structure. The thematic structure will appear more explicitly in the text, as sections or paragraphs. The pragmatic and logical/emotional structures will remain mostly implicit, shaping order, emphasis, transitions, and tone.
Thesis to keep visible while writing:
- Existing economic information systems make nature visible mainly as owned resource, natural capital, ecosystem service, externality, or legal person. These categories are insufficient for complex ecological systems. We propose
Source/ Source-NDO as a new economic-information primitive: a generative, non-ownable, partially unknowable system whose boundary events can be recorded, whose condition can be sensed, and whose access rules can adapt through stewardship governance. | give the writer a stable compass for the whole paper | make the paper feel like a focused contribution rather than a broad critique of economics
The structures:
-
Introduction: externalities as economic information failure | open with the concrete problem shared by environmental practitioners, economists, policy actors, and activists | create urgency without starting from ideology
- Present ecological degradation linked to human economic activity: extraction, pollution, biodiversity loss, water stress, soil depletion, climate impacts, and ecosystem fragmentation. Keep this empirical, measurable, and scientifically grounded. [Literature anchors: Millennium Ecosystem Assessment; IPBES global and values assessments; SEEA EA.] | establish that the problem exists before proposing an ontology | build trust and realism
- Explain that an externality is not only a moral or pricing problem; it is also an information-system problem, because the effects of economic events often remain outside the economic record. [Literature anchors: Pigou on divergence between private and social net product; Coase on social cost, rights, and transaction costs.] | shift the reader from "environmental problem" to "economic information problem" | prepare the reader to accept an infrastructural/ontological proposal
- State the paper's practical goal: make ecological effects visible inside economic information systems so economic agents can steward natural sources/resources rather than merely consume resources. | clarify what the paper is trying to accomplish | orient the reader toward constructive action
-
Why existing economic categories fail | review familiar approaches without getting trapped in ideological debate | show that the proposed primitive responds to a gap shared across multiple paradigms
- Market accounting and conventional economics: nature appears as input, asset, cost, externality, or natural capital. [Literature anchors: Pigou; Coase; Costanza et al.; Daly; Georgescu-Roegen.] | summarize the dominant economic framing | show why ecological effects are often displaced outside transactions
- State planning, regulation, and policy frameworks: nature appears as managed stock, protected zone, compliance object, or public asset. [Literature anchors: Scott's critique of state legibility and high modernism; SEEA as constructive statistical counterpoint.] | acknowledge the state/regulatory path without making the paper a capitalism/socialism polemic | show that visibility and stewardship problems persist even when markets are constrained
- Ecosystem services and natural capital accounting, including SEEA: nature becomes legible through extent, condition, services, degradation, enhancement, and sometimes monetary valuation. [Literature anchors: Daily; Costanza et al.; TEEB; SEEA EA; ARIES for SEEA.] | connect to the strongest existing environmental accounting work | show respect for existing frameworks while preparing the distinction between description and governance
- Rights of Nature and ecological personhood: nature becomes legally represented as a rights-bearing person or subject. [Literature anchors: Ecuador Constitution Articles 71-74; Te Awa Tupua Act 2017; Atrato River case if added later.] | acknowledge an important activist/legal tradition | prepare the later argument that personification protects nature politically but creates ontological and governance problems
- Commons governance and Ostrom's resource systems: communities can steward shared resource systems through monitoring, sanctions, nested institutions, and adaptive rules. [Literature anchors: Ostrom 1990, 2005, 2009; Folke et al. 2005.] | introduce the strongest governance precedent | show that the paper builds on commons governance rather than replacing it
- REA and ValueFlows: economic events, agents, commitments, claims, and resources can be modeled with much more precision than conventional accounting allows. [Literature anchors: McCarthy 1982; Geerts and McCarthy; ValueFlows specification.] | introduce the information-system tradition that makes implementation plausible | prepare the reader for the worked modeling comparison
- Synthesis of the insufficiency: these approaches see parts of the problem, but none gives economic information systems a first-class object for a generative, unowned, complex ecological system that can accumulate event history and condition future access. | define the gap | create the opening for
Source
-
The ontological gap: Agent, Resource, Source | introduce the conceptual core early | give the reader the simplest possible vocabulary for the rest of the paper
- Define
Agent: an entity that can act, intend, commit, deliberate, bear responsibility, and participate in governance. Include individuals, organizations, networks, and possibly delegated artificial agents. | establish what agency means | prevent the later confusion between ecological causality and intention - Define
Resource: an appropriable or inventoriable output used in economic processes, such as water, timber, fish, energy, data, or a tool. | retain the usefulness of existing economic primitives | show that the paper is not rejecting resource accounting where it is appropriate - Define
Source: a generative system that yields resources, absorbs effects, conditions future possibilities, regenerates or degrades, and cannot honestly be reduced to either an owned resource or an intentional agent. | introduce the new primitive | make the central conceptual move clear - Explain why nature-as-resource fails: the river, watershed, forest, wetland, or atmosphere is reduced to inventory, stock, asset, or service flow, which hides generative complexity and tends toward extraction. | clarify one category error | create dissatisfaction with reduction to resource
- Explain why nature-as-agent also fails: ecological systems do not form intentions, make commitments, deliberate, or bear responsibility; human representatives inevitably speak for them. Use the corporation-as-person analogy carefully and concisely. | clarify the second category error | protect the paper from anthropomorphic confusion while respecting Rights of Nature motivations
- Present
Sourceas the third category: neither resource nor person, neither property nor agent, but a generative ecological/economic primitive around which stewardship can be organized. | stabilize the new ontology | give the reader a memorable conceptual anchor
- Define
-
Nature and economy as complex systems: the black-box principle | introduce the epistemology required by the proposal | move the reader from control/planning to stewardship/adaptation
- Explain that watersheds, forests, rivers, fisheries, soils, and atmospheres are complex systems: partially knowable, nonlinear, multi-scalar, path-dependent, and capable of regime shifts. [Literature anchors: Holling 1973; Gunderson and Holling 2002; Folke et al. 2005.] | establish the complexity requirement | show why complete representation is impossible
- Explain that the economy is also a complex adaptive system, not a clockwork machine that can be fully planned or optimized. | align ecological complexity with economic complexity | prepare the case for iterative governance loops
- Introduce the black-box principle: we do not model the full interior of the ecological system; we record boundary events, sense condition, and adapt governance. [Literature anchors: Ashby's black box and requisite variety; Scott's critique of schematic simplification.] | define the epistemic stance | replace false certainty with disciplined humility
- Connect this to Cynefin / probe-sense-respond, resilience theory, Panarchy, Morin, and adaptive governance. [Literature anchors: Snowden and Boone 2007; Holling 1973; Gunderson and Holling 2002; Folke et al. 2005. ToDo: select the most appropriate references; avoid overloading the main text with theory.] | ground the complexity argument in literature | make the proposal academically credible
-
Existing frameworks and what they miss | position the contribution in the literature | show continuity with prior work while making the novelty precise
- Ostrom and commons governance distinguish resource systems from resource units, which strongly resembles Source vs Resource. [Literature anchors: Ostrom 1990; Ostrom 2009.] | show that the idea has a commons-governance lineage | reassure readers that the proposal is not invented in isolation
- Social-Ecological Systems theory distinguishes resource systems, resource units, governance systems, and actors, but remains mostly analytical rather than executable. [Literature anchors: Ostrom 2009; McGinnis and Ostrom if added later.] | connect to SES literature | show the movement from description to implementation
- SEEA and ecosystem accounting make ecological condition and services visible, but do not by themselves condition future access through object-attached governance. [Literature anchors: SEEA EA; ARIES for SEEA.] | identify the "map vs cybernetic control system" distinction | make the implementation gap clear
- Ecological economics and natural capital recognize ecological limits and services, but often remain attached to stocks, flows, valuation, and capital metaphors. [Literature anchors: Georgescu-Roegen; Daly; Daily; Costanza et al.; TEEB; IPBES Values Assessment.] | acknowledge ecological economics as ally and limit case | prepare the ecological value vector as non-reductive alternative
- REA / ValueFlows model economic events well, but lack a first-class place for unowned generative sources that can be both flow origin and flow sink. [Literature anchors: McCarthy; Geerts and McCarthy; ValueFlows spec.] | identify the precise ontology gap in the chosen technical substrate | prepare the modeling demonstration
-
Worked case: modeling a river/watershed | turn the abstract argument into a concrete demonstration | help non-technical readers see the problem and solution in one memorable example
- Present the river/watershed case with multiple economic agents: agriculture, city utility, mining, hydro dam, fishing, tourism, forestry, and regeneration work. | make the problem empirical and relational | invite readers from policy/environment/economics into a shared case
- Model A: use ValueFlows 1.0 as-is. Show what it does well: economic events and derived resources such as gallons of water, fish, timber, and services. | avoid caricaturing ValueFlows | build fairness and credibility
- Show where Model A breaks: false ownership claim, resource-from-nowhere through
raise, resource/agent contradiction for pollution, missing source hierarchy, missing source coupling, missing black-box construct, missing governance reflexivity. | expose the need for the new primitive | create a clear "before" picture - Model B: augment ValueFlows with
vf:Source. Show extraction, pollution, non-consumptive use, regeneration, and cross-source coupling as first-class economic events. | demonstrate the proposed primitive | create the "after" picture - Use Occam's razor after the demonstration: adding one primitive removes multiple fictions and inexpressible residues. | justify the ontology surgically | convince the reader that this is a minimal, not bloated, extension
-
From visibility to stewardship: the governance loop | show why recording externalities is not enough | move from information to agency and institutional change
- Explain the loop: events -> ledger -> ecological interpretation -> policy/rules -> access affordances -> future events. | present the mechanism | show how the model becomes operational
- Show how extraction becomes visible: water abstraction, fish harvest, timber removal, biomass removal, soil removal. | make the ledger concrete | help readers imagine implementation
- Show how pollution/loading becomes visible: effluent, nutrient runoff, heavy metals, carbon emissions, sedimentation, heat, noise, or other relevant stressors. | make externalities first-class | create the core payoff of the paper
- Show how regeneration becomes visible: reforestation, riparian restoration, wetland repair, remediation, habitat restoration, pollution reduction, biodiversity enhancement. | avoid a purely punitive environmental ledger | create a regenerative and hopeful emotional direction
- Show how governance can condition future access: quotas, buffers, role requirements, monitoring requirements, restoration obligations, temporary restrictions, or graduated sanctions. | translate visibility into stewardship | make the model useful for policy and activism
- Explain why the model extends Ostrom into complex systems: rules are not designed once from complete knowledge; they adapt as the source ledger grows. | connect commons governance to complexity epistemology | make the originality claim stronger
-
Ecological value without reducing nature to price | articulate a value theory compatible with OVN, ecological economics, and complexity | prevent the model from being mistaken for another monetization framework
- Explain that in OVN terms value is relational: it arises from the relation between agents and what affects their goals, needs, viability, or capacity to act. | preserve the OVN value theory | avoid claiming that value lives inside nature as a thing
- Define ecological value as the contribution of an ecological Source to the maintenance, regeneration, resilience, adaptive capacity, and flourishing of socio-ecological systems. [Literature anchors: IPBES Values Assessment; Costanza 2000/2020 on efficiency, fairness, sustainability; Folke et al. on adaptive capacity.] | give the paper a usable definition | connect ecological value to stewardship rather than price
- Present the ecological value vector: Sustenance, Regeneration, Resilience, Adaptive Capacity, Generative Capacity, Commons Value, and Learning Value. [Literature anchors: ecosystem services literature for sustenance; resilience/Panarchy for resilience/adaptation; commons/infrastructure literature for commons value; adaptive governance and knowledge commons for learning value.] | make ecological value multidimensional and operationalizable | resist collapsing ecological value into one metric
- Connect the value vector to Source-NDO state: stock, flux, assimilation capacity, resilience, regime state, adaptive capacity, generative capacity, dependency index, and knowledge value. | show how value can be computed or interpreted from source state | bridge philosophy and information systems
-
Implementation: Nondominium hApp and Source-NDO | move from ontology to executable infrastructure | show that the proposal is not only theoretical
- Introduce Nondominium in the context of OVN, REA, ValueFlows, Holochain, and agent-centric infrastructure. Keep this concise for non-technical readers. | situate the implementation | make the technical stack legible without overwhelming the audience
- Explain the NDO as a governance-bearing object with identity, event history, attached rules, and stewardship relations, not as an owned asset. | connect Source to Nondominium architecture | show the property-regime innovation
- Explain how Source-NDO can make externalities visible: ecological Sources become endpoints for economic events, so extraction, loading, regeneration, and condition changes are no longer outside the ledger. | state the implementation payoff | reinforce the central thesis
- Explain the fivefold synthesis: commons governance (Ostrom), complexity epistemology (Morin/Cynefin/resilience), economic accounting (REA/ValueFlows), explicit externality tracking, and nondominium property relations. | consolidate the originality | leave the reader with a coherent synthesis
-
Limits, risks, and open questions | strengthen credibility and avoid techno-solutionism | show the proposal is responsible, situated, and open to governance
- Measurement quality: who produces ecological data, how sensors are trusted, how uncertainty is represented, and how missing data affects governance. | anticipate practical objections | build trust with scientific and policy readers
- Governance legitimacy: who interprets the ledger, who changes rules, who represents affected communities, and how conflicts are resolved. | address political reality | avoid the impression that information alone solves governance
- Indigenous, local, and experiential knowledge: how qualitative and place-based knowledge can inform the source ledger without being extracted or flattened. | widen the epistemic base | respect environmental justice and local stewardship traditions
- Data sovereignty and privacy: how communities control sensitive ecological and social data. | address risks of surveillance or enclosure | align the model with commons values
- Risk of green accounting capture: how to prevent Source-NDOs from becoming another way to legitimize extraction through better measurement. | name the adversarial failure mode | show moral seriousness
- Legal interoperability: how Source-NDO governance relates to rights of nature, public law, commons agreements, permits, and institutional policy. | connect the proposal to existing institutions | make adoption plausible
-
Conclusion: Source as missing primitive for ecological-economic information systems | close the argument | leave the reader with the paper's contribution in one sentence
- Restate the problem: externalities remain invisible when economic systems have no honest object for generative ecological systems. | return to the opening | create closure
- Restate the proposal:
Source/ Source-NDO is a third primitive alongside Agent and Resource. | make the core idea memorable | give readers a portable concept - Restate the practical effect: extraction, pollution, regeneration, and ecological condition can become visible economic events around a stewarded, non-ownable, complex source. | summarize the utility | leave the reader with a constructive path
- End with the paradigm shift: the central economic question becomes not only "how much value was extracted?" but "how much generative capacity was maintained, enhanced, or degraded?" | close with a strong normative and emotional frame | move the reader from extraction to stewardship
MODELING
Modeling a river: ValueFlows 1.0 vs Augmented ValueFlows (vf:Source / Nondominium)
A worked case study.
We model a river as commons or nondominium in two ways, using plain ValueFlows 1.0 and ValueFlows augmented with a vf:Source. We use these two alternatives to specify a primitive in the Nondominium hApp called Nondominium Object (NDO). Then we use Occam’s razor to choose between these two representations.
1. The case
A watershed feeds a river. The river spans a conflicting economic ecosystem:
| Agent | Interaction with the river | Externality / conflict |
|---|---|---|
| AgriCoop (irrigation) | consumes water | nutrient runoff (N, P) pollutes downstream |
| CityUtility (public supply) | consumes water | needs clean water; harmed by upstream pollution |
| MiningCo | consumes water, discharges effluent | heavy metals pollute; conflicts with consumption and agriculture |
| HydroDam | uses flow (non-consumptive) | diverts and re-times flow, starving agriculture downstream |
| FisherGuild | extracts fish | overfishing degrades the biological regime, then water quality |
| RiverTours | uses the river for transport/recreation | low impact; harmed by pollution and low flow |
| ForestryOp | cuts trees in the watershed forest | deforestation degrades infiltration, then river flow and quality |
| RegenCollective | reforestation, riparian restoration, remediation | raises the generative capacity of the coupled sources |
The goal: use Nondominium to align these agents toward sustainable use, arriving at what Ostrom would call successful commons stewardship, and going beyond Ostrom because the resource system is genuinely complex (the watershed), not merely complicated.
The governance loop (the mechanism)
The watershed is a complex system that cannot be fully described, quantified, or managed. The model does not try to represent that complexity. It treats the watershed as a black box and captures only what is measurable at the boundary as ValueFlows economic events: trees cut, fish caught, gallons abstracted, kilograms of pollutant discharged, trees replanted. The river is an NDO: the events are logged against it, the ledger is handed to complexity scientists, academics, environmental orgs, and resource managers, who formulate policy, which is formalized into the NDO’s governance rules, which govern access for each agent, and which evolve as the ledger grows. The loop is: observe boundary events, sense regime, adapt governance, condition future access. That is Cynefin probe-sense-respond applied to a commons.
2. The source hierarchy and the black-box principle
A watershed is a source of sources. The river cannot be separated from it: the river is as much a part of the whatershed as the bacteria, plants, animals, rock chemistry, and the atmospheric coupling (clouds, rain) that compose it. The watershed provides sub-sources (river, forest, fauna, flora), and those provide inventoriable economic resources.
WATERSHED (complex system, black box)
/ | \\ \\
RIVER FOREST FAUNA FLORA (sub-sources)
| | | |
water m3 planks fish herbs (economic resources, inventoriable)
Two distinct generative relations live here:
- Source provides Source (watershed -> river): generative parenthood.
- Source yields Resource (river -> gallons of water): the inventoriable output ValueFlows already models well.
The black-box principle: we never claim to model the interior of the watershed. We model the boundary flows (the events) and we govern the boundary (access rules). Everything below depends on this stance, and it is exactly where the two models diverge, because one of them has a place to put a black-boxed generative commons and the other does not.
3. Model A: ValueFlows 1.0 as is
VF 1.0 offers EconomicResource, EconomicEvent, Agent (Person / Organization / EcologicalAgent), Process, Action, ResourceSpecification, plus the planning and exchange layers (Intent, Commitment, Agreement, Plan). The events ValueFlows models superbly. The trouble is everything the events are about.
What VF 1.0 does well: the events and the derived resources
The gallons, fish, and planks, once appropriated, are proper EconomicResources, and the measurable acts are proper EconomicEvents. This part is correct and should be kept verbatim in both models.
Where it breaks: the river has no honest type
To log “AgriCoop abstracted 10,000 m3 from the river,” VF 1.0 needs the water to come from somewhere. The river is the source, but VF 1.0 has only two slots for it, and both are fictions:
Fiction 1, the river as EconomicResource. A resource requires primaryAccountable, defined as the agent with “primary rights and responsibilities (ownership).” Nondominium means no dominium, no owner. You must either invent an owner (a steward org as primaryAccountable), which records a false ownership claim in the very ledger meant to be authoritative and destroys the nondominium regime, or leave it null, which violates the resource model and breaks hREA implementations that require it.
Fiction 2, appropriation as raise. If you refuse the owner, the only way to get water into AgriCoop’s inventory is raise (“adjust up to account for newly found resource without a process”). But raise has no provider and no source: the water appears from nowhere, and the river’s depletion becomes invisible. This is the phlogiston negative-mass move in concrete form: to keep the books balanced you posit resource from nothing.
# VF 1.0 abstraction event, option (a): depletion vanishes
EconomicEvent { action: raise, resourceInventoriedAs: Water#agri, resourceQuantity: 10000 m3 }
# provider: none.
The river is never debited. Sustainability is unaccountable.
# option (b): reintroduce the owner fiction
EconomicResource River { primaryAccountable: StewardOrg }
# nondominium broken
EconomicEvent { action: transfer, provider: StewardOrg, receiver: AgriCoop, quantity: 10000 m3 }
Fiction 3, the Resource/Agent contradiction. Pollution is an output flow whose receiver must be an Agent. If the river is a resource, it cannot receive MiningCo’s effluent. To absorb pollution you must also type the river as an EcologicalAgent. Now the river is a resource (to inventory water) and an agent (to receive waste): one thing, two incompatible types, and the agent typing re-attributes the agency the prior synthesis showed it does not have.
EconomicEvent { action: produce, provider: MiningCo, receiver: ???, resourceInventoriedAs: HeavyMetals }
# receiver must be an Agent. River-as-Resource cannot receive -> forced dual typing.
The residues VF 1.0 cannot express at all
- No Source-provides-Source edge: the watershed -> river hierarchy is faked with containedIn (wrong: containment is not generation) or pushed to free text.
- No cross-source coupling: forest sustainability conditioning river flow and quality (the heart of the case) has no edge; it lives only in external analysis.
- No black-box construct: VF 1.0 assumes resources and events are fully specified. The epistemic stance “this interior is opaque and must not be modeled” is inexpressible.
- No governance reflexivity: the events -> policy -> rules -> access loop cannot close on the object. You can write Agreements and Commitments, but nothing anchors them to a governed commons that accumulates its own ledger and conditions its own future access.
Tally for Model A
Three active fictions (false ownership, raise-from-nowhere, resource/agent contradiction) plus four inexpressible residues (hierarchy, coupling, black box, governance reflexivity). The “parsimonious” ontology produces a baroque, internally contradictory model that loses the very things the project exists to do: hold a commons in nondominium and steward a complex system.
4. Model B: Augmented ValueFlows with vf:Source
Add one primitive: vf:Source. It is the ontology-layer type of what the property regime calls a Nondominium Object. They are the same entity from two angles:
| vf:Source (ontology) | Nondominium Object (property regime) |
|---|---|
| unowned, no primaryAccountable | held in nondominium, no dominium |
| stewardedBy -> Agent | governance module and stewards |
| event ledger with the Source as flow endpoint | events logged against the NDO |
| conditions / affords edge | access capabilities granted by governance |
| opaque complexInterior, sensed via regimeState / resilience | “we do not model the watershed, we govern the boundary” |
| Source-to-Source coupling | watershed -> river -> forest sustainability links |
The single new ontological affordance that does all the work: flows may originate from and terminate in sources, not only agents.
Entity inventory
Source Watershed { complexInterior: true, stewardedBy: WatershedGovernance, provides: [River, Forest, Fauna, Flora] }
Source River {
providedBy: Watershed,
yields: [WaterSpec, FishSpec],
currentStock, fluxRate, assimilationCapacity, regimeState, resilience, tippingThreshold,
stewardedBy: RiverGovernance, # no primaryAccountable: this is the point
realizedAs: NDO#river # the Nondominium Object
}
Source Forest { providedBy: Watershed, yields: [TimberSpec], conditions: River }
Key events, modeled cleanly
# Abstraction: the river is the provider (Source as flow origin); depletion is visible
EconomicEvent { action: extract, provider: River(Source), receiver: AgriCoop, quantity: 10000 m3 }
-> decrements River.currentStock
# Non-consumptive use: HydroDam uses the flux, altering the regime, not the stock
EconomicEvent { action: use, provider: River(Source), receiver: HydroDam, effect: River.regimeState }
# Pollution: the river is the receiver (Source as sink); loading is visible
EconomicEvent { action: produce, provider: MiningCo, receiver: River(Source), quantity: 50 kg HeavyMetals }
-> debits River.assimilationCapacity
# Fishing: the fauna/river source yields fish; extraction debits the biological stock
EconomicEvent { action: extract, provider: River(Source), receiver: FisherGuild, quantity: 500 fish }
# Regeneration: raises a coupled source, which conditions the river
EconomicEvent { action: raise, target: Forest(Source), provider: RegenCollective, quantity: 1000 trees }
-> Forest.conditions(River): improved infiltration raises River.fluxRate and resilience
Every event now has an honest subject. No false owner, no raise-from-nowhere, no dual typing. Depletion, pollution loading, and regeneration are all first-class and visible on the Source.
Governance reflexivity, native
The river NDO accumulates its own ledger. Complexity scientists read it and emit policy, formalized as access rules expressed through the affords edge:
Affordance { source: River, agent: MiningCo, action: produce(pollutant), maxQuantity: 10 kg/month, rule: R-2026-03 }
Affordance { source: River, agent: AgriCoop, action: extract(water), maxQuantity: 8000 m3/season, rule: R-2026-04 }
The loop closes on the object: events -> ledger -> policy -> affordances -> conditioned future events. The Source is the anchor that both accumulates the events and carries the governance that conditions the next ones.
Sustainability as a computable cross-source relation
Because Sources couple (Forest.conditions(River)), sustainability is not a slogan but a relation over the source web: for each Source, compare withdrawals (extract + consume) and loading (produce-into) against regeneration (raise) and assimilationCapacity, propagated across couplings. Deforestation shows up as a drop in Forest stock that lowers River fluxRate and resilience, tightening the river’s sustainable abstraction budget. The model makes the forest-river link an accounting fact.
Beyond Ostrom
Ostrom’s design principles (clear boundaries, monitoring, graduated sanctions, conflict resolution, nested governance) largely assume a complicated resource system whose state can be tracked and whose rules can be designed from understanding it. The watershed is complex: its interior is opaque, its responses nonlinear, its regime shifts abrupt. The Source-NDO extends Ostrom into the complex domain: you cannot design optimal rules from understanding the system, so you sense the boundary ledger and adapt governance continuously, holding precautionary buffers against tipping points you cannot predict. The black box is not a limitation worked around; it is the honest design center. That is the “beyond Ostrom” move, and Model B is built for it while Model A has no place to put it.
5. The Occam’s razor verdict
The razor’s naive reading favors Model A: VF 1.0 adds zero classes, the augmentation adds one. But the razor’s real target (Popper, Quine) is the multiplication of ad hoc hypotheses and unexplained residue, not the size of the vocabulary. It operates on two levels:
- Ontological parsimony: how many classes the vocabulary names.
- Model parsimony: how many entities and fictions a faithful representation must posit.
Adding vf:Source raises the first and sharply lowers the second.
| Model A (VF 1.0) | Model B (augmented) | |
|---|---|---|
| New classes | 0 | 1 (vf:Source = NDO) |
| False ownership claim | required (Fiction 1) | none (Source has no owner) |
| Resource from nowhere (raise) | required to hide depletion (Fiction 2) | none (Source is debited) |
| Resource/Agent contradiction | required for pollution (Fiction 3) | none (Source is sink) |
| Source hierarchy | inexpressible | native edge |
| Cross-source coupling | inexpressible | native edge |
| Black-box epistemics | inexpressible | native (complexInterior) |
| Governance reflexivity | out of band | native (ledger -> affordances) |
The decisive argument: Occam’s razor minimizes the entities a theory must posit, not the terms in its vocabulary. Nondominium Objects already exist in this system; the project is built on them. VF 1.0, lacking a type for them, must reconstruct each NDO out of mismatched parts plus three fictions. That reconstruction posits more (a fake owner, a phantom raise, a contradictory dual type) than simply admitting the entity that is already there. Refusing to name the Source does not remove it from the world; it forces you to smuggle it in piecemeal and falsely. The augmented ontology is more parsimonious at the level that matters: the furniture of reality it commits you to. VF 1.0 here is “simpler than possible” (the Einstein corrective): the honest simplest theory that fits a complex, unowned, generative, governed commons needs the Source primitive.
There is also an epistemic razor. Model A, by typing the river as a fully specified Resource, implicitly claims the watershed is analyzable (complicated). The case states it is not. Model B’s black-box Source matches the complex-domain epistemics and refuses to posit a describable interior it can never verify. Do not multiply unverifiable entities: another reason the razor cuts toward B.
Steelman of A, and rebuttal
The strongest case for A: “Use EconomicResource with a convention (primaryAccountable = a commons DAO, classifiedAs nondominium) and handle hierarchy, coupling, and governance in the hREA app layer. Ontologies need not model everything.” The rebuttal: pushing it to the app layer means the ontology stops being the shared semantic substrate, so every implementation reinvents nondominium and source semantics privately, defeating interoperability, the whole reason for a shared vocabulary. And the dominium fiction is not a neutral convention: primaryAccountable asserts ownership rights, the exact inverse of nondominium. Writing a false property claim into the authoritative ledger is a misstatement of the regime, not a shortcut. Parsimony and correctness point the same way.
6. Recommendation
Choose the augmented ValueFlows, but augment surgically. The augmentation is minimal and located precisely at the joint where VF 1.0 forces fictions:
- Keep VF 1.0 unchanged for the event ledger and the derived resources (gallons, fish, planks). It is correct there, in both models.
- Add vf:Source as the type of the Nondominium Object: the unowned, black-boxed, generative commons that anchors the ledger, absorbs pollution, yields resources, couples to other sources, and carries evolving governance.
This is itself a razor-friendly result: the smallest possible addition (one primitive) removes the largest amount of fiction (three active fictions plus four inexpressible residues), and it names an entity the system already contains. The new entity pays for itself many times over in eliminated epicycles.
7. Coda: what this means for Nondominium
vf:Source gives Nondominium its missing ontological foundation. An NDO is not a resource that happens to be unowned; it is a Source: a complex, generative, agentless commons whose interior is opaque and whose stewardship is the continuous, ledger-driven, complexity-informed adaptation of access rules at its boundary. Modeling it as a Source rather than a resource is what lets Nondominium be both faithful to the property regime (no dominium) and honest about the science (irreducible complexity), and it is what carries commons stewardship beyond Ostrom into the complex domain.
PERTINENT LITERATURE
We are attempting to ground an ontology and accounting infrastructure that can:
- Represent ecosystems as generative commons rather than owned resources.
- Capture externalities as first-class economic events.
- Track extraction, regeneration, pollution, ecological condition, and source-to-source coupling.
- Govern access through adaptive, polycentric, object-attached institutions.
- Treat ecosystems as complex systems whose internal dynamics remain partially opaque.
- Create information infrastructures that connect ecological observations, accounting systems, governance rules, and economic activity.
- Move beyond static resource accounting toward reflexive governance: events -> ledger -> interpretation -> policy/rules -> access affordances -> future events.
The literature should be organized around the claims we need to defend, not only around academic domains.
Claim-To-Literature Map
| Claim we need to support | Primary sources | What they contribute | Source-NDO extension |
|---|---|---|---|
| Externalities are effects not captured by the private transaction | Pigou, The Economics of Welfare (1920/1932), Part II, Ch. IX; Coase, "The Problem of Social Cost" (1960) | Pigou frames divergence between private and social net product; Coase reframes externalities through reciprocal harm, rights, and transaction costs | Source-NDO turns the ecological endpoint into a ledger endpoint, making the "outside" of the transaction recordable |
| Commons can be governed without privatization or central command | Ostrom, Governing the Commons (1990); Ostrom, Understanding Institutional Diversity (2005); Ostrom, "A General Framework for Analyzing Sustainability of Social-Ecological Systems" (2009) | Monitoring, graduated sanctions, nested institutions, resource systems/resource units, governance systems, actors | Source-NDO makes the resource system an executable information object rather than only an analytical category |
| Ecological systems are complex, nonlinear, and regime-shifting | Holling, "Resilience and Stability of Ecological Systems" (1973); Gunderson & Holling, Panarchy (2002); Folke et al., "Adaptive Governance of Social-Ecological Systems" (2005) | Resilience, adaptive cycles, cross-scale dynamics, adaptive governance, transformation under disturbance | Source-NDO encodes complexity epistemology through boundary observation and adaptive rule evolution |
| Complete ecological representation is impossible or dangerous as a governance assumption | Ashby, An Introduction to Cybernetics (1956); Scott, Seeing Like a State (1998); Snowden & Boone, "A Leader's Framework for Decision Making" (2007) | Black-box theory, requisite variety, critique of schematic legibility, probe-sense-respond in complex contexts | Source-NDO refuses to model the full interior; it governs observable boundary events and source state signals |
| Ecosystem services and natural capital make nature economically visible but often through service/capital metaphors | Daily, Nature's Services (1997); Costanza et al., "The Value of the World's Ecosystem Services and Natural Capital" (1997); TEEB (2010); Millennium Ecosystem Assessment (2005) | Ecosystem services, natural capital, valuation, human dependence on ecosystem functions | Source-NDO keeps the visibility goal but avoids reducing sourcehood to price, asset, or service flow |
| Environmental-economic accounting already tracks ecosystem extent, condition, services, and assets | SEEA Central Framework (2012); SEEA Ecosystem Accounting (2021); ARIES for SEEA | International statistical standard; spatial ecosystem accounts; extent, condition, physical and monetary service accounts; automated data/model integration | Source-NDO adds a reflexive governance layer: accounts condition future access instead of remaining descriptive |
| Values of nature are plural and cannot be reduced to one monetary metric | IPBES Values Assessment (2022); Costanza, "Social Goals and the Valuation of Ecosystem Services" (2000); Costanza et al., "Valuing natural capital and ecosystem services toward the goals of efficiency, fairness, and sustainability" (2020) | Intrinsic, instrumental, relational values; efficiency, fairness, sustainability; valuation as goal-relative | Source-NDO ecological value vector can express sustenance, regeneration, resilience, adaptation, generation, commons, and learning |
| Economic information systems need explicit ontological primitives | McCarthy, "The REA Accounting Model" (1982); Geerts & McCarthy on REA ontology; ValueFlows specification | Resources, Events, Agents; commitments and claims; economic event ledgers | Source-NDO proposes one surgical primitive missing from REA/ValueFlows: a generative source that can be flow origin/sink without being owner or agent |
| Classifications and information infrastructures shape reality; they are not neutral | Star & Ruhleder, "Steps Toward an Ecology of Infrastructure" (1996); Bowker & Star, Sorting Things Out (1999) | Infrastructure is relational and embedded; classifications have moral and political consequences | Adding Source is not just vocabulary; it changes what economic systems can see, govern, and protect |
| Rights of Nature legally protects ecosystems but often through personhood | Ecuador Constitution (2008), Arts. 71-74; Te Awa Tupua Act (2017); Atrato River case (to verify if used) | Nature as rights-bearing subject or legal person; human guardians speak for the ecological entity | Source-NDO offers a non-personifying alternative: governance attached to a source without pretending the source has intentions |
Core Bibliography To Use First
Externalities, Social Cost, and Economic Blind Spots
- Pigou, A. C. (1920/1932). The Economics of Welfare, especially Part II, Chapter IX, "Divergences between Marginal Social Net Product and Marginal Private Net Product." Use to ground the classical externality problem.
- Coase, R. H. (1960). "The Problem of Social Cost." Journal of Law and Economics, 3, 1-44. https://doi.org/10.1086/466560. Use as the institutional/property-rights counterpoint to Pigou.
- Georgescu-Roegen, N. (1971). The Entropy Law and the Economic Process. Harvard University Press. Use to ground the biophysical critique of treating the economy as a closed circular flow.
- Daly, H. E. (1977/1991). Steady-State Economics. W. H. Freeman / Island Press. Use to ground ecological limits, throughput, and the economy as subsystem of a finite biosphere.
Commons, SES, and Adaptive Governance
- Ostrom, E. (1990). Governing the Commons. Cambridge University Press. Use for the design principles of commons governance.
- Ostrom, E. (2005). Understanding Institutional Diversity. Princeton University Press. Use for institutional analysis and rule diversity.
- Ostrom, E. (2009). "A General Framework for Analyzing Sustainability of Social-Ecological Systems." Science, 325(5939), 419-422. https://doi.org/10.1126/science.1172133. Use for Resource System / Resource Unit / Governance System / User categories.
- Folke, C., Hahn, T., Olsson, P., & Norberg, J. (2005). "Adaptive Governance of Social-Ecological Systems." Annual Review of Environment and Resources, 30, 441-473. https://doi.org/10.1146/annurev.energy.30.050504.144511. Use for adaptive governance, learning, bridging organizations, and crisis-as-transformation.
- Berkes, F. (2012). Sacred Ecology (3rd ed.). Routledge. Use for indigenous and traditional ecological knowledge, but be careful not to instrumentalize it.
Complexity, Resilience, Black-Box Epistemology
- Holling, C. S. (1973). "Resilience and Stability of Ecological Systems." Annual Review of Ecology and Systematics, 4, 1-23. https://doi.org/10.1146/annurev.es.04.110173.000245. Use for ecological resilience and non-equilibrium thinking.
- Gunderson, L. H., & Holling, C. S. (Eds.). (2002). Panarchy: Understanding Transformations in Human and Natural Systems. Island Press. Use for cross-scale adaptive cycles.
- Ashby, W. R. (1956). An Introduction to Cybernetics. Chapman & Hall. Use for black-box theory and the Law of Requisite Variety.
- Snowden, D. J., & Boone, M. E. (2007). "A Leader's Framework for Decision Making." Harvard Business Review, 85(11), 68-76. Use for Cynefin and probe-sense-respond in complex contexts.
- Scott, J. C. (1998). Seeing Like a State. Yale University Press. Use as a warning against over-legibility and centralized simplification of complex natural/social systems.
Ecosystem Services, Natural Capital, and Plural Values
- Daily, G. C. (Ed.). (1997). Nature's Services: Societal Dependence on Natural Ecosystems. Island Press. Use for ecosystem services and life-support framing.
- Costanza, R., d'Arge, R., de Groot, R., et al. (1997). "The Value of the World's Ecosystem Services and Natural Capital." Nature, 387, 253-260. https://doi.org/10.1038/387253a0. Use as the landmark valuation paper; treat it as important but not the final model.
- Millennium Ecosystem Assessment. (2005). Ecosystems and Human Well-being: Synthesis. Island Press / World Resources Institute. Use for provisioning, regulating, cultural, and supporting services.
- TEEB. (2010). The Economics of Ecosystems and Biodiversity: Mainstreaming the Economics of Nature. Use for policy-facing ecosystem valuation and biodiversity economics.
- IPBES. (2022). Methodological Assessment Report on the Diverse Values and Valuation of Nature. Use to support plural, relational, intrinsic, and instrumental values of nature.
- Costanza, R. (2000). "Social Goals and the Valuation of Ecosystem Services." Ecosystems, 3, 4-10. Use to support valuation relative to efficiency, fairness, and sustainability.
- Costanza, R., et al. (2020). "Valuing natural capital and ecosystem services toward the goals of efficiency, fairness, and sustainability." Ecosystem Services, 43, 101096. Use as updated plural-value ecological economics.
Environmental Accounting and Information Infrastructure
- United Nations et al. (2012). System of Environmental-Economic Accounting 2012: Central Framework. Use for the official environmental-economic accounting baseline.
- United Nations et al. (2021). System of Environmental-Economic Accounting--Ecosystem Accounting (SEEA EA). Use as the most important official framework for ecosystem extent, condition, services, degradation, and enhancement.
- ARIES for SEEA. Use as the closest existing implementation precedent: an open-source, semantically informed modeling platform for compiling ecosystem accounts according to SEEA EA.
- Star, S. L., & Ruhleder, K. (1996). "Steps Toward an Ecology of Infrastructure." Information Systems Research, 7(1), 111-134. https://doi.org/10.1287/isre.7.1.111. Use to frame Source-NDO as infrastructure, not just an ontology.
- Bowker, G. C., & Star, S. L. (1999). Sorting Things Out: Classification and Its Consequences. MIT Press. Use to justify why adding the
Sourcecategory has practical and political consequences.
REA, ValueFlows, and Economic Ontologies
- McCarthy, W. E. (1982). "The REA Accounting Model: A Generalized Framework for Accounting Systems in a Shared Data Environment." The Accounting Review, 57(3), 554-578. Use as the origin of Resource-Event-Agent accounting.
- Geerts, G. L., & McCarthy, W. E. (2002). "An ontological analysis of the economic primitives of the extended-REA enterprise information architecture." International Journal of Accounting Information Systems, 3(1), 1-16. Use for REA as economic ontology.
- ValueFlows specification. Use the official vocabulary to ground claims about
EconomicResource,EconomicEvent,Agent,ResourceSpecification,Commitment, andClaim.
Rights of Nature, Legal Personhood, and Category Boundaries
- Constitution of the Republic of Ecuador (2008), Articles 71-74. Use for national constitutional recognition of Rights of Nature / Pacha Mama, including rights to existence, regeneration, restoration, and non-appropriation of environmental services.
- Te Awa Tupua (Whanganui River Claims Settlement) Act 2017. Use for legal personhood: the Act declares Te Awa Tupua a legal person with rights, powers, duties, and liabilities, exercised by Te Pou Tupua.
- Atrato River judgment (Colombia, 2016). [ToDo: verify official citation before relying on it.] Use only if we want a broader Rights of Nature comparison.
High-Priority Sources For The Actual Paper
If the paper must be concise, prioritize these:
- Pigou, The Economics of Welfare.
- Coase, "The Problem of Social Cost."
- Ostrom, Governing the Commons.
- Ostrom, "A General Framework for Analyzing Sustainability of Social-Ecological Systems."
- Holling, "Resilience and Stability of Ecological Systems."
- Gunderson & Holling, Panarchy.
- Folke et al., "Adaptive Governance of Social-Ecological Systems."
- SEEA Ecosystem Accounting.
- ARIES for SEEA.
- McCarthy, "The REA Accounting Model."
- ValueFlows specification.
- IPBES Values Assessment.
- Bowker & Star, Sorting Things Out.
- Te Awa Tupua Act 2017 and Ecuador Constitution Articles 71-74.
Together these support the paper's major claims: externalities as accounting failures, commons stewardship, social-ecological systems, complexity and black-box governance, ecosystem accounting, plural values of nature, information infrastructure, economic event ontologies, and the limits of ecological personhood.
Source Validation Notes
- SEEA EA is an official UN statistical framework adopted by the UN Statistical Commission in March 2021. Its core accounts are extent, condition, physical ecosystem services, monetary ecosystem services, and monetary ecosystem assets.
- Ostrom's 2009 Science paper explicitly distinguishes four first-tier SES subsystems: resource systems, resource units, governance systems, and users.
- Holling's 1973 paper is in Annual Review of Ecology and Systematics, 4, 1-23, DOI 10.1146/annurev.es.04.110173.000245.
- Folke et al. 2005 is in Annual Review of Environment and Resources, 30, 441-473, DOI 10.1146/annurev.energy.30.050504.144511.
- McCarthy's REA paper appeared in The Accounting Review, 57(3), 554-578.
- Costanza et al. 1997 appeared in Nature, 387, 253-260, DOI 10.1038/387253a0.
- Te Awa Tupua Act 2017, section 14, declares Te Awa Tupua a legal person and specifies that rights, powers, duties, and liabilities are exercised through Te Pou Tupua.
PRIOR KNOWLEDGE
What follows is not a legal novelty claim. It is an intellectual positioning exercise: where does Source-NDO sit relative to existing bodies of knowledge, and what exact gap does it fill?
1. Situating The Source-NDO Within Existing Literature
The Source-NDO sits at the intersection of several traditions that usually remain separate:
| Tradition | Primary object of analysis | What it gives us | What remains missing |
|---|---|---|---|
| Welfare economics and externalities | Private/social costs and benefits | A reason ecological effects disappear from transactions | A ledger object that makes the ecological endpoint explicit |
| Commons studies | Institutions, rules, collective action | Stewardship without privatization or central command | Executable resource-system objects in accounting infrastructure |
| Social-ecological systems | Resource systems, units, actors, governance systems | A diagnostic ontology for coupled human/ecological systems | Machine-readable economic event participation by resource systems |
| Ecological economics | Biophysical limits, natural capital, ecosystem services | The economy as embedded in ecological life-support systems | A non-reductive primitive for generative sources beyond capital/services |
| Resilience and complexity science | Adaptive cycles, regime shifts, emergence | A reason complete ecological modeling is impossible | An information-system pattern for black-box stewardship |
| Environmental accounting | Extent, condition, services, assets | Statistical visibility for ecosystems | Reflexive governance that conditions future economic access |
| Information infrastructure studies | Standards, classifications, infrastructure | Awareness that categories shape action and power | A new category that makes externalities governable without enclosure |
| REA / ValueFlows | Economic resources, events, agents | Event-centric economic accounting | A source primitive that can originate/receive flows without being owner or agent |
| Rights of Nature | Legal subjects and ecological guardianship | Legal/political protection of ecological entities | A non-personifying way to attach governance to nature |
The central observation is that none of these traditions by itself possesses a satisfactory operational category corresponding to what we call a Source: a generative, non-ownable, partially unknowable entity that yields resources, receives ecological effects, conditions future economic possibilities, and accumulates the historical evidence required for its own governance.
2. Economics: Externality As Displaced Information
Pigou gives us the classical formulation: private net product and social net product can diverge. This is the basis for understanding pollution, depletion, and ecological degradation as effects that do not return to the decision calculus of the actor producing them.
Coase complicates this by showing that externalities are also institutional and relational: harms are reciprocal, rights matter, and transaction costs determine whether parties can bargain or must rely on institutional design. This is useful for Source-NDO because the proposal is not merely "tax the polluter" or "price the service." It asks a prior information-system question: where does the ecological effect appear in the shared record?
Source-NDO reframes externality as a ledger topology problem. If the river cannot be a flow endpoint, pollution remains outside the economic event record or is routed through a fictional agent/resource. If the river is a Source, the event can be written as MiningCo -> River(Source), and the externality becomes internal to the information system without pretending the river is a person or an owned asset.
3. Ecological Economics: Nature As Capital, Services, And Biophysical Limit
Georgescu-Roegen and Daly supply the biophysical foundation: the economy is not a closed circular flow of exchange value. It is an open subsystem of a finite, entropic biosphere. This supports the paper's critique of treating ecosystems as ordinary inventory.
Daily, Costanza, the Millennium Ecosystem Assessment, TEEB, and SEEA make nature visible through services, natural capital, extent, condition, and ecosystem asset accounts. This is indispensable. The paper should not dismiss this tradition. It should say: this work made a major step by making nature legible to economics and policy.
The Source-NDO departure is narrower and more precise. Ecosystem services frameworks usually describe what nature contributes to humans. Source-NDO describes the generative system as an economic-information endpoint. It can yield resources, absorb pollution, condition other sources, and carry governance rules. The Source is not merely the stock behind a service flow; it is the governed, event-bearing object around which stewardship occurs.
IPBES and Costanza's later work on plural valuation help prevent a common misunderstanding: the proposal is not simply a new monetary valuation mechanism. Source-NDO is compatible with monetary valuation where communities choose it, but its deeper value contribution is multidimensional: sustenance, regeneration, resilience, adaptation, generation, commons dependence, and learning.
4. Ostrom And SES: Resource Systems Become Executable Objects
Ostrom's distinction between resource systems and resource units is the closest conceptual ancestor of Source vs Resource:
| Ostrom / SES | Source-NDO |
|---|---|
| Resource system | Source |
| Resource unit | Resource |
| Governance system | Object-attached governance rules and institutions |
| Users / actors | Agents |
| Action situation | Economic events, commitments, claims, and governance transitions |
Examples:
| Resource system / Source | Resource unit / Resource |
|---|---|
| Forest | Timber, carbon sequestration, habitat functions |
| Fishery | Fish |
| Irrigation system / watershed | Water |
| Wetland | Flood buffering, water purification, biomass |
The difference is operational. In Ostrom and SES theory, the resource system is an analytical category for researchers and practitioners. In Source-NDO, the Source is a machine-readable accounting and governance object: events can originate from it, terminate in it, be logged against it, and condition access rules attached to it.
This is the paper's bridge from commons analysis to economic information infrastructure.
5. Complexity, Resilience, And The Black-Box Principle
Holling, Panarchy, and adaptive governance literature establish that ecosystems are not merely complicated systems awaiting better measurement. They are complex adaptive systems with nonlinear dynamics, cross-scale coupling, thresholds, resilience, and transformation.
Ashby gives us a language for the black-box principle. A system may be too large, inaccessible, or complex to inspect internally. Governance does not require complete internal representation; it requires enough variety in observation and response to keep essential variables within viable bounds.
Scott provides the warning: attempts to make nature and society legible for centralized administration often simplify away the local, practical, ecological relationships that matter. This supports a careful design constraint: Source-NDO should not become another high-modernist over-modeling apparatus. It must preserve uncertainty, local knowledge, plural interpretation, and adaptive revision.
Cynefin gives a practical governance frame: in complex domains, the appropriate pattern is not predict-plan-control, but probe-sense-respond. The Source-NDO governance loop matches this:
- observe boundary events,
- sense source condition and regime,
- interpret through science and situated knowledge,
- adapt governance rules,
- condition future access,
- learn from the next round of events.
6. SEEA And ARIES: From Ecosystem Accounts To Reflexive Governance
SEEA EA is the strongest existing benchmark for ecosystem accounting. It organizes spatially explicit accounts for ecosystem extent, condition, physical ecosystem service flows, monetary ecosystem service flows, and monetary ecosystem assets. ARIES for SEEA is especially relevant because it shows that semantically informed tools can automate and customize ecosystem account compilation across territories.
The Source-NDO should be positioned as complementary, not competitive. SEEA answers: How can ecosystem condition and services be statistically represented and linked to economic activity? Source-NDO asks: How can economic activity around an ecological source be recorded in a way that changes future permissions, responsibilities, and stewardship rules?
The difference is the reflexive loop:
SEEA-style account -> policy insight
versus
Source-NDO event ledger -> ecological interpretation -> governance rule -> conditioned future event
In short: SEEA is closest to the map; Source-NDO aspires to be part of the governance cybernetics.
7. REA, ValueFlows, And The Missing Primitive
McCarthy's REA model is foundational because it moves accounting away from account balances as primary objects and toward economic phenomena: Resources, Events, and Agents. ValueFlows extends this pattern into open, networked economic coordination with commitments, claims, processes, resource specifications, and event vocabularies.
This is exactly the right substrate for the paper's purposes. The problem is not that REA/ValueFlows are wrong. The problem is that their primitive set forces ecological systems into categories that do not fit:
- If a river is an
EconomicResource, it tends to require an ownership or primary-accountable fiction. - If a river is an
Agent, it receives person-like agency it does not possess. - If water appears through
raise, depletion from the river/source can disappear from the ledger.
The Source primitive is therefore not a wholesale replacement of ValueFlows. It is a minimal extension at the exact point where the ontology otherwise creates fictions.
8. Rights Of Nature: Important Protection, Problematic Ontology
Rights of Nature and ecological personhood should be treated with respect. Ecuador's Constitution and the Te Awa Tupua Act are serious legal and political innovations responding to real failures of property law and environmental regulation.
The Source-NDO critique is not that these movements are wrong to protect nature. The critique is that legal personhood can introduce a category ambiguity: rivers, forests, and watersheds do not deliberate, commit, form intentions, or bear responsibility. Their rights and duties must be exercised through human representatives. This may be practical in law, but it is dangerous if imported directly into economic ontology.
Source-NDO offers a third path: attach governance to ecological systems without personifying them. A Source can be protected, stewarded, monitored, and governed without being an Agent.
9. Information Infrastructure: Why The Category Matters
Bowker and Star are important because they show that classification systems do not merely describe reality. They organize work, allocate visibility, distribute power, and silence some relations while amplifying others.
This means adding Source is not a cosmetic vocabulary change. It changes what the economic information system can see:
- without Source, depletion can become invisible,
- without Source, pollution has no honest receiver,
- without Source, cross-source coupling remains external analysis,
- without Source, governance cannot attach directly to the ecological object,
- without Source, externalities remain structurally external.
From an information-infrastructure perspective, Source-NDO is a classification intervention with practical consequences.
10. Where The Source-NDO Appears Most Original
The strongest originality emerges where several traditions fail to connect.
A. Ontological Separation Of Source And Resource
Many frameworks distinguish resource systems and resource units analytically. Few make that distinction operational inside economic event infrastructure. Source-NDO makes the distinction machine-readable and action-relevant.
B. Nondominium As An Ontological And Institutional Primitive
Most institutional frameworks assume private, public, collective, or common property. Source-NDO introduces governable-without-ownership as an economic-information category. Stewardship becomes separable from dominium.
C. Integration Of Externalities Into The Ledger
Externalities are no longer merely outside effects to price later. They become event flows with ecological endpoints. Pollution, extraction, and regeneration become part of the record around the Source.
D. Governance Attached To Ecological Objects
Most governance systems revolve around organizations. Source-NDO shifts the center of gravity toward the ecological object itself: watershed, river, forest, fishery, wetland, atmosphere. Governance becomes attached to the source being affected.
E. From Representation To Execution
Most literature discussed above is descriptive, analytical, legal, or statistical. Source-NDO asks whether a generative ecological system can become an executable governance primitive in an economic information system.
A Deeper Interpretation
Looking across the literature, the Source-NDO is best understood not merely as environmental accounting and not merely as commons governance. It is a proposed new category of economic object:
a generative, stewarded, non-ownable, partially unknowable entity that conditions the production of economic resources and accumulates the historical evidence required for its own governance.
Pieces of this appear in:
- Pigou and Coase: externalities, rights, and social cost,
- Ostrom: commons institutions and resource systems,
- SES theory: coupled resource/governance/user systems,
- Holling and Panarchy: resilience, adaptive cycles, and regime shifts,
- Ashby and Cynefin: black-box observation and probe-sense-respond,
- SEEA and ARIES: ecosystem accounts and environmental data infrastructure,
- IPBES and ecological economics: plural values and natural capital critique,
- REA/ValueFlows: event-centric accounting,
- Bowker and Star: the politics of classification and infrastructure,
- Rights of Nature: legal recognition of ecological entities.
The paper's contribution is the synthesis: turning those fragments into a single operational primitive for ecological-economic information systems.
COMPLEXITY ECONOMICS
We think that here is a deeper interpretation that goes beyond environmental accounting. The Source-NDO may represent an attempt to solve what I would call the missing ontological layer of complexity economics.
1. The hidden weakness in most complexity economics
Most complexity economists agree on several propositions:
- economies are complex adaptive systems,
- emergence matters,
- agents are heterogeneous,
- networks matter,
- equilibrium is generally absent,
- adaptation and learning are fundamental.
However, most complexity economics still focuses primarily on: agents, interactions, networks and institutions. The ontology remains largely anthropocentric. Even in the Santa Fe tradition, the economy is usually modeled as a population of interacting adaptive agents. The environment appears mostly as constraints, resources or exogenous conditions. This creates a paradox: complexity economics claims that economies are embedded in larger complex systems, but its models often stop at the boundary of human actors.
2. P2P economics extends complexity economics
This is widely covered in recent Sensorica writings, which argue that P2P systems are not merely compatible with complexity economics; they may constitute an organizational response to rising societal complexity. Hierarchical institutions fail because complexity exceeds centralized processing capacity, while distributed peer networks process information through self-organization and feedback. This is already an extension of complexity economics.
Complexity economics explains why economies behave as complex adaptive systems. P2P theory asks what organizational forms are capable of operating effectively within such systems?
The Source-NDO primitive adds another layer. As neoclassical economics focused on the market actor, complexity economics recognizes expands to the adaptive agent, which becomes a networked peer in P2P economics. They all treat resources pretty much the same way, as accountable, inputs and outputs of economic processes. Neither speak about a generative resource. The shift is subtle but profound. The Source-NDO says: the economy is not only composed of agents interacting. It is composed of agents, networks, institutions, economic resources, as well as generative sources. The watershed itself becomes part of the economic ontology, not as a resource, not as a stakeholder, not as a legal person, but as a generative system.
4. Introducing generative causality
Complexity economics usually models: Agent → Agent interactions or Agent → Network interactions. The Source-NDO introduces: Source → Source interactions. Examples:
- Forest → River
- River → Fish population
- Wetland → Watershed
So the economic system becomes embedded in a network of generative systems. This is much closer to ecological reality. In fact, one could argue that the Source-NDO introduces a form of ecological causality that complexity economics generally lacks. The economy is no longer a self-contained adaptive system, it becomes a subsystem of a larger adaptive system.
5. The deepest connection with Morin
This is where we see a very strong alignment with Edgar Morin. Morin repeatedly criticizes what he calls reductionism:
- separating object from context,
- separating part from whole,
- separating system from environment.
The Source-NDO does something unusual, it creates an accounting object that is simultaneously inside the economy and outside the economy. The watershed is not reducible to economic activity. Yet economic activity cannot be understood without it. This is very close to Morin's principle of recursive organization: the product becomes a producer of what produces it. The watershed produces economic activity. Economic activity alters the watershed. The modified watershed alters future economic activity. This recursive loop is largely absent from conventional accounting.
6. The most important thing still missing
We think that there is one major complexity-economic concept that is not yet fully present in the model. We talk about stocks, withdrawals, regeneration, pollution, resilience and tipping points. But we don’t fully represent emergence. Complexity economics is fundamentally concerned with emergent structures. The Source-NDO currently captures: state, condition, events. But not emergence itself.
Example
A watershed does not merely regenerate. It may produce entirely new structures:
- new wetlands,
- new ecological niches,
- new species assemblages,
- new economic opportunities,
- new social institutions.
Likewise, peer production networks exhibit emergence:
- new projects,
- new roles,
- new norms,
- new governance structures.
These cannot be predicted from individual events.
Proposed additions
Regime emergence
We already have: regimeState, resilience and tippingThreshold. We can also add emergentProperties or emergenceIndicators. Examples:
River:
- biodiversity index
- trophic complexity
- habitat diversity
OVN:
- contributor diversity
- innovation diversity
- project diversity
These are not resources. They are emergent system-level properties. This would move the ontology closer to complexity science.
Adaptive capacity
Resilience and adaptive capacity are not identical. Resilience measures persistence. Adaptive capacity measures ability to discover new configurations. A forest may be resilient but incapable of transformation. A peer network may be highly adaptive despite low stability. Therefore, resilience, adaptiveCapacity should probably be separate attributes. This comes directly from resilience theory and Panarchy.
Knowledge as a source
This is an exciting one. The watershed example naturally leads to ecological sources. But OVN and P2P systems revolve around another type of source: knowledge commons. Consider open-source codebase, Wikipedia, Design repository, Scientific knowledge commons. These are also generative, non-rival, stewarded, not reducible to resources. In fact they satisfy almost every property of the Source-NDO. So perhaps the Source ontology should be generalized:
| Source type | Examples |
|---|---|
| Ecological source | Watershed, forest |
| Knowledge source | Repository, design commons |
| Social source | Community, network |
| Cultural source | Language, traditions |
This would connect ecological commons and knowledge commons within the same framework. That would be a major contribution to P2P economics.
Source metabolism
Complexity economics often views economies as evolving ecologies. Ecologies have metabolism. A source therefore might have:
- inflows,
- outflows,
- regeneration rate,
- decay rate,
- carrying capacity.
Not merely inventory. Not merely stock. But metabolism. This language is much closer to ecological economics and complexity science than traditional accounting.
The strongest complexity-economics interpretation
If I were to express the Source-NDO in a single sentence within the context of complexity economics, I would say:
The Source-NDO extends complexity economics beyond networks of adaptive agents by introducing generative, non-ownable, adaptive sources as first-class participants in economic systems, allowing economic activity to be modeled as a recursive process embedded within larger ecological, knowledge, and social commons.
That is potentially a significant step because complexity economics has become very good at modeling interactions among agents, while the Source-NDO begins to model the generative substrates from which agents, resources, and opportunities continuously emerge. In that sense, the Source-NDO is not merely an environmental accounting innovation. It may be the sitting at the foundation of commons-centric complexity economics, where the primary unit of analysis is neither the firm nor the market nor even the agent, but the evolving generative commons that make economic activity possible. This also aligns remarkably well with the Sensorica argument that the next stage beyond hierarchy is networked collective intelligence: the Source-NDO provides a way to anchor that collective intelligence to the commons it depends on and regenerates.
VALUE
The value question touches the intersection of:
- OVN's theory of value,
- ecological economics,
- complexity economics,
- and the Source-NDO ontology.
Ecological value is often defined in ways that are incompatible with the OVN approach. Most ecological economics literature tends to define ecological value as:
- monetary value of ecosystem services,
- willingness-to-pay,
- replacement cost,
- natural capital value.
The OVN definition of value is fundamentally different. In OVN, value is not a property of a thing, it emerges from the relationship between an agent and something that affects the agent's goals, needs, viability, or capacity to act. Thus, ecological value cannot literally reside in the watershed, river, forest, or fish population. Instead:
Ecological value is the capacity of an ecological source to contribute to the viability, adaptive capacity, and flourishing of agents and agent networks.
This is much closer to a complexity-oriented interpretation.
NOTE: pay attention because according to OVN value is related to agents and their relations, it is not in the thing. Therefore, the economy becomes a human thing. Those who want to include nature in the economy cause a problem. Nature cannot have a value experience. The economy is a human thing. So there must be a separation. We must maintain an ontological separation, the dualism nature-economy persists. We can include nature in the economy, but by other means…
Ecological Value in OVN Terms
Definition
The contribution of an ecological Source to the maintenance, regeneration, resilience, and evolutionary potential of a socio-ecological system.
Notice that:
- the Source is not valuable in itself,
- value emerges through relationships,
- value is dynamic,
- value depends on context,
- value can differ across agents.
This is fully aligned with the OVN theory of value.
First Dimension: Sustenance Value
This is closest to conventional ecosystem services.
Examples:
- water provision
- food provision
- timber
- pollination
- climate regulation
Question:
How much does the Source support the ongoing functioning of agents?
Metrics:
- water availability
- biomass production
- fish population
- pollination rates
- nutrient cycling
Watershed example:
River → provides water
Forest → regulates water cycle
Second Dimension: Regenerative Value
This dimension is usually absent from economics. A Source is valuable because it can regenerate itself and other sources.
Example:
- Forest → restores soil
- Wetland → restores water quality
- Mangrove → restores fisheries
Metrics:
- regeneration rate
- soil formation rate
- nutrient recovery rate
- carbon sequestration rate
This aligns naturally with the Source-NDO notion of:
Source → conditions → Source
Third Dimension: Resilience Value
This is where complexity economics enters. A source contributes value because it stabilizes the broader system.
Example:
- Wetland absorbs floods.
- Forest buffers droughts.
- Biodiversity absorbs shocks.
Metrics:
- biodiversity
- redundancy
- connectivity
- response to disturbance
A river with the same water volume can have radically different resilience value.
Fourth Dimension: Adaptive Capacity Value
This goes beyond resilience.
Resilience asks:
Can the system survive?
Adaptive capacity asks:
Can the system evolve?
Examples:
- genetic diversity
- species diversity
- habitat diversity
- knowledge diversity within stewardship communities
Metrics:
- diversity indices
- network diversity
- innovation potential
This is strongly aligned with complexity economics.
Fifth Dimension: Generative Value
This is probably the most important dimension for the Source-NDO framework. The Source is fundamentally generative, it creates possibilities.
A watershed generates:
- water
- fish
- recreation
- tourism
- agriculture
- cultural meaning
- future opportunities
Many of these do not yet exist. Traditional economics struggles with this because future possibilities are not inventory. Generative value measures the capacity of a source to produce future value experiences.
Metrics (potential indicators):
- ecosystem complexity
- biodiversity
- ecological connectivity
- carrying capacity
- emergence indicators
Sixth Dimension: Commons Value
This dimension emerges directly from OVN and Nondominium. A source has value because it serves as shared infrastructure.
Examples:
- watershed
- atmosphere
- forest
- open-source design repository
Question:
How many agents depend on it?
Metrics:
- number of dependent agents
- diversity of dependent agents
- dependency ratio
- criticality
This resembles infrastructure value.
Seventh Dimension: Learning Value
This is rarely discussed. Complex adaptive systems continuously generate information.
A watershed is also:
- a sensor,
- an experiment,
- a knowledge generator.
Examples:
- environmental monitoring
- scientific research
- indigenous knowledge
- adaptive governance
Metrics:
- observations generated
- knowledge produced
- model improvements
- governance improvements
This is highly compatible with the OVN emphasis on knowledge commons.
A Complexity-Oriented Ecological Value Vector
We would propose:
Ecological Value
=
(
Sustenance,
Regeneration,
Resilience,
Adaptation,
Generation,
Commons,
Learning
)
or
EV =
(S,R,Rs,A,G,C,L)
The key insight is: Ecological value is multidimensional and cannot be collapsed into one number without losing critical information. This is very consistent with complexity economics.
Relation to the Source-NDO
The current Source-NDO already contains some relevant attributes:
currentStock
fluxRate
assimilationCapacity
resilience
regimeState
We would extend it with:
adaptiveCapacity
generativeCapacity
dependencyIndex
knowledgeValue
Then ecological value becomes something computed from Source state rather than something attached to extracted resources. This is a significant departure from both traditional economics and ecosystem service accounting.
The deeper synthesis with OVN
The deepest alignment with the OVN value theory may be this:
Traditional economics tends to ask: What is the value of the forest?
OVN asks: How does interaction with the forest affect agents?
The Source-NDO introduces a third perspective: What capacities does the forest possess that enable future value experiences for present and future agents?
This shifts attention away from pricing outputs and toward stewarding generative capacities.
In a complexity-oriented P2P economy, that may become the central economic question: not "How much value was extracted?" but "How much generative capacity was maintained, enhanced, or degraded?" The ecological value of a Source is therefore best understood as the state of its generative capacities across multiple dimensions rather than as a monetary quantity or a stock of ecosystem services.
NATURE AS AGENT
Let’s explore this beyond ontology design and enter philosophy, law, governance, and complexity science.
We believe that Nature is important, therefore it should be represented. At the same time, the movement that advocated the “Rights of Nature” is based on a wrong assumption. Nature is real and critically important, but it belongs to a fundamentally different ontological category than agents. The Source-NDO proposal gains strength precisely because it avoids reducing nature either to a resource or to a person.
1. The Common Category Error
The underlying issue is a classic category error. Gilbert Ryle introduced the notion of a category mistake: treating something as belonging to a logical category to which it does not belong.
Examples:
- asking what color the number seven is,
- treating a corporation as a biological organism.
Our ontology contains at least three distinct categories:
| Category | Examples |
|---|---|
| Agent | person, organization |
| Source | river, watershed, forest |
| Resource | water, timber, fish |
Confusion arises when one category is forced into another.
2. Nature as Agent
The environmental narrative often personifies nature as Mother Earth, Gaia, Nature is angry, the planet is punishing us, the river wants to flow freely, etc. Such language can be emotionally powerful and politically useful, but taken literally it creates conceptual problems. The Earth does not form intentions, deliberate, choose goals, negotiate, experience emotions, assign responsibility. A drought is not revenge. A flood is not punishment. A wildfire is not moral judgment. These are physical processes emerging from interactions among atmosphere, vegetation, hydrology, climate, geology, human interventions. Complexity theory actually reinforces this point as complex systems generate emergent behavior without intention. A hurricane, a watershed or an ecosystem does not decide.
3. Corporation as Person
A strikingly similar process occurred with corporations. Historically corporations were viewed as legal instruments, contractual structures or organizational technologies. Over time many jurisdictions adopted the notion of corporate personhood. A corporation became a "legal person." Initially this was a practical shorthand, it allowed corporations to sign contracts, own property and appear in court. As a legal fiction, this was useful. The problem emerged when the fiction became reified. People began speaking as if corporations genuinely possessed properties of natural persons.
The Contradiction
A corporation possesses assets, contracts and governance structures, but it lacks consciousness, subjective experience, suffering, moral responsibility. Only actual humans possess those. Yet personhood language encourages treating corporations as if they possessed both.This creates paradoxes.
Observed Consequences
Separation of power and responsibility
Corporations accumulate rights, assets and influence, while responsibility becomes diffused among shareholders, executives, employees and contractors. The "person" can act. Yet the person cannot suffer. This creates asymmetry.
Political distortions
Corporate personhood has enabled corporations to claim protections originally intended for human beings. The most cited example is the extension of constitutional protections to corporations in some jurisdictions. The legal fiction gradually acquires political reality.
Moral confusion
When an oil company pollutes a river, people say the corporation did it, but corporations do not possess minds. Actual decisions were made by boards, executives, investors and managers. The legal person can obscure the human causal chain.
4. Rights of Nature and Ecological Personhood
A parallel movement now exists around rivers, forests, and ecosystems. Examples include:
- Whanganui River
- Atrato River
- constitutional rights of nature in Ecuador
These developments emerge from legitimate concerns about environmental destruction, inadequate legal protection and failures of traditional property systems. The motivations are understandable, however, the solution often introduces another category mistake.
5. What Happens When Nature Becomes an Agent?
If a river is classified as an agent, several conceptual problems appear.
Problem 1: Agency without intention
Agents normally possess preferences, goals, decision-making capability. A river possesses none of these. Therefore its "agency" must be represented by humans. Immediately the question arises: Which humans, scientists, Government, indigenous groups, NGOs, residents, future generations? The river itself never answers, humans answer on its behalf. The river becomes a rhetorical proxy.
Problem 2: Representation paradox
The more nature is treated as an agent, the more human representatives gain power. Ironically, personified nature often leads to increased human mediation. The river never speaks, representatives do. This can conceal political interests behind ecological language.
Problem 3: Responsibility paradox
If a river becomes an agent, can it bear responsibility, can it violate obligations, can it be negligent, can it enter reciprocal agreements. The answer is generally no. Thus ecological personhood often grants rights without corresponding capacities. This differs from ordinary agency.
Problem 4: Complexity distortion
Complex systems do not act through centralized intentions. A watershed is distributed, emergent, multi-scalar and adaptive. Personification implicitly suggests a unified actor. Complexity science suggests the opposite. The watershed is not a subject. It is a system.
6. Why Source Is a Better Category
The Source concept avoids both errors. Nature is not reduced to a resource, which implies extraction. It is also not reduced to an agent, which implies intention. Instead Source captures what ecosystems actually are. A Source generates, conditions, constrains, enables, absorbs, transforms, regenerates. These are causal capacities, not intentions, preferences, emotions or ownership claims.
7. Complexity Economics Perspective
Complexity economics already moved beyond the notion that only agents matter. It recognizes networks, institutions, infrastructures, ecosystems, emergent structures. Yet most economic ontologies still force everything into agent or resource. The Source-NDO introduces a third category. This aligns better with complex systems thinking. A watershed is not an agent nor a resource. It is a Generative Complex System or a Source. This is a more precise ontological description.
The Deeper Conclusion
The historical experience of corporate personhood provides a warning. A legal fiction introduced as a practical shortcut gradually became mistaken for an ontological reality. The result was persistent confusion about rights, responsibility, accountability and power. Environmental personhood risks creating a parallel confusion. The intention, to protect nature, is understandable and often laudable. But the conceptual tool may be flawed because it assigns agency where there is none. The Source-NDO offers an alternative path. Instead of personifying nature, it recognizes nature as a distinct category of entity:
neither resource nor person, neither property nor agent, but a generative source whose dynamics condition economic activity and whose stewardship requires governance without ownership.
This is arguably more consistent with complexity science, ecological reality, and the principles of nondominium. It preserves the causal importance of ecosystems without importing anthropomorphic assumptions, and it allows governance systems to be attached to ecological systems without pretending that rivers, forests, watersheds, or the Earth possess intentions, preferences, emotions, or moral agency. In that sense, the Source concept is not merely an ontology extension; it is a corrective against two centuries of conceptual oscillation between treating nature as an object to be exploited and treating nature as a person to be represented. It proposes a third category that is closer to what complex ecological systems actually are.
Source-NDO: Making Nature Visible in Economic Information Systems
Abstract
Ecological degradation is usually described as a policy failure, a market failure, or a moral failure. It is also an information-system failure. Many effects of economic activity are called "externalities" because they do not appear inside the transaction record that coordinates economic agents. Pollution, depletion, regeneration, and ecological condition are often measured elsewhere, after the fact, by regulators, scientists, or affected communities. This paper proposes a new economic-information primitive, the Source, implemented as a Source-NDO: a generative, non-ownable, partially unknowable ecological system whose boundary events can be recorded, whose condition can be sensed, and whose access rules can adapt through stewardship governance. The Source is neither an Agent nor a Resource. A river does not deliberate or bear responsibility like an agent, but it is also not merely an owned stock of water. It is a generative system that yields resources, receives ecological effects, conditions other sources, and makes future economic activity possible. By extending event-based economic ontologies such as REA and ValueFlows with this primitive, externalities can become first-class economic events without reducing nature to property, capital, or legal personhood.
1. Externalities As Information Failure
Economic activity changes ecological systems. Farms withdraw water and release nutrients. Mines consume water and discharge heavy metals. Dams use river flow without consuming it but alter timing, sediment, and downstream access. Forest operations remove trees and change infiltration, erosion, and biodiversity. Restoration groups replant riparian zones, rebuild wetlands, and improve the regenerative capacity of the watershed. These acts are economic, but the ecological effects are often not recorded in the same information system that records the transaction.
The classical language for this problem is externality. Pigou framed it as a divergence between private and social net product: economic actors are interested in the private result of their operations, while some benefits or harms fall on others without compensation (Pigou, 1920/1932). Coase later reframed the problem through rights, reciprocal harm, and transaction costs, insisting that institutions matter because real parties do not bargain in a frictionless world (Coase, 1960). Both traditions remain useful. But both leave open a prior question: where, in the economic information system, does the ecological effect appear?
If a factory sells a product, the sale appears in accounting. If a farm buys water rights, the contract appears. If a city utility pays for treatment, the cost appears. But the river's changing assimilation capacity, the wetland's reduced flood-buffering capacity, or the forest's effect on downstream flow may appear only in environmental reports, scientific models, or public controversy. The economic ledger and the ecological ledger are separated. The "externality" is external not only to price but also to the record of economic coordination.
The purpose of this paper is to propose a way to change that record. We need economic information systems that make ecological effects visible without forcing nature into categories that distort it. The challenge is not simply to attach a price to nature, nor to declare nature a person, nor to create more reports. The challenge is to represent natural systems as entities around which economic activity, ecological monitoring, and adaptive governance can be coordinated.
2. Why Existing Categories Are Not Enough
Several traditions already make nature visible, and this paper builds on them. Ecosystem-services research showed that human economies depend on functions that ecosystems perform: water purification, pollination, flood regulation, soil formation, climate regulation, and much more. Daily's Nature's Services helped consolidate this framing (Daily, 1997), and Costanza et al. famously estimated the value of global ecosystem services and natural capital in Nature (Costanza et al., 1997). The Millennium Ecosystem Assessment and TEEB brought ecosystem services into policy language. The UN System of Environmental-Economic Accounting--Ecosystem Accounting (SEEA EA), adopted by the UN Statistical Commission in 2021, now provides the strongest official accounting framework for ecosystem extent, condition, physical service flows, monetary service flows, and ecosystem assets (United Nations et al., 2021).
Ecological economics adds a deeper warning. Georgescu-Roegen argued that the economic process is embedded in the entropy-bound material world, not in a closed circular flow of exchange (Georgescu-Roegen, 1971). Daly later framed the economy as a subsystem of a finite biosphere and emphasized throughput limits (Daly, 1977/1991). These traditions make clear that ecological systems are not optional background conditions. They are the generative basis and sink environment of economic life.
This is important work. It makes nature visible to economics and policy. Yet most of it remains descriptive. SEEA EA can tell us how ecosystem extent and condition are changing, and ARIES for SEEA can help compile ecosystem accounts through semantic modeling and data integration. But an account is not yet a governance object. It does not itself condition future economic events. It does not say: this mine can discharge only this much this month; this farm's abstraction is reduced because upstream forest loss has lowered flow resilience; this restoration work increases future access capacity. The account informs policy, but the policy remains outside the accounting object.
Commons governance gives us another crucial foundation. Ostrom showed that communities can govern common-pool resources without defaulting to either privatization or centralized command. Her design principles emphasize clear boundaries, monitoring, graduated sanctions, conflict-resolution mechanisms, and nested institutions (Ostrom, 1990). Later social-ecological systems (SES) work distinguishes resource systems, resource units, governance systems, and users (Ostrom, 2009). This distinction is close to the one we need. A forest is not the same as timber; a fishery is not the same as fish; a watershed is not the same as gallons of water.
But in SES theory, the resource system is primarily an analytical object. Researchers and practitioners use it to diagnose sustainability. It is not usually an executable object inside an economic information system. It does not itself receive economic events, accumulate a ledger, or carry machine-readable governance rules.
Rights of Nature and ecological personhood respond to a related failure. Ecuador's Constitution recognizes the rights of nature, or Pacha Mama, including respect for existence and the maintenance and regeneration of life cycles. The Te Awa Tupua Act declares the Whanganui River a legal person: "Te Awa Tupua is a legal person and has all the rights, powers, duties, and liabilities of a legal person" (Te Awa Tupua Act, 2017, s. 14). These are serious legal innovations. They emerge from real failures of property law and environmental regulation, and they should be treated with respect.
Yet legal personhood is not the same as economic ontology. A river does not deliberate, commit, form intentions, or bear responsibility. Its legal powers must be exercised by human representatives. That may be practical in law, but it creates problems if imported directly into economic information systems. The risk is a category error: nature is not merely a resource to be consumed, but it is also not an agent in the same sense as a person, cooperative, firm, or state.
Event-based economic ontologies such as REA and ValueFlows bring us closer to implementation. McCarthy's REA model shifted accounting toward Resources, Events, and Agents as economic primitives in shared data environments (McCarthy, 1982). ValueFlows extends this style of modeling for open and networked economic coordination. It can represent economic resources, economic events, agents, commitments, claims, processes, and resource specifications. This is exactly the kind of infrastructure needed for commons-oriented economic systems.
But if we try to model nature using only Agent and Resource, we hit a boundary. A river is not honestly an owned economic resource, and it is not honestly an agent. Something is missing.
3. Agent, Resource, Source
The missing primitive is Source.
An Agent is an entity that can act, intend, commit, deliberate, accept obligations, and bear responsibility. In economic information systems, agents can be individuals, organizations, networks, cooperatives, and perhaps delegated artificial agents whose scope and operator are declared. The crucial point is agency: the ability to participate in commitments and governance.
A Resource is an appropriable or inventoriable output used in economic processes: water abstracted into a tank, timber cut into planks, fish landed at a dock, electricity delivered to a meter, data stored in a repository, or a tool held in custody. Resource accounting is necessary. Once water is abstracted, fish are caught, or timber is cut, those things can be counted, transferred, consumed, used, or transformed.
A Source is different. A source is a generative system that yields resources, absorbs effects, conditions future possibilities, regenerates or degrades, and interacts with other sources. A watershed yields river flow; a forest conditions infiltration, biodiversity, and soil stability; a wetland absorbs flood peaks and pollutants; a fishery yields fish only if its biological regime remains viable. A source is not merely a stock behind a flow. It is a complex system whose generative capacity makes economic activity possible.
The Source category avoids two reductions. It avoids reducing nature to a Resource, which frames the river mainly as inventory or service flow. It also avoids reducing nature to an Agent, which imports intention where there is none. A river can provide water, receive pollution, condition fish populations, and alter economic possibilities. But it does not negotiate, promise, consent, or take responsibility. The Source is therefore a third category: neither resource nor person, neither property nor agent, but a generative ecological entity around which stewardship can be organized.
This may sound like a small terminological change, but classifications matter. Bowker and Star argue that classification systems and standards shape infrastructure, visibility, and power (Bowker & Star, 1999). If an information system has no category for a generative ecological source, certain relations remain invisible or must be represented through fictions. If it does have such a category, new forms of accounting and governance become possible.
4. Complexity And The Black-Box Principle
The Source primitive is not only an ontological proposal. It also carries an epistemological stance.
Watersheds, forests, fisheries, soils, and atmospheres are complex systems. Holling's work on ecological resilience challenged equilibrium-centered views of ecosystems and made persistence under disturbance central to ecological thinking (Holling, 1973). Panarchy extended this into cross-scale adaptive cycles (Gunderson & Holling, 2002). Adaptive governance literature emphasizes learning, bridging organizations, trust, and transformation under disturbance (Folke et al., 2005). These systems are partially knowable, nonlinear, path-dependent, multi-scalar, and capable of regime shifts.
The implication is not that we need infinite data before governing. It is the opposite. We must stop pretending that governance requires a complete model of the ecological interior.
Ashby's cybernetics gives us a useful language. Some systems are too large, inaccessible, or complex to inspect directly; they must be treated as black boxes whose behavior is studied through inputs, outputs, and responses (Ashby, 1956). Scott's critique of high-modernist planning gives the political warning: attempts to make nature and society legible for centralized control often simplify away the practical and ecological relations that matter (Scott, 1998). Cynefin gives the operational pattern: in complex domains one does not predict, plan, and control; one probes, senses, and responds (Snowden & Boone, 2007).
The Source-NDO adopts this stance. It does not try to model the full interior of a watershed. It records boundary events and condition signals. Trees cut, gallons abstracted, pollutants discharged, fish caught, wetlands restored, riparian buffers planted, sediment loads measured, biodiversity indicators updated. The governance object does not claim omniscience. It asks for a disciplined loop:
observe boundary events, sense source condition, interpret through science and situated knowledge, adapt governance rules, condition future access, and learn from the next round of events.
This is not a weakness of the model. It is the model's integrity. It refuses to reduce ecological complexity to false precision.
5. A River Case
Consider a watershed feeding a river. The river participates in a contested economic ecosystem. An agricultural cooperative abstracts water and contributes nutrient runoff. A city utility depends on clean water downstream. A mining company consumes water and discharges effluent. A hydro dam uses flow without consuming water but changes timing and sediment dynamics. Fishers extract fish. Tour operators use the river for recreation and transport. A forestry operation removes trees in the watershed, affecting infiltration and flow stability. A regeneration collective restores riparian zones and wetlands.
ValueFlows 1.0 can model many of the economic events well once the outputs have become resources. Water in the cooperative's tank is an EconomicResource. Fish landed by the fishing guild are EconomicResources. Timber cut into planks is an EconomicResource. Events such as use, consume, produce, transfer, work, and transport are useful and should be kept.
The problem is the river itself.
If the river is modeled as an EconomicResource, the system tends to ask who is primary accountable, who owns or controls the resource, or who bears the rights and responsibilities over it. In a nondominium regime, this is precisely the wrong move. The river is not owned by a steward organization. A steward may hold obligations, but stewardship is not dominium.
If the river is avoided as a resource, water abstraction may appear as a raise event in the receiver's inventory: water appears in AgriCoop's stock because it has been "found" or "raised." But then the river is not debited. Depletion disappears from the economic record.
Pollution creates another contradiction. If MiningCo discharges heavy metals, the river is the ecological receiver. But if the river is only a resource, it cannot receive an event in the way an agent can. If the river is typed as an ecological agent, then the system gives it agency it does not possess. The same entity is pushed into two incompatible categories: resource for extraction, agent for pollution.
The Source primitive removes these fictions. The event can be represented honestly:
EconomicEvent:
action: extract
provider: River(Source)
receiver: AgriCoop(Agent)
quantity: 10000 m3 water
The river is debited as a source, not as an owned resource. Pollution can also be represented honestly:
EconomicEvent:
action: produce/discharge
provider: MiningCo(Agent)
receiver: River(Source)
quantity: 50 kg heavy metals
Regeneration becomes visible:
EconomicEvent:
action: restore/raise
provider: RegenCollective(Agent)
target: RiparianForest(Source)
result: improved infiltration and reduced sediment loading
Source-to-source coupling also becomes visible. The forest conditions the river. The wetland conditions flood buffering and water quality. The river conditions fish populations. The source web is not an external report; it becomes part of the accounting graph.
The result is more parsimonious than forcing nature into existing categories. Adding one primitive removes several fictions: false ownership, resource-from-nowhere, river-as-agent, missing source hierarchy, missing source coupling, and missing object-attached governance. Occam's razor does not merely count vocabulary terms. It asks whether the theory multiplies ad hoc assumptions. Here, the Source primitive adds one term but removes a much larger number of fictions.
6. From Visibility To Stewardship
Visibility alone is not enough. A report can say that a river is degraded while the next transaction proceeds unchanged. The Source-NDO proposal matters because it connects the event ledger to adaptive governance.
The loop is:
events -> ledger -> ecological interpretation -> governance rules -> access affordances -> future events
Extraction becomes visible as an event from the Source to an Agent. Pollution becomes visible as an event from an Agent to the Source. Regeneration becomes visible as work that improves source condition or generative capacity. Cross-source coupling becomes visible when one source conditions another: forest loss lowers river resilience; wetland restoration increases flood buffering; biodiversity affects fishery stability.
Governance can then condition future access. If nutrient runoff exceeds thresholds, agricultural abstraction may require remediation commitments. If forest loss reduces infiltration, downstream water quotas may change. If restoration improves riparian condition, access constraints may adapt. If uncertainty is high, precautionary buffers can be increased. This is not static command-and-control. It is adaptive stewardship anchored in an object that accumulates its own history.
In this sense, the Source-NDO extends Ostrom into more complex ecological domains. Ostrom's commons governance gives us monitoring, sanctions, conflict resolution, and nested institutions. But many ecological systems are not merely complicated resource systems whose rules can be designed once from adequate knowledge. They are complex systems whose responses are uncertain and evolving. The Source-NDO treats rules as revisable governance attached to a source ledger.
7. Ecological Value Without Reducing Nature To Price
Because the paper proposes a new economic object, it must also be careful about value. The aim is not to replace the price of ecosystem services with another single number. The IPBES Values Assessment emphasizes the diverse values of nature, including instrumental, intrinsic, and relational values (IPBES, 2022). Costanza has also argued that valuation should be related not only to efficiency but also to fairness and sustainability (Costanza, 2000; Costanza et al., 2020).
In OVN terms, value is relational. It is not simply inside a thing. It emerges in relation to agents, needs, capacities, viability, goals, and future possibilities. A river does not "experience value." But the river has capacities that make value experiences possible for present and future agents. Therefore ecological value is best understood as the contribution of a Source to the maintenance, regeneration, resilience, adaptive capacity, and flourishing of socio-ecological systems.
This suggests a value vector rather than a single price:
Sustenance: water, food, materials, pollination, climate regulation.
Regeneration: soil formation, water purification, biomass recovery, carbon sequestration.
Resilience: buffering shocks, maintaining function under disturbance, avoiding regime collapse.
Adaptive capacity: diversity, connectivity, and the ability to discover new viable configurations.
Generative capacity: the ability to produce future resources, relations, opportunities, and meanings not yet known.
Commons value: the number and diversity of agents that depend on the source as shared infrastructure.
Learning value: observations, knowledge, models, and governance improvements generated through interaction with the source.
The key point is that ecological value is not exhausted by extracted resources. The central question becomes: how much generative capacity was maintained, enhanced, or degraded? That question is more appropriate for complex ecological sources than "how much value was extracted?"
8. Implementation: Source-NDO
The full usefulness of the Source primitive appears only when it is implemented inside an information infrastructure able to make a source persistent, uncapturable, governed, and accountable without making it owned. This is why Nondominium matters. The Nondominium hApp is built on Holochain and uses the ValueFlows vocabulary, but its distinctive contribution is not merely a new database schema. It is an architecture for organization-agnostic, governance-bearing objects on a distributed hash table (DHT).
In the current Nondominium design, an NDO begins with a Layer 0 identity anchor, NondominiumIdentity. This entry contains a name, initiator, property regime, resource nature, lifecycle stage, creation time, and description. Its action hash becomes the stable identifier of the object. In Holochain terms, this is not a record in a platform database controlled by an administrator; it is an entry on an agent-centric source chain, published and linked into the DHT for discovery. The object is found through DHT links and anchors, not through a central owner's table. This matters for commons and nondominium property regimes because the object is no longer dependent on one organization to continue existing. No platform operator can simply delete the source from a private database, and no single steward can convert its identity into private property by administrative command.
For a Source-NDO, this means a river, forest, wetland, watershed, or fishery can receive a persistent economic-information identity without becoming an asset owned by the organization that first registered it. The source can be discoverable, linkable, auditable, and governed while remaining organization-agnostic. This is the technical condition that makes nondominium more than a legal or moral declaration. The source becomes difficult to enclose because its identity, history, and governance relations are distributed across the network.
The second crucial feature is NDO-embedded governance. In Nondominium, governance rules are attached to the resource specification or, in the NDO model, to the object itself as it grows from identity to specification and process. Access and interaction rules are not merely external policies stored in a manual, a government database, or an organization's internal workflow. They become part of the object's operational surface. An agent does not simply ask a platform for permission to use a source; the agent interacts with an object whose rules travel with it.
For a Source-NDO, this is essential. A watershed cannot be governed well if every interaction is interpreted separately by disconnected institutions. The rules for abstraction, loading, remediation, monitoring, restoration, buffer requirements, or seasonal restrictions need to be attached to the source being affected. This gives the Source-NDO a kind of accessibility autonomy. It is not autonomous in the sense of having agency or intention. It is autonomous in the infrastructural sense that the conditions for access are bound to the object rather than to an owning organization.
The third feature is governance-as-operator. The Nondominium architecture separates the resource zome, which stores data, from the governance zome, which evaluates state transitions. In the specified pattern, a proposed transition is not applied directly. It is submitted as a governance transition request; the governance module evaluates applicable rules, checks permissions and constraints, and returns a governance result. Only then can state change and related economic events be recorded.
This separation is especially important for complex ecological sources. A Source-NDO should not change state merely because an agent writes a new value. If a river moves from "stable" to "stressed," if an extraction quota changes, or if a restoration event raises generative capacity, that change should be mediated by rules, evidence, and validation. Governance-as-operator turns the source from a passive record into a cybernetic object: events and observations feed into interpretation; interpretation updates rules or state; rules condition future events.
Because governance is a separate architectural module, it can evolve over time. This is where the black-box principle becomes operational. Stewards do not need to know the complete interior of the watershed. They acquire peripheral data: withdrawals, pollutant loads, sensor readings, fish counts, flood events, restoration work, seasonal variation, and local observations. Governance can then adapt around these signals. As the source ledger grows, stewards can revise thresholds, add monitoring obligations, change access rules, or introduce graduated sanctions. The governance module becomes the adaptive interface between the unknowable interior of the ecological system and the economic actions occurring at its boundary.
The fourth feature is the Private Participation Receipt system. PPRs are private, cryptographically signed participation records stored on agents' source chains. They extend ValueFlows claims with participation categories, performance metrics, signatures, counterparties, and resource references. This gives Nondominium a flexible relation between public exposure and private accountability.
For ecological governance, that flexibility is critical. Not every stewardship action or ecological interaction should be globally public in full detail. Some information may be sensitive: locations of endangered species, sacred sites, private land-use details, personal identities, or conflict records. At the same time, governance requires proof. Agents must be able to show that monitoring happened, that remediation work was completed, that a validator participated, that a custody or restoration obligation was fulfilled, or that a disputed event was recorded at a certain time. PPRs allow agents to secure evidence of their actions while preserving privacy by default.
This creates a powerful design space. Public policy or community governance may require some information to be publicly exposed: total withdrawals, aggregate pollutant loads, restoration events, or source-condition indicators. Other information may remain private but verifiable. In future implementations, zero-knowledge proofs can allow an agent to prove a claim about their private chain, such as "I completed five validated restoration commitments" or "this monitoring obligation was fulfilled by a qualified steward," without exposing all counterparties, notes, locations, or private records. PPRs therefore combine proof and accountability without forcing total transparency.
Taken together, these mechanisms explain why Source becomes powerful specifically in Nondominium. ValueFlows gives the event vocabulary. Holochain gives agent-centric DHT infrastructure. Nondominium adds organization-agnostic identity, uncapturable object persistence, embedded governance, governance-as-operator, and private-but-verifiable participation records. A Source-NDO is therefore not just a concept named in a paper. It is a candidate implementation pattern for ecological sources that must be stewarded without being owned, observed without being fully modeled, and governed without central platform control.
This combination is the paper's core contribution. Many traditions contain one part of it: commons governance, ecosystem accounting, event-based economic ontology, distributed infrastructure, and privacy-preserving accountability. Source-NDO composes them into an operational primitive for ecological-economic information systems.
9. Limits And Risks
The proposal must not be presented as a magic solution. Several risks are serious.
Measurement quality matters. Who produces ecological data? Are sensors trustworthy? How is uncertainty represented? What happens when data is missing, delayed, or contested? - P2P offers solutions, as it is focused on validation.
Governance legitimacy matters. Who interprets the ledger? Scientists, local communities, public agencies, indigenous authorities, resource users, or some combination? Who changes the rules? Who can challenge them? - Cosmolocalism provides answers, as knowledge remains global and decisionmaking rests with the locals.
Local and indigenous knowledge must not be extracted and flattened into a technical schema. Berkes' work on sacred ecology and traditional ecological knowledge is a reminder that stewardship knowledge is situated, relational, and often inseparable from culture and practice (Berkes, 2012). A Source-NDO should be able to receive qualitative, narrative, and community-validated signals without pretending all knowledge is sensor data.
Data sovereignty matters. Ecological data can expose communities, sacred sites, endangered species, or politically sensitive land-use conflicts. Visibility must be governed.
There is also a risk of green accounting capture. Better measurement can legitimize extraction if governance remains weak. A company might say: "we recorded the damage, therefore the activity is responsible." - Source-NDO addresses this as it ties to access rules, obligations, and accountability, not only disclosure.
Finally, legal interoperability remains open. Source-NDOs would need to interact with public law, permits, rights-of-nature frameworks, commons agreements, indigenous jurisdiction, and existing environmental reporting systems. The proposal is infrastructural, not a replacement for law or politics.
10. Conclusion
Economic systems have long struggled to include nature without reducing it. Nature appears as resource, asset, service, cost, externality, protected area, or legal person. Each category reveals something and hides something. The Source primitive proposes another path.
A Source is a generative, non-ownable, partially unknowable system that yields resources, receives ecological effects, conditions future economic possibilities, and accumulates the evidence required for its own stewardship. A Source-NDO makes this primitive executable in an economic information system. It allows a river, forest, wetland, fishery, or watershed to become a ledger-bearing governance object without becoming property and without pretending to be a person.
The paradigm shift is simple but deep. The economy is not only a network of agents exchanging resources. It is embedded in a wider network of generative sources. If economic information systems cannot see those sources, externalities will remain structurally external. If they can see them, then extraction, pollution, regeneration, resilience, and adaptive capacity can become part of economic coordination. Moreover, if governance is attached to these sources as an operator, a gate for economic action, we can steward them.
The next economic question is therefore not only: how much value was extracted? It is: how much generative capacity was maintained, enhanced, or degraded?
References
Ashby, W. R. (1956). An Introduction to Cybernetics. Chapman & Hall.
ARIES for SEEA. (n.d.). ARIES for SEEA Explorer. Integrated Modelling Partnership / United Nations ecosystem accounting tooling.
Berkes, F. (2012). Sacred Ecology (3rd ed.). Routledge.
Bowker, G. C., & Star, S. L. (1999). Sorting Things Out: Classification and Its Consequences. MIT Press.
Coase, R. H. (1960). The problem of social cost. Journal of Law and Economics, 3, 1-44. https://doi.org/10.1086/466560
Costanza, R. (2000). Social goals and the valuation of ecosystem services. Ecosystems, 3, 4-10.
Costanza, R., d'Arge, R., de Groot, R., et al. (1997). The value of the world's ecosystem services and natural capital. Nature, 387, 253-260. https://doi.org/10.1038/387253a0
Costanza, R., et al. (2020). Valuing natural capital and ecosystem services toward the goals of efficiency, fairness, and sustainability. Ecosystem Services, 43, 101096.
Daily, G. C. (Ed.). (1997). Nature's Services: Societal Dependence on Natural Ecosystems. Island Press.
Daly, H. E. (1977/1991). Steady-State Economics. W. H. Freeman / Island Press.
Ecuador. (2008). Constitution of the Republic of Ecuador, Articles 71-74.
Folke, C., Hahn, T., Olsson, P., & Norberg, J. (2005). Adaptive governance of social-ecological systems. Annual Review of Environment and Resources, 30, 441-473. https://doi.org/10.1146/annurev.energy.30.050504.144511
Geerts, G. L., & McCarthy, W. E. (2002). An ontological analysis of the economic primitives of the extended-REA enterprise information architecture. International Journal of Accounting Information Systems, 3(1), 1-16.
Georgescu-Roegen, N. (1971). The Entropy Law and the Economic Process. Harvard University Press.
Gunderson, L. H., & Holling, C. S. (Eds.). (2002). Panarchy: Understanding Transformations in Human and Natural Systems. Island Press.
Holling, C. S. (1973). Resilience and stability of ecological systems. Annual Review of Ecology and Systematics, 4, 1-23. https://doi.org/10.1146/annurev.es.04.110173.000245
IPBES. (2022). Methodological Assessment Report on the Diverse Values and Valuation of Nature. IPBES Secretariat.
McCarthy, W. E. (1982). The REA accounting model: A generalized framework for accounting systems in a shared data environment. The Accounting Review, 57(3), 554-578.
Millennium Ecosystem Assessment. (2005). Ecosystems and Human Well-being: Synthesis. Island Press.
Ostrom, E. (1990). Governing the Commons. Cambridge University Press.
Ostrom, E. (2009). A general framework for analyzing sustainability of social-ecological systems. Science, 325(5939), 419-422. https://doi.org/10.1126/science.1172133
Pigou, A. C. (1920/1932). The Economics of Welfare. Macmillan.
Scott, J. C. (1998). Seeing Like a State. Yale University Press.
Snowden, D. J., & Boone, M. E. (2007). A leader's framework for decision making. Harvard Business Review, 85(11), 68-76.
Star, S. L., & Ruhleder, K. (1996). Steps toward an ecology of infrastructure: Design and access for large information spaces. Information Systems Research, 7(1), 111-134. https://doi.org/10.1287/isre.7.1.111
Te Awa Tupua (Whanganui River Claims Settlement) Act 2017 (NZ).
TEEB. (2010). The Economics of Ecosystems and Biodiversity: Mainstreaming the Economics of Nature.
United Nations et al. (2021). System of Environmental-Economic Accounting--Ecosystem Accounting (SEEA EA).
ValueFlows. (n.d.). ValueFlows specification. https://www.valueflo.ws/
Appendix: Human-AI Collaboration Summary
This paper was produced through a human-AI collaboration in which the human author retained the primary role in goal definition, conceptual direction, normative judgment, and final authorship authority. The AI systems contributed retrieval, synthesis, structuring, drafting, and editorial support. This division follows the collaboration framework developed at Sensorica, where AI is treated as strongest in search, aggregation, summarization, pattern expansion, drafting, and procedural workflow support, while human contribution remains central in value framing, meaning-making, contextual reframing, ethical boundary setting, responsibility, creative direction, and final approval.
The collaboration unfolded in three broad phases: brainstorming, structuring and planning the paper, and text improvement/refinement.
In the brainstorming phase, the human author introduced the idea of Source as a new primitive alongside Resource and Agent, and framed Source as a complex system. The human author also made the first observation that treating a river either as a resource or as an agent creates a category error. The intuition and initial argument against nature-as-agent also came from the human author, including the comparison between personifying nature and treating corporations as persons. AI later helped substantiate and expand this argument.
This brainstorming phase drew on the humans' experience with the OVN model and with development of the Nondominium hApp. The human author identified the governance layer of Nondominium as the place where ecological complexity could enter the system: not by claiming complete knowledge of an ecosystem's interior, but through policy that adapts from peripheral data, source-condition signals, and information acquired through economic events. The human author also explicitly introduced the black-box idea for complex ecological systems; AI later helped find relevant references from cybernetics, complexity science, resilience theory, and adaptive governance to support that intuition. The discussion of value depended on Sensorica's definition of value in the OVN wiki, which reflects the network's collective intelligence: value is relational and emerges through agents' experiences, needs, goals, and capacities, rather than residing as a property inside objects.
AI contributed pattern recognition, conceptual expansion, and first-pass theoretical scaffolding. It helped articulate the ecological value vector used in the paper: Sustenance, Regeneration, Resilience, Adaptive Capacity, Generative Capacity, Commons Value, and Learning Value. It also helped polish the critique of nature-as-agent: ecological systems generate effects but do not deliberate, intend, commit, feel harm, or bear moral responsibility. That exchange supplied important conceptual raw material, but the originating questions, domain constraints, value commitments, and direction of inquiry came from the human author and the prior human brainstorming.
In the structuring and planning phase of this paper, the human author provided a first layout with 3 interlocking structures: thematic, pragmatic and logical. He also explained the intended audience, specified that the paper should help environmental practitioners, economists, policy actors, activists, and related readers understand a paradigm shift, and asked for the planning and brainstorming material to remain intact. The human author chose the paper's practical goal: making externalities visible inside economic information systems so economic agents can steward natural sources and resources. The human author also set editorial constraints: keep the paper concise, preserve conceptual depth, use references and quotations for important claims, and keep the planning file available for later revision.
The AI contribution in this phase was to read and reorganize the planning material, strengthen the paper structure, improve the literature and prior-knowledge sections, validate and insert source anchors, and draft the paper. The AI synthesized the human-provided concepts into a more coherent essay structure: externalities as information failure; limits of existing categories; Agent, Resource, and Source; complexity and the black-box principle; a worked river case; the visibility-to-stewardship governance loop; ecological value without reduction to price; implementation as Source-NDO; and limits and risks. The AI also added references and performed coherence and diagnostic checks.
In the text improvement and refinement phase, the human author evaluated the draft and identified a weak point in the implementation section. The human author clarified that the full power of the Source primitive only becomes visible in the context of the Nondominium hApp, and supplied the architectural concepts that needed to be made explicit: organization-agnostic NDOs on the DHT, uncapturable commons and nondominium property regimes, NDO-embedded governance, governance-as-operator, the evolution of governance as a separate module, and Private Participation Receipts as a flexible privacy/accountability mechanism. The human author also connected these concepts back to the black-box ecological model: stewards use peripheral data and economic-event information to steer a complex source toward sustainable states without pretending to fully know its interior.
The AI contribution in this refinement phase was to inspect the Nondominium documentation and codebase, verify the current implementation status and architectural claims, and rewrite the implementation section accordingly. This included distinguishing implemented features, such as the Layer 0 NondominiumIdentity DHT anchor and PPR data structures, from normative architectural targets such as full governance-as-operator lifecycle integration. AI then strengthened the prose so that the implementation section explained why Source-NDO is not merely a conceptual addition to ValueFlows, but an implementation pattern made powerful by Nondominium's DHT identity, embedded governance, adaptive governance module, and private-but-verifiable participation records.
The collaboration was therefore hybrid. The human author supplied the original problem, philosophical and political motivation, domain knowledge, conceptual constraints, and evaluative direction. AI systems supplied cognitive offloading: retrieval, condensation, comparison, structure generation, prose drafting, and consistency checking. The resulting paper should be read as human-directed and AI-assisted: the AI helped transform a complex body of prior thinking into a written form, but the central thesis, purpose, framing, and responsibility for use remain with the human author.
Source-NDO: Making Nature Visible in Economic Information Systems
Abstract
Ecological degradation is usually described as a policy failure, a market failure, or a moral failure. It is also an information-system failure. Many effects of economic activity are called "externalities" because they do not appear inside the transaction record that coordinates economic agents. Pollution, depletion, regeneration, and ecological condition are often measured elsewhere, after the fact, by regulators, scientists, or affected communities. This paper proposes a new economic-information primitive, the Source, implemented as a Source-NDO: a generative, non-ownable, partially unknowable ecological system whose boundary events can be recorded, whose condition can be sensed, and whose access rules can adapt through stewardship governance.
The Source is neither an Agent nor a Resource. While in abstract modeling an "agent" can be thinly defined as any entity with a behavioral rule, real-world trans-domain systems—where transactions, agreements, and legal consequences merge on distributed ledgers—require a thicker distinction. A river does not negotiate, commit, or bear legal liability. Yet it is also not merely an owned, inventoriable stock of water. It is a generative system that yields resources, receives ecological effects, conditions other sources, and makes future economic activity possible. By extending event-based economic ontologies such as REA and ValueFlows with this primitive, ecological boundaries can be represented honestly without reducing nature to property, capital, or legal personhood, and without laundering human political decisions behind a fictitious natural agency.
1. Externalities As Information Failure
Economic activity changes ecological systems. Farms withdraw water and release nutrients. Mines consume water and discharge heavy metals. Dams use river flow without consuming it but alter timing, sediment, and downstream access. Forest operations remove trees and change infiltration, erosion, and biodiversity. Restoration groups replant riparian zones, rebuild wetlands, and improve the regenerative capacity of the watershed. These acts are economic, but the ecological effects are often not recorded in the same information system that records the transaction.
The classical language for this problem is externality. Pigou framed it as a divergence between private and social net product: economic actors are interested in the private result of their operations, while some benefits or harms fall on others without compensation (Pigou, 1920/1932). Coase later reframed the problem through rights, reciprocal harm, and transaction costs, insisting that institutions matter because real parties do not bargain in a frictionless world (Coase, 1960). Both traditions remain useful. But both leave open a prior question: where, in the economic information system, does the ecological effect appear?
If a factory sells a product, the sale appears in accounting. If a farm buys water rights, the contract appears. If a city utility pays for treatment, the cost appears. But the river's changing assimilation capacity, the wetland's reduced flood-buffering capacity, or the forest's effect on downstream flow may appear only in environmental reports, scientific models, or public controversy. The economic ledger and the ecological ledger are separated. The "externality" is external not only to price but also to the record of economic coordination.
The purpose of this paper is to propose a way to change that record. We need economic information systems that make ecological effects visible without forcing nature into categories that distort it. The challenge is not simply to attach a price to nature, nor to declare nature a person, nor to create more reports. The challenge is to represent natural systems as entities around which economic activity, ecological monitoring, and adaptive governance can be coordinated on-ledger.
2. Why Existing Categories Are Not Enough
Several traditions already make nature visible, and this paper builds on them. Ecosystem-services research showed that human economies depend on functions that ecosystems perform: water purification, pollination, flood regulation, soil formation, climate regulation, and much more (Daily, 1997; Costanza et al., 1997). The UN System of Environmental-Economic Accounting—Ecosystem Accounting (SEEA EA), adopted in 2021, provides a robust framework for ecosystem extent, condition, and service flows (United Nations et al., 2021).
Ecological economics adds the warning that the economic process is embedded in a finite, entropy-bound biosphere (Georgescu-Roegen, 1971; Daly, 1977/1991). Yet most of this work remains descriptive; accounts inform policy, but the policy remains outside the accounting object. The account does not itself condition future economic events at the ledger level.
Commons governance gives us another crucial foundation. Ostrom showed that communities can govern common-pool resources without defaulting to either privatization or centralized command (Ostrom, 1990). Her social-ecological systems (SES) work distinguishes resource systems (forest, fishery) from resource units (timber, fish) (Ostrom, 2009). But in SES theory, the resource system is primarily an analytical object. It is not an executable object inside an economic information system. It does not itself receive economic events, accumulate a ledger, or carry machine-readable governance rules.
Rights of Nature and ecological personhood respond to these failures by declaring rivers or forests to be legal persons (e.g., the Whanganui River in New Zealand; Te Awa Tupua Act, 2017). These are serious legal innovations, yet legal personhood is not the same as economic ontology. A river does not deliberate, commit, form intentions, or bear responsibility. Its legal powers must be exercised by human representatives, creating a proxy-power bottleneck prone to capture.
Event-based economic ontologies such as REA (McCarthy, 1982) and ValueFlows bring us closest to implementation, representing resources, events, agents, commitments, and claims in shared data environments. But if we try to model nature using only Agent and Resource, we hit a boundary.
3. Agent, Resource, Source
3.1 The Thick vs. Thin Definition of Agency
A major barrier to resolving nature’s representation in economic software is a definitional mismatch. In abstract modeling, systems dynamics, and agent-based modeling (ABM), "agency" is often defined thinly: an agent is simply any computational entity possessing an assigned behavioral rule (Tesfatsion, 2006). Under this thin definition, a river, a microbial community, or a weather pattern can be modeled as an agent. The "intention" or "rule" is merely a mathematical function decided by the modeler to run simulations or generate forecasts.
However, when an economic ontology is used to build real-world participatory systems—such as peer-to-peer economic networks, supply chains, or shared ledgers executing smart contracts and covenants—the definition of Agent thickens and collides with legal, social, and civic agency. In these trans-domain platforms, an Agent is an entity that:
- possesses a persistent identity,
- can cryptographically sign agreements,
- can initiate and accept commitments (promises of future action),
- can deliberate and make intentional choices, and
- can be held accountable and liable under community dispute resolution or legal frameworks.
When economic transactions and legal/governance contracts merge in the same software ledger (as is common in decentralized web3 or Holochain architectures), applying a "thin" modeling shortcut like river-as-agent in a "thick" execution environment introduces severe contradictions:
- The Representation Loophole: Because the river cannot log into a device, write to a source chain, or sign a transaction, human proxies or committees must act and commit "on its behalf." This concentrates immense, un-auditable power in the hands of the proxy, who can represent their own political or commercial interests as "what the river decided."
- The Liability Paradox: If a river is modeled as an agent with standing, it must also be liable for its actions. If the Ganges floods a field or destroys a village, can the river be sued or punished? When courts in India declared rivers as legal persons, the ruling was quickly stayed because the nominated human guardians refused to accept legal liability for the river's floods.
To maintain semantic and trans-domain integrity, we must restrict Agent to entities capable of human-scale decision-making, cryptographic commitment, and accountability (individuals, cooperatives, organizations, networks, or clearly bounded software bots with human operators).
3.2 The Limits of Resources and Processes
If the river is not an Agent, can it be modeled as a Resource or a Process?
An Economic Resource is an appropriable, inventoriable, and measurable output of human or natural activity. Once water is pumped into a tank, timber is cut, or fish are landed, they are Resources. They are finite, rivalrous, can be held in custody by a custodian, and can have an owner. A river or a watershed is not an inventoriable resource; treating it as such requires assigning an owner or primary accountable agent, which is fundamentally incompatible with a commons or nondominium property regime.
A Process in event-centric ontologies defines a bounded, intentional economic transformation (a recipe) with planned inputs, outputs, and start/end dates, carried out by agents (e.g., a manufacturing run). A river is not an intentional economic process. Attempting to model a river as a Process requires:
- representing a process with no beginning or end date,
- representing a process running on itself for its own cause without human agents, and
- representing an infinite recursive cascade of feedback loops (processes of processes) with completely unknown inputs and outputs.
Furthermore, a process is event-centric, whereas ecological stewardship is state-centric. We need to track the persistent condition and health of the river over time, not just the individual events that pass through it.
3.3 The Source Primitive
The missing primitive is Source.
A Source is a generative, non-ownable, partially unknowable system that yields resources, receives ecological effects, conditions future economic possibilities, and accumulates the historical ledger required for its own stewardship. It is the resource-system counterpart to Ostrom’s resource-units.
+-----------------------------------------------------------------------+
| AGENT |
| Acts, intends, commits, and bears responsibility |
| (Individuals, Cooperatives, Organizations, Bots) |
+-----------------------------------+-----------------------------------+
|
Boundary Events | (Extract, Discharge, Restore)
v
+-----------------------------------------------------------------------+
| SOURCE |
| Generative system; lacks intention and ownership |
| (Watershed, River, Forest, Knowledge Commons) |
+-----------------------------------+-----------------------------------+
|
| Yields
v
+-----------------------------------------------------------------------+
| RESOURCE |
| Appropriable, inventoriable, and measureable units |
| (Water m³, Timber logs, Landed fish, CAD Files) |
+-----------------------------------------------------------------------+
By introducing Source as a first-class ontological primitive, we establish a clean separation of roles:
- The Source remains a passive, ledger-bearing ecological anchor that represents the natural boundary. It has no agency, cannot commit, cannot be sued, and cannot be owned.
- The Stewards are real Agents (organizations, councils, or individuals) who hold explicit, auditable obligations to monitor the Source, interpret its condition, and adjust its access rules.
- The Resources are the actual units harvested or extracted from the Source, which can then flow through standard economic processes.
4. Complexity And The Black-Box Principle
The Source primitive is not only an ontological proposal; it also carries a crucial epistemological and cybernetic stance.
Watersheds, forests, fisheries, soils, and atmospheres are complex systems. They are characterized by non-linear relationships, multi-scalar feedback loops, path dependency, and the capacity for sudden regime shifts (Holling, 1973; Gunderson & Holling, 2002). They are partially knowable but fundamentally unpredictable.
Traditional modern planning often assumes that to govern an ecosystem, we must construct a complete, detailed model of its interior. This overconfidence leads to what can be called the tyranny of the model (Scott, 1998): a centralized, simplified representation of nature is codified into rules, and when nature behaves unexpectedly, the model's rigid constraints cause catastrophic failures or ecological collapse. Centralizing the representation of a complex system inside a single "atmosphere-agent" or "river-agent" that automatically computes and triggers actions assumes a level of predictive omniscience we do not possess.
The Source-NDO operationalizes W. Ross Ashby's black-box principle (Ashby, 1956). We acknowledge that the interior of the ecological system is complex and opaque. Instead of trying to model its entire internal dynamics, we govern the boundary where human economic activity interacts with it. We record boundary inputs and outputs (extractions, discharges, restoration work) and observe peripheral condition signals (water quality, flow rate, species diversity index).
Stewardship then proceeds not through a static, pre-programmed engineering model, but through a disciplined, adaptive cybernetic loop:
- Sensing: Economic boundary events are recorded on the Source's ledger alongside sensor and qualitative condition signals.
- Deliberation: Human agents, local organizations, and scientific/indigenous experts interpret these signals, bringing a variety of competing models and situated knowledge to bear.
- Adaptation: Based on this collective interpretation, stewards revise the quantitative access rules (affordances) and thresholds attached to the Source.
- Conditioning: These updated rules programmatically condition or restrict future boundary events.
This black-box approach shifts our focus from predictive control to distributed, polycentric sensemaking (Folke et al., 2005). It accommodates both scientific data and qualitative, localized, and indigenous observations without flattening them into a single technical schema.
5. A River Case
To understand why this ontological separation is necessary, let us analyze a watershed commons using Occam's razor.
Consider a river basin with multiple conflicting actors:
- An agricultural cooperative (AgriCoop) abstracts water for irrigation and contributes nutrient runoff.
- A mining company (MiningCo) consumes water and discharges heavy-metal effluent.
- A hydro dam (HydroDam) uses flow non-consumptively but alters downstream flow timing and sediment.
- A fishing guild (FisherGuild) extracts fish from the river.
- A forestry operation (ForestryOp) logs trees in the watershed, altering runoff stability.
- A regeneration collective (RegenCollective) restores riparian forests and wetlands.
- A municipal utility (CityUtility) downstream requires clean drinking water.
5.1 The Failures of the Two-Primitive Model
If we attempt to represent this scenario using only the standard REA/ValueFlows primitives (Agent and Resource), we are forced to commit three active fictions and leave four critical relationships inexpressible:
1. The Fiction of False Ownership
To record that AgriCoop withdrew water from the river, the river must be represented as an EconomicResource. In any standard ledger, a resource carries a primaryAccountable custodian or owner. Representing the river as owned or controlled by a "Steward organization" codifies dominium in the ledger, violating the core principle of a nondominium property regime.
2. The Fiction of Resource-from-Nowhere
To avoid false ownership, we might omit the river entirely. Abstraction then appears as a raise event: water simply "appears" or "is found" in AgriCoop's private stock. But this means the river is never debited. The depletion of the watershed vanishes from the economic ledger, making sustainability metrics mathematically impossible to compute within the transaction record.
3. The Contradiction of Dual-Typing
When MiningCo discharges heavy metals, the river is the receiver. But as a passive Resource, the river cannot be the "receiver" of an event in standard REA, because the receiver must be an Agent. To make this work, the modeler must type the river as an EcologicalAgent. Now, the exact same entity is represented as a Resource for AgriCoop's extraction, and as an Agent for MiningCo's pollution. This dual-typing breaks the mathematical and logical consistency of the ontology.
4. The Inexpressible Residues
Without a Source primitive, we cannot represent:
- Source Hierarchies: The parent watershed yields the river, which yields water resources.
- Cross-Source Coupling: The forest conditions the river. If ForestryOp cuts trees, the River's flow resilience is directly debited through structural links, not human transactions.
- Reflexive Loops: The event ledger on the river is disconnected from the rules governing access to it.
5.2 The Source-NDO Representation
The Source primitive resolves these distortions. Extraction is recorded honestly with the Source as the provider:
EconomicEvent:
action: extract
provider: River (Source)
receiver: AgriCoop (Agent)
resourceQuantity: 10,000 m³ water
The river's stock is debited as a Source, without assigning ownership. Pollution is recorded with the Source as the receiver:
EconomicEvent:
action: produce/discharge
provider: MiningCo (Agent)
receiver: River (Source)
resourceQuantity: 50 kg heavy metals
RegenCollective's work is recorded as a direct improvement of the Source's state:
EconomicEvent:
action: raise
provider: RegenCollective (Agent)
target: Forest (Source)
resourceQuantity: 1,000 trees
5.3 Occam's Razor: Fewer Primitives vs. Fewer Fictions
Ontology design is guided by Occam's razor: minimize unnecessary concepts. However, Occam's razor is often misapplied to mean simply counting the total number of words in an ontology's glossary.
The true test of parsimony is whether the ontology minimizes the overall complexity of the represented system. Refusing to add the Source primitive keeps the ontology's glossary small, but it multiplies ad-hoc fictions and workarounds in our software code (smuggling non-ownership rules into agents, overloading resource fields, and creating custom translation layers).
Adding one primitive (Source) eliminates three fictions and four residues. By committing to a third category that aligns with Ostrom's resource-systems, the data model becomes structurally cleaner, more type-safe, and infinitely easier to maintain across different software implementations.
6. From Visibility To Stewardship
A ledger that merely records degradation is a passive archive. The Source-NDO connects the transaction ledger directly to programmatically enforced governance:
boundary events ➔ ledger ➔ ecological interpretation ➔ governance rules ➔ access affordances ➔ future events
This loop avoids the power vacuum and representation trap that often derail environmental governance.
6.1 The Power-Capture and Laundering Traps
When a river or atmosphere is personified as an "agent" represented by a "guardian" or "stewardship committee," a dangerous conflation occurs. If the committee decides to increase LoggingCo's cutting quota, the decision is recorded as: "The River Agent committed to allow LoggingCo to cut 500 trees."
This creates two systemic pathologies:
- Laundering of Human Choices: Political compromises, backroom negotiations, or commercial influences are laundered through the system as "the will of the river." The actual human actors are insulated from accountability.
- Ambiguity of Audit: It becomes impossible to distinguish between checking the performance of the committee and checking the state of the river.
The Source-NDO resolves this by splitting the Source (object of governance) from the Stewards (actors of governance):
- The Source maintains a passive ledger of events (how much was extracted, how much was discharged, what sensor readings landed).
- The Stewards (e.g., local water parliaments, polycentric water councils) are registered as standard, accountable Agents. Their decisions, rules, and validations are recorded as their own on-chain commitments. They can be audited, held liable, and voted out by the community if their rules fail to protect the Source's condition.
The river does not make promises; humans make promises about the river. By keeping the Source as a passive data-and-rule anchor, we ensure that checks, balances, and political negotiations remain fully visible and attributable to the humans who make them.
6.2 Polycentric Water Parliaments: A Pragmatic Context
This design is grounded in real-world environmental struggles. In countries like France, water governance has historically been managed through polycentric, local water councils or "water parliaments" (Comités de bassin and local commissions). These local and regional bodies are where the actual distributed power over water resources resides, allowing water users, local citizens, and environmental associations to coordinate.
However, this distributed power is frequently threatened by national governments or centralized utility platforms that seek to consolidate control over water systems, flattening local ecological realities into standardized administrative quotas.
The Source-NDO serves as an informational shield for these local parliaments. By registering a water basin or aquifer as an uncapturable, localized Source-NDO on a distributed ledger, the local community anchors the event ledger and access rules to the physical territory. It enables a polycentric governance model:
- Local sensor data and qualitative citizen-science observations are recorded directly to the Source's decentralized ledger.
- Local water councils adapt extraction rules dynamically based on these local signals.
- Central authorities or large commercial actors cannot unilaterally override or delete these rules because the ledger and its governance-operator are cryptographically distributed across the local nodes (nondominium).
7. Ecological Value Without Reducing Nature To Price
Because a Source is a persistent, non-ownable system, its value cannot be represented by a single market price or asset valuation. Doing so falls back into the commodification trap that the nondominium property regime is designed to resist. The IPBES Values Assessment emphasizes that nature carries a diverse vector of instrumental, intrinsic, and relational values that cannot be collapsed without immense loss of informational resolution (IPBES, 2022).
Furthermore, a Source possesses what ecological economists call existential or systemic value: if the source collapse (e.g., the Dust Bowl or the severe drying of major river systems like the Danube), all dependent economic activities vanish. The value of the Source is therefore not the sum of its extracted resources; it is the prerequisite for any resource flow to exist at all.
We propose representing ecological value as a multi-dimensional value vector attached to the Source's specification, including:
- Sustenance: The capacity to yield material resources (water, wood, fish, crops) and absorb organic effects.
- Regeneration: The capacity to recover condition, rebuild biomass, purify water, and sequester carbon.
- Resilience: The capacity to buffer shocks, resist degradation, and avoid catastrophic regime collapse.
- Adaptive Capacity: The structural and biological diversity that allows the system to organize into new viable states under disturbance.
- Generative Capacity: The systemic wealth that produces future ecological relations and economic affordances.
- Commons Value: The density and diversity of human and non-human agents whose survival and coordination depend on the Source as shared infrastructure.
- Learning Value: The volume of observations, localized knowledge, and governance iterations accumulated on the Source's ledger.
By maintaining this vector as an explicit, multi-dimensional signal, communities can evaluate their success not by "how much resource value was extracted," but by "how much generative capacity was maintained or enhanced."
8. Implementation: Source-NDO
The full usefulness of the Source primitive appears only when it is implemented inside an information infrastructure able to make a source persistent, uncapturable, governed, and accountable without making it owned. This is why Nondominium matters. Built on the agent-centric Holochain framework and using the ValueFlows vocabulary, Nondominium provides a standalone hApp where resources and sources can carry their own governance.
In the Nondominium architecture, this is achieved through five core mechanisms:
1. Permanent Layer 0 Identity
A Source-NDO begins with a Layer 0 NondominiumIdentity entry. This entry is published to a distributed hash table (DHT) and is immutable. Because there are no administrative keys, central servers, or platform databases, no single operator can delete the Source’s identity, and no steward can unilaterally convert it into private property. Its stable action_hash remains an uncapturable anchor for all time.
2. The SourceProfile Extension
To protect the immutability of the Layer 0 identity while allowing condition indicators to evolve, the system links the Layer 0 anchor to a mutable, versioned SourceProfile entry:
#![allow(unused)] fn main() { pub struct SourceProfile { pub ndo_identity_hash: ActionHash, // Links to Layer 0 Identity pub source_type: SourceType, // Hydrological, Biological, etc. pub regime_state: SourceRegimeState, // Pristine, Stable, Stressed, etc. pub stewarded_by: Vec<AgentPubKey>, // Accountable Stewards (Agents) pub current_stock: Option<f64>, pub flux_rate: Option<f64>, pub assimilation_capacity: Option<f64>, pub resilience: Option<f64>, pub tipping_threshold: Option<f64>, pub complex_interior: bool, // Black-box flag pub last_condition_update: Timestamp, } }
This profile is updated only through governance-validated coordinator functions. Extracting or discharging agents cannot write directly to these condition fields; they are computed and updated by the governance operator when boundary events are validated.
3. Source-to-Source Coupling Links
Ecosystem coupling is represented through SourceCouplingLink entries on the DHT, establishing native structural relationships independent of human transactions:
Watershed --Yields--> RiverForest --Conditions (0.68)--> River
When a Raise event increases the condition of the Forest (e.g., reforestation), the governance operator automatically propagates a derived, weighted improvement (delta * 0.68) to the River's flux_rate and resilience indicators, making forest-river ecological coupling a native, verifiable accounting fact.
4. Governance-as-Operator
Nondominium separates the resource/data zome from the governance zome. Proposed state transitions on a Source (e.g., an AgriCoop water withdrawal request) are submitted as a GovernanceTransitionRequest. The governance zome evaluates the applicable GovernanceRule entries, verifies if the requesting agent's cumulative use matches current access affordances, and checks if the withdrawal would push current_stock below tipping_threshold. Only if the transition passes validation does the operator authorize the state update and record the EconomicEvent.
5. Private Participation Receipts (PPR)
All interactions generate bi-directional, cryptographically signed Private Participation Receipts stored as private entries on the agents' personal source chains. In ecological governance, this is a powerful shield. Sensitive data—such as exact locations of endangered species, indigenous sacred sites, or private land-use details—can remain fully private. At the same time, the agent can use zero-knowledge proofs to verify their compliance with stewardship obligations (e.g., proving "I completed five validated riparian restoration commitments" or "I submitted monthly water-quality monitoring data") without exposing the raw data, locations, or counterparties.
9. Limits And Risks
No technical primitive is a complete solution for wicked ecological crises. The Source-NDO carries distinct operational risks that must be managed:
9.1 The Problem of Measurement Quality
An adaptive governance loop is only as good as its inputs. If sensors are faulty, tampered with, or missing, the rule-operator will execute on corrupted signals.
In Nondominium, this is mitigated by peer-to-peer validation. Data enters the ledger not as an absolute truth, but as an EconomicEvent or ValidationReceipt authored and signed by a specific agent. These events are auditable. If an actor submits fraudulent data, any peer (a local NGO, a neighbor, or a downstream utility) can raise a red flag. Because the history is transparent and immutable, fraudulent reporting severely impacts the actor's PPR-based reputation score, directly restricting their future access affordances.
9.2 The Challenge of Governance Legitimacy
Who decides which ecological models are used to set thresholds? Who has the authority to revise the rules?
We align with the principles of cosmolocalism (Berkes, 2012): while the technical protocol and ecological knowledge can be shared globally, the actual decision-making authority must rest with the local stewards and water parliaments who inhabit the territory. The credentialing and roles (who is recognized as a qualified validator or steward) are managed at the local group DNA layer, preventing remote central governments or platforms from capturing the local rule-making process.
9.3 Greenwashing and Compliance Capture
There is a risk that highly sophisticated multinational corporations adopt Source-NDO tracking simply to legitimize extraction: "We recorded our pollution perfectly on-chain, therefore we are a sustainable business."
This is prevented because in Nondominium, the ledger is not merely a reporting tool. The governance-as-operator pattern means the access rules are hard-wired into the DHT: if MiningCo's cumulative discharges hit the Source's assimilation_capacity threshold, the software operator programmatically blocks their subsequent extraction requests. The ledger is an active gatekeeper, not a passive disclosure sheet.
10. Conclusion
Economic information systems have long struggled to represent nature without distorting it. When nature is squeezed into our existing categories, it is either reduced to an owned, commodified resource, or personified as a fictitious agent whose legal or political representation invites capture and laundering.
The Source primitive offers another path. A Source is a generative, non-ownable, partially unknowable system. Implemented as a Source-NDO on Nondominium, it allows a river, forest, wetland, fishery, or watershed to become a ledger-bearing, rule-enforcing governance object without becoming property and without pretending to be a person.
The paradigm shift is simple but deep. The economy is not merely a closed, circular flow of exchange between human agents. It is structurally embedded in a wider network of generative ecological sources. By bringing these sources onto the ledger as first-class, uncapturable entities, we can move our economic coordination from a logic of extraction to a cybernetic loop of adaptive stewardship.
The defining economic question is no longer: "how much value was extracted?" It is: "how much generative capacity was maintained, enhanced, or degraded?"
References
- Ashby, W. R. (1956). An Introduction to Cybernetics. Chapman & Hall.
- ARIES for SEEA. (n.d.). ARIES for SEEA Explorer. Integrated Modelling Partnership / United Nations.
- Berkes, F. (2012). Sacred Ecology (3rd ed.). Routledge.
- Bowker, G. C., & Star, S. L. (1999). Sorting Things Out: Classification and Its Consequences. MIT Press.
- Coase, R. H. (1960). The problem of social cost. Journal of Law and Economics, 3, 1-44.
- Costanza, R. (2000). Social goals and the valuation of ecosystem services. Ecosystems, 3, 4-10.
- Costanza, R., d'Arge, R., de Groot, R., et al. (1997). The value of the world's ecosystem services and natural capital. Nature, 387, 253-260.
- Costanza, R., et al. (2020). Valuing natural capital and ecosystem services toward the goals of efficiency, fairness, and sustainability. Ecosystem Services, 43, 101096.
- Daily, G. C. (Ed.). (1997). Nature's Services: Societal Dependence on Natural Ecosystems. Island Press.
- Daly, H. E. (1977/1991). Steady-State Economics. W. H. Freeman / Island Press.
- Folke, C., Hahn, T., Olsson, P., & Norberg, J. (2005). Adaptive governance of social-ecological systems. Annual Review of Environment and Resources, 30, 441-473.
- Georgescu-Roegen, N. (1971). The Entropy Law and the Economic Process. Harvard University Press.
- Gunderson, L. H., & Holling, C. S. (Eds.). (2002). Panarchy: Understanding Transformations in Human and Natural Systems. Island Press.
- Holling, C. S. (1973). Resilience and stability of ecological systems. Annual Review of Ecology and Systematics, 4, 1-23.
- IPBES. (2022). Methodological Assessment Report on the Diverse Values and Valuation of Nature. IPBES Secretariat.
- McCarthy, W. E. (1982). The REA accounting model: A generalized framework for accounting systems in a shared data environment. The Accounting Review, 57(3), 554-578.
- Ostrom, E. (1990). Governing the Commons. Cambridge University Press.
- Ostrom, E. (2009). A general framework for analyzing sustainability of social-ecological systems. Science, 325(5939), 419-422.
- Pigou, A. C. (1920/1932). The Economics of Welfare. Macmillan.
- Scott, J. C. (1998). Seeing Like a State. Yale University Press.
- Snowden, D. J., & Boone, M. E. (2007). A leader's framework for decision making. Harvard Business Review, 85(11), 68-76.
- Te Awa Tupua (Whanganui River Claims Settlement) Act 2017 (NZ).
- TEEB. (2010). The Economics of Ecosystems and Biodiversity: Mainstreaming the Economics of Nature.
- United Nations et al. (2021). System of Environmental-Economic Accounting—Ecosystem Accounting (SEEA EA).
- ValueFlows. (n.d.). ValueFlows specification. https://www.valueflo.ws/
Appendix: Human-AI Collaboration Summary
This paper was produced through a human-AI collaboration in which the human author (Tiberius Brastaviceanu) retained the primary role in goal definition, conceptual direction, normative judgment, and final authorship authority. This division follows the collaboration framework developed at Sensorica, where AI is treated as strongest in search, aggregation, summarization, pattern expansion, drafting, and procedural workflow support, while human contribution remains central in value framing, meaning-making, contextual reframing, ethical boundary setting, responsibility, creative direction, and final approval.
The collaboration unfolded in three broad phases: brainstorming, structuring and planning the paper, and text improvement/refinement.
In the brainstorming phase, the human author introduced the idea of Source as a new primitive alongside Resource and Agent, and framed Source as a complex system. The human author also made the first observation that treating a river either as a resource or as an agent creates a category error. The intuition and initial argument against nature-as-agent also came from the human author, including the comparison between personifying nature and treating corporations as persons. AI later helped substantiate and expand this argument.
This brainstorming phase drew on the humans' experience with the OVN model and with development of the Nondominium hApp. The human author identified the governance layer of Nondominium as the place where ecological complexity could enter the system: not by claiming complete knowledge of an ecosystem's interior, but through policy that adapts from peripheral data, source-condition signals, and information acquired through economic events. The human author also explicitly introduced the black-box idea for complex ecological systems; AI later helped find relevant references from cybernetics, complexity science, resilience theory, and adaptive governance to support that intuition. The discussion of value depended on Sensorica's definition of value in the OVN wiki, which reflects the network's collective intelligence: value is relational and emerges through agents' experiences, needs, goals, and capacities, rather than residing as a property inside objects.
AI contributed pattern recognition, conceptual expansion, and first-pass theoretical scaffolding. It helped articulate the ecological value vector used in the paper: Sustenance, Regeneration, Resilience, Adaptive Capacity, Generative Capacity, Commons Value, and Learning Value. It also helped polish the critique of nature-as-agent: ecological systems generate effects but do not deliberate, intend, commit, feel harm, or bear moral responsibility. That exchange supplied important conceptual raw material, but the originating questions, domain constraints, value commitments, and direction of inquiry came from the human author and the prior human brainstorming.
In the structuring and planning phase of this paper, the human author provided a first layout with 3 interlocking structures: thematic, pragmatic and logical. He also explained the intended audience, specified that the paper should help environmental practitioners, economists, policy actors, activists, and related readers understand a paradigm shift, and asked for the planning and brainstorming material to remain intact. The human author chose the paper's practical goal: making externalities visible inside economic information systems so economic agents can steward natural sources and resources. The human author also set editorial constraints: keep the paper concise, preserve conceptual depth, use references and quotations for important claims, and keep the planning file available for later revision.
The AI contribution in this phase was to read and reorganize the planning material, strengthen the paper structure, improve the literature and prior-knowledge sections, validate and insert source anchors, and draft the paper. The AI synthesized the human-provided concepts into a more coherent essay structure: externalities as information failure; limits of existing categories; Agent, Resource, and Source; complexity and the black-box principle; a worked river case; the visibility-to-stewardship governance loop; ecological value without reduction to price; implementation as Source-NDO; and limits and risks. The AI also added references and performed coherence and diagnostic checks.
In the text improvement and refinement phase, the human author evaluated the draft and identified a weak point in the implementation section. The human author clarified that the full power of the Source primitive only becomes visible in the context of the Nondominium hApp, and supplied the architectural concepts that needed to be made explicit: organization-agnostic NDOs on the DHT, uncapturable commons and nondominium property regimes, NDO-embedded governance, governance-as-operator, the evolution of governance as a separate module, and Private Participation Receipts as a flexible privacy/accountability mechanism. The human author also connected these concepts back to the black-box ecological model: stewards use peripheral data and economic-event information to steer a complex source toward sustainable states without pretending to fully know its interior.
In the second revision of this paper (resulting in Version 2), the collaboration was expanded to address and resolve a comprehensive body of peer critiques from domain specialists in ValueFlows, agent-based computational economics, stock-flow consistent modeling, and commons governance. The human author directed the AI to address core objections regarding the "thin vs. thick" definition of agency, the limits of representing natural systems as processes, the risk of power-capture and accountability laundering under proxy-based legal representation (such as "river guardians"), and the exact data relationships that make the Source primitive distinct and executable inside the Nondominium/ValueFlows ledger. The AI analyzed the peer comment threads, extracted the underlying ontological and socio-political tensions, and re-drafted the paper to preemptively answer these objections. The resulting text reframes the Source-NDO not as a metaphysical claim about nature, but as a pragmatic, trans-domain informational standard that keeps human stewards explicitly accountable for their choices while preserving the uncapturable, persistent identity of the natural commons.
Source-NDO Requirements (Post-MVP)
Status: Post-MVP Requirements
Created: 2026-07-01
Relates to: [ndo_prima_materia.md](../ndo_prima_materia.md), [resources.md](../resources.md), [governance.md](../governance.md), [requirements.md](../requirements.md)
Grounding: [source-ndo-paper.md](source-ndo-paper.md) (full theoretical justification, river case study, Occam's razor proof, complexity economics analysis)
Other docs: [Source-NDO-brainstorming.md](Source-NDO-brainstorming.md), [source-valueflows-integration.mdd](source-valueflows-integration.md)
Sibling NDO types: [project-type-ndo-specifications.md](project-type-ndo-specifications.md)
1. Problem Statement and Ontological Position
1.1 The missing primitive
The REA/ValueFlows economic ontology operates with two primitives: Agent (entities that can act, commit, deliberate, and bear responsibility) and Resource (appropriable, inventoriable outputs used in economic processes). A river, watershed, forest, or fishery fits neither category honestly.
If modelled as an EconomicResource, the system requires a primaryAccountable owner — the exact inverse of the Nondominium property regime. If modelled as an Agent, it is attributed intention it does not possess; and if avoided entirely, abstraction events appear as raise (resource-from-nowhere) while depletion disappears from the ledger entirely.
The academic paper (source-ndo-paper.md) demonstrates this with Occam's razor: without the Source primitive, a faithful representation of a watershed under Nondominium governance requires three active fictions (false ownership, phantom raise, resource/agent dual-typing for pollution receivers) and four inexpressible relations (source hierarchy, cross-source coupling, black-box epistemics, governance reflexivity). Adding one primitive removes all seven.
Source is therefore a third ontological primitive: neither resource nor person, neither property nor agent, but a generative, non-ownable, partially unknowable system that yields resources, receives ecological effects, conditions future possibilities, and accumulates the historical evidence required for its own stewardship.
1.2 Ostrom mapping
The Source/Resource distinction has a direct lineage in Elinor Ostrom's Social-Ecological Systems framework:
| Ostrom / SES concept | Source-NDO equivalent |
|---|---|
| Resource system (e.g. fishery, watershed) | Source |
| Resource unit (e.g. fish, gallons of water) | Resource (EconomicResource) |
| Governance system | Object-attached GovernanceRule entries (governance-as-operator) |
| Users / actors | Agents |
| Action situation | Economic events, commitments, claims |
The Source-NDO operationalises Ostrom's analytical categories as machine-readable accounting and governance objects — the resource system can receive and originate economic events and carry adaptive governance rules, not merely be described analytically.
1.3 Scope
A Source-NDO is a Nondominium Object whose Layer 0 NondominiumIdentity represents a generative ecological system (watershed, river, forest, fishery, wetland, atmosphere, soil system) or a generative knowledge commons (open-source design repository, scientific knowledge base, language corpus — sources that produce non-rival resources). See §2.3 for the full type taxonomy.
Source-NDO is a post-MVP extension. It does not require breaking changes to existing entry types; it adds new typed Layer 0 attributes, a new vf:Source role for ValueFlows events, and an adaptive governance pattern built on the existing governance-as-operator architecture.
2. Conceptual Model
2.1 Three ontological categories
AGENT — acts, intends, commits, bears responsibility
— individuals, organisations, networks, bots
RESOURCE — appropriable, inventoriable output
— water in a tank, fish landed, timber cut, a tool in custody
SOURCE — generative system that yields Resources, receives effects,
— conditions future possibilities, regenerates or degrades
— not owned, not an agent, not merely a stock behind a flow
A Source yields Resources (a river yields cubic metres of water when abstracted). A Source receives ecological effects (a river receives heavy-metal discharge). A Source conditions other Sources (a forest conditions river infiltration and flow stability). These are distinct event types, all of which become first-class economic events once the Source primitive is available as a flow endpoint.
2.2 Source as NDO
In the Nondominium architecture, a Source-NDO is a NondominiumIdentity entry with:
property_regime: Nondominium(orCommonPoolfor rivalrous consumable ecological stocks)resource_nature: PhysicalorInformation(see §2.3)- A set of Source-specific Layer 0 extension attributes (§4.1)
- No
primaryAccountable— stewardship relations usestewardedBylinks to Agent(s) with a stewardship role, never ownership - Governance-as-adaptive-operator (§5): the governance loop is cybernetic rather than rule-evaluation only
The Layer 0 identity hash becomes the stable anchor for the source's entire economic history — all events that extract from it, discharge into it, or restore it are linked against this hash.
2.3 Source type taxonomy
| Source type | Examples | ResourceNature equivalent | Notes |
|---|---|---|---|
| Ecological — hydrological | Watershed, river, groundwater, wetland | Physical | Rivalrous; extraction and pollution compete |
| Ecological — biological | Forest, fishery, soil system, biodiversity | Physical | Some rivalrous (fishery); some regenerative |
| Ecological — atmospheric | Atmosphere, climate system | Physical | Assimilation capacity rivalrous |
| Knowledge commons | Open-source design repository, scientific commons, language corpus | Information | Non-rivalrous; yields knowledge resources |
| Social commons | Community, network, trust fabric | Information | Non-rivalrous; yields social capital and governance capacity |
The existing ResourceNature enum covers Source types adequately for Layer 0 classification; a separate SourceType sub-classification is recommended for Layer 1 (§4.2).
2.4 Source hierarchy and coupling
Sources can be organised hierarchically and can condition each other. These are first-class relations in the Source-NDO model:
Source → yields → Source (generative parenthood: watershed yields river)
Source → conditions → Source (coupling: forest conditions river flow and resilience)
Source → yields → Resource (production: river yields gallons of water when abstracted)
Example:
WATERSHED (complex system — black box)
├── RIVER (sub-source) ─── yields ──► water m³ (EconomicResource)
├── FOREST (sub-source) ─── yields ──► timber (EconomicResource)
│ └── conditions RIVER (improved infiltration ↑ river resilience)
├── FAUNA (sub-source) ─── yields ──► fish (EconomicResource)
└── FLORA (sub-source) ─── yields ──► herbs (EconomicResource)
The watershed is treated as a black box: its full interior is not modelled. Governance operates on observable boundary events, not on a complete internal description. This is the black-box principle (Ashby, 1956; Snowden & Boone, 2007): in complex domains, govern observable periphery and adapt; do not claim to model the interior.
3. ValueFlows Extension: vf:Source
3.1 The extension
Source-NDO proposes adding vf:Source as a typed role for flow endpoints in ValueFlows economic events, alongside Agent and EconomicResource. The single new affordance: flows may originate from and terminate in Sources, not only in Agents or Resources.
3.2 Event types using Sources as flow endpoints
Extraction (Source as provider):
EconomicEvent {
action: extract,
provider: River(Source),
receiver: AgriCoop(Agent),
quantity: 10000 m³ water
}
→ decrements River.currentStock; depletion is visible
Non-consumptive use (Source as provider of flux, not stock):
EconomicEvent {
action: use,
provider: River(Source),
receiver: HydroDam(Agent),
effect: River.regimeState (altered timing/sediment, not volume)
}
Pollution / loading (Source as receiver):
EconomicEvent {
action: produce,
provider: MiningCo(Agent),
receiver: River(Source),
quantity: 50 kg heavy metals
}
→ debits River.assimilationCapacity; pollution is visible
Regeneration (Agent raises a Source):
EconomicEvent {
action: raise,
target: Forest(Source),
provider: RegenCollective(Agent),
quantity: 1000 trees
}
→ Forest.conditions(River): improved infiltration raises River.fluxRate and resilience
3.3 What the extension removes
Adding vf:Source eliminates:
| Fiction removed | Description |
|---|---|
| False ownership claim | No primaryAccountable needed; no fictional steward-as-owner |
Resource-from-nowhere raise | Extraction from a Source is debited against it; depletion is visible |
| Resource/Agent dual-typing | Sources can receive pollution events without being attributed agency |
| Inexpressible source hierarchy | Source yields Source is a native edge |
| Inexpressible cross-source coupling | Source conditions Source is a native edge |
| Missing black-box epistemics | complexInterior: true and regimeState encode partial knowability |
| Missing governance reflexivity | Events accumulate on the Source → rules adapt → future events are conditioned |
4. Data Model
4.1 Source-specific Layer 0 attributes (extension to NondominiumIdentity)
These attributes extend the existing NondominiumIdentity for Source-NDOs. They may be implemented as a separate SourceProfile entry linked to Layer 0 (to avoid breaking changes) or as additional optional fields on NondominiumIdentity guarded by resource_nature.
#![allow(unused)] fn main() { pub struct SourceProfile { pub ndo_identity_hash: ActionHash, // links to NondominiumIdentity // Ecological condition state (updated by governance events) pub current_stock: Option<f64>, // current extractable quantity pub flux_rate: Option<f64>, // natural replenishment rate per period pub assimilation_capacity: Option<f64>, // pollution absorption capacity remaining pub regime_state: SourceRegimeState, // ecological regime classification pub resilience: Option<f64>, // 0.0–1.0 resilience index pub tipping_threshold: Option<f64>, // stock/flux ratio below which regime shift is likely // Complexity economics dimensions pub adaptive_capacity: Option<f64>, // ability to discover new viable configurations pub generative_capacity: Option<f64>, // capacity to produce future resources and opportunities pub dependency_index: Option<f64>, // proportion of network agents dependent on this source // Coupling relations (links, not inline fields) pub source_type: SourceType, // Hydrological | Biological | Atmospheric | Knowledge | Social pub complex_interior: bool, // always true for ecological sources; governs black-box stance // Stewardship (replaces primaryAccountable) pub stewarded_by: Vec<AgentPubKey>, // agents with stewardship obligations (not ownership) pub created_at: Timestamp, pub last_condition_update: Timestamp, } pub enum SourceRegimeState { Pristine, // minimal anthropogenic impact; high resilience Stable, // functioning within normal variability; monitoring adequate Stressed, // measurable degradation; precautionary governance active Degraded, // significant loss of function; restoration required Critical, // near tipping threshold; emergency governance possible Transformed, // post-regime-shift; new stable state (may be lower function) } pub enum SourceType { Hydrological, // watershed, river, groundwater, wetland Biological, // forest, fishery, soil system, biodiversity Atmospheric, // atmosphere, climate system KnowledgeCommons, // open-source repository, scientific commons SocialCommons, // community, trust fabric } }
4.2 Ecological value vector (Layer 1 — informative)
The ecological value of a Source is multidimensional and cannot be collapsed into one metric (aligned with IPBES Values Assessment and OVN value theory). At Layer 1, the SourceSpecification should support expressing:
| Dimension | Description | Example metrics |
|---|---|---|
| Sustenance | Ongoing provision of economic resources | Water availability, biomass, fish population, pollination rates |
| Regeneration | Capacity to restore itself and other sources | Soil formation rate, carbon sequestration, water quality recovery |
| Resilience | Stabilisation of the broader socio-ecological system | Biodiversity index, redundancy, shock response |
| Adaptive capacity | Ability to evolve into new viable configurations | Genetic diversity, habitat diversity, innovation potential |
| Generative capacity | Capacity to produce future resources and opportunities not yet known | Ecosystem complexity, connectivity, carrying capacity |
| Commons value | Significance as shared infrastructure across the agent network | Number and diversity of dependent agents, dependency ratio |
| Learning value | Knowledge generated through observation and interaction | Monitoring outputs, governance improvements, model accuracy |
4.3 Source-to-Source links
#![allow(unused)] fn main() { pub enum SourceLinkType { Yields, // Source yields a sub-Source (watershed → river) Conditions, // Source conditions another Source (forest → river flow) ProvidedBy, // inverse of Yields (river is provided by watershed) } pub struct SourceCouplingLink { pub from_source_hash: ActionHash, pub to_source_hash: ActionHash, pub link_type: SourceLinkType, pub coupling_strength: Option<f64>, // 0.0–1.0; estimated from monitoring data pub notes: Option<String>, } }
5. Governance Requirements
5.1 Adaptive governance loop
Source-NDO governance operates as a cybernetic loop rather than a one-time rule evaluation. This extends the governance-as-operator pattern to complex, partially unknowable ecological systems:
Boundary events (extraction, discharge, restoration)
↓
Event ledger (accumulated on Source Layer 0 hash)
↓
Ecological interpretation (by scientists, local stewards, monitoring systems)
↓
Governance rule adaptation (GovernanceRule entries updated or replaced)
↓
Access affordances (who can do what, under what conditions, up to what quantity)
↓
Conditioned future events (agents interact with the Source under new rules)
↓ (loop)
The black-box principle governs this loop: stewards do not need to model the full interior of the watershed. They observe peripheral signals (withdrawals, pollutant loads, sensor readings, fish counts, flood events, seasonal variation, local knowledge). Governance adapts from these signals. As the source ledger grows, stewards can revise thresholds, add monitoring obligations, change access rules, or introduce graduated sanctions.
This is "beyond Ostrom" in the complexity-science sense: Ostrom's design principles assume a complicated resource system whose rules can be designed from adequate knowledge. Sources are complex systems with nonlinear dynamics and potential regime shifts. Rules must adapt continuously as the source ledger grows (Holling, 1973; Gunderson & Holling, 2002; Folke et al., 2005).
5.2 PropertyRegime constraints
Source-NDOs SHALL observe the following property regime constraints:
- MUST be
NondominiumorCommonPool:Private,Commons,Pool,Collective, andPublicregimes are inappropriate for ecological sources — they imply ownership, enclosure, or public-body dominion that the Source primitive is designed to prevent. PropertyRegime::Nondominiumis preferred: governance-embedded uncapturability, noprimaryAccountable.PropertyRegime::CommonPoolmay apply to rivalrous consumable stock sources (e.g., a specific fish stock where the extraction quota is the primary governance mechanism).
5.3 Governance rule requirements (REQ-SOURCE-GOV-*)
REQ-SOURCE-GOV-01: Source-NDO governance MUST support adaptive rule revision: governance rules attached to a Source should be updatable through a defined governance process (not only by the initiator), reflecting changes in ecological interpretation. Rule version history SHALL be maintained.
REQ-SOURCE-GOV-02: Source-NDOs MUST support access affordance rules expressed as quantitative constraints on boundary events: maximum extraction quantity per period, maximum pollutant loading, minimum restoration obligation per extraction event, seasonal restrictions.
REQ-SOURCE-GOV-03: The governance evaluation for Source-NDO events MUST check current SourceRegimeState. Events that would push the source toward or past tipping_threshold MAY be blocked or require multi-validator approval under precautionary governance rules.
REQ-SOURCE-GOV-04: Source-NDOs SHOULD support monitoring obligations as a class of GovernanceRule: agents that extract from or discharge into a Source may be required to submit condition data as a precondition for continued access. Monitoring data updates SourceProfile.regime_state and related indicators.
REQ-SOURCE-GOV-05: SourceRegimeState transitions (e.g. Stable → Stressed, Stressed → Degraded) MUST be governance-validated — they require evidence (monitoring data, scientific assessment, community observation) and multi-validator approval, not unilateral declaration.
REQ-SOURCE-GOV-06: The governance module SHALL record all Source-NDO boundary events as EconomicEvent entries linked to the Source's Layer 0 hash, forming an auditable ledger of all extraction, loading, non-consumptive use, and restoration actions.
5.4 Stewardship model
Source-NDOs use stewardship rather than ownership:
| Concept | Standard NDO | Source-NDO |
|---|---|---|
| Custodian | EconomicResource.custodian: AgentPubKey | Not applicable (Sources are not held in custody) |
| Primary responsible | primaryAccountable: AgentPubKey | stewardedBy: Vec<AgentPubKey> — obligations, not rights |
| Role type | PrimaryAccountableAgent | Steward — a new functional role for Source governance |
| Transfer | Custody transfer event | Stewardship succession event (governance-validated) |
The Steward role carries obligations (monitoring, maintaining condition indicators, processing access requests, implementing governance decisions) without conferring alienation rights. No steward can privatise a Source-NDO.
5.5 Data sovereignty and knowledge integration
REQ-SOURCE-GOV-07: Source-NDOs MUST support attaching qualitative and community-validated condition signals to the event ledger, not only quantitative sensor data. Narrative observations, indigenous knowledge assessments, and community-validated condition reports are legitimate inputs to governance interpretation.
REQ-SOURCE-GOV-08: Sensitive ecological data (endangered species locations, sacred sites, private land-use details) attached to Source-NDO records SHALL be stored as Holochain private entries with capability-grant access control, following the PrivatePersonData model in zome_person. The PPR system's privacy model applies to stewardship participation data.
6. Lifecycle and Layer Activation
6.1 LifecycleStage for Source-NDOs
Source-NDOs use the same LifecycleStage enum as other NDOs, but the semantic mapping differs:
| LifecycleStage | Source-NDO meaning |
|---|---|
Ideation | Source identified and named; Layer 0 only; minimal condition data |
Specification | Boundary conditions defined; stakeholders identified; monitoring plan drafted |
Development | Active monitoring established; governance rules being developed; stewards named |
Stable | Governance rules active; monitoring operational; event ledger accumulating |
Active | Full governance loop operational; regular rule revision cycle in place |
Hibernating | Governance temporarily paused (e.g. seasonal closure, dispute resolution in progress) |
Deprecated | Source governance superseded by a broader governance structure (e.g. a watershed-level Source-NDO supersedes a river-level one) |
EndOfLife | Irreversible loss (e.g. geological change, complete ecosystem collapse); Layer 0 tombstone preserved as historical record |
6.2 Layer activation
Source-NDOs use the same three-layer model as all NDOs:
- Layer 0:
NondominiumIdentity+SourceProfileextension; permanent anchor - Layer 1:
SourceSpecification— boundary definitions, monitoring framework, stakeholder map, ecological value vector expression; activated when governance framework is being formalised - Layer 2: Economic events, commitments, claims, PPRs; activated when boundary events begin to be recorded
7. PPR Integration
Private Participation Receipts for Source-NDO interactions use the existing 16-category system with the following emphasis:
| PPR category | Source-NDO use |
|---|---|
ValidationActivity | Monitoring data submission, condition assessment, governance interpretation |
RuleCompliance | Compliance with extraction quotas, discharge limits, monitoring obligations |
MaintenanceCommitmentAccepted / MaintenanceFulfillmentCompleted | Restoration commitments (reforestation, riparian restoration, remediation) |
DisputeResolutionParticipation | Disputes about Source condition assessments or access affordances |
ResourceCreation | Registration of a new Source-NDO and initial condition assessment |
GoodnFaithTransfer | Stewardship succession — transfer of steward obligations to a new agent |
Stewardship participation records (monitoring contributions, governance interpretation events, restoration work) SHALL be PPR-eligible, enabling stewards to accumulate governance standing through contribution to Source health.
8. Requirements Summary (REQ-SOURCE-*)
8.1 Ontological requirements
REQ-SOURCE-ONT-01: The system SHALL recognise Source as a distinct ontological category for flow endpoints in economic events, separable from both Agent and EconomicResource (cf. vf:Source ValueFlows extension, §3).
REQ-SOURCE-ONT-02: Source-NDOs SHALL NOT require a primaryAccountable agent. The property regime SHALL be Nondominium or CommonPool. Governance SHALL reject any GovernanceRule that attempts to assign ownership of a Source-NDO.
REQ-SOURCE-ONT-03: The system SHALL support Source-to-Source links of types yields, conditions, and providedBy (§4.3) to represent source hierarchies and ecological coupling.
REQ-SOURCE-ONT-04: Source-NDOs SHALL be represented on the DHT as NondominiumIdentity entries with a linked SourceProfile extension, using the permanent Layer 0 hash as the event ledger anchor.
8.2 Data model requirements
REQ-SOURCE-DATA-01: SourceProfile SHALL record: current_stock, flux_rate, assimilation_capacity, regime_state, resilience, tipping_threshold, adaptive_capacity, generative_capacity, dependency_index, source_type, complex_interior, stewarded_by (§4.1).
REQ-SOURCE-DATA-02: SourceRegimeState SHALL progress through: Pristine → Stable → Stressed → Degraded → Critical → Transformed, with governance-validated transitions in both directions (§5.3, REQ-SOURCE-GOV-05).
REQ-SOURCE-DATA-03: The Layer 1 SourceSpecification SHOULD support the ecological value vector dimensions: Sustenance, Regeneration, Resilience, Adaptive Capacity, Generative Capacity, Commons Value, Learning Value (§4.2).
8.3 Event and governance requirements
See §5.3 (REQ-SOURCE-GOV-01 through REQ-SOURCE-GOV-08) for the full governance requirement set.
REQ-SOURCE-EVENT-01: Boundary events on Source-NDOs (extraction, loading, non-consumptive use, regeneration) SHALL be recorded as EconomicEvent entries with the Source's Layer 0 hash as the resource_inventoried_as target, regardless of whether the Source is provider or receiver.
REQ-SOURCE-EVENT-02: Extraction events from a Source SHALL decrement SourceProfile.current_stock (or its flux_rate-denominated period budget); loading events SHALL decrement assimilation_capacity. These updates SHALL be governance-validated, not directly writable by the extracting/discharging agent.
REQ-SOURCE-EVENT-03: Regeneration events (restoration, remediation) SHALL be able to increment current_stock, flux_rate, assimilation_capacity, or resilience through governance-validated raise-equivalent events, recording the contributing agent and PPR.
9. Implementation Phasing (informative)
| Phase | Deliverable |
|---|---|
| Phase A | SourceProfile entry type; SourceType and SourceRegimeState enums; Layer 0 + SourceProfile link; Source-to-Source coupling links; Steward role type |
| Phase B | vf:Source event role; boundary event recording (extraction, loading, regeneration); event-triggered current_stock and assimilation_capacity updates |
| Phase C | Adaptive governance loop: SourceRegimeState transitions; access affordance rules; monitoring obligation GovernanceRule type; precautionary blocking at tipping_threshold |
| Phase D | Ecological value vector expression in Layer 1 SourceSpecification; PPR integration for stewardship participation; ZKP-compatible proof of monitoring obligation fulfilment |
| Phase E | Cross-DNA source hierarchy links (watershed-level Source-NDO governing river-level Source-NDOs across different communities); federation-level source governance |
10. Relation to Complexity Oriented Programming
Source-NDO is a direct application of COP principles (see complexity-oriented-programming skill):
| COP principle | Source-NDO enactment |
|---|---|
| Dynamic complexity matching | Governance overhead grows from Layer 0 (Ideation, minimal) to full adaptive loop (Active); the system never requires complete ecological specification upfront |
| Stigmergic coordination | Source-NDOs modify the governance environment via their ledger: stewards respond to source condition signals rather than following explicit orders |
| Anti-fragility | The adaptive governance loop treats ecological stress events as information for rule revision, not as failures; the system gets better at governance as the ledger grows |
| Path-dependency awareness | SourceRegimeState history and event ledger preserve the full trajectory; governance rules carry their provenance |
| Fractal composability | Source hierarchies (watershed → river → water) use the same NDO primitives at every scale; governance principles are self-similar |
| Probe-sense-respond | The governance loop is explicitly cybernetic: boundary events probe; condition monitoring senses; governance rule adaptation responds |
11. Traceability
| Source | Normative IDs |
|---|---|
source-ndo-paper.md §8 (Implementation) | REQ-SOURCE-ONT-01 – -04 |
source-ndo-paper.md §4 (Black-box principle) | REQ-SOURCE-GOV-01, -03, -04 |
source-ndo-paper.md §6 (Governance loop) | REQ-SOURCE-GOV-02, -06, REQ-SOURCE-EVENT-01 – -03 |
| Ostrom SES framework | REQ-SOURCE-ONT-01 (resource system = Source) |
ndo_prima_materia.md §4 (three-layer model) | §6 (Layer activation) |
ndo_prima_materia.md governance-as-operator | §5.1 (adaptive governance loop) |
resources.md §4.4.3 (property regimes) | REQ-SOURCE-ONT-02 |
governance.md §2.1 (governance-as-operator) | §5.1 |
This is a normative post-MVP requirements document. Source-NDO does not modify existing REQ-NDO- invariants (Layer 0 permanence, governance-as-operator, PPR privacy model). It extends the economic ontology at the flow-endpoint level and adds Source-specific governance patterns on top of the existing architecture.*
Source–Valueflows Integration Design
Status: Post-MVP design (implementation-informing)
Created: 2026-07-05
Relates to: [source-ndo-requirements.md](source-ndo-requirements.md), [Source-NDO-brainstorming.md](Source-NDO-brainstorming.md), [ndo_prima_materia.md](../ndo_prima_materia.md), [specifications.md](../../specifications/specifications.md)
Normative requirements: REQ-SOURCE-* in [source-ndo-requirements.md](source-ndo-requirements.md)
Purpose
This document integrates the vf:Source primitive into nondominium's Valueflows model. It is structured as two deliberately separated discussions:
| Part | Scope | Audience |
|---|---|---|
| Part I — Valueflows | Implementation-agnostic ontology | Any REA/VF implementer |
| Part II — Nondominium | This Holochain hApp's Rust/TS data model | nondominium developers |
Parts III–IV apply both layers in a worked use case and concrete data model. Part V records open decisions before implementation.
This document does not modify zome code. It informs Phase A–E implementation described in source-ndo-requirements.md §9.
Valueflows
Scope: Pure ontology. No Holochain, no NDO layers, no governance-as-operator. Any Valueflows-compliant system could adopt this extension.
1.1 Valueflows primitive recap
Valueflows is an open vocabulary built on the REA (Resource–Event–Agent) accounting ontology. It models economic activity through three knowledge/plan/observation layers:
| VF layer | Purpose | Core types |
|---|---|---|
| Knowledge | Types and templates | ResourceSpecification, ProcessSpecification (Recipe) |
| Plan | Intent and obligation | Intent, Commitment, Agreement |
| Observation | What happened | EconomicEvent, Claim |
Agents (vf:Person, vf:Organization, vf:EcologicalAgent) are entities that initiate, receive, commit to, and bear responsibility for economic flows.
Resources (vf:EconomicResource) are inventoried instances conforming to a ResourceSpecification. Each resource may carry a primaryAccountable agent — the agent with primary rights and responsibilities (ownership/accounting association).
Events (vf:EconomicEvent) record observed economic activity. Each event has:
action— one of the VF action vocabulary (produce,consume,use,transfer,raise,lower, …)provider— the agent from whom the flow is initiatedreceiver— the agent to whom the flow is directedresourceInventoriedAs/affects— the economic resource affectedresourceQuantity— amount and unit
Processes group inputs and outputs. Commitments promise future events; Claims link fulfilled events back to commitments.
nondominium's MVP implements this pattern in zome_gouvernance (EconomicEvent, Commitment, Claim) and zome_resource (ResourceSpecification, EconomicResource), with 16 VfAction variants including nondominium extensions (InitialTransfer, AccessForUse, TransferCustody).
1.2 The endpoint constraint (why the gap exists)
The Valueflows specification defines typed ranges for flow endpoints. From the official ontology (/valueflows/valueflows, all_vf.html):
vf:provider
rdfs:comment "The economic agent from whom the intended, committed, or actual economic event is initiated."
rdfs:range vf:Agent .
vf:receiver
rdfs:comment "The economic agent to whom the intended, committed, or actual economic event is directed."
rdfs:range vf:Agent .
vf:primaryAccountable
rdfs:comment "The agent currently with primary rights and responsibilites for the economic resource."
rdfs:range vf:Agent .
Consequence: in Valueflows 1.0, every flow endpoint and every resource accountability anchor must be an Agent. Resources are inventoried outputs; they are never providers, receivers, or sinks for ecological loading.
This is correct for appropriable economic outputs (water in a tank, fish landed, timber cut). It is incorrect for generative ecological systems (rivers, watersheds, forests, fisheries, knowledge commons) that:
- yield resources without being owned
- receive pollution and ecological effects without possessing agency
- condition other generative systems (forest → river infiltration)
- accumulate an event ledger that should drive adaptive governance
1.3 The ontological gap
A river under a nondominium property regime fits neither category honestly:
| If modelled as… | Problem |
|---|---|
EconomicResource | Requires primaryAccountable — a false ownership claim, the inverse of nondominium |
Agent / EcologicalAgent | Attributes intention the river does not possess; human representatives speak for it |
| Avoided entirely | Abstraction appears as raise (resource from nowhere); depletion and pollution vanish from the ledger |
Ostrom's Social-Ecological Systems framework already distinguishes resource system (fishery, watershed) from resource unit (fish, gallons of water). Valueflows collapses both into EconomicResource + Agent, losing the resource-system category at the executable layer.
Three active fictions (Model A)
Using Valueflows 1.0 as-is for a watershed commons produces:
- False ownership —
EconomicResource { primaryAccountable: StewardOrg }records dominium in the ledger meant to be authoritative. - Resource from nowhere —
raisecreates water inventory with no provider; the river is never debited; sustainability is unaccountable. - Resource/Agent contradiction — river typed as Resource for extraction and as EcologicalAgent to receive MiningCo's effluent; one entity, two incompatible types.
Four inexpressible residues
- Source hierarchy — watershed → river cannot be expressed as generation (only containment or free text).
- Cross-source coupling — forest conditions river flow; no native edge.
- Black-box epistemics — no construct for "interior opaque; govern boundary only."
- Governance reflexivity — events → policy → access rules cannot close on the ecological object itself.
See Source-NDO-brainstorming.md §3–§5 for the full river/watershed worked comparison and Occam's-razor analysis.
1.4 The vf:Source proposal
vf:Source is a third ontological primitive alongside Agent and EconomicResource:
AGENT — acts, intends, commits, bears responsibility
(individuals, organisations, networks, bots)
RESOURCE — appropriable, inventoriable output
(water in a tank, fish landed, timber cut, a design file in custody)
SOURCE — generative system that yields Resources, receives effects,
conditions future possibilities, regenerates or degrades
(not owned, not an agent, not merely a stock behind a flow)
Single new affordance: flows may originate from and terminate in Sources, not only in Agents or Resources.
At the RDF level this implies extending vf:provider and vf:receiver domains to include vf:Source, and introducing vf:Source as a class distinct from vf:Agent and vf:EconomicResource. Nondominium's implementation details are in Part II.
Ostrom mapping
| Ostrom / SES | vf:Source extension |
|---|---|
| Resource system | Source |
| Resource unit | Resource (EconomicResource) |
| Governance system | Governance rules attached to Source (implementation-specific) |
| Users / actors | Agent |
| Action situation | EconomicEvent, Commitment, Claim |
1.5 Event shapes with Source endpoints
Boundary events on a Source use standard VF actions with Source as provider or receiver:
Extraction (Source as provider)
EconomicEvent {
action: extract, // see §1.6 — VF core vocabulary note
provider: River (Source),
receiver: AgriCoop (Agent),
resourceConformsTo: WaterSpec,
resourceQuantity: 10000 m³
}
→ decrements River.currentStock; depletion is visible
Non-consumptive use (Source as provider of flux)
EconomicEvent {
action: use,
provider: River (Source),
receiver: HydroDam (Agent),
effect: River.regimeState // altered timing/sediment, not stock volume
}
Pollution / loading (Source as receiver)
EconomicEvent {
action: produce,
provider: MiningCo (Agent),
receiver: River (Source),
resourceQuantity: 50 kg heavy metals
}
→ debits River.assimilationCapacity; pollution is visible
Regeneration (Agent raises a Source)
EconomicEvent {
action: raise,
target: Forest (Source),
provider: RegenCollective (Agent),
resourceQuantity: 1000 trees
}
→ Forest.conditions(River): improved infiltration raises River.fluxRate and resilience
Source-to-Source relations (not events — structural links)
Source --yields--> Source (watershed yields river)
Source --conditions--> Source (forest conditions river flow)
Source --yields--> Resource (river yields gallons when abstracted)
1.6 Action vocabulary note: extract
Valueflows core actions include consume, lower, raise, produce, use, transfer, etc., but no dedicated extract action. Source-NDO literature uses extract informally for "withdraw from a generative system without transferring ownership."
| Option | Semantics | Trade-off |
|---|---|---|
Add Extract to extended VF vocabulary | Clearest semantics for Source withdrawal | New action; all VF implementations must recognise it |
Map to Consume | Resource leaves the Source and enters agent inventory | Conflates rivalrous depletion with generic consumption |
Map to Lower | Decrements quantity at Source | Closest to stock debit; less intuitive for "yield to inventory" |
Map to Transfer with Source as provider | Flow from Source to Agent | Requires Source as legal provider (the whole point of the extension) |
Recommendation for nondominium: add Extract as a 17th VfAction variant in crates/shared/src/types.rs, documented as "withdraw quantity from a Source into an inventoried Resource; debits Source condition state." This preserves semantic clarity for governance rules (max extract per season) and PPR categorisation. Until implemented, Lower on the Source plus Raise/Transfer on the derived Resource is an acceptable interim mapping.
1.7 What the extension removes
| Removed | Description |
|---|---|
| False ownership claim | Source has no primaryAccountable; stewardship ≠ dominium |
Resource-from-nowhere raise | Extraction debits the Source; depletion is visible |
| Resource/Agent dual-typing | Source receives pollution without agency |
| Inexpressible source hierarchy | Source yields Source is a native edge |
| Inexpressible cross-source coupling | Source conditions Source is a native edge |
| Missing black-box epistemics | complexInterior: true, regimeState encode partial knowability |
| Missing governance reflexivity | Event ledger on Source → rules adapt → future events conditioned |
Occam's razor verdict
Adding one primitive (vf:Source) removes three fictions and four residues. Refusing to name the Source does not remove it from the world — it forces smuggling via mismatched parts. The augmented ontology is more parsimonious at the level that matters: the furniture of reality the model commits to.
Part II — Nondominium Discussion
Scope: How
vf:Sourcelands on this hApp's Rust zomes, TypeScript shared types, governance-as-operator pattern, and NDO three-layer model.
2.1 Current-state mapping
| Valueflows concept | nondominium implementation | Source gap |
|---|---|---|
Agent | AgentPubKey + Person (zome_person) | OK |
ResourceSpecification | ResourceSpecification (zome_resource) | OK for inventoriable types |
EconomicResource | EconomicResource { custodian: AgentPubKey, … } | custodian = ownership/custody fiction for Sources |
EconomicEvent.provider | AgentPubKey | Cannot be a Source |
EconomicEvent.receiver | AgentPubKey | Cannot receive pollution into a Source |
EconomicEvent.resource_inventoried_as | ActionHash → EconomicResource | REQ-SOURCE-EVENT-01 also targets Source Layer 0 hash |
primaryAccountable | EconomicResource.custodian | Inappropriate for Source-NDO |
Commitment / Claim | zome_gouvernance entries | Need Source-aware evaluation |
GovernanceRule | rule_data: RuleData (4 typed variants, #132) | No Source-aware variant; adaptive rules need a new one |
| Layer 0 identity | NondominiumIdentity | Permanent anchor; Source-NDO uses same entry |
| NDO federation links | NdoHardLink (Component, DerivedFrom, Supersedes) | Cross-NDO; not Source coupling |
VfAction | 16 variants in crates/shared/src/types.rs | No Extract |
| Design-system types | SourceProfile, SourceType, SourceRegimeState in packages/ndo-ui/src/domain/types.ts | UI scaffold only; not in Rust zomes yet |
Current EconomicEvent (ground truth):
#![allow(unused)] fn main() { pub struct EconomicEvent { pub action: VfAction, pub provider: AgentPubKey, pub receiver: AgentPubKey, pub resource_inventoried_as: ActionHash, pub affects: ActionHash, pub resource_quantity: f64, pub event_time: Timestamp, pub note: Option<String>, } }
2.2 Central design decision: Source as flow endpoint
How does a Source participate as provider or receiver in an EconomicEvent?
Option A — FlowEndpoint enum (breaking)
Replace provider/receiver: AgentPubKey with FlowEndpoint { Agent(AgentPubKey), Source(ActionHash) }.
- Pros: Cleanest semantics; one field per role; aligns with vf:Source long-term.
- Cons: Breaking change to every existing event, commitment, test, and UI binding.
Option B — Additive optional fields (recommended)
Keep existing Agent fields; add parallel Source fields:
#![allow(unused)] fn main() { pub struct EconomicEvent { // … existing fields … pub source_provider: Option<ActionHash>, // NondominiumIdentity Layer 0 hash pub source_receiver: Option<ActionHash>, } }
Integrity validation: exactly one of { provider, source_provider } must be set for the initiating side; same for receiver. Agent–Agent events unchanged.
- Pros: Non-breaking; post-MVP additive; Sweettest can cover Source events without migrating history.
- Cons: Two parallel representations; callers must check both fields.
Option C — Overload resource_inventoried_as / affects
Per REQ-SOURCE-EVENT-01, point resource_inventoried_as at the Source's Layer 0 hash; infer provider/receiver role from action direction.
- Pros: Minimal schema change.
- Cons: Overloads a field meant for inventoried resources; ambiguous for events affecting both Source and Resource; weak type safety.
Recommendation: Option B for Phase B implementation; consider Option A as a major-version migration once Source events are stable.
2.3 SourceProfile as Layer 0 extension
REQ-SOURCE-ONT-04 and REQ-NDO-L0 immutability require Source condition state not on NondominiumIdentity itself. Implement as a separate entry linked from Layer 0:
#![allow(unused)] fn main() { pub struct SourceProfile { pub ndo_identity_hash: ActionHash, pub source_type: SourceType, pub regime_state: SourceRegimeState, pub stewarded_by: Vec<AgentPubKey>, pub current_stock: Option<f64>, pub flux_rate: Option<f64>, pub assimilation_capacity: Option<f64>, pub resilience: Option<f64>, pub tipping_threshold: Option<f64>, pub adaptive_capacity: Option<f64>, pub generative_capacity: Option<f64>, pub dependency_index: Option<f64>, pub complex_interior: bool, pub created_at: Timestamp, pub last_condition_update: Timestamp, } }
Link: NondominiumIdentity (action_hash) → SourceProfile via LinkTypes::NdoToSourceProfile.
Archetype flag: UI uses ndo_archetype: "source_ndo" (packages/ndo-ui/src/domain/types.ts); Rust may add an optional marker or infer from linked SourceProfile.
Layer 1: SourceSpecification (boundary definitions, monitoring framework, ecological value vector) — activated when governance is formalised; links via future NDOToSpecification.
Enums align with design-system TS: SourceType, SourceRegimeState, EcologicalValueDimension.
2.4 Source-to-Source coupling links
Distinct from NdoHardLink (cross-DNA federation). Intra-network ecological structure:
#![allow(unused)] fn main() { pub enum SourceLinkType { Yields, Conditions, ProvidedBy } pub struct SourceCouplingLink { pub from_source_hash: ActionHash, // Layer 0 hash pub to_source_hash: ActionHash, pub link_type: SourceLinkType, pub coupling_strength: Option<f64>, pub notes: Option<String>, } }
Anchor: SourceCoupling(from_hash, link_type) → to_hash.
2.5 Stewardship model
Source-NDOs use stewardship, not custody or ownership:
| Concept | Standard NDO / Resource | Source-NDO |
|---|---|---|
| Holder | EconomicResource.custodian | Not applicable |
| Responsible party | PrimaryAccountableAgent | SourceProfile.stewarded_by |
| Role | PrimaryAccountableAgent | Steward (new RoleType variant) |
| Transfer | Custody transfer event | Stewardship succession (governance-validated) |
Steward carries obligations (monitoring, access decisions, rule implementation) without alienation rights. No steward can privatise a Source-NDO. Governance rejects rules asserting ownership (REQ-SOURCE-ONT-02).
Current RoleType (zome_person): SimpleAgent, AccountableAgent, PrimaryAccountableAgent, Transport, Repair, Storage. Phase A adds Steward.
2.6 Adaptive governance loop
Extends governance-as-operator (zome_gouvernance evaluates; zome_resource holds data) into a cybernetic loop for complex Sources:
Boundary events (extract, load, restore, use)
↓
Event ledger (linked to Source Layer 0 hash)
↓
Ecological interpretation (stewards, scientists, community signals)
↓
GovernanceRule adaptation (versioned rule entries on Layer 1)
↓
Access affordances (quantitative constraints in rule_data JSON)
↓
Conditioned future events (governance operator blocks or requires approval)
↓ (loop)
Black-box principle: stewards observe boundary signals (withdrawals, pollutant loads, sensor readings, narrative assessments) — not the full watershed interior. SourceProfile.complex_interior: true encodes this epistemic stance.
State updates (REQ-SOURCE-EVENT-02): current_stock, assimilation_capacity, etc. are updated only through governance-validated transitions triggered by approved events — never by direct write from the extracting agent.
Example affordance rule (GovernanceRule):
{
"rule_type": "source_access_affordance",
"rule_data": {
"source_hash": "<river_layer0>",
"agent_role": "AccountableAgent",
"action": "Extract",
"max_quantity_per_period": 8000,
"period": "season",
"resource_unit": "m3"
}
}
2.7 PropertyRegime constraints
Source-NDOs MUST use PropertyRegime::Nondominium or PropertyRegime::CommonPool (REQ-SOURCE-ONT-02). Integrity validation on create_ndo when SourceProfile is linked should reject Private, Commons, Pool, Collective for Source archetypes.
Governance operator rejects GovernanceRule entries that assert transferable ownership over a Source Layer 0 hash.
2.8 VfAction extension
Add to crates/shared/src/types.rs:
#![allow(unused)] fn main() { Extract, // Withdraw from Source into inventoried Resource; debits Source condition }
Semantic methods (mirroring existing VfAction helpers):
Extract.requires_source_provider()→ trueProducewithsource_receiver→ loading/pollutionRaisewith Source asaffects→ regeneration
2.9 PPR mapping for Source interactions
| Activity | PPR category |
|---|---|
| Source-NDO registration + initial assessment | ResourceCreation |
| Monitoring data submission | ValidationActivity |
| Compliance with extract/discharge limits | RuleCompliance |
| Restoration commitment / fulfillment | MaintenanceCommitmentAccepted / MaintenanceFulfillmentCompleted |
| Dispute over condition or access | DisputeResolutionParticipation |
| Stewardship succession | GoodFaithTransfer |
| Regime state transition validation | ValidationActivity |
Stewardship participation accumulates governance standing via existing PPR → ReputationSummary path; no new PPR categories required for MVP.
Part III — Worked Use Case
Each scenario appears twice: abstract VF (Part I style) then nondominium instance data (Part II structures).
3.1 River / watershed (primary)
The case
A watershed feeds a river. Eight agents interact with conflicting interests:
| Agent | Interaction | Externality |
|---|---|---|
| AgriCoop | Irrigation — consumes water | Nutrient runoff (N, P) downstream |
| CityUtility | Public water supply | Needs clean water; harmed by upstream pollution |
| MiningCo | Abstraction + effluent | Heavy metals; conflicts with agriculture |
| HydroDam | Non-consumptive flow use | Alters timing; starves downstream agriculture |
| FisherGuild | Fish extraction | Overfishing degrades biological regime |
| RiverTours | Recreation / transport | Low impact; harmed by pollution and low flow |
| ForestryOp | Watershed logging | Reduces infiltration → flow and quality |
| RegenCollective | Reforestation, riparian work | Raises generative capacity of coupled Sources |
Governance goal: align agents toward sustainable use — Ostrom commons stewardship extended into the complex domain (probe–sense–respond, not design-once rules).
Source hierarchy
WATERSHED (complex system — black box)
├── RIVER (sub-source) ── yields ──► water m³ (EconomicResource)
├── FOREST (sub-source) ── yields ──► timber (EconomicResource)
│ └── conditions RIVER
├── FAUNA (sub-source) ── yields ──► fish
└── FLORA (sub-source) ── yields ──► herbs
Model A breaks (VF 1.0 as-is)
Fiction 1 — false ownership
EconomicResource River { primaryAccountable: StewardOrg }
EconomicEvent { action: transfer, provider: StewardOrg, receiver: AgriCoop, quantity: 10000 m³ }
Records dominium in the authoritative ledger; violates nondominium property regime.
Fiction 2 — depletion invisible
EconomicEvent { action: raise, resourceInventoriedAs: Water#agri, quantity: 10000 m³ }
// provider: none — river never debited
Fiction 3 — pollution dual-typing
EconomicEvent { action: produce, provider: MiningCo, receiver: ??? }
// River-as-Resource cannot receive → forced EcologicalAgent typing
Residues: no Watershed yields River edge; no Forest conditions River; no complexInterior; no closed governance loop on the river object.
Model B — vf:Source (abstract VF)
// Abstraction — depletion visible
EconomicEvent { action: extract, provider: River(Source), receiver: AgriCoop, quantity: 10000 m³ }
// Pollution — loading visible
EconomicEvent { action: produce, provider: MiningCo, receiver: River(Source), quantity: 50 kg }
// Regeneration — cross-source coupling
EconomicEvent { action: raise, provider: RegenCollective, target: Forest(Source), quantity: 1000 trees }
→ Forest.conditions(River): fluxRate ↑, resilience ↑
nondominium instance data
Three Source-NDOs registered in a Group via create_ndo + linked SourceProfile:
| NDO | property_regime | source_type | Key SourceProfile fields |
|---|---|---|---|
| Watershed | Nondominium | (parent) | complex_interior: true, regime_state: Stable |
| River | Nondominium | Hydrological | current_stock: 5_000_000 m³, flux_rate: 120_000 m³/month, assimilation_capacity: 500 kg, stewarded_by: [WatershedCouncil, RiverKeepers] |
| Forest | Nondominium | Biological | current_stock: 0.85 (canopy index), resilience: 0.72, stewarded_by: [ForestryBoard] |
Coupling links (SourceCouplingLink):
| from | link_type | to | coupling_strength |
|---|---|---|---|
| Watershed | Yields | River | — |
| Watershed | Yields | Forest | — |
| Forest | Conditions | River | 0.68 |
Sample events (Option B schema):
| # | action | provider | receiver | source_provider | source_receiver | affects (Layer 0) | qty | Effect |
|---|---|---|---|---|---|---|---|---|
| E1 | Extract | AgriCoop | AgriCoop | — | — | River | 10_000 m³ | current_stock −10_000 |
| E2 | Produce | MiningCo | — | — | River | River | 50 kg | assimilation_capacity −50 |
| E3 | Raise | RegenCollective | RegenCollective | — | — | Forest | 1000 trees | Forest stock ↑; propagates to River via Conditions |
Governance rules (Layer 1, GovernanceRule):
| rule_id | type | summary |
|---|---|---|
| R-2026-03 | source_access_affordance | MiningCo: max 10 kg/month pollutants |
| R-2026-04 | source_access_affordance | AgriCoop: max 8000 m³/season extract |
| R-2026-05 | source_monitoring_obligation | Extractors must submit monthly flow readings |
After E1–E3 accumulate on the River ledger, stewards revise R-2026-04 downward if regime_state transitions toward Stressed (REQ-SOURCE-GOV-05).
3.2 Knowledge commons (parallel)
Shows vf:Source generalises beyond ecology — directly relevant to nondominium's design-file and open-hardware NDOs.
The case
OpenCNC Designs — an open-source CNC machine design repository under PropertyRegime::Nondominium, SourceType::KnowledgeCommons.
| Agent | Interaction |
|---|---|
| DesignerAlice | Contributes CAD files |
| FabLabBerlin | Forks design for local materials |
| PartSupplier | Fabricates parts from published specs |
| MaintainerBob | Curates quality, merges contributions |
VF abstract
Source OpenCNC {
source_type: KnowledgeCommons,
complex_interior: false, // designs are inspectable unlike watershed
stewarded_by: [MaintainerBob, DesignCouncil]
}
// Contribution enriches the Source
EconomicEvent { action: work, provider: DesignerAlice, receiver: OpenCNC(Source) }
// Fork creates derived Source coupled to parent
Source FabLabFork --providedBy--> OpenCNC
Source OpenCNC --yields--> ResourceSpecification "CNC-v3.2"
// Fabrication extracts inventoriable instance from Source
EconomicEvent { action: extract, provider: OpenCNC(Source), receiver: PartSupplier,
resourceConformsTo: CNC-v3.2, quantity: 1 }
Non-rival: extract copies the design without depleting the Source (current_stock unchanged; generative_capacity and dependency_index track usage).
nondominium instance data
| NDO | resource_nature | source_type | Notes |
|---|---|---|---|
| OpenCNC | Information | KnowledgeCommons | flux_rate: N/A, dependency_index: 0.45 |
| FabLabBerlin-Fork | Information | KnowledgeCommons | ProvidedBy → OpenCNC |
| Event | action | Flow | Effect |
|---|---|---|---|
| K1 | Work | DesignerAlice → OpenCNC (source_receiver) | Contribution logged; LearningValue ↑ |
| K2 | Extract | OpenCNC (source_provider) → PartSupplier | New EconomicResource instance; Source undiminished |
| K3 | Cite | FabLabFork → OpenCNC | Attribution edge; Conditions coupling for upstream propagation |
Governance: GovernanceRule requires Cite on fork; RuleCompliance PPR for maintainers enforcing attribution.
Part IV — Data Model
4.1 Three-primitive relationship diagram
graph LR Agent["Agent (Person / Organization)"] Event["EconomicEvent"] Resource["EconomicResource"] Source["Source-NDO (NondominiumIdentity + SourceProfile)"] Agent -->|"provider / receiver (AgentPubKey)"| Event Source -->|"source_provider / source_receiver (Layer0 hash)"| Event Event -->|"affects"| Resource Event -->|"affects"| Source Source -->|"yields"| Resource Source -->|"yields"| Source Source -->|"conditions"| Source Agent -->|"stewarded_by"| Source
4.2 Entity definitions (design-level Rust)
Enums (crates/shared/src/types.rs — proposed additions)
#![allow(unused)] fn main() { pub enum SourceType { Hydrological, Biological, Atmospheric, KnowledgeCommons, SocialCommons, } pub enum SourceRegimeState { Pristine, Stable, Stressed, Degraded, Critical, Transformed, } pub enum SourceLinkType { Yields, Conditions, ProvidedBy, } // VfAction extension // Extract, // add to existing enum }
SourceProfile (zome_resource integrity — proposed)
See §2.3. Linked from NondominiumIdentity action hash. Updated only via governance-validated coordinator functions (apply_source_condition_update).
Extended EconomicEvent (zome_gouvernance integrity — Option B)
#![allow(unused)] fn main() { pub struct EconomicEvent { pub action: VfAction, pub provider: AgentPubKey, pub receiver: AgentPubKey, pub source_provider: Option<ActionHash>, pub source_receiver: Option<ActionHash>, pub resource_inventoried_as: ActionHash, pub affects: ActionHash, pub resource_quantity: f64, pub event_time: Timestamp, pub note: Option<String>, } }
Integrity rules:
(provider set XOR source_provider set)for initiating side when action requires a provider(receiver set XOR source_receiver set)for receiving side when action requires a receiveraffectsMUST reference either anEconomicResourceor a Source Layer 0NondominiumIdentityhash (discriminated by link presence ofSourceProfile)- Agent–Agent events: both Source fields
None(backward compatible)
SourceCouplingLink (zome_resource integrity — proposed)
See §2.4.
TypeScript mirror (packages/ndo-ui/src/domain/types.ts)
Existing types SourceProfile, SourceType, SourceRegimeState, EcologicalValueDimension, NdoArchetypeId::source_ndo remain the UI contract. Backend implementation must serialize compatibly.
4.3 River instance graph
graph TD Watershed["Watershed NDO + SourceProfile"] River["River NDO + SourceProfile"] Forest["Forest NDO + SourceProfile"] WaterRes["EconomicResource: water m3"] AgriCoop["AgriCoop Agent"] MiningCo["MiningCo Agent"] RegenColl["RegenCollective Agent"] Watershed -->|Yields| River Watershed -->|Yields| Forest Forest -->|Conditions 0.68| River River -->|yields on extract| WaterRes AgriCoop -->|E1 Extract| River MiningCo -->|E2 Produce into| River RegenColl -->|E3 Raise| Forest
Concrete instance rows
NDO Layer 0
| hash (example) | name | property_regime | lifecycle_stage |
|---|---|---|---|
ndo:watershed | Alpine Watershed | Nondominium | Active |
ndo:river | Alpine River | Nondominium | Active |
ndo:forest | Alpine Forest | Nondominium | Active |
SourceProfile snapshots (after E1–E3)
| source | current_stock | assimilation_capacity | resilience | regime_state |
|---|---|---|---|---|
| River | 4_990_000 m³ | 450 kg | 0.71 | Stable |
| Forest | 0.87 canopy | — | 0.74 | Stable |
Events
E1: { action: Extract, provider: AgriCoop, source_provider: ndo:river,
affects: ndo:river, quantity: 10000, unit: m3, event_hash: evt:e1 }
E2: { action: Produce, provider: MiningCo, source_receiver: ndo:river,
affects: ndo:river, quantity: 50, unit: kg, note: "heavy metals", event_hash: evt:e2 }
E3: { action: Raise, provider: RegenCollective, affects: ndo:forest,
quantity: 1000, unit: trees, event_hash: evt:e3 }
GovernanceRule rows
R-2026-04: { max_extract_m3_per_season: 8000, source: ndo:river, enforced_by: "Steward" }
R-2026-03: { max_load_kg_per_month: 10, source: ndo:river, pollutant: "heavy_metals" }
4.4 Knowledge-commons instance rows
| hash | name | source_type | property_regime |
|---|---|---|---|
ndo:opencnc | OpenCNC Designs | KnowledgeCommons | Nondominium |
ndo:fablab-fork | FabLab Berlin Fork | KnowledgeCommons | Nondominium |
| link | type |
|---|---|
ndo:fablab-fork → ndo:opencnc | ProvidedBy |
| Event | Effect on SourceProfile |
|---|---|
| K1 Work into OpenCNC | ecological_values.LearningValue ↑ |
| K2 Extract spec to fabricator | dependency_index ↑; stock unchanged |
| K3 Cite on fork | attribution recorded; coupling maintained |
4.5 Data-relationship walkthrough
Extract debits stock (E1)
- AgriCoop submits
Extractwithsource_provider = ndo:river. - Governance operator evaluates R-2026-04: 10_000 > 8_000 seasonal cap → reject OR multi-validator override if emergency.
- If approved: create
EconomicEvent; linkNdoToTransitionEvent/ Source event anchor onndo:river. - Coordinator calls
apply_source_condition_update:current_stock -= 10000. - Check
tipping_threshold: ifcurrent_stock / flux_rateratio critical → block further extracts (REQ-SOURCE-GOV-03). - Issue PPRs: AgriCoop
RuleComplianceor violation record; stewardsValidationActivityif monitoring submitted.
Raise propagates via Conditions (E3)
- RegenCollective
Raiseonndo:forestapproved. SourceProfilefor Forest: canopy index ↑,resilience↑.- Traverse
SourceCouplingLink { Forest → Conditions → River }withcoupling_strength: 0.68. - Derived update on River:
flux_rate += delta * 0.68,resilience += delta * 0.68(formula configurable in governance module). - River ledger now shows regeneration pathway — forest–river sustainability is an accounting fact, not external analysis.
Part V — Open Questions and Traceability
5.1 Pre-implementation decisions
| # | Question | Options | Recommendation |
|---|---|---|---|
| 1 | Flow endpoint representation | A enum / B additive / C overload | B now; A at major version |
| 2 | Extract action | New variant / map to Lower | New Extract variant |
| 3 | SourceProfile shape | Monolithic / split state vs value-vector | Monolithic MVP; split Layer 1 value vector later |
| 4 | Stock update authority | Agent-writable / governance-only | Governance-validated only (REQ-SOURCE-EVENT-02) |
| 5 | Cross-DNA Source hierarchy | Same cell links / NdoHardLink extension | Phase E: extend federation pattern |
| 6 | affects typing | Tag link / separate field affects_kind | Tag link SourceProfile presence discriminates |
| 7 | Fauna/Flora sub-sources | Separate NDOs / folded into Forest | Separate NDOs when distinct governance needed |
5.2 Implementation phasing (from REQ doc)
| Phase | This document section | Deliverable |
|---|---|---|
| A | §2.3, §2.4, §2.5 | SourceProfile, enums, coupling links, Steward role |
| B | §2.2, §2.8, §4.5 | Option B event fields, Extract, boundary event recording |
| C | §2.6 | Adaptive loop, regime transitions, affordance rules |
| D | §3.2, Layer 1 | Ecological value vector, PPR integration |
| E | §5.1 #5 | Cross-DNA watershed federation |
5.3 REQ-SOURCE-* traceability
| Requirement | Addressed in |
|---|---|
| REQ-SOURCE-ONT-01 | Part I §1.4; Part II §2.2 |
| REQ-SOURCE-ONT-02 | Part II §2.5, §2.7 |
| REQ-SOURCE-ONT-03 | Part II §2.4; Part IV §4.2 |
| REQ-SOURCE-ONT-04 | Part II §2.3; Part IV §4.3 |
| REQ-SOURCE-DATA-01 | Part II §2.3; Part IV §4.2 |
| REQ-SOURCE-DATA-02 | Part II §2.6; Part IV §4.5 |
| REQ-SOURCE-DATA-03 | Part III §3.2; Phase D |
| REQ-SOURCE-GOV-01 – 08 | Part II §2.6 |
| REQ-SOURCE-EVENT-01 – 03 | Part II §2.2; Part IV §4.5 |
5.4 Related documents
| Document | Role |
|---|---|
[source-ndo-requirements.md](source-ndo-requirements.md) | Normative REQ-SOURCE-* requirements |
[Source-NDO-brainstorming.md](Source-NDO-brainstorming.md) | Academic grounding, river case study, Occam analysis |
[ndo_prima_materia.md](../ndo_prima_materia.md) | NDO three-layer model, Layer 0 invariants |
[specifications.md](../../specifications/specifications.md) | MVP EconomicEvent, governance-as-operator |
| Valueflows specification | VF 1.0 ontology baseline |
This design document extends Valueflows at the flow-endpoint level and maps the extension onto nondominium's existing NDO, governance-as-operator, and PPR architecture without breaking Layer 0 permanence or MVP event history.
ValueFlows DSL
Requirements Document for Nondominium
| Project | Nondominium — Valueflows-compliant Resource Sharing Holochain Application |
| Organization | Sensorica Open Value Network |
| Authors | Sacha Pignot (Soushi888), Tibi |
| Status | Draft — For Community Review |
| Version | 1.0 (2025-12-28) |
| Repository | github.com/sensorica/nondominium |
Technical Specifications: See Valueflows DSL Technical Specifications for implementation details, syntax specifications, and technical architecture.
Scope note (ValueFlows version): This document specifies a DSL for ValueFlows 1.0 — the current, ratified vocabulary that Nondominium implements today (two flow-endpoint primitives:
AgentandEconomicResource). A separate, in-progress design proposes an augmented ValueFlows profile that adds a third primitive,vf:Source, for generative non-ownable systems (watersheds, forests, knowledge commons). Anywhere this document refers toSource,vf:Source,extract, or Source-NDOs, it is describing future/work-in-progress capability, not the MVP DSL. Seesource-valueflows-integration.mdandsource-ndo-requirements.md. The delineation is made explicit throughout (see §2.1.1).
Table of Contents
- Executive Summary
- Background and Context
- Goals and Objectives
- Target Users
- Use Cases
- Functional Requirements
- Non-Functional Requirements
- Technical Constraints
- Proposed Syntax Examples
- Implementation Roadmap
- Success Criteria
- Open Questions
- References
1. Executive Summary
This document specifies the requirements for a Domain-Specific Language (DSL) designed to express Valueflows economic patterns within the Nondominium ecosystem. The DSL aims to provide power users, network administrators, and developers with a concise, human-readable scripting language for bootstrapping networks, bulk resource registration, process recipe definition, and automated economic coordination.
Nondominium is a Valueflows-compliant Holochain application implementing distributed, agent-centric resource management with embedded governance. While a graphical user interface serves daily operations, complex administrative tasks—such as initializing a new commons network with dozens of resources, members, and governance rules—benefit significantly from a scriptable approach.
The proposed DSL bridges the gap between the formal Valueflows ontology and practical operational needs, enabling reproducible configurations, version-controlled economic definitions, and automated workflows that would be tedious or error-prone through manual GUI interaction.
2. Background and Context
2.1 Valueflows Overview
Valueflows is an open vocabulary for distributed economic networks, built upon the Resource-Event-Agent (REA) accounting ontology. It provides a standardized way to describe economic activity across organizational boundaries, enabling coordination between agents who may use different software systems.
Core Valueflows concepts include:
- Agents — Persons, organizations, or ecological agents that perform economic activities
- Resources — Economic resources tracked by specification (type) and optionally as inventoried instances
- Events — Observed economic activities: produce, consume, use, transfer, modify, move, etc.
- Processes — Transformations that take resource inputs and produce outputs
- Commitments — Promised future economic events
- Intents — Desired economic events not yet committed (offers and requests)
- Recipes — Templates defining how processes transform inputs to outputs
2.1.1 ValueFlows 1.0 vs. Augmented ValueFlows (planned)
The DSL specified in this document targets ValueFlows 1.0. Understanding the boundary between the ratified standard and the planned augmentation matters for scoping the DSL grammar and its compilation targets.
ValueFlows 1.0 (current — the DSL's baseline). The standard recognizes exactly two flow-endpoint primitives: Agent and EconomicResource. Every EconomicEvent has a provider and a receiver, both of which are strictly typed to vf:Agent in the specification; appropriable outputs are EconomicResources with a primaryAccountable agent. This is what Nondominium's zome_gouvernance and zome_resource implement today (EconomicEvent.provider/receiver are AgentPubKey; EconomicResource.custodian is an AgentPubKey). All MVP DSL constructs in §6 compile to this model.
Augmented ValueFlows (planned / work-in-progress — NOT part of the MVP DSL). A separate design proposes a third primitive, vf:Source — a generative, non-ownable, partially unknowable system that yields resources, receives effects, and conditions future possibilities (e.g. a river/watershed or a knowledge commons). Sources become valid flow endpoints and introduce an extract action, coupling links between Sources, a Steward functional role, and an adaptive (black-box) governance loop. This work is fully specified in source-valueflows-integration.md and source-ndo-requirements.md.
| Aspect | ValueFlows 1.0 (DSL baseline) | Augmented ValueFlows (planned) |
|---|---|---|
| Flow-endpoint primitives | Agent, EconomicResource | + vf:Source |
EconomicEvent endpoints | provider/receiver → Agent | endpoints may also be a Source |
| Actions | standard VF action set (§6.1.4) | + extract (draw yield from a Source) |
| Governance target | agent-held resources | + adaptive stewardship of Sources |
| DSL status | in scope for MVP | future — grammar reserved, not implemented |
Throughout the remainder of this document, any construct that touches Source is flagged (Planned — Augmented ValueFlows) and is out of scope for the MVP DSL grammar. It is documented here so the DSL's syntax and roadmap reserve room for it without committing to implementation.
2.2 Nondominium Architecture
Nondominium implements Valueflows on Holochain through a three-zome architecture:
- zome_person — Agent identity, profiles, roles, and capability-based access control
- zome_resource — Resource specifications, economic resources, and lifecycle management
- zome_gouvernance — State transition operator that evaluates governance rules and validates changes
This governance-as-operator design separates data management from business logic enforcement, allowing governance rules to be modified without changing resource data structures. The DSL must respect this separation while providing a unified scripting experience.
2.3 Problem Statement
Current limitations that the DSL addresses:
- Manual repetition — Registering many resources or agents requires repetitive GUI interactions
- No reproducibility — Network configurations cannot be version-controlled or replicated
- Steep learning curve — Understanding Valueflows requires navigating verbose JSON-LD or GraphQL structures
- No automation — Recurring administrative tasks cannot be scripted
- Testing complexity — Creating realistic test environments requires manual setup
3. Goals and Objectives
3.1 Primary Goals
- Accessibility — Lower the barrier to working with Valueflows patterns through readable, intuitive syntax
- Efficiency — Enable bulk operations that would be impractical through GUI interaction
- Reproducibility — Allow network configurations to be version-controlled, shared, and replicated
- Correctness — Provide compile-time validation of economic logic before execution
- Integration — Seamlessly compile to Nondominium's hREA zome calls
3.2 Secondary Goals
- Contribution to Valueflows ecosystem — Design the DSL to potentially benefit other Valueflows implementations
- Educational value — Help users understand Valueflows concepts through practical usage
- Extensibility — Support future additions to the Valueflows vocabulary and Nondominium features
4. Target Users
4.1 Primary Users
Network Administrators — Individuals responsible for setting up and maintaining Nondominium networks for their organizations or communities. They need to:
- Bootstrap new networks with initial agents, resources, and governance rules
- Migrate existing data from legacy systems
- Perform bulk updates across many resources
- Define and update governance rules systematically
Developers — Technical contributors building on or extending Nondominium. They need to:
- Create reproducible test environments
- Script integration tests with realistic data
- Generate demonstration scenarios
- Debug issues by examining DSL-generated state
4.2 Secondary Users
Power Users — Technically inclined community members who prefer scripting over GUI interaction for:
- Batch resource registration (e.g., cataloging an entire workshop)
- Defining complex process recipes
- Automating recurring administrative tasks
Other Valueflows Implementers — Projects building Valueflows-based systems who may adopt or adapt the DSL for their own use cases.
5. Use Cases
5.1 Network Bootstrapping
Scenario: A new fabrication commons wants to launch their Nondominium network with initial configuration.
Requirements:
- Define the organization and founding members
- Register resource specifications (equipment types, material categories)
- Create initial inventory of resources
- Establish governance rules for resource access and transfer
- Set up standard process recipes for common workflows
5.2 Bulk Resource Registration
Scenario: An existing workshop joins the network and needs to register all their equipment.
Requirements:
- Import from CSV or structured data sources
- Apply common properties to groups of resources
- Generate unique identifiers systematically
- Validate data consistency before committing
5.3 Process Recipe Definition
Scenario: The network documents standard manufacturing processes for replication and planning.
Requirements:
- Define input resources (consumed, used, cited)
- Define output resources (produced)
- Specify work requirements by skill type
- Indicate process stages and dependencies
- Support recipe scaling (multiplying quantities)
5.4 Governance Rule Configuration
Scenario: Administrators define access policies, booking limits, and approval workflows.
Requirements:
- Define rules that apply to resource categories
- Specify conditions, thresholds, and approvers
- Update rules without affecting resource data
- Validate rule consistency and coverage
5.5 Migration and Export
Scenario: Data moves between systems or needs backup/restore capability.
Requirements:
- Export current network state as DSL scripts
- Diff two states to generate migration scripts
- Import from other Valueflows implementations
- Generate JSON-LD or GraphQL representations
6. Functional Requirements
6.1 Language Primitives
The DSL must support the following ValueFlows 1.0 concepts as first-class language constructs. (The Source primitive is a planned augmentation — see §6.1.7 — and is not part of the MVP grammar.)
6.1.1 Agents
- Person agents with profile information
- Organization agents (formal and informal)
- Role assignments within organizations
- Agent relationships (member-of, works-for, etc.)
6.1.2 Resources
- Resource specifications (types/kinds)
- Economic resources (inventoried instances)
- Resource classifications (taxonomies)
- Units of measure
- Lot and serial number tracking
6.1.3 Flows
- Intents (offers and requests)
- Commitments (promises)
- Economic events (observations)
- Claims (reciprocal expectations)
6.1.4 Actions
All standard ValueFlows 1.0 actions must be supported:
- Process actions: produce, consume, use, cite, work, deliverService, modify
- Transfer actions: transfer, transferAllRights, transferCustody
- Movement actions: move, pickup, dropoff
- Combination actions: combine, separate
- Adjustment actions: raise, lower, copy
(Planned — Augmented ValueFlows) The augmented profile adds an
extractaction for drawing yield from avf:Source(e.g. abstracting water from a watershed, downloading a design from a commons repository).extractis not part of the MVP DSL action set; it is reserved for the future Source work. Seesource-valueflows-integration.md.
6.1.5 Processes and Recipes
- Process specifications (types)
- Process instances
- Recipe definitions with input/output flows
- Stage tracking for multi-step workflows
6.1.6 Governance (Nondominium-specific)
- Access rules for resource types
- Approval workflows
- Booking and usage limits
- Private Participation Receipts (PPR) configuration
6.1.7 Sources — (Planned — Augmented ValueFlows, WIP)
Not part of the MVP DSL. The following constructs are reserved for the future augmented-ValueFlows profile and are documented so the grammar can accommodate them later without breaking changes. Full requirements live in
source-valueflows-integration.mdandsource-ndo-requirements.md.
When the vf:Source primitive is adopted, the DSL is expected to add:
- Source declarations — a generative system (e.g.
Hydrological,KnowledgeCommons) with aSourceProfile(regime state, stock/flux, stewards, coupling links), modeled as a Layer 0 NDO extension extractevents — events whose provider or receiver is aSourcerather than anAgent- Source coupling links — typed relationships between Sources (
Yields,Conditions, etc.) so effects propagate across a watershed or dependency graph Stewardrole assignments — a functional role emphasizing obligations toward a Source rather than rights over a resource- Adaptive governance blocks — rules that observe boundary events on a Source and adapt (black-box governance loop)
The grammar should treat these as an optional, versioned language extension gated behind the augmented-ValueFlows profile, keeping the MVP declarative core (§6.1.1–6.1.6) unchanged.
6.2 Operations
6.2.1 CRUD Operations
- Create new entities
- Read/query existing entities
- Update entity properties
- Delete/archive entities
6.2.2 Bulk Operations
- Create multiple entities from templates
- Update entities matching criteria
- Import from external data sources
- Export to various formats
6.2.3 Validation
The DSL must provide comprehensive validation across multiple dimensions:
- Syntax validation — Grammar compliance and structure checking
- Type checking — Unit compatibility, resource specification matching
- Reference integrity — Agent and resource existence verification
- Economic logic — Process balance, valid action sequences
- Governance compliance — Rule coverage, conflict detection
See technical specifications for detailed validation pipeline architecture.
6.3 CLI Interface
| Command | Description |
|---|---|
nondom apply <script.vf> | Execute a DSL script against the network |
nondom validate <script.vf> | Validate syntax and semantics without executing |
nondom apply --dry-run <script.vf> | Show what would change without applying |
nondom export --format vf | Export current state as DSL script |
nondom import <file> --mapping <map.vf> | Import from external format using mapping |
nondom repl | Interactive shell for exploratory scripting |
7. Non-Functional Requirements
7.1 Usability
- Syntax should be readable by non-programmers familiar with Valueflows concepts
- Error messages must reference source locations and suggest corrections
- Documentation with examples for all major use cases
- Syntax highlighting support for common editors (VS Code, Vim, Emacs)
7.2 Performance
Target Performance Metrics:
| Operation | Target | Notes |
|---|---|---|
| Parse 1000 entities | < 1 second | Script size |
| Validate typical script | < 2 seconds | All validation phases |
| Create 100 resources | < 10 seconds | Excluding DHT latency |
| Export 1000 entities | < 5 seconds | To DSL format |
| Bulk update 100 resources | < 5 seconds | With where clause |
Scalability:
- Support scripts with 1000+ entity definitions
- Memory usage < 100MB for typical operations
- Batch operations optimize Holochain network calls
See technical specifications for detailed optimization strategies.
7.3 Reliability
- Atomic execution — All-or-nothing application of changes
- Idempotent operations — Repeated executions produce consistent results
- Clear rollback semantics — Graceful failure recovery
- No data corruption — Crash-safe operations
7.4 Extensibility
- Support for custom attributes beyond core Valueflows
- Plugin architecture for additional compilation targets
- Versioned language specification for backward compatibility
7.5 Security
The DSL must provide:
- Agent authentication — Scripts execute with authenticated agent's permissions
- Capability-based access control — All operations validated against capability tokens
- Data privacy — Sensitive data handling respects Nondominium's privacy model
- Audit logging — Comprehensive logging of all operations
- Declarative-only execution — No arbitrary code execution or system access
- Rate limiting — Abuse prevention for bulk operations
See technical specifications for detailed security model.
8. Technical Constraints
8.1 Technology Stack
- Implementation language: Rust (to align with Nondominium's existing codebase)
- Parser: pest or nom parser combinators
- Primary target: Nondominium hREA zome calls
- Secondary targets: JSON-LD export, GraphQL mutations, visualization
8.2 Valueflows Compliance
- DSL concepts must map cleanly to Valueflows vocabulary
- Terminology should align with Valueflows documentation
- Export to standard Valueflows JSON-LD must be lossless
8.3 Holochain Integration
- Respect Holochain's agent-centric security model
- Work within DHT consistency constraints
- Support capability-based access control
9. Proposed Syntax Examples
The following examples illustrate the proposed DSL syntax. Final syntax will be refined during implementation.
9.1 Network Bootstrap
# Network initialization script
network FabLabMontreal {
created: 2025-01-15
jurisdiction: Quebec
}
agents {
organization Sensorica {
type: OpenValueNetwork
location: Montreal
}
person Alice { roles: [Founder, Steward] }
person Bob { roles: [Technician, Member] }
}
9.2 Resource Registration
resource_specifications {
Equipment {
governance: commons_stewardship
accounting: use_tracking
}
Material {
governance: pool_contribution
accounting: quantity_consumed
}
}
resources {
CNC_Router : Equipment {
custodian: Sensorica
location: "Main workshop"
value_estimate: 15000 CAD
}
PLA_Filament : Material {
quantity: 50 kg
pool: shared_consumables
}
}
9.3 Process Recipe
recipe MachinePart {
inputs:
Aluminum_Stock 0.5kg (consume)
CNC_Machine 2h (use)
work:
Fabrication 2h
outputs:
Machined_Part 1 (produce)
}
9.4 Governance Rules
governance {
rule EquipmentBooking {
applies_to: Equipment
max_advance_booking: 14 days
requires_approval_above: 8h
approvers: [Steward, Technician]
}
}
9.5 Economic Events
# Recording actual events
event production_001 {
action: produce
provider: Alice
output: Machined_Part
quantity: 10
at: 2025-01-20T14:30:00
}
# Fulfilling a commitment
fulfill order_123 {
performed_by: Bob
resource: Machined_Part
quantity: 10
to: Customer
}
9.6 Bulk Operations
# Register multiple similar resources
resources {
3D_Printer_Fleet : Equipment * 5 {
custodian: Sensorica
model: "Prusa MK4"
location: "Print farm"
# Creates: 3D_Printer_Fleet_1 through 3D_Printer_Fleet_5
}
}
# Update matching resources
update resources where type == Equipment {
maintenance_schedule: monthly
}
9.7 Sources — (Planned — Augmented ValueFlows, WIP)
Illustrative future syntax, not implemented. This sketch shows how the DSL might express
vf:Sourceonce the augmented-ValueFlows profile is adopted. It is included only to reserve syntactic space; it is not part of the MVP grammar. Authoritative modeling lives insource-valueflows-integration.md.
# Declare a generative Source (Layer 0 NDO extension) — PLANNED
source WatershedX {
type: Hydrological
property_regime: Nondominium
regime_state: Stressed
stewarded_by: [Alice, Bob]
# coupling to a downstream Source
yields: AquiferY
}
# Draw yield from the Source via the planned `extract` action — PLANNED
event abstraction_042 {
action: extract
provider: WatershedX # a Source acts as flow endpoint
receiver: Alice
resource: FreshWater
quantity: 500 L
at: 2026-04-01T09:00:00
}
# Adaptive governance keyed to observed boundary events — PLANNED
governance {
adaptive rule WaterAbstractionLimit {
applies_to: WatershedX
when: regime_state == Stressed
max_extract_per_day: 1000 L
on_breach: tighten_and_notify_stewards
}
}
See technical specifications for additional syntax examples and edge cases.
10. Implementation Roadmap
Phase 1: Core Language (MVP)
Duration: 4-6 weeks
- Parser implementation for core constructs
- Agent and resource registration
- Basic validation (syntax, types)
- CLI with apply and validate commands
- Compilation to Nondominium zome calls
Deliverables: Working DSL for basic agent and resource definitions
Phase 2: Completeness
Duration: 4-6 weeks
- Full Valueflows action support
- Process and recipe definitions
- Governance rule configuration
- Import/export functionality
- Dry-run and diff capabilities
Deliverables: Complete DSL covering all major use cases
Phase 3: Tooling
Duration: 3-4 weeks
- Language server protocol (LSP) implementation
- VS Code extension
- REPL for interactive exploration
- Documentation and tutorial content
Deliverables: Developer-friendly tooling ecosystem
Phase 4: Ecosystem
Duration: Ongoing
- Additional compilation targets (GraphQL, visualization)
- Community feedback integration
- Coordination with Valueflows community
- Template library for common patterns
Deliverables: Sustainable community-driven development
Future / Deferred: Augmented ValueFlows (vf:Source) support
Status: Not scheduled — gated on adoption of the augmented-ValueFlows profile.
Support for the Source primitive (§6.1.7, §9.7) — source declarations, the extract action, coupling links, Steward roles, and adaptive governance blocks — is explicitly out of scope for Phases 1–4. It will be planned as a distinct, versioned language extension only after the augmented-ValueFlows design (source-valueflows-integration.md) is ratified and the corresponding Nondominium backend (SourceProfile, Source flow endpoints, Steward role) is implemented. The MVP grammar reserves room for it without committing to a timeline.
11. Success Criteria
11.1 Measurable Success Metrics
| Criterion | Measurable Target | Verification Method |
|---|---|---|
| Network Bootstrapping | Bootstrap 100-agent network in < 5 minutes | Time full bootstrap script execution |
| Bulk Registration | Register 100 resources in < 10 seconds | Benchmark bulk resource creation |
| Script Reviewability | Comprehend 200-line script in < 5 minutes | User testing with experienced administrators |
| Error Resolution | Fix common errors in < 2 minutes using error messages | Measure time-to-fix for typical errors |
| External Adoption | 2+ organizations using DSL in production by Q2 2026 | Track adoption through GitHub issues and community |
| Community Feedback | 80%+ positive sentiment on Valueflows design alignment | Survey Valueflows community members |
| Parse Performance | Parse 1000-entity script in < 1 second | Automated performance benchmarking |
| Validation Accuracy | < 1% false positive rate in validation errors | Test suite with valid and invalid scripts |
| Documentation Coverage | 100% of language constructs documented | Automated documentation completeness check |
| Test Coverage | > 90% code coverage for DSL compiler | Automated test coverage reporting |
11.2 User Acceptance Criteria
Network Administrators:
- Can create bootstrap script without programming background
- Successfully complete initial network setup in < 30 minutes
- Understand error messages and fix issues independently
- Export/import network state for backup purposes
- Define governance rules using DSL syntax
Developers:
- Create reproducible test environments with < 50 line scripts
- Generate 100+ test resources in < 30 seconds
- Debug issues using DSL-generated state exports
- Integrate DSL into CI/CD pipelines
- Extend DSL with custom attributes when needed
Power Users:
- Register equipment inventory using bulk operations
- Define complex process recipes for manufacturing
- Automate recurring administrative tasks
- Share scripts with community for reuse
- Contribute governance rule templates
11.3 Technical Validation Criteria
Correctness:
- All Valueflows actions supported and tested
- Economic logic validation prevents invalid states
- Governance rules enforce correctly
- Round-trip export/import preserves data 100%
Performance:
- Parse 1000 entities in < 1 second
- Validate typical script in < 2 seconds
- Execute 100-entity script in < 30 seconds (excluding DHT)
- Memory usage < 100MB for typical operations
Reliability:
- Atomic transactions succeed or roll back completely
- Idempotent operations produce consistent results
- Error recovery gracefully handles failures
- No data corruption in crash scenarios
Usability:
- Error messages include line numbers and suggestions
- Syntax highlighting available for VS Code, Vim, Emacs
- Tutorial covers all common use cases
- Example scripts for all major patterns
- CLI help provides clear usage guidance
11.4 Ecosystem Integration Criteria
Valueflows Alignment:
- Terminology matches Valueflows specification
- Export to JSON-LD is lossless
- Community review validates design approach
- Contribution guidelines for upstream inclusion
Nondominium Integration:
- Compiles to correct hREA zome calls
- Respects capability-based access control
- Works with existing GUI-created data
- Governance rules integrate with zome_gouvernance
12. Open Questions
| Question | Status | Resolution / Considerations |
|---|---|---|
| File extension | ⏳ Open | Options: .vf (recommended), .nondom, .valueflows — Community feedback requested |
| Scripting capabilities | ✅ RESOLVED | Three-tier progressive model (see technical specs) — MVP is declarative, T2 adds templates, T3 adds scripting |
| Temporal expressions | ⏳ Open | Consider ISO 8601 durations, cron-like schedules, natural language — Needs UX research |
| Module system | ⏳ Open | include directive shown in examples, but dependency resolution TBD — Circular dependency prevention needed |
| Governance scope | ✅ RESOLVED | Tightly integrated (see technical specs Section 3) — Full DSL syntax for governance rules with testing |
12.1 Decision Log
Resolved: Scripting Capabilities (2025-01-15)
- Decision: Three-tier progressive language model
- Rationale: Allows MVP to remain simple while providing upgrade path
- Impact: Most users only need Tier 1; Tier 3 can be added based on demand
- Reference: Technical Specifications, Section 1.1
Resolved: Governance Scope (2025-01-15)
- Decision: Governance rules are first-class DSL constructs
- Rationale: Enables version-controlled, testable governance policies
- Impact: Unified scripting experience for data and rules
- Reference: Technical Specifications, Section 3
12.2 Questions Requiring Community Input
File Extension:
- Proposed:
.vf(short, memorable, indicates Valueflows) - Alternatives:
.nondom(project-specific),.valueflows(explicit but long) - Decision Target: Q1 2026, after MVP prototype testing
Temporal Expressions:
- Use Cases: Booking durations, maintenance schedules, temporal governance rules
- Options:
- ISO 8601:
P1H(1 hour),P30M(30 minutes) - Natural:
1h,30min,2days - Cron:
0 9 * * 1-5(9am weekdays)
- ISO 8601:
- Research Needed: User testing for readability and ease of use
Module System Design:
- Requirements:
- Import scripts by path
- Circular dependency detection
- Namespace isolation
- Re-exports for library scripts
- Open Issues: How to handle version mismatches between imported scripts?
13. References
- Valueflows Specification (v1.0): https://www.valueflo.ws/
- Nondominium Repository: https://github.com/sensorica/nondominium
- hREA Project: https://github.com/h-REA/hREA
- REA Ontology: https://wiki.p2pfoundation.net/Resource-Event-Agent_Model
- Holochain Documentation: https://developer.holochain.org/
- Technical Specifications: Valueflows DSL Technical Specifications
- Augmented ValueFlows — Source integration (planned/WIP):
source-valueflows-integration.md - Source-NDO requirements (planned/WIP):
source-ndo-requirements.md
Appendix A: Valueflows Action Reference
The following are ValueFlows 1.0 actions supported by the MVP DSL.
| Action | Effect on Resource | Typical Use |
|---|---|---|
produce | Increments quantity | Manufacturing output |
consume | Decrements quantity | Raw material input |
use | No quantity change | Equipment usage |
cite | No quantity change | Reference designs/docs |
work | N/A (effort) | Labor contribution |
deliverService | N/A (service) | Service delivery |
modify | Changes properties | Repair, upgrade |
transfer | Changes custody + rights | Full ownership transfer |
transferAllRights | Changes rights only | Sell without delivery |
transferCustody | Changes custody only | Lend, consign |
move | Changes location | Transportation |
pickup | Start custody transfer | Receive shipment |
dropoff | Complete custody transfer | Deliver shipment |
combine | Creates container | Packaging, kitting |
separate | Splits container | Unpacking |
raise | Increments (adjustment) | Inventory correction up |
lower | Decrements (adjustment) | Inventory correction down |
copy | Creates duplicate | Digital resources |
Planned — Augmented ValueFlows (not in MVP DSL):
| Action | Effect on Resource / Source | Typical Use |
|---|---|---|
extract | Draws yield from a vf:Source; debits the Source's stock/regime state | Abstracting water from a watershed; downloading a design from a knowledge commons |
Appendix B: Glossary
| Term | Definition |
|---|---|
| Agent | A person, organization, or ecological entity that can participate in economic activity |
| Augmented ValueFlows | (Planned/WIP) A proposed profile extending ValueFlows 1.0 with the vf:Source primitive, the extract action, and adaptive stewardship governance |
| Commitment | A promise to perform an economic event in the future |
| DHT | Distributed Hash Table — Holochain's data storage mechanism |
| Economic Event | An observed change in resources or resource rights |
| Economic Resource | Something of value that can be tracked and accounted for |
| hREA | Holochain implementation of the REA accounting model |
| Intent | A desired economic event that has not yet been committed to |
| PPR | Private Participation Receipt — Nondominium's reputation tracking mechanism |
| Process | A transformation that takes inputs and produces outputs |
| Recipe | A template defining a repeatable process |
| REA | Resource-Event-Agent — An accounting ontology |
| Resource Specification | A type or kind of resource (not an instance) |
Source (vf:Source) | (Planned/WIP) A proposed third ValueFlows primitive: a generative, non-ownable, partially unknowable system that yields resources, receives effects, and conditions future possibilities (e.g. a watershed or knowledge commons) |
| Source-NDO | (Planned/WIP) A Nondominium NDO whose Layer 0 carries a SourceProfile, representing a vf:Source in the hApp |
| Steward | (Planned/WIP) A functional role for Source governance, emphasizing obligations toward a Source over rights over a resource |
| Valueflows | A vocabulary for distributed economic coordination (this DSL targets v1.0) |
| Zome | A module in a Holochain application |
Unyt Integration: Economic Closure for the Nondominium Object
Status: Post-MVP Design Document
Created: 2026-03-11
Authors: Nondominium project
Relates to: ndo_prima_materia.md, many-to-many-flows.md, versioning.md
Table of Contents
- Framing: The Generic NDO and Nondominium as Instantiation
- The Economic Closure Problem
- The NDO Economic Loop
- Unyt as Economic Operator
- Integration Architecture
- Alliance Design Patterns
- The Reputation-Credit Mechanism
- Economic Governance
- Generic NDO and Nondominium as Instantiation
- Integration Path
- Requirements
1. Framing: The Generic NDO and Nondominium as Instantiation
This document is written in the context of a conceptual shift in the Nondominium project's post-MVP trajectory. The Nondominium Object (NDO) — the three-layer DHT primitive described in ndo_prima_materia.md — is being recognised as generic infrastructure that should exist independently of any specific application domain.
The plan:
- A new project (working name: NDO Commons) will implement the three-layer model (Identity, Specification, Process), the lifecycle state machine, the capability slot surface, the governance-as-operator architecture, and the PPR system as a generic, reusable Holochain hApp primitive
- Nondominium (this project) will become one instantiation of that generic primitive: a peer resource-sharing economy built on top of NDO Commons, adding resource-domain-specific entry types, PPR categories, role structures, and economic configurations
- Other projects can build their own NDO instantiations: fabrication networks, cooperative enterprises, local economic systems, digital commons — any community that needs a cryptographically-accountable, self-governing, lifecycle-aware object infrastructure
This document specifies how Unyt integrates with the generic NDO. The Unyt integration is designed to be:
- Optional — the NDO functions without it; economic settlement is a capability communities activate when they need it, not a structural requirement
- Modular — it connects to the NDO via the capability slot mechanism (Section 6 of
ndo_prima_materia.md) and a standard GovernanceRule type, requiring no modifications to the NDO's core data model - Alliance-configurable — each NDO community defines its own Unyt Alliance: its unit of account, its credit limit algorithm, its Smart Agreement templates, its fee policy
- Lifecycle-aware — economic terms can differ across NDO lifecycle stages; a resource under development may be accessed freely while the same resource in
Activestate requires economic settlement
Nondominium's specific Unyt configuration (resource-sharing currencies, Commons Alliance archetype, credit limit algorithm based on physical resource PPRs) is described in Section 9 as an instantiation example, not as the generic specification.
2. The Economic Closure Problem
The ValueFlows standard, on which the NDO is built, provides rigorous primitives for describing and observing economic activity: Resources, Events, Agents, Processes, Commitments, Claims. It is a complete accounting ontology — a language for observing what happens economically.
What ValueFlows does not provide is settlement. It accurately records who did what, with what resource, at what time. It does not close the loop by specifying what economic value subsequently flows to the people who contributed. The observation is complete; the consequence is absent.
This is the economic closure problem: a system that observes all economic activity but produces no economic consequence cannot sustain the incentive structures needed for long-term participation. Agents contribute, validate, steward, repair, transport — and the system records all of it — but nothing economically meaningful follows from the record. The loop is open.
Open loops break commons economies. The digital commons (FLOSS, Wikipedia) can survive on open loops because information is non-rivalrous: sharing a file costs nothing. Physical commons — shared tools, equipment, spaces, transport capacity, repair skill — are rivalrous. Physical stewardship has real costs: time, expertise, risk of damage to one's equipment, opportunity cost. A system that observes stewardship without rewarding it will reliably attract less of it, and will ultimately fail to retain the agents who are best at it.
The closure Unyt provides has four dimensions:
- Settlement — economic value flows as a direct consequence of observed events; the RAVE (Recorded Agreement Verifiably Executed) is the cryptographic proof that value flowed
- Currencies — communities define their own units of account, matched to the actual value their resources produce; credits earned through contribution can be spent on access, services, or governance
- Credit — participation history determines economic capacity; the past record of an agent becomes collateral for future engagement, without requiring financial deposits or social vouching
- Governance weight — economic standing feeds back into governance authority; those who have contributed most to the commons have the most legitimate standing to shape its rules
When all four dimensions are active, the loop closes. The sections that follow trace that loop in full.
3. The NDO Economic Loop
The NDO's three layers provide the structural basis for description and observation. Unyt provides the settlement layer that makes observation consequential. Together they define a complete, self-reinforcing economic loop.
┌──────────────────────────────────────────────────────────────────────────┐
│ THE NDO ECONOMIC LOOP │
│ │
│ DESCRIPTION (Layer 1) │
│ What the resource is. What governance rules apply. │
│ What economic terms govern access, contribution, and benefit. │
│ ↓ │
│ OBSERVATION (Layer 2) │
│ What happens: events, commitments, claims, quality receipts (PPRs). │
│ Who did what, when, with what resource, at what quality. │
│ ↓ │
│ SETTLEMENT (Unyt Smart Agreement → RAVE) │
│ Value flows as a direct consequence of observed events. │
│ Smart Agreement executed → RAVE produced → credits flow to stewards. │
│ ↓ │
│ REPUTATION (PPR + RAVE linkage) │
│ The permanent record of participation quality and economic reliability.│
│ PPR: who did what, how well (quality proof). │
│ RAVE: who settled what, to whom, under what rules (economic proof). │
│ Together: a complete, cross-verifiable agent economic identity. │
│ ↓ │
│ CREDIT (Compute Credit Limit Agreement) │
│ Reputation → economic capacity in the commons. │
│ New agents: minimal credit (minimal track record). │
│ Reliable stewards: expanded credit (demonstrated trustworthiness). │
│ The past record becomes collateral for future engagement. │
│ ↓ │
│ ACCESS (UnytAgreement enforcement + RAVE as precondition) │
│ Credit + agreement execution → state transition approved. │
│ Resources governed by their own economic terms, enforced by peers. │
│ ↓ │
│ MOTIVATION │
│ Participation in the commons earns economic standing. │
│ Economic standing unlocks access to more of the commons. │
│ The incentive to contribute aligns perfectly with the incentive │
│ to participate: they are the same incentive. │
│ ↓ │
│ GOVERNANCE │
│ Economic standing → governance weight. │
│ Those who have contributed most to the commons have the most │
│ standing to shape its rules. Smart Agreements ARE governance rules. │
│ ↓ │
│ DESCRIPTION (Layer 1 — updated through governance) │
│ Governance decisions update economic terms. │
│ New Smart Agreements are endorsed as GovernanceRules. │
│ Credit limit algorithms are recalibrated. │
│ The resource's economic self-description evolves with the community. │
│ [loop] │
└──────────────────────────────────────────────────────────────────────────┘
Each element of the loop maps to specific technical primitives:
| Loop element | NDO primitive | Unyt primitive |
|---|---|---|
| Description | Layer 1 (ResourceSpecification + GovernanceRule) | EconomicAgreementRuleData (in GovernanceRule) |
| Observation | Layer 2 (EconomicEvent, Commitment, Claim, PPR) | — |
| Settlement | — | Unyt Smart Agreement + RAVE |
| Reputation | PrivateParticipationClaim (PPR) | settlement_rave_hash field (on PPR) |
| Credit | — | Compute Credit Limit Agreement (RHAI) |
| Access | Governance zome (state transition) | UnytAgreement enforcement + RAVE validation |
| Motivation | — | Credit capacity as economic signal |
| Governance | GovernanceRule + role-based access | Smart Agreements as economic governance rules |
The loop is the architecture. Every design decision in the integration should be evaluated against how it strengthens or weakens the loop's coherence.
4. Unyt as Economic Operator
Unyt (unyt.co) is peer-to-peer accounting infrastructure built on Holochain. Each participant runs the application on their own device, maintains their own cryptographically-signed chain of records, and validates peers directly. There are no central servers, miners, or stakers. Like the NDO, it is agent-centric and DHT-based — both systems share the same foundational architecture.
This architectural compatibility is not incidental. It means:
- The same agent key that signs NDO events also signs Unyt transactions. Cross-cell calls between the NDO cell and the Unyt cell share the same cryptographic identity without trust bridges or API integrations.
- The NDO's agent-centric observation (Layer 2 events, PPRs on each agent's source chain) can be accessed by Unyt's credit limit algorithm via cross-DNA calls to the same node — no data replication, no synchronization protocol.
- Both systems use Holochain's append-only DHT and source chain model, so RAVEs are as permanent and tamper-evident as PPRs; neither can be retroactively altered.
Unyt's key primitives in the NDO context:
Unyt Alliance — A configured deployment of the Unyt system. Each Alliance defines its own Base Unit (unit of account), credit limit algorithms, transaction fee policies, Smart Agreement templates, Service Networks (sub-communities), and governance. For the generic NDO: each NDO community that activates economic settlement configures a Unyt Alliance. The Alliance is the community's economic constitution, parallel to but separate from the NDO's governance constitution (GovernanceRules).
Smart Agreement — Programmable economic rules governing value flows, credit extension, and coordination. Validated by peers, not by central servers. For the NDO: Smart Agreements are the economic complement to GovernanceRules — where GovernanceRules specify who may take what action, Smart Agreements specify what economic consequence follows when they do.
RAVE (Recorded Agreement Verifiably Executed) — The immutable artifact produced when a Smart Agreement executes. Contains inputs used, the agreement reference, and outputs produced. Any participant can independently verify the execution. For the NDO: the RAVE is the economic proof that complements the PPR's participation proof. Together they constitute a complete, doubly-verifiable record that neither system alone can provide.
Compute Credit Limit Agreement — A configurable Smart Agreement (RHAI script) that dynamically calculates each agent's credit capacity. For the NDO: this is the bridge between observation and economic capacity. The agent's participation history, expressed through their ReputationSummary, becomes the primary input — making reputation the collateral for economic access.
Source Chain — Each agent's append-only, cryptographically-signed record of all their actions. In Holochain, this is the same structure in both the NDO cell and the Unyt cell. An agent's economic history in Unyt and their participation history in the NDO are both part of the same cryptographic identity — they are two aspects of a single coherent agent record.
5. Integration Architecture
The NDO-Unyt integration uses four coupling points, designed to be independently activatable across the three integration phases described in Section 10.
5.1 Capability Slot (Layer 0 — discovery surface)
The UnytAgreement(String) slot type in the SlotType enum (defined in ndo_prima_materia.md Section 8.3) is the permissionless discovery surface. Any Accountable Agent can attach a proposed Unyt Smart Agreement to any NDO's Layer 0 identity hash. This is informational — a proposal, a market signal, a community suggestion. Multiple competing proposals may coexist. The governance zome does not enforce Tier 1 slots.
The String parameter carries the Unyt Alliance network seed, allowing a single NDO to be referenced by agreements on different Alliance instances (for inter-community bridging or migration scenarios).
5.2 GovernanceRule — EconomicAgreement Type (Layer 1 — authoritative terms)
GovernanceRule entries of type EconomicAgreement are the authoritative economic terms. When a custodian or governance process creates this rule, it endorses a specific Unyt Smart Agreement as the economic condition for a set of VfAction events. The rule carries:
#![allow(unused)] fn main() { // New variant in GovernanceRuleType enum (zome_resource integrity) pub enum GovernanceRuleType { // ... existing rule types ... EconomicAgreement, // rule_data: JSON-serialized EconomicAgreementRuleData } #[derive(Serialize, Deserialize)] pub struct EconomicAgreementRuleData { pub unyt_alliance_id: String, // Network seed of the Unyt Alliance pub smart_agreement_hash: String, // Entry hash of the Unyt Smart Agreement pub trigger_actions: Vec<VfAction>, // Which VfActions trigger settlement pub settlement_window_secs: u64, // Max seconds between RAVE execution and transition pub note: Option<String>, // Human-readable description of economic terms } }
This rule lives in Layer 1 alongside other GovernanceRules — access control, role requirements, validation schemes. It is the economic layer of the resource's governance specification.
5.3 State Transition Enforcement (Governance Zome — enforcement bridge)
When the governance zome processes a state transition whose VfAction matches a trigger_actions entry in an endorsed EconomicAgreement rule, the transition request must include a rave_hash. The governance zome:
- Confirms the transition's
VfActionis in the rule'strigger_actionslist - Retrieves and validates the RAVE from the Unyt DHT (cross-DNA call)
- Confirms the RAVE was executed within
settlement_window_secs - Confirms RAVE inputs match the transition context (resource identity, provider, receiver, quantity or duration)
- Approves the transition and generates the PPR with
settlement_rave_hashpopulated
This makes the governance zome's approval conditional on cryptographic proof of economic settlement — the resource does not move, change state, or transfer custody until the agreed value has flowed.
5.4 PPR + RAVE Linkage (Layer 2 — provenance chain closure)
The settlement_rave_hash field on PrivateParticipationClaim entries is the binding point between the NDO's participation record and Unyt's economic record:
#![allow(unused)] fn main() { pub struct PrivateParticipationClaim { // ... existing fields ... pub settlement_rave_hash: Option<String>, // Unyt RAVE hash; None if no economic rule triggered } }
This creates a complete, cross-verifiable provenance chain:
Commitment
└─ (fulfilled by) EconomicEvent
└─ (generates) PrivateParticipationClaim (PPR)
├── performance_metrics: { timeliness, quality, reliability, communication }
├── bilateral_signatures: (provider_sig, receiver_sig)
└── settlement_rave_hash → Unyt RAVE
└─ (verifiable on Unyt DHT: inputs, agreement, outputs, executor)
The PPR is the participation proof: who did what, with what quality, in which role. The RAVE is the economic proof: what value flowed, to whom, under what rules, verified by Unyt peers. Together, they constitute a record of a resource interaction that is complete in both the participation and economic dimensions — and that feeds back into both the reputation system and the credit limit algorithm.
5.5 Unyt Alliance (external, per-community)
The Unyt Alliance is a separate Holochain cell (or Unyt Sandbox deployment) that the NDO cell interacts with via cross-DNA calls. It is not embedded in the NDO — it is federated alongside it. Each NDO community configures its own Alliance.
graph LR
subgraph NDO_Cell ["NDO Cell"]
L0["Layer 0 (Identity)"]
L1["Layer 1 (Spec + GovernanceRules)"]
L2["Layer 2 (Process + Events + PPRs)"]
GZ["Governance Zome\n(state transition operator)"]
end
subgraph Unyt_Cell ["Unyt Alliance Cell"]
UA["Alliance Config\n(Base Unit, fees, parameters)"]
SA["Smart Agreements\n(RHAI templates + RAVEs)"]
CL["Credit Limit Agreement\n(Compute Credit Limit RHAI)"]
end
L0 -->|"CapabilitySlot\n(UnytAgreement — Tier 1)"| SA
L1 -->|"GovernanceRule\n(EconomicAgreement — Tier 2)"| SA
GZ -->|"cross-DNA call\n(RAVE validation)"| SA
L2 -->|"PPR.settlement_rave_hash"| SA
L2 -->|"ReputationSummary\n(cross-DNA call)"| CL
CL -->|"credit_limit result"| UA
6. Alliance Design Patterns
Different NDO communities have very different economic needs. The Unyt Alliance is configurable enough to support a broad spectrum. Three archetypes cover the most common patterns; communities can combine and extend them freely.
6.1 Gift Economy Alliance
When to use: Communities where sharing is unconditional, economic tracking is for awareness not enforcement. Time banks, mutual aid networks, close-knit cooperatives, family or neighbourhood resource sharing.
Base Unit: A contribution token (e.g. "GiftHour") with no monetary exchange value — a formal record of giving, not a claim on receiving. The unit's purpose is visibility, not pricing.
Credit limit: Generous and largely uniform. Participation history is tracked but does not gate access. Reputation is public and affirming, not exclusionary.
Smart Agreements: None that gate resource access. Optionally: Aggregate Payment agreements that route a fraction of activity-generated tokens to the NDO's governance pool (funding maintenance, shared infrastructure, community operations).
Fees: Zero. Always.
NDO Integration: UnytAgreement capability slots are informational only (Tier 1). No EconomicAgreement governance rules enforced. Settlement is voluntary, reciprocal, and community-normed rather than system-enforced.
Loop dynamics: In this archetype, Unyt's primary contribution is visibility and soft incentive, not enforcement. The observation → settlement → reputation path is active, but the credit → access gate is open. The loop is complete but runs on social rather than economic pressure.
6.2 Commons Alliance
When to use: Shared resources with real stewardship costs; access should be earned through contribution; non-contributing access-seekers should pay fees. Tool libraries, maker spaces, shared equipment pools, repair networks.
Base Unit: A commons credit (e.g. "CommonHour" or "FabCredit") earned through contribution, validation, and stewardship; spent on access and services.
Credit limit: Dynamically derived from ReputationSummary (see Section 7). New members get minimal credit (observer access only). Each validated contribution, stewardship event, or governance participation increases credit. Long-term reliable stewards have the highest credit capacity.
Smart Agreements:
Conditional Forwardfor access fees (non-contributors pay before access; contributors access freely within credit)Aggregate Paymentfor stewardship compensation (custodian + maintenance fund + optional protocol treasury)Proof of Servicefor service billing (transport, repair, storage providers automatically settled on validated Claim)
Fees: Small, directed entirely to the community's maintenance fund. No fees to Unyt as a platform — Unyt does not require fees to operate.
NDO Integration: Full integration across all three phases. EconomicAgreement governance rules enforce access and service settlement. PPR + RAVE linkage generates reputation. Credit limit derived from PPRs creates the graduation gradient.
Loop dynamics: This is the fully-closed loop archetype. Every element is active: description → observation → settlement → reputation → credit → access → motivation → governance → description. The commons is economically self-sustaining.
6.3 Cooperative Alliance
When to use: Productive communities with shared output and shared revenue; contributors should receive proportional benefit from what they collectively created. Open hardware design communities, fabrication networks, cooperative software projects, distributed manufacturing.
Base Unit: A contribution token tied to a revenue-distribution mechanism. The token is less a currency than an accounting ledger entry — a share in the cooperative's outputs.
Credit limit: Contribution depth. Agents who have produced more (validated commits, design iterations, test fabrications, governance participation) have higher standing and thus higher credit capacity.
Smart Agreements:
Aggregate Paymentwith proportional distribution: each contributor receives a share of revenue proportional to their verified Layer 2 contribution history- Revenue sharing tables managed by governance, updated as the community's understanding of contribution value evolves
Fees: Zero. All economic flows are internal to the cooperative; no platform extraction is appropriate.
NDO Integration: Full integration. The Layer 2 contribution tracking (EconomicEvents, PPRs) feeds directly into Unyt's revenue distribution algorithm. The NDO's observation layer is the distribution basis — there is no separate contribution ledger.
Loop dynamics: The loop here runs most visibly through the governance dimension: as contributors earn revenue shares, they become more invested in governance (they have economic skin in the game), which improves decision-making quality, which improves the product, which generates more revenue, which distributes to contributors — a virtuous cycle.
7. The Reputation-Credit Mechanism
The feedback from reputation to credit is the backbone of the self-sustaining commons. This section specifies it in full.
7.1 ReputationSummary as Credit Input
The NDO's governance zome derives ReputationSummary entries from an agent's accumulated PPRs. The Unyt integration adds one new field to this summary:
#![allow(unused)] fn main() { pub struct ReputationSummary { pub agent: AgentPubKey, pub period_start: Timestamp, pub period_end: Timestamp, // Existing fields pub average_performance_score: f64, // Weighted avg across all PPR categories (0.0-1.0) pub creation_count: u32, // ResourceCreation + ResourceValidation PPRs pub custody_count: u32, // CustodyTransfer + CustodyAcceptance PPRs pub service_count: u32, // Maintenance + Storage + Transport PPRs pub governance_count: u32, // DisputeResolution + ValidationActivity + RuleCompliance PPRs // New field, enabled by Unyt integration pub economic_reliability_score: f64, // Fraction of settlement-required interactions settled // cleanly (RAVE within window, no disputes, no reclaims) // Range: 0.0 (never settled) to 1.0 (always settled) } }
The economic_reliability_score is the economic analogue of the existing quality metrics. It answers the question: when this agent was required to settle economically (access fee, service payment, custody bond), did they follow through? An agent with high quality scores but low economic reliability is a participation risk. An agent with both high quality and high economic reliability is the ideal steward.
This field is 0.0 for all agents before Unyt integration is active (no settlement records exist). It becomes meaningful as soon as an agent begins interacting with economically-governed resources.
7.2 Compute Credit Limit Agreement (RHAI)
The Unyt Alliance's Compute Credit Limit Agreement is a RHAI script that receives the agent's ReputationSummary as input (sourced from the NDO governance zome via cross-DNA call) and produces a credit limit as output.
A reference implementation suitable for the Commons Alliance archetype:
// Inputs provided by Unyt framework:
// reputation (ReputationSummary), config (Alliance Global Config parameters)
let base_credit = config.base_credit_limit;
// Performance multiplier: quality of past interactions
let performance_bonus = base_credit
* reputation.average_performance_score
* config.performance_weight;
// Depth bonuses: breadth and depth of network contribution
let custody_bonus = reputation.custody_count * config.custody_credit_per_event;
let service_bonus = reputation.service_count * config.service_credit_per_event;
let governance_bonus = reputation.governance_count * config.governance_credit_per_event;
// Capacity before reliability adjustment
let capacity = base_credit + performance_bonus
+ custody_bonus + service_bonus + governance_bonus;
// Economic reliability multiplier: agents who settle cleanly get full capacity;
// agents who routinely fail to settle are capped at 50% of earned capacity.
// This is the most important guard against economic free-riding.
let reliability_multiplier = 0.5 + (0.5 * reputation.economic_reliability_score);
capacity * reliability_multiplier
All config.* parameters are set in the Alliance's Global Configuration and can be updated through community governance without modifying the RHAI script. The community tunes the model as it learns what parameter values produce the outcomes it wants.
7.3 The Graduation Gradient
New agents start with base_credit_limit and no bonuses. Their first interactions are therefore constrained — they can access resources with low economic requirements, but not those with high access fees or custody bonds. This is intentional: it protects the commons from agents with no track record.
As agents accumulate PPRs with RAVE linkage, their credit capacity grows continuously:
| Agent standing | Typical credit capacity | Enabled interactions |
|---|---|---|
| New (no PPRs) | Base credit only | Low-cost access; observation; contribution proposals |
| Emerging (5–20 PPRs) | Base + moderate bonuses | Standard access; simple service commitments |
| Established (20+ PPRs, high quality) | Full bonuses | Full access; custody responsibility; complex service chains |
| Senior (50+ PPRs, specialist roles) | Maximum credit | High-value custody; governance weight; inter-alliance bridging |
The gradient is a continuous function, not a hard gate. Agents grow into the commons economically as they demonstrate trustworthiness, reliability, and economic responsibility. The system never stops anyone permanently — it calibrates access to demonstrated track record.
A key property: this system is self-regulating without administrators. No human decides who gets how much credit. The RHAI script is the credit policy; PPRs are the evidence; peers validate both. The community designs the rules (through governance); the algorithm enforces them (through Unyt); the DHT records everything permanently.
8. Economic Governance
The deepest dimension of the Unyt integration is its role in governance. This is not simply about who pays for access. It is about who has the standing to shape the rules, and about making rule-setting itself consequential.
8.1 Smart Agreements as Governance Rules
The NDO's governance model separates governance-as-operator (the governance zome evaluates rules and approves transitions) from the data model (zome_resource stores the rules). Unyt extends this model: Smart Agreements are economic governance rules. They specify not just what may happen, but what must economically flow when it does.
A resource's complete governance constitution therefore has three layers:
- Access rules —
GovernanceRuleentries specifying who may take what action (role requirements, validation requirements, agent tier checks) - Economic rules —
GovernanceRuleentries of typeEconomicAgreementspecifying what must settle before the action is approved - Settlement logic — Unyt Smart Agreement RHAI scripts specifying exactly how value flows when settlement is triggered
Together, these three layers constitute a complete, peer-enforced, cryptographically-guaranteed economic constitution for the resource. No legal system, no platform, no administrator required. The rules are in the DHT; the enforcement is in the validation logic; the settlement is in Unyt. The "governance engine" is the network of peers running the same code.
This is the fullest expression of what ndo_prima_materia.md calls the governance-as-operator architecture: not just governance deciding who can act, but governance specifying the complete economic context of action — including consequences, settlement flows, and redistribution rules.
8.2 Economic Standing as Governance Weight
A commons governance system faces a persistent challenge: how do you weight decision-making authority? Options include one-agent-one-vote (ignores contribution depth), stake-weighted voting (replicates capital concentration), or delegated representation (reintroduces hierarchy).
The Unyt integration offers a fourth option: contribution-weighted governance. Because the NDO's PPR system tracks participation quality and the Unyt integration tracks economic reliability, the ReputationSummary is a natural, continuously-updated, peer-validated measure of an agent's depth of investment in the commons. This can serve as governance weight without requiring any additional infrastructure.
Specific governance applications in the NDO context:
- N-of-M validation schemes: validators for lifecycle transitions (e.g.
Prototype → Stable) can be weighted by their governance PPR count and economic reliability score, ensuring that the most engaged participants have the most influence over quality gates - Dispute resolution authority: access to
DisputeResolutionParticipationPPR roles can require minimum credit standing, ensuring only economically embedded agents serve as dispute resolvers - Economic rule amendments: amendments to
EconomicAgreementgovernance rules (changing payment terms, credit limit parameters) can require supermajority consent from agents above a minimum credit tier, preventing rule changes by agents with no stake in the outcome
These are optional governance configurations — not requirements of the generic NDO. Each NDO instantiation decides which governance weightings make sense for its community.
8.3 Commons Treasury and Protocol Economics
For communities that configure non-zero fees (Commons Alliance, Cooperative Alliance), accumulated fees constitute a commons treasury. Unyt's Service Network mechanism allows this treasury to be managed by a designated steward, a multisig group, or a DAO-style governance process.
The treasury's purpose is to make the commons economically self-sustaining: paying for maintenance and repair of physical infrastructure, funding development of shared digital resources, compensating governance work (validation, dispute resolution, rule-writing), and building bridge deposits for inter-alliance connectivity.
Critically: the treasury's distribution rules are themselves Unyt Smart Agreements — configurable by the community, enforced by Unyt, updatable through governance. No central administrator manages the treasury. The rules manage it.
8.4 Inter-NDO Economic Bridges
When multiple NDO communities (multiple Unyt Alliances) want to connect, Unyt's inter-Alliance bridging mechanism allows value to flow between them. This enables:
- A hardware design commons and a regional fabrication network to exchange credits (design access in exchange for fabrication capacity)
- A tool library and a repair cooperative to share economic infrastructure (repair credits earned by tool library members; tool access earned by repair members)
- A network of local resource-sharing communities to maintain separate identities and governance while exchanging value
At the generic NDO level, inter-community bridging is an Alliance configuration decision. Each Alliance decides whether to enable bridging, with which Alliances, and at what conversion rates. The Layer 0 NDO identity hash provides a stable cross-network reference point — an NDO is always identifiable regardless of which Alliance is processing a transaction involving it.
Unyt's EVM blockchain bridge is the mechanism for communities that need to interface with the conventional monetary economy: paying for insurance, physical storage rent, online services, or participating in markets beyond the peer network. Organisations can lock real-world value (ETH, stablecoins) and mirror it into the commons network as credits; participants can redeem back out when needed.
9. Generic NDO and Nondominium as Instantiation
This section makes the generic/specific distinction concrete — what is part of the reusable NDO infrastructure and what is Nondominium's domain-specific contribution.
9.1 What the Generic NDO Infrastructure Provides (Unyt Layer)
The generic NDO project implements these Unyt integration points at the Holochain level:
UnytAgreement(String)variant in theSlotTypeenumEconomicAgreementvariant in theGovernanceRuleTypeenum withEconomicAgreementRuleDataschemasettlement_rave_hash: Option<String>field onPrivateParticipationClaimeconomic_reliability_score: f64field onReputationSummary- Cross-DNA call interface:
get_reputation_summary(agent, period) -> ReputationSummary - Cross-DNA call interface:
validate_ndo_context(resource_hash, provider, receiver, action) -> ValidationResult - Governance zome extension:
EconomicAgreementrule detection and RAVE validation inevaluate_transition_request
The generic NDO does not implement:
- Any specific Unyt Alliance configuration (currencies, credit algorithms, fee policies)
- Any specific Smart Agreement templates (RHAI scripts)
- Any specific resource domain types or PPR categories
- Any specific governance weight calculations
9.2 What Nondominium Adds as an Instantiation
Nondominium (this project), built on the generic NDO, adds:
- Resource domain types: the specific VfActions (
AccessForUse,TransferCustody, etc.) and four economic processes (Transport, Storage, Repair, Use) - PPR category domain: the 16
ParticipationClaimTypevariants specific to physical resource sharing (see governance zome documentation) - Default Alliance configuration: Commons Alliance archetype, tuned for physical resource sharing economies
- Standard Smart Agreement templates: the four value flow patterns defined in
ndo_prima_materia.mdSection 6.6 (Access Fee, Service Billing, Revenue Sharing, Custody Bond) - Credit limit algorithm: the RHAI script from Section 7.2, with parameter defaults tuned for physical resource stewardship economies
- Role-based credit tiers: mapping SimpleAgent / AccountableAgent / PrimaryAccountableAgent role promotions onto credit gradient thresholds
9.3 The Separation
┌─────────────────────────────────────────────────────────────────┐
│ GENERIC NDO INFRASTRUCTURE │
│ (implements ndo_prima_materia.md + this document's integration layer) │
│ │
│ • Three-layer model (L0, L1, L2) │
│ • Lifecycle state machine │
│ • Capability slot surface (incl. UnytAgreement type) │
│ • GovernanceRule framework (incl. EconomicAgreement type) │
│ • PPR system (incl. settlement_rave_hash, economic_reliability) │
│ • Cross-DNA Unyt call interfaces │
│ • Governance zome RAVE validation │
└──────────────────────┬──────────────────────┬───────────────────┘
│ │
┌──────────▼──────┐ ┌──────────▼──────────────────┐
│ NONDOMINIUM │ │ OTHER NDO INSTANTIATIONS │
│ (this project) │ │ (future) │
│ │ │ │
│ • Resource │ │ • Fabrication network │
│ domain types │ │ • Local currency system │
│ • 16 PPR │ │ • Cooperative enterprise │
│ categories │ │ • Digital commons │
│ • Commons │ │ • Art circulation network │
│ Alliance │ │ • etc. │
│ config │ │ │
└────────┬────────┘ └─────────────────────────────┘
│
┌────────▼────────────────────────────────┐
│ UNYT ALLIANCE (per NDO community) │
│ │
│ • Base Unit (community currency) │
│ • Credit limit RHAI script + params │
│ • Smart Agreement templates │
│ • Fee policy (default: zero) │
│ • Service Networks │
│ • Treasury management │
│ • Inter-alliance bridge config │
└──────────────────────────────────────────┘
10. Integration Path
The integration is structured as four sequential phases. Each phase delivers independent value; none require rollback of prior work.
Phase 1 — NDO Foundation (Generic NDO project; no Unyt deployment needed)
Implement in the generic NDO project at the Holochain level:
UnytAgreement(String)inSlotTypeenumEconomicAgreementinGovernanceRuleTypeenum withEconomicAgreementRuleDataschemasettlement_rave_hash: Option<String>onPrivateParticipationClaimeconomic_reliability_score: f64onReputationSummary(computed as0.0when no RAVE data exists)- Cross-DNA call stubs (return placeholder data until Phase 3)
What this delivers: The generic NDO is structurally Unyt-ready. Any NDO instantiation can inherit these integration points. No Unyt Alliance is required to run. The stubs ensure that zomes compile and pass validation; they just don't execute economic logic yet.
Phase 2 — Alliance Configuration (Per-community, parallel to Phase 1)
Configure Unyt Alliances for communities that want to activate economic settlement:
- Deploy Unyt Sandbox for the community's Alliance
- Define Base Unit (name, symbol, initial supply or mutual credit parameters)
- Configure credit limit algorithm (RHAI script with initial parameters)
- Create standard Smart Agreement templates using the Unyt Smart Agreement Library as starting point
- Set fee policy
- Register Alliance network seed in NDO capability slots (
UnytAgreementTier 1 links)
What this delivers: The Alliance exists and is functional. Agents can use it for voluntary payments and reputation-building before enforcement is active. Economic infrastructure is in place; it runs in parallel with the NDO without being coupled to it yet.
Phase 3 — Enforcement (zome_gouvernance changes)
Implement in the NDO governance zome:
evaluate_transition_requestextended to detectEconomicAgreementgovernance rules- Cross-DNA call to Unyt cell implementing the RAVE validation sequence (Section 5.3)
rave_hashrequirement in transition request payloads for governed resources- PPR generation updated to populate
settlement_rave_hashon valid RAVEs economic_reliability_scorecomputation inReputationSummaryderivation
What this delivers: Full enforcement. Resources with economic terms are now automatically governed by them. The NDO economic loop is closed. A resource without a Unyt agreement is unaffected; a resource with one enforces it peer-to-peer.
Phase 4 — Ecosystem (post-basic integration)
- Inter-Alliance bridging for multi-community NDO networks (bridging configuration in Alliance + NDO discovery via Layer 0 identity hashes)
- Governance weight calculations using
ReputationSummary+economic_reliability_scorefor weighted N-of-M validation and governance participation - Treasury management Smart Agreements for commons maintenance funding
- EVM blockchain bridging for fiat/crypto on-off ramp (for communities requiring interface with the conventional economy)
What this delivers: The NDO network effect. Multiple communities sharing NDO infrastructure, exchanging value across Unyt Alliance bridges, with governance informed by cross-community economic standing.
11. Requirements
11.1 Generic NDO Integration Layer Requirements
- REQ-UNYT-NDO-01: The generic NDO shall implement
UnytAgreement(String)as a namedSlotTypevariant where the String carries the Unyt Alliance network seed identifier. - REQ-UNYT-NDO-02: The generic NDO shall implement
EconomicAgreementas a namedGovernanceRuleTypevariant withEconomicAgreementRuleDataas its structuredrule_dataschema, carryingunyt_alliance_id,smart_agreement_hash,trigger_actions,settlement_window_secs, and optionalnote. - REQ-UNYT-NDO-03: The
PrivateParticipationClaimentry type shall includesettlement_rave_hash: Option<String>. This field shall beNonefor all transitions where noEconomicAgreementrule was triggered. - REQ-UNYT-NDO-04: The
ReputationSummaryderived type shall includeeconomic_reliability_score: f64, computed as the fraction of an agent's settlement-required interactions that were settled cleanly. The value shall be0.0for agents with no settlement history. - REQ-UNYT-NDO-05: The governance zome shall expose a cross-DNA-callable function
get_reputation_summary(agent: AgentPubKey, period: Option<TimePeriod>) -> ReputationSummaryfor use by Unyt's Compute Credit Limit Agreement. - REQ-UNYT-NDO-06: The governance zome shall expose a cross-DNA-callable function
validate_ndo_context(resource_hash: ActionHash, provider: AgentPubKey, receiver: AgentPubKey, action: VfAction) -> ValidationResultfor use by Unyt RAVE input validation. - REQ-UNYT-NDO-07: Cross-DNA call stubs for Unyt interfaces shall be implemented in Phase 1 and shall return placeholder passing results until Phase 3 activates live Unyt connections.
11.2 Alliance Configuration Requirements
- REQ-UNYT-AL-01: Each NDO community activating economic settlement shall configure a Unyt Alliance with at minimum:
unyt_alliance_id,base_credit_limit, aCompute Credit Limit AgreementRHAI script acceptingReputationSummaryas input, and at least one Smart Agreement template matching the community's primary economic interaction patterns. - REQ-UNYT-AL-02: The Alliance's
Compute Credit Limit Agreementshall acceptReputationSummaryas an input parameter, sourced from the NDO governance zome via cross-DNA call. - REQ-UNYT-AL-03: Alliance fee policies shall default to zero. Non-zero fees require explicit community configuration through Alliance governance. No fees to the Unyt platform are mandatory.
- REQ-UNYT-AL-04: Alliance Global Configuration parameters (credit weights, bonus rates, reliability multiplier) shall be independently updatable through community governance, without modifying or redeploying the RHAI credit limit script.
11.3 State Transition Enforcement Requirements
- REQ-UNYT-ENF-01: When the governance zome processes a state transition whose
VfActionmatches atrigger_actionsentry in an endorsedEconomicAgreementgovernance rule, the transition request shall include arave_hash. Requests without a requiredrave_hashshall be rejected with aSettlementRequiredrejection reason. - REQ-UNYT-ENF-02: RAVE validation shall include: (a) retrieval from the Unyt DHT, (b) confirmation of execution within
settlement_window_secs, (c) confirmation that RAVE inputs match the transition context (resource identity, provider, receiver, VfAction, quantity or duration within tolerance). - REQ-UNYT-ENF-03: Approved transitions with valid RAVEs shall generate PPRs with
settlement_rave_hashpopulated for all participating agents. Approved transitions without economic rules shall generate PPRs withsettlement_rave_hash: None. - REQ-UNYT-ENF-04: RAVE validation failures shall produce a
GovernanceTransitionResult::Rejectedwith a specificrejection_reasonindicating the settlement failure (RAVE not found, RAVE expired, context mismatch). The agent may re-execute the Unyt agreement and resubmit the transition request.
11.4 Economic Governance Requirements
- REQ-UNYT-GOV-01: NDO instantiations may optionally use
economic_reliability_scoreand PPR category counts as weights in N-of-M validation schemes. The generic NDO shall expose these through its governance query API without mandating their use. - REQ-UNYT-GOV-02: Amendments to
EconomicAgreementgovernance rules shall require authorization by the role defined in the rule'senforced_byfield, consistent with the governance-as-operator architecture (REQ-ARCH-07). - REQ-UNYT-GOV-03: The credit limit graduation gradient (base credit, bonus parameters, reliability multiplier) shall be community-configurable via Alliance Global Configuration parameters. Hard-coded credit tiers in the generic NDO code are not permitted.
- REQ-UNYT-GOV-04: An NDO resource that has no endorsed
EconomicAgreementgovernance rule shall be fully accessible according to its non-economic governance rules alone. Unyt integration shall be invisible and non-blocking for resources that have not opted into it.
This document is post-MVP. It describes the integration of Unyt as the economic settlement layer for the generic NDO primitive. The generic NDO project (implementing ndo_prima_materia.md as a standalone hApp) has not yet begun. When it is created, Nondominium (this project) will migrate to it as one instantiation, inheriting the Unyt integration layer described here. The integration path in Section 10 applies to the generic NDO project first, and to Nondominium thereafter.
Flowsta Integration: Cross-App Identity and Authentication for the NDO
Status: Post-MVP Design Document
Created: 2026-03-24
Authors: Nondominium project
Relates to: ndo_prima_materia.md, unyt-integration.md, documentation/archives/resources.md, documentation/archives/agent.md, documentation/archives/governance.md
Table of Contents
- Purpose and scope
- Rationale: why Flowsta, why a capability
- How Flowsta entered the foundational documents
- Architecture summary
- Relationship to Unyt and the prima materia
- Integration path (three phases)
- Requirements traceability
- Current MVP vs planned enforcement
1. Purpose and scope
This document is the dedicated specification stub for integrating Flowsta — decentralized identity and authentication for Holochain apps (Vault, agent linking, W3C DIDs) — with the Nondominium Object (NDO) and the Nondominium hApp.
It serves three functions:
- Narrative home — explains the initial rationale for choosing Flowsta-shaped integration (cross-app identity, recovery, optional governance enforcement) in one place.
- Cross-document index — records where that rationale and mechanics were first woven into the project’s archive knowledge base (
resources.md,agent.md,governance.md) and the normative requirements (ndo_prima_materia.md). - Implementation pointer — aligns engineering work with REQ-NDO-CS-12 through REQ-NDO-CS-15, REQ-NDO-AGENT-07 / REQ-NDO-AGENT-08, and
ndo_prima_materia.mdSection 6.7 / Section 11.6.
Detailed cryptographic payloads, zome API listings, and UI copy should grow here over time; the authoritative structural spec remains ndo_prima_materia.md Section 6.7 until this file absorbs lower-level detail.
2. Rationale: why Flowsta, why a capability
2.1 Problems the NDO leaves open
The MVP NDO stack assumes long-lived Holochain signing keys and local-to-DHT reputation:
Personentries and PPRs are designed for permanence and auditability, but there is no deterministic key recovery in the core DNA: device loss can strand an agent from their source chain and private data.- Roles, PPR-derived
ReputationSummary, and governance standing are not portable across other Holochain apps unless additional infrastructure provides a verifiable same-person link. - Multi-network participants (bridge nodes between OVNs or hApps) face repeated cold-start trust and sybil pressure at every network boundary if each conductor treats them as a unrelated keypair.
These gaps show up explicitly in the archive gap tables (e.g. resources.md §2.4, agent.md §2.6, governance.md §2.8).
2.2 Capability, not a mandatory layer
Cross-app identity must not be hard-coded as a third structural pillar or a registration gate on every agent. That would violate complexity-oriented programming (COP) and pay-as-you-grow: many communities only need AgentPubKey and local PPRs.
Flowsta is therefore integrated as an optional capability, parallel to Unyt:
- Unyt answers who owes what to whom (settlement, RAVE, economic closure).
- Flowsta answers who is who (DID, dual-signed linking, Vault recovery).
Communities may adopt one, both, or neither. Attachment is stigmergic: agents and custodians opt in through capability slots and (when desired) governance rules.
2.3 What Flowsta adds in one sentence
Flowsta provides Vault-mediated dual-signed IsSamePersonEntry attestations on the NDO DHT, a FlowstaIdentity capability slot on the agent’s Person entry hash pointing at that attestation, W3C DIDs for cross-app reference, and BIP39 / backup / CAL-aligned export for operational resilience — without changing the Person schema.
3. How Flowsta entered the foundational documents
The same design was introduced consistently but with document-specific emphasis: resources emphasize access and asset governance; agents emphasize identity and portability; governance emphasizes Tier 2 rules and the governance-as-operator path.
3.1 documentation/archives/resources.md
- Header:
flowsta-integration.mdadded to Relates to. - §2.4 Known gaps: rows for no cross-app identity / DID and no agent key recovery, with Flowsta as the planned mitigation (
ndo_prima_materia.mdSection 6.7). - §3.8 Flowsta Integration: roadmap summary —
FlowstaIdentityonPerson, two tiers, Vault recovery, PPR attribution to DID. - §4.5 Accessibility credentials: FlowstaIdentity-based dimension; Tier 1 voluntary link vs Tier 2 governance requirement (REQ-NDO-CS-14 / CS-15, Flowsta Phase 3).
- §4.6 Transferability: clarifies attribution portability (via DID) ≠ claim transferability (
PrivateParticipationClaimremains bound to local keys). - §5.1 / §5.3: mapped planned rows and cross-app identity verification gap row.
- §6.6 (governance defaults TODO): two bullets — Tier 1 (Flowsta Phase 1; REQ-NDO-CS-12/CS-13) without Affiliation/ZKP infrastructure; Tier 2 (Flowsta Phase 3; REQ-NDO-CS-14/CS-15) for governance-enforced linking — distinct from AffiliationState / PortableCredential / ZKP dimensions.
3.2 documentation/archives/agent.md
- Header:
flowsta-integration.mdin Relates to. - §2.6: OVN-framed gap rows for cross-app identity and deterministic recovery.
- §3.2 CapabilitySlot on Agent Identity: Flowsta Auth as first concrete implementation —
FlowstaIdentity→IsSamePersonEntry, DID, forward reference to §3.5; pattern defined inndo_prima_materia.mdSection 6.5 (Person surface) and Section 6.7 (Flowsta). - §3.4 Credential portability: Flowsta DID as cross-app anchor for attributing
ReputationSummary; complements NDO-nativePortableCredentialforward design in this file, Section 6.5 (not prima materia §6.5 — that section is the Person attachment surface inndo_prima_materia.md). - §3.5 Flowsta Integration: agent linking zomes, Tier 1 / Tier 2 and Phase 1 / Phase 3, Vault, OAuth-only vs Vault path; pointers to
ndo_prima_materia.md6.7, 11.6, andresources.md§3.8. - §4.4 Identity architecture: near-term Flowsta bridge vs longer-term ZKP/VC depth; REQ-NDO-AGENT-08.
- §5.1–5.3: planned rows; portability and credential/sybil rows extended with Flowsta complements.
- §6.3
AgentProfile/ §6.5PortableCredential: forward-design sketch and portable-credential note tying issuers to Flowsta DID when aFlowstaIdentityslot exists. - §7: complexity economics — bridge nodes, Tier 1 vs Tier 2 and Bar-Yam-style matching.
3.3 documentation/archives/governance.md
- Header:
flowsta-integration.mdand cross-links to other archives. - §1.2: stigmergy extended to agent
Personhash and Tier 1 vs Tier 2 (Flowsta Phase 3 for Tier 2). - §2.8: gap row for governance-enforced cross-app identity; sybil row notes Flowsta Tier 2 as complement to vouching/PoP.
- §3.2 → §3.7: Unyt subsection bridges to §3.7 Flowsta Integration — Identity Verification Governance: parallel UnytAgreement / EconomicAgreement / RAVE vs FlowstaIdentity / IdentityVerification /
IsSamePersonEntry; REQ-NDO-CS-12–15; plannedevaluate_transition_requestalignment; MVP reality (GovernanceRuleas strings;validate_agent_for_promotion/validate_agent_for_custodianshipwithout Flowsta today). - §3.3 / §3.5 / §4.1 / §4.4 / §4.7 / §5.1 / §5.3 / §6.4 / §7: typed rules, mapped rows, sybil resolution, weight function, complexity — all aligned with IdentityVerification and Flowsta tiers.
- Closing note:
ndo_prima_materia.md§§6.6–6.7 and §§11.5–11.6 traceability.
Together, these documents implement a single architectural story: permissionless discovery (Tier 1), optional hard enforcement (Tier 2), and clear separation from economic closure (Unyt).
4. Architecture summary
The following is a condensed restatement of ndo_prima_materia.md Section 6.7; see there for diagrams and full prose.
| Element | Role |
|---|---|
Person entry hash | Agent identity anchor; target for FlowstaIdentity CapabilitySlot links (REQ-NDO-AGENT-07). |
flowsta-agent-linking zomes | Integrity + coordinator zomes in the DNA manifest; commit IsSamePersonEntry (dual-signed 78-byte payload: NDO agent key + Flowsta Vault key). |
FlowstaIdentity slot | Tier 1: any agent may link their Person hash to an IsSamePersonEntry action hash (REQ-NDO-CS-12, REQ-NDO-CS-13). |
| W3C DID | e.g. did:flowsta:uhCAk... (or did:key:...) — cross-app stable identifier. |
IdentityVerification governance rule | Tier 2: conditions high-trust transitions (e.g. PrimaryAccountableAgent promotion, high-value custody) on REQ-NDO-CS-15 checks (REQ-NDO-CS-14). |
| Revocation | revoke_link on the Flowsta coordinator; Tier 2 validation must treat revoked links as invalid. |
| PPR / reputation | With a valid Tier 1 link, ReputationSummary is attributable to a DID; PortableCredential interoperability is anchored by the same DID (REQ-NDO-AGENT-08). |
OAuth-only path (@flowsta/auth): convenient DID for web contexts while the app keeps separate Holochain keys; the Vault path is what produces IsSamePersonEntry on the NDO DHT (Flowsta docs “Option 1” vs “Option 2” — summarized in agent.md §3.5).
5. Relationship to Unyt and the prima materia
- Prima materia Section 6.6 (Unyt) and Section 6.7 (Flowsta) are parallel two-tier models: slot (discoverable) + endorsed
GovernanceRule(enforceable). - Section 11.5 (Unyt) and Section 11.6 (Flowsta) situate both in the Relationship to Other Post-MVP Work matrix.
- When both are active, a Flowsta DID can anchor cross-app attribution of reputation signals that also feed Unyt credit and governance-weight narratives (see
governance.md§3.5 and prima Section 6.7, Flowsta and Unyt).
6. Integration path (three phases)
Aligned with ndo_prima_materia.md Section 6.7:
| Phase | Focus | Outcome |
|---|---|---|
| 1 | Capability surface + DNA | FlowstaIdentity in SlotType; flowsta-agent-linking zomes; SDK wiring; Tier 1 linking without governance enforcement. |
| 2 | Frontend / UX | Link Flowsta flows, DID display, badges, Vault backup APIs (startAutoBackup, backupToVault, etc.). |
| 3 | Governance zome | IdentityVerification (or equivalent) in typed governance rules; transition evaluation validates REQ-NDO-CS-15; complements Unyt Phase 3-style evaluate_transition_request extensions. |
Phases are independent and cumulative — no rollback of earlier phases required.
7. Requirements traceability
| ID | Summary |
|---|---|
| REQ-NDO-CS-12 | FlowstaIdentity in SlotType; link target is IsSamePersonEntry from Flowsta coordinator. |
| REQ-NDO-CS-13 | Tier 1: any agent may attach slot on own Person hash; no extra governance requirement beyond standard capability governance (REQ-NDO-CS-03). |
| REQ-NDO-CS-14 | Governance supports IdentityVerification (or equivalent) conditioning promotions / high-value transitions on verified slot. |
| REQ-NDO-CS-15 | Tier 2 verification: slot exists; IsSamePersonEntry includes requestor AgentPubKey; not revoked. |
| REQ-NDO-AGENT-07 | Person hash as capability surface; Flowsta as first concrete implementation. |
| REQ-NDO-AGENT-08 | Portable credentials; Flowsta DID as cross-network identity anchor when combined with FlowstaIdentity. |
8. Current MVP vs planned enforcement
As of the Nondominium MVP codebase:
GovernanceRuleinzome_resourceis now the typedrule_data: RuleDataenum (#132), but its four variants areAccessRequirement,UsageLimit,TransferCondition, andMaintenanceSchedule: there is noIdentityVerificationvariant, and Flowsta zomes are not part of the shipped DNA unless explicitly added in a future milestone.zome_gouvernanceexposes flows such asvalidate_agent_for_promotionandvalidate_agent_for_custodianshipfor private-field validation, not for FlowstaIdentityVerification.
Therefore Tier 2 and Phase 3 are specified and documented but not yet implemented in WASM. This document and the archive sections describe target behavior; governance.md §3.7 states the folding of identity checks into unified transition evaluation explicitly.
For OVN-scale motivation (bridge nodes, governance equation, holonic layers), see documentation/archives/agent.md, documentation/archives/governance.md, and documentation/archives/resources.md in the sections cited above.
nondominium - Technical Specifications
1. Introduction
1.1 Purpose
This document provides the detailed technical specifications for the nondominium Holochain application (hApp). It is based on the requirements outlined in requirements.md and the architecture described in other nondominium project documents. It is intended for Holochain developers.
1.2 Guiding Principles
- Valueflows Compliance: Data structures will adhere to the Valueflows standard.
- Agent-Centricity: All data is created and validated from the perspective of the individual agent.
- Capability-Based Security: Access and permissions will be managed through Holochain's capability token mechanism.
2. Holochain DNA and Zome Structure
As per the project's architectural description, the hApp will be composed of three distinct zomes. This separation of concerns will enhance modularity and clarity.
zome_person: Handles agent identity, profiles, and roles.zome_resource: Manages the lifecycle of Economic Resources and their Specifications.zome_governance: Implements the logic for Commitments, Claims, and other governance-related actions.
3. Governance-as-Operator Architecture Overview
3.1 Architecture Principle
The nondominium system implements a governance-as-operator architecture where:
- Resource Zome operates as a pure data model responsible for resource specifications, economic resources, and data persistence
- Governance Zome operates as a state transition operator responsible for evaluating governance rules, validating state changes, and generating economic events
This separation enables independent evolution of data structures and governance rules while maintaining clear interfaces and responsibilities.
3.2 Cross-Zome Interface
Implementation status (2026-08-29, post-#132).
GovernanceTransitionRequest,TransitionContext, andGovernanceTransitionResultare defined incrates/shared/src/io/governance.rs, andevaluate_state_transitionis live inzome_gouvernance/src/transition.rs.request_resource_transitiondoes not exist: the resource zome does not yet call into this path, so evaluation runs parallel and advisory alongsidepropose_commitment/log_economic_eventrather than as the mandatory funnel. Treat the request side of this document as the design target, not current behaviour. Status:documentation/IMPLEMENTATION_STATUS.md§ Governance-as-Operator Architecture.
The primary interface between zomes follows the governance operator pattern:
#![allow(unused)] fn main() { // Resource zome requests state transition (design target — not yet in code) #[hdk_extern] pub fn request_resource_transition( request: GovernanceTransitionRequest, ) -> ExternResult<GovernanceTransitionResult>; // Governance zome evaluates and decides #[hdk_extern] pub fn evaluate_state_transition( request: GovernanceTransitionRequest, ) -> ExternResult<GovernanceTransitionResult>; }
3.3 Data Flow Pattern
- State Change Request: Resource zome receives agent request
- Governance Evaluation: Cross-zome call to governance zome for decision
- State Application: Resource zome applies approved changes
- Event Generation: Economic events generated for audit trail
4. Data Structures (Integrity Zome Entries)
4.1. zome_person Entries
4.1.1. AgentProfile
Stores public-facing information about an agent.
- Fields:
agent_pub_key: AgentPubKey: The public key of the agent.name: String: The agent's chosen public name/pseudonym.avatar_url: Option<String>
- Links:
AllAgents -> AgentProfile: Anchor for discovering all agent profiles.
3.1.2. PrivateProfile
- Description: Stores an agent's private Personal Identifiable Information (PII) as a Holochain private entry in the agent's source chain. The agent can grant access to this data on a case-by-case basis (see https://developer.holochain.org/build/entries/).
private_data: ...(fields like legal name, address, email, photo ID hash)- Links:
AgentProfile -> PrivateProfile: Links the public profile to the private data.
3.1.3. Role
Defines a specific role an agent can have (e.g., User, Repair, Transport, Storage).
- Fields:
role_name: Stringvalidated_by: Option<AgentPubKey>: The Accountable or Primary Accountable Agent who validated the role assignment (fulfills REQ-GOV-06).validation_receipt: Option<ActionHash>: Link to the ValidationReceipt for this role assignment.
- Links:
AgentProfile -> Role: Assigns a role to an agent. This link's tag could hold validation info (e.g., who validated the role).
4.2. zome_resource Entries
3.2.1. ResourceSpecification
A template for a class of resources.
- Fields:
name: Stringdescription: Stringcategory: Stringimage_url: Option<String>tags: Vec<String>is_active: boolscope: ResourceScope:Project|Network|Public— discovery visibility (mutable)ndo_identity_hash: ActionHash: immutable pointer to the Layer 0NondominiumIdentitythis spec activatesndo_state_hash: ActionHash: the NDO action the author observed at activation, resolved backward by validation
- Links:
AllResourceSpecifications -> ResourceSpecification: Anchor for discovery (Projectscope skips it).NdoToSpecification: Layer 0 identity -> this spec. Creating it is Layer 1 activation (REQ-NDO-L1-01).SpecificationToGovernanceRule -> GovernanceRule: rules are separate entries, not an embedded vector.
3.2.2. GovernanceRule
A rule embedded within a ResourceSpecification that defines how resources can be accessed and managed.
- Fields:
rule_data: RuleData: tagged enum —AccessRequirement|UsageLimit|TransferCondition|MaintenanceSchedule, each with a typed payload.GovernanceRuleTypeis derived from the discriminant, never stored.enforced_by: Option<String>: Role required to enforce this rulendo_identity_hash: ActionHash: Layer 0 pointer, required for constraint evaluationproperty_regime: PropertyRegime,resource_nature: ResourceNature: denormalized from Layer 0 so validation needs no DHT readrivalry_override: Option<Rivalry>: overrides the rivalry implied by the regime
3.2.3. EconomicResource
A concrete instance of a resource.
- Fields:
conforms_to: ActionHash: Link to theResourceSpecification.quantity: f64unit: Stringcustodian: AgentPubKey: The Primary Accountable Agent holding the resource.
- Links:
ResourceSpecification -> EconomicResource: Find all resources of a type.AgentProfile -> EconomicResource(as Custodian): Link to the agent currently holding it. Tag: "custodian".
3.2.4. EconomicProcess
Represents structured activities that transform Economic Resources or provide ecosystem services in the nondominium network.
-
Fields:
process_type: String: The type of process ("Use", "Transport", "Storage", "Repair")name: String: Human-readable name for the process instancedescription: Option<String>: Optional description of the specific processrequired_role: String: Agent role required to initiate this processinputs: Vec<ActionHash>: Links to EconomicResources that are inputs to the processoutputs: Vec<ActionHash>: Links to EconomicResources that are outputs from the processstarted_by: AgentPubKey: Agent who initiated the processstarted_at: Timestamp: When the process was initiatedcompleted_at: Option<Timestamp>: When the process was completed (None if ongoing)location: Option<String>: Physical or logical location where process occursstatus: ProcessStatus: Current status of the process
-
Links:
AllEconomicProcesses -> EconomicProcess: Discovery anchor for all processesAgentProfile -> EconomicProcess: Processes initiated by an agentEconomicResource -> EconomicProcess: Link resources to processes that use themEconomicProcess -> EconomicEvent: Events that occur within a process
3.2.5. ProcessStatus
Enumeration representing the current state of an Economic Process.
- Values:
Planned: Process is planned but not yet startedInProgress: Process is currently activeCompleted: Process has finished successfullySuspended: Process is temporarily pausedCancelled: Process was cancelled before completionFailed: Process failed to complete successfully
3.3. zome_governance Entries
3.3.1. EconomicEvent
Records a consummated action on a resource.
- Fields:
action: VfAction: ValueFlows action enum (e.g., Transfer, Use, Produce, InitialTransfer, AccessForUse, TransferCustody)provider: AgentPubKeyreceiver: AgentPubKeyresource_inventoried_as: ActionHash: Link to theEconomicResourceaffects: ActionHash: Link to theEconomicResourcethat is affectedresource_quantity: f64: Quantity of resource affected by the eventevent_time: Timestamp: When the event occurrednote: Option<String>: Optional notes about the event
- Links:
EconomicResource -> EconomicEvent: History of events for a resourceEconomicProcess -> EconomicEvent: Events that occur within a process context
3.3.2. Commitment
An intention to perform an EconomicEvent.
- Fields:
action: VfAction: The intended ValueFlows action (e.g., AccessForUse, Transfer, Use)provider: AgentPubKeyreceiver: AgentPubKeyresource_inventoried_as: Option<ActionHash>: Link to specific resource if applicableresource_conforms_to: Option<ActionHash>: Link to ResourceSpecification if generalinput_of: Option<ActionHash>: Optional link to an EconomicProcessdue_date: Timestampnote: Option<String>: Optional commitment notescommitted_at: Timestamp: When the commitment was made
- Links:
AgentProfile -> Commitment: Agent's outgoing/incoming commitmentsEconomicProcess -> Commitment: Commitments related to a process
3.3.3. Claim
Fulfills a Commitment (public governance record).
- Fields:
fulfills: ActionHash: Link to theCommitmentfulfilled_by: ActionHash: Link to the resultingEconomicEventclaimed_at: Timestamp: When the claim was creatednote: Option<String>: Optional notes about the claim fulfillment
- Links:
Commitment -> Claim: Shows a commitment has been actioned
- Note: This is the public governance record. Private Participation Receipts (PPRs) are generated alongside Claims to track reputation privately.
3.3.4. ValidationReceipt
Records validation of resources, events, or agent promotions by Accountable Agents.
- Fields:
validator: AgentPubKey: The agent performing the validationvalidated_item: ActionHash: Link to the item being validated (Resource, Event, Role, or Agent promotion)validation_type: String: e.g., "resource_approval", "process_validation", "identity_verification", "role_assignment", "agent_promotion"approved: bool: Whether the validation was approved or rejectednotes: Option<String>: Optional validation notes
- Links:
ValidatedItem -> ValidationReceipt: Track all validations for an item
3.3.5. ResourceValidation
Tracks the overall validation status of a resource requiring peer review.
- Fields:
resource: ActionHash: Link to theEconomicResourcebeing validatedvalidation_scheme: String: e.g., "2-of-3", "simple_majority"required_validators: u32: Number of validators neededcurrent_validators: u32: Number of validators who have respondedstatus: String: "pending", "approved", "rejected"
- Links:
EconomicResource -> ResourceValidation: One validation per resource
3.3.6. PrivateParticipationClaim (Private Entry)
A cryptographically signed receipt stored as a private entry that extends the ValueFlows Claim structure to track agent reliability and form the foundation for the reputation system.
-
Fields:
fulfills: ActionHash: Link to the Commitment fulfilled (standard ValueFlows)fulfilled_by: ActionHash: Link to the resulting EconomicEvent (standard ValueFlows)claimed_at: Timestamp: When the claim was created (standard ValueFlows)claim_type: ParticipationClaimType: Type of participation being claimedcounterparty: AgentPubKey: The other agent involved in the bi-directional receiptperformance_metrics: PerformanceMetrics: Quantitative measures of performancebilateral_signature: CryptographicSignature: Cryptographic proof of mutual agreementinteraction_context: String: Context of the interaction (e.g., "resource_creation", "custody_transfer", "maintenance_service")role_context: Option<String>: Specific role context if applicable (e.g., "Transport", "Repair", "Storage")resource_reference: Option<ActionHash>: Link to the resource involved in the interaction
-
Privacy: Stored as Holochain private entry accessible only to the owning agent
-
Links: None (private entries are not linked in DHT for privacy preservation)
3.3.7. ParticipationClaimType
Enumeration defining the types of participation claims that can be issued.
- Values:
ResourceContribution: Receipt for successfully creating and getting a resource validatedNetworkValidation: Receipt for performing validation dutiesResponsibleTransfer: Receipt for properly transferring resource custodyCustodyAcceptance: Receipt for accepting resource custody responsiblyServiceCommitmentAccepted: Receipt for accepting a service commitmentGoodFaithTransfer: Receipt for transferring resource in good faith for serviceServiceFulfillmentCompleted: Receipt for completing a service successfullyMaintenanceFulfillment: Receipt for completing maintenance serviceStorageFulfillment: Receipt for completing storage serviceTransportFulfillment: Receipt for completing transport serviceEndOfLifeDeclaration: Receipt for declaring resource end-of-lifeEndOfLifeValidation: Receipt for validating resource end-of-lifeDisputeResolutionParticipation: Receipt for constructive dispute resolution participationGovernanceCompliance: Receipt for consistent adherence to governance protocols
3.3.8. PerformanceMetrics
Quantitative measures of agent performance in economic interactions.
- Fields:
timeliness_score: f64: How promptly the agent fulfilled commitments (0.0-1.0)quality_score: f64: Quality of service provided (0.0-1.0)reliability_score: f64: Consistency and dependability (0.0-1.0)communication_score: f64: Effectiveness of communication (0.0-1.0)completion_rate: f64: Percentage of commitments successfully completedresource_condition_maintained: Option<bool>: Whether resource condition was maintained (for service roles)additional_metrics: Option<String>: JSON-encoded additional context-specific metrics
3.3.9. CryptographicSignature
Cryptographic proof of mutual agreement between agents in bi-directional receipt issuance.
- Fields:
signer: AgentPubKey: Agent who created the signaturesignature: Signature: Cryptographic signature of the receipt datasigned_data_hash: ActionHash: Hash of the data that was signedsignature_algorithm: String: Algorithm used for signing (e.g., "Ed25519")created_at: Timestamp: When the signature was created
3.3.10. ReputationSummary
Aggregated reputation metrics derived from an agent's Private Participation Claims.
- Fields:
agent: AgentPubKey: The agent whose reputation is summarizedtotal_interactions: u32: Total number of completed economic interactionsaverage_timeliness: f64: Average timeliness score across all interactionsaverage_quality: f64: Average quality score across all interactionsaverage_reliability: f64: Average reliability score across all interactionsaverage_communication: f64: Average communication score across all interactionscompletion_rate: f64: Overall percentage of commitments successfully completedrole_performance: std::collections::HashMap<String, RolePerformance>: Performance breakdown by rolerecent_activity: Vec<RecentInteraction>: Summary of recent interactions (last 30 days)calculated_at: Timestamp: When this summary was calculated
3.3.11. RolePerformance
Performance metrics for a specific role.
- Fields:
role_name: String: The role (e.g., "Transport", "Repair", "Storage")interaction_count: u32: Number of interactions in this roleaverage_performance: f64: Average performance score for this rolespecialization_score: f64: How specialized/expert the agent is in this rolelast_activity: Timestamp: Most recent activity in this role
3.3.12. RecentInteraction
Summary of a recent economic interaction for reputation display.
- Fields:
interaction_type: String: Type of interaction (e.g., "custody_transfer", "repair_service")counterparty: AgentPubKey: The other agent involvedperformance_score: f64: Overall performance in this interactioninteraction_date: Timestamp: When the interaction occurredresource_involved: Option<ActionHash>: Resource that was involved, if applicable
3.3.13. ProcessValidationRequirements
Defines validation requirements for a specific Economic Process type.
- Fields:
process_type: String: The type of process (e.g., "Use", "Transport", "Repair", "Storage")required_role: Option<String>: Role required to initiate this processminimum_validators: u32: Minimum number of validators requiredvalidation_scheme: String: Validation scheme to use (e.g., "simple_majority", "2-of-3")completion_validation_required: bool: Whether completion needs separate validationperformance_thresholds: PerformanceThresholds: Minimum performance thresholdsspecial_requirements: Vec<String>: Any special requirements for this process type
3.3.14. PerformanceThresholds
Minimum performance thresholds for process validation.
- Fields:
minimum_timeliness: f64: Minimum acceptable timeliness scoreminimum_quality: f64: Minimum acceptable quality scoreminimum_reliability: f64: Minimum acceptable reliability scoreminimum_communication: f64: Minimum acceptable communication scoreminimum_completion_rate: f64: Minimum acceptable completion rate
5. Cross-Zome Interface Types
5.1 Governance Transition Request
Interface for requesting state changes from the governance zome:
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct GovernanceTransitionRequest { /// The action the requesting agent wants to perform pub action: VfAction, /// Current state of the resource being modified pub resource: EconomicResource, /// Agent requesting the state change pub requesting_agent: AgentPubKey, /// Additional context for the transition pub context: TransitionContext, } }
5.2 Transition Context
Additional context information for state transitions:
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct TransitionContext { /// Target location for transport/move actions pub target_location: Option<String>, /// Quantity change for produce/consume actions pub quantity_change: Option<f64>, /// Target custodian for transfer actions pub target_custodian: Option<AgentPubKey>, /// Process notes and observations pub process_notes: Option<String>, /// Associated economic process if applicable pub process_context: Option<ActionHash>, } }
5.3 Governance Transition Result
Result structure returned by the governance zome:
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug)] pub struct GovernanceTransitionResult { /// Whether the transition was approved pub success: bool, /// Updated resource state (if approved) pub new_resource_state: Option<EconomicResourceView>, /// Reserved for when event generation is wired; currently always None on this path. pub economic_event_hash: Option<ActionHash>, /// Detailed reasons for rejection (if applicable) pub rejection_reasons: Option<Vec<String>>, /// Required next steps or additional validation needed pub next_steps: Option<Vec<String>>, /// Soft constraint violations — non-blocking advisory feedback pub advisory_warnings: Option<Vec<String>>, /// Soft violations in structured form, for UI dry-run parity pub soft_violations: Option<Vec<ConstraintViolation>>, } }
6. Zome Functions (Coordinator Zomes)
4.1. zome_person Functions
create_profile(name: String, avatar: Option<String>, private_profile: ...) -> Recordget_my_profile() -> (Record, Record)get_agent_profile(agent: AgentPubKey) -> Option<Record>assign_role(agent: AgentPubKey, role: String) -> ActionHash(Requires validation by Accountable Agent; for specialized roles, must follow REQ-GOV-06 validation process)promote_agent_to_accountable(simple_agent: AgentPubKey, private_profile_hash: ActionHash) -> ValidationReceipt: Promotes a Simple Agent to Accountable Agent status after successful validation (REQ-GOV-08).get_my_participation_claims() -> Vec<PrivateParticipationClaim>: Returns all private participation receipts for the calling agent.- Capability:
general_access
- Capability:
get_reputation_summary() -> ReputationSummary: Calculates and returns aggregated reputation metrics based on participation claims.- Capability:
general_access
- Capability:
get_participation_claims_by_type(claim_type: ParticipationClaimType) -> Vec<PrivateParticipationClaim>: Returns participation claims filtered by type.- Capability:
general_access
- Capability:
4.2. zome_resource Functions
create_resource_specification(input: ResourceSpecificationInput) -> CreateResourceSpecificationOutput: Activates Layer 1 — creates the spec, its nested typedGovernanceRuleentries, and theNdoToSpecificationlink. FulfillsREQ-GOV-06andREQ-NDO-L1-01.- Capability:
restricted_access(Only Accountable Agents can define new resource types)
- Capability:
create_economic_resource(spec_hash: ActionHash, quantity: f64, unit: String) -> Record: Creates a new Economic Resource. This is the first step for a Simple Agent (REQ-USER-S-05). Automatically triggers validation process (REQ-GOV-02).- Capability:
general_access
- Capability:
get_all_resource_specs() -> Vec<Record>: Discovery function for all resource specifications.- Capability:
general_access
- Capability:
get_resources_by_spec(spec_hash: ActionHash) -> Vec<Record>: Filtered discovery by specification.- Capability:
general_access
- Capability:
get_my_resources() -> Vec<Record>: Returns resources where the calling agent is the custodian.- Capability:
general_access
- Capability:
transfer_custody(resource_hash: ActionHash, new_custodian: AgentPubKey) -> Record: Transfers custody and creates anEconomicEventvia cross-zome call tozome_governance. Enforces governance rules (REQ-GOV-07).- Capability:
restricted_access
- Capability:
check_first_resource_requirement(agent: AgentPubKey) -> bool: Checks if an agent has created at least one resource. FulfillsREQ-GOV-01.- Capability:
general_access
- Capability:
initiate_economic_process(process_type: String, resource_hashes: Vec<ActionHash>, location: Option<String>) -> Record: Initiates an Economic Process (Use, Transport, Storage, Repair). Validates agent has required role for the process type.- Capability:
restricted_access(Role-gated: requires specific credentials for Transport, Repair, Storage)
- Capability:
complete_economic_process(process_hash: ActionHash, output_resources: Vec<ActionHash>) -> Record: Completes an Economic Process and records any resource changes.- Capability:
restricted_access
- Capability:
get_active_processes() -> Vec<Record>: Returns all active processes initiated by the calling agent.- Capability:
general_access
- Capability:
get_process_by_resource(resource_hash: ActionHash) -> Vec<Record>: Returns all processes that have used a specific resource.- Capability:
general_access
- Capability:
4.3. zome_governance Functions
propose_commitment(action: VfAction, resource_hash: ActionHash, provider: AgentPubKey, due: Timestamp) -> Record: Creates a future intention to act on a resource.- Capability:
restricted_access
- Capability:
accept_commitment(commitment_hash: ActionHash) -> Record: Accepts a proposed commitment.- Capability:
restricted_access
- Capability:
claim_commitment(commitment_hash: ActionHash, resource_id: ActionHash) -> Record: Fulfills a commitment and creates the correspondingEconomicEvent.- Capability:
restricted_access
- Capability:
log_initial_transfer(resource_hash: ActionHash, receiver: AgentPubKey, quantity: f64) -> Record: A simplified function for aSimple Agent's first transaction (REQ-USER-S-07). This triggers the validation process for Simple Agent promotion (REQ-GOV-02).- Capability:
general_access
- Capability:
validate_new_resource(resource_hash: ActionHash, validation_scheme: String) -> ValidationReceipt: Peer-validates a newly created Resource. FulfillsREQ-USER-A-07andREQ-GOV-02. Supports configurable validation schemes (REQ-GOV-04).- Capability:
restricted_access
- Capability:
validate_process_event(event_hash: ActionHash) -> ValidationReceipt: Validates an event related to a core process (e.g., Storage, Repair). FulfillsREQ-USER-A-08andREQ-GOV-05.- Capability:
restricted_access
- Capability:
validate_agent_identity(simple_agent: AgentPubKey, private_profile_hash: ActionHash) -> ValidationReceipt: Validates a Simple Agent's identity information and their first resource transfer, potentially promoting them to Accountable Agent status. Full validation requires access to the agent's private entry. Fulfills REQ-GOV-08.- Capability:
restricted_access
- Capability:
check_validation_status(resource_hash: ActionHash) -> ResourceValidation: Returns the current validation status of a resource.- Capability:
general_access
- Capability:
get_validation_history(item_hash: ActionHash) -> Vec<ValidationReceipt>: Returns all validation receipts for a given item.- Capability:
general_access
- Capability:
validate_process_completion(process_hash: ActionHash) -> ValidationReceipt: Validates that an Economic Process was completed according to its specifications and governance rules.- Capability:
restricted_access
- Capability:
get_process_validation_requirements(process_type: String) -> ProcessValidationRequirements: Returns the validation requirements for a specific process type.- Capability:
general_access
- Capability:
issue_participation_receipts(commitment_hash: ActionHash, event_hash: ActionHash, counterparty: AgentPubKey, performance_metrics: PerformanceMetrics) -> (ActionHash, ActionHash): Issues bi-directional Private Participation Claims for both agents involved in an economic interaction. Returns the action hashes of both receipts.- Capability:
restricted_access
- Capability:
sign_participation_claim(claim_hash: ActionHash, signature: CryptographicSignature) -> Record: Adds cryptographic signature to a participation claim to complete the bi-directional receipt process.- Capability:
general_access
- Capability:
validate_participation_claim_signature(claim_hash: ActionHash) -> bool: Validates the cryptographic signature of a participation claim.- Capability:
general_access
- Capability:
5. Security and Validation
- Capability Tokens: Zome functions will be protected by capability grants.
Simple Agentsget a general token.Accountable Agentsget a restricted token after their first validated transaction (REQ-SEC-01). - Validation Logic:
- The
zome_personintegrity zome will validate that only an Accountable Agent can assign aRole, and that specialized roles (Transport, Repair, Storage) require validation by existing Primary Accountable Agents per REQ-GOV-04 (Specialized Role Validation). - The
zome_personintegrity zome will validate that promotion from Simple Agent to Accountable Agent requires validation by an Accountable or Primary Accountable Agent, following the process in REQ-GOV-03 (Agent Validation). - The
zome_resourceintegrity zome ensures a resource cannot be created without a validResourceSpecificationand enforces embedded governance rules (REQ-GOV-07). - The
zome_resourceintegrity zome ensures that new resources start in a 'pending validation' state and are set to 'validated' upon successful peer review, as described in REQ-GOV-02 (Resource Validation). - The
zome_governanceintegrity zome ensures aClaimmatches itsCommitmentand validates all validation receipts for authenticity. - The system supports configurable validation schemes (e.g., 2-of-3, N-of-M reviewers) for Resource approval per REQ-GOV-06 (Multi-Reviewer Validation).
- Certain types of validation are restricted to Agents with specific Roles per REQ-GOV-05 (Role-Gated Validation).
- The
zome_resourceintegrity zome validates that Economic Processes can only be initiated by agents with appropriate roles (Transport, Repair, Storage processes require specific credentials). - Economic Process validation ensures that:
- Only agents with required roles can initiate specific process types
- Process inputs and outputs are properly linked to existing Economic Resources
- Process completion triggers appropriate Economic Events
- Resource state changes are validated according to process type (e.g., Repair may change resource state, Transport preserves state)
- The
- Cross-Zome Calls: Functions will call other zomes to maintain transactional integrity (e.g.,
transfer_custodymust create a validEconomicEventand enforce governance rules,initiate_economic_processmust validate agent roles across zomes). - First Resource Requirement: The system enforces that Simple Agents must create at least one resource before accessing others (
REQ-GOV-01), implemented through thecheck_first_resource_requirementfunction. - Process Role Enforcement: Economic Processes enforce role-based access control where specialized processes (Transport, Repair, Storage) require agents to hold appropriate validated credentials, while Use processes are accessible to all Accountable Agents.
- Private Participation Receipt (PPR) Validation:
- PPR issuance is automatically triggered for every completed economic interaction that involves a Commitment-Claim-Event cycle
- Bi-directional receipt generation ensures both agents receive appropriate participation claims
- Cryptographic signature validation ensures authenticity and prevents manipulation
- Performance metrics are validated to be within acceptable ranges (0.0-1.0 for scores)
- PPR claim types must correspond to the actual economic action performed
- End-of-life declarations require multiple validator participation receipts with enhanced security measures
- Private entry storage ensures receipt privacy while maintaining auditability for the owning agent
6. Future Development: Architecture Specifications for P2P and Organizational Contexts
6.1 Overview
This section specifies the technical architecture for supporting two distinct deployment contexts:
- Pure P2P Context: Individual humans directly using Nondominium
- Organizational Context: Organizations accessing Nondominium through bridge services (ERP, Tiki, etc.)
These specifications correspond to the future development requirements defined in REQ-FUT-* series.
6.2 Identity & Delegation Architecture
6.2.1 Organizational Agent Identity
SPEC-FUT-ID-01: Organizational Agent Entry
New entry type for representing organizational agents:
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct OrganizationalAgent { /// Unique identifier for the organization pub org_id: AgentPubKey, /// Human-readable organization name pub org_name: String, /// Legal entity information (optional) pub legal_entity_info: Option<LegalEntityInfo>, /// Organization type (e.g., "cooperative", "corporation", "nonprofit") pub org_type: String, /// Root signing authority for the organization pub root_authority: AgentPubKey, /// Active delegation policy pub delegation_policy: DelegationPolicy, /// Created timestamp pub created_at: Timestamp, } }
SPEC-FUT-ID-02: Delegation Entry
Entry type for employee/member delegations:
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Delegation { /// The organizational agent granting delegation pub delegator: AgentPubKey, /// The employee/member receiving delegation pub delegate: AgentPubKey, /// Scoped capabilities (e.g., ["Transport", "Use"]) pub capabilities: Vec<String>, /// Monetary or quantity limits (optional) pub limits: Option<DelegationLimits>, /// Expiry timestamp (optional, None = no expiry) pub expires_at: Option<Timestamp>, /// Status: "active", "revoked", "expired" pub status: DelegationStatus, /// Created timestamp pub created_at: Timestamp, /// Revoked timestamp (if applicable) pub revoked_at: Option<Timestamp>, } }
SPEC-FUT-ID-03: Delegation Limits
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct DelegationLimits { /// Maximum transaction value pub max_value: Option<f64>, /// Maximum resource quantity pub max_quantity: Option<f64>, /// Allowed resource types pub allowed_resource_specs: Option<Vec<ActionHash>>, /// Geographic restrictions pub geographic_limits: Option<Vec<String>>, } }
SPEC-FUT-ID-04: Delegation Validation
#![allow(unused)] fn main() { #[hdk_extern] pub fn validate_delegation(delegation_hash: ActionHash, action: VfAction) -> ExternResult<bool> { // Check delegation status (active/revoked/expired) // Verify capability scope includes requested action // Validate limits are not exceeded // Return authorization result } }
6.2.2 Delegation Zome Functions
SPEC-FUT-ID-05: Delegation Management Functions
#![allow(unused)] fn main() { // Create delegation for employee/member #[hdk_extern] pub fn create_delegation( delegate: AgentPubKey, capabilities: Vec<String>, limits: Option<DelegationLimits>, expires_at: Option<Timestamp> ) -> ExternResult<ActionHash>; // Revoke delegation immediately #[hdk_extern] pub fn revoke_delegation(delegation_hash: ActionHash) -> ExternResult<()>; // Get all active delegations for an organization #[hdk_extern] pub fn get_active_delegations(org_agent: AgentPubKey) -> ExternResult<Vec<Delegation>>; // Check if delegate has specific capability #[hdk_extern] pub fn check_delegation_capability( delegate: AgentPubKey, capability: String ) -> ExternResult<bool>; }
6.3 Organizational Reputation Architecture
6.3.1 Organizational PPR Aggregation
SPEC-FUT-REP-01: Organizational Participation Claim
Extended PPR structure for organizational context:
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct OrganizationalParticipationClaim { /// Standard PPR fields pub base_claim: PrivateParticipationClaim, /// The delegate who performed the action pub performed_by: Option<AgentPubKey>, /// Internal attribution hash (for org audit) pub internal_attribution: Option<Hash>, /// Whether this was an organizational or personal action pub action_context: ActionContext, } }
SPEC-FUT-REP-02: Reputation Aggregation
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct OrganizationalReputationSummary { /// The organizational agent pub org_agent: AgentPubKey, /// Standard reputation metrics (external view) pub external_reputation: ReputationSummary, /// Internal attribution by delegate (private) pub delegate_performance: HashMap<AgentPubKey, ReputationSummary>, /// Aggregate organizational metrics pub org_metrics: OrganizationalMetrics, } }
SPEC-FUT-REP-03: Organizational Metrics
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct OrganizationalMetrics { /// Total active delegates pub active_delegates: u32, /// Organizational transaction volume pub transaction_volume: u32, /// Organizational reliability score pub org_reliability: f64, /// Resource pool size pub resource_pool_size: u32, } }
6.3.2 Reputation Functions
SPEC-FUT-REP-04: Organizational Reputation Functions
#![allow(unused)] fn main() { // Get organizational reputation (external view) #[hdk_extern] pub fn get_organizational_reputation(org_agent: AgentPubKey) -> ExternResult<OrganizationalReputationSummary>; // Get delegate performance (organizational admin only) #[hdk_extern] pub fn get_delegate_performance( org_agent: AgentPubKey, delegate: AgentPubKey ) -> ExternResult<ReputationSummary>; // Issue organizational PPR with internal attribution #[hdk_extern] pub fn issue_organizational_ppr( commitment_hash: ActionHash, event_hash: ActionHash, performed_by: AgentPubKey, performance_metrics: PerformanceMetrics ) -> ExternResult<ActionHash>; }
6.4 Bridge Service Architecture
6.4.1 Node.js Bridge Service Specification
SPEC-FUT-BRG-01: Bridge Service Core Architecture
The bridge service acts as a RESTful interface between organizational systems (ERP, Tiki) and Holochain:
Organizational System (PHP/Python) <--HTTP/JSON--> Node.js Bridge <--WebSocket--> Holochain Conductor
Components:
- REST API Layer: Express.js or Fastify for HTTP endpoints
- Holochain Client:
@holochain/clientfor WebSocket communication - Cache Layer: Redis for frequently accessed data
- Queue Layer: Bull/BullMQ for async operations
- Signal Handler: Real-time event forwarding to organizational systems
SPEC-FUT-BRG-02: Bridge Service Data Structures
// Bridge configuration
interface BridgeConfig {
adminWsUrl: string; // Holochain Admin WebSocket URL
appWsUrl: string; // Holochain App WebSocket URL
appId: string; // Nondominium hApp ID
redisUrl: string; // Redis connection URL
orgWebhookUrl: string; // Organizational system webhook endpoint
webhookSecret: string; // HMAC signature secret
cacheEnabled: boolean; // Enable/disable caching
cacheTTL: number; // Cache time-to-live (seconds)
}
// Bridge request format
interface BridgeRequest {
dna_hash: string; // Nondominium DNA hash
agent_key: string; // Organizational agent key
zome: string; // Target zome name
function: string; // Target function name
payload: any; // Function payload
delegate?: string; // Optional delegate agent key
}
// Bridge response format
interface BridgeResponse {
success: boolean;
data?: any;
error?: string;
cached?: boolean;
timestamp: number;
}
SPEC-FUT-BRG-03: Bridge REST API Endpoints
Core endpoints that organizational systems interact with:
// Resource management
POST /api/resources
GET /api/resources/search
GET /api/resources/:hash
POST /api/resources/:hash/use
DELETE /api/resources/:hash
// Transaction management
POST /api/commitments
GET /api/commitments/:hash
POST /api/events
GET /api/events/by-resource/:resource_hash
// Reputation queries
GET /api/reputation/:agent_id/summary
GET /api/reputation/:agent_id/receipts
// Batch operations
POST /api/batch
// Organizational management
POST /api/org/delegations
DELETE /api/org/delegations/:hash
GET /api/org/delegations/active
GET /api/org/reputation
// Health and monitoring
GET /health
GET /metrics
SPEC-FUT-BRG-04: Signal Forwarding
Real-time signal forwarding from Holochain to organizational systems:
// Signal handler
class SignalForwarder {
async handleSignal(signal: HolochainSignal): Promise<void> {
// Transform Holochain signal to organizational format
const orgEvent = this.transformSignal(signal);
// POST to organizational webhook
await this.postToWebhook(orgEvent);
}
private transformSignal(signal: HolochainSignal): OrganizationalEvent {
return {
type: signal.data.type,
payload: signal.data.payload,
timestamp: Date.now(),
signature: this.generateHMAC(signal)
};
}
}
6.4.2 Organizational System Integration
SPEC-FUT-BRG-05: PHP Client Library
PHP library for Tiki and similar systems:
class NondominiumClient {
private $bridge_url;
private $org_agent_key;
private $delegate_key;
public function __construct($bridge_url, $org_agent_key, $delegate_key = null);
// Resource operations
public function createResource($spec_hash, $quantity, $unit);
public function searchResources($query = null);
public function initiateUse($resource_hash, $receiver, $start_time, $end_time);
// Batch operations
public function batchOperations($operations);
// Reputation queries
public function getOrganizationalReputation();
public function getDelegatePerformance($delegate_agent);
// Delegation management
public function createDelegation($delegate, $capabilities, $limits = null);
public function revokeDelegation($delegation_hash);
}
SPEC-FUT-BRG-06: Python Client Library
Python library for ERPLibre/Odoo:
class NondominiumBridgeClient:
def __init__(self, bridge_url: str, org_agent_key: str, delegate_key: str = None):
self.bridge_url = bridge_url
self.org_agent_key = org_agent_key
self.delegate_key = delegate_key
# Resource operations
def create_resource(self, spec_hash: str, quantity: float, unit: str) -> dict:
pass
def search_resources(self, query: str = None) -> list:
pass
# Batch operations
def batch_operations(self, operations: list) -> list:
pass
# Webhook handling
def handle_signal(self, signal: dict) -> None:
pass
6.5 Organizational Governance Architecture
6.5.1 Policy-Driven Governance
SPEC-FUT-GOV-01: Organizational Governance Policy
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct OrganizationalGovernancePolicy { /// Organization this policy applies to pub org_agent: AgentPubKey, /// Automated approval rules pub approval_rules: Vec<ApprovalRule>, /// Multi-signature requirements pub multisig_requirements: Vec<MultiSigRequirement>, /// Policy version pub version: String, /// Policy effective date pub effective_at: Timestamp, } }
SPEC-FUT-GOV-02: Approval Rule
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct ApprovalRule { /// Rule name pub name: String, /// Conditions for automatic approval pub conditions: Vec<Condition>, /// Actions this rule applies to pub applies_to: Vec<VfAction>, /// Whether approval is automatic or manual pub auto_approve: bool, } #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Condition { pub field: String, // e.g., "resource_value", "borrower_reputation" pub operator: Operator, // e.g., "greater_than", "less_than", "equals" pub value: String, // Comparison value } }
SPEC-FUT-GOV-03: Multi-Signature Requirement
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct MultiSigRequirement { /// Transaction types requiring multi-sig pub transaction_types: Vec<String>, /// Minimum number of signatures required pub min_signatures: u32, /// Required roles for signers pub required_roles: Vec<String>, /// Value threshold for triggering multi-sig pub value_threshold: Option<f64>, } }
6.5.2 Governance Functions
SPEC-FUT-GOV-04: Organizational Governance Functions
#![allow(unused)] fn main() { // Set organizational governance policy #[hdk_extern] pub fn set_governance_policy(policy: OrganizationalGovernancePolicy) -> ExternResult<ActionHash>; // Evaluate approval request against policy #[hdk_extern] pub fn evaluate_approval_request( action: VfAction, context: ApprovalContext ) -> ExternResult<ApprovalDecision>; // Initiate multi-signature transaction #[hdk_extern] pub fn initiate_multisig_transaction( action: VfAction, resource_hash: ActionHash, required_signers: Vec<AgentPubKey> ) -> ExternResult<ActionHash>; // Sign multi-signature transaction #[hdk_extern] pub fn sign_multisig_transaction( transaction_hash: ActionHash, signature: CryptographicSignature ) -> ExternResult<()>; // Check multi-signature completion #[hdk_extern] pub fn check_multisig_status(transaction_hash: ActionHash) -> ExternResult<MultiSigStatus>; }
6.6 Device & Session Management
6.6.1 Session Management Architecture
SPEC-FUT-DEV-01: Session Entry
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct OrganizationalSession { /// Session identifier pub session_id: String, /// Organizational agent pub org_agent: AgentPubKey, /// Delegate agent for this session pub delegate: AgentPubKey, /// Device identifier pub device_id: String, /// Session creation time pub created_at: Timestamp, /// Session expiry time pub expires_at: Timestamp, /// Session status pub status: SessionStatus, /// OAuth/SSO token reference (hashed) pub auth_token_hash: Option<Hash>, } }
SPEC-FUT-DEV-02: Device Registration
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct RegisteredDevice { /// Device identifier pub device_id: String, /// Organization this device belongs to pub org_agent: AgentPubKey, /// Device type (e.g., "tablet", "mobile", "workstation") pub device_type: String, /// Whether device is shared or personal pub is_shared: bool, /// Registered delegates for this device pub authorized_delegates: Vec<AgentPubKey>, /// Device registration time pub registered_at: Timestamp, /// Device status pub status: DeviceStatus, } }
6.6.2 Session Functions
SPEC-FUT-DEV-03: Session Management Functions
#![allow(unused)] fn main() { // Create organizational session #[hdk_extern] pub fn create_session( delegate: AgentPubKey, device_id: String, auth_token_hash: Option<Hash> ) -> ExternResult<String>; // Returns session_id // Validate active session #[hdk_extern] pub fn validate_session(session_id: String) -> ExternResult<bool>; // Terminate session #[hdk_extern] pub fn terminate_session(session_id: String) -> ExternResult<()>; // Map OAuth token to Holochain capability #[hdk_extern] pub fn map_oauth_to_capability( oauth_token_hash: Hash, delegate: AgentPubKey ) -> ExternResult<CapabilityGrant>; // Register organizational device #[hdk_extern] pub fn register_device( device_id: String, device_type: String, is_shared: bool ) -> ExternResult<ActionHash>; // Revoke device access remotely #[hdk_extern] pub fn revoke_device_access(device_id: String) -> ExternResult<()>; }
6.7 Custody vs Ownership Architecture
6.7.1 Organizational Resource Ownership
SPEC-FUT-OWN-01: Extended Resource Entry
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct OrganizationalEconomicResource { /// Standard resource fields pub base_resource: EconomicResource, /// Owner (may differ from custodian in org context) pub owner: AgentPubKey, /// Current physical location pub location: Option<LocationInfo>, /// Internal organizational tracking ID pub internal_id: Option<String>, /// Legal contract attachment (hashed) pub contract_hash: Option<Hash>, } }
SPEC-FUT-OWN-02: Location Tracking
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct LocationInfo { /// Location type (e.g., "warehouse", "service_truck", "customer_site") pub location_type: String, /// Location identifier pub location_id: String, /// Geographic coordinates (optional) pub coordinates: Option<(f64, f64)>, /// Updated timestamp pub updated_at: Timestamp, } }
SPEC-FUT-OWN-03: Internal Transfer Event
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct InternalTransferEvent { /// Resource being transferred pub resource: ActionHash, /// Organization owning the resource pub organization: AgentPubKey, /// Previous custodian (employee) pub from_custodian: AgentPubKey, /// New custodian (employee) pub to_custodian: AgentPubKey, /// Previous location pub from_location: Option<LocationInfo>, /// New location pub to_location: Option<LocationInfo>, /// Transfer timestamp pub transferred_at: Timestamp, /// Does NOT trigger ownership change pub is_internal: bool, } }
6.7.2 Ownership Functions
SPEC-FUT-OWN-04: Organizational Ownership Functions
#![allow(unused)] fn main() { // Internal custody transfer (within organization) #[hdk_extern] pub fn internal_custody_transfer( resource_hash: ActionHash, new_custodian: AgentPubKey, new_location: Option<LocationInfo> ) -> ExternResult<ActionHash>; // Update resource location without custody change #[hdk_extern] pub fn update_resource_location( resource_hash: ActionHash, location: LocationInfo ) -> ExternResult<()>; // Attach legal contract to commitment #[hdk_extern] pub fn attach_contract( commitment_hash: ActionHash, contract_hash: Hash ) -> ExternResult<()>; // Reconcile organizational inventory #[hdk_extern] pub fn reconcile_inventory( org_agent: AgentPubKey, inventory_snapshot: Vec<ResourceInventoryItem> ) -> ExternResult<ReconciliationReport>; }
6.8 Architecture Modularity Specifications
SPEC-FUT-ARCH-01: Context Detection
The system should automatically detect operational context:
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone)] pub enum AgentContext { PureP2P, // Individual human agent Organizational(OrganizationalAgent), // Organizational agent Delegate(AgentPubKey, AgentPubKey), // Delegate acting for organization } // Determine agent context #[hdk_extern] pub fn get_agent_context(agent: AgentPubKey) -> ExternResult<AgentContext>; }
SPEC-FUT-ARCH-02: Pluggable Governance
Governance logic should be modular and swappable:
#![allow(unused)] fn main() { pub trait GovernanceModule { fn evaluate_action(&self, action: VfAction, context: ActionContext) -> Result<ApprovalDecision>; fn get_validation_requirements(&self, action: VfAction) -> ValidationRequirements; } // P2P Governance Module pub struct P2PGovernanceModule; impl GovernanceModule for P2PGovernanceModule { /* ... */ } // Organizational Governance Module pub struct OrganizationalGovernanceModule; impl GovernanceModule for OrganizationalGovernanceModule { /* ... */ } }
SPEC-FUT-ARCH-03: Unified Reputation Framework
Reputation calculation should work across contexts:
#![allow(unused)] fn main() { pub trait ReputationCalculator { fn calculate_reputation(&self, agent: AgentPubKey) -> Result<ReputationSummary>; fn aggregate_pprs(&self, claims: Vec<PrivateParticipationClaim>) -> PerformanceMetrics; } // Works for both P2P and organizational agents #[hdk_extern] pub fn calculate_unified_reputation(agent: AgentPubKey) -> ExternResult<ReputationSummary> { let context = get_agent_context(agent)?; let calculator = match context { AgentContext::PureP2P => P2PReputationCalculator::new(), AgentContext::Organizational(_) => OrganizationalReputationCalculator::new(), AgentContext::Delegate(org, _) => OrganizationalReputationCalculator::new(), }; calculator.calculate_reputation(agent) } }
6.9 Deployment Specifications
SPEC-FUT-DEPLOY-01: Docker Compose Architecture
Standard deployment for organizational integration:
services:
holochain:
image: holochain/holochain:latest
ports:
- "8000:8000" # Admin WebSocket
- "8888:8888" # App WebSocket
bridge:
build: ./bridge-service
environment:
- HC_ADMIN_WS_URL=ws://holochain:8000
- HC_APP_WS_URL=ws://holochain:8888
- REDIS_URL=redis://redis:6379
depends_on:
- holochain
- redis
redis:
image: redis:7-alpine
organizational_system:
# ERP, Tiki, or other organizational platform
depends_on:
- bridge
SPEC-FUT-DEPLOY-02: Bridge Service Health Monitoring
interface HealthStatus {
status: 'healthy' | 'degraded' | 'unhealthy';
holochain: {
connected: boolean;
latency: number;
};
redis: {
connected: boolean;
memory_usage: number;
};
queue: {
jobs_pending: number;
jobs_failed: number;
};
uptime: number;
version: string;
}
// Health check endpoint
GET /health -> HealthStatus
6.10 Implementation Priorities
Phase 1 (Current): Pure P2P implementation
- Focus: Individual agents, direct custody, simple governance
Phase 2 (Near-term Future Development):
- Delegation pattern (SPEC-FUT-ID-01 through SPEC-FUT-ID-05)
- Organizational reputation (SPEC-FUT-REP-01 through SPEC-FUT-REP-04)
- Basic bridge service (SPEC-FUT-BRG-01 through SPEC-FUT-BRG-03)
Phase 3 (Long-term Future Development):
- Multi-signature governance (SPEC-FUT-GOV-01 through SPEC-FUT-GOV-04)
- Session & device management (SPEC-FUT-DEV-01 through SPEC-FUT-DEV-03)
- Full organizational features (custody vs ownership, policy automation)
6.11 Migration Strategy
SPEC-FUT-MIGRATE-01: Backward Compatibility
New organizational features must not break existing P2P functionality:
- P2P agents can interact with organizational agents seamlessly
- Core ValueFlows data structures remain unchanged
- Organizational features are additive, not breaking changes
SPEC-FUT-MIGRATE-02: Data Migration
When transitioning from P2P-only to organizational support:
- Existing PPRs remain valid and portable
- Existing resources can be claimed by organizations
- Agent identities can be promoted to organizational agents
7. MVP UI Layer Specifications
Status: Implemented. Full design rationale in
documentation/specifications/ui_architecture.md. Normative UI requirements indocumentation/requirements/ui_design.mdanddocumentation/requirements/requirements.md §4.5.
7.1 Shared Types — @nondominium/shared-types
The following interfaces are defined in packages/shared-types/src/resource.types.ts and consumed by both the service layer and Svelte components:
// NDO Layer 0 identity anchor
interface NdoDescriptor {
name: string;
property_regime: PropertyRegime;
resource_nature: ResourceNature;
lifecycle_stage: LifecycleStage;
description?: string;
initiator: AgentPubKey; // base64-encoded
created_at: Timestamp;
successor_ndo_hash?: ActionHash;
hibernation_origin?: LifecycleStage;
action_hash: ActionHash;
entry_hash: EntryHash;
}
// Canonical PropertyRegime — mirrors crates/shared/src/types.rs (7 variants)
type PropertyRegime =
| 'Private' // Full rights bundle; individual ownership
| 'Commons' // Non-rivalrous shared; licensing/attribution governance
| 'Collective' // Cooperative/collective ownership
| 'Pool' // Rivalrous shareables; custody/scheduling/maintenance
| 'CommonPool' // Rivalrous consumable; quota/depletion rules
| 'Public' // Public/governmental stewardship; open-access; non-alienable by public body
| 'Nondominium'; // Uncapturable by design; no alienation permitted
// NDO creation payload (mirrors Rust NondominiumIdentityInput)
interface NdoInput {
name: string;
property_regime: PropertyRegime;
resource_nature: ResourceNature;
lifecycle_stage: LifecycleStage;
description?: string;
}
// DNA properties of a cloned `ndo` cell (ADR-010 model A; ADR-013 binding).
// Mirrors crates/shared/src/types.rs::NdoDnaProperties field-for-field. The field
// set AND order are DnaHash input — changing either orphans every existing NDO
// cell. Excludes `initiator` (holochain 0.6.0 carries clone properties as
// YamlProperties, which has no binary variant for an AgentPubKey), and excludes
// the mutable `lifecycle_stage` / entry-only `description`.
interface NdoDnaProperties {
name: string;
property_regime: PropertyRegime;
resource_nature: ResourceNature;
created_at: Timestamp; // micros from a ms clock — NOT a uniqueness source
}
// The group→NDO pointer (ADR-011): an entry on the group clone cell carrying the
// coordinates a peer needs to re-derive, verify, and join the NDO cell. Also the
// create payload (`NdoAnchorInput` is an alias). Only name/description/
// lifecycle_stage are mutable caches — zome_group_integrity rejects an update
// that rewrites any other field.
interface NdoAnchorEntry {
group_hash: ActionHash;
name: string;
description: string | null;
ndo_dna_hash: DnaHash; // THE permanent NDO identity
network_seed: string; // needed to clone/join the cell
identity_action_hash: ActionHash; // Layer 0 genesis entry inside the ndo cell
initiator: AgentPubKey;
ndo_created_at: Timestamp;
lifecycle_stage: LifecycleStage;
property_regime: PropertyRegime;
resource_nature: ResourceNature;
}
// Lifecycle transition payload
interface UpdateLifecycleStageInput {
ndo_original_action_hash: ActionHash;
new_lifecycle_stage: LifecycleStage;
transition_event_hash: ActionHash | null; // null in MVP
successor_ndo_hash?: ActionHash; // required for Deprecated
}
// Transition history entry
interface NdoTransitionHistoryEvent {
from_stage: LifecycleStage;
to_stage: LifecycleStage;
agent: AgentPubKey;
timestamp: Timestamp;
event_hash: ActionHash;
}
// Group descriptor (DNA-backed — one cloned Group DNA cell per group; PR #107)
interface GroupDescriptor {
id: string; // canonical key = network_seed
networkSeed: string;
name: string;
description?: string;
createdBy?: string; // LobbyUserProfile.nickname at creation
createdAt?: number;
dnaHash?: string; // clone cell DNA hash (base64)
groupHash?: string; // GroupProfile ActionHash (base64)
memberProfile?: GroupMemberProfile; // Level 2 — localStorage only (ndo_group_profiles_v1)
}
// Level 1 identity — Lobby user profile
interface LobbyUserProfile {
nickname: string; // required
realName?: string;
bio?: string;
email?: string;
phone?: string;
address?: string;
}
// Level 2 identity — per-group disclosure preferences
interface GroupMemberProfile {
isAnonymous: boolean;
shownFields: (keyof Omit<LobbyUserProfile, 'nickname'>)[];
}
7.2 Service Layer
Services are Effect-TS Context.Tag / Layer values. All zome calls are wrapped via wrapZomeCallWithErrorFactory:
const wz = <T>(fnName: string, payload: unknown, context: string) =>
wrapZomeCallWithErrorFactory<T, DomainError>(
holochainClient, 'zome_name', fnName, payload, context,
DomainError.fromError
);
resource.service.ts — NDO-specific zome calls added for MVP:
| Function | Zome call |
|---|---|
createNdo(input) | create_ndo |
getNdo(hash) | get_ndo |
updateLifecycleStage(input) | update_lifecycle_stage |
getMyNdos() | get_my_ndos |
getNdosByLifecycleStage(stage) | get_ndos_by_lifecycle_stage |
getNdosByNature(nature) | get_ndos_by_nature |
getNdosByPropertyRegime(regime) | get_ndos_by_property_regime |
getNdoTransitionHistory(hash) | get_ndo_transition_history |
lobby.service.ts — Group + Lobby DNA backed (Group DNA complete, PR #107):
| Function | Behaviour |
|---|---|
getMyGroups() | Enumerate group clone cells from appInfo + get_my_group per cell |
createGroup(name, createdBy) | createCloneCell → create_group → join_group → announce_group (post-steps best-effort via E.catchAll) |
joinGroup(inviteCode) | Decode invite → createCloneCell(same seed) → fetchGroupProfileWithRetry (poll get_my_group 6× / ~2.4 s) → is_member guard → best-effort join_group → invite-payload GroupDescriptor fallback so the group appears without reload. TODO(signals) |
ensureMembership(groupId) | Idempotent membership self-heal: resolve group hash via get_my_group → is_member → best-effort join_group if missing. Run on every full loadGroupData so a joined agent reliably appears in the DHT member list even if the initial join missed the commit |
generateInviteLink(groupId) | { network_seed, group_dna_hash, group_name } → ?group=<base64> URL |
saveGroupMemberProfile(groupId, profile) | localStorage[ndo_group_profiles_v1] (Level 2 identity — only remaining localStorage state) |
ndo.service.ts — higher-level aggregation over the per-NDO-cell model (ADR-010 model A). Each NDO is its own cloned ndo cell whose DnaHash is bound to the NDO identity through DNA properties; the group→NDO pointer is an NdoAnchor entry on the group clone cell carrying the full clone coordinates (ndo_dna_hash, network_seed, identity_action_hash) plus cached card fields. Anchors are the only pointer these read paths follow — SoftLink is no longer used for NDO association.
Every "where is this NDO anchored" question is answered from a single scanGroupAnchors() pass over the agent's group cells.
| Function | Behaviour |
|---|---|
getLobbyNdoDescriptors() | One anchor scan across the agent's group clone cells → render cards from the cached anchor fields (no ndo cell is joined) |
createNdo(input, groupId) | createNdoCloneCell(networkSeed, properties) → create_ndo inside the new ndo cell → create_ndo_anchor on the group cell. The anchor write is not best-effort: it is the only discovery path, so a failure fails the create rather than orphaning the cell |
getNdoDescriptorForSpecActionHash(hash) | Resolve the ndo cell from the anchor (ensureNdoCloneCell provisions it for a peer who never joined) → live get_ndo; falls back to the legacy shared nondominium cell for pre-migration NDOs |
updateLifecycleStage(input) | update_lifecycle_stage on the ndo cell → refresh_ndo_anchor_lifecycle_stage on each group that anchors it (best-effort cache convergence); legacy shared-cell fallback retained |
getGroupNdoDescriptors(groupId) | get_ndo_anchors on that group's cell → cards from cached anchor fields |
getAssociatedGroupIds(ndoHashB64) | Groups whose anchors carry this NDO identity, from the one scan |
associateNdoWithGroup(ndoHashB64, groupId) | Copies an existing anchor's clone coordinates into a second group as a new NdoAnchor (no-op if already anchored there) |
getNdoTransitionHistory(hash) | get_ndo_transition_history on the resolved ndo cell; legacy shared-cell fallback |
joinNdo / getNdoMembers | Resolves the ndo cell from anchor coordinates, then join_ndo / get_ndo_members on zome_resource. joinNdo is idempotent (is_ndo_member guard); member names resolve via zome_person with a truncated-pubkey fallback |
7.3 Error Context Registry
New error context strings added to ui/src/lib/errors/error-contexts.ts:
RESOURCE_CONTEXTS.CREATE_NDO
RESOURCE_CONTEXTS.GET_NDO
RESOURCE_CONTEXTS.UPDATE_LIFECYCLE_STAGE
RESOURCE_CONTEXTS.GET_MY_NDOS
RESOURCE_CONTEXTS.GET_NDOS_BY_LIFECYCLE_STAGE
RESOURCE_CONTEXTS.GET_NDOS_BY_NATURE
RESOURCE_CONTEXTS.GET_NDOS_BY_PROPERTY_REGIME
RESOURCE_CONTEXTS.GET_NDO_TRANSITION_HISTORY
7.4 Store Specifications
app.context.svelte.ts
Module-level reactive state (Svelte 5 rune pattern). lobbyUserProfile is hydrated from localStorage at import time and persisted reactively:
// Initialised from localStorage at module load
let lobbyUserProfile = $state<LobbyUserProfile | null>(loadProfileFromStorage());
// Reactive setter — persists to localStorage on write
lobby.store.svelte.ts
| State | Type | Description |
|---|---|---|
ndos | NdoDescriptor[] | All NDOs from DHT |
filteredNdos | NdoDescriptor[] | ndos after activeFilters applied |
groups | GroupDescriptor[] | From LobbyService.getMyGroups() |
activeFilters | ActiveFilters | { lifecycleStages, natures, regimes } |
Filter logic: OR within each dimension, AND across dimensions. Empty set = show all.
group.store.svelte.ts — new file
| State | Source |
|---|---|
group | LobbyService.getMyGroups() (group clone cells) |
groupNdos | NdoService.getGroupNdoDescriptors(groupId) via NdoAnchors on the group cell |
members | GroupService.getMembers(cellId) (DHT) |
loadGroupData(groupId, { silent? }) switches the store's active group context. A full (non-silent) load runs LobbyService.ensureMembership(groupId) (membership self-heal) before fetching NDOs + members; a silent load (used by the reactivity layer) skips the reconcile, leaves isLoading untouched, and keeps existing data on transient failure. refreshCurrentGroup() is a silent re-fetch of the open group. createNdo(input) creates on DHT then reloads.
Shared-group reactivity (pull model). GroupView keeps the open group fresh as peers' changes gossip in by calling refreshCurrentGroup() on tab focus / visibility change and on a gentle ~8 s poll (paused when the tab is hidden), in addition to the per-open reconcile in loadGroupData. This is pull-only; the push upgrade is TODO(signals) — zome_group remote_signal to members on join_group / create_soft_link / log_work, with focus/poll retained as an offline/missed-signal fallback (design note in dnas/group/zomes/coordinator/zome_group/src/lib.rs).
7.5 LifecycleStage State Machine
Allowed transitions enforced in both LifecycleTransitionModal.svelte (frontend) and zome_resource validation (Rust):
Ideation → Specification | Deprecated | EndOfLife
Specification → Development | Deprecated | EndOfLife
Development → Prototype | Deprecated | EndOfLife
Prototype → Stable | Deprecated | EndOfLife
Stable → Distributed | Deprecated | EndOfLife
Distributed → Active | Deprecated | EndOfLife
Active → Hibernating | Deprecated | EndOfLife
Hibernating → <hibernation_origin> | Deprecated | EndOfLife
Deprecated → EndOfLife
EndOfLife → (terminal, no transitions)
Special transition behaviours:
- → Deprecated:
successor_ndo_hashrequired; searched fromlobbyStore.ndosby name. - → Hibernating: confirmation prompt shown;
hibernation_origin= current stage preserved in entry. transition_event_hash: passed asnullin MVP; automaticEconomicEventgeneration is deferred to backend Phase 2.3 (PPR system).
7.6 Local Development & Multi-Agent Web Harness
The dev runtime is the browser (Electron/hc-spin superseded). scripts/launch-happ.mjs (bun run start / AGENTS=N bun run network) starts kitsune2-bootstrap-srv, creates/runs hc sandbox conductors, installs the .happ via path-based installApp (avoids the admin-websocket bundle-streaming timeout), writes the ui/static/hc-connection.json connection manifest, and launches one Vite dev server per agent on consecutive ports (5173 + agent-1, pinned via VITE_DEV_AGENT), auto-opening a browser tab per agent (NO_OPEN=1 to disable).
- Isolation by origin: one port per agent → isolated
localStorage, clean permalinks. The?agent=Nquery param remains as a manual override only. - Connection (
ui/src/lib/utils/hc-connect.ts):connectHolochainClientresolveslauncher/manifest/envmodes;getDevAgentIndex()prefers?agent=N→VITE_DEV_AGENT→localStorage. Signing credentials are authorized for provisioned and cloned cells withauthorizeWithRetry(survives "source chain head has moved");authorizeCellSigningcovers group clone cells created after connect. - UI-only
localStoragekeys are namespaced viadevStorageKey(base)→${base}__a{agent}.
Full detail: documentation/specifications/ui_architecture.md §15.
project: nondominium type: architecture status: active created: 2026-03-25 version: v1.0 design
Nondominium v1.0 — Architecture & Data Model Design
Design session: 2026-03-25 Basis: ValueFlows 1.0 ontology + NDO Prima Materia Scope: Three-zome Holochain DNA — data model, VF compliance, zome boundaries, coordinator signatures
1. Design Principles
1.0 Dual-DNA Architecture (Ground Rule)

hREA DNA owns all canonical ValueFlows entry types (EconomicResource, EconomicEvent, Commitment). NDO DNA calls hREA via cross-DNA calls — never duplicates VF types. The bridge (sync_agent_hash, bridge_economic_event, get_hrea_resource) is the only coupling point.
Nondominium runs as a dual-DNA hApp — hrea DNA + ndo DNA, both registered as roles in happ.yaml. NDO does not re-implement VF entry types. All VF core types are owned by the hrea DNA. NDO coordinates governance, identity, and accountability on top of hREA via cross-DNA calls (CallTargetCell::OtherRole("hrea")).
| Lives in hREA DNA | Lives in NDO DNA |
|---|---|
| EconomicResource, EconomicEvent | NondominiumIdentity (Layer 0) |
| Commitment, Agreement, Plan | GovernanceRule, CapabilitySlot |
| ResourceSpecification (VF core) | PrivateParticipationClaim (PPR) |
| Process, Intent (post-v1.0) | ValidationReceipt, ResourceValidation |
| ReaAgent, ReaUnit | PrivatePersonData, Person |
| All VF 1.0 types | All NDO governance/identity extensions |
NDO zomes interact with hREA via:
call(CallTargetCell::OtherRole("hrea"), "hrea", fn_name, input)— from coordinator- Storing returned
ActionHashvalues in NDO-side link structures for traversal
hREA dependency: NDO v1.0 depends on hREA reaching a target compliance state. See documentation/hREA/strategic-roadmap.md (Phase 1 gap closure) and documentation/hREA/valueflows-1.0-compliance.md for the full audit. P0 gaps (effortQuantity, vf:Claim) must land in hREA before NDO's full work-event and reciprocity workflows are available.
1.1 VF 1.0 as the Floor, NDO Innovations as the Extension
ValueFlows 1.0 defines the economic ontology. VF core classes are provided by the hREA DNA. Every VF class either:
- Delegated to hREA — NDO calls hREA coordinator functions and stores returned hashes
- Extended by NDO — NDO adds a companion entry type with NDO-specific fields linked to the hREA hash
- Is deferred from v1.0 scope (Intent, vf:Claim as reciprocity — handled by hREA post-Phase 1)
NDO adds above the VF floor:
| NDO Extension | Relationship to VF |
|---|---|
NondominiumIdentity (Layer 0) | Not in VF — resource identity anchor |
LifecycleStage | Not in VF — resource maturity stages |
OperationalState | Replaces VF's string state with typed enum |
PropertyRegime | Not in VF — governance classification |
ResourceNature | Not in VF — Digital/Physical/Hybrid |
GovernanceRule | Not in VF — embedded Ostromian governance |
CapabilitySlot surface | Not in VF — stigmergic attachment |
PrivateParticipationClaim (PPR) | Extends vf:Claim with bilateral signatures |
1.2 Governance-as-Operator (preserve)
zome_resource = pure data model. No business logic.
zome_gouvernance = state transition operator. Reads resource state, evaluates rules, approves or rejects transitions, generates EconomicEvents.
This boundary is non-negotiable. It enables swappable governance without touching the data model.
1.3 Three-Layer NDO (new in v1.0)
Every resource begins as a Layer 0 identity anchor and grows in structural complexity as its social complexity demands:
Layer 2 — PROCESS (EconomicEvents, Commitments, PPRs)
↑ activated by NDOToProcess link
Layer 1 — SPECIFICATION (ResourceSpecification, GovernanceRules)
↑ activated by NDOToSpecification link
Layer 0 — IDENTITY (NondominiumIdentity — permanent, immutable name+regime+nature+lifecycle)
2. VF 1.0 Class Mapping
Legend: hREA = provided by hREA DNA (cross-DNA call from NDO) · NDO = native NDO entry type · NDO+hREA = NDO extends hREA with a companion entry
| VF Class | DNA | Entry / Mechanism | NDO Zome | v1.0 Status | Notes |
|---|---|---|---|---|---|
vf:Agent | hREA | ReaAgent via cross-DNA call | zome_person | Partial — individual only | NDO also stores AgentPubKey + Person |
vf:EconomicResource | hREA | ReaEconomicResource via cross-DNA | zome_resource | Full (via hREA) | NDO stores returned hash; links to NondominiumIdentity |
vf:ResourceSpecification | NDO+hREA | ReaResourceSpecification (hREA) + ResourceSpecification extension (NDO) | zome_resource | Full | NDO extension holds: category, tags, is_active, image |
vf:EconomicEvent | hREA | ReaEconomicEvent via cross-DNA | zome_gouvernance | Full (via hREA) | NDO calls hREA; stores hash for PPR linkage |
vf:Commitment | hREA | ReaCommitment via cross-DNA | zome_gouvernance | Full (via hREA) | NDO calls hREA; links PPR to hREA Commitment hash |
vf:Agreement | hREA | ReaAgreement via cross-DNA | zome_gouvernance | Full (via hREA) | NDO calls hREA post-Phase 1a (reciprocal fields) |
vf:Claim | NDO | Fulfillment (Rust: Claim — ADR-004) | zome_gouvernance | Partial | NDO fulfillment bridge; hREA vf:Claim = post-Phase 1c |
vf:Process | hREA | ReaProcess via cross-DNA | zome_gouvernance | Basic (via hREA) | NDO Layer 2 activation links to hREA Process hash |
vf:Unit | NDO | Unit | zome_resource | Full | NDO-local for now; may delegate to hREA post-v1.0 |
vf:Intent | — | — | — | Post-v1.0 | Valid VF 1.0 class — deferred; CapabilitySlot path |
NDO: NondominiumIdentity | NDO | NondominiumIdentity | zome_resource | New | Layer 0 permanent identity anchor |
NDO: GovernanceRule | NDO | GovernanceRule | zome_resource | Enhanced | GovernanceRuleType enum (was String) |
| NDO: PPR | NDO | PrivateParticipationClaim | zome_gouvernance | Unchanged | Bilateral cryptographic accountability |
3. Complete Entry Type Specifications
3.1 zome_resource Integrity
Supporting Types (shared)
#![allow(unused)] fn main() { #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] pub struct QuantityValue { pub has_numerical_value: f64, pub has_unit: ActionHash, // → Unit entry } #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] pub enum PropertyRegime { Private, // Full rights bundle; individual ownership Commons, // Non-rivalrous; governance via licensing/attribution Collective, // Cooperative/collective ownership Pool, // Rivalrous shared; custody/scheduling/maintenance CommonPool, // Rivalrous consumable; quota/depletion rules Public, // Public/governmental stewardship; open-access; non-alienable by public body Nondominium, // Uncapturable; contribution-based access; no alienation } #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] pub enum ResourceNature { Digital, // Software, data, design files, documents Physical, // Material objects, equipment, spaces Hybrid, // Digital twin of a physical resource } #[derive(Clone, PartialEq, Debug, Serialize, Deserialize, Default)] pub enum LifecycleStage { #[default] Ideation, // Idea registered, no form yet Specification, // Form defined; design or spec exists Development, // Active work; not yet distributable Prototype, // Working prototype; validation in progress Stable, // Peer-validated; ready for active use Distributed, // Actively used across multiple agents/locations Active, // In active operational use Hibernating, // Temporarily inactive; may be reactivated Deprecated, // Superseded; has declared successor NDO EndOfLife, // Permanently concluded; tombstone only } #[derive(Clone, PartialEq, Debug, Serialize, Deserialize, Default)] pub enum OperationalState { #[default] Available, // No active process; ready for use PendingValidation, // Initial state; awaiting peer validation Reserved, // Commitment accepted; process not yet started InTransit, // Transport process active (Move/TransferCustody event open) InStorage, // Storage service commitment active InMaintenance, // Repair/modify process active InUse, // Use event open; actively being used } #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] pub enum GovernanceRuleType { AccessRequirement, // Role/affiliation/capability required for access MaintenanceSchedule, // Maintenance obligations and intervals RoleRequirement, // Specific role required for a given VfAction UsageLimit, // Quantity/time/frequency limits TransferCondition, // Conditions for custody/ownership transfer IdentityVerification, // Requires Flowsta cross-app identity (Tier 2) EconomicAgreement, // Unyt Smart Agreement binding (stub; Phase 3) } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct CapabilitySlotTag { pub slot_type: SlotType, pub attached_at: Timestamp, pub label: Option<String>, } #[derive(Clone, Debug, Serialize, Deserialize)] pub enum SlotType { Documentation, IssueTracker, FabricationQueue, GovernanceDAO, VersionGraph, DigitalAsset, WeaveWAL, FlowstaIdentity, // IsSamePersonEntry action hash (Flowsta cross-app identity) UnytAgreement(String), // Unyt Alliance network seed CustomApp(String), // Extensible } }
Entry Types
#![allow(unused)] fn main() { // vf:Unit — first-class unit of measure #[hdk_entry_helper] pub struct Unit { pub label: String, // "kilogram", "hour", "each", "piece" pub symbol: Option<String>, // "kg", "h", "ea" } // NDO Layer 0 — permanent identity anchor for every Nondominium Object #[hdk_entry_helper] pub struct NondominiumIdentity { pub name: String, pub description: Option<String>, pub initiator: AgentPubKey, // Post-v1.0: AgentContext — supports Bot agents and composed collective agents (dual-face model: agent face references this NDO as resource face) pub property_regime: PropertyRegime, pub resource_nature: ResourceNature, pub lifecycle_stage: LifecycleStage, // Only field mutable after creation pub created_at: Timestamp, } // Immutability rules: initiator, property_regime, resource_nature, name, description = immutable. // lifecycle_stage = only mutable field. Every update must reference a triggering EconomicEvent hash. // Deletion: ALWAYS INVALID. NondominiumIdentity entries are permanent DHT records. // vf:ResourceSpecification — Layer 1 form definition #[hdk_entry_helper] pub struct ResourceSpecification { pub name: String, pub description: String, pub category: String, pub image_url: Option<String>, pub tags: Vec<String>, pub is_active: bool, // VF 1.0 additions: pub default_unit_of_resource: Option<ActionHash>, // → Unit pub default_unit_of_effort: Option<ActionHash>, // → Unit pub medium_of_exchange: bool, // Is this a currency-like resource? pub substitutable: bool, // Can instances be freely swapped? } // vf:EconomicResource — Layer 2 physical/digital instance #[hdk_entry_helper] pub struct EconomicResource { // VF 1.0 compliant fields: pub accounting_quantity: QuantityValue, // Committed/on-books quantity pub onhand_quantity: QuantityValue, // Physically available quantity pub primary_accountable: AgentPubKey, // Accountable agent (was: custodian) pub custodian: Option<AgentPubKey>, // Physical custody (may differ from accountable) pub conforms_to: ActionHash, // → ResourceSpecification (required, embedded) pub current_location: Option<String>, // NDO-specific: pub operational_state: OperationalState, // Process condition on instance (REQ-NDO-OS-01) pub tracking_identifier: Option<String>, // Serial number, QR code, etc. } // Typed governance rule — replaces untyped String rule_type #[hdk_entry_helper] pub struct GovernanceRule { pub rule_type: GovernanceRuleType, // Was: String — now typed enum pub rule_data: String, // JSON-encoded parameters (typed per rule_type in Phase 2) pub enforced_by: Option<String>, // Role name string (post-v1.0: GovernanceRoleRef) } }
Link Types (zome_resource)
#![allow(unused)] fn main() { #[hdk_link_types] pub enum LinkTypes { // Existing discovery anchors (preserved): AllResourceSpecifications, AllEconomicResources, AllGovernanceRules, SpecificationToResource, CustodianToResource, // → renamed to AccountableToResource in Phase 2 SpecificationToGovernanceRule, AgentToOwnedSpecs, AgentToManagedResources, AgentToOwnedRules, SpecsByCategory, ResourcesByLocation, ResourcesByState, // DEPRECATED → split below RulesByType, ResourceToValidation, ResourceSpecificationUpdates, EconomicResourceUpdates, GovernanceRuleUpdates, // NEW — NDO Three-Layer Links: AllNDOs, // Anchor → NondominiumIdentity NDOsByLifecycleStage, // LifecyclePath → NondominiumIdentity NDOsByNature, // NaturePath → NondominiumIdentity NDOsByRegime, // RegimePath → NondominiumIdentity NDOLifecycleHistory, // NondominiumIdentity → LifecycleEvent (audit trail) NDOToSpecification, // NondominiumIdentity → ResourceSpecification (Layer 1 activation) NDOToProcess, // NondominiumIdentity → Process (Layer 2 activation) NDOToComponent, // NondominiumIdentity → NondominiumIdentity (holonic composition) // NEW — Capability Surface: CapabilitySlot, // NondominiumIdentity → capability target (tag carries SlotType) // NEW — VF ResourceState split: ResourcesByOperationalState, // OperationalState → EconomicResource (replaces ResourcesByState) // NEW — Unit discovery: AllUnits, // Anchor → Unit } }
3.2 zome_gouvernance Integrity
New Entry Types
#![allow(unused)] fn main() { // vf:Process — Layer 2 anchor; records the economic activity around an NDO #[hdk_entry_helper] pub struct Process { pub name: String, pub note: Option<String>, pub in_scope_of: Option<AgentPubKey>, // Post-v1.0: AgentContext — collective variants carry NDO hash as resource-face reference (dual-face model) pub created_at: Timestamp, pub finished: bool, } // vf:Agreement — set of reciprocal commitments among agents #[hdk_entry_helper] pub struct Agreement { pub name: String, pub description: Option<String>, pub parties: Vec<AgentPubKey>, // Post-v1.0: Vec<AgentContext> — collective variants carry NDO hash as resource-face reference (dual-face model) pub created_at: Timestamp, pub note: Option<String>, } }
Updated Entry Types
#![allow(unused)] fn main() { // vf:EconomicEvent — observed economic flow (updated for VF 1.0) #[hdk_entry_helper] pub struct EconomicEvent { pub action: VfAction, pub provider: AgentPubKey, pub receiver: AgentPubKey, pub resource_inventoried_as: ActionHash, pub affects: ActionHash, pub resource_quantity: QuantityValue, // Was: f64 — now VF-compliant QuantityValue pub effort_quantity: Option<QuantityValue>, // NEW: labor/effort measure pub event_time: Timestamp, pub note: Option<String>, pub at_location: Option<String>, // NEW: event location pub to_location: Option<String>, // NEW: destination (transport) // VF 1.0 relations: pub fulfills: Option<ActionHash>, // NEW: → Commitment (direct VF link) pub realization_of: Option<ActionHash>, // NEW: → Agreement pub triggered_claim: Option<ActionHash>, // NEW: → Fulfillment (audit bridge) } // vf:Commitment — planned economic flow (updated for VF 1.0) #[hdk_entry_helper] pub struct Commitment { pub action: VfAction, pub provider: AgentPubKey, pub receiver: AgentPubKey, pub resource_inventoried_as: Option<ActionHash>, pub resource_conforms_to: Option<ActionHash>, pub input_of: Option<ActionHash>, // → Process pub due_date: Timestamp, pub note: Option<String>, pub committed_at: Timestamp, // VF 1.0 addition: pub clause_of: Option<ActionHash>, // NEW: → Agreement } // NDO Fulfillment — fulfillment bridge (renamed from Claim for semantic clarity) // Note: Keeps "Claim" as the Rust type name for backwards compatibility in this zome, // but semantically acts as a VF fulfillment record. #[hdk_entry_helper] pub struct Claim { pub fulfills: ActionHash, // → Commitment pub fulfilled_by: ActionHash, // → EconomicEvent pub claimed_at: Timestamp, pub note: Option<String>, } // Existing entries preserved: // ValidationReceipt, ResourceValidation, PrivateParticipationClaim (PPR — unchanged) }
Updated Link Types (zome_gouvernance)
#![allow(unused)] fn main() { #[hdk_link_types] pub enum LinkTypes { // Existing (preserved): ValidatedItemToReceipt, ResourceToValidation, CommitmentToClaim, ResourceToEvent, AllValidationReceipts, AllEconomicEvents, AllCommitments, AllClaims, AllResourceValidations, AgentToPrivateParticipationClaims, EventToPrivateParticipationClaims, CommitmentToPrivateParticipationClaims, ResourceToPrivateParticipationClaims, // NEW: AllProcesses, // Anchor → Process AllAgreements, // Anchor → Agreement AgreementToCommitment, // Agreement → Commitment (stipulates) AgreementToEvent, // Agreement → EconomicEvent (realizes) ProcessToEvent, // Process → EconomicEvent ProcessToCommitment, // Process → Commitment } }
4. Three-Layer Activation Model
flowchart TD
subgraph L0["NDO Layer 0 — IDENTITY · NDO-specific (no VF equivalent)"]
NDO["NondominiumIdentity\nname · regime · nature · lifecycle_stage"]
end
subgraph L1["NDO Layer 1 — SPECIFICATION · VF: Knowledge Layer"]
SPEC["ResourceSpecification\nname · description · category\ndefault_unit · substitutable · medium_of_exchange"]
GRULE["GovernanceRule\nrule_type(enum) · rule_data · enforced_by"]
end
subgraph L2["NDO Layer 2 — PROCESS · VF: Plan + Observation Layers"]
subgraph VFP["VF Plan Layer"]
PROC["Process\nname · in_scope_of · finished"]
COMMIT["Commitment\naction · provider · receiver\ndue_date · clause_of"]
AGREE["Agreement\nname · parties"]
end
subgraph VFO["VF Observation Layer"]
ERES["EconomicResource\naccounting_qty · onhand_qty\nprimary_accountable · conforms_to"]
EEVENT["EconomicEvent\naction · provider · receiver\nresource_quantity · fulfills"]
PPR["PrivateParticipationClaim\n(NDO extension of vf:Claim)\nbilateral signature · 16 categories"]
end
end
Agent(["Agent · VF Observation Layer\nAgentPubKey + Person entry"])
Agent -->|"create_ndo()"| NDO
NDO -->|"NDOToSpecification\nactivate_layer1()"| SPEC
SPEC -->|"SpecificationToGovernanceRule"| GRULE
NDO -->|"NDOToProcess\nactivate_layer2()"| PROC
PROC -->|"ProcessToResource"| ERES
ERES -->|"conforms_to"| SPEC
PROC -->|"ProcessToEvent"| EEVENT
PROC -->|"ProcessToCommitment"| COMMIT
COMMIT -->|"clause_of"| AGREE
EEVENT -->|"fulfills"| COMMIT
EEVENT -->|"realization_of"| AGREE
EEVENT -->|"triggers"| PPR
NDO -->|"NDOToComponent\n(holonic composition)"| NDO
Activation rules:
- Layer 0 is created first; its
ActionHashis the stable NDO identifier forever - Layer 1 activates via
NDOToSpecificationlink — retroactive activation is supported - Layer 2 activates via
NDOToProcesslink — requires Layer 1 to be active first EconomicResourceinstances link through the Process, never directly to Layer 0- An NDO can contain other NDOs via
NDOToComponent(holonic composition)
Lifecycle Transition State Machine
stateDiagram-v2
direction LR
[*] --> Ideation : create_ndo()
Ideation --> Specification : Work\n(initiator)
Specification --> Development : Work\n(initiator / AccountableAgent)
Development --> Prototype : Modify\n(custodian + validation)
Prototype --> Stable : Accept\n(N-of-M peer validation)
Stable --> Distributed : Transfer\n(PrimaryAccountableAgent)
Distributed --> Active : (operational use begins)
Ideation --> Hibernating : Lower
Specification --> Hibernating : Lower
Development --> Hibernating : Lower
Prototype --> Hibernating : Lower
Stable --> Hibernating : Lower
Distributed --> Hibernating : Lower
Active --> Hibernating : Lower
Hibernating --> Ideation : Raise\n(return to prior stage)
Hibernating --> Specification : Raise\n(return to prior stage)
Hibernating --> Development : Raise\n(return to prior stage)
Hibernating --> Prototype : Raise\n(return to prior stage)
Hibernating --> Stable : Raise\n(return to prior stage)
Hibernating --> Distributed : Raise\n(return to prior stage)
Hibernating --> Active : Raise\n(return to prior stage)
Hibernating --> Active : Raise\n(claim — any AccountableAgent\nif inactivity criteria met)
Active --> Deprecated : Cite\n(successor NDO required)
Active --> EndOfLife : Consume\n(challenge period)
Deprecated --> EndOfLife : Consume
Hibernating --> EndOfLife : Consume
EndOfLife --> [*] : tombstone (permanent, never deleted)
Transition Authorization Table
| Transition | Authorized by | VfAction trigger |
|---|---|---|
| Ideation → Specification | Initiator | Work |
| Specification → Development | Initiator or any Accountable Agent | Work |
| Development → Prototype | Custodian + governance validation | Modify |
| Prototype → Stable | N-of-M peer validation | Accept |
| Stable / Active → Distributed | Primary Accountable Agent | Transfer |
| Any → Hibernating | Current custodian(s) | Lower |
| Hibernating → [prior stage] | Current custodian(s) | Raise |
| Hibernating → Active (custodian claim) | Any AccountableAgent — inactivity criteria met (governance-configured threshold) | Raise |
| Any → Deprecated | Custodian + successor NDO declared | Cite |
| Any → EndOfLife | Custodian + challenge period elapsed | Consume |
5. Zome Responsibility Boundaries

zome_person owns identity and roles. zome_resource owns NDO entry types. zome_gouvernance owns the accountability cycle (Commitment/Event/Claim/PPR). hREA DNA is the source of truth for ValueFlows. Arrows show authorized cross-zome call directions.
hREA DNA — VF Core Layer
Owns: All VF 1.0 core types. Accessed via CallTargetCell::OtherRole("hrea").
- Entry types:
ReaEconomicResource,ReaEconomicEvent,ReaCommitment,ReaAgreement,ReaProcess,ReaResourceSpecification,ReaAgent,ReaUnit, + all other VF types - NDO interacts with hREA only through its coordinator public functions — never reads hREA's source chain directly
- hREA Phase 1+2 roadmap:
documentation/hREA/strategic-roadmap.md
zome_resource — NDO Identity & Extension Layer
Owns: NDO-specific resource data. No business logic. Cross-DNA calls to hREA for VF operations.
- Entry types:
Unit,NondominiumIdentity,ResourceSpecification(NDO extension — category, tags, image, is_active),GovernanceRule - Responsibility: Layer 0 identity anchors, NDO resource spec extensions, governance rule storage, capability slots
- Cross-DNA calls:
create_rea_resource_specification,create_rea_economic_resource(stores returned hashes) - Does NOT: Own VF core types, evaluate governance rules, issue PPRs, approve state transitions
zome_gouvernance — Operator & Accountability
Owns: NDO governance logic. NDO-specific accountability types. Orchestrates hREA economic events.
- Entry types:
Fulfillment(Rust:Claim— ADR-004),ValidationReceipt,ResourceValidation,PrivateParticipationClaim - Responsibility: Receive transition requests. Evaluate GovernanceRules. Call hREA to create EconomicEvents, Commitments, Agreements. Issue PPRs after hREA call succeeds.
- Cross-DNA calls:
create_rea_economic_event,create_rea_commitment,create_rea_agreement,create_rea_process - Does NOT: Create hREA entries without governance evaluation; own VF core types
zome_person — Identity & Privacy
Owns: Agent identity, capability grants, roles, devices.
- No changes in v1.0.
- Post-v1.0: Add
AgentContextunion type,AffiliationRecord.
Cross-DNA + Cross-Zome Call Pattern (governance-as-operator)
sequenceDiagram
actor Agent
participant ZR as zome_resource<br/>(NDO — identity/extension)
participant ZG as zome_gouvernance<br/>(NDO — operator)
participant ZP as zome_person<br/>(NDO — identity)
participant HR as hREA DNA<br/>(VF core types)
Agent->>ZR: request_resource_transition(input)
ZR->>ZG: cross_zome_call("evaluate_transition", request)
ZG->>ZR: cross_zome_call("get_governance_rules", spec_hash)
ZR-->>ZG: Vec<GovernanceRule>
ZG->>ZP: cross_zome_call("get_agent_capability_level", agent_pub_key)
ZP-->>ZG: CapabilityLevel
ZG->>ZG: evaluate rules against request + capability
alt approved
ZG->>HR: cross_dna_call("create_rea_economic_event", event_input)
HR-->>ZG: ActionHash (hREA event hash)
ZG->>ZR: cross_zome_call("update_resource_operational_state", new_state)
ZR-->>ZG: ActionHash
ZG->>ZG: issue_ppr(hrea_event_hash, participants)
ZG-->>ZR: Ok(hrea_event_hash)
ZR-->>Agent: Ok(hrea_event_hash)
else rejected
ZG-->>ZR: Err(GovernanceViolation)
ZR-->>Agent: Err(GovernanceViolation)
end
6. Coordinator Function Signatures (New & Updated)
zome_resource — New Functions
#![allow(unused)] fn main() { // Unit management fn create_unit(input: CreateUnitInput) -> ExternResult<ActionHash> fn get_unit(unit_hash: ActionHash) -> ExternResult<Option<Record>> fn get_all_units() -> ExternResult<Vec<UnitRecord>> // NDO Layer 0 management fn create_ndo(input: CreateNDOInput) -> ExternResult<ActionHash> fn get_ndo(ndo_hash: ActionHash) -> ExternResult<Option<Record>> fn get_all_ndos() -> ExternResult<Vec<NDORecord>> fn get_ndos_by_lifecycle_stage(stage: LifecycleStage) -> ExternResult<Vec<ActionHash>> fn get_ndos_by_nature(nature: ResourceNature) -> ExternResult<Vec<ActionHash>> fn get_ndos_by_regime(regime: PropertyRegime) -> ExternResult<Vec<ActionHash>> fn update_ndo_lifecycle(input: UpdateNDOLifecycleInput) -> ExternResult<ActionHash> // UpdateNDOLifecycleInput { original_hash, previous_hash, new_stage, transition_event_hash } // Layer activation fn activate_layer1(ndo_hash: ActionHash, spec_hash: ActionHash) -> ExternResult<()> fn activate_layer2(ndo_hash: ActionHash, process_hash: ActionHash) -> ExternResult<()> fn get_ndo_layer1(ndo_hash: ActionHash) -> ExternResult<Option<Record>> // latest ResourceSpec fn get_ndo_layer2(ndo_hash: ActionHash) -> ExternResult<Option<Record>> // active Process // Capability slots fn add_capability_slot(input: AddCapabilitySlotInput) -> ExternResult<()> // AddCapabilitySlotInput { ndo_hash, target_hash, slot_type, label } fn get_capability_slots(ndo_hash: ActionHash) -> ExternResult<Vec<CapabilitySlotRecord>> fn get_slots_by_type(ndo_hash: ActionHash, slot_type: SlotType) -> ExternResult<Vec<ActionHash>> }
zome_resource — Updated Signatures
#![allow(unused)] fn main() { // ResourceSpecification now includes VF fields fn create_resource_specification(input: CreateResourceSpecInput) -> ExternResult<ActionHash> // CreateResourceSpecInput adds: default_unit_of_resource, default_unit_of_effort, // medium_of_exchange, substitutable // EconomicResource now uses QuantityValue, primary_accountable, conforms_to fn create_economic_resource(input: CreateEconomicResourceInput) -> ExternResult<ActionHash> // CreateEconomicResourceInput: accounting_quantity: QuantityValue, onhand_quantity: QuantityValue, // primary_accountable: AgentPubKey, custodian: Option<AgentPubKey>, // conforms_to: ActionHash, current_location: Option<String> // State update now uses OperationalState fn update_economic_resource_operational_state( input: UpdateOperationalStateInput ) -> ExternResult<ActionHash> // UpdateOperationalStateInput { original_hash, previous_hash, new_state: OperationalState, // triggering_event_hash: ActionHash } }
zome_gouvernance — New Functions
#![allow(unused)] fn main() { // Process management fn create_process(input: CreateProcessInput) -> ExternResult<ActionHash> fn get_process(process_hash: ActionHash) -> ExternResult<Option<Record>> fn get_all_processes() -> ExternResult<Vec<ProcessRecord>> fn conclude_process(process_hash: ActionHash, terminal_event_hash: ActionHash) -> ExternResult<()> // Agreement management fn create_agreement(input: CreateAgreementInput) -> ExternResult<ActionHash> fn get_agreement(agreement_hash: ActionHash) -> ExternResult<Option<Record>> fn get_all_agreements() -> ExternResult<Vec<AgreementRecord>> fn get_agreement_commitments(agreement_hash: ActionHash) -> ExternResult<Vec<ActionHash>> fn get_agreement_events(agreement_hash: ActionHash) -> ExternResult<Vec<ActionHash>> }
7. VfAction — Preserved + Context
The VfAction enum is unchanged in v1.0. NDO-specific extensions (InitialTransfer, AccessForUse, TransferCustody) are preserved. The semantic methods (requires_existing_resource, creates_resource, modifies_quantity, changes_custody) are preserved.
Post-v1.0 addition: corrects → EconomicEvent (correction events) — not yet in scope.
8. PPR System — Preserved Unchanged
The PrivateParticipationClaim (16-category bilateral cryptographic participation receipts) is unchanged in v1.0. It is not a VF class — it is an NDO innovation that extends VF's Claim concept with bilateral accountability.
The PPR PerformanceMetrics struct (timeliness, quality, reliability, communication weights) is unchanged.
ReputationSummary computation is unchanged.
9. Explicit Out-of-Scope for v1.0
| Feature | Reason | Phase |
|---|---|---|
AgentContext union (collective, project, network, bot, external) | Requires governance refactoring across all 3 zomes; collective variants use dual-face model — agent face (AgentContext) + resource face (NondominiumIdentity) linked by ActionHash; multi-sig collective actions post-v1.0 | Post-v1.0 |
AffiliationRecord + AffiliationState derivation | Depends on AgentContext | Post-v1.0 |
| Flowsta Phase 2/3 (governance enforcement of identity verification) | Stub in GovernanceRuleType; UI/governance integration separate | Post-v1.0 |
| Unyt Smart Agreement full integration | Stub in GovernanceRuleType + SlotType; RAVE proof validation separate | Post-v1.0 |
vf:Intent | Valid VF 1.0 class — deferred post-v1.0; extension path via CapabilitySlot surface | Post-v1.0 |
vf:Claim (reciprocity, settlement) | NDO Fulfillment entry (Rust: Claim) has fulfillment semantics; VF reciprocity Claim = post-v1.0 | Post-v1.0 |
ProcessSpecification | Not yet needed | Post-v1.0 |
| Many-to-many flows (multi-custodian) | Architecture requires AgentContext | Post-v1.0 |
| Versioning DAG / digital resource integrity | Separate specification | Post-v1.0 |
| Network and federation governance layers | Requires holonic governance design | Post-v1.0 |
| Non-binary decision mechanisms (conviction voting, quadratic) | Governance extension | Post-v1.0 |
| ZKP proofs for affiliation privacy | Cryptographic infrastructure | Post-v1.0 |
| Dispute resolution mechanism | Beyond PPR category placeholder | Post-v1.0 |
| Frontend updates | Separate work | Separate |
| GovernanceRule typed rule_data schemas (per GovernanceRuleType) | Phase 2 governance work | Post-v1.0 |
10. Architecture Decision Records
ADR-001: QuantityValue as mandatory (not Option)
- Status: Accepted
- Decision:
accounting_quantityandonhand_quantityare required fields onEconomicResource, not Optional. Unit entry must exist before EconomicResource creation. - Rationale: VF compliance. Optional quantity is meaningless for resource tracking. If quantity is unknown, use 0.0 with an appropriate unit.
- Consequence: All EconomicResource creation call sites must be updated. Test fixtures need Unit entries created first.
ADR-002: conforms_to as embedded ActionHash (not link-only)
- Status: Accepted
- Decision:
EconomicResource.conforms_to: ActionHashis embedded in the entry, not expressed only viaSpecificationToResourcelink. - Rationale: VF compliance. Bi-directional: embed on resource (resource knows its spec) + keep link from spec (spec knows its instances). Discovery works both ways.
- Consequence:
conforms_tois required on creation. Cannot have an EconomicResource without a ResourceSpecification.
ADR-003: GovernanceRule.rule_data remains String in v1.0
- Status: Accepted
- Decision:
GovernanceRule.rule_typechanges toGovernanceRuleTypeenum, butrule_data: String(JSON) remains untyped in v1.0. - Rationale: Defining typed schemas for each
GovernanceRuleTypevariant (AccessRequirement params, MaintenanceSchedule params, etc.) is substantial design work beyond v1.0 scope. The enum gives us type-safety on the category without requiring complete schema for each. - Consequence: Runtime validation of rule_data remains the responsibility of the coordinator. Phase 2 will add typed rule_data per variant.
ADR-004: NDO's Claim entry retains name but repurposed as Fulfillment
- Status: Accepted
- Decision: The current
Claimentry (fulfills → Commitment, fulfilled_by → EconomicEvent) is semantically a VF "fulfillment bridge." It is NOT VF'svf:Claim(reciprocity). Rust struct keeps nameClaim; design docs call it "Fulfillment." - Rationale: Renaming the Rust type in v1.0 would be a larger refactor than the value it provides. VF compliance is achieved via
EconomicEvent.fulfills → Commitment(direct field); the bridge entry becomes redundant but is kept for audit trail. - Consequence: Post-v1.0, the Claim entry may be renamed to Fulfillment and VF's reciprocity Claim added as a new entry type.
ADR-005: Process entry type lives in zome_gouvernance
- Status: Accepted
- Decision:
Processentry type is defined inzome_gouvernanceintegrity, notzome_resource. - Rationale: Processes are governed economic activities. Layer 2 activation link (
NDOToProcess) inzome_resourceLinkTypes points to aProcessentry hash inzome_gouvernance— cross-zome ActionHash references are valid in Holochain. - Consequence: The NDO Layer 2 activation is a cross-zome link.
get_ndo_layer2(ndo_hash)in the resource coordinator must make a cross-zome call to retrieve the Process record.
ADR-006: VF core types delegated to hREA DNA, not reimplemented in NDO
- Status: Accepted
- Decision: NDO does not re-implement VF entry types (EconomicResource, EconomicEvent, Commitment, Agreement, Process, ResourceSpecification). All VF core types are owned by the
hreaDNA (registered asOtherRole("hrea")inhapp.yaml). NDO coordinator zomes call hREA functions and store returnedActionHashvalues. - Rationale: Avoids duplication and divergence. hREA is the canonical VF 1.0 implementation. NDO's value is in governance, identity, and accountability layers — not in reimplementing economic primitives. The
vendor/hreasubmodule is already a live runtime DNA in the bundle. - Consequence: NDO v1.0 capabilities are bounded by hREA's current compliance level (~65% VF 1.0). P0 gaps in hREA (
effortQuantity,vf:Claim) must be resolved before NDO's work-event recording and claim-based reciprocity workflows are available. Seedocumentation/hREA/strategic-roadmap.mdfor the Phase 1 gap closure plan.
11. Migration Notes (Current → v1.0)
| Current | v1.0 | Migration |
|---|---|---|
EconomicResource.quantity: f64 | accounting_quantity: QuantityValue + onhand_quantity: QuantityValue | All creation call sites; test fixtures need Unit entries |
EconomicResource.unit: String | Removed (unit is in QuantityValue) | See above |
EconomicResource.custodian: AgentPubKey | primary_accountable: AgentPubKey + custodian: Option<AgentPubKey> | Rename + add physical custody field |
ResourceState enum | OperationalState enum (on EconomicResource) + LifecycleStage (on NondominiumIdentity) | State mapping: Active→Available, PendingValidation→PendingValidation, Maintenance→InMaintenance, Retired→EndOfLife, Reserved→Reserved |
GovernanceRule.rule_type: String | GovernanceRule.rule_type: GovernanceRuleType | All coordinator match arms |
EconomicEvent.resource_quantity: f64 | resource_quantity: QuantityValue | Same as EconomicResource quantity migration |
| No Agreement | Agreement entry in zome_gouvernance | New entry type, new coordinator functions |
| No NondominiumIdentity | NondominiumIdentity entry in zome_resource | New entry type; no existing entries to migrate |
| No Process entry | Process entry in zome_gouvernance | New entry type for Layer 2 activation |
| No Unit entry | Unit entry in zome_resource | New entry type; must be created before EconomicResource |
Nondominium Architecture Components
- Generated: 2025-10-30
- Updated: 2025-11-23
- Version: 3.0 (Improved mermaid diagrams)
- Scope: Detailed component breakdown and interaction patterns
🎯 Executive Summary
Nondominium implements a multi-DNA Holochain architecture that enables distributed resource sharing with embedded governance, capability-based security, and cryptographically-secured reputation tracking. The hApp composes five DNA roles into a fractal Lobby → Group → NDO holarchy:
- Nondominium DNA (provisioned, shared): the 3-zome core (
zome_person,zome_resource,zome_gouvernance) detailed throughout this document - Lobby DNA (provisioned, fixed network seed): permissionless entry point — agent presence and the global group registry (PR #103; see
zomes/lobby_zome.md) - Group DNA (one cloned cell per group,
deferred: true): per-group coordination DHT with network isolation (PR #107; seezomes/group_zome.md) - NDO DNA (one cloned cell per NDO,
deferred: true): per-NDO resource network bundling the existing resource and governance zome WASMs; the clone's DNA hash is the NDO's permanent identity (issue #112, ADR-010/011/012) - hREA DNA (vendored): canonical ValueFlows event recording via the hREA bridge
The core supports four structured Economic Processes (Use, Transport, Storage, Repair) with role-based access control and a 16-category PPR reputation system for trustworthy agent interactions.
🏗️ System Architecture
High-Level System Architecture
graph TB
subgraph "Frontend Layer"
UI["Svelte 5.0 + TypeScript"]
Client["holochain-client ^0.20.0"]
end
subgraph "Holochain Runtime"
WASM[WASM Compilation]
DHT[DHT-based P2P Networks]
CapSec[Capability-Based Security]
end
subgraph "Lobby DNA (provisioned)"
Lobby["zome_lobby<br/>Agent presence + group registry"]
end
subgraph "Group DNA (cloned per group)"
Group["zome_group<br/>Membership, work logs, soft links, NDO anchors"]
end
subgraph "NDO DNA (cloned per NDO)"
NdoCell["zome_resource + zome_gouvernance<br/>One network per NDO"]
end
subgraph "Nondominium DNA (3-zome core)"
Person["zome_person<br/>Identity and Access"]
Resource["zome_resource<br/>Resource Management"]
Gov["zome_gouvernance<br/>Governance and Reputation"]
end
UI --> Client
Client --> WASM
WASM --> DHT
WASM --> CapSec
Lobby --> DHT
Group --> DHT
NdoCell --> DHT
Person --> DHT
Resource --> DHT
Gov --> DHT
Data Flow Architecture
sequenceDiagram
participant Agent as Agent Request
participant UI as UI Client
participant Auth as Auth & Cap Check
participant Role as Role Validation
participant Zome as Zome Function
participant PPR as PPR System
Agent->>UI: Submit Request
UI->>Auth: Validate Capability Token
Auth->>Role: Check Role Permissions
Role->>Zome: Execute Function
Zome->>PPR: Issue PPR if Applicable
PPR-->>Zome: PPR Issued
Zome-->>Role: Function Result
Role-->>Auth: Validation Complete
Auth-->>UI: Access Granted
UI-->>Agent: Response/Result
Core Technology Stack
┌─────────────────────────────────────────────────────────────┐
│ FRONTEND LAYER │
├─────────────────────────────────────────────────────────────┤
│ Svelte 5.0 + TypeScript + Vite 7 │
│ @holochain/client ^0.20.0 │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ HOLOCHAIN RUNTIME │
├─────────────────────────────────────────────────────────────┤
│ Rust (HDK ^0.6.0 / HDI ^0.7.0) → WASM Compilation │
│ DHT-based peer-to-peer network │
│ Capability-based security & gossip │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ ZOME LAYER │
├─────────────────────────────────────────────────────────────┤
│ zome_person │ zome_resource │ zome_gouvernance │
│ (Identity) │ (Resources) │ (Governance) │
└─────────────────────────────────────────────────────────────┘
🔐 Zome Components
1. zome_person - Identity & Access Management
Zome Person Architecture
graph TB
subgraph "zome_person"
subgraph "Agent Identity"
Person[Person Entry<br/>Public Profile]
EncProfile[PrivatePersonData<br/>Private Data]
Discovery[Discovery Anchors<br/>Agent Directory]
end
subgraph "Capability System"
CapToken["CapabilityToken<br/>Role-based Access"]
CapProgress["CapabilityProgression<br/>Trust Advancement"]
ACL["Access Control Lists<br/>Resource Permissions"]
end
subgraph "Private Data Sharing"
DataReq["DataAccessRequest<br/>time-limited (max 30d)"]
DataGrant["DataAccessGrant<br/>Field-specific Control"]
PrivateData["PrivateDataEntry<br/>Encrypted Info"]
end
subgraph "Role Management"
RoleAssign["RoleAssignment<br/>Validation Metadata"]
RoleQual["RoleQualification<br/>Requirements Tracking"]
RoleProgress["RoleProgression<br/>Advancement Criteria"]
end
end
Person --> Discovery
EncProfile --> DataGrant
CapToken --> CapProgress
DataReq --> DataGrant
RoleAssign --> RoleQual
Core Components
┌─────────────────────────────────────────────────────────────┐
│ zome_person │
├─────────────────────────────────────────────────────────────┤
│ 1.1 AGENT IDENTITY │
│ ├── Person Entry (public profile) │
│ ├── PrivatePersonData Entry (private data) │
│ └── Discovery Anchors (findable agent directory) │
│ │
│ 1.2 CAPABILITY SYSTEM │
│ ├── CapabilityToken Entry (role-based access) │
│ ├── CapabilityProgression (trust advancement) │
│ └── Access Control Lists (resource permissions) │
│ │
│ 1.3 PRIVATE DATA SHARING │
│ ├── DataAccessRequest Entry (time-limited; max 30-day grants) │
│ ├── DataAccessGrant Entry (field-specific control) │
│ └── PrivateDataEntry (encrypted personal information) │
│ │
│ 1.4 ROLE MANAGEMENT │
│ ├── RoleAssignment Entry (with validation metadata) │
│ ├── RoleQualification Entry (requirements tracking) │
│ └── RoleProgression Entry (advancement criteria) │
└─────────────────────────────────────────────────────────────┘
Key Functions
#![allow(unused)] fn main() { // Identity Management create_person(PersonInput) -> PersonHash get_person(PersonHash) -> Person get_all_persons() -> Vec<Person> update_person(PersonHash, PersonInput) -> PersonHash delete_person(PersonHash) -> DeleteResult // Capability Management create_capability_token(CapabilityRequest) -> CapabilityTokenHash get_agent_capability_level(AgentPubKey) -> CapabilityLevel promote_agent_capability(AgentPubKey, PromotionCriteria) -> PromotionResult // Private Data Sharing request_private_data_access(DataAccessRequest) -> RequestHash grant_private_data_access(RequestHash, GrantDetails) -> GrantHash get_private_data(GrantHash, FieldList) -> PrivateData revoke_private_data_access(GrantHash) -> RevokeResult // Role Management assign_role(AgentPubKey, RoleAssignment) -> RoleHash get_agent_roles(AgentPubKey) -> Vec<RoleAssignment> validate_role_requirements(AgentPubKey, RoleType) -> ValidationStatus }
2. zome_resource - Resource Lifecycle Management
Zome Resource Architecture
graph TB
subgraph "zome_resource"
subgraph "Resource Specification"
ResSpec[ResourceSpecification<br/>Type Definition]
ResProp[ResourceProperty<br/>Custom Properties]
SpecCat[SpecificationCategory<br/>Classification]
end
subgraph "Economic Resource"
EconRes[EconomicResource<br/>Resource Instance]
ResState[LifecycleStage on NDO + OperationalState on EconomicResource]
ResHistory[ResourceHistory<br/>Audit Trail]
ResCustody[ResourceCustody<br/>Custody Tracking]
end
subgraph "Economic Processes"
UseProc[UseProcess<br/>Time-limited Access]
TransProc[TransportProcess<br/>Location Movement]
StorageProc[StorageProcess<br/>Preservation]
RepairProc[RepairProcess<br/>Restoration]
end
subgraph "Economic Events"
EconEvent[EconomicEvent<br/>State Changes]
EventVal[EventValidation<br/>Validation Workflow]
EventImpact[EventImpact<br/>Resource Impact]
end
end
ResSpec --> EconRes
ResProp --> ResSpec
SpecCat --> ResSpec
EconRes --> ResState
EconRes --> ResHistory
EconRes --> ResCustody
UseProc --> EconEvent
TransProc --> EconEvent
StorageProc --> EconEvent
RepairProc --> EconEvent
EconEvent --> EventVal
EconEvent --> EventImpact
Core Components
┌─────────────────────────────────────────────────────────────┐
│ zome_resource │
├─────────────────────────────────────────────────────────────┤
│ 2.1 RESOURCE SPECIFICATION │
│ ├── ResourceSpecification Entry (type definition) │
│ ├── ResourceProperty Entry (custom properties) │
│ └── SpecificationCategory Entry (classification) │
│ │
│ 2.2 ECONOMIC RESOURCE │
│ ├── EconomicResource Entry (resource instance) │
│ ├── LifecycleStage (on NondominiumIdentity) + OperationalState (on EconomicResource) │
│ ├── ResourceHistory Entry (audit trail) │
│ └── ResourceCustody Entry (custody tracking) │
│ │
│ 2.3 ECONOMIC PROCESSES │
│ ├── UseProcess Entry (time-limited access) │
│ ├── TransportProcess Entry (location movement) │
│ ├── StorageProcess Entry (preservation) │
│ └── RepairProcess Entry (restoration) │
│ │
│ 2.4 ECONOMIC EVENTS │
│ ├── EconomicEvent Entry (state changes) │
│ ├── EventValidation Entry (validation workflow) │
│ └── EventImpact Entry (resource impact tracking) │
└─────────────────────────────────────────────────────────────┘
Key Functions
#![allow(unused)] fn main() { // Resource Specification create_resource_specification(ResourceSpecInput) -> ResourceSpecHash get_resource_specification(ResourceSpecHash) -> ResourceSpecification update_resource_specification(ResourceSpecHash, ResourceSpecInput) -> ResourceSpecHash // Economic Resource Management create_economic_resource(ResourceInput) -> EconomicResourceHash get_economic_resource(EconomicResourceHash) -> EconomicResource update_economic_resource(EconomicResourceHash, ResourceUpdate) -> EconomicResourceHash transfer_resource_custody(EconomicResourceHash, AgentPubKey) -> TransferResult // Economic Process Management initiate_use_process(UseProcessInput) -> UseProcessHash initiate_transport_process(TransportProcessInput) -> TransportProcessHash initiate_storage_process(StorageProcessInput) -> StorageProcessHash initiate_repair_process(RepairProcessInput) -> RepairProcessHash // Process Execution complete_use_process(UseProcessHash, CompletionDetails) -> CompletionResult complete_transport_process(TransportProcessHash, TransportDetails) -> CompletionResult complete_storage_process(StorageProcessHash, StorageDetails) -> CompletionResult complete_repair_process(RepairProcessHash, RepairDetails) -> CompletionResult }
3. zome_gouvernance - Governance & Reputation
Zome Governance Architecture
graph TB
subgraph "zome_gouvernance"
subgraph "Commitment System"
Commitment[Commitment<br/>Agreements & Obligations]
CommitFulfill[CommitmentFulfillment<br/>Completion Tracking]
CommitValidation[CommitmentValidation<br/>Validation Workflow]
end
subgraph "PPR Reputation System"
PPR[PPR Entry<br/>14 Categories]
PPRValidation[PPRValidation<br/>Crypto Verification]
ReputationSummary[ReputationSummary<br/>Derived Metrics]
PPRMilestone[PPRMilestone<br/>Advancement Criteria]
end
subgraph "Multi-Reviewer Validation"
ValWorkflow[ValidationWorkflow<br/>Validation Setup]
ValReview[ValidationReview<br/>Individual Assessments]
ValConsensus[ValidationConsensus<br/>Consensus Determination]
ValAppeal[ValidationAppeal<br/>Dispute Resolution]
end
subgraph "Agent Promotion"
PromotionElig[PromotionEligibility<br/>Qualification Check]
PromotionApp[PromotionApplication<br/>Advancement Request]
PromotionDecision[PromotionDecision<br/>Approval/Rejection]
PromotionHistory[PromotionHistory<br/>Audit Trail]
end
end
Commitment --> CommitFulfill
CommitFulfill --> CommitValidation
PPR --> PPRValidation
PPRValidation --> ReputationSummary
ReputationSummary --> PPRMilestone
ValWorkflow --> ValReview
ValReview --> ValConsensus
ValConsensus --> ValAppeal
PromotionElig --> PromotionApp
PromotionApp --> PromotionDecision
PromotionDecision --> PromotionHistory
PPRMilestone -.-> PromotionElig
ValConsensus -.-> PPRValidation
Core Components
┌─────────────────────────────────────────────────────────────┐
│ zome_gouvernance │
├─────────────────────────────────────────────────────────────┤
│ 3.1 COMMITMENT SYSTEM │
│ ├── Commitment Entry (agreements & obligations) │
│ ├── CommitmentFulfillment Entry (completion tracking) │
│ └── CommitmentValidation Entry (validation workflow) │
│ │
│ 3.2 PPR REPUTATION SYSTEM │
│ ├── PPR Entry (14 reputation categories) │
│ ├── PPRValidation Entry (cryptographic verification) │
│ ├── ReputationSummary Entry (derived metrics) │
│ └── PPRMilestone Entry (advancement criteria) │
│ │
│ 3.3 MULTI-REVIEWER VALIDATION │
│ ├── ValidationWorkflow Entry (validation setup) │
│ ├── ValidationReview Entry (individual assessments) │
│ ├── ValidationConsensus Entry (consensus determination) │
│ └── ValidationAppeal Entry (dispute resolution) │
│ │
│ 3.4 AGENT PROMOTION │
│ ├── PromotionEligibility Entry (qualification check) │
│ ├── PromotionApplication Entry (advancement request) │
│ ├── PromotionDecision Entry (approval/rejection) │
│ └── PromotionHistory Entry (audit trail) │
└─────────────────────────────────────────────────────────────┘
PPR System Categories
#![allow(unused)] fn main() { pub enum PPRCategory { // Resource & Service Categories ResourceContribution, // Resource creation and validation ResourceValidation, // Resource quality assessment UseService, // Use process participation TransportService, // Transport service provision StorageService, // Storage service provision RepairService, // Repair service provision ServiceValidation, // Service quality assessment // Governance & Community Categories CommitmentFulfillment, // Commitment completion tracking GovernanceParticipation, // Governance activity participation Custodianship, // Resource custody responsibilities DisputeResolution, // Conflict resolution participation CoordinationService, // Coordination activities Mentorship, // Knowledge sharing and guidance CommunityBuilding, // Community development activities } }
Key Functions
#![allow(unused)] fn main() { // Commitment Management create_commitment(CommitmentInput) -> CommitmentHash get_commitment(CommitmentHash) -> Commitment fulfill_commitment(CommitmentHash, FulfillmentDetails) -> FulfillmentResult validate_commitment_fulfillment(CommitmentHash) -> ValidationResult // PPR System issue_ppr(PPRIssuanceRequest) -> PPRHash get_ppr_summary(AgentPubKey, PPRCategory) -> PPRSummary validate_ppr_eligibility(AgentPubKey, PPRCategory) -> EligibilityResult derive_reputation_score(AgentPubKey) -> ReputationMetrics // Multi-Reviewer Validation create_validation_workflow(ValidationWorkflowInput) -> WorkflowHash submit_validation_review(WorkflowHash, ValidationReview) -> ReviewHash check_validation_consensus(WorkflowHash) -> ConsensusResult appeal_validation_decision(WorkflowHash, AppealDetails) -> AppealHash // Agent Promotion evaluate_agent_promotion(AgentPubKey, PromotionType) -> EvaluationResult promote_to_accountable_agent(AgentPubKey) -> PromotionResult promote_to_primary_accountable_agent(AgentPubKey) -> PromotionResult get_promotion_history(AgentPubKey) -> Vec<PromotionRecord> }
🔄 Cross-Zome Integration Patterns
Cross-Zome Data Flow
graph LR
subgraph "zome_person"
Person[Person Entry]
CapToken[Capability Token]
RoleAssign[Role Assignment]
end
subgraph "zome_resource"
ResSpec[Resource Spec]
EconRes[Economic Resource]
UseProc[Use Process]
EconEvent[Economic Event]
end
subgraph "zome_gouvernance"
PPR[PPR Entry]
Commitment[Commitment]
ValWorkflow[Validation Workflow]
Promotion[Promotion]
end
Person --> CapToken
CapToken --> RoleAssign
RoleAssign -.-> UseProc
ResSpec --> EconRes
EconRes --> UseProc
UseProc --> EconEvent
EconEvent --> PPR
PPR --> ValWorkflow
ValWorkflow --> Promotion
Promotion -.-> CapToken
1. Capability Progression Integration
sequenceDiagram
participant Agent as Agent
participant Person as zome_person
participant Resource as zome_resource
participant Gov as zome_gouvernance
Agent->>Person: Request Process Access
Person->>Person: Get Capability Level
Person->>Gov: Get Reputation Score
Gov-->>Person: Return Reputation
Person->>Person: Validate Process Access
alt Access Granted
Person->>Resource: Authorize Process
Resource->>Resource: Execute Economic Process
Resource->>Gov: Trigger PPR Issuance
Gov->>Gov: Update Agent Reputation
Gov-->>Person: Promotion Eligibility
Person-->>Agent: Process Complete
else Access Denied
Person-->>Agent: Access Denied
end
#![allow(unused)] fn main() { // Cross-zome capability validation fn validate_process_access(agent: AgentPubKey, process_type: EconomicProcess) -> bool { let capability = zome_person::get_agent_capability_level(agent)?; let reputation = zome_gouvernance::derive_reputation_score(agent)?; match process_type { EconomicProcess::Use => { // Accountable Agent (stewardship) or higher capability.level >= CapabilityLevel::Accountable }, EconomicProcess::Transport | EconomicProcess::Storage | EconomicProcess::Repair => { // Primary Accountable Agent (coordination/governance) only capability.level >= CapabilityLevel::Primary && reputation.exceeds_threshold(PROMOTION_THRESHOLD) } } } }
2. PPR Issuance Coordination
#![allow(unused)] fn main() { // PPR issuance coordination across zomes fn coordinate_ppr_issuance(event: EconomicEvent) -> Vec<PPRIssuance> { let mut issuances = Vec::new(); // Resource-based PPRs (zome_resource coordination) if let Some(resource) = event.affected_resource { if event.action == VfAction::Produce { issuances.push(PPRIssuance { recipient: event.provider, category: PPRCategory::ResourceContribution, evidence: resource.hash, }); } } // Process-based PPRs (cross-zome coordination) if let Some(process) = event.process { match process.process_type { UseProcess => issuances.push(PPRIssuance { recipient: event.receiver, category: PPRCategory::UseService, evidence: process.hash, }), TransportProcess => issuances.push(PPRIssuance { recipient: event.provider, category: PPRCategory::TransportService, evidence: process.hash, }), // ... other process types } } issuances } }
3. Private Data Sharing with Economic Processes
#![allow(unused)] fn main() { // Private data access for economic processes fn authorize_process_data_access( process: EconomicProcess, requesting_agent: AgentPubKey, required_fields: Vec<PrivateDataField> ) -> Result<DataAccessGrant, DataAccessError> { // Validate process participation let participation = validate_process_participation(process, requesting_agent)?; // Check role requirements let role = zome_person::get_agent_roles(requesting_agent)? .into_iter() .find(|r| r.matches_process_requirements(&process)) .ok_or(DataAccessError::InsufficientRole)?; // Illustrative pseudocode — align grant duration with zome_person capability rules (30-day max). let grant = DataAccessGrant { requesting_agent, granting_agent: process.resource_owner, accessible_fields: required_fields, expires_at: sys_time()? + Duration::from_secs(7 * 24 * 60 * 60), // example: 7 days; cap 30 days in MVP metadata purpose: format!("Data access for {} process", process.process_type), process_context: process.hash, }; Ok(grant) } }
🛡️ Security Architecture
Capability-Based Access Control Flow
graph TD
subgraph "Trust Levels"
Simple[Simple Agent<br/>Basic Member]
Accountable[Accountable Agent<br/>Stewardship Role]
Primary[Primary Accountable<br/>Coordination Role]
Advanced[Advanced Agent<br/>Governance Role]
end
subgraph "Simple Agent Capabilities"
S1[General Capability Token]
S2[Create Resources]
S3[Initial Transfer]
S4[Basic PPR Eligibility]
end
subgraph "Accountable Agent Capabilities"
A1[Restricted Capability Token<br/>Role-specific]
A2[Access Resources]
A3[Validate Others]
A4[Initiate Use Processes]
A5[Service PPR Eligibility]
end
subgraph "Primary Accountable Capabilities"
P1[Full Capability Token<br/>Comprehensive Access]
P2[Hold Custody]
P3[Validate Specialized Roles]
P4[Initiate All Processes]
P5[All 16 PPR Categories<br/>Including Custodianship]
end
subgraph "Advanced Agent Capabilities"
AD1[Advanced Governance Token]
AD2[Dispute Resolution]
AD3[End-of-Life Validation]
AD4[System Leadership]
end
Simple --> S1 --> S2 --> S3 --> S4 --> Accountable
Accountable --> A1 --> A2 --> A3 --> A4 --> A5 --> Primary
Primary --> P1 --> P2 --> P3 --> P4 --> P5 --> Advanced
Advanced --> AD1 --> AD2 --> AD3 --> AD4
1. Capability-Based Access Control
Trust Level Progression:
Simple Agent (member)
├── General Capability Token
├── Can: Create resources, make InitialTransfer
├── PPR Eligibility: ResourceContribution upon validation
└── Promotion Criteria: First validated transaction
Accountable Agent (stewardship)
├── Restricted Capability Token (role-specific)
├── Can: Access resources, validate others, initiate Use processes
├── PPR Eligibility: Service processes, validation activities
└── Promotion Criteria: PPR milestones + specialized role validation
Primary Accountable Agent (coordination/governance)
├── Full Capability Token (comprehensive access)
├── Can: Hold custody, validate specialized roles, initiate all processes
├── PPR Eligibility: All 16 categories including custodianship
└── Advanced: Dispute resolution, end-of-life validation
2. Cryptographic Reputation System
PPR Cryptographic Structure:
├── Issuer Signature (Ed25519)
├── Recipient Identity (AgentPubKey)
├── Category & Evidence (Process/Resource hash)
├── Timestamp & Expiration
├── Validation Metadata (Reviewer signatures)
└── Reputation Impact Calculation
Reputation Derivation:
├── PPR Collection (all categories)
├── Quality Scoring (reviewer assessments)
├── Temporal Weighting (recent > historical)
├── Category Diversity (balanced participation)
└── Cryptographic Proof (tamper-evident)
3. Private Data Protection
Data Access Control:
├── Field-Level Granularity (specific data elements)
├── Time-Limited Grants (30-day maximum per capability metadata)
├── Purpose Binding (process-specific usage)
├── Automatic Expiration (system-enforced)
├── Audit Trail (access logging)
└── Revocation Capability (immediate termination)
Encryption Strategy:
├── End-to-End Encryption (agent-to-agent)
├── Key Management (capability-based)
├── Secure Storage (encrypted entries)
├── Access Validation (real-time checks)
└── Secure Transmission (Holochain secure messaging)
📊 Economic Process Architecture
Economic Process Flow
graph TB
subgraph "Economic Resources"
Resource[Economic Resource<br/>Physical/Digital Asset]
Spec[Resource Specification<br/>Type & Properties]
end
subgraph "Process Types"
Use[Use Process<br/>Time-Limited Access]
Transport[Transport Process<br/>Custody Transfer]
Storage[Storage Process<br/>Preservation]
Repair[Repair Process<br/>Restoration]
end
subgraph "Process Roles"
User[User<br/>Accountable Agent]
Provider[Provider<br/>Resource Owner]
Transporter[Transporter<br/>Primary Accountable]
StorageProvider[Storage Provider<br/>Primary Accountable]
RepairProvider[Repair Provider<br/>Primary Accountable]
end
subgraph "Economic Events"
CreateEvent[Create Event<br/>Resource Creation]
UseEvent[Use Event<br/>Resource Access]
TransferEvent[Transfer Event<br/>Custody Change]
RepairEvent[Repair Event<br/>Resource Restoration]
end
Resource --> Use
Resource --> Transport
Resource --> Storage
Resource --> Repair
Use --> User
Use --> Provider
Transport --> Transporter
Storage --> StorageProvider
Repair --> RepairProvider
Use --> UseEvent
Transport --> TransferEvent
Repair --> RepairEvent
Resource --> CreateEvent
1. Use Process (Time-Limited Access)
sequenceDiagram
participant User as User (Accountable Agent)
participant Provider as Provider (Resource Owner)
participant Resource as Resource System
participant Gov as Governance (PPR System)
User->>Provider: Request Resource Access
Provider->>Resource: Check Resource Availability
Resource-->>Provider: Availability Confirmed
Provider->>User: Grant Access (Time-limited)
User->>Resource: Use Resource
Resource->>Resource: Track Usage
Resource-->>User: Usage Complete
User->>Gov: Report Service Quality
Provider->>Gov: Report User Compliance
Gov->>Gov: Issue PPRs to Both Parties
Gov-->>User: PPR Issued (UseService)
Gov-->>Provider: PPR Issued (ServiceValidation)
#![allow(unused)] fn main() { UseProcess { resource: EconomicResourceHash, user: AgentPubKey, provider: AgentPubKey, time_start: SystemTime, time_end: SystemTime, usage_terms: UsageAgreement, access_requirements: AccessConstraints, tracking_mechanism: UsageMonitoring, } }
Role Requirements:
- User: Accountable Agent (stewardship role)
- Provider: Resource owner or custodian
- Validation: Service quality assessment possible
2. Transport Process (Custody Transfer)
#![allow(unused)] fn main() { TransportProcess { resource: EconomicResourceHash, transporter: AgentPubKey, from_location: Location, to_location: Location, custody_transfer: CustodyAgreement, tracking_requirements: TrackingProtocol, insurance_terms: InsuranceCoverage, } }
Role Requirements:
- Transporter: Primary Accountable Agent (coordination role)
- Custodian: Resource owner or appointed custodian
- Validation: Transport service assessment possible
3. Storage Process (Preservation)
#![allow(unused)] fn main() { StorageProcess { resource: EconomicResourceHash, storage_provider: AgentPubKey, storage_location: Location, storage_conditions: PreservationRequirements, monitoring_protocol: ConditionMonitoring, access_during_storage: AccessPolicy, } }
Role Requirements:
- Storage Provider: Primary Accountable Agent (coordination role)
- Resource Owner: Maintains ultimate ownership
- Validation: Storage service assessment possible
4. Repair Process (Restoration)
#![allow(unused)] fn main() { RepairProcess { resource: EconomicResourceHash, repair_provider: AgentPubKey, repair_specification: RepairPlan, quality_requirements: QualityStandards, cost_structure: CostAgreement, validation_requirements: QualityAssurance, } }
Role Requirements:
- Repair Provider: Primary Accountable Agent (coordination role)
- Quality Validator: Specialized validation role
- Validation: Repair service assessment possible
🔄 Validation & Governance Workflows
PPR System Workflow
stateDiagram-v2
[*] --> EventOccurrence: Economic Event
EventOccurrence --> PPRIssuance: Trigger PPR Creation
PPRIssuance --> ValidationRequired: Needs Verification
ValidationRequired --> UnderReview: Assign Reviewers
state UnderReview {
[*] --> Reviewer1
Reviewer1 --> Reviewer2
Reviewer2 --> Reviewer3
Reviewer3 --> ConsensusCheck
}
UnderReview --> ValidationApproved: Consensus Reached
UnderReview --> ValidationRejected: No Consensus
ValidationApproved --> PPRActive: Activate PPR
ValidationRejected --> AppealProcess: Dispute Filed
AppealProcess --> Reconsideration: Valid Appeal
AppealProcess --> PPRRejected: Appeal Denied
Reconsideration --> UnderReview: Re-validate
PPRActive --> ReputationUpdate: Update Score
ReputationUpdate --> [*]
PPRRejected --> [*]
Multi-Reviewer Validation System
graph TB
subgraph "Validation Workflow"
ValType[Validation Type<br/>2-of-3, N-of-M, Majority]
Subject[Validation Subject<br/>Resource/Service/Commitment]
Reviewers[Required Reviewers<br/>Min 2, Max 5]
Deadline[Review Deadline<br/>24-72 hours]
Criteria[Validation Criteria<br/>Quality Rules]
end
subgraph "Review Process"
Assign[Assign Reviewers<br/>Random Selection]
Collect[Collect Reviews<br/>Parallel Process]
Consensus[Consensus Check<br/>Threshold Analysis]
Outcome[Validation Outcome<br/>Approved/Rejected]
end
subgraph "Appeal Process"
Appeal[Appeal Initiation<br/>3-day Window]
ReReview[Re-review Process<br/>New Reviewers]
FinalDecision[Final Decision<br/>Binding Outcome]
end
ValType --> Assign
Subject --> Assign
Reviewers --> Assign
Deadline --> Collect
Criteria --> Collect
Assign --> Collect
Collect --> Consensus
Consensus --> Outcome
Outcome --> Appeal
Appeal --> ReReview
ReReview --> FinalDecision
#![allow(unused)] fn main() { ValidationWorkflow { workflow_type: ValidationType, // 2-of-3, N-of-M, simple_majority subject: ValidationSubject, // Resource, Service, Commitment required_reviewers: u32, review_deadline: SystemTime, validation_criteria: ValidationRules, appeal_process: AppealProcedure, } }
Validation Types:
- 2-of-3 Validation: 3 reviewers, 2 required for consensus
- N-of-M Validation: Custom reviewer numbers and consensus thresholds
- Simple Majority: Democratic decision-making with minimum participation
2. Agent Promotion Workflow
graph TD
subgraph "Promotion Levels"
Simple[Simple Agent<br/>Base Access]
Accountable[Accountable Agent<br/>Stewardship Role]
Primary[Primary Accountable<br/>Coordination Role]
Advanced[Advanced Agent<br/>Governance Role]
end
subgraph "Simple → Accountable"
S1[First Validated Transaction]
S2[Basic PPR Earned]
S3[Identity Verified]
end
subgraph "Accountable → Primary"
A1[Multiple PPR Categories<br/>3+ Categories]
A2[Specialized Validation<br/>Process Expertise]
A3[Community Standing<br/>Reputation Threshold]
end
subgraph "Primary → Advanced"
P1[Governance Participation<br/>Commitment Fulfillment]
P2[Dispute Resolution<br/>Mediation Experience]
P3[System Leadership<br/>Coordination Excellence]
end
Simple --> S1 --> S2 --> S3 --> Accountable
Accountable --> A1 --> A2 --> A3 --> Primary
Primary --> P1 --> P2 --> P3 --> Advanced
#![allow(unused)] fn main() { PromotionWorkflow { current_level: CapabilityLevel, target_level: CapabilityLevel, eligibility_criteria: PromotionRequirements, evaluation_period: Duration, required_ppr_categories: Vec<PPRCategory>, milestone_achievements: Vec<PPRMilestone>, review_board: Vec<AgentPubKey>, } }
Promotion Criteria:
- Simple → Accountable: First validated transaction + basic PPR
- Accountable → Primary: Multiple PPR categories + specialized validation
- Primary → Advanced: Governance participation + dispute resolution experience
3. Dispute Resolution Process
#![allow(unused)] fn main() { DisputeResolution { dispute_type: DisputeCategory, parties_involved: Vec<AgentPubKey>, evidence_collection: Vec<EvidenceHash>, mediation_process: MediationProcedure, resolution_options: ResolutionOptions, enforcement_mechanism: EnforcementStrategy, } }
Dispute Categories:
- Resource Quality: Resource not meeting specifications
- Service Quality: Service not meeting agreed standards
- Access Violations: Unauthorized resource access or use
- Contract Disputes: Commitment fulfillment disagreements
- Reputation Challenges: PPR validity disputes
📈 Performance & Scalability Architecture
1. DHT Optimization Strategies
Anchor Pattern Optimization:
├── Resource Discovery Anchors (category-based indexing)
├── Agent Discovery Anchors (role-based indexing)
├── Process Type Anchors (process-based indexing)
└── Geographic Anchors (location-based indexing)
Link Traversal Optimization:
├── Efficient Link Creation (minimal link overhead)
├── Cached Link Queries (reduced DHT calls)
├── Batch Link Operations (reduced network traffic)
└── Link Cleanup Strategies (DHT maintenance)
2. Reputation System Performance
PPR Calculation Optimization:
├── Incremental Updates (only calculate changes)
├── Cached Reputation Scores (periodic refresh)
├── Category-Specific Caching (domain-specific optimization)
└── Asynchronous Validation (non-blocking reputation updates)
Scalability Considerations:
├── PPR Rate Limiting (prevents reputation spam)
├── Validation Pool Management (efficient reviewer assignment)
├── Reputation Decay (historical relevance weighting)
└── Distributed Calculation (peer-to-peer reputation consensus)
3. Private Data Access Performance
Access Control Optimization:
├── Capability Token Caching (reduced validation overhead)
├── Grant Status Indexing (fast access validation)
├── Field-Level Access Caching (optimized data retrieval)
└── Expiration Queue Management (automatic cleanup)
Encryption Performance:
├── Symmetric Encryption for Data (efficient encryption/decryption)
├── Asymmetric Encryption for Keys (secure key exchange)
├── Key Derivation Optimization (efficient key management)
└── Secure Storage Compression (reduced storage overhead)
🔮 Future Architecture Extensions
1. Advanced Governance Features
- Dynamic Rule Updates: Community-driven governance rule modifications
- Delegated Validation: Hierarchical validation delegation systems
- Cross-Community Coordination: Inter-hApp governance coordination
- Automated Dispute Resolution: AI-assisted dispute mediation
2. Enhanced Economic Processes
- Process Composition: Complex multi-process workflows
- Resource Bundling: Package deals and combined services
- Subscription Models: Recurring access and service arrangements
- Market Integration: External market price discovery and integration
3. Advanced Reputation Systems
- Skill-Based Reputation: Domain-specific expertise tracking
- Temporal Reputation Patterns: Time-based reputation analysis
- Network Reputation: Relationship-based reputation scoring
- Privacy-Preserving Reputation: Zero-knowledge reputation proofs
4. Performance & Scalability Enhancements
- Sharding Strategies: Horizontal scaling through network partitioning
- Caching Layers: Multi-level caching for frequently accessed data
- Compression Algorithms: Advanced data compression for storage efficiency
- Load Balancing: Intelligent request routing and resource allocation
📋 Architecture Decision Records (ADRs)
ADR-001: Three-Zome Architecture
Decision: Implement 3-zome architecture (person, resource, governance) Rationale: Clear separation of concerns, focused responsibility domains Alternatives Considered: Single monolithic zome, 5+ specialized zomes Impact: Simplified development, clear API boundaries, cross-zome coordination complexity Status note: The 3-zome design still describes the Nondominium DNA core, but the hApp is no longer a single DNA — see ADR-013.
ADR-013: Multi-DNA Split — Lobby, Group, and NDO Networks
Decision: Split the hApp into multiple DNA roles: a provisioned Lobby DNA (global group registry + agent presence), a cloned Group DNA per group (isolated coordination DHT), and a cloned NDO DNA per Nondominium Object (isolated resource network reusing the existing resource and governance zome WASMs), alongside the provisioned Nondominium core and vendored hREA DNA.
Rationale: Complexity matching — coordination overhead activates when coordination begins, not at install. Group data does not belong in a global DHT; an NDO must not be captive to any single group's DHT (REQ-RES-02). Placing immutable Layer 0 fields in the NDO clone's DNA properties makes the DNA hash the NDO's permanent, organization-agnostic identity, enforced by hash physics rather than validation code (ADR-010 in the NDO-per-cell design).
Alternatives Considered: Single shared DHT for everything (rejected: no network isolation, group-scoped visibility impossible); a Lobby-level global NDO registry (rejected in PR #107; group-level NdoAnchor entries carry clone coordinates instead, ADR-011); a dedicated slim NDO zome (rejected for MVP: code fork, ADR-012).
Impact: Delivered incrementally by PR #103 (Lobby), PR #107 (Group), and issue #112 (NDO DNA + NdoAnchor). Browsing NDOs reads group-cell anchors and never requires joining NDO cells; PPRs and governance run inside each NDO network; Person identity and the hREA bridge stay in the provisioned cells.
ADR-002: PPR-Based Reputation System
Decision: Implement 14-category PPR reputation system with cryptographic proofs Rationale: Comprehensive reputation tracking, fraud resistance, privacy preservation Alternatives Considered: Simple scoring system, centralized reputation database Impact: Complex implementation, strong trust foundations, computational overhead
ADR-003: Four Economic Processes
Decision: Standardize on Use, Transport, Storage, Repair processes Rationale: Covers common sharing scenarios, clear role definitions, structured workflows Alternatives Considered: Unlimited process types, minimal process structure Impact: Standardized workflows, limited flexibility, easier validation
ADR-004: Capability-Based Security Model
Decision: Progressive capability tokens with role-based restrictions Rationale: Gradual trust building, principle of least privilege, automated advancement Alternatives Considered: All-or-nothing access, centralized authorization Impact: Complex access control, strong security, user-friendly progression
🎯 Architecture Quality Metrics
Performance Targets
- Zome Function Response Time: < 500ms for common operations
- PPR Calculation Time: < 2s for reputation score derivation
- Validation Workflow Time: < 24h for standard validations
- Private Data Access Time: < 1s for authorized access requests
Security Metrics
- Capability Token Security: Cryptographically secure, non-repudiable
- PPR System Integrity: Tamper-evident, cryptographically verifiable
- Private Data Protection: End-to-end encryption, field-level access control
- Access Control Compliance: 100% enforcement of capability restrictions
Scalability Targets
- Concurrent Users: Support 1000+ concurrent agents
- Resource Management: 10,000+ concurrent economic resources
- Process Throughput: 100+ concurrent economic processes
- Reputation Queries: 10,000+ concurrent reputation calculations
Reliability Requirements
- System Availability: 99.9% uptime for critical functions
- Data Consistency: Strong consistency for all economic transactions
- Backup Recovery: Complete data recovery from any network state
- Error Recovery: Graceful handling of network partitions and failures
This architecture document represents the current state of the Nondominium system as of October 30, 2025. It is a living document that evolves with the implementation and community feedback.
Nondominium UI Architecture
Status: MVP implemented (see documentation/IMPLEMENTATION_STATUS.md for current status). Perspectives (§16) are the next planned UI work.
Cross-references: documentation/requirements/ui_design.md (normative UI requirements), documentation/requirements/requirements.md (REQ-USER-* stories).
1. Overview
The Nondominium frontend is a SvelteKit application using Svelte 5 runes, Effect-TS for async state management, and UnoCSS for styling. It exposes the three-zome Holochain backend through a typed service + store layer and renders a three-level navigational hierarchy:

Lobby (global shared DHT) discovers Groups via GroupAnnouncement — not NDOs directly. Each Group is a cloned Group DNA cell with its own isolated DHT; Groups point at NDOs via NdoAnchor entries, and each NDO is itself a cloned ndo cell (ADR-010 model A). The Lobby's NdoBrowser aggregates only NDOs from the agent's own groups — there is no global public NDO registry. Identity deepens at each level: localStorage nickname (Level 1) → per-group profile (Level 2) → Person DHT entry on first NDO action (Level 3).
This hierarchy maps to the three concentric organizational scopes in ui_design.md:
- Lobby — the entry point: the NDOs aggregated from the agent's own groups, Groups listed in sidebar (no global public NDO registry).
- Group — organizational context: NDOs scoped to a group, where new NDOs are created.
- NDO — the resource identity detail view: Layer 0 metadata, lifecycle transitions, fork friction.
On top of this hierarchy, the next UI iteration adds a cross-cutting Perspective layer (Resource · Agent · Intelligence · Work) with a switcher and a navigation trail — see §16 and ui_design.md § Perspectives.
2. Technology Stack
| Layer | Technology |
|---|---|
| Framework | SvelteKit 2 + Svelte 5 runes ($state, $derived, $effect) |
| Language | TypeScript (strict mode) |
| Styling | UnoCSS (atomic CSS, preset-wind) |
| Headless components | Melt UI next-gen (melt) |
| Async / error handling | Effect-TS (effect package) — Context.Tag, Layer, E.gen |
| Holochain client | @holochain/client ^0.20.0 |
| Shared types | @nondominium/shared-types (workspace package) |
| Build | Vite 7 |
| Dev runtime | Browser (web) — Electron/hc-spin superseded by a per-agent Vite harness (§15) |
3. Layer Architecture
┌──────────────────────────────────────────────────────────────────┐
│ ROUTES │
│ / (LobbyView) /group/[id] /ndo/[hash] /ndo/new │
└──────────────────────────────────────────────────────────────────┘
↓
┌──────────────────────────────────────────────────────────────────┐
│ COMPONENTS │
│ lobby/: LobbyView, GroupSidebar, NdoBrowser, NdoCard, │
│ UserProfileForm │
│ group/: GroupView, NdoCreateModal, GroupProfileModal, MemberList │
│ ndo/: NdoView, NdoIdentityLayer, LifecycleTransitionModal, │
│ TransitionHistoryPanel, ForkNdoModal │
│ shell/: Sidebar (global nav) │
└──────────────────────────────────────────────────────────────────┘
↓
┌──────────────────────────────────────────────────────────────────┐
│ STORES (Svelte 5 $state + Effect-TS) │
│ app.context.svelte.ts — cross-view app state │
│ lobby.store.svelte.ts — Lobby-level NDOs, groups, filters │
│ group.store.svelte.ts — Group-scoped NDOs │
│ resource.store.svelte.ts — ResourceSpecification list │
└──────────────────────────────────────────────────────────────────┘
↓
┌──────────────────────────────────────────────────────────────────┐
│ SERVICES (Effect-TS Context.Tag / Layer) │
│ person.service.ts — PersonServiceTag / PersonServiceLive │
│ resource.service.ts — ResourceServiceTag / ResourceServiceLive │
│ governance.service.ts — GovernanceServiceTag / Live │
│ ndo.service.ts — NdoServiceTag / NdoServiceLive │
│ lobby.service.ts — LobbyServiceTag / LobbyServiceLive │
│ group.service.ts — GroupServiceTag / GroupServiceLive (stub) │
└──────────────────────────────────────────────────────────────────┘
↓
┌──────────────────────────────────────────────────────────────────┐
│ HOLOCHAIN CLIENT │
│ holochain.service.svelte.ts — HolochainClientServiceTag │
│ wrapZomeCallWithErrorFactory — wz<T>(fnName, payload, ctx) │
└──────────────────────────────────────────────────────────────────┘
↓
┌──────────────────────────────────────────────────────────────────┐
│ HOLOCHAIN CONDUCTOR (multi-DNA hApp) │
│ nondominium DNA: zome_person · zome_resource · zome_gouvernance │
│ lobby DNA (provisioned) · group DNA (cloned per group) │
│ ndo DNA (cloned per NDO, #112) · hrea DNA (vendored) │
└──────────────────────────────────────────────────────────────────┘
4. Three-Level Identity Model (MVP)
The MVP UI introduces three distinct identity layers that do not require DHT writes for the outer two, enabling permissionless browsing and progressive disclosure.
Level 1 — Lobby (LobbyUserProfile, localStorage)
interface LobbyUserProfile {
nickname: string; // required
realName?: string;
bio?: string;
email?: string;
phone?: string;
address?: string;
}
- Stored in
localStoragekeyndo_lobby_profile_v1. - Hydrated into
appContext.lobbyUserProfile($state) on first module load. - Created/edited via
UserProfileForm.svelte(modal on first launch, page-mode for edits). - No DHT entry. Exists before any
Personentry is created.
Level 2 — Group (GroupMemberProfile, localStorage)
interface GroupMemberProfile {
isAnonymous: boolean;
shownFields: (keyof Omit<LobbyUserProfile, 'nickname'>)[];
}
- Stored alongside
GroupDescriptorinlocalStoragekeyndo_groups_v1. - Prompted once per group via
GroupProfileModal.svelteon first group entry. - Agent controls which
LobbyUserProfilefields are visible to other group members.
Level 3 — NDO/Agent (Person entry, zome_person DHT)
- Written to the DHT when an agent performs their first DHT-active action (create NDO, accept commitment).
- Linked to
AgentPubKeyon-chain. - Required for governance participation, custodianship, specialised process access.
- Documented in
documentation/requirements/agent.md §2.1.
5. Group Architecture (DNA-backed)
Groups are the mandatory context for NDO creation. Each group is a cloned Group DNA cell (role_name: 'group', unique network_seed, clone_limit: 64 in workdir/happ.yaml).
interface GroupDescriptor {
id: string; // canonical key = network_seed
networkSeed: string;
name: string;
description?: string;
createdBy?: string; // LobbyUserProfile.nickname at creation
createdAt?: number;
dnaHash?: string; // clone cell DNA hash (base64)
groupHash?: string; // GroupProfile ActionHash (base64)
memberProfile?: GroupMemberProfile; // Level 2 — localStorage only (ndo_group_profiles_v1)
}
Lifecycle: createGroup → createCloneCell → create_group → join_group → announce_group (Lobby DNA). Invite links encode { network_seed, group_dna_hash, group_name } as ?group=<base64>.
NDO association: each NDO is its own cloned ndo cell (ADR-010 model A). A group's NDO list = get_ndo_anchors(group_hash) on the group clone cell; cards render straight from the anchors' cached fields, so browsing never joins an ndo cell. Opening an NDO resolves its cell from the anchor coordinates (ensureNdoCloneCell, provisioning it for a peer who never joined) and reads the live entry. Pre-migration NDOs in the shared nondominium cell still resolve through a legacy fallback. Full rationale: documentation/specifications/adr/ADR-010-013-per-ndo-cells.md.
6. Component Reference
Lobby Level
| Component | File | Description |
|---|---|---|
LobbyView | lobby/LobbyView.svelte | Root lobby layout: profile bar, sidebar, NdoBrowser |
UserProfileForm | lobby/UserProfileForm.svelte | Lobby profile create/edit (modal or page mode) |
GroupSidebar | lobby/GroupSidebar.svelte | Groups list, Create Group form, Join Group form, My Profile link |
NdoBrowser | lobby/NdoBrowser.svelte | Filter chip bar (3 groups × multi-select) + NdoCard grid |
NdoCard | lobby/NdoCard.svelte | Compact NDO summary card with lifecycle/nature/regime badges |
Group Level
| Component | File | Description |
|---|---|---|
GroupView | group/GroupView.svelte | Group header, invite link, Create NDO, group-scoped NdoBrowser, MemberList (DHT) |
NdoCreateModal | group/NdoCreateModal.svelte | 5-field NDO creation form (name, regime, nature, stage, description) |
GroupProfileModal | group/GroupProfileModal.svelte | Per-group profile presentation choice (first entry only) |
NDO Level
| Component | File | Description |
|---|---|---|
NdoView | ndo/NdoView.svelte | NDO detail: header, tab navigation, Fork button |
NdoIdentityLayer | ndo/NdoIdentityLayer.svelte | Layer 0 identity panel: badges, initiator link, transition button, history |
LifecycleTransitionModal | ndo/LifecycleTransitionModal.svelte | State machine transitions with special Deprecated / Hibernating handling |
TransitionHistoryPanel | ndo/TransitionHistoryPanel.svelte | Collapsible history of lifecycle transitions |
ForkNdoModal | ndo/ForkNdoModal.svelte | Informational fork friction modal with copy-pubkey CTA |
Shell
| Component | File | Description |
|---|---|---|
Sidebar | shell/Sidebar.svelte | Global nav — "Browse NDOs", context-aware "New NDO" link |
Planned (Perspectives, §16):
shell/PerspectiveSwitcher.svelte,shell/NavigationTrail.svelte, and aperspectives/component folder.Sidebar's "Browse NDOs" link is expected to become the entry to the Resource Perspective.
7. State Management
app.context.svelte.ts
Cross-view singleton. All $state variables are module-level (Svelte 5 rune pattern):
| Field | Type | Persisted |
|---|---|---|
myAgentPubKey | `AgentPubKey | null` |
myPerson | `Person | null` |
currentView | `'lobby' | 'group' |
selectedGroupId | `string | null` |
selectedNdoId | `ActionHash | null` |
lobbyUserProfile | `LobbyUserProfile | null` |
Planned (§16):
currentPerspective('resource' | 'agent' | 'intelligence' | 'work') andnavigationTrail(stack ofPerspectiveLocation) will be added here;currentViewremains the Lobby/Group/NDO level within a Perspective.
lobby.store.svelte.ts
Effect-TS E.gen store instantiated once at module load via E.runSync.
| Reactive field | Derives from |
|---|---|
ndos | NdoServiceTag.getLobbyNdoDescriptors() |
filteredNdos | ndos + activeFilters (client-side OR-within/AND-across) |
groups | LobbyServiceTag.getMyGroups() |
activeFilters | Mutations via setFilters() / clearFilters() |
myPerson | PersonServiceTag.getMyPersonProfile() |
group.store.svelte.ts
Singleton per-session; loadGroupData(groupId) switches context:
| Field | Source |
|---|---|
group | LobbyServiceTag.getMyGroups() |
groupNdos | NdoServiceTag.getGroupNdoDescriptors(groupId) via SoftLinks |
members | GroupServiceTag.getMembers(cellId) |
loadGroupData(groupId, { silent? })— on a full (non-silent) load it first runslobbyService.ensureMembership(groupId)(idempotent self-heal so a joined agent always becomes a committed member), then fetches NDOs + members. A silent load (used by the pull layer) skips the membership reconcile, does not toggleisLoading, and keeps existing data on transient failure (no flicker/blanking).refreshCurrentGroup()— silent re-fetch of the currently-open group; driven byGroupView's pull-based reactivity (tab focus / visibility change + gentle ~8 s poll while visible).TODO(signals): replace the pull layer with Holochain remote signals (focus/poll kept only as an offline/missed-signal fallback).
8. Service Layer
Pattern
All services use the wz<T> factory:
const wz = <T>(fnName: string, payload: unknown, context: string) =>
wrapZomeCallWithErrorFactory<T, DomainError>(
holochainClient, 'zome_name', fnName, payload, context, DomainError.fromError
);
ndo.service.ts — NdoServiceTag
| Method | Delegates to |
|---|---|
getLobbyNdoDescriptors() | Union of SoftLink targets across all group clone cells → resource.getNdo |
getNdoDescriptorForSpecActionHash(hash) | Direct resource.getNdo(hash) first; fallbacks to listings/cache |
createNdo(input, groupId) | resource.createNdo(input) + create_soft_link on group cell |
updateLifecycleStage(input) | resource.updateLifecycleStage(input) |
getNdoTransitionHistory(hash) | resource.getNdoTransitionHistory(hash) (zome fn not yet implemented; returns []) |
getGroupNdoDescriptors(groupId) | get_soft_links → resolve each target via resource.getNdo |
getAssociatedGroupIds(ndoHashB64) | SoftLink scan across agent's groups |
joinNdo / getNdoMembers | DHT-backed via zome_resource join_ndo / get_ndo_members on the per-NDO clone cell; joinNdo is idempotent |
lobby.service.ts — LobbyServiceTag (Group + Lobby DNA)
| Method | Behaviour |
|---|---|
getMyGroups() | Enumerate group clone cells from appInfo + get_my_group per cell |
createGroup(name, createdBy) | createCloneCell → create_group → join_group → announce_group (the join_group/announce_group post-steps are best-effort via E.catchAll, so transient contention never aborts creation) |
joinGroup(inviteCode) | Decode invite → createCloneCell(same seed) → fetchGroupProfileWithRetry (poll get_my_group, 6× / ~2.4 s for DHT gossip) → is_member guard → best-effort join_group → on profile miss, build a GroupDescriptor from the invite payload so the group still appears immediately. TODO(signals): replace the poll with a Holochain remote signal once available |
ensureMembership(groupId) | Idempotent membership self-heal: resolve group hash via get_my_group → is_member → best-effort join_group if missing. Covers joins that missed the membership commit (payload-fallback path / swallowed join_group). Called on every full loadGroupData so a joined agent always reconciles into the member list |
generateInviteLink(groupId) | { network_seed, group_dna_hash, group_name } → ?group=<base64> URL |
getGroupCell(groupId) | Resolve clone CellId by network_seed |
saveGroupMemberProfile(groupId, profile) | localStorage[ndo_group_profiles_v1] (Level 2 identity) |
group.service.ts — GroupServiceTag
| Method | Zome call |
|---|---|
getMembers(cellId) | get_group_members (each member = action author of a GroupMembership linked from the group hash) |
getSoftLinks / createSoftLink | get_soft_links / create_soft_link |
Shared-group reactivity & data freshness
Shared-group items (members, NDO SoftLinks, work logs) live on the group clone-cell DHT and reach other members via gossip. The UI keeps views fresh with a pull-only model today (no push):
- Per-open reconciliation —
loadGroupDatarunsensureMembership(self-heal) then re-reads members + NDOs whenever a group view mounts orgroupIdchanges. - Tab focus / visibility —
GroupViewcallsrefreshCurrentGroup()(silent) when the window regains focus or the tab becomes visible. - Gentle poll — a ~8 s interval silent refresh while the group is open and the tab is visible (paused when hidden).
- Join gossip-retry + fallback —
fetchGroupProfileWithRetryinjoinGroupabsorbs the gossip latency of a freshly-cloned cell.
Consequence: a change made by another member appears within the poll interval, on focus, or on reload — not instantly. The push upgrade (TODO(signals)) is to have zome_group remote_signal members on join_group / create_soft_link / log_work, with the UI refreshing on those signals and the pull layer kept only as an offline/missed-signal fallback (consolidated design note in dnas/group/zomes/coordinator/zome_group/src/lib.rs).
9. Routing
| Route | Component | Notes |
|---|---|---|
/ | LobbyView | Lobby entry point; shows all NDOs |
/group/[id] | GroupView | Group-scoped view; ?createNdo=1 auto-opens modal |
/ndo/[hashB64] | NdoView | NDO detail (hash is base64-encoded ActionHash) |
/ndo/new | Redirect page | Redirects to active group or shows explanation |
Planned Perspective routes (§16): /resource, /agent (+ /agent/[pubkey]), /intelligence, /work (+ /work/[projectHash]). / remains the Lobby entry until the Resource Perspective replaces it as the default landing view.
Navigation Logic
- "New NDO" link in Sidebar: if
appContext.selectedGroupIdis set →/group/{id}?createNdo=1; else →/ndo/new(explanation screen). - Group navigation:
GroupSidebar.sveltecallsgoto('/group/{id}')after create/join. - Post-NDO-creation:
NdoCreateModal.sveltecallsgoto('/ndo/{hashB64}')on success.
10. NDO Lifecycle State Machine (Frontend Mirror)
LifecycleTransitionModal.svelte encodes the same state machine as the Rust validation in zome_resource. Allowed transitions:
| From | Allowed next stages |
|---|---|
| Ideation | Specification, Deprecated, EndOfLife |
| Specification | Development, Deprecated, EndOfLife |
| Development | Prototype, Deprecated, EndOfLife |
| Prototype | Stable, Deprecated, EndOfLife |
| Stable | Distributed, Deprecated, EndOfLife |
| Distributed | Active, Deprecated, EndOfLife |
| Active | Hibernating, Deprecated, EndOfLife |
| Hibernating | hibernation_origin stage, Deprecated, EndOfLife |
| Deprecated | EndOfLife |
Special handling:
- Deprecated: requires successor NDO selection (autocomplete from
lobbyStore.ndos). - Hibernating: confirmation message shown;
hibernation_originpreserved in entry. - Transition button visible to initiator only (
descriptor.initiator === encodeHashToBase64(myAgentPubKey)). transition_event_hashis passed asnullin MVP (automatic EconomicEvent generation is a post-MVP backend task).
11. Filter Architecture (NdoBrowser)
Three independent chip groups with multi-select:
| Group | Options | Logic |
|---|---|---|
| LifecycleStage | 10 variants | OR within group |
| ResourceNature | 5 variants | OR within group |
| PropertyRegime | 7 variants | OR within group |
Cross-group logic: AND (an NDO must match at least one selection in every active group).
Default: all filters empty = show all NDOs.
Chip colors: match the badge colors in NdoIdentityLayer.svelte color maps.
12. Fork Friction Pattern
Fork requests are intentionally non-trivial by design (see ui_design.md Fork section). The MVP implements:
- Informational modal only (
ForkNdoModal.svelte): explains negotiation → consensus → Unyt stake (post-MVP) flow. - CTA: copy initiator's
AgentPubKey(base64) to clipboard for out-of-band contact. - Visibility: Fork button visible to any authenticated user (anyone with
myAgentPubKeyset). - Full fork submission (claim, vote, Unyt stake) is post-MVP.
13. Post-MVP UI Tracks
The following UI capabilities are documented but not yet implemented. Perspectives (§16) are not post-MVP: they are the next planned UI work (see ui_design.md § Perspectives ToDos); only the parallax/landscape visual layer on top of them remains post-MVP.
| Track | Trigger | Design reference |
|---|---|---|
NDO membership (join_ndo) | Backend stub in UI; implement NdoMembership in zome_resource | documentation/zomes/resource_zome.md § NDO membership |
get_ndo_transition_history | Lifecycle audit panel empty until zome fn lands | TransitionHistoryPanel.svelte |
| NDO cell cloning | Per-NDO DHT once Holochain cloning stabilises | ndo_prima_materia.md §4 |
| PPR / Reputation dashboard | After PPR zome functions are complete (#14–#21) | specifications/governance/private-participation-receipt.md |
| Economic Process workflows | After Phase 2.2 process infrastructure lands | requirements.md §4.2, implementation_plan.md §5 Phase 2.2 |
| Person management components | After enhanced private data sharing (#40) | requirements.md §4.1, issue #8 |
| Role management UI | After agent promotion workflow (#33, #34) | requirements.md §4.3 |
| Moss WeApplet | Post-MVP deployment target | implementation_plan.md §12.6 |
| Unyt / Flowsta integration UI | Phases 12.2–12.3 in implementation plan | post-mvp/unyt-integration.md, post-mvp/flowsta-integration.md |
| Push reactivity via Holochain signals | Replace the pull layer (focus + poll + per-open reconcile) with remote_signal from zome_group on member/SoftLink/work-log mutations | TODO(signals) in zome_group/src/lib.rs, GroupView.svelte, lobby.service.ts |
14. Effect-TS Patterns
Service injection
// Resolved layer for direct component use
export const NdoServiceResolved: Layer.Layer<NdoServiceTag> =
NdoServiceLive.pipe(Layer.provide(ResourceServiceResolved));
// Usage in a Svelte $effect or onMount
const exit = await E.runPromiseExit(
pipe(
E.gen(function* () {
const svc = yield* NdoServiceTag;
return yield* svc.getLobbyNdoDescriptors();
}),
E.provide(NdoServiceResolved)
)
);
Store instantiation (Svelte 5 rune + Effect pattern)
// Module-level $state variables (top-level only — Svelte 5 rune constraint)
let ndos = $state<NdoDescriptor[]>([]);
// Store created synchronously with E.runSync; Effect only provides dependencies
export const lobbyStore = pipe(
createLobbyStore(), // E.Effect<LobbyStore, never, Services>
E.provide(LobbyStoreServicesResolved),
E.runSync // services are pure/synchronous; no async at creation time
);
Error handling
All zome errors are domain-tagged (ResourceError, PersonError, etc.) with context strings for debugging. Effects that may fail are run with E.runPromiseExit, and Exit.isSuccess(exit) guards all state mutations.
15. Local Development & Multi-Agent Web Harness
The dev runtime is the browser, not Electron. The previous hc-spin flow streamed the full .happ (~8 MB) over the admin websocket and timed out, so local development is now orchestrated by scripts/launch-happ.mjs (invoked by bun run start / AGENTS=N bun run network).
15.1 Launcher responsibilities (scripts/launch-happ.mjs)
- Bootstrap + signaling: spawns
kitsune2-bootstrap-srvand parses its listening URLs. - Sandboxes:
hc sandbox --piped create -n N … webrtc <signal>thenhc sandbox --piped run(LAIR password piped on stdin). - Path-based install: connects an
AdminWebsocketper conductor and callsinstallApp({ source: { type: 'path', value: happPath } })+enableApp— avoids the websocket bundle-streaming timeout. - Connection manifest: writes
ui/static/hc-connection.json({ appId, agents: [{ agent, adminWsUrl, appWsUrl }], updatedAt }), updated incrementally as each conductor comes up. - One Vite server per agent:
startUiServers()spawnsbun run startfromui/for each agent withUI_PORT = basePort + (agent-1)andVITE_DEV_AGENT = agent. Agent n →http://localhost:{5173 + n - 1}. - Auto-open: when a Vite server prints its
Local:URL, the launcher opens a browser tab (open/start/xdg-open). SetNO_OPEN=1to disable (headless/CI). - Shutdown:
SIGINT/SIGTERMtears down all UI servers, the sandbox, and the bootstrap server.
15.2 Why a port per agent
Each agent gets a dedicated port = dedicated origin, which yields fully isolated browser localStorage per agent while keeping URLs clean (no ?agent= noise in permalinks). This replaced an earlier single-origin ?agent=N approach. The query param is retained only as a manual override for advanced cases.
15.3 Agent selection (ui/src/lib/utils/hc-connect.ts)
getDevAgentIndex() resolves which conductor a window binds to, in priority order:
?agent=Nquery param (manual override).VITE_DEV_AGENTenv var (the primary mechanism — injected per Vite server by the launcher).localStorage[ndo_dev_agent], else default1.
15.4 Connection modes (connectHolochainClient)
| Mode | Trigger | Notes |
|---|---|---|
launcher | window.__HC_LAUNCHER_ENV__ present | hc-spin Electron path (legacy/optional) |
manifest | /hc-connection.json has agents | Primary web path; picks the entry matching getDevAgentIndex(); polls up to 5 min while conductors install |
env | VITE_HC_ADMIN_WS_URL + VITE_HC_APP_WS_URL | manual override |
In manifest/env modes the result carries the adminWsUrl so the UI can authorize signing credentials for runtime-created group clone cells.
15.5 Signing-credential authorization & resilience
- On connect, the UI calls
authorizeSigningCredentialsfor everyprovisionedandclonedcell (clone cells lose in-memory signing credentials on reload, so their zome calls would otherwise fail). - Grants are serialized (each is a source-chain commit); concurrent grants raise "source chain head has moved", so
authorizeWithRetryretries with backoff (5 attempts). authorizeCellSigning(adminWsUrl, cellId)is exported so a group clone cell created after initial connect (create/join group) is authorized on demand.
15.6 Per-agent UI-state namespacing
Because two windows can share an origin (the ?agent= override), all UI-only localStorage keys are namespaced via devStorageKey(base) → ${base}__a{agentIndex}:
| Base key | Owner |
|---|---|
ndo_lobby_profile_v1 | app.context.svelte.ts (Level 1 profile) |
ndo_group_profiles_v1 | lobby.service.ts (Level 2 disclosure prefs) |
ndo_group_visited_v1 | GroupView.svelte (first-visit prompt) |
ndo_dev_agent | dev agent index (not namespaced — it is the namespace) |
Note: DHT-backed state (groups, NDOs, members) is isolated by the conductor itself; namespacing only protects the UI-only localStorage layer when origins are shared.
16. Perspectives Architecture (Next, planned)
Status: planned — next UI iteration after the MVP. Normative requirements: documentation/requirements/ui_design.md § Perspectives and § Perspectives ToDos. Nothing below is implemented yet.
A Perspective is a lens (filters, default tools, layout) over data already reachable through the Lobby → Group → NDO hierarchy. Perspectives are orthogonal to that hierarchy: currentView (lobby/group/ndo) says where the agent is; currentPerspective says how the data is being looked at.
16.1 Perspectives and data sources
Each Perspective has a base primitive and answers "what is the agent doing?" (see ui_design.md § Perspectives).
| Perspective | Route | Base primitive | Primary data | Backing services |
|---|---|---|---|---|
| Resource | /resource | Resource (NDO) | NDOs across own groups; linked Agents (custodian, repair, ...); Sources and the Source view | NdoServiceTag, LobbyServiceTag, PersonServiceTag |
| Agent | /agent, /agent/[pubkey] | Agent (incl. Groups) | Agent profiles, group members, skills, relationship graph, Group announcements | PersonServiceTag, GroupServiceTag, LobbyServiceTag |
| Intelligence | /intelligence | Projects / organizations beyond the current sphere | Groups and project-type NDOs, incl. outside the agent's own groups; role / skills / reputation (PPR) / interaction history; project-declared benefits; MCP assistant | LobbyServiceTag, NdoServiceTag, GovernanceServiceTag (PPR) |
| Work | /work, /work/[projectHash] | Process / work item, scoped to a resource, project or group | Project-type NDOs the agent subscribed to or contributed to; tasks, commitments, contributions, stigmergic signals | NdoServiceTag (joinNdo / getNdoMembers), GovernanceServiceTag, GroupServiceTag |
Progressive layering: within a Perspective, a view starts from its primitive and adds layers on demand (e.g. Resource: communities → local map → users → owner organization). Layers are modelled as an ordered list in each Perspective's view config, not as separate routes.
Known gaps to close first: (1) a way to identify project-type NDOs; (2) project-declared benefits must be added to the project-type NDO specification (requirements/post-mvp/project-type-ndo-specifications.md) before Intelligence can assess them; (3) cross-group / Lobby-level discovery — today the Lobby only aggregates the agent's own groups; (4) skills / reputation data (Person + PPR still in progress); (5) push signals for Work's stigmergic feed (pull-based polling as interim, see § 8); (6) an MCP server exposing the agent's profile and project data for the Intelligence assistant.
16.2 State
Added to app.context.svelte.ts (module-level $state, Svelte 5 pattern):
type Perspective = 'resource' | 'agent' | 'intelligence' | 'work';
interface PerspectiveLocation {
perspective: Perspective;
route: string; // e.g. '/agent/uhCAk…'
entity?: { kind: 'ndo' | 'agent' | 'group' | 'project'; id: string; label: string };
viewState?: unknown; // filters, scroll, selection — restored on "back"
}
// appContext.currentPerspective: Perspective
// appContext.navigationTrail: PerspectiveLocation[] (in-memory; not persisted)
A dedicated perspective.store.svelte.ts (Effect-TS pattern as in § 14) owns jumpTo(target), back(), switchTo(perspective) and trail truncation, so components never mutate the trail directly.
16.3 Navigation semantics
- Switch (
switchTo): user picks a Perspective in the switcher; trail is reset to that Perspective's root. Each Perspective remembers its lastviewState. - Jump (
jumpTo): a contextual link carrying an entity (e.g. linked Agent in an NDO expanded view → Agent Perspective; joined project → Work). The current location is pushed onnavigationTrailwith itsviewState. - Back (
back): pops the trail and restores route +viewState.NavigationTrail.svelterenders the stack as a breadcrumb (Resource: Drill press → Agent: Alice → Groups). - Hints:
PerspectiveSwitcher.sveltemay show a contextual badge when another Perspective is relevant (e.g. "Discover projects" in Work → Intelligence).
Jump table (authoritative list in ui_design.md § Cross-Perspective Navigation): Work → Intelligence; Intelligence → Work (on join); Resource → Agent (linked Agent); Agent → Resource; Agent/Intelligence → Work or Group (on join).
16.4 Tools (perspective-agnostic)
Tools are not Perspectives. A small tool registry (tools/registry.ts) lets any Perspective mount a tool over its current entity set via a typed contract:
interface PerspectiveTool<T> {
id: string; // 'map', 'chat', 'simulation', 'kanban', ...
accepts: (kind: EntityKind) => boolean;
component: Component<{ entities: T[]; onSelect: (e: T) => void }>;
}
The Chat tool (direct contact with an Agent, possibly via the Capability Surface) is available from several Perspectives. The Geographic map is the first tool (it replaces the former Geographic Perspective): opened from Resource it maps NDOs, from Agent it maps Agents, from Intelligence it maps opportunities. Kanban is Work-scoped; simulations (time-allocation portfolio, benefit redistribution) are primarily hosted by Intelligence, next to the MCP-based assistant.
16.5 Component / file plan
| Component | File | Role |
|---|---|---|
PerspectiveSwitcher | shell/PerspectiveSwitcher.svelte | Persistent switcher + contextual hints |
NavigationTrail | shell/NavigationTrail.svelte | Breadcrumb + "Back to |
ResourcePerspective | perspectives/ResourcePerspective.svelte | Seeded from NdoBrowser; adds linked-Agent view |
AgentPerspective / AgentProfileView | perspectives/AgentPerspective.svelte | Agent search, profile, connections, Group discovery |
IntelligencePerspective | perspectives/IntelligencePerspective.svelte | Ranked discovery + tool slot |
WorkPerspective / ProjectWorkspace | perspectives/WorkPerspective.svelte | Project list, kanban, tasks, signals |
ToolHost | tools/ToolHost.svelte | Mounts registered tools in any Perspective |
Implementation order follows ui_design.md § Perspectives ToDos: switcher and trail first, then Resource (reusing NdoBrowser), Agent, Intelligence, Work.
16.5.1 Layer 0 cut (prototyped in the design system, not yet in the app)
For the Layer 0 release the Perspective switcher sits inside the Group page (Lobby → Group → Perspective); only Resource is live and every Perspective is group-scoped. The prototype lives in nondominium-design-system (/scenarios/resource-perspective), with components in @nondominium/ndo-ui. The port to this app is a ToDo (ui_design.md § Port to the nondominium app).
| Piece | Location (in packages/ndo-ui/src/) | Role |
|---|---|---|
| Coming-next registry | domain/coming-next.ts | Single source of copy for every "Soon" item (perspectives, tabs, access actions, processes, governed transitions, jump points; Unyt stake and Source view copy exist but are not wired yet), plus the PERSPECTIVES list and PerspectiveId |
ComingNextPopup, SoonBadge | components/primitives/ | Reusable popup (built on Modal; optional live shortcut, e.g. Offer → Create NDO) and badge |
PerspectiveSwitcher, Breadcrumb | components/patterns/perspectives/ | Tablist of four Perspectives (non-live ones open the popup and keep the current one); breadcrumb Lobby › Group › Resource › NDO |
ResourcePerspective | same | Search, ownership scope, sort, stage / nature / regime filters over NdoBrowser; logic in domain/resource-perspective.ts (searchNdos, scopeNdos, sortNdos) |
GroupPerspectivesView | same | Perspective host replacing the Group page body (header, switcher, Resource Perspective, member list) |
ResourceNdoView, NdoActionRow | same | NDO view with Overview + "Soon" tabs, access actions and processes row, join / associate / fork / copy link |
Additive changes to existing components (no breaking changes for current callers): NdoBrowser gains cardAction and emptyMessage; NdoIdentityPanel gains lockedTransition, onlockedtransitionclick, oninitiatorclick; MemberList gains onmemberclick.
State at this cut: currentPerspective only ('resource' live); navigationTrail and jumpTo / back stay in § 16.2 and arrive with the Agent Perspective. Jump points open the Coming-next popup instead of navigating.
Authorization is unchanged: the lifecycle transition remains initiator-only, enforced in the integrity zome (zome_resource); the UI only mirrors it by locking the button for non-initiators.
16.6 Community-specific implementations (later)
Community-specific UIs (terminology → workflows → visuals) sit on top of the four base Perspectives; ValueFlows stays the background vocabulary. Architecturally this implies a dictionary layer: a per-community mapping from display terms to the base vocabulary, consulted by components instead of hard-coded labels (so new base components should already route user-facing terms through a single t()-style lookup). How this relates to the Surface / Surface Attachment (capability slots) is to be specified; see ui_design.md § Community-Specific Implementations. Higher-level interoperability concerns are parked (ui_design.md § Future Reflection).
VfAction Usage Guide
Overview
The VfAction enum provides type-safe representation of ValueFlows actions in the nondominium system, supporting structured Economic Processes, role-based access control, and comprehensive governance workflows. It replaces the previous string-based approach with a strongly-typed enum that ensures compile-time validation, better documentation, and seamless integration with the Private Participation Receipt (PPR) system.
Available Actions
Standard ValueFlows Actions
Transfer Actions
Transfer- Transfer ownership/custody between agentsMove- Move a resource from one location to another (used in Transport processes)
Production/Consumption Actions
Use- Core nondominium process: use a resource without consuming it (accessible to all Accountable Agents)Consume- Consume/destroy a resource (used in end-of-life processes)Produce- Create/produce a new resourceWork- Apply work/labor to a resource (used in Transport and Storage processes, requires specialized roles)
Modification Actions
Modify- Modify an existing resource, applies to the Repair Process, accessible by Agents that have credencials for the Repair role.
Quantity Adjustment Actions
Raise- Increase quantity/value of a resourceLower- Decrease quantity/value of a resource
Citation/Reference Actions
Cite- Reference or cite a resourceAccept- Accept delivery or responsibility
nondominium-Specific Actions
InitialTransfer- First transfer by a Simple Agent (triggers agent promotion process)AccessForUse- Request access to use a resource (creates commitment for Use process)TransferCustody- Transfer custody between Primary Accountable Agents (nondominium specific)
VfAction in Economic Processes
The nondominium system implements four structured Economic Processes that use specific VfAction combinations:
Process-Action Mappings
Use Process (Core nondominium process)
- Primary Action:
Use - Access: All Accountable Agents
- Resource Effect: Resource unchanged
- PPR Generated: Service process receipts
Transport Process (Material resource movement)
- Primary Actions:
Move,Work - Access: Agents with Transport role credentials only
- Resource Effect: Resource location changed, otherwise unchanged
- PPR Generated: Transport-specific service receipts
Storage Process (Temporary custody)
- Primary Actions:
Work,TransferCustody - Access: Agents with Storage role credentials only
- Resource Effect: Resource unchanged
- PPR Generated: Storage-specific service receipts
Repair Process (Resource maintenance)
- Primary Actions:
Modify,Work - Access: Agents with Repair role credentials only
- Resource Effect: Resource state may change (broken → functional)
- PPR Generated: Repair-specific service receipts
Governance-as-Operator Pattern Examples
Cross-Zome State Transition Examples
The governance-as-operator pattern requires explicit cross-zome calls for state changes:
Resource Transfer with Governance Evaluation
#![allow(unused)] fn main() { use zome_gouvernance_integrity::VfAction; // Transfer resource custody through governance operator pub fn transfer_resource_with_governance( resource_hash: ActionHash, new_custodian: AgentPubKey, notes: Option<String>, ) -> ExternResult<GovernanceTransitionResult> { // 1. Get current resource state let resource = get_economic_resource(resource_hash)?; let agent_info = agent_info()?; // 2. Create governance transition request let transition_request = GovernanceTransitionRequest { action: VfAction::TransferCustody, resource: resource.clone(), requesting_agent: agent_info.agent_initial_pubkey, context: TransitionContext { target_custodian: Some(new_custodian), process_notes: notes, ..Default::default() }, }; // 3. Call resource zome to handle state transition let result: GovernanceTransitionResult = call( CallTargetCell::Local, "zome_resource", "request_resource_transition".into(), None, &transition_request, )?; // 4. Handle result if result.success { println!("Transfer approved by governance"); if let Some(event) = result.economic_event { println!("Economic event generated: {:?}", event); } } else { println!("Transfer rejected: {:?}", result.rejection_reasons); } Ok(result) } }
Use Process with Governance Validation
#![allow(unused)] fn main() { // Use process with governance operator pattern pub fn request_resource_use_with_governance( resource_hash: ActionHash, use_notes: Option<String>, ) -> ExternResult<GovernanceTransitionResult> { let resource = get_economic_resource(resource_hash)?; let agent_info = agent_info()?; let use_request = GovernanceTransitionRequest { action: VfAction::Use, resource: resource, requesting_agent: agent_info.agent_initial_pubkey, context: TransitionContext { process_notes: use_notes, ..Default::default() }, }; let result: GovernanceTransitionResult = call( CallTargetCell::Local, "zome_resource", "request_resource_transition".into(), None, &use_request, )?; // Check if specific validation was required if let Some(next_steps) = result.next_steps { println!("Additional validation required: {:?}", next_steps); } Ok(result) } }
Transport Process with Role Validation
#![allow(unused)] fn main() { // Transport process requiring Transport role validation pub fn transport_resource_with_governance( resource_hash: ActionHash, destination: String, transport_notes: Option<String>, ) -> ExternResult<GovernanceTransitionResult> { let resource = get_economic_resource(resource_hash)?; let agent_info = agent_info()?; let transport_request = GovernanceTransitionRequest { action: VfAction::Move, resource: resource, requesting_agent: agent_info.agent_initial_pubkey, context: TransitionContext { target_location: Some(destination), process_notes: transport_notes, ..Default::default() }, }; let result: GovernanceTransitionResult = call( CallTargetCell::Local, "zome_resource", "request_resource_transition".into(), None, &transport_request, )?; // Transport generates both Move and Work events if result.success { if let Some(event) = result.economic_event { match event.action { VfAction::Move => println!("Transport move event generated"), VfAction::Work => println!("Transport work event generated"), _ => println!("Other event type: {:?}", event.action), } } } Ok(result) } }
Repair Process with State Change Validation
#![allow(unused)] fn main() { // Repair process with state transition validation // Repair sets OperationalState::InMaintenance on the EconomicResource instance; // LifecycleStage on NondominiumIdentity remains unchanged (REQ-NDO-OS-01). pub fn repair_resource_with_governance( resource_hash: ActionHash, repair_details: String, new_operational_state: Option<OperationalState>, ) -> ExternResult<GovernanceTransitionResult> { let resource = get_economic_resource(resource_hash)?; let agent_info = agent_info()?; let repair_request = GovernanceTransitionRequest { action: VfAction::Modify, resource: resource, requesting_agent: agent_info.agent_initial_pubkey, context: TransitionContext { process_notes: Some(repair_details), metadata: new_operational_state.map(|state| { let mut metadata = HashMap::new(); metadata.insert("target_operational_state".to_string(), state.to_string()); metadata }).unwrap_or_default(), ..Default::default() }, }; let result: GovernanceTransitionResult = call( CallTargetCell::Local, "zome_resource", "request_resource_transition".into(), None, &repair_request, )?; // Verify resource state was updated as expected if result.success { if let (Some(expected_state), Some(actual_state)) = (new_state, result.new_resource_state.as_ref()) { if actual_state.state == expected_state { println!("Resource state correctly updated to: {:?}", expected_state); } else { warn!("Resource state mismatch: expected {:?}, got {:?}", expected_state, actual_state.state); } } } Ok(result) } }
Batch Processing with Governance
#![allow(unused)] fn main() { // Batch multiple state transitions efficiently pub fn batch_process_transitions( requests: Vec<GovernanceTransitionRequest>, ) -> ExternResult<Vec<GovernanceTransitionResult>> { // Validate batch size if requests.len() > 50 { return Err(WasmError::Guest( "Batch size too large, maximum 50 requests".to_string() ).into()); } // Group requests by resource specification for efficiency let mut grouped_requests: HashMap<ActionHash, Vec<GovernanceTransitionRequest>> = HashMap::new(); for request in requests { let spec_hash = request.resource.conforms_to; grouped_requests.entry(spec_hash) .or_insert_with(Vec::new) .push(request); } // Process each group through resource zome let mut all_results = Vec::new(); for group_requests in grouped_requests.values() { let group_results: Vec<GovernanceTransitionResult> = call( CallTargetCell::Local, "zome_resource", "batch_state_transitions".into(), None, &group_requests, )?; all_results.extend(group_results); } Ok(all_results) } // Example batch usage pub async fn example_batch_transfers() -> ExternResult<()> { let transfers = vec![ create_transfer_request("resource_1", "agent_2"), create_transfer_request("resource_2", "agent_3"), create_transfer_request("resource_3", "agent_1"), ]; let results = batch_process_transitions(transfers)?; for (index, result) in results.iter().enumerate() { match result.success { true => println!("Transfer {} approved", index + 1), false => println!("Transfer {} rejected: {:?}", index + 1, result.rejection_reasons), } } Ok(()) } fn create_transfer_request(resource_id: &str, target_agent: &str) -> GovernanceTransitionRequest { let resource_hash = resource_id.parse().expect("Invalid resource ID"); let target_custodian = target_agent.parse().expect("Invalid agent ID"); GovernanceTransitionRequest { action: VfAction::TransferCustody, resource: get_economic_resource(resource_hash).unwrap(), requesting_agent: agent_info().unwrap().agent_initial_pubkey, context: TransitionContext { target_custodian: Some(target_custodian), ..Default::default() }, } } }
Usage Examples
Economic Process Workflows
Simple Agent First Transaction
#![allow(unused)] fn main() { use zome_gouvernance_integrity::VfAction; // Simple Agent's first transfer (triggers promotion) let initial_transfer_event = LogEconomicEventInput { action: VfAction::InitialTransfer, provider: simple_agent_pubkey, receiver: accountable_agent_pubkey, resource_inventoried_as: new_resource_hash, resource_quantity: 1.0, note: Some("First resource transfer triggering agent promotion".to_string()), }; // This automatically triggers: // 1. Resource validation by receiving agent // 2. Simple Agent promotion to Accountable Agent // 3. Bi-directional PPR issuance (ResourceContribution + NetworkValidation) }
Use Process (Core nondominium)
#![allow(unused)] fn main() { // Creating commitment for Use process let use_commitment = Commitment { action: VfAction::Use, provider: resource_custodian, receiver: requesting_agent, resource_inventoried_as: Some(resource_hash), input_of: Some(use_process_hash), due_date: future_timestamp, note: Some("Resource use under governance rules".to_string()), committed_at: sys_time()?, }; // Economic event upon completion let use_event = LogEconomicEventInput { action: VfAction::Use, provider: resource_custodian, receiver: requesting_agent, resource_inventoried_as: resource_hash, resource_quantity: 1.0, note: Some("Resource used according to embedded governance rules".to_string()), }; }
Transport Process (Specialized role required)
#![allow(unused)] fn main() { // Transport process commitment (requires Transport role) let transport_commitment = Commitment { action: VfAction::Work, // Transport is a Work action provider: transport_agent_with_credentials, receiver: destination_agent, resource_inventoried_as: Some(resource_hash), input_of: Some(transport_process_hash), due_date: delivery_deadline, note: Some("Transport resource to new location".to_string()), committed_at: sys_time()?, }; // Movement event during transport let move_event = LogEconomicEventInput { action: VfAction::Move, provider: transport_agent, receiver: destination_agent, resource_inventoried_as: resource_hash, resource_quantity: 1.0, note: Some("Resource moved from origin to destination".to_string()), }; }
Repair Process (Modifies resource state)
#![allow(unused)] fn main() { // Repair commitment (requires Repair role) let repair_commitment = Commitment { action: VfAction::Modify, provider: repair_agent_with_credentials, receiver: resource_owner, resource_inventoried_as: Some(broken_resource_hash), input_of: Some(repair_process_hash), due_date: repair_completion_date, note: Some("Repair resource from broken to functional state".to_string()), committed_at: sys_time()?, }; // Repair completion event let repair_event = LogEconomicEventInput { action: VfAction::Modify, provider: repair_agent, receiver: resource_owner, resource_inventoried_as: broken_resource_hash, resource_quantity: 1.0, note: Some("Resource repaired: broken → functional".to_string()), }; }
Process Chaining (Multi-role agent)
#![allow(unused)] fn main() { // Agent with Transport + Repair roles chaining actions let chained_commitment = Commitment { action: VfAction::Work, // Represents entire chain provider: multi_role_agent, receiver: final_recipient, resource_inventoried_as: Some(resource_hash), input_of: Some(chained_process_hash), due_date: completion_deadline, note: Some("Transport → Repair → Transport delivery chain".to_string()), committed_at: sys_time()?, }; // Single completion event for entire chain let chain_completion_event = LogEconomicEventInput { action: VfAction::Work, provider: multi_role_agent, receiver: final_recipient, resource_inventoried_as: resource_hash, resource_quantity: 1.0, note: Some("Completed transport + repair + delivery chain".to_string()), }; }
TypeScript (UI) - Process Management
import type { VfAction, EconomicEvent, Commitment } from "./types";
// Process initiation helper
const initiateProcess = (
processType: "Use" | "Transport" | "Storage" | "Repair",
resourceHash: string,
agentHasRole: boolean,
): Commitment => {
if (!agentHasRole && processType !== "Use") {
throw new Error(`Agent lacks required role for ${processType} process`);
}
const actionMap: Record<string, VfAction> = {
Use: "Use",
Transport: "Work",
Storage: "Work",
Repair: "Modify",
};
return {
action: actionMap[processType],
provider: agentPubKey,
receiver: recipientPubKey,
resource_inventoried_as: resourceHash,
input_of: `${processType.toLowerCase()}_process_${Date.now()}`,
due_date: Date.now() + 24 * 60 * 60 * 1000, // 24 hours
note: `${processType} process commitment`,
committed_at: Date.now(),
};
};
// Usage examples
const useCommitment = initiateProcess("Use", resourceHash, true); // All Accountable Agents can use
const transportCommitment = initiateProcess(
"Transport",
resourceHash,
hasTransportRole,
);
const repairCommitment = initiateProcess("Repair", resourceHash, hasRepairRole);
// PPR generation tracking
const trackPPRGeneration = (commitment: Commitment, event: EconomicEvent) => {
// When claim links commitment to event, bi-directional PPRs are automatically generated
console.log(
`PPRs will be issued for ${commitment.action} process completion`,
);
// Example PPR types generated:
// - ServiceCommitmentAccepted (when commitment created)
// - ServiceFulfillmentCompleted (when event recorded)
// - Corresponding counterparty receipts
};
Action Properties & Role Requirements
The VfAction enum includes helper methods to understand action behavior and governance requirements:
#![allow(unused)] fn main() { use zome_gouvernance_integrity::VfAction; let action = VfAction::Work; // Used in Transport/Storage processes // Check if action requires existing resource if action.requires_existing_resource() { // Validate resource exists before allowing action let resource_exists = verify_resource_exists(resource_hash)?; } // Check if action creates new resource if action.creates_resource() { // Handle resource creation logic and trigger validation let validation_required = action == VfAction::Produce; } // Check if action modifies quantity if action.modifies_quantity() { // Update resource quantity and validate changes update_resource_quantity(resource_hash, new_quantity)?; } // Check if action changes custody if action.changes_custody() { // Update custodian information and generate custody PPRs transfer_custody_with_pprs(current_custodian, new_custodian)?; } // NEW: Check if action requires specialized role fn requires_specialized_role(action: &VfAction, process_type: &str) -> Option<String> { match (action, process_type) { (VfAction::Work, "Transport") => Some("Transport".to_string()), (VfAction::Work, "Storage") => Some("Storage".to_string()), (VfAction::Modify, "Repair") => Some("Repair".to_string()), (VfAction::Use, _) => None, // Accessible to all Accountable Agents _ => None, } } // NEW: Check if action triggers PPR generation fn triggers_ppr_generation(action: &VfAction) -> bool { match action { VfAction::InitialTransfer => true, // ResourceContribution + NetworkValidation VfAction::Use => true, // Service process receipts VfAction::Work => true, // Transport/Storage service receipts VfAction::Modify => true, // Repair service receipts VfAction::TransferCustody => true, // ResponsibleTransfer + CustodyAcceptance _ => false, } } // NEW: Get process validation requirements fn get_validation_requirements(action: &VfAction, process_type: &str) -> ValidationRequirements { match (action, process_type) { (VfAction::InitialTransfer, _) => ValidationRequirements { requires_resource_validation: true, requires_agent_validation: true, minimum_validators: 1, validation_scheme: "simple_majority".to_string(), }, (VfAction::Work, "Transport") => ValidationRequirements { requires_process_validation: true, minimum_validators: 1, validation_scheme: "simple_approval".to_string(), }, (VfAction::Modify, "Repair") => ValidationRequirements { requires_process_validation: true, requires_state_change_validation: true, minimum_validators: 1, validation_scheme: "simple_approval".to_string(), }, _ => ValidationRequirements::default(), } } // Example usage in process validation let transport_action = VfAction::Work; if let Some(required_role) = requires_specialized_role(&transport_action, "Transport") { let agent_has_role = check_agent_role(agent_pubkey, &required_role)?; if !agent_has_role { return Err(ProcessError::InsufficientRole(required_role)); } } if triggers_ppr_generation(&transport_action) { // Prepare for automatic PPR issuance upon process completion prepare_ppr_generation(commitment_hash, process_type)?; } }
Role-Action Matrix
| Action | Use Process | Transport Process | Storage Process | Repair Process | Role Required |
|---|---|---|---|---|---|
Use | ✓ (Primary) | - | - | - | Accountable Agent |
Work | - | ✓ (Primary) | ✓ (Primary) | ✓ (Secondary) | Transport/Storage Role |
Modify | - | - | - | ✓ (Primary) | Repair Role |
Move | - | ✓ (Secondary) | - | - | Transport Role |
TransferCustody | - | ✓ (Final) | ✓ (Final) | ✓ (Final) | Process Role + Custodian |
Migration from String-Based Actions
Before (String-based)
#![allow(unused)] fn main() { // Old approach - error-prone let event = EconomicEvent { action: "initial-transfer".to_string(), // Could have typos // ... }; }
After (Enum-based)
#![allow(unused)] fn main() { // New approach - type-safe let event = EconomicEvent { action: VfAction::InitialTransfer, // Compile-time validation // ... }; }
Benefits
Core Development Benefits
- Type Safety: Compile-time validation prevents typos and invalid actions
- IDE Support: Better autocomplete and refactoring support
- Documentation: Self-documenting code with clear action definitions
- ValueFlows Compliance: Ensures actions match standard vocabulary
- Maintainability: Easier to add new actions and understand existing code
Governance Integration Benefits
- Role-Based Access Control: Automatic validation of agent roles for specialized processes
- PPR Integration: Seamless Private Participation Receipt generation for reputation tracking
- Process Validation: Built-in support for Economic Process validation requirements
- Cross-Zome Consistency: Unified action handling across person, resource, and governance zomes
- Audit Trail Completeness: Every action properly logged with governance context
Economic Process Benefits
- Process Chaining Support: Enable complex multi-step service delivery
- State Management: Proper resource state transitions based on action type
- Validation Automation: Automatic triggering of appropriate validation workflows
- Performance Tracking: Built-in performance metrics for service quality assessment
Security & Privacy Benefits
- Capability Enforcement: Actions respect progressive agent capability levels
- End-to-End Validation: From commitment through completion with cryptographic signatures
- Dispute Resolution Support: Clear action history for conflict resolution
- Privacy Preservation: PPR generation respects private entry storage patterns
Future Extensions
The VfAction enum is designed for extensibility to support advanced governance features:
Phase 2 Action Extensions
#![allow(unused)] fn main() { pub enum VfAction { // ... existing actions // Advanced governance actions Delegate, // Delegate responsibility to another agent Revoke, // Revoke access or role assignment Audit, // Formal audit process initiation Mediate, // Dispute mediation action Escalate, // Escalate dispute to higher governance level } }
Phase 3 Network Actions
#![allow(unused)] fn main() { pub enum VfAction { // ... existing actions // Cross-network actions Bridge, // Bridge resource to another network Federate, // Federate governance across networks Synchronize, // Synchronize state across federated networks Migrate, // Migrate resource between networks } }
Integration Requirements for New Actions
When adding new VfAction variants:
- Update Helper Methods: Extend
requires_existing_resource(),creates_resource(), etc. - Define Role Requirements: Specify which agent roles can perform the action
- PPR Integration: Define what PPR types should be generated
- Validation Rules: Specify validation requirements and schemes
- Process Integration: Define how action fits into Economic Processes
- TypeScript Types: Update UI types for consistency
Example: Adding a Delegate Action
#![allow(unused)] fn main() { // 1. Add to enum pub enum VfAction { // ... existing actions Delegate, // Delegate responsibility to another agent } // 2. Update helper methods impl VfAction { pub fn requires_delegation_capability(&self) -> bool { match self { VfAction::Delegate => true, _ => false, } } } // 3. Define role requirements fn requires_specialized_role(action: &VfAction, process_type: &str) -> Option<String> { match (action, process_type) { // ... existing matches (VfAction::Delegate, _) => Some("Primary Accountable Agent".to_string()), _ => None, } } // 4. PPR integration fn triggers_ppr_generation(action: &VfAction) -> bool { match action { // ... existing matches VfAction::Delegate => true, // DelegationAccepted + ResponsibilityTransferred _ => false, } } // 5. TypeScript update export type VfAction = // ... existing actions | "Delegate"; // Delegate responsibility to another agent }
Action Design Principles
New actions should follow these principles:
- ValueFlows Alignment: Maintain compatibility with ValueFlows standard
- Role-Based Access: Clear role requirements for governance
- PPR Generation: Automatic reputation tracking integration
- Process Awareness: Integration with Economic Process workflows
- Validation Support: Built-in validation and compliance checking
- Privacy Preservation: Respect private entry patterns for sensitive operations
Remember to update all three layers (Rust integrity, Rust coordinator, TypeScript UI) when adding new actions to maintain type consistency and governance integration across the entire stack.
Protocol Bridge Specifications for Nondominium
Executive Summary
This document outlines the technical requirements for integrating Nondominium's Holochain-based resource sharing protocol with external platforms using a Bun Bridge Service powered by the official @holochain/client library. This approach provides full-featured, real-time integration while allowing each platform (Tiki Wiki, Odoo/ERPLibre, Dolibarr, etc.) to maintain its familiar workflow.
The architecture separates concerns into two layers:
- Protocol Bridge (generic, reusable): Bun/TypeScript service translating REST/JSON to Holochain WebSocket
- Platform Integration Layer (per-platform): Business logic, data mapping, and UI specific to each platform
1. Architecture Overview
1.1 Two-Layer Architecture (Protocol Bridge + Platform Module)
graph TB
subgraph "Platform Layer (per-platform)"
PlatformUI[Platform Web Interface]
PlatformBackend[Platform Backend]
MobileApp[Mobile Application]
end
subgraph "Bun Bridge Service"
BridgeAPI[REST API Layer]
HoloClient[@holochain/client]
Cache[Redis Cache]
Queue[Job Queue]
SignalHandler[Signal Handler]
end
subgraph "Holochain Infrastructure"
Conductor[Holochain Conductor]
DNA[Nondominium DNA]
DHT[Distributed Hash Table]
end
PlatformUI --> PlatformBackend
PlatformBackend --> BridgeAPI
MobileApp --> BridgeAPI
BridgeAPI --> HoloClient
HoloClient <--> Conductor
SignalHandler --> PlatformBackend
BridgeAPI --> Cache
BridgeAPI --> Queue
Conductor <--> DNA
DNA <--> DHT
1.2 Component Specifications
1. Bun Bridge Service
- Purpose: Official WebSocket-based bridge between platform backends and Holochain
- Technology: Bun with
@holochain/clientlibrary and Hono framework - Key Features:
- RESTful API for platform modules (PHP, Python, Java, etc.)
- Full WebSocket connectivity to Holochain Conductor
- Real-time signal subscription and forwarding
- Request batching and caching (Redis)
- Async job queue for long-running operations
- Proper zome call signing and capability management
- Health monitoring and logging
Why Bun + Hono?
- Consistency: The main nondominium repo already uses Bun as its runtime
- Official Support:
@holochain/clientis maintained by Holochain core team and works with Bun - Full Features: Real-time signals, proper signing, batch operations
- Performance: Bun's fast startup, native WebSocket, and low memory footprint; Hono's lightweight routing
- Built-in TypeScript: No transpilation step needed
- RESTful Interface: Clean Hono API for any platform to consume
- Caching & Queuing: Performance optimization built-in
2. Holochain Conductor
- Purpose: Run Nondominium hApp and manage agent keys
- Deployment: Docker containerized
- Configuration:
- Admin WebSocket on port 8000
- App WebSocket on port 8888
- Support for multiple concurrent agents (organizations)
- Automatic conductor configuration via bridge service
3. Platform Integration Layer
- Purpose: Connect platform user accounts to Holochain agents
- Requirements (per-platform):
- Platform session token validation
- Holochain agent key generation and management
- Role-based access control mapping
- Secure credential storage
- Single Sign-On (SSO) compatibility
1.3 Organization-as-Agent Model
Based on the ERP-Holochain bridge analysis, platforms operate in an Organizational Context with the following implications:
Identity Architecture
- Platform Group/Organization -> Holochain Organization Agent
- Platform User -> Delegate Key (with scoped permissions)
- Delegation Pattern: Required for all zome calls signed by users on behalf of organizations
Reputation Aggregation
- External PPRs accrue to the Organization
- Internal attribution tracked via
performed_bymetadata - New users inherit the organization's reputation (trust by association)
Governance Model
- Policy-Driven: Automated rules based on platform group permissions
- Multi-Sig Support: High-value transactions require multiple delegate approvals
- Automated Approval: ERP-style workflows (e.g., "Auto-approve Use requests < $500")
Custody vs. Ownership
- Organization owns the resource
- Individual users (employees) hold temporary custody
- Internal transfers (between users in same org) may not trigger DHT events
Device Management
- Shared Terminals: Warehouse tablets used by multiple staff members
- Session Management: Rapid login/logout of different delegates
- SSO Integration: Map platform session tokens to Holochain capability tokens
1.4 Why Bun Bridge (Not HTTP Gateway)?
The Bun Bridge Service using @holochain/client is the only recommended approach for production platform-Nondominium integration:
Key Advantages:
- Official Library:
@holochain/clientis maintained by Holochain core team - Full Features: Real-time signals, proper zome call signing, batch operations
- Production-Ready: Built-in connection management, retry logic, health checks
- Performance: Persistent WebSocket connection, Redis caching, job queues
- Clean API: RESTful interface familiar to developers of all platforms
HTTP Gateway Alternative (Not Recommended for Production):
- GET-only requests with Base64-encoded payloads
- No native signal support for real-time updates
- Limited batch operations and session management
- Performance constraints (connection overhead per request)
Note: The
hc-http-gwHTTP Gateway is suitable for PoC/prototyping. See the nondominium-erp-bridge repository for a Python PoC reference implementation using hc-http-gw with 101 tests.
2. Integration API Specifications
2.1 Bridge Architecture
The Bun Bridge Service architecture provides a clean RESTful interface for any platform's backend code:
Architecture:
Platform Backend <--HTTP/JSON--> Bun Bridge (@holochain/client) <--WebSocket--> Holochain Conductor <--> Nondominium DHT
How It Works:
- Platform modules make standard HTTP requests to the Bun Bridge REST API
- Bun Bridge maintains persistent WebSocket connection to Holochain
- Bridge handles zome call signing, capability tokens, and signal subscriptions
- Real-time signals from Holochain pushed to platforms via webhooks
- Redis caching for frequently accessed data (resource lists, reputation scores)
- Job queue for async operations (batch syncs, long-running processes)
Benefits:
- Clean Interface: Platform developers work with familiar REST/JSON
- Full Features: Access to all Holochain capabilities (signals, signing, etc.)
- Performance: Caching, batching, connection pooling
- Reliability: Built-in retry logic, error handling, health checks
- Real-time: WebSocket signals forwarded to platforms instantly
2.2 Core REST API Endpoints
Bun Bridge REST API
# Resource Discovery
POST /api/resources
GET /api/resources/{resource_id}
GET /api/resources/search?query=CNC
# Resource Operations
POST /api/resources
PUT /api/resources/{resource_id}
DELETE /api/resources/{resource_id}
PATCH /api/resources/{resource_id}/state
# Transaction Management
POST /api/commitments
GET /api/commitments/{commitment_id}
POST /api/events
GET /api/events/by-resource/{resource_id}
# Reputation System
GET /api/reputation/{agent_id}/summary
GET /api/reputation/{agent_id}/receipts
# Batch Operations
POST /api/batch
2.3 Bun Bridge Service Implementation
// bridge-service.js
import { AppWebsocket, AdminWebsocket } from '@holochain/client';
import { Hono } from 'hono';
import { createClient } from 'redis';
class NondominiumBridgeService {
constructor(config) {
this.appWs = null;
this.adminWs = null;
this.redis = createClient({ url: config.redisUrl });
this.config = config;
}
async connect() {
// Connect to Holochain Admin API
this.adminWs = await AdminWebsocket.connect({
url: new URL(this.config.adminWsUrl),
wsClientOptions: { origin: 'nondominium-bridge' }
});
// Connect to App WebSocket
const token = await this.adminWs.issueAppAuthenticationToken({
installed_app_id: this.config.appId
});
this.appWs = await AppWebsocket.connect({
url: new URL(this.config.appWsUrl),
token: token.token,
wsClientOptions: { origin: 'nondominium-bridge' }
});
// Subscribe to signals
this.appWs.on('signal', this.handleSignal.bind(this));
await this.redis.connect();
console.log('Bridge connected to Holochain and Redis');
}
async handleSignal(signal) {
console.log('Received signal:', signal);
// Push signal to registered webhook endpoints
await this.notifyWebhooks(signal);
}
async notifyWebhooks(signal) {
// POST to registered platform webhook endpoints
for (const [url, config] of this.webhooks) {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Nondominium-Signature': this.generateSignature(signal)
},
body: JSON.stringify({
type: signal.data.type,
payload: signal.data.payload
})
});
console.log(`Notified ${url}:`, response.status);
}
}
async callZome(cellId, zomeName, fnName, payload) {
const cacheKey = `zome:${zomeName}:${fnName}:${JSON.stringify(payload)}`;
// Check cache for read operations
if (fnName.startsWith('get_')) {
const cached = await this.redis.get(cacheKey);
if (cached) return JSON.parse(cached);
}
try {
const result = await this.appWs.callZome({
cell_id: cellId,
zome_name: zomeName,
fn_name: fnName,
payload: payload
}, 30000);
// Cache read operations
if (fnName.startsWith('get_')) {
await this.redis.setEx(cacheKey, 300, JSON.stringify(result));
}
return result;
} catch (error) {
console.error('Zome call failed:', error);
throw error;
}
}
generateSignature(data) {
// HMAC signature for webhook authentication
return crypto.createHmac('sha256', this.config.webhookSecret)
.update(JSON.stringify(data))
.digest('hex');
}
}
// Initialize bridge
const bridge = new NondominiumBridgeService({
adminWsUrl: process.env.HC_ADMIN_WS_URL || 'ws://localhost:8000',
appWsUrl: process.env.HC_APP_WS_URL || 'ws://localhost:8888',
appId: process.env.HC_APP_ID || 'nondominium',
redisUrl: process.env.REDIS_URL || 'redis://localhost:6379',
webhookSecret: process.env.WEBHOOK_SECRET
});
await bridge.connect();
// Hono API
const app = new Hono();
function getCellId(body: any, query: any) {
return [body?.dna_hash || query?.dna_hash, body?.agent_key || query?.agent_key];
}
// Resource Management
app.post('/api/resources', async (c) => {
try {
const body = await c.req.json();
const cellId = getCellId(body, null);
const result = await bridge.callZome(cellId, 'zome_resource', 'create_economic_resource', {
spec_hash: body.spec_hash,
quantity: body.quantity,
unit: body.unit,
custodian: body.custodian
});
return c.json({ success: true, data: result });
} catch (error) {
return c.json({ success: false, error: error.message }, 500);
}
});
app.get('/api/resources/search', async (c) => {
try {
const query = c.req.query();
const cellId = getCellId(null, query);
const resources = await bridge.callZome(cellId, 'zome_resource', 'get_all_economic_resources', {
query: query.query
});
return c.json({ success: true, data: resources });
} catch (error) {
return c.json({ success: false, error: error.message }, 500);
}
});
// Batch operations
app.post('/api/batch', async (c) => {
try {
const body = await c.req.json();
const cellId = getCellId(body, null);
const results = await Promise.all(
body.operations.map((op: any) =>
bridge.callZome(cellId, op.zome, op.function, op.payload)
)
);
return c.json({ success: true, data: results });
} catch (error) {
return c.json({ success: false, error: error.message }, 500);
}
});
app.get('/health', (c) => {
return c.json({
status: 'ok',
holochain: bridge.appWs ? 'connected' : 'disconnected',
redis: bridge.redis.isOpen ? 'connected' : 'disconnected'
});
});
const PORT = process.env.PORT || 3000;
export default { port: PORT, fetch: app.fetch };
3. Data Model Reference
3.1 Nondominium Zome Functions
The Nondominium hApp exposes three zomes. For the complete function reference, see the ERP Bridge Technical Specifications (Sections 4.3-4.4), which documents all coordinator functions for zome_person, zome_resource, and zome_gouvernance.
Summary of available zomes:
| Zome | Purpose | Key Functions |
|---|---|---|
zome_person | Agent identity, profiles, roles, capabilities | create_person, assign_person_role, store_private_person_data, grant_private_data_access |
zome_resource | Resource specs, economic resources, governance rules | create_resource_specification, create_economic_resource, transfer_custody, create_governance_rule |
zome_gouvernance | Commitments, events, validation, PPR | propose_commitment, log_economic_event, issue_participation_receipts, create_validation_receipt |
3.2 Critical Naming Conventions
Pydantic/JSON field names must match Rust zome field names exactly (Holochain uses JSON transcoding):
| Correct Field Name | NOT the REA/ValueFlows Name | Context |
|---|---|---|
spec_hash | conforms_to | EconomicResourceInput — links resource to its specification |
category | default_unit | ResourceSpecification — category string, not a unit |
Enum Values (PascalCase strings):
OperationalState:"PendingValidation","Available","Reserved","InTransit","InStorage","InMaintenance","InUse"LifecycleStage(onNondominiumIdentity):"Ideation","Specification", … through"EndOfLife"VfAction: 16 variants —"Transfer","Use","InitialTransfer","TransferCustody", etc.ParticipationClaimType: 16 variants —"ResourceProvider","ResourceReceiver","Custodian", etc.
Reference: The nondominium-erp-bridge Pydantic v2 models in
bridge/models.pyserve as the authoritative source for field names and types.
4. User Story Implementation Flow
4.1 Phase 1: Resource Discovery & Registration
sequenceDiagram
participant UserA as User A (Org A)
participant Platform as Platform UI
participant Bridge as Bun Bridge Service
participant Conductor as Holochain Conductor
participant DNA as Nondominium DNA
UserA->>Platform: Login to platform
Platform->>Bridge: Validate session + get agent keys
Bridge->>Conductor: authenticate_agent()
Conductor->>DNA: Return agent_pub_key
UserA->>Platform: Register resource (e.g., CNC machine)
Platform->>Bridge: POST /api/resources
Bridge->>Conductor: create_economic_resource()
Conductor->>DNA: Resource entry created
DNA-->>Conductor: resource_hash
Conductor-->>Bridge: Resource created
Bridge-->>Platform: Resource details + QR code
Platform-->>UserA: Resource registered successfully
4.2 Phase 2: Multi-Party Transaction Process
sequenceDiagram
participant UserB as User B (Org B)
participant Platform as Platform UI
participant Bridge as Bun Bridge Service
participant Conductor as Holochain Conductor
participant DNA as Nondominium DNA
UserB->>Platform: Search for equipment
Platform->>Bridge: GET /api/resources/search
Bridge->>Conductor: get_all_economic_resources()
Conductor->>DNA: Query resources
DNA-->>Conductor: Available resources
Conductor-->>Bridge: Resource list + governance rules
Bridge-->>Platform: Formatted resource data
Platform-->>UserB: Display available resources
UserB->>Platform: Submit access request
Platform->>Bridge: POST /api/commitments
Bridge->>Conductor: propose_commitment()
Conductor->>DNA: Create commitment
DNA-->>Conductor: commitment_hash
Conductor-->>Bridge: Commitment created
Bridge-->>Platform: Request submitted for approval
4.3 Phase 3: Custody Transfer with QR Codes
sequenceDiagram
participant UserA as User A (Org A)
participant UserB as User B (Org B)
participant Mobile as Mobile App
participant Bridge as Bun Bridge Service
participant Conductor as Holochain Conductor
participant DNA as Nondominium DNA
Note over UserA,UserB: Physical transfer at location
UserA->>Mobile: Scan QR code on resource
Mobile->>Bridge: POST /api/transport/qr-scan
Bridge->>Conductor: initiate_transfer_custody()
Conductor->>DNA: Create TransferCustody event
UserB->>Mobile: Scan confirmation QR code
Mobile->>Bridge: POST /api/transport/confirm
Bridge->>Conductor: complete_transfer_custody()
Conductor->>DNA: Update custodian field
DNA->>Conductor: Generate PPR receipts
Conductor->>Bridge: Transfer complete + PPRs
Bridge-->>Mobile: Success confirmation
5. Mobile Application Requirements
QR Code Scanning Features
interface QRCodeData {
resourceId: string;
resourceHash: string;
location: {
latitude: number;
longitude: number;
};
timestamp: string;
custodianPubKey: string;
sessionId: string;
}
// Scan result processing
function processQRScan(qrData: QRCodeData): Promise<TransferResult> {
// Validate QR code authenticity
// Initiate custody transfer
// Generate cryptographic signatures
// Update real-time status
}
Offline Capabilities
- Cache critical resource data for offline access
- Queue custody transfer operations when connectivity lost
- Synchronize pending operations when connection restored
- Local storage of QR code scan history
Push Notifications
// Real-time transaction updates
interface NotificationPayload {
type: "transaction_update" | "resource_available" | "ppr_update";
title: string;
message: string;
data: any;
priority: "high" | "normal" | "low";
}
6. Security & Authentication
Identity Bridge Architecture
Based on the Organizational Context from the ERP bridge analysis, platforms operate in a delegated agency model where:
- Platform organizations are represented as Holochain agents
- Individual platform users act as delegates/representatives of the organization
- Delegation requires scope, expiry, and revocation mechanisms
Key Security Concepts
- Organization Agent Key: Generated via Holochain Admin API, stored securely server-side
- Delegate Key: Per-user signing key for acting on behalf of the organization
- Capability Grants: Scoped, time-limited permissions granted to delegate keys
- Webhook Signatures: HMAC-SHA256 signatures for verifying signal authenticity
Data Privacy Controls
// Privacy settings per resource
interface ResourcePrivacy {
resourceId: string;
publicFields: ("name" | "location" | "specifications")[];
privateFields: ("owner_details" | "usage_history" | "maintenance_records")[];
accessControl: "public" | "organization_only" | "approved_agents_only";
}
Organizational vs. P2P Context
| Aspect | Organizational (ERP/Platform) | Pure P2P |
|---|---|---|
| Identity Model | Platform Group = Org Agent, Users = Delegates | 1 Human = 1 Agent Key |
| Signing Authority | Delegated (users sign on behalf of org) | Direct (individual signs) |
| Reputation | Accrues to organization, internal attribution | Accrues to individual |
| Governance | Policy-driven, automated rules | Ad-hoc, social negotiation |
| Device Usage | Shared terminals, SSO integration | Personal devices |
7. Performance Requirements
Response Time Targets
- Resource Search: < 2 seconds for basic queries
- Transaction Updates: < 500ms for status changes
- QR Code Processing: < 3 seconds end-to-end
- Real-time Synchronization: < 1 second for webhook delivery
- Authentication: < 1 second for user validation
Scalability Requirements
concurrent_users:
target: 1000
peak: 5000
resource_transactions:
daily_volume: 10000
peak_concurrent: 500
api_throughput:
requests_per_second: 1000
burst_capacity: 5000
data_storage:
resources_per_organization: 10000
transaction_history: 7_years
Caching Strategy
// Multi-level caching
interface CacheConfiguration {
level1_memory: {
user_sessions: "15 minutes";
resource_metadata: "1 hour";
reputation_scores: "30 minutes";
};
level2_redis: {
search_results: "5 minutes";
transaction_status: "real-time";
availability_data: "2 minutes";
};
level3_cdn: {
static_assets: "24 hours";
api_responses: "5 minutes";
qr_codes: "1 hour";
};
}
8. Integration Workflow Requirements
Data Synchronization
Master Data Management
// Platform <-> Holochain sync mapping
interface SyncMapping {
platformUser: HolochainAgent;
platformResource: EconomicResource;
platformTransaction: Commitment + EconomicEvent[];
platformProfile: Person + PrivatePersonData;
}
// Bidirectional sync rules
const SYNC_RULES = {
// Platform -> Holochain
userRegistration: "create_holochain_agent",
resourceCreation: "create_economic_resource",
transactionInitiation: "create_commitment",
// Holochain -> Platform
reputationUpdates: "update_user_profile",
transactionCompletion: "update_transaction_status",
custodyTransfers: "update_resource_custodian"
};
Conflict Resolution
interface ConflictResolution {
strategy:
| "holochain_master"
| "platform_master"
| "timestamp_win"
| "manual_review";
rules: {
resource_metadata: "holochain_master";
user_preferences: "platform_master";
transaction_status: "timestamp_win";
reputation_data: "holochain_master";
};
}
Error Handling & Recovery
Transaction Rollback
interface RollbackStrategy {
commitment_creation: [
"delete_commitment_entry",
"release_resource_reservation",
"notify_stakeholders",
];
custody_transfer: [
"reverse_custody_update",
"invalidate_ppr_receipts",
"notify_transport_parties",
];
}
Fallback Procedures
// Service degradation handling
const FALLBACK_PROCEDURES = {
bridge_service_down: "cache_operations + retry_exponential_backoff",
conductor_unavailable: "read_only_mode + queue_operations",
network_partition: "local_validation + sync_when_available",
high_load: "request_throttling + background_processing",
};
9. Testing Requirements
Integration Test Scenarios
End-to-End User Journey Tests
describe("Platform-Nondominium Integration", () => {
test("Complete resource sharing workflow", async () => {
// 1. User A registers resource through platform
// 2. User B discovers resource via platform search
// 3. Transaction negotiation through platform UI
// 4. QR code-based custody transfer
// 5. Usage tracking and PPR generation
// 6. Return process and reputation updates
});
test("Multi-organization resource discovery", async () => {
// 1. Multiple organizations register resources
// 2. Cross-organization search functionality
// 3. Trust validation between organizations
// 4. Compliance with governance rules
});
});
Performance & Load Testing
interface LoadTestConfiguration {
concurrent_users: [100, 500, 1000, 5000];
scenarios: [
"resource_search",
"transaction_creation",
"qr_scan",
"real_time_sync",
];
duration: "10 minutes per scenario";
success_criteria: {
response_time_p95: "< 2 seconds";
error_rate: "< 0.1%";
throughput: "> 500 requests/second";
};
}
Security Testing
interface SecurityTests {
authentication_tests: [
"invalid_session_token",
"cross_organization_access",
"privilege_escalation_attempts",
];
data_privacy: [
"sensitive_data_encryption",
"access_control_enforcement",
"audit_trail_completeness",
];
api_security: [
"rate_limiting_effectiveness",
"input_validation",
"sql_injection_prevention",
"xss_protection",
];
}
10. Deployment Architecture
Bridge Per Organization (Recommended)
Each organization runs its own full stack:
┌─────────────────────────┐ ┌─────────────────────────┐
│ Org A Server │ │ Org B Server │
│ ┌─────────────────────┐ │ │ ┌─────────────────────┐ │
│ │ Platform + Module │ │ │ │ Platform + Module │ │
│ ├─────────────────────┤ │ │ ├─────────────────────┤ │
│ │ Bun Bridge │ │ │ │ Bun Bridge │ │
│ ├─────────────────────┤ │ │ ├─────────────────────┤ │
│ │ Holochain Node │ │ │ │ Holochain Node │ │
│ │ (Org A Agent) │ │ │ │ (Org B Agent) │ │
│ └─────────────────────┘ │ │ └─────────────────────┘ │
└───────────┬─────────────┘ └───────────┬─────────────┘
│ │
└───────────────────────────────┘
DHT Network
Generic Docker Compose Template
# docker-compose.yml (template - adapt for your platform)
services:
platform:
# Your platform (Tiki, Odoo, Dolibarr, etc.)
depends_on:
- bridge
holochain:
image: holochain/holochain:latest
# NO public ports - internal only
volumes:
- ./nondominium.happ:/happ/nondominium.happ
- holochain_data:/data
command: holochain -c /data/conductor-config.yml
bridge:
build: ./bridge-service
# NO public ports - internal only
environment:
- HC_ADMIN_WS_URL=ws://holochain:8000
- HC_APP_WS_URL=ws://holochain:8888
- HC_APP_ID=nondominium
- REDIS_URL=redis://redis:6379
- WEBHOOK_SECRET=${WEBHOOK_SECRET}
depends_on:
- holochain
- redis
redis:
image: redis:7-alpine
volumes:
holochain_data:
Bridge Service Dockerfile
# bridge-service/Dockerfile
FROM oven/bun:latest
WORKDIR /app
COPY package.json bun.lockb ./
RUN bun install --production
COPY . .
EXPOSE 3000
CMD ["bun", "run", "index.ts"]
Shared Bridge Service (Managed) — Alternative
For organizations preferring managed infrastructure:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Platform A │ │ Platform B │ │ Platform C │
│ Org A │ │ Org B │ │ Org C │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
└───────────────────┼───────────────────┘
│
┌────────▼────────┐
│ Managed Bridge │ ← Multi-tenant
│ Service │ API key per org
└────────┬────────┘
│
┌─────────────┼─────────────┐
│ │ │
┌──────▼──────┐ ┌────▼─────┐ ┌──────▼──────┐
│ Org A Node │ │Org B Node│ │ Org C Node │
└─────────────┘ └──────────┘ └─────────────┘
11. Compliance & Governance
Data Protection
- GDPR compliance for European users
- PII encryption at rest and in transit
- Right to be forgotten implementation
- Audit trail for all resource transactions
Regulatory Compliance
- Equipment insurance validation integration
- Transport certification verification
- Safety protocol compliance tracking
- Tax reporting for resource usage fees
Governance Framework
- Multi-stakeholder governance council
- Dispute resolution mechanism
- Protocol amendment process
- Emergency response procedures
Appendix A: Tiki Wiki Platform Example
This appendix contains Tiki Wiki/PHP-specific implementation examples demonstrating how a PHP-based platform integrates with the Bun Bridge Service.
A.1 PHP Client
<?php
// Tiki module calling Bun Bridge Service
class NondominiumClient {
private $bridge_url;
private $dna_hash;
private $agent_key;
public function __construct($bridge_url, $dna_hash, $agent_key) {
$this->bridge_url = $bridge_url;
$this->dna_hash = $dna_hash;
$this->agent_key = $agent_key;
}
/**
* Search for resources
*/
public function searchResources($query = null, $category = null) {
$response = $this->makeRequest('GET', '/api/resources/search', [
'query' => ['query' => $query, 'category' => $category, 'dna_hash' => $this->dna_hash, 'agent_key' => $this->agent_key]
]);
return $response['data'];
}
/**
* Create a new resource
*/
public function createResource($spec_hash, $quantity, $unit) {
$response = $this->makeRequest('POST', '/api/resources', [
'json' => [
'dna_hash' => $this->dna_hash,
'agent_key' => $this->agent_key,
'spec_hash' => $spec_hash,
'quantity' => $quantity,
'unit' => $unit,
'custodian' => $this->agent_key
]
]);
return $response['data'];
}
/**
* Initiate use process
*/
public function initiateUse($resource_hash, $receiver, $start_time, $end_time) {
$response = $this->makeRequest('POST', "/api/resources/{$resource_hash}/use", [
'json' => [
'dna_hash' => $this->dna_hash,
'agent_key' => $this->agent_key,
'receiver' => $receiver,
'start_time' => $start_time,
'end_time' => $end_time
]
]);
return $response['data'];
}
private function makeRequest($method, $path, $options = []) {
$url = $this->bridge_url . $path;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
if (isset($options['query'])) {
$url .= '?' . http_build_query($options['query']);
curl_setopt($ch, CURLOPT_URL, $url);
}
if (isset($options['json'])) {
$json = json_encode($options['json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
}
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code !== 200) {
throw new Exception("Bridge request failed: HTTP {$http_code}");
}
return json_decode($response, true);
}
}
A.2 Tiki Module Integration
<?php
/**
* Tiki Module: mod-nondominium_resources.php
* Display available resources from Nondominium
*/
require_once('lib/nondominium/NondominiumBridge.php');
function module_nondominium_resources_info() {
return [
'name' => tr('Nondominium Resources'),
'description' => tr('Display available shared resources from Nondominium network'),
'prefs' => ['feature_nondominium'],
'params' => [
'max' => [
'required' => false,
'name' => tr('Maximum number of resources'),
'description' => tr('Maximum number of resources to display'),
'default' => 10,
],
],
];
}
function module_nondominium_resources($mod_reference_values) {
global $prefs;
$bridge = new NondominiumBridge(
$prefs['nondominium_gateway_url'],
$prefs['nondominium_dna_hash']
);
try {
$resources = $bridge->searchResources();
// Filter and format for Tiki display
$smarty = TikiLib::lib('smarty');
$smarty->assign('resources', array_slice($resources, 0, $mod_reference_values['max']));
return $smarty->fetch('modules/mod-nondominium_resources.tpl');
} catch (Exception $e) {
return '<div class="alert alert-danger">' . tr('Error loading resources: ') . $e->getMessage() . '</div>';
}
}
A.3 Tiki Tracker Integration
<?php
/**
* Sync Tiki Tracker items with Nondominium resources
*/
class TikiNondominiumSync {
private $bridge;
private $tracker_id;
public function __construct($bridge, $tracker_id) {
$this->bridge = $bridge;
$this->tracker_id = $tracker_id;
}
/**
* Publish a Tiki Tracker item as a Nondominium resource
*/
public function publishTrackerItem($item_id) {
$trklib = TikiLib::lib('trk');
$item = $trklib->get_tracker_item($item_id);
// Map Tiki fields to Nondominium structure
$resource_data = [
'name' => $item['fields']['name'],
'description' => $item['fields']['description'],
'quantity' => $item['fields']['quantity'],
'unit' => $item['fields']['unit'],
'location' => $item['fields']['location']
];
// Create ResourceSpecification in Nondominium
$spec = $this->bridge->callZome('resource', 'create_resource_specification', [
'name' => $resource_data['name'],
'description' => $resource_data['description']
]);
// Create EconomicResource
$resource = $this->bridge->createResource(
$spec['hash'],
$resource_data['quantity'],
$resource_data['unit'],
$this->getCurrentUserAgentKey()
);
// Store Nondominium hash in Tiki tracker field
$trklib->modify_field($item_id, 'nondominium_hash', $resource['hash']);
return $resource;
}
/**
* Sync Nondominium events back to Tiki
*/
public function syncEventsToTiki($resource_hash) {
$events = $this->bridge->callZome('gouvernance', 'get_events_by_resource', [
'resource_hash' => $resource_hash
]);
foreach ($events as $event) {
// Log event in Tiki activity stream
TikiLib::lib('logs')->add_log('nondominium_event', sprintf(
'Resource %s: %s by %s',
$resource_hash,
$event['action'],
$event['provider']
));
}
}
private function getCurrentUserAgentKey() {
global $user;
$userlib = TikiLib::lib('user');
return $userlib->get_user_preference($user, 'nondominium_agent_key');
}
}
A.4 Webhooks (PHP Handler)
<?php
/**
* webhook_nondominium.php
* Handle real-time updates from Nondominium via webhooks
*/
// Authenticate webhook (verify signature)
function validate_webhook_signature($payload, $signature) {
global $prefs;
$expected = hash_hmac('sha256', $payload, $prefs['nondominium_webhook_secret']);
return hash_equals($expected, $signature);
}
// Main webhook handler
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_NONDOMINIUM_SIGNATURE'] ?? '';
if (!validate_webhook_signature($payload, $signature)) {
http_response_code(401);
exit('Invalid signature');
}
$data = json_decode($payload, true);
switch ($data['type']) {
case 'commitment.updated':
handle_commitment_update($data);
break;
case 'resource.availability':
handle_resource_availability($data);
break;
case 'reputation.updated':
handle_reputation_update($data);
break;
default:
http_response_code(400);
exit('Unknown event type');
}
function handle_commitment_update($data) {
$trklib = TikiLib::lib('trk');
// Find Tiki tracker item by commitment hash
$items = $trklib->list_items($tracker_id = get_commitment_tracker_id(), 0, -1, '', [
'nondominium_hash' => $data['commitmentId']
]);
if (!empty($items['data'])) {
$item_id = $items['data'][0]['itemId'];
// Update status field
$trklib->modify_field($item_id, 'status', $data['status']);
// Send notification to user
send_tiki_notification(
$item_id,
'Commitment Status Updated',
sprintf('Your resource request is now: %s', $data['status'])
);
}
}
function handle_resource_availability($data) {
// Update Tiki tracker item availability status
// Trigger intertracker reference updates if needed
}
function handle_reputation_update($data) {
global $user;
$userlib = TikiLib::lib('user');
// Update user's reputation score in Tiki profile
$userlib->set_user_preference(
$user,
'nondominium_reputation_score',
$data['newScore']
);
// Display notification
TikiLib::lib('smarty')->display_notification([
'title' => 'Reputation Updated',
'message' => sprintf('Your reputation score is now: %.2f', $data['newScore'])
]);
}
http_response_code(200);
echo json_encode(['status' => 'ok']);
A.5 Identity Bridge (PHP)
<?php
/**
* TikiHolochainAuth.php
* Manage identity mapping between Tiki users and Holochain agents
*/
class TikiHolochainAuth {
/**
* Generate or retrieve Holochain agent key for organization
*/
public function getOrganizationAgentKey($org_id) {
global $prefs;
// Check if organization already has agent key
$existing_key = $this->getOrgPreference($org_id, 'holochain_agent_key');
if ($existing_key) {
return $existing_key;
}
// Generate new agent key via Holochain admin API
$admin_client = new HolochainAdminClient($prefs['holochain_admin_url']);
$agent_key = $admin_client->generateAgentPubKey();
// Store in Tiki
$this->setOrgPreference($org_id, 'holochain_agent_key', $agent_key);
return $agent_key;
}
/**
* Create delegation for a Tiki user to act on behalf of organization
*/
public function createDelegation($user, $org_id, $permissions, $expiry_days = 90) {
$bridge = new NondominiumBridge(
$GLOBALS['prefs']['nondominium_gateway_url'],
$GLOBALS['prefs']['nondominium_dna_hash']
);
// Get organization's agent key
$org_agent_key = $this->getOrganizationAgentKey($org_id);
// Generate delegate key for this user
$delegate_key = $this->getUserDelegateKey($user);
// Create capability grant in Holochain
$cap_grant = $bridge->callZome('person', 'grant_signing_key', [
'cell_id' => [$GLOBALS['prefs']['nondominium_dna_hash'], $org_agent_key],
'functions' => $permissions, // e.g., ['Transport', 'Use']
'signing_key' => $delegate_key,
'expiry' => time() + ($expiry_days * 86400)
]);
// Store delegation in Tiki
$this->storeDelegation([
'user' => $user,
'org_id' => $org_id,
'delegate_key' => $delegate_key,
'cap_secret' => $cap_grant['cap_secret'],
'permissions' => json_encode($permissions),
'expires_at' => time() + ($expiry_days * 86400)
]);
return $cap_grant;
}
/**
* Validate user's delegation and return signing credentials
*/
public function validateDelegation($user, $org_id) {
$delegation = $this->getDelegation($user, $org_id);
if (!$delegation) {
throw new Exception('No delegation found for user');
}
if ($delegation['expires_at'] < time()) {
throw new Exception('Delegation has expired');
}
return [
'org_agent_key' => $this->getOrganizationAgentKey($org_id),
'delegate_key' => $delegation['delegate_key'],
'cap_secret' => $delegation['cap_secret'],
'permissions' => json_decode($delegation['permissions'], true)
];
}
/**
* Revoke delegation (e.g., when user leaves organization)
*/
public function revokeDelegation($user, $org_id) {
$delegation = $this->getDelegation($user, $org_id);
if ($delegation) {
$bridge = new NondominiumBridge(
$GLOBALS['prefs']['nondominium_gateway_url'],
$GLOBALS['prefs']['nondominium_dna_hash']
);
// Revoke capability in Holochain
$bridge->callZome('person', 'revoke_signing_key', [
'cap_secret' => $delegation['cap_secret']
]);
// Remove from Tiki database
$this->deleteDelegation($user, $org_id);
}
}
private function getUserDelegateKey($user) {
$userlib = TikiLib::lib('user');
$existing = $userlib->get_user_preference($user, 'holochain_delegate_key');
if ($existing) {
return $existing;
}
// Generate new delegate keypair
$keypair = sodium_crypto_sign_keypair();
$public_key = sodium_crypto_sign_publickey($keypair);
// Store in user preferences (encrypted)
$userlib->set_user_preference($user, 'holochain_delegate_key', base64_encode($public_key));
$userlib->set_user_preference($user, 'holochain_delegate_keypair', base64_encode($keypair));
return base64_encode($public_key);
}
private function storeDelegation($data) {
global $tiki_p_nondominium_delegations;
TikiDb::get()->query(
"INSERT INTO `$tiki_p_nondominium_delegations`
(`user`, `org_id`, `delegate_key`, `cap_secret`, `permissions`, `expires_at`)
VALUES (?, ?, ?, ?, ?, ?)",
[
$data['user'],
$data['org_id'],
$data['delegate_key'],
$data['cap_secret'],
$data['permissions'],
$data['expires_at']
]
);
}
private function getDelegation($user, $org_id) {
global $tiki_p_nondominium_delegations;
return TikiDb::get()->getOne(
"SELECT * FROM `$tiki_p_nondominium_delegations` WHERE `user` = ? AND `org_id` = ?",
[$user, $org_id]
);
}
private function deleteDelegation($user, $org_id) {
global $tiki_p_nondominium_delegations;
TikiDb::get()->query(
"DELETE FROM `$tiki_p_nondominium_delegations` WHERE `user` = ? AND `org_id` = ?",
[$user, $org_id]
);
}
}
A.6 Organizational Delegation Workflow
<?php
/**
* Example: Tiki user Alice requests to transport a resource on behalf of Acme Corp
*/
$auth = new TikiHolochainAuth();
$bridge = new NondominiumBridge($gateway_url, $dna_hash);
// Step 1: Validate Alice's delegation
try {
$credentials = $auth->validateDelegation('alice', $org_id = 123); // Acme Corp
// Alice has permissions: ['Transport', 'Use']
if (!in_array('Transport', $credentials['permissions'])) {
throw new Exception('User not authorized for Transport');
}
} catch (Exception $e) {
die('Authorization failed: ' . $e->getMessage());
}
// Step 2: Sign the transport request with delegate key
$transport_payload = [
'resource_hash' => $resource_hash,
'from_location' => 'Warehouse A',
'to_location' => 'Client Site B',
'scheduled_date' => '2025-12-20'
];
// The zome call is signed by Alice's delegate key on behalf of Acme Corp
$result = $bridge->callZome('resource', 'initiate_transport_process', array_merge(
$transport_payload,
[
'provenance' => $credentials['org_agent_key'], // Acme Corp's identity
'performed_by' => $credentials['delegate_key'] // Alice's delegate key
]
));
// Step 3: Track internal attribution
// The organization (Acme Corp) gets the external PPR, but Tiki tracks that Alice performed it
TikiLib::lib('logs')->add_log('nondominium_transport', sprintf(
'Transport initiated by %s on behalf of organization %d',
'alice',
$org_id
));
A.7 Capability-Based Access Control (PHP)
<?php
/**
* Role-based permissions mapping for Tiki-Nondominium integration
*/
class NondominiumRoleManager {
const ROLE_PERMISSIONS = [
'Resource Coordinator' => ['view', 'request_access', 'transfer_custody'],
'Technical Manager' => ['view', 'request_access', 'use_resource'],
'Transport Specialist' => ['transfer_custody', 'view_transport_logs'],
'Warehouse Manager' => ['view', 'create_resource', 'update_inventory'],
];
/**
* Get Holochain permissions for a Tiki group/role
*/
public function getHolochainPermissions($tiki_role) {
return self::ROLE_PERMISSIONS[$tiki_role] ?? [];
}
/**
* Automatically delegate permissions when user joins a Tiki group
*/
public function onUserAddedToGroup($user, $group, $org_id) {
$auth = new TikiHolochainAuth();
$permissions = $this->getHolochainPermissions($group);
if (!empty($permissions)) {
try {
$auth->createDelegation($user, $org_id, $permissions);
TikiLib::lib('logs')->add_log('nondominium_delegation', sprintf(
'Delegation created for user %s in group %s',
$user,
$group
));
} catch (Exception $e) {
TikiLib::lib('logs')->add_log('nondominium_error', $e->getMessage());
}
}
}
/**
* Revoke delegation when user leaves group
*/
public function onUserRemovedFromGroup($user, $group, $org_id) {
$auth = new TikiHolochainAuth();
$auth->revokeDelegation($user, $org_id);
}
}
A.8 Docker Compose (Tiki-Specific)
# docker-compose.yml (Tiki Wiki deployment)
version: '3.8'
services:
tiki:
image: tiki/tiki:latest
ports:
- "80:80"
environment:
- DB_HOST=mysql
- DB_NAME=tiki
- DB_USER=tiki
- DB_PASS=tiki
volumes:
- ./tiki_nondominium_plugin:/var/www/html/lib/nondominium
depends_on:
- mysql
- bridge
holochain:
image: holochain/holochain:latest
ports:
- "8000:8000" # Admin WebSocket
- "8888:8888" # App WebSocket
volumes:
- ./nondominium.happ:/happ/nondominium.happ
- holochain_data:/data
command: holochain -c /data/conductor-config.yml
bridge:
build: ./bridge-service
ports:
- "3000:3000"
environment:
- HC_ADMIN_WS_URL=ws://holochain:8000
- HC_APP_WS_URL=ws://holochain:8888
- HC_APP_ID=nondominium
- REDIS_URL=redis://redis:6379
- TIKI_WEBHOOK_URL=http://tiki/tiki/nondominium/webhook
- WEBHOOK_SECRET=${WEBHOOK_SECRET}
depends_on:
- holochain
- redis
redis:
image: redis:7-alpine
ports:
- "6379:6379"
mysql:
image: mysql:8
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=tiki
- MYSQL_USER=tiki
- MYSQL_PASSWORD=tiki
volumes:
- mysql_data:/var/lib/mysql
volumes:
holochain_data:
mysql_data:
A.9 Implementation Roadmap (Tiki-Specific)
Phase 1: Foundation (4 weeks)
- Set up development environment (Docker Compose)
- Deploy Holochain Conductor and Nondominium hApp
- Implement Bun Bridge Service with
@holochain/client - Create REST API endpoints for Tiki integration
- Create organizational delegation system (TikiHolochainAuth.php)
- Develop Tiki plugin skeleton with NondominiumClient.php
Phase 2: Core Features (6 weeks)
- Implement resource discovery and search (via PHP Bridge)
- Build transaction workflow with delegation signing
- Develop QR code scanning with performed_by attribution
- Create webhook handlers for real-time updates (webhook_nondominium.php)
- Implement organizational PPR aggregation and display
- Integrate Tiki Tracker items with Nondominium resources (TikiNondominiumSync.php)
Phase 3: Mobile & Advanced Features (4 weeks)
- Develop mobile application with QR scanning
- Implement push notifications
- Add offline capability support
- Create advanced analytics dashboard
- Implement multi-language support
Phase 4: Testing & Optimization (3 weeks)
- Comprehensive integration testing
- Performance optimization
- Security audit and penetration testing
- User acceptance testing with pilot organizations
- Documentation and training materials
Phase 5: Production Deployment (2 weeks)
- Production environment setup
- Data migration from pilot systems
- Go-live with monitoring and support
- Post-launch optimization and bug fixes
A.10 Tiki-Specific Sequence Diagrams (Original User Story Versions)
These are the original sequence diagrams using the Tiki-specific participants (Sarah/Sensorica, Marco/FabLab) from the ERP bridge user story.
Resource Registration (Sarah/Sensorica)
sequenceDiagram
participant Sarah as Sarah (Sensorica)
participant Tiki as Tiki Wiki
participant Bridge as Bun Bridge Service
participant Conductor as Holochain Conductor
participant DNA as Nondominium DNA
Sarah->>Tiki: Login to Tiki Wiki
Tiki->>Bridge: Validate session + get agent keys
Bridge->>Conductor: authenticate_agent()
Conductor->>DNA: Return agent_pub_key
Sarah->>Tiki: Register CNC machine
Tiki->>Bridge: POST /api/resources
Bridge->>Conductor: create_economic_resource()
Conductor->>DNA: Resource entry created
DNA-->>Conductor: resource_hash
Conductor-->>Bridge: Resource created
Bridge-->>Tiki: Resource details + QR code
Tiki-->>Sarah: Resource registered successfully
Resource Discovery (Marco/FabLab)
sequenceDiagram
participant Marco as Marco (FabLab)
participant Tiki as Tiki Wiki
participant Bridge as Bun Bridge Service
participant Conductor as Holochain Conductor
participant DNA as Nondominium DNA
Marco->>Tiki: Search CNC equipment
Tiki->>Bridge: GET /api/resources/search
Bridge->>Conductor: get_all_economic_resources()
Conductor->>DNA: Query resources
DNA-->>Conductor: Available resources
Conductor-->>Bridge: Resource list + governance rules
Bridge-->>Tiki: Formatted resource data
Tiki-->>Marco: Display available CNC machines
Marco->>Tiki: Submit access request
Tiki->>Bridge: POST /api/commitments
Bridge->>Conductor: propose_commitment()
Conductor->>DNA: Create commitment
DNA-->>Conductor: commitment_hash
Conductor-->>Bridge: Commitment created
Bridge-->>Tiki: Request submitted for approval
Custody Transfer (Sarah & Marco)
sequenceDiagram
participant Sarah as Sarah (Sensorica)
participant Marco as Marco (FabLab)
participant Mobile as Mobile App
participant Bridge as Bun Bridge Service
participant Conductor as Holochain Conductor
participant DNA as Nondominium DNA
Note over Sarah,Marco: Physical transfer at location
Sarah->>Mobile: Scan QR code on CNC machine
Mobile->>Bridge: POST /api/transport/qr-scan
Bridge->>Conductor: initiate_transfer_custody()
Conductor->>DNA: Create TransferCustody event
Marco->>Mobile: Scan confirmation QR code
Mobile->>Bridge: POST /api/transport/confirm
Bridge->>Conductor: complete_transfer_custody()
Conductor->>DNA: Update custodian field
DNA->>Conductor: Generate PPR receipts
Conductor->>Bridge: Transfer complete + PPRs
Bridge-->>Mobile: Success confirmation
Appendix B: Odoo/ERPLibre Platform Example
B.1 PoC Reference Implementation
The Python PoC reference implementation is maintained in the nondominium-erp-bridge repository. It provides:
- Pydantic v2 models (
bridge/models.py): Authoritative source for field names and types mapping 1:1 to Rust zome types. Coverszome_resourceandzome_gouvernance(25+ governance types). - Typed gateway client (
bridge/gateway_client.py): HTTP client wrapping zome functions as typed Python methods (32+ methods across 2 zomes). - 101 tests: Comprehensive test suite covering model serialization, gateway client URL construction, ERP-to-Nondominium mapping, cross-org discovery, sync pipeline idempotency, governance models, and use process orchestration.
- Development scripts:
setup_conductor.sh,smoke_test.py,sync_inventory.py,demo_full_flow.py.
The PoC uses hc-http-gw (HTTP GET with base64url-encoded payloads). In production (Phase 2), this repo evolves into or is replaced by the Bun Protocol Bridge described in this specification.
B.2 Odoo Addon
The Odoo nondominium_connector addon is maintained in a separate repository: odoo-addons-nondominium. It provides:
- Docker Compose setup (Odoo 17 + PostgreSQL)
- Product sync from Odoo UI to Nondominium
- Configuration views for hc-http-gw connection settings
For the PoC, the addon calls hc-http-gw directly — this is acceptable given the PoC scope (each repo is self-contained). In production (Phase 2), the addon will be refactored to call the Bun Protocol Bridge REST API instead.
B.3 PoC vs Production Approach
| Aspect | PoC (current) | Production (Phase 2) |
|---|---|---|
| Protocol Bridge | hc-http-gw (HTTP GET) | Bun with @holochain/client (WebSocket) |
| Python repo role | Reference impl, Pydantic models, test suite | Evolves into or replaced by Bun bridge |
| Odoo addon | Calls hc-http-gw directly | Calls Bun bridge REST API |
| Sync direction | ERP -> Nondominium | Bidirectional |
| Real-time | Polling | Signals + Webhooks |
References
Holochain Integration
- Holochain Client JS
- Holochain Client JS API Docs
- Holochain HTTP Gateway (PoC)
- Bun Documentation
- Hono Documentation
Nondominium & ValueFlows
ERP Bridge Reference Implementation
- nondominium-erp-bridge — Python PoC, Pydantic models, 101 tests
- odoo-addons-nondominium — Odoo addon
- ERP Bridge Technical Specifications
Platform-Specific Resources
This protocol bridge specification enables any Web2 platform to become a gateway for Holochain-based resource sharing, maintaining platform familiarity while introducing trust and transparency capabilities through the Nondominium protocol. The Bun Bridge Service (using Hono for routing and @holochain/client for Holochain connectivity) provides full-featured, production-ready integration with real-time signals, proper zome call signing, and organizational delegation patterns.
Nondominium API Reference
Generated: 2025-12-17 · Resource / governance input structs re-synced against source 2026-08-29 (post-#132) Version: 3.1 (Updated with Current Implementation) Scope: Complete function documentation for all zomes based on actual codebase
🎯 API Overview
Nondominium implements a comprehensive REST-like API through Holochain zome functions, organized into three main zomes with distinct responsibilities. All functions follow consistent patterns for input validation, error handling, and DHT integration.
API Conventions
- Input Types: Structured input parameters with validation
- Return Types:
ExternResult<T>with comprehensive error handling - Authentication: Agent identity automatically verified via
agent_info() - Authorization: Role-based access control enforced at function level
- Auditing: All operations create immutable audit trails
🔐 zome_person - Identity & Access Management
Person Profile Management
create_person(input: PersonInput) -> ExternResult<Record>
Purpose: Create a new agent profile with discovery anchors Authorization: Any agent can create their own profile Input:
#![allow(unused)] fn main() { pub struct PersonInput { pub name: String, pub avatar_url: Option<String>, pub bio: Option<String>, } }
Returns: Record containing the created Person entry
Side Effects:
- Creates
Personentry with agent public key - Creates discovery anchor links for agent findability
- Links agent pubkey to person entry Error Cases:
PersonError::PersonExists- Agent already has a profile- Network/DHT errors during entry creation
get_latest_person_record(original_action_hash: ActionHash) -> ExternResult<Option<Record>>
Purpose: Retrieve the most recent version of a person record
Authorization: Public access (person data is public)
Input: ActionHash of the original person entry
Returns: Latest Record entry or None if not found
Error Cases:
PersonError::PersonNotFound- No person entry found- Network/DHT errors during retrieval
get_latest_person(original_action_hash: ActionHash) -> ExternResult<Person>
Purpose: Retrieve the most recent version of a person entry
Authorization: Public access (person data is public)
Input: ActionHash of the original person entry
Returns: Latest Person entry with all current fields
Error Cases:
PersonError::PersonNotFound- No person entry foundPersonError::SerializationError- Record parsing failed
update_person(input: UpdatePersonInput) -> ExternResult<Record>
Purpose: Update an existing person profile Authorization: Only profile owner can update Input:
#![allow(unused)] fn main() { pub struct UpdatePersonInput { pub original_action_hash: ActionHash, pub name: Option<String>, pub avatar: Option<String>, pub bio: Option<String>, pub location: Option<String>, pub tags: Option<Vec<String>>, } }
Returns: Updated Record with new version
Side Effects:
- Creates new entry version with update links
- Updates discovery anchors if needed
- Maintains audit trail of changes Error Cases:
PersonError::Unauthorized- Not profile ownerPersonError::PersonNotFound- Original entry not found
get_all_persons(()) -> ExternResult<GetAllPersonsOutput>
Purpose: Discover all agents in the network Authorization: Public access for discovery Returns:
#![allow(unused)] fn main() { pub struct GetAllPersonsOutput { pub persons: Vec<PersonProfile>, } }
Performance: Uses anchor-based traversal for efficient discovery
get_person_profile(agent_pubkey: AgentPubKey) -> ExternResult<PersonProfileOutput>
Purpose: Get comprehensive profile information for a specific agent Authorization: Public access Returns:
#![allow(unused)] fn main() { pub struct PersonProfileOutput { pub person: Option<Person>, pub role: Option<PersonRole>, pub capability_level: String, } }
get_my_person_profile(()) -> ExternResult<PersonProfileOutput>
Purpose: Get current agent's complete profile Authorization: Current agent only Returns: Full profile including private information Performance: Optimized for current agent access patterns
get_agent_person_links(agent_pubkey: AgentPubKey) -> ExternResult<Vec<Link>>
Purpose: Get all links between an agent and person entries Authorization: Public access Returns: Vector of links showing agent-person relationships Use Case: Multi-device support and relationship management
get_agent_person(agent_pubkey: AgentPubKey) -> ExternResult<Option<ActionHash>>
Purpose: Get the primary person associated with an agent Authorization: Public access Returns: ActionHash of person entry if association exists Use Case: Agent-to-person lookup for profile access
get_person_agents(person_hash: ActionHash) -> ExternResult<Vec<AgentPubKey>>
Purpose: Get all agents associated with a person Authorization: Public access Returns: Vector of agent public keys Use Case: Multi-device support and agent management
add_agent_to_person(input: (AgentPubKey, ActionHash)) -> ExternResult<bool>
Purpose: Associate an additional agent with a person (multi-device support) Authorization: Person owner only Input: Tuple of (agent_pubkey, person_hash) Returns: Success status Use Case: Adding new devices to existing person profile
remove_agent_from_person(input: (AgentPubKey, ActionHash)) -> ExternResult<bool>
Purpose: Remove agent association from a person Authorization: Person owner only Input: Tuple of (agent_pubkey, person_hash) Returns: Success status Use Case: Removing lost or deactivated devices
is_agent_associated_with_person(input: (AgentPubKey, ActionHash)) -> ExternResult<bool>
Purpose: Check if agent is associated with person Authorization: Public access Input: Tuple of (agent_pubkey, person_hash) Returns: Boolean indicating association status Use Case: Authorization checks and validation
get_hrea_agents(hashes: Vec<ActionHash>) -> ExternResult<Vec<Option<Record>>>
Purpose: Retrieve ReaAgent records from the hREA DNA by action hashes
Authorization: Public access
Input: Vector of ActionHash values (typically from Person.hrea_agent_hash)
Returns: Vector of optional Records (None if a hash is not found in hREA)
Use Case: Resolve agent names and avatars from hREA without duplicating data in the Nondominium DNA. Part of the Phase 1 hREA bridge — see hREA/integration-strategy.md Pattern 5.
promote_agent_to_accountable(input: PromoteAgentInput) -> ExternResult<String>
Purpose: Promote an agent to accountable status with validation Authorization: Governance role required Input:
#![allow(unused)] fn main() { pub struct PromoteAgentInput { pub agent: AgentPubKey, pub first_resource_hash: ActionHash, } }
Returns: String indicating new capability level Use Case: Agent promotion workflow
Private Data Management
store_private_person_data(input: PrivatePersonDataInput) -> ExternResult<Record>
Purpose: Store private personal data with encryption Authorization: Current agent only Input:
#![allow(unused)] fn main() { pub struct PrivatePersonDataInput { pub legal_name: String, pub email: String, pub phone: Option<String>, pub address: Option<String>, pub emergency_contact: Option<String>, pub time_zone: Option<String>, pub location: Option<String>, } }
Returns: Encrypted Record with private data
Security: Data encrypted before storage in DHT
update_private_person_data(input: UpdatePrivatePersonDataInput) -> ExternResult<Record>
Purpose: Update existing private personal data
Authorization: Current agent only
Input: Similar to PrivatePersonDataInput with optional fields for updates
Returns: Updated encrypted Record
Security: Data encrypted before storage in DHT
get_my_private_person_data(()) -> ExternResult<Option<PrivatePersonData>>
Purpose: Retrieve current agent's private data Authorization: Current agent only Returns: Decrypted private data if available Security: Automatic decryption for authorized access
`get_agent_private_data(
agent_pubkey: AgentPubKey,
required_fields: Vec<String>,
) -> ExternResult<Option
Device Management
register_device_for_person(input: RegisterDeviceInput) -> ExternResult<Record>
Purpose: Register a new device for a person (multi-device support) Authorization: Device owner or person representative Input:
#![allow(unused)] fn main() { pub struct RegisterDeviceInput { pub device_id: String, pub device_name: String, pub device_type: String, // "mobile", "desktop", "tablet", "web", "server" pub person_hash: ActionHash, } }
Returns: Created Device entry record
Side Effects: Creates device-person relationship links
get_devices_for_person(person_hash: ActionHash) -> ExternResult<Vec<DeviceInfo>>
Purpose: Get all devices registered for a specific person Authorization: Person owner or authorized agent Returns: Vector of device information structures Use Case: Multi-device management and security
get_device_info(device_id: String) -> ExternResult<Option<DeviceInfo>>
Purpose: Get detailed information about a specific device Authorization: Device owner or authorized agent Returns: Device information if device exists Use Case: Device verification and management
update_device_activity(device_id: String) -> ExternResult<bool>
Purpose: Update the last active timestamp for a device Authorization: Any authenticated request for the device Returns: Success status Use Case: Device activity tracking and security monitoring
deactivate_device(device_id: String) -> ExternResult<bool>
Purpose: Deactivate a device (revoke access) Authorization: Device owner or person representative Returns: Success status Security: Prevents further access from deactivated device
get_my_devices(()) -> ExternResult<Vec<DeviceInfo>>
Purpose: Get all devices for the current agent Authorization: Current agent only Returns: Vector of device information for current agent Use Case: Device management interface for users
Capability-Based Sharing
grant_private_data_access(input: GrantPrivateDataAccessInput) -> ExternResult<GrantPrivateDataAccessOutput>
Purpose: Grant another agent access to specific private data fields Authorization: Data owner only Input:
#![allow(unused)] fn main() { pub struct GrantPrivateDataAccessInput { pub agent_to_grant: AgentPubKey, pub fields_allowed: Vec<String>, pub context: String, pub expires_in_days: Option<u32>, } }
Returns:
#![allow(unused)] fn main() { pub struct GrantPrivateDataAccessOutput { pub grant_hash: ActionHash, pub cap_secret: CapSecret, } }
Security: Creates granular, field-level access control
create_private_data_cap_claim(input: CreatePrivateDataCapClaimInput) -> ExternResult<Record>
Purpose: Create capability claim for private data access (for grantee) Authorization: Any agent can create claims Input:
#![allow(unused)] fn main() { pub struct CreatePrivateDataCapClaimInput { pub grantor: AgentPubKey, pub fields: Vec<String>, pub purpose: String, pub expires_at: Option<Timestamp>, } }
Returns: Capability claim record Security: Creates cryptographically secure capability claim
get_private_data_with_capability(input: GetPrivateDataWithCapabilityInput) -> ExternResult<FilteredPrivateData>
Purpose: Access private data using capability claim Authorization: Valid capability claim required Input:
#![allow(unused)] fn main() { pub struct GetPrivateDataWithCapabilityInput { pub target_agent: AgentPubKey, pub cap_claim: CapClaim, pub cap_secret: CapSecret, pub requested_fields: Vec<String>, } }
Returns: Filtered private data based on authorized fields Security: Cryptographic verification of capability claim
get_my_capability_grants(()) -> ExternResult<Vec<PrivateDataCapabilityMetadata>>
Purpose: List all active capability grants issued by current agent Authorization: Current agent only Returns: List of capability grants with metadata Utility: For managing and revoking access permissions
create_transferable_private_data_access(input: CreateTransferableAccessInput) -> ExternResult<Record>
Purpose: Create transferable access capability for delegation Authorization: Data owner only Input:
#![allow(unused)] fn main() { pub struct CreateTransferableAccessInput { pub agent_pubkey: AgentPubKey, pub fields: Vec<String>, pub context: String, pub expires_at: Option<Timestamp>, } }
Security: Enables controlled delegation of access rights Use Case: Service providers needing temporary access to client data
revoke_private_data_access(grant_hash: ActionHash) -> ExternResult<()>
Purpose: Revoke previously granted private data access Authorization: Grant owner only Input: ActionHash of the capability grant to revoke Security: Immediately terminates access permissions Use Case: Security incident response and access management
validate_capability_grant(grant_hash: ActionHash) -> ExternResult<bool>
Purpose: Validate if a capability grant is still active and valid Authorization: Public access Input: ActionHash of the capability grant to validate Returns: Boolean indicating grant validity Use Case: Pre-access validation and security checks
grant_role_based_private_data_access(input: RoleBasedAccessInput) -> ExternResult<Record>
Purpose: Grant private data access based on role assignment Authorization: System or governance role required Input:
#![allow(unused)] fn main() { pub struct RoleBasedAccessInput { pub role_name: String, pub fields: Vec<String>, pub context: String, pub expires_at: Option<Timestamp>, } }
Security: Role-based access control for private data Use Case: Organizational data access policies
validate_agent_private_data(input: ValidationDataRequest) -> ExternResult<ValidationResult>
Purpose: Validate an agent's request for private data access Authorization: Validation service or authorized validator Input:
#![allow(unused)] fn main() { pub struct ValidationDataRequest { pub requesting_agent: AgentPubKey, pub target_agent: AgentPubKey, pub requested_fields: Vec<String>, pub context: String, } }
Returns:
#![allow(unused)] fn main() { pub struct ValidationResult { pub is_valid: bool, pub granted_fields: Vec<String>, pub reason: Option<String>, } }
Security: Structured validation with reasoning
validate_agent_private_data_with_grant(input: ValidationWithGrantRequest) -> ExternResult<ValidationResult>
Purpose: Validate private data access with specific capability grant Authorization: Validation service or authorized validator Input: Validation request with specific grant information Returns: Validation result with grant-specific reasoning Security: Grant-specific validation for audit trails
Role Management
assign_person_role(input: PersonRoleInput) -> ExternResult<Record>
Purpose: Assign a role to an agent Authorization: System or governance role required Input:
#![allow(unused)] fn main() { pub struct PersonRoleInput { pub agent_pubkey: AgentPubKey, pub role_name: String, pub description: Option<String>, } }
Returns: Role assignment record Security: Role assignments create capability implications
get_latest_person_role_record(original_action_hash: ActionHash) -> ExternResult<Option<Record>>
Purpose: Retrieve the most recent version of a person role record Authorization: Public access for role verification Returns: Latest role record or None if not found Use Case: Role history and validation
get_latest_person_role(original_action_hash: ActionHash) -> ExternResult<PersonRole>
Purpose: Retrieve the most recent version of a person role
Authorization: Public access for role verification
Returns: Latest PersonRole entry
Error Cases: Role not found, record parsing failed
update_person_role(input: UpdatePersonRoleInput) -> ExternResult<Record>
Purpose: Update an existing person role Authorization: System or governance role required Input:
#![allow(unused)] fn main() { pub struct UpdatePersonRoleInput { pub original_action_hash: ActionHash, pub previous_action_hash: ActionHash, pub role_name: Option<String>, pub description: Option<String>, } }
Returns: Updated role assignment record Security: Maintains audit trail of role changes
get_person_roles(agent_pubkey: AgentPubKey) -> ExternResult<GetPersonRolesOutput>
Purpose: Retrieve all roles assigned to an agent Authorization: Public access for role verification Returns:
#![allow(unused)] fn main() { pub struct GetPersonRolesOutput { pub roles: Vec<PersonRole>, } }
get_my_person_roles(()) -> ExternResult<GetPersonRolesOutput>
Purpose: Get current agent's roles with validation details Authorization: Current agent only Returns: Complete role information including validation metadata
get_person_capability_level(agent_pubkey: AgentPubKey) -> ExternResult<String>
Purpose: Determine agent's capability level based on roles Authorization: Public access for capability verification Returns: String capability level ("Simple Agent", "Accountable Agent", "Primary Accountable Agent", etc.) Logic:
- "Simple Agent" - Basic agent capabilities
- "Accountable Agent" - Resource access and management
- "Primary Accountable Agent" - Process initiation and coordination
- Specialized roles: "Transport Agent", "Repair Agent", "Storage Agent"
has_person_role_capability(input: (AgentPubKey, String)) -> ExternResult<bool>
Purpose: Check if agent has specific role capability Authorization: Public access for role verification Input: Tuple of (agent_pubkey, role_name) Returns: Boolean indicating role presence
Role Promotion Workflow
promote_agent_with_validation(input: PromoteAgentInput) -> ExternResult<Record>
Purpose: Promote an agent with validation and PPR generation Authorization: Governance role required Input:
#![allow(unused)] fn main() { pub struct PromoteAgentInput { pub agent: AgentPubKey, pub first_resource_hash: ActionHash, } }
Returns: Role promotion record with validation metadata Side Effects: Generates PPRs for promotion validation Security: Comprehensive validation with reputation assessment
request_role_promotion(input: RolePromotionRequest) -> ExternResult<ActionHash>
Purpose: Request role promotion for current agent Authorization: Any agent can request promotion Input:
#![allow(unused)] fn main() { pub struct RolePromotionRequest { pub desired_role: String, pub evidence: Option<String>, pub context: String, } }
Returns: ActionHash of the promotion request Use Case: Self-initiated promotion requests
approve_role_promotion(input: ApprovePromotionInput) -> ExternResult<Record>
Purpose: Approve a role promotion request Authorization: Governance role required Input:
#![allow(unused)] fn main() { pub struct ApprovePromotionInput { pub request_hash: ActionHash, pub validator_notes: Option<String>, pub assigned_role: String, } }
Returns: Approved role promotion record Side Effects: Creates PPRs for successful promotion Security: Multi-validator approval process
🏗️ zome_resource - Resource Lifecycle Management
NDO (NondominiumIdentity) Layer 0 Management
create_ndo(input: NdoInput) -> ExternResult<NdoOutput>
Purpose: Create a new Nondominium Identity (Layer 0 anchor) for a resource Authorization: Any agent Input:
#![allow(unused)] fn main() { pub struct NdoInput { pub name: String, pub property_regime: PropertyRegime, pub resource_nature: ResourceNature, pub lifecycle_stage: LifecycleStage, // any non-terminal stage pub description: Option<String>, } }
Returns: NdoOutput { action_hash, entry } — action_hash is the permanent Layer 0 identity
PropertyRegime: seven canonical variants — Private, Commons, Collective, Pool, CommonPool, Public, Nondominium
Side Effects: Creates AllNdos, AgentToNdo, NdoByLifecycleStage, NdoByNature, and NdoByPropertyRegime links
Error Cases: Empty name, terminal initial stage (Hibernating, Deprecated, EndOfLife)
get_ndo(original_action_hash: ActionHash) -> ExternResult<Option<NondominiumIdentity>>
Purpose: Retrieve the latest version of an NDO by its stable Layer 0 identity hash
Authorization: Public
Returns: Latest NondominiumIdentity entry or None if not found on DHT
update_lifecycle_stage(input: UpdateLifecycleStageInput) -> ExternResult<ActionHash>
Purpose: Transition an NDO's lifecycle stage through the state machine Authorization: Initiator only Input:
#![allow(unused)] fn main() { pub struct UpdateLifecycleStageInput { pub original_action_hash: ActionHash, pub new_stage: LifecycleStage, pub successor_ndo_hash: Option<ActionHash>, // required when new_stage == Deprecated pub transition_event_hash: Option<ActionHash>, // optional EconomicEvent reference } }
Returns: New ActionHash (original remains the stable Layer 0 identity)
Side Effects: Moves NdoByLifecycleStage link to new stage anchor; conditionally creates NdoToSuccessor and NdoToTransitionEvent links
Error Cases: Unauthorized, invalid state machine transition, missing successor_ndo_hash when entering Deprecated
get_all_ndos(()) -> ExternResult<GetAllNdosOutput>
Purpose: Discover all NDOs in the network
Authorization: Public
Returns: GetAllNdosOutput { ndos: Vec<NdoOutput> } — resolved to latest versions; unavailable entries silently skipped
get_my_ndos(()) -> ExternResult<GetAllNdosOutput>
Purpose: Retrieve all NDOs created by the calling agent
Authorization: Any agent (scoped to caller)
Returns: GetAllNdosOutput { ndos: Vec<NdoOutput> } — resolved to latest versions; unavailable entries silently skipped
get_ndos_by_lifecycle_stage(stage: LifecycleStage) -> ExternResult<GetAllNdosOutput>
Purpose: Query NDOs currently at a specific lifecycle stage
Authorization: Public
Returns: GetAllNdosOutput { ndos: Vec<NdoOutput> } — uses NdoByLifecycleStage anchor; silently skips unavailable entries
Requirements: REQ-NDO-L0-05, REQ-NDO-L0-07
get_ndos_by_nature(nature: ResourceNature) -> ExternResult<GetAllNdosOutput>
Purpose: Query NDOs of a specific resource nature
Authorization: Public
Returns: GetAllNdosOutput { ndos: Vec<NdoOutput> } — uses NdoByNature anchor; silently skips unavailable entries
Requirements: REQ-NDO-L0-05, REQ-NDO-L0-07
get_ndos_by_property_regime(regime: PropertyRegime) -> ExternResult<GetAllNdosOutput>
Purpose: Query NDOs under a specific property regime
Authorization: Public
Returns: GetAllNdosOutput { ndos: Vec<NdoOutput> } — uses NdoByPropertyRegime anchor; silently skips unavailable entries
Requirements: REQ-NDO-L0-05, REQ-NDO-L0-07
Resource Specification Management
create_resource_specification(input: ResourceSpecificationInput) -> ExternResult<CreateResourceSpecificationOutput>
Purpose: Activate NDO Layer 1 — define the resource's form and its typed governance rules
Authorization: Any agent; the target NDO must be at lifecycle stage Specification through Active
Input:
#![allow(unused)] fn main() { pub struct ResourceSpecificationInput { pub name: String, pub description: String, pub category: String, pub image_url: Option<String>, pub tags: Vec<String>, pub scope: ResourceScope, // Project | Network | Public pub ndo_identity_hash: ActionHash, // Layer 0 NDO this spec activates pub governance_rules: Vec<NestedGovernanceRuleInput>, } pub struct NestedGovernanceRuleInput { pub rule_data: RuleData, pub enforced_by: Option<String>, } }
Returns: CreateResourceSpecificationOutput { spec_hash, spec, governance_rule_hashes }
Side Effects:
- Creates the specification entry with discovery anchors (
Projectscope skips the global anchor) - Creates the
NdoToSpecificationlink — this is Layer 1 activation - Creates each nested
GovernanceRuleand links it viaSpecificationToGovernanceRule, so rules are never orphaned - Creates category and tag-based discovery links
get_latest_resource_specification(original_action_hash: ActionHash) -> ExternResult<ResourceSpecification>
Purpose: Retrieve most recent resource specification version
Authorization: Public access
Returns: Latest ResourceSpecification with all properties
Error Cases: Specification not found, record corruption
update_resource_specification(input: UpdateResourceSpecificationInput) -> ExternResult<Record>
Purpose: Update resource specification with version tracking Authorization: Specification owner only Input:
#![allow(unused)] fn main() { pub struct UpdateResourceSpecificationInput { pub original_action_hash: ActionHash, pub name: Option<String>, pub description: Option<String>, pub resource_class: Option<String>, pub default_unit: Option<String>, pub custom_properties: Option<HashMap<String, PropertyValue>>, pub behavior: Option<String>, pub conforming: Option<bool>, pub image: Option<String>, pub category: Option<String>, pub tags: Option<Vec<String>>, pub governance_rules: Option<Vec<ActionHash>>, } }
Returns: Updated specification with version tracking
get_all_resource_specifications(()) -> ExternResult<GetAllResourceSpecificationsOutput>
Purpose: Discover all resource specifications in network
Authorization: Public access
Returns: GetAllResourceSpecificationsOutput { specifications, action_hashes } — parallel vectors of same length and order. action_hashes[i] is the original creation ActionHash for specifications[i], suitable for use as a stable route identifier (e.g. /ndo/[id]).
get_resource_specification_profile(action_hash: ActionHash) -> ExternResult<ResourceSpecificationProfile>
Purpose: Get comprehensive specification profile with metadata Authorization: Public access Returns: Specification with creation metadata and governance rules
get_resource_specifications_by_category(category: String) -> ExternResult<Vec<Record>>
Purpose: Find specifications by category classification Authorization: Public access Performance: Category-based anchor traversal for efficiency
get_resource_specifications_by_tag(tag: String) -> ExternResult<Vec<Record>>
Purpose: Find specifications with specific tags Authorization: Public access Utility: Tag-based resource discovery
get_my_resource_specifications(()) -> ExternResult<Vec<Link>>
Purpose: List specifications created by current agent Authorization: Current agent only Returns: Links to created specifications
Economic Resource Management
create_economic_resource(input: EconomicResourceInput) -> ExternResult<Record>
Purpose: Create resource instance from specification Authorization: Any agent can create resources Input:
#![allow(unused)] fn main() { pub struct EconomicResourceInput { pub resource_specification: ActionHash, pub name: String, pub accounting_quantity: Option<f64>, pub unit_of_effort: Option<String>, pub current_quantity: f64, pub primary_accountable: AgentPubKey, pub classified_as: Vec<String>, pub unit_of_resource: String, pub stage: Option<String>, pub state: Option<String>, pub location: Option<String>, pub note: Option<String>, pub image: Option<String>, } }
Returns: Created EconomicResource entry
Side Effects:
- Creates resource with lifecycle tracking
- Links to specification for type validation
- Establishes custody relationships
- Creates economic event for resource creation
get_latest_economic_resource(original_action_hash: ActionHash) -> ExternResult<EconomicResource>
Purpose: Retrieve most recent resource state
Authorization: Public access for resource discovery
Returns: Current EconomicResource with state and metadata
update_economic_resource(input: UpdateEconomicResourceInput) -> ExternResult<Record>
Purpose: Update resource properties and state Authorization: Primary accountable agent or authorized role Input:
#![allow(unused)] fn main() { pub struct UpdateEconomicResourceInput { pub original_action_hash: ActionHash, pub name: Option<String>, pub accounting_quantity: Option<f64>, pub unit_of_effort: Option<String>, pub current_quantity: Option<f64>, pub primary_accountable: Option<AgentPubKey>, pub classified_as: Option<Vec<String>>, pub unit_of_resource: Option<String>, pub stage: Option<String>, pub state: Option<String>, pub location: Option<String>, pub note: Option<String>, pub image: Option<String>, } }
Returns: Updated resource with audit trail Security: Role-based authorization for resource updates
get_all_economic_resources(()) -> ExternResult<GetAllEconomicResourcesOutput>
Purpose: Discover all economic resources in network Authorization: Public access Performance: Anchor-based discovery with pagination support
get_economic_resource_profile(action_hash: ActionHash) -> ExternResult<EconomicResourceProfile>
Purpose: Get comprehensive resource profile with history Authorization: Public access Returns: Resource with specification details and lifecycle events
get_resources_by_specification(spec_hash: ActionHash) -> ExternResult<Vec<Record>>
Purpose: Find all resources of a specific type Authorization: Public access Utility: Resource browsing and discovery
get_my_economic_resources(()) -> ExternResult<Vec<Link>>
Purpose: List resources where current agent has custody or ownership Authorization: Current agent only Returns: Links to resources with relationship metadata
get_agent_economic_resources(agent_pubkey: AgentPubKey) -> ExternResult<Vec<Link>>
Purpose: List resources associated with specific agent Authorization: Public access Returns: Resources where agent has accountability or custody
update_operational_state(input: UpdateOperationalStateInput) -> ExternResult<Record>
Purpose: Update EconomicResource.operational_state (REQ-NDO-OS-01)
Authorization: Current agent (interim; governance-zome ownership deferred per REQ-NDO-OS-02)
Input:
#![allow(unused)] fn main() { pub struct UpdateOperationalStateInput { pub resource_hash: ActionHash, pub new_operational_state: OperationalState, } }
Returns: Updated EconomicResource record; moves ResourcesByOperationalState anchor link
get_resources_by_operational_state(state: OperationalState) -> ExternResult<Vec<Record>>
Purpose: Faceted discovery of economic resources by operational state (REQ-NDO-OS-06)
Authorization: Public read
Returns: Records linked from ndo.opstate.{state} anchor
Governance Rules Management
create_governance_rule(input: GovernanceRuleInput) -> ExternResult<Record>
Purpose: Create a typed governance rule bound to an NDO's classification
Authorization: Any agent; check_rule_data_permitted rejects rules the NDO's PropertyRegime / ResourceNature forbid
Input:
#![allow(unused)] fn main() { pub struct GovernanceRuleInput { pub rule_data: RuleData, // AccessRequirement | UsageLimit | TransferCondition | MaintenanceSchedule pub enforced_by: Option<String>, pub ndo_identity_hash: ActionHash, pub property_regime: PropertyRegime, pub resource_nature: ResourceNature, pub rivalry_override: Option<Rivalry>, /// Set this to link the rule to a spec. Omitting it creates an orphan rule /// that `get_resource_specification_with_rules` cannot surface. pub specification_hash: Option<ActionHash>, } }
Returns: Created GovernanceRule entry
Purpose: Embed compliance rules directly in resource definitions
get_latest_governance_rule(original_action_hash: ActionHash) -> ExternResult<GovernanceRule>
Purpose: Retrieve governance rule details Authorization: Public access for compliance verification Returns: Complete governance rule with validation logic
update_governance_rule(input: UpdateGovernanceRuleInput) -> ExternResult<Record>
Purpose: Update governance rule with version tracking Authorization: Governance role required Returns: Updated rule with audit trail
get_all_governance_rules(()) -> ExternResult<GetAllGovernanceRulesOutput>
Purpose: Discover all governance rules Authorization: Public access Returns: Array of all active governance rules
get_governance_rules_by_type(rule_type: String) -> ExternResult<Vec<Record>>
Purpose: Find governance rules by type classification Authorization: Public access Utility: Rule discovery and compliance checking
🏛️ zome_gouvernance - Governance & Reputation
Commitment Management
get_all_commitments(()) -> ExternResult<Vec<Commitment>>
Purpose: Retrieve all commitments in the network Authorization: Public access for commitment discovery Returns: Array of all commitment entries Use Case: Finding available commitment opportunities
get_commitments_for_agent(agent: AgentPubKey) -> ExternResult<Vec<Commitment>>
Purpose: Find commitments involving specific agent Authorization: Public access Returns: Commitments where agent is provider or receiver Utility: Agent reputation and capability assessment
Claim Management
get_all_claims(()) -> ExternResult<Vec<Claim>>
Purpose: Retrieve all claims in the network Authorization: Public access Returns: Array of all claim entries Purpose: Claim discovery and verification
get_claims_for_commitment(commitment_hash: ActionHash) -> ExternResult<Vec<Claim>>
Purpose: Find claims related to specific commitment Authorization: Public access Returns: Claims providing evidence for commitment fulfillment Use Case: Commitment validation and reputation assessment
Economic Event Management
get_all_economic_events(()) -> ExternResult<Vec<EconomicEvent>>
Purpose: Retrieve all economic events for transparency Authorization: Public access Returns: Array of all economic events Purpose: Complete economic activity audit trail
get_events_for_resource(resource_hash: ActionHash) -> ExternResult<Vec<EconomicEvent>>
Purpose: Get economic history of specific resource Authorization: Public access Returns: Events affecting resource state and ownership Utility: Resource lifecycle tracking and provenance
get_events_for_agent(agent: AgentPubKey) -> ExternResult<Vec<EconomicEvent>>
Purpose: Get economic activity for specific agent Authorization: Public access Returns: Events where agent participated as provider or receiver Use Case: Agent economic reputation and activity assessment
PPR (Private Participation Receipt) System
get_my_participation_claims(input: GetMyParticipationClaimsInput) -> ExternResult<ParticipationClaimBundle>
Purpose: Retrieve current agent's PPR claims for reputation assessment Authorization: Current agent only Input:
#![allow(unused)] fn main() { pub struct GetMyParticipationClaimsInput { pub categories: Option<Vec<ParticipationClaimType>>, pub time_range: Option<TimeRange>, pub include_expired: bool, } }
Returns:
#![allow(unused)] fn main() { pub struct ParticipationClaimBundle { pub claims: Vec<ParticipationClaim>, pub summary: ReputationSummary, pub verification_contexts: Vec<VerificationContext>, } }
Security: Cryptographic verification of all PPR claims
create_service_commitment_pprs(commitment_hash: ActionHash) -> ExternResult<Vec<Record>>
Purpose: Automatically issue PPRs when service commitments are created Authorization: System function based on commitment creation Returns: Created PPR entries for commitment initiation Logic: Issues PPRs to both provider and potential receivers
create_service_fulfillment_pprs(commitment_hash: ActionHash) -> ExternResult<Vec<Record>>
Purpose: Issue PPRs upon successful commitment fulfillment Authorization: System function triggered by fulfillment validation Returns: PPR entries documenting successful service delivery Categories: Service-specific PPR categories based on commitment type
Validation System
create_validation_receipt(input: CreateValidationReceiptInput) -> ExternResult<Record>
Purpose: Create validation receipt for resource, service, or commitment Authorization: Validator role required Input:
#![allow(unused)] fn main() { pub struct CreateValidationReceiptInput { pub validated_item: ActionHash, pub validation_type: String, pub validator: AgentPubKey, pub assessment: String, pub confidence: f64, pub evidence: Option<String>, pub metrics: Option<HashMap<String, f64>>, } }
Returns: Validation receipt with cryptographic signature Purpose: Create evidence for PPR issuance and reputation building
get_validation_history(item_hash: ActionHash) -> ExternResult<Vec<ValidationReceipt>>
Purpose: Retrieve complete validation history for any item Authorization: Public access Returns: All validation receipts for the specified item Use Case: Multi-reviewer validation and quality assessment
get_all_validation_receipts(()) -> ExternResult<Vec<ValidationReceipt>>
Purpose: Discover all validation receipts in network Authorization: Public access Returns: Array of all validation receipts Utility: Validator discovery and reputation assessment
create_resource_validation(input: CreateResourceValidationInput) -> ExternResult<Record>
Purpose: Create comprehensive resource validation with multi-reviewer process Authorization: Resource owner or authorized validator Input:
#![allow(unused)] fn main() { pub struct CreateResourceValidationInput { pub resource_hash: ActionHash, pub validation_type: String, pub required_reviewers: u32, pub validation_criteria: String, pub deadline: Option<u64>, pub incentive: Option<f64>, } }
Returns: Resource validation workflow setup Process: Initiates multi-reviewer validation workflow
Private Data Validation
get_validation_requirements(process_type: String) -> ExternResult<Vec<String>>
Purpose: Get required private data fields for economic process validation Authorization: Public access Returns: List of required private data fields Use Case: Process compliance and data access planning
create_validation_with_private_data(input: CreateValidationWithPrivateDataInput) -> ExternResult<Record>
Purpose: Create validation that requires access to private data Authorization: Authorized validator with capability grants Input:
#![allow(unused)] fn main() { pub struct CreateValidationWithPrivateDataInput { pub validated_item: ActionHash, pub validation_type: String, pub required_private_data: Vec<String>, pub validator: AgentPubKey, pub assessment: String, pub confidence: f64, pub data_access_grants: Vec<CapClaim>, } }
Returns: Validation with private data access verification Security: Requires valid capability grants for all accessed private data
NDO Federation Extensions
Added in PR #103. Implements REQ-NDO-EXT-01–16 from post-mvp/lobby-dna.md.
create_ndo_hard_link(input: CreateNdoHardLinkInput) -> ExternResult<ActionHash>
Purpose: Create a permanent, immutable OVN-licensed structural link between two NDOs Authorization: Any agent (immutability enforced at integrity layer) Input:
#![allow(unused)] fn main() { pub struct CreateNdoHardLinkInput { pub from_ndo_identity_hash: ActionHash, pub to_ndo_dna_hash: DnaHash, pub to_ndo_identity_hash: ActionHash, pub link_type: NdoLinkType, // Component | DerivedFrom | Supersedes pub fulfillment_hash: ActionHash, } }
Returns: ActionHash of the new NdoHardLink entry
Use Case: Recording that one NDO is a component of, fork of, or supersedes another NDO
get_ndo_hard_links(ndo_identity_hash: ActionHash) -> ExternResult<Vec<NdoHardLinkRecord>>
Purpose: Retrieve all hard links originating from an NDO
Authorization: Any agent (public DHT)
Returns: Vec<NdoHardLinkRecord> via NdoToHardLinks anchor
get_ndo_hard_links_by_type(input: GetNdoHardLinksByTypeInput) -> ExternResult<Vec<NdoHardLinkRecord>>
Purpose: Retrieve hard links filtered by NdoLinkType
Authorization: Any agent (public DHT)
Returns: Filtered Vec<NdoHardLinkRecord>
validate_contribution(input: ValidateContributionInput) -> ExternResult<ActionHash>
Purpose: Record and peer-validate a work contribution (Work | Modify | Cite) on an NDO
Authorization: Any agent; calling agent becomes first validator
Input:
#![allow(unused)] fn main() { pub struct ValidateContributionInput { pub provider: AgentPubKey, pub action: VfAction, // Work | Modify | Cite only pub ndo_identity_hash: ActionHash, pub note: String, pub effort_quantity: Option<f64>, pub has_point_in_time: Timestamp, // ... optional work log / process / fulfillment references } }
Returns: ActionHash of the Contribution entry
Use Case: Recording that an agent performed design, development, or citation work on an NDO
get_ndo_contributions(ndo_identity_hash: ActionHash) -> ExternResult<Vec<ContributionRecord>>
Purpose: Retrieve all contributions for a given NDO
Authorization: Any agent (public DHT)
Returns: Vec<ContributionRecord> via NdoToContributions anchor
get_agent_contributions(provider: AgentPubKey) -> ExternResult<Vec<ContributionRecord>>
Purpose: Retrieve all contributions from a given provider agent
Authorization: Any agent (public DHT)
Returns: Vec<ContributionRecord> via AgentToContributions anchor
create_agreement(input: CreateAgreementInput) -> ExternResult<ActionHash>
Purpose: Create the first benefit redistribution Agreement (v1) for an NDO
Authorization: Any agent; primary_accountable list declares governance signatories
Input:
#![allow(unused)] fn main() { pub struct CreateAgreementInput { pub ndo_identity_hash: ActionHash, pub clauses: Vec<BenefitClause>, pub primary_accountable: Vec<AgentPubKey>, } }
Returns: ActionHash of the Agreement entry
Use Case: Defining how economic benefits (monetary, governance weight, access rights) are distributed among NDO contributors
update_agreement(input: UpdateAgreementInput) -> ExternResult<ActionHash>
Purpose: Update an existing Agreement, incrementing version monotonically
Authorization: Any agent; integrity enforces version = previous + 1
Returns: ActionHash of the updated Agreement entry
get_current_agreement(ndo_identity_hash: ActionHash) -> ExternResult<Option<AgreementRecord>>
Purpose: Retrieve the latest version of the Agreement for an NDO
Authorization: Any agent (public DHT)
Returns: Option<AgreementRecord> resolving the full update chain
Lobby DNA Functions (zome_lobby_coordinator)
Global discovery and federation layer. Uses canonical network_seed: nondominium-lobby-v1.
Agent Profile Functions
upsert_lobby_agent_profile(input: LobbyAgentProfileInput) -> ExternResult<ActionHash>
Purpose: Create or update the calling agent's Lobby profile (upsert pattern via update chain)
Authorization: Any agent
Returns: ActionHash of the new or updated entry
Note: Creates two links on first call — global AllLobbyAgents (path anchor) and per-agent AgentToLobbyProfile (agent pubkey anchor, used for lookup and update detection)
get_lobby_agent_profile(agent: AgentPubKey) -> ExternResult<Option<LobbyAgentProfile>>
Purpose: Retrieve a specific agent's current Lobby profile (resolves update chain)
Authorization: Any agent (public DHT)
Returns: Option<LobbyAgentProfile>
get_all_lobby_agents(_: ()) -> ExternResult<Vec<LobbyAgentProfileRecord>>
Purpose: Retrieve all Lobby agent profiles via global path anchor
Authorization: Any agent (public DHT)
Returns: Vec<LobbyAgentProfileRecord>
Group Registry Functions
NDO discoverability flows through the Group layer, not the Lobby (Lobby → Groups → NDOs). The Lobby hosts the group registry; groups host NDOs.
announce_group(input: AnnounceGroupInput) -> ExternResult<Record>
Purpose: Register a group cloned cell in the Lobby DHT so other agents can discover it and obtain its DnaHash for CellId addressing
Authorization: Any agent
Input: { group_name, group_dna_hash: DnaHash, network_seed, description }
Returns: Record of the created GroupAnnouncement entry
get_all_group_announcements(_: ()) -> ExternResult<Vec<Record>>
Purpose: Enumerate all group announcements via the lobby.groups path anchor
Authorization: Any agent (public DHT)
get_my_group_announcements(_: ()) -> ExternResult<Vec<Record>>
Purpose: Return group announcements registered by the calling agent Authorization: Any agent (public DHT)
get_group_announcement_by_dna_hash(dna_hash: DnaHash) -> ExternResult<Option<Record>>
Purpose: Look up a group announcement by its cloned cell DNA hash Authorization: Any agent (public DHT)
get_my_groups(_: ()) -> ExternResult<Vec<GroupDescriptorStub>>
Purpose: Return lightweight stubs for the calling agent's announced groups
Returns: Vec<GroupDescriptorStub> derived from get_my_group_announcements
🔗 Cross-Zome Integration Functions
Agent Capability Assessment
These functions combine data from multiple zomes to provide comprehensive capability assessment:
#![allow(unused)] fn main() { // Combined capability evaluation (pseudo-code) fn evaluate_agent_capability(agent: AgentPubKey) -> CapabilityAssessment { let person_info = zome_person::get_person_capability_level(agent)?; let reputation = zome_gouvernance::get_my_participation_claims(agent)?; let resources = zome_resource::get_agent_economic_resources(agent)?; CapabilityAssessment { level: person_info.capability_level, reputation_score: reputation.summary.overall_score, resource_count: resources.len(), eligible_processes: calculate_eligible_processes(person_info, reputation), } } }
Economic Process Validation
Cross-zome validation ensures process compliance across all domains:
#![allow(unused)] fn main() { // Process authorization validation (pseudo-code) fn validate_process_authorization( agent: AgentPubKey, process_type: EconomicProcess ) -> AuthorizationResult { let capability = zome_person::get_person_capability_level(agent)?; let reputation = zome_gouvernance::derive_reputation_score(agent)?; match process_type { UseProcess => { require_capability_level(capability, "stewardship")?; validate_reputation_threshold(reputation, USE_PROCESS_THRESHOLD)?; }, TransportProcess | StorageProcess | RepairProcess => { require_capability_level(capability, "coordination")?; validate_reputation_threshold(reputation, ADVANCED_PROCESS_THRESHOLD)?; validate_specialized_role(agent, process_type)?; } } } }
🛡️ Security & Authorization Patterns
1. Capability-Based Access Control
All API functions enforce capability-based authorization:
#![allow(unused)] fn main() { // Standard authorization pattern fn check_authorization(agent: AgentPubKey, required_level: &str) -> Result<(), AuthorizationError> { let current_level = get_person_capability_level(agent)?; if !capability_sufficient(¤t_level, required_level) { return Err(AuthorizationError::InsufficientCapability); } Ok(()) } }
2. Private Data Protection
Private data functions implement field-level access control:
#![allow(unused)] fn main() { // Private data access pattern fn authorize_private_data_access( requestor: AgentPubKey, target: AgentPubKey, fields: Vec<String> ) -> Result<DataAccessGrant, AccessError> { let grant = validate_capability_claim(requestor, target, fields)?; ensure_grant_not_expired(&grant)?; ensure_field_authorized(&grant, fields)?; Ok(grant) } }
3. PPR Cryptographic Verification
PPR functions implement cryptographic verification:
#![allow(unused)] fn main() { // PPR verification pattern fn verify_ppr_authenticity(ppr: &ParticipationClaim) -> Result<VerificationResult, VerificationError> { let signature_valid = verify_signature(&ppr.signature, &ppr.issuer, &ppr.content)?; let context_valid = verify_verification_context(&ppr.verification_context)?; let not_expired = check_expiration(&ppr.expires_at)?; Ok(VerificationResult { signature_valid, context_valid, not_expired, overall_trust_score: calculate_trust_score(ppr), }) } }
📊 Performance & Optimization
DHT Optimization Patterns
- Anchor-Based Discovery: All discovery functions use anchor paths for efficient DHT traversal
- Link Caching: Frequently accessed link queries are cached at the conductor level
- Batch Operations: Multi-entry operations minimize DHT round trips
Memory Management
- Lazy Loading: Large data structures are loaded on-demand
- Reference Counting: Shared data structures use reference counting to prevent memory leaks
- Cleanup Strategies: Expired capabilities and outdated entries are periodically cleaned up
Network Efficiency
- Compression: Large data payloads are compressed before DHT storage
- Validation Caching: Validation results are cached to reduce redundant computations
- Async Processing: Long-running operations use async patterns to prevent blocking
🔮 API Evolution & Extensibility
Versioning Strategy
- Semantic Versioning: API versions follow semantic versioning (MAJOR.MINOR.PATCH)
- Backward Compatibility: Deprecated functions remain supported for at least one major version
- Migration Paths: Clear migration guidelines provided for breaking changes
Extension Points
- Custom Validation: Pluggable validation modules for domain-specific requirements
- New PPR Categories: Extensible PPR system for new reputation dimensions
- Process Types: Economic process system supports new process type definitions
Integration APIs
Future API extensions will include:
- External System Integration: Webhook and event streaming capabilities
- Analytics APIs: Advanced reputation and economic analytics
- Governance APIs: Dynamic rule management and democratic governance features
📋 Error Handling Reference
Common Error Types
#![allow(unused)] fn main() { // Person Management Errors (actual implementation) pub enum PersonError { PersonAlreadyExists, PersonNotFound(String), PrivateDataNotFound, RoleNotFound(String), NotAuthor, SerializationError(String), EntryOperationFailed(String), LinkOperationFailed(String), InvalidInput(String), InsufficientCapability(String), } // Resource Management Errors (actual implementation) pub enum ResourceError { ResourceSpecNotFound(String), EconomicResourceNotFound(String), GovernanceRuleNotFound(String), NotAuthor, NotCustodian, SerializationError(String), EntryOperationFailed(String), LinkOperationFailed(String), InvalidInput(String), GovernanceViolation(String), } // Governance Errors (actual implementation) pub enum GovernanceError { ValidationReceiptNotFound(String), EconomicEventNotFound(String), ResourceValidationNotFound(String), CommitmentNotFound(String), NotAuthorizedValidator, InsufficientCapability(String), ValidationAlreadyExists(String), InvalidValidationScheme(String), SerializationError(String), EntryOperationFailed(String), LinkOperationFailed(String), InvalidInput(String), CrossZomeCallFailed(String), } }
Error Response Format
All API functions return ExternResult<T> with comprehensive error information:
#![allow(unused)] fn main() { pub struct ErrorDetails { pub error_type: String, pub error_code: u32, pub message: String, pub details: Option<String>, pub retry_possible: bool, pub suggested_actions: Vec<String>, } }
🏘️ zome_group — Per-Group Coordination (Group DNA, cloned cell)
Full documentation:
zomes/group_zome.md
Each group occupies its own cloned cell. Functions below operate within the calling cell's isolated DHT. The TypeScript GroupService uses CellId (DnaHash + AgentPubKey) to address the correct cloned cell — the group_dna_hash in the Lobby's GroupAnnouncement is used to resolve the CellId via getGroupCellHandle(client, dnaHash).
Group Profile
create_group(input: GroupProfileInput) -> ExternResult<Record>
Input: { name: String, description: Option<String> }
Returns: Created GroupProfile record. Also creates the all_groups anchor link.
Validation: name non-empty, ≤ 100 characters.
Note: Initiator and created_at come from the action header (record.action().author() / record.action().timestamp()), not from entry fields.
get_group(group_hash: ActionHash) -> ExternResult<Option<Record>>
Retrieves a GroupProfile by action hash.
get_my_group() -> ExternResult<Option<Record>>
Returns the single GroupProfile in this cloned cell (one group per cell). Use this instead of get_all_groups — in the one-group-per-cell model, it's always 0 or 1 results.
update_group(input: UpdateGroupInput) -> ExternResult<Record>
Input: { previous_action_hash: ActionHash, original_action_hash: ActionHash, updated_name: String, updated_description: Option<String> }
Updates the group name and/or description. Only the original initiator may update.
Creates a GroupUpdates link from original_action_hash to the new version's action hash.
Membership
join_group(group_hash: ActionHash) -> ExternResult<Record>
Creates a GroupMembership entry and GroupToMembers + MemberToGroups links.
Guard: Returns GroupError::AlreadyMember if agent already has a membership entry.
leave_group(group_hash: ActionHash) -> ExternResult<()>
Deletes the GroupToMembers and MemberToGroups links for the calling agent.
The GroupMembership entry is intentionally retained on-chain as an audit trail.
get_group_members(group_hash: ActionHash) -> ExternResult<Vec<AgentPubKey>>
Returns the AgentPubKey of every current member, read from each GroupToMembers link's author in a single get_links round-trip (does not get each GroupMembership record, which may be absent from the local shard before sync).
is_member(input: (AgentPubKey, ActionHash)) -> ExternResult<bool>
Predicate: does the given agent appear in get_group_members?
Work Logs
log_work(input: WorkLogInput) -> ExternResult<Record>
Input: { group_hash: ActionHash, description: String, hours: f32 }
Creates a WorkLog entry with GroupToWorkLogs and AgentToWorkLogs links.
Validation: description non-empty; hours > 0.
get_work_logs(group_hash: ActionHash) -> ExternResult<Vec<Record>>
Returns Records for all WorkLog entries in the group. Author = record.action().author().
get_my_work_logs() -> ExternResult<Vec<Record>>
Returns Records for WorkLog entries authored by the calling agent (via AgentToWorkLogs links).
Soft Links
Note: SoftLinks are no longer the Group → NDO pointer — see NDO Anchors below. They remain available for planning-level links.
create_soft_link(input: SoftLinkInput) -> ExternResult<Record>
Input: { group_hash: ActionHash, target_ndo_hash: ActionHash, description: Option<String> }
Creates a SoftLink entry — a planning-level Group → NDO relationship. No PPRs generated (ADR-GROUP-04). Creator = action author.
get_soft_links(group_hash: ActionHash) -> ExternResult<Vec<Record>>
Returns Records for all SoftLink entries in the group. Creator = record.action().author().
NDO Anchors
The authoritative Group → NDO pointer in the Lobby → Groups → NDOs hierarchy (ADR-011). Each NDO is its own cloned ndo cell (ADR-010); the anchor carries the coordinates needed to re-derive, verify, and join that cell, plus cached fields so browsing never joins it. Rationale: documentation/specifications/adr/ADR-010-013-per-ndo-cells.md.
create_ndo_anchor(input: NdoAnchorInput) -> ExternResult<Record>
Input: { group_hash: ActionHash, name: String, description: Option<String>, ndo_dna_hash: DnaHash, network_seed: String, identity_action_hash: ActionHash, initiator: AgentPubKey, ndo_created_at: Timestamp, lifecycle_stage: LifecycleStage, property_regime: PropertyRegime, resource_nature: ResourceNature }
Creates an NdoAnchor and links it from the group (GroupToNdoAnchors). Anchor author and timestamp come from the action header. The same NDO may be anchored in several groups.
get_ndo_anchors(group_hash: ActionHash) -> ExternResult<Vec<Record>>
Returns the latest Record for every anchor in the group, resolving the NdoAnchorUpdates chain so cached descriptor fields reflect the most recent sync.
update_ndo_anchor(input: UpdateNdoAnchorInput) -> ExternResult<Record>
Input: { original_action_hash: ActionHash, previous_action_hash: ActionHash, updated_name: String, updated_description: Option<String>, updated_lifecycle_stage: LifecycleStage }
Refreshes an anchor's cached descriptor. Identity coordinates are copied from the original entry, and integrity rejects any update that changes them (validate_ndo_anchor_update), so an update can never repoint a group at a different NDO cell.
refresh_ndo_anchor_lifecycle_stage(input: RefreshAnchorLifecycleInput) -> ExternResult<Option<Record>>
Input: { group_hash: ActionHash, identity_action_hash: ActionHash, updated_lifecycle_stage: LifecycleStage }
Re-syncs one anchor's cached lifecycle_stage after an NDO lifecycle transition, resolving the anchor by NDO identity rather than by action hash — the client knows the NDO, while the original-vs-latest anchor action hashes belong to the group's link graph. Returns Ok(None) when no anchor in this group points at that NDO (a no-op, not an error).
This API reference represents the complete current functionality of the Nondominium system based on actual codebase analysis. Function signatures and behaviors evolve with implementation improvements and community feedback.
🔄 Updates in Version 3.0 (2025-12-17)
Major Corrections:
- ✅ PersonInput structure: Corrected
avatar→avatar_url, removed non-existentlocationandtagsfields - ✅ Function signatures: Updated all function signatures to match actual implementation
- ✅ Error types: Replaced with actual error enums from the codebase
New Function Categories Added:
- 🆕 Device Management (6 functions): Multi-device support with registration, deactivation, activity tracking
- 🆕 Advanced Capability Sharing (4 functions): Grant revocation, validation, role-based access
- 🆕 Role Promotion Workflow (3 functions): Request/approve/promotion with PPR integration
Missing Functions Now Included:
- Person Management: Added 8 missing functions for agent-person relationships and promotion
- Private Data: Added
store_private_person_dataand correctedget_agent_private_datasignature - Capability System: Added
grant_private_data_access,revoke_private_data_access, validation functions
Accuracy Improvements:
- Capability Levels: Updated to reflect actual role types ("Simple Agent", "Accountable Agent", etc.)
- Security Patterns: Corrected to match actual implementation patterns
- Data Structures: All input/output structures now match actual code
ADR-010 … ADR-013 — Per-NDO cells, group anchors, and DnaHash binding
Status: Accepted, implemented in v0.1.0 (PR #128, Closes #120)
Scope: NDO Layer 0 identity. Touches documentation/requirements/ndo_prima_materia.md's
three-layer model, so it is load-bearing per documentation/TELOS.md.
Long-form design of record: .local/nondominium-architecture-design-2026-08-08.md
(kept out of the repo). This file is the in-repo record: it states the decisions,
the constraints that forced them, and where the code lives — enough to review or
revise the architecture without the local document.
ADR-010 — One cloned cell per NDO ("model A")
Decision. Every NDO is its own cloned ndo DNA cell, provisioned on demand
(workdir/happ.yaml: role ndo, deferred: true, clone_limit: 512). The Layer 0
NondominiumIdentity genesis entry lives inside that cell, not in the shared
nondominium cell.
Why. An NDO is a coordination boundary, not a row: its members, its process activity, and eventually its governance all want their own DHT. A shared cell makes every NDO's traffic every agent's traffic and gives the NDO no identity of its own beyond an action hash in someone else's DHT.
Consequence. The NDO's permanent identity becomes its DnaHash — see ADR-013.
Pre-migration NDOs still exist in the shared nondominium cell, so the read paths
keep a legacy fallback (ndo.service.ts).
ADR-011 — Group DHTs anchor NDOs; there is no global registry
Decision. Discovery is per group. Each group clone cell holds NdoAnchor entries
(dnas/group/zomes/integrity/zome_group_integrity), one per NDO the group hosts,
carrying the full clone coordinates plus cached card fields. The Lobby's NDO browser
is the union of the agent's groups' anchors.
Why. A global registry re-centralises exactly what the group DHT already decentralises, and it would make every NDO visible to every agent regardless of membership.
Consequence. The anchor is the ONLY pointer any NDO read path follows. Three things follow from that, and all three are enforced in code:
createNdodoes not treat the anchor write as best-effort — an NDO whose anchor did not land is a cell nobody can reach again.- Associating an existing NDO with a second group means writing a second anchor
(
NdoService.associateNdoWithGroup), not aSoftLink.SoftLinkremains a valid group entry type but is no longer part of NDO association. - Cached anchor fields drift:
refresh_ndo_anchor_lifecycle_stageresolves an anchor by NDO identity (the client knows the NDO, not the anchor's original-vs-latest action hashes, which belong to the group's link graph) and re-syncslifecycle_stageafter a transition.
ADR-012 — Anchor coordinates are a pinning check, not a trust assertion
Decision. A reader does not trust anchor.ndo_dna_hash. It re-derives the clone
from (network_seed, properties) and compares the resulting DnaHash to the
anchor's. Matching hashes prove the anchor names the cell it claims to.
Consequence. Client, zomes, and tests must derive the same hash from the same
inputs, which is why NdoDnaProperties has exactly one definition
(crates/shared/src/types.rs) that the UI mirror and the Sweettest suite both
follow. A hand-kept mirror already drifted once (a stale initiator field).
ADR-013 — The DnaHash is bound to the NDO identity via DNA properties
Decision. The clone's DNA properties carry the immutable Layer 0 classification:
#![allow(unused)] fn main() { pub struct NdoDnaProperties { pub name: String, pub property_regime: PropertyRegime, pub resource_nature: ResourceNature, pub created_at: Timestamp, } }
validate_create_nondominium_identity (dnas/nondominium/zomes/integrity/zome_resource)
rejects a create_ndo whose name / property_regime / resource_nature diverge
from the cell's properties. Immutability is then hash physics, not a validation rule
someone can forget: changing a classification field means a different DnaHash,
i.e. a different network.
Constraint that shaped it. holochain 0.6.0 transports create_clone_cell
properties as YamlProperties(serde_yaml::Value), which has no binary variant. An
AgentPubKey in properties hangs createCloneCell from the JS client, so
initiator is NOT bound by the DnaHash; it stays authoritative on the entry and is
cached on the anchor for display. created_at IS in the properties but is not
entry-validated (the entry uses sys_time, the properties use the client's
value) — the full mirror validation waits on a create_ndo refactor that reads
dna_info().properties.
created_at is not a uniqueness source. It is microseconds derived from a
millisecond wall clock. Two identically-classified NDOs created in the same
millisecond would share it; distinctness comes from the per-NDO network_seed,
which is also DnaHash input.
Skip path. On the shared nondominium cell (properties: ~), deserialising to
NdoDnaProperties fails and the binding check is skipped, so legacy shared-cell
NDOs keep working. A clone with malformed properties therefore gets no binding —
contained, because such a clone is a different DnaHash on a different network.
Where this lives in code
| Concern | Location |
|---|---|
NdoDnaProperties (the one definition) | crates/shared/src/types.rs |
| ADR-013 binding check | dnas/nondominium/zomes/integrity/zome_resource/src/lib.rs |
NdoAnchor entry + update immutability | dnas/group/zomes/integrity/zome_group_integrity/src/lib.rs |
Anchor externs (create / get / update / refresh) | dnas/group/zomes/coordinator/zome_group/src/ndo_anchor.rs |
Clone provisioning (createNdoCloneCell, ensureNdoCloneCell) | ui/src/lib/services/holochain.service.svelte.ts |
| Anchor-driven read/write paths | ui/src/lib/services/zomes/ndo.service.ts |
| Rust coverage | dnas/group/tests/src/ndo_anchor/mod.rs |
| Browser coverage (2 conductors) | ui/tests/e2e/specs/{core-flows,multi-agent}.spec.ts |
Open follow-ups
- Full ADR-013 mirror validation (
initiator,created_at) behind acreate_ndorefactor that readsdna_info().properties. - Lifecycle transitions do not yet generate an
EconomicEvent(REQ-NDO-LC-02 / LC-03);transition_event_hashisnullin the MVP. - Anchor cache convergence is pull-based;
remote_signalpush isTODO(signals).
Governance in nondominium
Overview
This document outlines the comprehensive governance system implemented in the nondominium project, built on Holochain and using ValueFlows vocabulary and patterns. The governance system spans across three zomes (zome_person, zome_resource, zome_governance) and provides the infrastructure for managing economic activities, validation, accountability, and reputation tracking in a decentralized sharing economy.
The governance system implements a complete agent lifecycle from Simple Agent through Accountable Agent to Primary Accountable Agent, with embedded governance rules, comprehensive validation schemes, structured Economic Processes, and a cryptographically-secured Private Participation Receipt (PPR) system for reputation tracking.
Core Governance Concepts
1. REA Pattern (Resources, Events, Agents)
The governance system is built on the ValueFlows REA (Resource, Event, Agent) ontology:
- Agents: Individual persons with progressive capability levels (Simple → Accountable → Primary Accountable) who perform Economic Events affecting Economic Resources
- Economic Events: Actions using VfAction enum that produce, modify, use, or transfer Economic Resources within structured Economic Processes
- Economic Resources: Material and digital assets with embedded governance rules, managed lifecycle states, and custodian tracking
- Economic Processes: Structured activities (Use, Transport, Storage, Repair) that transform Economic Resources or provide ecosystem services with role-based access control
2. Multi-Layered Ontology
The governance system operates across three levels as defined in ValueFlows:
- Knowledge Level: Embedded governance rules, validation schemes, process requirements, and agent role definitions stored in ResourceSpecifications and process templates
- Plan Level: Commitments with VfAction types, process initiation requests, and validation workflows linking agents to future economic activities
- Observation Level: Completed Economic Events, fulfilled Claims, issued ValidationReceipts, and Private Participation Receipts (PPRs) providing cryptographically-signed reputation tracking
3. Agent Capability Progression
The governance system implements a progressive trust model through three agent types:
- Simple Agent: Entry-level with general capability token, can create Resources and make first transaction
- Accountable Agent: Validated agent with restricted capability token, can access Resources, validate others, and participate in specialized Economic Processes
- Primary Accountable Agent (Custodian): Advanced agent with full capability token, holds physical custody of Resources, can validate role requests, and participate in dispute resolution
TODO (G1, REQ-GOV-16 — post-MVP): Agent capability progression currently models only individual human agents. Post-MVP: Collective, Project, Network, and Bot agents must be supported as governance actors. For Collective/Project/Network agents, governance actions are signed by the designated
PrimaryAccountableAgentrepresentative of the collective NDO. For Bot agents, governance actions are limited to declaredcapabilitiesinAgentEntityType::Bot { capabilities }. Seegovernance.md §3.6and§6.6.
Governance Structures
1. Validation System
The validation system implements comprehensive peer review and verification across all governance activities, supporting configurable validation schemes and role-based access control.
ValidationReceipt
#![allow(unused)] fn main() { pub struct ValidationReceipt { pub validator: AgentPubKey, // TODO (G1, REQ-GOV-16 — post-MVP): replace with AgentContext. // Post-MVP, collective agent and bot validators must be supported // within their declared scope. pub validated_item: ActionHash, pub validation_type: String, pub approved: bool, pub notes: Option<String>, pub validated_at: Timestamp, } }
Purpose: Records validation decisions made by Accountable and Primary Accountable agents on resources, events, processes, agent promotions, and role assignments.
Validation Types:
- resource_approval: Validating new Resources during first access events
- process_validation: Validating Economic Process completions and outcomes
- identity_verification: Confirming agent identities for Simple Agent promotion
- role_assignment: Validating specialized role requests (Transport, Repair, Storage)
- agent_promotion: Validating Simple Agent promotion to Accountable Agent
- end_of_life_validation: Validating Resource end-of-life declarations
ResourceValidation
#![allow(unused)] fn main() { pub struct ResourceValidation { pub resource: ActionHash, pub validation_scheme: String, pub required_validators: u32, pub current_validators: u32, pub status: String, pub created_at: Timestamp, pub updated_at: Timestamp, } }
Purpose: Manages validation workflows for resources requiring multiple validators.
Validation Schemes:
- "simple_majority": More than 50% of required validators must approve
- "2-of-3": Exactly 2 out of 3 designated validators must approve
- "N-of-M": N validators out of M designated validators must approve
- "consensus": All required validators must approve
Status Values:
- "pending": Validation in progress, awaiting validator responses
- "approved": Sufficient validators have approved
- "rejected": Validation failed or was explicitly rejected
2. Economic Event Tracking
EconomicEvent
#![allow(unused)] fn main() { pub struct EconomicEvent { pub action: VfAction, pub provider: AgentPubKey, pub receiver: AgentPubKey, pub resource_inventoried_as: ActionHash, pub affects: ActionHash, pub resource_quantity: f64, pub event_time: Timestamp, pub note: Option<String>, } }
Purpose: Records all economic activities and resource flows in the system.
Governance Functions:
- Audit Trail: Complete record of all economic activities
- Provenance Tracking: Following resource flows forward and backward
- Compliance Monitoring: Ensuring activities follow governance rules
- Performance Analysis: Supporting accountability and transparency
3. Commitment and Claim System
Commitment
#![allow(unused)] fn main() { pub struct Commitment { pub action: VfAction, pub provider: AgentPubKey, pub receiver: AgentPubKey, pub resource_inventoried_as: Option<ActionHash>, pub resource_conforms_to: Option<ActionHash>, pub input_of: Option<ActionHash>, pub due_date: Timestamp, pub note: Option<String>, pub committed_at: Timestamp, } }
Purpose: Represents agreed-upon future actions between agents.
Governance Functions:
- Contractual Agreements: Formalizing promises between agents
- Planning and Coordination: Supporting operational planning
- Accountability: Creating clear expectations and obligations
- Dispute Resolution: Providing basis for conflict resolution
Claim
#![allow(unused)] fn main() { pub struct Claim { pub fulfills: ActionHash, pub fulfilled_by: ActionHash, pub claimed_at: Timestamp, pub note: Option<String>, } }
Purpose: Links commitments to their fulfillment through economic events (public governance record).
Governance Functions:
- Obligation Tracking: Monitoring fulfillment of commitments
- Reciprocal Claims: Managing reciprocal obligations in exchanges
- Dispute Resolution: Supporting claims and counter-claims
- Performance Measurement: Tracking agent reliability and performance
- PPR Generation: Triggers automatic Private Participation Receipt issuance for reputation tracking
3. Economic Process Management
The governance system manages structured Economic Processes that provide ecosystem services with role-based access control and comprehensive validation.
EconomicProcess
#![allow(unused)] fn main() { pub struct EconomicProcess { pub process_type: String, pub name: String, pub description: Option<String>, pub required_role: String, pub inputs: Vec<ActionHash>, pub outputs: Vec<ActionHash>, pub started_by: AgentPubKey, pub started_at: Timestamp, pub completed_at: Option<Timestamp>, pub location: Option<String>, pub status: ProcessStatus, } }
Process Types & Role Requirements:
- Use: Core nondominium process accessible to all Accountable Agents
- Transport: Material Resource movement between locations (requires Transport role)
- Storage: Temporary Resource custody until new Agent requests access (requires Storage role)
- Repair: Resource maintenance and restoration, may change Resource state (requires Repair role)
Process Status Values:
- Planned: Process is planned but not yet started
- InProgress: Process is currently active
- Completed: Process finished successfully with validation
- Suspended: Process temporarily paused
- Cancelled: Process cancelled before completion
- Failed: Process failed to complete successfully
Governance Functions:
- Role Enforcement: Only agents with appropriate roles can initiate specialized processes
- Process Chaining: Agents with multiple roles can chain actions (transport → repair → transport)
- State Management: Proper Resource state transitions based on process type
- Validation Requirements: Process completion validation according to process-specific criteria
4. Private Participation Receipt (PPR) System
The governance system implements a comprehensive reputation tracking mechanism through cryptographically-signed Private Participation Receipts stored as private entries.
PrivateParticipationClaim
#![allow(unused)] fn main() { pub struct PrivateParticipationClaim { // Standard ValueFlows fields pub fulfills: ActionHash, pub fulfilled_by: ActionHash, pub claimed_at: Timestamp, // PPR-specific extensions pub claim_type: ParticipationClaimType, pub counterparty: AgentPubKey, pub performance_metrics: PerformanceMetrics, pub bilateral_signature: CryptographicSignature, pub interaction_context: String, pub role_context: Option<String>, pub resource_reference: Option<ActionHash>, } }
PPR Issuance Categories:
Genesis Role - Network Entry:
- ResourceContribution: Receipt for successfully creating and validating a Resource
- NetworkValidation: Receipt for performing validation duties
Core Usage Role - Custodianship:
- ResponsibleTransfer: Receipt for properly transferring Resource custody
- CustodyAcceptance: Receipt for accepting Resource custody responsibly
Intermediate Roles - Specialized Services:
- ServiceCommitmentAccepted: Receipt for accepting service commitments (Transport, Repair, Storage)
- GoodFaithTransfer: Receipt for transferring Resource in good faith for service
- ServiceFulfillmentCompleted: Receipt for completing services successfully
- MaintenanceFulfillment, StorageFulfillment, TransportFulfillment: Service-specific completion receipts
Network Governance:
- DisputeResolutionParticipation: Receipt for constructive participation in conflict resolution
- GovernanceCompliance: Receipt for consistent adherence to governance protocols
Resource End-of-Life:
- EndOfLifeDeclaration: Receipt for declaring Resource end-of-life
- EndOfLifeValidation: Receipt for validating Resource end-of-life (enhanced security)
PPR Governance Principles:
- Bi-directional Issuance: Every economic interaction generates exactly 2 receipts between participating agents
- Cryptographic Integrity: All receipts are cryptographically signed for authenticity
- Privacy Preservation: Stored as Holochain private entries accessible only to owning agent
- Performance Tracking: Quantitative metrics (timeliness, quality, reliability, communication scores)
- Reputation Derivation: Agents can calculate and selectively share reputation summaries
Agent Roles and Permissions
1. Simple Agent
- Capabilities: General capability token
- Permissions:
- Search and discover nondominium resources
- Create new nondominium resources
- Complete identity verification
- Make first transaction to become Accountable Agent
2. Accountable Agent
- Capabilities: Restricted capability token
- Permissions:
- All Simple Agent permissions
- Signal intent to access resources
- Acquire specialized roles (Repair, Transport, Storage)
- Validate other agents and resources
- Participate in validation workflows
3. Primary Accountable Agent (Custodian)
- Capabilities: Full capability token
- Permissions:
- All Accountable Agent permissions
- Hold custody of material resources
- Apply governance rules programmatically
- Hold shared credentials with access conditions
- Validate other agents for specialized roles
Governance Rules and Validation
1. Access Control Rules
- Permissionless Access: Anyone can access resources under defined rules
- Role-Based Access: Different permissions based on agent roles
- Validation Requirements: Resources may require validation before access
- Custody Transfer: Rules for transferring resource custody between agents
2. Validation Schemes
- Simple Validation: Single validator approval
- Multi-Signature: Multiple validators required
- Majority Rule: Simple majority of validators
- Consensus: All validators must approve
3. Governance Rule Types
- Access Requirements: Who can access resources and under what conditions
- Usage Limits: Restrictions on how resources can be used
- Transfer Conditions: Rules for transferring resources between agents
- Maintenance Obligations: Requirements for resource maintenance and care
TODO (post-MVP — temporal governance, governance.md §4.8): GovernanceRule entries must support an optional
expires_at: Timestampfield for time-limited rules. Rules with an expiry become inactive after the deadline without requiring a manual update. The governance evaluation engine must skip expired rules duringevaluate_transition.TODO (post-MVP — configurable processes, governance.md §6.2): Economic Process types (Use, Transport, Storage, Repair) are currently hardcoded. Post-MVP, they must become configurable
GovernanceProcessentries that communities can extend with custom process types, role requirements, and validation schemes. Seegovernance.md §6.2.TODO (post-MVP — EconomicAgreement rule type, ndo_prima_materia.md §6.6): Add
EconomicAgreementto theGovernanceRuleTypeenum for Unyt Smart Agreement integration. When present, the governance zome requires a valid Unyt RAVE before approving state transitions for the configuredtrigger_actions. Seendo_prima_materia.md§6.6 andREQ-NDO-CS-09.
4. Role-Specific Validation Rules
Agents seeking to acquire specialized roles such as Transport, Repair, and Storage must undergo additional validation, as defined in the nondominium governance model (Sensorica nondominium):
- Eligibility: Only Accountable Agents or Primary Accountable Agents may request these roles.
- Validation Process:
- The agent submits a request to acquire a specialized role (Transport, Repair, or Storage).
- The request is reviewed by one or more existing Primary Accountable Agents who already hold the relevant role.
- The reviewing agents validate the applicant's credentials, history, and, if required, their identity and prior actions.
- Upon successful validation, a ValidationReceipt is issued, and the role is granted to the agent.
- The system may require a minimum number of validators (e.g., 2-of-3 or majority) depending on the resource or process sensitivity.
- Criteria for Validation:
- Demonstrated trustworthiness and accountability (e.g., successful prior transactions, positive validation history)
- Sufficient knowledge or credentials for the requested role
- Compliance with any additional governance rules or obligations (e.g., maintenance standards for Storage, safety for Transport)
- Revocation: Roles can be revoked if the agent violates governance rules, as determined by a validation process involving other Primary Accountable Agents.
These validation rules ensure that only qualified and trusted agents can access and perform critical roles, supporting the self-governance, capture resistance, and accountability principles of the nondominium system.
Economic Actions (VfAction)
The governance system supports almost all ValueFlows economic actions:
Standard ValueFlows Actions
- Transfer: Transfer ownership/custody
- Move: Move resources between locations
- Use: Use resources without consuming
- Produce: Create/produce new resources
- Work: Apply work/labor to resources
- Modify: Modify existing resources
- Combine: Combine multiple resources
- Separate: Separate resources into multiple
- Raise: Increase resource quantity/value
- Lower: Decrease resource quantity/value
- Cite: Reference or cite resources
- Accept: Accept delivery or responsibility
nondominium-Specific Actions
- InitialTransfer: First transfer by a Simple Agent
- AccessForUse: Request access to use a resource
- TransferCustody: Transfer custody (nondominium specific)
Economic Processes (VfAction)
The governance system supports the following Nondominium-specific processes:
- Use: This is the core Nondominium process, a Resource is used by agents acording to its rules and in accordance to the network governance.
- Transport: A material Economic Resource is moved from one location to another. The process is only accessible by Agents that hold credencials (capability tokens) for the Transport role. The Economic Resource is unchanged by the process.
- Storage: A material Economic Resource is placed in storage until a new Accountable Agent request access. The process is only accessible by Agents that hold credencials (capability tokens) for the Storage role. The Economic Resource is unchanged by the process.
- Repair: A material Economic Resource is repaired. The Economic Resource is changed by the process, perhaps from a broken state to a working/functional state.
These processes apply to material Economic Resources and are seen as part of ecosystem services, provided by agents in intermediate roles, gated by their credencials.
Dispute Resolution
Resolve disputes at the edge of the network, among agents that have interacted in the past and are about to interact. Avoid the creation of super users or admin roles. Disputes arise during custodian transfer events, for example when a Resource is stolen (made unavailable) by an agent, i.e. when a current custodian doesn't fulfill its role and responsibility vis avi the Nondominium Resource.
- Any Accountable Agent makes a request to access a Resource listed as available.
- The current Custodian of the said Resource is non responsive.
- The said Accountable Agent raises a red flag, which triggers a dispute resolution process.
- The Resource metadata can be access to reveal its past custodian transfers (transactions).
- The last agents, up to the last fourth, that have interacted in the past with the current Custodian are notified to participate in the dispute resolution process. All these agents must have access to the current Custodian private data, which allows them to physically locate the person in the role of current Custodian. This can trigger legal procedures, since the current Custodian has committed to legal obligations (contract) when has acquired the Resource. At least one of the said agents can pursue the dispute resolution process.
- If none of these agents want to pursue the dispute resolution process their profile is marked as having missed to fulfill their responsibility of defending or protecting the Nondomonium network, which is a data entry in their reputation metadata.
Governance Workflows
1. Resource Creation and Validation
- Simple or Accountable Agent creates new nondominium resource
- Resource enters "pending_validation" state
- Accountable Agents validate resource
- Resource becomes available for access
2. Access Request and Approval
- Accountable Agent signals intent to access resource
- Primary Accountable Agent (custodian) reviews request
- Governance rules are applied programmatically
- Access is granted or denied based on rules and validation
3. Custody Transfer

- Current Primary Accountable Agent (custodian) initiates transfer
- New custodian accepts responsibility
- Transfer event is recorded
- Links are updated to reflect new custody
4. Validation Workflows
- Resource requires validation
- Validation scheme determines required validators
- Validators review and approve/reject
- Validation status is updated
- Resource becomes available or rejected
5. Agent Onboarding and Progression
Simple Agent to Accountable Agent Promotion
- Simple Agent creates their first nondominium Resource with embedded governance rules
- Simple Agent initiates first transaction (Initial Transfer) to interested Accountable Agent
- Receiving Accountable Agent validates both the Resource and the Simple Agent's identity (private entry access)
- Upon successful validation:
- ValidationReceipt issued for both Resource and Agent promotion
- Simple Agent promoted to Accountable Agent with restricted capability token
- Bi-directional PPRs issued (ResourceContribution + NetworkValidation)
- Resource state changes from "pending_validation" to "validated"
Specialized Role Acquisition
- Accountable Agent requests specialized role (Transport, Repair, Storage)
- Request reviewed by existing Primary Accountable Agents holding the relevant role
- Validators assess credentials, history, and compliance with role requirements
- ValidationReceipt issued upon approval, role granted
- PPRs issued for validation participation
6. Economic Process Workflows
Process Initiation and Completion
- Accountable Agent with appropriate role initiates Economic Process
- Commitment created with specific VfAction and process details
- Process status tracked (Planned → InProgress → Completed)
- Process completion validated according to process-specific requirements
- Economic Event recorded upon completion
- Claim created linking Commitment to Economic Event
- Bi-directional PPRs automatically issued based on process type
Process Chaining Example (Transport + Repair)
- Agent with Transport + Repair roles creates single Commitment for chained actions
- Process initiated: receive → transport → repair → transport → deliver
- Internal process status updates managed by executing agent
- Final delivery triggers completion validation
- Bi-directional PPRs issued: "Transport + Repair fulfillment completed" + "custody acceptance"
7. Resource End-of-Life Management
- Agent declares Resource end-of-life with evidence documentation
- Multiple expert validators required (minimum 2-3, depending on Resource value)
- Past custodians notified, challenge period initiated (7-14 days)
- Expert validators review evidence and Resource condition
- If no challenges raised, Resource moved to final disposal/storage
- Enhanced PPRs issued with strict validation requirements
- Resource state updated to "decommissioned"
8. Dispute Resolution
- Accountable Agent requests access to available Resource
- Current custodian becomes non-responsive or refuses access improperly
- Requesting agent raises dispute flag
- System identifies last four agents who interacted with current custodian
- Past interaction partners notified (must have custodian's private data access)
- At least one past partner must pursue dispute resolution
- Failure to participate impacts reputation through negative PPR entries
- Resolution process can trigger legal procedures based on custodian contracts
Implementation Details
1. Zome Structure
The governance system spans across three integrated zomes:
zome_person
- Entry Types: Person, PrivatePersonData, PersonRole, DataAccessGrant, DataAccessRequest
- Functions: Agent identity management, role assignment, reputation tracking, private data sharing
- Capabilities: PPR storage and retrieval, reputation summary calculation
zome_resource
- Entry Types: ResourceSpecification, EconomicResource, GovernanceRule, EconomicProcess, ProcessStatus
- Functions: Resource lifecycle management, process initiation and completion, embedded rule enforcement
- Capabilities: Process chaining, role-based access control, state management
zome_governance
- Entry Types: ValidationReceipt, EconomicEvent, Commitment, Claim, ResourceValidation, PrivateParticipationClaim
- Functions: Validation workflows, PPR issuance, cross-zome validation, dispute resolution support
- Capabilities: Multi-signature validation, cryptographic signature verification, reputation derivation
2. Cross-Zome Integration
- Role Validation:
zome_personvalidates agent roles beforezome_resourceallows process initiation - Governance Enforcement:
zome_resourcecallszome_governancefor validation and PPR issuance - Identity Verification:
zome_governanceaccesseszome_personprivate entries for agent validation - Transactional Integrity: All economic interactions span multiple zomes with atomic operations
3. Security and Privacy
- Capability-based security: Progressive access control through capability tokens (general → restricted → full)
- Role-based access control: Economic Processes enforce specialized role requirements with validated credentials
- Private entries: Sensitive information (PII, PPRs) stored as Holochain private entries in agent's source chain
- Cryptographic integrity: All PPRs cryptographically signed for authenticity and non-repudiation
- Selective disclosure: Agents control sharing of private data and reputation summaries
- Audit trails: Complete record of all economic activities, validations, and governance actions
- End-of-life security: Enhanced validation requirements prevent resource theft through false end-of-life claims
Governance Principles
1. Decentralized Authority
- No single point of control or super-users in the network
- Governance distributed among network participants through progressive trust model
- Rules embedded in ResourceSpecifications and enforced programmatically
- Edge-based dispute resolution involving recent interaction partners
2. Transparency and Accountability
- All economic activities recorded as Economic Events with complete audit trails
- Public governance rules and validation schemes machine-readable and transparent
- Clear validation processes with cryptographically-signed ValidationReceipts
- Comprehensive reputation tracking through Private Participation Receipts
3. Inclusive Participation
- Permissionless entry under defined governance rules (Simple Agent level)
- Progressive capability model enabling advancement through validated participation
- Multiple specialized roles supporting diverse ecosystem services
- Stakeholder-driven governance through peer validation and role-based access
4. Capture Resistance
- Resources cannot be monopolized due to embedded governance rules
- Distributed validation prevents capture by single actors
- End-of-life security measures prevent resource theft
- Multi-reviewer validation schemes ensure no single point of failure
5. Privacy-Preserving Accountability
- Private Participation Receipts enable reputation without compromising privacy
- Selective disclosure allows agents to control information sharing
- Cryptographic signatures ensure authenticity while preserving autonomy
- Private entries protect sensitive information while enabling governance
6. Process-Aware Governance
- Structured Economic Processes with role-based access control
- Process chaining enables complex service delivery
- State management ensures proper Resource lifecycle tracking
- Performance metrics support quality assurance and continuous improvement
Future Enhancements
Phase 2 Enhancements (Building on Current Foundation)
- Advanced Governance Rule Engine: Conditional logic and smart contract-like governance rules
- Automated Validation Workflows: AI-assisted validation and anomaly detection
- Enhanced Dispute Resolution: Formal mediation protocols and reputation-weighted resolution
- Cross-Network Resource Sharing: Federation with other nondominium networks
- Economic Incentive Mechanisms: Value accounting and contribution-based incentives
Phase 3 Enhancements (Advanced Network Features)
- Integration with External Governance: Legal system integration and compliance frameworks
- Advanced Reputation Algorithms: Machine learning-based trust prediction and recommendation systems
- Scalable Validation Schemes: Optimized validation for large-scale networks
- Multi-Network Identity: Cross-platform agent identity and reputation portability
- Automated Compliance Checking: Real-time governance rule compliance monitoring
10. Governance-as-Operator Architecture Implementation
The nondominium governance system implements a modular architecture following REQ-ARCH-07, separating data management from business logic enforcement:
- Architecture Specification: See Governance Operator Architecture for detailed technical specifications and design patterns
- Implementation Guide: See Governance Operator Implementation Guide for comprehensive code examples, cross-zome interfaces, and testing patterns
This modular design enables:
- Independent evolution of resource data structures and governance rules
- Swappable governance schemes for different resource types
- Comprehensive testing of governance logic in isolation
- Clear separation of concerns between data persistence and business rule enforcement
References
- ValueFlows Core Concepts
- ValueFlows Governance Patterns
- nondominium Project Documentation
- Holochain Governance Documentation
Governance-as-Operator Architecture Specification
1. Overview

zome_resource stores entries only — no business logic. zome_gouvernance evaluates rules, approves or rejects transitions, and generates audit trail events. The clean boundary enables independent evolution and swappable governance schemes.
Implementation status (2026-08-29, post-#132).
GovernanceTransitionRequest,TransitionContext, andGovernanceTransitionResultare defined incrates/shared/src/io/governance.rs, andevaluate_state_transitionis live inzome_gouvernance/src/transition.rs.request_resource_transitiondoes not exist: the resource zome does not yet call into this path, so evaluation runs parallel and advisory alongsidepropose_commitment/log_economic_eventrather than as the mandatory funnel. Treat the request side of this document as the design target, not current behaviour. Status:documentation/IMPLEMENTATION_STATUS.md§ Governance-as-Operator Architecture.
The governance-as-operator architecture establishes a clear separation between data management and business logic enforcement in the nondominium system. This design enables independent evolution of resource data structures and governance rules, providing a foundation for modular, maintainable, and extensible decentralized resource management.
1.1 Core Principles
- Resource Zome: Pure data model responsible for resource specification management, economic resource lifecycle, and data persistence
- Governance Zome: State transition operator responsible for evaluating governance rules, validating state changes, and generating economic events
- Cross-Zome Interface: Well-defined communication protocol for state transition requests and decisions
- Event-Driven Architecture: All state changes generate corresponding economic events for audit trails and reputation tracking
1.2 Business Benefits
- Modularity: Independent evolution of data structures and governance logic
- Testability: Governance logic can be unit tested independently of data management
- Swappability: Different governance schemes can be applied to the same resource types
- Maintainability: Clear separation of concerns reduces system complexity
1.3 Related specifications (post-MVP NDO & integrations)
Typed governance evaluation is specified to grow toward a single evaluate_transition_request path that can read:
- Economic closure (Unyt): endorsed
EconomicAgreementrules, transitionrave_hash, RAVE validation —documentation/requirements/ndo_prima_materia.md§6.6, REQ-NDO-CS-07–CS-11; design narrative indocumentation/requirements/post-mvp/unyt-integration.md. - Cross-app identity (Flowsta):
IdentityVerification(or equivalent) rules andFlowstaIdentityslot checks per REQ-NDO-CS-14–CS-15 —ndo_prima_materia.md§6.7;documentation/requirements/post-mvp/flowsta-integration.md. - Agent / resource ontology context:
documentation/archives/governance.md§3.7 (parallel Unyt vs Flowsta operator pattern).
MVP code may still use separate coordinator entry points (e.g. validate_agent_for_promotion); the target architecture folds these into unified transition evaluation as the generic NDO matures.
2. Cross-Zome Interface Specifications
2.1 State Transition Request
The primary interface for resource state changes follows this structure:
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct GovernanceTransitionRequest { /// The action the requesting agent wants to perform pub action: VfAction, /// Current state of the resource being modified pub resource: EconomicResource, /// Agent requesting the state change /// TODO (G1, REQ-GOV-16): replace AgentPubKey with AgentContext post-MVP. /// For collective/bot agents, the signing authority is the designated operator key. /// The governance evaluation must resolve AgentContext → effective AgentPubKey /// before capability token validation. pub requesting_agent: AgentPubKey, /// Additional context for the transition pub context: TransitionContext, } #[derive(Serialize, Deserialize, Debug, Clone)] pub struct TransitionContext { /// Target location for transport/move actions pub target_location: Option<String>, /// Quantity change for produce/consume actions pub quantity_change: Option<f64>, /// Target custodian for transfer actions /// TODO (G1, REQ-AGENT-02): replace Option<AgentPubKey> with Option<AgentContext> post-MVP /// to support custody transfer to Collective, Project, Network, and Bot agents. /// AgentContext = union of AgentPubKey | CollectiveAgentHash. pub target_custodian: Option<AgentPubKey>, /// Process notes and observations pub process_notes: Option<String>, /// Associated economic process if applicable pub process_context: Option<ActionHash>, } // TODO (G2, REQ-AGENT-03, REQ-AGENT-05): extend governance evaluation to query AffiliationState. // The validate_agent_permissions function in GovernanceEngine must be extended post-MVP to: // 1. Cross-zome call zome_person to retrieve the requesting agent's AffiliationRecord entries // 2. Derive the agent's current AffiliationState (UnaffiliatedStranger | CloseAffiliate | // ActiveAffiliate | CoreAffiliate | InactiveAffiliate) // 3. Compare AffiliationState against GovernanceRule.rule_data["min_affiliation"] condition // This enables affiliation-gated resource access without storing affiliation as a declared field. }
2.2 State Transition Result
The governance zome returns detailed results for each transition request:
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug)] pub struct GovernanceTransitionResult { /// Whether the transition was approved pub success: bool, /// Updated resource state (if approved) pub new_resource_state: Option<EconomicResource>, /// Generated economic event for audit trail pub economic_event: Option<EconomicEvent>, /// Validation receipts from governance evaluation pub validation_receipts: Vec<ValidationReceipt>, /// Detailed reasons for rejection (if applicable) pub rejection_reasons: Option<Vec<String>>, /// Required next steps or additional validation needed pub next_steps: Option<Vec<String>>, } }
2.3 Resource State Change
Detailed resource state changes tracked by the system:
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct ResourceStateChange { /// Hash of the original resource state pub original_resource_hash: ActionHash, /// Hash of the new resource state pub new_resource_hash: ActionHash, /// Action that triggered the state change pub triggering_action: VfAction, /// Agent who initiated the change /// TODO (G1, REQ-GOV-16): replace with AgentContext post-MVP. pub initiated_by: AgentPubKey, /// Governance decision that authorized the change pub governance_decision: GovernanceDecision, /// Economic event recording the change pub economic_event: EconomicEvent, /// Timestamp when the change occurred pub changed_at: Timestamp, } #[derive(Serialize, Deserialize, Debug, Clone)] pub struct GovernanceDecision { /// Whether the change was approved pub approved: bool, /// Governance rules that were evaluated pub evaluated_rules: Vec<ActionHash>, /// Role-based permission check results pub role_permissions: Vec<RolePermissionResult>, /// Additional validation constraints pub validation_constraints: Vec<ValidationConstraint>, /// Decision rationale pub rationale: String, } }
TODO (post-MVP — governance weight dampening, governance.md §6.4): When
governance_weight(agent)incorporatesunyt_credit_capacityfrom the Unyt credit system, apply logarithmic dampening (e.g.,log(1 + credit_capacity)) to prevent a feedback loop where high reputation → high credit → higher governance weight → even higher reputation. Without dampening, early participants accumulate runaway influence. Seegovernance.md §6.4.
3. Modular Design Patterns
3.1 Pure Function Governance

Four-stage pure function pipeline: (1) capability/permission check, (2) GovernanceRule evaluation, (3) state validity check, (4) result combination. A FAIL at any stage triggers immediate rejection. Same inputs always produce same outputs — independently testable.
Governance logic is implemented as pure functions that evaluate state transitions without side effects:
#![allow(unused)] fn main() { impl GovernanceEngine { /// Pure function: evaluates state transition without side effects pub fn evaluate_transition( request: GovernanceTransitionRequest, rules: Vec<GovernanceRule>, agent_permissions: AgentPermissions, ) -> ExternResult<TransitionEvaluation> { // 1. Validate agent permissions let permission_result = validate_agent_permissions( &request.requesting_agent, &request.action, &agent_permissions, )?; // 2. Evaluate applicable governance rules let rule_results = evaluate_governance_rules( &request.resource, &request.action, &rules, )?; // 3. Check state transition validity let state_validity = validate_state_transition( &request.resource.state, &request.action, &request.context, )?; // 4. Combine all evaluations into final decision Ok(TransitionEvaluation { allowed: permission_result.allowed && rule_results.all_passed && state_validity.valid, new_state: calculate_new_state(&request.resource, &request.action, &request.context)?, required_events: generate_required_events(&request.action), validation_notes: combine_validation_notes(permission_result, rule_results, state_validity), }) } } }
3.2 State Management Isolation
Resource state management is isolated from governance evaluation:
#![allow(unused)] fn main() { // Resource zome: manages state but delegates decision making impl ResourceManager { pub fn request_state_change( &self, request: GovernanceTransitionRequest, ) -> ExternResult<GovernanceTransitionResult> { // 1. Get current resource state let current_resource = self.get_resource(request.resource_hash)?; // 2. Call governance operator for decision let governance_result = call GovernanceZome::evaluate_transition( GovernanceTransitionRequest { action: request.action, resource: current_resource, requesting_agent: request.requesting_agent, context: request.context, } )?; // 3. Apply state change if approved if governance_result.success { if let Some(new_state) = governance_result.new_resource_state { self.update_operational_state(new_state)?; } if let Some(event) = governance_result.economic_event { self.record_economic_event(event)?; } } Ok(governance_result) } } }
3.3 Event Generation Patterns
All state changes generate corresponding economic events:
#![allow(unused)] fn main() { impl EventGenerator { pub fn generate_state_change_event( action: VfAction, resource_before: &EconomicResource, resource_after: Option<&EconomicResource>, requesting_agent: AgentPubKey, governance_decision: &GovernanceDecision, ) -> ExternResult<EconomicEvent> { Ok(EconomicEvent { action, provider: resource_before.custodian, receiver: requesting_agent, resource_inventoried_as: resource_before.conforms_to, affects: get_action_hash(resource_before)?, resource_quantity: calculate_quantity_change(resource_before, resource_after)?, event_time: sys_time()?, note: Some(format!( "State change approved: {}", governance_decision.rationale )), }) } } }
4. Implementation Guidelines
4.1 Cross-Zome Call Patterns

Complete round-trip: agent request → zome_resource → zome_gouvernance (4-stage evaluation) → hREA DNA (EconomicEvent commit) → DHT → results propagated back. Solid arrows = calls, dashed = returns.
Efficient cross-zome communication patterns:
#![allow(unused)] fn main() { // Resource zome: synchronous governance evaluation #[hdk_extern] pub fn request_resource_transition( request: GovernanceTransitionRequest, ) -> ExternResult<GovernanceTransitionResult> { // 1. Prepare cross-zome call let governance_input = request.clone(); // 2. Call governance zome let result: GovernanceTransitionResult = call( CallTargetCell::Local, "zome_gouvernance", "evaluate_state_transition".into(), None, &governance_input, )?; // 3. Handle result and update local state if result.success { update_operational_state(result.new_resource_state)?; create_economic_event(result.economic_event)?; } Ok(result) } // Governance zome: pure function evaluation #[hdk_extern] pub fn evaluate_state_transition( request: GovernanceTransitionRequest, ) -> ExternResult<GovernanceTransitionResult> { // 1. Load applicable governance rules let rules = get_applicable_rules(&request.resource)?; // 2. Evaluate using pure function let evaluation = GovernanceEngine::evaluate_transition( request, rules, get_agent_permissions(&request.requesting_agent)?, )?; // 3. Generate economic event if approved let economic_event = if evaluation.allowed { Some(generate_economic_event(&request, &evaluation)?) } else { None }; Ok(GovernanceTransitionResult { success: evaluation.allowed, new_resource_state: evaluation.new_state, economic_event, validation_receipts: evaluation.validation_receipts, rejection_reasons: evaluation.rejection_reasons, next_steps: evaluation.next_steps, }) } }
4.2 Error Handling Strategies
Robust error handling across zome boundaries:
#![allow(unused)] fn main() { #[derive(Debug, Serialize, Deserialize)] pub enum GovernanceError { PermissionDenied(String), RuleViolation(String), InvalidStateTransition(String), ResourceNotFound(String), CrossZomeCallFailed(String), } // Resource zome error handling pub fn handle_governance_result( result: Result<GovernanceTransitionResult, GovernanceError> ) -> ExternResult<()> { match result { Ok(transition_result) => { if transition_result.success { // Apply approved changes apply_state_changes(transition_result)?; } else { // Log rejection for audit trail log_governance_rejection(transition_result)?; } Ok(()) } Err(GovernanceError::CrossZomeCallFailed(msg)) => { // Log error but don't fail completely warn!("Governance evaluation failed: {}", msg); Err(WasmError::Guest(format!("Governance unavailable: {}", msg)).into()) } Err(error) => { // Log other errors error!("Governance error: {:?}", error); Err(WasmError::Guest(error.to_string()).into()) } } } }
4.3 Validation Separation
Clear separation between data validation and governance validation:
#![allow(unused)] fn main() { // Resource zome: data integrity validation impl ResourceValidator { pub fn validate_resource_data( resource: &EconomicResource, ) -> ExternResult<()> { // Pure data validation if resource.quantity <= 0.0 { return Err(ResourceError::InvalidQuantity.into()); } if resource.unit.trim().is_empty() { return Err(ResourceError::InvalidUnit.into()); } // Check specification exists let _spec = get(resource.conforms_to, GetOptions::default())? .ok_or(ResourceError::SpecificationNotFound)?; Ok(()) } } // Governance zome: business rule validation impl GovernanceValidator { pub fn validate_governance_rules( request: &GovernanceTransitionRequest, rules: &[GovernanceRule], ) -> ExternResult<Vec<RuleValidationResult>> { rules.iter() .map(|rule| evaluate_rule(request, rule)) .collect() } } }
5. Testing Strategy
5.1 Unit Testing Governance Logic
Isolated testing of governance evaluation logic:
#![allow(unused)] fn main() { #[cfg(test)] mod governance_tests { use super::*; #[test] fn test_transfer_approval() { let request = create_transfer_request(); let rules = create_test_rules(); let permissions = create_test_permissions(); let result = GovernanceEngine::evaluate_transition( request, rules, permissions, ).unwrap(); assert!(result.allowed); assert!(result.new_state.is_some()); assert!(!result.validation_receipts.is_empty()); } #[test] fn test_unauthorized_role_rejection() { let request = create_repair_request(); let permissions = AgentPermissions { roles: vec!["Transport".to_string()], // No Repair role ..Default::default() }; let result = GovernanceEngine::evaluate_transition( request, vec![], permissions, ).unwrap(); assert!(!result.allowed); assert!(result.rejection_reasons.unwrap().iter() .any(|reason| reason.contains("Insufficient role"))); } } }
5.2 Cross-Zome Integration Testing
Testing interaction between resource and governance zomes:
#![allow(unused)] fn main() { #[cfg(test)] mod cross_zome_tests { use super::*; #[test] fn test_end_to_end_state_transition() { // Setup test environment let (conductor_config, _dna_file) = setup_test_environment().await; let alice_agent = setup_agent(conductor_config.clone()).await; let bob_agent = setup_agent(conductor_config).await; // Create test resource let resource_hash = alice_agent.call::<CreateResourceOutput>( "create_economic_resource", create_test_resource_input(), ).await?.resource_hash; // Request state change let transition_request = GovernanceTransitionRequest { action: VfAction::Transfer, resource: get_resource(resource_hash).await?, requesting_agent: bob_agent.agent_pub_key().clone(), context: TransitionContext { target_custodian: Some(bob_agent.agent_pub_key().clone()), ..Default::default() }, }; // Process transition let result = alice_agent.call::<GovernanceTransitionResult>( "request_resource_transition", transition_request, ).await?; assert!(result.success); assert!(result.economic_event.is_some()); } } }
5.3 Mock Governance for Resource Testing
Mock governance for isolated resource zome testing:
#![allow(unused)] fn main() { pub struct MockGovernanceZome { approval_mode: ApprovalMode, } #[derive(Debug)] pub enum ApprovalMode { ApproveAll, RejectAll, RoleBased(Vec<String>), Conditional(Box<dyn Fn(&GovernanceTransitionRequest) -> bool>), } impl MockGovernanceZome { pub fn evaluate_transition( &self, request: GovernanceTransitionRequest, ) -> ExternResult<GovernanceTransitionResult> { let approved = match &self.approval_mode { ApprovalMode::ApproveAll => true, ApprovalMode::RejectAll => false, ApprovalMode::RoleBased(allowed_roles) => { // Mock role checking logic false // Simplified for example } ApprovalMode::Conditional(validator) => validator(&request), }; Ok(GovernanceTransitionResult { success: approved, new_resource_state: if approved { Some(calculate_new_state(&request)) } else { None }, economic_event: if approved { Some(generate_test_event(&request)) } else { None }, validation_receipts: vec![], rejection_reasons: if approved { None } else { Some(vec!["Mock rejection".to_string()]) }, next_steps: None, }) } } }
6. Performance Considerations
6.1 Cross-Zome Call Optimization
Strategies for efficient cross-zome communication:
#![allow(unused)] fn main() { // Batch multiple state changes #[hdk_extern] pub fn batch_state_transitions( requests: Vec<GovernanceTransitionRequest>, ) -> ExternResult<Vec<GovernanceTransitionResult>> { // Group requests by governance rules needed let mut grouped_requests = HashMap::new(); for request in requests { let rule_set = determine_required_rules(&request); grouped_requests.entry(rule_set) .or_insert_with(Vec::new) .push(request); } // Process each group with single governance call let mut results = Vec::new(); for (rule_set, group_requests) in grouped_requests { let group_results = evaluate_transition_group(rule_set, group_requests)?; results.extend(group_results); } Ok(results) } }
6.2 State Management Efficiency
Efficient state management patterns:
#![allow(unused)] fn main() { // Lazy evaluation of governance rules pub struct LazyRuleEvaluator { cached_rules: LruCache<String, Vec<GovernanceRule>>, rule_loader: Box<dyn Fn(&str) -> ExternResult<Vec<GovernanceRule>>>, } impl LazyRuleEvaluator { pub fn get_rules_for_resource( &mut self, resource_spec: &ActionHash, ) -> ExternResult<&Vec<GovernanceRule>> { let cache_key = format!("{}", resource_spec); if !self.cached_rules.contains(&cache_key) { let rules = (self.rule_loader)(&cache_key)?; self.cached_rules.put(cache_key.clone(), rules); } Ok(self.cached_rules.get(&cache_key).unwrap()) } } }
This architecture specification provides the technical foundation for implementing the governance-as-operator pattern, ensuring clear separation of concerns while maintaining efficient cross-zome communication and comprehensive state management.
Governance Operator Implementation Guide
1. Technical Architecture Overview
1.1 Resource Zome Data Model
The resource zome operates as a pure data model responsible for:
- Resource specification management
- Economic resource lifecycle operations
- Data persistence and retrieval
- Discovery and query functions
Key Characteristics:
- No business logic or validation rules
- Pure CRUD operations on data structures
- Cross-zome calls for governance decisions
- Event generation after approved changes
1.2 Governance Zome Operator Functions
The governance zome operates as a state transition operator responsible for:
- Evaluating governance rules and policies
- Validating agent permissions and roles
- Authorizing or rejecting state transitions
- Generating economic events for audit trails
Key Characteristics:
- Pure function evaluation logic
- No direct data persistence
- Comprehensive validation frameworks
- Integration with reputation system
1.3 Cross-Zome Communication Patterns
Communication follows the operator pattern with these key patterns:
-
Request-Evaluate-Apply Pattern
- Resource zome requests state change
- Governance zome evaluates and decides
- Resource zome applies approved changes
-
Event-Driven Auditing
- Every state transition generates economic events
- Complete audit trail maintained
- Reputation system integration
-
Error Handling Propagation
- Clear error boundaries between zomes
- Graceful degradation when governance unavailable
- Comprehensive error reporting
2. Implementation Details
2.1 Cross-Zome Interface Implementation
Resource Zome Implementation:
#![allow(unused)] fn main() { use crate::ResourceError; use hdk::prelude::*; use zome_resource_integrity::*; use zome_gouvernance_integrity::*; // Cross-zome interface structures #[derive(Serialize, Deserialize, Debug, Clone)] pub struct GovernanceTransitionRequest { pub action: VfAction, pub resource: EconomicResource, pub requesting_agent: AgentPubKey, pub context: TransitionContext, } #[derive(Serialize, Deserialize, Debug)] pub struct GovernanceTransitionResult { pub success: bool, pub new_resource_state: Option<EconomicResource>, pub economic_event: Option<EconomicEvent>, pub validation_receipts: Vec<ValidationReceipt>, pub rejection_reasons: Option<Vec<String>>, pub next_steps: Option<Vec<String>>, } // Primary interface function for resource state changes #[hdk_extern] pub fn request_resource_transition( request: GovernanceTransitionRequest, ) -> ExternResult<GovernanceTransitionResult> { // 1. Validate input data integrity validate_transition_request(&request)?; // 2. Call governance zome for evaluation let governance_result = call( CallTargetCell::Local, "zome_gouvernance", "evaluate_state_transition".into(), None, &request, )?; // 3. Handle governance decision match governance_result.success { true => { // 3a. Apply approved state changes if let Some(new_state) = governance_result.new_resource_state.clone() { update_operational_state(new_state)?; } // 3b. Record economic event if let Some(event) = governance_result.economic_event.clone() { create_economic_event(event)?; } // 3c. Update state transition links update_state_transition_links(&request, &governance_result)?; Ok(governance_result) } false => { // 4a. Log rejection for audit trail log_governance_rejection(&request, &governance_result)?; // 4b. Return decision to caller Ok(governance_result) } } } // Validate transition request before governance evaluation fn validate_transition_request( request: &GovernanceTransitionRequest, ) -> ExternResult<()> { // Validate resource exists let _resource_record = get( get_action_hash(&request.resource)?, GetOptions::default() )?.ok_or(ResourceError::EconomicResourceNotFound( "Resource not found".to_string() ))?; // Validate agent permissions basic checks let agent_info = agent_info()?; if agent_info.agent_initial_pubkey != request.requesting_agent { return Err(ResourceError::NotAuthor.into()); } // Validate action compatibility with resource state validate_action_state_compatibility(&request.action, &request.resource.state)?; Ok(()) } // Helper function to get action hash from resource fn get_action_hash(resource: &EconomicResource) -> ExternResult<ActionHash> { // This would typically be stored alongside the resource // For implementation, this depends on how resources are tracked todo!("Implement action hash retrieval") } // Validate that action is compatible with current operational state // (LifecycleStage on NondominiumIdentity is validated separately — REQ-NDO-OS-02 deferred) fn validate_action_state_compatibility( action: &VfAction, current_operational_state: &OperationalState, ) -> ExternResult<()> { match (current_operational_state, action) { (OperationalState::PendingValidation, VfAction::Use) => { return Err(ResourceError::InvalidInput( "Cannot use resource pending validation".to_string() ).into()); } (OperationalState::Reserved, VfAction::Use) => { return Err(ResourceError::InvalidInput( "Cannot use reserved resource".to_string() ).into()); } _ => Ok(()), // Valid combination } } }
Governance Zome Implementation:
#![allow(unused)] fn main() { use hdk::prelude::*; use zome_gouvernance_integrity::*; // Governance evaluation engine #[hdk_extern] pub fn evaluate_state_transition( request: GovernanceTransitionRequest, ) -> ExternResult<GovernanceTransitionResult> { // 1. Load applicable governance rules let governance_rules = load_applicable_rules(&request.resource)?; // 2. Check agent permissions and roles let agent_permissions = check_agent_permissions( &request.requesting_agent, &request.action, )?; // 3. Evaluate state transition using pure function let evaluation = GovernanceEngine::evaluate_transition( &request, &governance_rules, &agent_permissions, )?; // 4. Generate economic event if approved let economic_event = if evaluation.allowed { Some(generate_economic_event(&request, &evaluation)?) } else { None }; // 5. Generate validation receipts let validation_receipts = generate_validation_receipts( &request, &evaluation, )?; // 6. Return comprehensive result Ok(GovernanceTransitionResult { success: evaluation.allowed, new_resource_state: evaluation.new_state, economic_event, validation_receipts, rejection_reasons: evaluation.rejection_reasons, next_steps: evaluation.next_steps, }) } // Load governance rules applicable to resource and action fn load_applicable_rules( resource: &EconomicResource, ) -> ExternResult<Vec<GovernanceRule>> { // 1. Get resource specification let spec_record = get( resource.conforms_to, GetOptions::default() )?.ok_or(GovernanceError::ResourceSpecificationNotFound)?; let spec: ResourceSpecification = spec_record.entry().ok_or( GovernanceError::InvalidEntryType )?; // 2. Get governance rules from specification let mut rules = Vec::new(); for rule_hash in spec.governance_rules { let rule_record = get(rule_hash, GetOptions::default())? .ok_or(GovernanceError::GovernanceRuleNotFound)?; let rule: GovernanceRule = rule_record.entry().ok_or( GovernanceError::InvalidEntryType )?; rules.push(rule); } // 3. Add system-wide rules rules.extend(load_system_governance_rules()?); Ok(rules) } // Check agent permissions and role requirements fn check_agent_permissions( agent_pubkey: &AgentPubKey, action: &VfAction, ) -> ExternResult<AgentPermissions> { // 1. Get agent profile and roles let agent_profile = get_agent_profile(agent_pubkey)?; let agent_roles = get_agent_roles(agent_pubkey)?; // 2. Check basic permissions let has_basic_access = agent_roles.iter() .any(|role| role.role_name == "Accountable Agent" || role.role_name == "Simple Agent"); if !has_basic_access { return Ok(AgentPermissions { allowed: false, required_roles: vec!["Accountable Agent".to_string()], role_status: "Insufficient role".to_string(), }); } // 3. Check role-specific requirements let required_roles = get_required_roles_for_action(action); let has_required_roles = required_roles.iter().all(|required_role| { agent_roles.iter().any(|role| role.role_name == *required_role) }); Ok(AgentPermissions { allowed: has_required_roles, required_roles, role_status: if has_required_roles { "Authorized".to_string() } else { "Insufficient role".to_string() }, }) } // Get roles required for specific actions fn get_required_roles_for_action(action: &VfAction) -> Vec<String> { match action { VfAction::Use => vec!["Accountable Agent".to_string()], VfAction::Transfer => vec!["Accountable Agent".to_string()], VfAction::TransferCustody => vec!["Accountable Agent".to_string()], VfAction::InitialTransfer => vec!["Simple Agent".to_string()], VfAction::Move | VfAction::Work => vec!["Transport".to_string()], VfAction::Modify => vec!["Repair".to_string()], VfAction::Consume | VfAction::Produce => vec!["Accountable Agent".to_string()], _ => vec!["Accountable Agent".to_string()], } } }
2.2 State Transition Logic
Pure Function Governance Engine:
#![allow(unused)] fn main() { pub struct GovernanceEngine; impl GovernanceEngine { /// Pure function: evaluates state transition without side effects pub fn evaluate_transition( request: &GovernanceTransitionRequest, rules: &[GovernanceRule], agent_permissions: &AgentPermissions, ) -> ExternResult<TransitionEvaluation> { // 1. Check agent permissions first if !agent_permissions.allowed { return Ok(TransitionEvaluation { allowed: false, new_state: None, required_events: vec![], validation_receipts: vec![], rejection_reasons: Some(vec![ format!("Permission denied: {}", agent_permissions.role_status) ]), next_steps: Some(vec![ "Acquire required role".to_string(), "Contact system administrator".to_string(), ]), }); } // 2. Evaluate governance rules let rule_results = evaluate_governance_rules(request, rules)?; // 3. Check if all rules passed let all_rules_passed = rule_results.iter().all(|result| result.passed); if !all_rules_passed { let failed_rules = rule_results.iter() .filter(|result| !result.passed) .collect::<Vec<_>>(); return Ok(TransitionEvaluation { allowed: false, new_state: None, required_events: vec![], validation_receipts: vec![], rejection_reasons: Some(failed_rules.iter() .map(|result| result.reason.clone()) .collect()), next_steps: Some(vec![ "Address governance rule violations".to_string(), "Modify request to comply with rules".to_string(), ]), }); } // 4. Calculate new resource state let new_state = calculate_new_state( &request.resource, &request.action, &request.context, )?; // 5. Determine required events let required_events = generate_required_events(&request.action); Ok(TransitionEvaluation { allowed: true, new_state: Some(new_state), required_events, validation_receipts: vec![], rejection_reasons: None, next_steps: None, }) } } #[derive(Debug)] pub struct TransitionEvaluation { pub allowed: bool, pub new_state: Option<EconomicResource>, pub required_events: Vec<String>, pub validation_receipts: Vec<ValidationReceipt>, pub rejection_reasons: Option<Vec<String>>, pub next_steps: Option<Vec<String>>, } #[derive(Debug)] pub struct AgentPermissions { pub allowed: bool, pub required_roles: Vec<String>, pub role_status: String, } #[derive(Debug)] pub struct RuleEvaluationResult { pub rule_hash: ActionHash, pub rule_type: String, pub passed: bool, pub reason: String, } // Evaluate all applicable governance rules fn evaluate_governance_rules( request: &GovernanceTransitionRequest, rules: &[GovernanceRule], ) -> ExternResult<Vec<RuleEvaluationResult>> { let mut results = Vec::new(); for rule in rules { let result = evaluate_single_rule(request, rule)?; results.push(result); } Ok(results) } // Evaluate a single governance rule fn evaluate_single_rule( request: &GovernanceTransitionRequest, rule: &GovernanceRule, ) -> ExternResult<RuleEvaluationResult> { let rule_hash = hash_entry(rule)?; let (passed, reason) = match rule.rule_type.as_str() { "access_requirement" => evaluate_access_requirement(request, rule)?, "usage_limit" => evaluate_usage_limit(request, rule)?, "transfer_conditions" => evaluate_transfer_conditions(request, rule)?, "custody_requirement" => evaluate_custody_requirement(request, rule)?, "location_restriction" => evaluate_location_restriction(request, rule)?, _ => (true, "Unknown rule type, auto-approving".to_string()), }; Ok(RuleEvaluationResult { rule_hash, rule_type: rule.rule_type.clone(), passed, reason, }) } }
2.3 Economic Event Generation
Event Generation Logic:
#![allow(unused)] fn main() { // Generate economic events for approved transitions fn generate_economic_event( request: &GovernanceTransitionRequest, evaluation: &TransitionEvaluation, ) -> ExternResult<EconomicEvent> { Ok(EconomicEvent { action: request.action.clone(), provider: request.resource.custodian, receiver: request.requesting_agent.clone(), resource_inventoried_as: Some(request.resource.conforms_to), affects: get_action_hash(&request.resource)?, resource_quantity: calculate_quantity_change( &request.resource, &request.action, &request.context, )?, event_time: sys_time()?, note: Some(format!( "State transition: {:?} approved", request.action )), }) } // Calculate quantity changes for different actions fn calculate_quantity_change( resource: &EconomicResource, action: &VfAction, context: &TransitionContext, ) -> ExternResult<f64> { match action { VfAction::Produce => { context.quantity_change.unwrap_or(1.0) } VfAction::Consume => { -context.quantity_change.unwrap_or(resource.quantity) } VfAction::Raise => { context.quantity_change.unwrap_or(0.0) } VfAction::Lower => { -context.quantity_change.unwrap_or(0.0) } _ => 0.0, // No quantity change for transfer, move, use, etc. } } // Generate required events based on action type fn generate_required_events(action: &VfAction) -> Vec<String> { match action { VfAction::Transfer | VfAction::InitialTransfer => { vec!["CustodyTransfer".to_string(), "ReceiptGeneration".to_string()] } VfAction::Use => { vec!["ResourceUse".to_string(), "ServiceProcess".to_string()] } VfAction::Move => { vec!["ResourceTransport".to_string(), "LocationChange".to_string()] } VfAction::Modify => { vec!["ResourceRepair".to_string(), "StateChange".to_string()] } _ => vec![], } } }
2.4 Error Handling Patterns
Comprehensive Error Handling:
#![allow(unused)] fn main() { #[derive(Debug, thiserror::Error)] pub enum GovernanceOperatorError { #[error("Permission denied: {0}")] PermissionDenied(String), #[error("Rule violation: {0}")] RuleViolation(String), #[error("Invalid state transition: {0}")] InvalidStateTransition(String), #[error("Cross-zome communication failed: {0}")] CrossZomeError(String), #[error("Data validation failed: {0}")] ValidationError(String), } // Error handling wrapper for cross-zome calls pub fn handle_governance_call<T>( call_result: Result<T, WasmError>, fallback_action: Option<T>, ) -> Result<T, GovernanceOperatorError> { match call_result { Ok(result) => Ok(result), Err(wasm_error) => { error!("Governance call failed: {:?}", wasm_error); match fallback_action { Some(fallback) => { warn!("Using fallback action due to governance unavailability"); Ok(fallback) } None => { Err(GovernanceOperatorError::CrossZomeError( wasm_error.to_string() )) } } } } } // Resource zome error handling with fallback #[hdk_extern] pub fn request_resource_transition_with_fallback( request: GovernanceTransitionRequest, ) -> ExternResult<GovernanceTransitionResult> { // Try governance evaluation let governance_result = handle_governance_call( call( CallTargetCell::Local, "zome_gouvernance", "evaluate_state_transition".into(), None, &request, ), Some(create_fallback_approval(&request)), )?; // Apply changes if approved if governance_result.success { apply_approved_changes(&request, &governance_result)?; } Ok(governance_result) } // Fallback approval for when governance is unavailable fn create_fallback_approval(request: &GovernanceTransitionRequest) -> GovernanceTransitionResult { match request.action { VfAction::Use | VfAction::Transfer => { // Allow basic actions without governance GovernanceTransitionResult { success: true, new_resource_state: Some(request.resource.clone()), economic_event: Some(create_basic_event(request)), validation_receipts: vec![], rejection_reasons: None, next_steps: Some(vec![ "Governance validation pending".to_string(), "Manual review recommended".to_string(), ]), } } _ => { // Reject complex actions without governance GovernanceTransitionResult { success: false, new_resource_state: None, economic_event: None, validation_receipts: vec![], rejection_reasons: Some(vec![ "Governance service unavailable".to_string(), "Complex action requires governance approval".to_string(), ]), next_steps: Some(vec![ "Retry later".to_string(), "Contact system administrator".to_string(), ]), } } } } }
3. Code Examples
3.1 Resource State Transitions
Complete Resource Transfer Example:
#![allow(unused)] fn main() { // Transfer custody of a resource pub async fn transfer_resource_example() -> Result<(), Box<dyn std::error::Error>> { let agent = Agent::new().await?; // 1. Create transfer request let transfer_request = GovernanceTransitionRequest { action: VfAction::TransferCustody, resource: get_resource("resource_hash").await?, requesting_agent: agent.agent_pubkey().clone(), context: TransitionContext { target_custodian: Some("new_custodian_pubkey".parse()?), process_notes: Some("Resource transfer for maintenance".to_string()), ..Default::default() }, }; // 2. Request state transition let result: GovernanceTransitionResult = agent.call( "request_resource_transition", transfer_request, ).await?; // 3. Handle result if result.success { println!("Transfer approved"); if let Some(event) = result.economic_event { println!("Economic event generated: {:?}", event); } } else { println!("Transfer rejected: {:?}", result.rejection_reasons); } Ok(()) } }
3.2 Governance Rule Evaluation
Custom Rule Implementation:
#![allow(unused)] fn main() { // Example: Location-based access rule fn evaluate_location_restriction( request: &GovernanceTransitionRequest, rule: &GovernanceRule, ) -> ExternResult<(bool, String)> { // Parse rule parameters let rule_params: LocationRuleParams = serde_json::from_str(&rule.rule_data)?; // Get current resource location let current_location = request.resource.current_location.as_deref().unwrap_or(""); // Check if action requires location compliance let requires_location_check = matches!(request.action, VfAction::Use | VfAction::Transfer | VfAction::Move ); if !requires_location_check { return Ok((true, "Location restriction not applicable".to_string())); } // Check if current location is in allowed list let location_allowed = rule_params.allowed_locations.contains(¤t_location.to_string()); if location_allowed { Ok((true, format!("Location '{}' is allowed", current_location))) } else { Ok((false, format!( "Location '{}' not in allowed locations: {:?}", current_location, rule_params.allowed_locations ))) } } #[derive(Deserialize)] struct LocationRuleParams { allowed_locations: Vec<String>, requires_approval: bool, notification_required: bool, } }
3.3 Economic Event Generation
Complex Event Generation:
#![allow(unused)] fn main() { // Generate events for multi-step process chains pub fn generate_process_chain_events( request: &GovernanceTransitionRequest, process_chain: &Vec<VfAction>, ) -> ExternResult<Vec<EconomicEvent>> { let mut events = Vec::new(); let mut current_resource = request.resource.clone(); for (index, action) in process_chain.iter().enumerate() { let event = EconomicEvent { action: action.clone(), provider: current_resource.custodian, receiver: request.requesting_agent.clone(), resource_inventoried_as: Some(current_resource.conforms_to), affects: get_action_hash(¤t_resource)?, resource_quantity: calculate_quantity_for_action(action, ¤t_resource)?, event_time: sys_time()?, note: Some(format!( "Step {} of process chain: {:?}", index + 1, action )), }; events.push(event); // Update resource state for next step current_resource = apply_action_to_resource(¤t_resource, action)?; } Ok(events) } }
3.4 Complete Workflow Examples
End-to-End Resource Lifecycle:
#![allow(unused)] fn main() { // Complete example: Resource creation through use pub async fn complete_resource_lifecycle() -> Result<(), Box<dyn std::error::Error>> { let agent = Agent::new().await?; // Step 1: Create resource specification let spec_hash = agent.call::<ActionHash>( "create_resource_spec", CreateResourceSpecInput { name: "3D Printer".to_string(), description: "Industrial 3D printer for prototyping".to_string(), category: "Equipment".to_string(), governance_rules: vec![create_usage_limit_rule()], }, ).await?; // Step 2: Create economic resource let resource_hash = agent.call::<CreateResourceOutput>( "create_economic_resource", EconomicResourceInput { spec_hash, quantity: 1.0, unit: "unit".to_string(), current_location: Some("Workshop A".to_string()), }, ).await?.resource_hash; // Step 3: Use resource (requires governance approval) let use_result: GovernanceTransitionResult = agent.call( "request_resource_transition", GovernanceTransitionRequest { action: VfAction::Use, resource: get_resource(resource_hash).await?, requesting_agent: agent.agent_pubkey().clone(), context: TransitionContext { process_notes: Some("Prototype development".to_string()), ..Default::default() }, }, ).await?; // Step 4: Handle result match use_result.success { true => { println!("Resource use approved"); // Step 5: Record usage completion if let Some(event) = use_result.economic_event { let _completion_receipt = agent.call::<ActionHash>( "record_usage_completion", event, ).await?; } } false => { println!("Resource use denied: {:?}", use_result.rejection_reasons); } } Ok(()) } }
4. Testing Patterns
4.1 Mock Governance for Resource Testing
Mock Implementation for Testing:
#![allow(unused)] fn main() { #[cfg(test)] pub struct MockGovernanceEngine { approval_mode: ApprovalMode, rule_results: HashMap<String, bool>, } #[derive(Debug, Clone)] pub enum ApprovalMode { ApproveAll, RejectAll, RoleBased(Vec<String>), Conditional(Box<dyn Fn(&GovernanceTransitionRequest) -> bool>), RuleBased(HashMap<String, bool>), } impl MockGovernanceEngine { pub fn evaluate_transition( &self, request: GovernanceTransitionRequest, ) -> ExternResult<GovernanceTransitionResult> { let approved = match &self.approval_mode { ApprovalMode::ApproveAll => true, ApprovalMode::RejectAll => false, ApprovalMode::RoleBased(allowed_roles) => { // Mock role checking allowed_roles.contains(&"Accountable Agent".to_string()) } ApprovalMode::Conditional(validator) => validator(&request), ApprovalMode::RuleBased(results) => { // Mock rule evaluation self.rule_results.values().all(|&result| *result) } }; let new_state = if approved { Some(calculate_new_state(&request)) } else { None }; Ok(GovernanceTransitionResult { success: approved, new_resource_state, economic_event: if approved { Some(generate_test_event(&request)) } else { None }, validation_receipts: vec![], rejection_reasons: if approved { None } else { Some(vec!["Mock rejection".to_string()]) }, next_steps: None, }) } } }
Testing Resource Zome with Mock Governance:
#![allow(unused)] fn main() { #[cfg(test)] mod resource_tests { use super::*; #[tokio::test] async fn test_resource_creation_with_mock_governance() { let mock_engine = MockGovernanceEngine { approval_mode: ApprovalMode::ApproveAll, rule_results: HashMap::new(), }; // Create test request let create_request = GovernanceTransitionRequest { action: VfAction::Produce, resource: create_test_resource(), requesting_agent: create_test_agent(), context: TransitionContext { quantity_change: Some(1.0), ..Default::default() }, }; // Test with mock governance let result = mock_engine.evaluate_transition(create_request).unwrap(); assert!(result.success); assert!(result.new_resource_state.is_some()); assert!(result.economic_event.is_some()); } #[tokio::test] async fn test_role_based_rejection() { let mock_engine = MockGovernanceEngine { approval_mode: ApprovalMode::RoleBased(vec!["Transport".to_string()]), rule_results: HashMap::new(), }; let repair_request = GovernanceTransitionRequest { action: VfAction::Modify, // Requires Repair role resource: create_test_resource(), requesting_agent: create_test_agent_with_role("Transport".to_string()), context: Default::default(), }; let result = mock_engine.evaluate_transition(repair_request).unwrap(); assert!(!result.success); assert!(result.rejection_reasons.is_some()); assert!(result.rejection_reasons.unwrap().iter() .any(|reason| reason.contains("Insufficient role"))); } } }
4.2 Governance Logic Unit Testing
Pure Function Testing:
#![allow(unused)] fn main() { #[cfg(test)] mod governance_tests { use super::*; #[test] fn test_permission_evaluation() { let agent_permissions = AgentPermissions { allowed: true, required_roles: vec!["Accountable Agent".to_string()], role_status: "Authorized".to_string(), }; let evaluation = TransitionEvaluation { allowed: true, new_state: None, required_events: vec![], validation_receipts: vec![], rejection_reasons: None, next_steps: None, }; assert!(agent_permissions.allowed); assert_eq!(agent_permissions.required_roles.len(), 1); assert!(evaluation.allowed); } #[test] fn test_rule_evaluation() { let rule = GovernanceRule { rule_type: "access_requirement".to_string(), rule_data: r#"{"min_agent_level": "Accountable Agent"}"#.to_string(), enforced_by: None, created_by: AgentPubKey::random(), created_at: sys_time().unwrap(), }; let request = create_test_request(); let result = evaluate_single_rule(&request, &rule).unwrap(); assert!(result.passed); assert_eq!(result.rule_type, "access_requirement"); } #[test] fn test_state_transition_validation() { let resource = EconomicResource { conforms_to: ActionHash::random(), quantity: 1.0, unit: "unit".to_string(), custodian: AgentPubKey::random(), created_by: AgentPubKey::random(), created_at: sys_time().unwrap(), current_location: Some("Workshop".to_string()), operational_state: OperationalState::Available, }; // Valid transition assert!(validate_action_state_compatibility( &VfAction::Transfer, &resource.operational_state ).is_ok()); // Invalid transition assert!(validate_action_state_compatibility( &VfAction::Use, &OperationalState::Reserved ).is_err()); } } }
4.3 Cross-Zome Integration Testing
Integration Test Setup:
#![allow(unused)] fn main() { #[cfg(test)] mod integration_tests { use super::*; #[tokio::test] async fn test_end_to_end_state_transition() { // Setup test environment let test_env = TestEnvironment::new().await; let resource_agent = test_env.create_agent("resource_owner").await; let request_agent = test_env.create_agent("requester").await; // Create test resource let resource_hash = resource_agent.call::<ActionHash>( "create_economic_resource", EconomicResourceInput { spec_hash: create_test_spec(), quantity: 1.0, unit: "unit".to_string(), current_location: Some("Test Location".to_string()), }, ).await; // Request state transition let transfer_request = GovernanceTransitionRequest { action: VfAction::Transfer, resource: resource_agent.call::<EconomicResource>( "get_economic_resource", resource_hash, ).await, requesting_agent: request_agent.agent_pubkey().clone(), context: TransitionContext { target_custodian: Some(request_agent.agent_pubkey().clone()), ..Default::default() }, }; // Process through resource zome let result: GovernanceTransitionResult = resource_agent.call( "request_resource_transition", transfer_request, ).await; // Verify outcome assert!(result.success); assert!(result.economic_event.is_some()); // Verify state changed in DHT let updated_resource = resource_agent.call::<EconomicResource>( "get_economic_resource", resource_hash, ).await; assert_eq!(updated_resource.custodian, request_agent.agent_pubkey()); } #[tokio::test] async fn test_governance_rule_enforcement() { let test_env = TestEnvironment::new().await; let agent = test_env.create_agent("test_agent").await; // Create resource with strict governance rules let spec_hash = agent.call::<ActionHash>( "create_resource_spec", CreateResourceSpecInput { name: "Restricted Resource".to_string(), description: "Resource with strict access rules".to_string(), category: "Restricted".to_string(), governance_rules: vec![ GovernanceRule { rule_type: "access_requirement".to_string(), rule_data: r#"{"requires_approval": true, "min_agent_level": "Accountable Agent"}"#.to_string(), enforced_by: Some("System".to_string()), created_by: AgentPubKey::random(), created_at: sys_time().unwrap(), } ], }, ).await; // Create resource let resource_hash = agent.call::<ActionHash>( "create_economic_resource", EconomicResourceInput { spec_hash, quantity: 1.0, unit: "unit".to_string(), current_location: Some("Test Location".to_string()), }, ).await; // Try to use resource with Simple Agent role let simple_agent = test_env.create_simple_agent("simple_agent").await; let use_request = GovernanceTransitionRequest { action: VfAction::Use, resource: agent.call::<EconomicResource>( "get_economic_resource", resource_hash, ).await, requesting_agent: simple_agent.agent_pubkey().clone(), context: Default::default(), }; let result: GovernanceTransitionResult = agent.call( "request_resource_transition", use_request, ).await; // Should be rejected due to insufficient role assert!(!result.success); assert!(result.rejection_reasons.is_some()); } } }
5. Performance Considerations
5.1 Cross-Zome Call Optimization
Batch Processing Pattern:
#![allow(unused)] fn main() { // Process multiple state transitions efficiently #[hdk_extern] pub fn batch_state_transitions( requests: Vec<GovernanceTransitionRequest>, ) -> ExternResult<Vec<GovernanceTransitionResult>> { // Group requests by resource specification for efficient rule loading let mut grouped_requests: HashMap<ActionHash, Vec<GovernanceTransitionRequest>> = HashMap::new(); for request in requests { let spec_hash = request.resource.conforms_to; grouped_requests.entry(spec_hash) .or_insert_with(Vec::new) .push(request); } // Process each group let mut all_results = Vec::new(); for (spec_hash, group_requests) in grouped_requests { // Load governance rules once per group let governance_rules = load_governance_rules_for_spec(&spec_hash)?; // Process all requests in the group let group_results = process_request_group(group_requests, &governance_rules)?; all_results.extend(group_results); } Ok(all_results) } }
5.2 State Management Efficiency
Lazy Loading and Caching:
#![allow(unused)] fn main() { use std::collections::HashMap; use lru::LruCache; pub struct EfficientGovernanceEngine { rule_cache: LruCache<ActionHash, Vec<GovernanceRule>>, permission_cache: LruCache<AgentPubKey, AgentPermissions>, cache_ttl: Duration, } impl EfficientGovernanceEngine { pub fn new() -> Self { Self { rule_cache: LruCache::new(std::num::NonZeroUsize::new(100)), permission_cache: LruCache::new(std::num::NonZeroUsize::new(200)), cache_ttl: Duration::from_secs(300), // 5 minutes } } pub fn get_rules_cached( &mut self, spec_hash: &ActionHash, ) -> ExternResult<&Vec<GovernanceRule>> { let cache_key = spec_hash.clone(); if !self.rule_cache.contains(&cache_key) { let rules = load_governance_rules_for_spec(spec_hash)?; self.rule_cache.put(cache_key, rules); } Ok(self.rule_cache.get(&cache_key).unwrap()) } pub fn get_permissions_cached( &mut self, agent_pubkey: &AgentPubKey, action: &VfAction, ) -> ExternResult<&AgentPermissions> { let cache_key = format!("{}-{:?}", agent_pubkey, action); let cache_key_hash = hash_string(&cache_key); if !self.permission_cache.contains(&cache_key_hash) { let permissions = check_agent_permissions(agent_pubkey, action)?; self.permission_cache.put(cache_key_hash, permissions); } Ok(self.permission_cache.get(&cache_key_hash).unwrap()) } } }
This implementation guide provides comprehensive technical details for implementing the governance-as-operator architecture, with practical examples, testing patterns, and performance optimizations for production deployment.
Cross-Zome API Specification
Implementation status (2026-08-29, post-#132).
GovernanceTransitionRequest,TransitionContext, andGovernanceTransitionResultare defined incrates/shared/src/io/governance.rs, andevaluate_state_transitionis live inzome_gouvernance/src/transition.rs.request_resource_transitiondoes not exist: the resource zome does not yet call into this path, so evaluation runs parallel and advisory alongsidepropose_commitment/log_economic_eventrather than as the mandatory funnel. Treat the request side of this document as the design target, not current behaviour. Status:documentation/IMPLEMENTATION_STATUS.md§ Governance-as-Operator Architecture.
Cross-zome contracts described here reflect the MVP split: zome_resource holds data; zome_gouvernance evaluates transitions. Post-MVP, typed rules for Unyt (EconomicAgreement, RAVE) and Flowsta (IdentityVerification) are specified in documentation/requirements/ndo_prima_materia.md §§6.6–6.7 and the integration stubs under documentation/requirements/post-mvp/ — see also governance-operator-architecture.md §1.3.
1. Resource Zome API
1.1 Data Access Functions
get_economic_resource
Retrieves a specific economic resource by its action hash.
#![allow(unused)] fn main() { #[hdk_extern] pub fn get_economic_resource( resource_hash: ActionHash, ) -> ExternResult<EconomicResource> }
Parameters:
resource_hash: ActionHash- The action hash of the resource to retrieve
Returns:
EconomicResource- The resource data structure
Errors:
WasmErrorGuest- If resource not found or access denied
Example:
#![allow(unused)] fn main() { let resource = call( CallTargetCell::Local, "zome_resource", "get_economic_resource".into(), None, &resource_hash, )?; }
get_economic_resource_with_state
Retrieves resource with full state transition history.
#![allow(unused)] fn main() { #[hdk_extern] pub fn get_economic_resource_with_state( resource_hash: ActionHash, ) -> ExternResult<ResourceWithState> }
Parameters:
resource_hash: ActionHash- Resource action hash
Returns:
ResourceWithState- Resource with state history
1.2 State Change Requests
request_resource_transition
Primary interface for requesting state changes through governance evaluation.
#![allow(unused)] fn main() { #[hdk_extern] pub fn request_resource_transition( request: GovernanceTransitionRequest, ) -> ExternResult<GovernanceTransitionResult> }
Parameters:
request: GovernanceTransitionRequest- Complete transition request
Returns:
GovernanceTransitionResult- Governance decision and results
Request Structure:
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct GovernanceTransitionRequest { /// The action the requesting agent wants to perform pub action: VfAction, /// Current state of the resource being modified pub resource: EconomicResource, /// Agent requesting the state change pub requesting_agent: AgentPubKey, /// Additional context for the transition pub context: TransitionContext, } }
Result Structure:
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug)] pub struct GovernanceTransitionResult { /// Whether the transition was approved pub success: bool, /// Updated resource state (if approved) pub new_resource_state: Option<EconomicResource>, /// Generated economic event for audit trail pub economic_event: Option<EconomicEvent>, /// Validation receipts from governance evaluation pub validation_receipts: Vec<ValidationReceipt>, /// Detailed reasons for rejection (if applicable) pub rejection_reasons: Option<Vec<String>>, /// Required next steps or additional validation needed pub next_steps: Option<Vec<String>>, } }
batch_state_transitions
Process multiple state transitions efficiently in a single call.
#![allow(unused)] fn main() { #[hdk_extern] pub fn batch_state_transitions( requests: Vec<GovernanceTransitionRequest>, ) -> ExternResult<Vec<GovernanceTransitionResult>> }
Parameters:
requests: Vec<GovernanceTransitionRequest>- Multiple transition requests
Returns:
Vec<GovernanceTransitionResult>- Results for each request in order
1.3 Query Functions
get_my_resources
Retrieves all resources where the calling agent is the custodian.
#![allow(unused)] fn main() { #[hdk_extern] pub fn get_my_resources() -> ExternResult<Vec<EconomicResource>> }
Returns:
Vec<EconomicResource>- Resources owned by the calling agent
get_resources_by_specification
Retrieves all resources conforming to a specific specification.
#![allow(unused)] fn main() { #[hdk_extern] pub fn get_resources_by_specification( spec_hash: ActionHash, ) -> ExternResult<Vec<EconomicResource>> }
Parameters:
spec_hash: ActionHash- Specification action hash
Returns:
Vec<EconomicResource>- Resources conforming to the specification
get_resources_by_operational_state
Retrieves resources in a specific operational state.
#![allow(unused)] fn main() { #[hdk_extern] pub fn get_resources_by_operational_state( state: OperationalState, ) -> ExternResult<Vec<Record>> }
Parameters:
state: OperationalState- Operational state to filter by
Returns:
Vec<Record>- Economic resource records in the specified operational state
Lifecycle maturity queries use
get_ndos_by_lifecycle_stageon Layer 0 (NdoByLifecycleStage), not economic-resource links.
2. Governance Zome API
2.1 State Transition Evaluation
evaluate_state_transition
Evaluates a state transition request and returns governance decision.
#![allow(unused)] fn main() { #[hdk_extern] pub fn evaluate_state_transition( request: GovernanceTransitionRequest, ) -> ExternResult<GovernanceTransitionResult> }
Parameters:
request: GovernanceTransitionRequest- Transition request to evaluate
Returns:
GovernanceTransitionResult- Governance evaluation result
Evaluation Process:
- Load applicable governance rules
- Check agent permissions and roles
- Evaluate all applicable rules
- Determine if transition is allowed
- Generate economic events if approved
2.2 Rule Processing
get_applicable_rules
Retrieves governance rules applicable to a specific resource and action.
#![allow(unused)] fn main() { #[hdk_extern] pub fn get_applicable_rules( resource_hash: ActionHash, action: VfAction, ) -> ExternResult<Vec<GovernanceRule>> }
Parameters:
resource_hash: ActionHash- Resource to get rules foraction: VfAction- Action being performed
Returns:
Vec<GovernanceRule>- Applicable governance rules
evaluate_rule
Evaluates a single governance rule against a transition request.
#![allow(unused)] fn main() { #[hdk_extern] pub fn evaluate_rule( request: GovernanceTransitionRequest, rule_hash: ActionHash, ) -> ExternResult<RuleEvaluationResult> }
Parameters:
request: GovernanceTransitionRequest- Transition requestrule_hash: ActionHash- Rule to evaluate
Returns:
RuleEvaluationResult- Rule evaluation result
2.3 Economic Event Generation
generate_economic_event
Generates an economic event for a completed state transition.
#![allow(unused)] fn main() { #[hdk_extern] pub fn generate_economic_event( request: GovernanceTransitionRequest, evaluation_result: &TransitionEvaluation, ) -> ExternResult<EconomicEvent> }
Parameters:
request: GovernanceTransitionRequest- Original transition requestevaluation_result: TransitionEvaluation- Internal evaluation result
Returns:
EconomicEvent- Generated economic event
2.4 Agent Permission Management
check_agent_permissions
Checks if an agent has permission to perform a specific action.
#![allow(unused)] fn main() { #[hdk_extern] pub fn check_agent_permissions( agent_pubkey: AgentPubKey, action: VfAction, ) -> ExternResult<AgentPermissions> }
Parameters:
agent_pubkey: AgentPubKey- Agent to check permissions foraction: VfAction- Action to check permissions for
Returns:
AgentPermissions- Permission check results
get_agent_roles
Retrieves all roles assigned to an agent.
#![allow(unused)] fn main() { #[hdk_extern] pub fn get_agent_roles( agent_pubkey: AgentPubKey, ) -> ExternResult<Vec<Role>> }
Parameters:
agent_pubkey: AgentPubKey- Agent to get roles for
Returns:
Vec<Role>- Agent's assigned roles
3. Interface Types
3.1 Request/Response Structures
GovernanceTransitionRequest
Complete request for state transition evaluation.
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct GovernanceTransitionRequest { /// The action the requesting agent wants to perform pub action: VfAction, /// Current state of the resource being modified pub resource: EconomicResource, /// Agent requesting the state change pub requesting_agent: AgentPubKey, /// Additional context for the transition pub context: TransitionContext, } }
TransitionContext
Additional context information for state transitions.
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone, Default)] pub struct TransitionContext { /// Target location for transport/move actions pub target_location: Option<String>, /// Quantity change for produce/consume actions pub quantity_change: Option<f64>, /// Target custodian for transfer actions pub target_custodian: Option<AgentPubKey>, /// Process notes and observations pub process_notes: Option<String>, /// Associated economic process if applicable pub process_context: Option<ActionHash>, /// Additional metadata pub metadata: HashMap<String, String>, } }
GovernanceTransitionResult
Comprehensive result from governance evaluation.
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug)] pub struct GovernanceTransitionResult { /// Whether the transition was approved pub success: bool, /// Updated resource state (if approved) pub new_resource_state: Option<EconomicResource>, /// Generated economic event for audit trail pub economic_event: Option<EconomicEvent>, /// Validation receipts from governance evaluation pub validation_receipts: Vec<ValidationReceipt>, /// Detailed reasons for rejection (if applicable) pub rejection_reasons: Option<Vec<String>>, /// Required next steps or additional validation needed pub next_steps: Option<Vec<String>>, /// Processing metadata pub metadata: TransitionMetadata, } }
TransitionMetadata
Metadata about the transition processing.
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug)] pub struct TransitionMetadata { /// Timestamp when evaluation started pub evaluation_started: Timestamp, /// Timestamp when evaluation completed pub evaluation_completed: Timestamp, /// Number of rules evaluated pub rules_evaluated: u32, /// Processing duration in milliseconds pub processing_duration_ms: u64, /// Governance engine version pub engine_version: String, } }
3.2 Validation Structures
RuleEvaluationResult
Result of evaluating a single governance rule.
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug)] pub struct RuleEvaluationResult { /// Hash of the evaluated rule pub rule_hash: ActionHash, /// Type of governance rule pub rule_type: String, /// Whether the rule was passed pub passed: bool, /// Detailed reason for evaluation result pub reason: String, /// Rule-specific evaluation data pub evaluation_data: Option<serde_json::Value>, /// Timestamp of evaluation pub evaluated_at: Timestamp, } }
AgentPermissions
Permission check results for agent and action.
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug)] pub struct AgentPermissions { /// Whether the permission was granted pub allowed: bool, /// Roles required for this action pub required_roles: Vec<String>, /// Current status of permission check pub status: String, /// Permission expiration (if applicable) pub expires_at: Option<Timestamp>, /// Additional permission constraints pub constraints: Vec<String>, } }
3.3 Error Handling
GovernanceError
Comprehensive error types for governance operations.
#![allow(unused)] fn main() { #[derive(Debug, thiserror::Error, Serialize, Deserialize)] pub enum GovernanceError { #[error("Permission denied: {0}")] PermissionDenied(String), #[error("Rule violation: {0}")] RuleViolation(String), #[error("Invalid state transition: {0}")] InvalidStateTransition(String), #[error("Agent not found: {0}")] AgentNotFound(String), #[error("Resource not found: {0}")] ResourceNotFound(String), #[error("Governance rule not found: {0}")] GovernanceRuleNotFound(String), #[error("Insufficient role: {0}")] InsufficientRole(String), #[error("Evaluation timeout: {0}ms")] EvaluationTimeout(u64), #[error("Cross-zome communication failed: {0}")] CrossZomeError(String), #[error("Data validation failed: {0}")] ValidationError(String), #[error("Configuration error: {0}")] ConfigurationError(String), } }
4. Usage Examples
4.1 Basic Resource Transfer
// TypeScript (Frontend) example
const transferResource = async (
resourceHash: string,
newCustodian: string,
notes: string
) => {
const request: GovernanceTransitionRequest = {
action: "TransferCustody",
resource: await getResource(resourceHash),
requestingAgent: await getMyAgentPubKey(),
context: {
targetCustodian: newCustodian,
processNotes: notes,
},
};
const result = await callZome<GovernanceTransitionResult>(
"zome_resource",
"request_resource_transition",
request
);
if (result.success) {
console.log("Transfer approved");
return result;
} else {
console.log("Transfer rejected:", result.rejectionReasons);
throw new Error("Transfer failed");
}
};
4.2 Complex Process Chain
#![allow(unused)] fn main() { // Rust backend example for process chaining pub async fn execute_transport_repair_chain( resource_hash: ActionHash, repair_location: String, final_destination: String, ) -> ExternResult<Vec<EconomicEvent>> { let agent_info = agent_info()?; let resource = get_economic_resource(resource_hash)?; // Step 1: Transport to repair location let transport_request = GovernanceTransitionRequest { action: VfAction::Move, resource: resource.clone(), requesting_agent: agent_info.agent_initial_pubkey, context: TransitionContext { target_location: Some(repair_location), process_notes: Some("Transport for repair".to_string()), ..Default::default() }, }; let transport_result = request_resource_transition(transport_request)?; if !transport_result.success { return Err(GovernanceError::RuleViolation( format!("Transport failed: {:?}", transport_result.rejection_reasons) ).into()); } // Step 2: Repair the resource let repair_request = GovernanceTransitionRequest { action: VfAction::Modify, resource: transport_result.new_resource_state.unwrap(), requesting_agent: agent_info.agent_initial_pubkey, context: TransitionContext { target_location: Some(repair_location), process_notes: Some("Maintenance repair".to_string()), ..Default::default() }, }; let repair_result = request_resource_transition(repair_request)?; if !repair_result.success { return Err(GovernanceError::RuleViolation( format!("Repair failed: {:?}", repair_result.rejection_reasons) ).into()); } // Step 3: Transport to final destination let final_transport_request = GovernanceTransitionRequest { action: VfAction::Move, resource: repair_result.new_resource_state.unwrap(), requesting_agent: agent_info.agent_initial_pubkey, context: TransitionContext { target_location: Some(final_destination), process_notes: Some("Transport after repair".to_string()), ..Default::default() }, }; let final_result = request_resource_transition(final_transport_request)?; if !final_result.success { return Err(GovernanceError::RuleViolation( format!("Final transport failed: {:?}", final_result.rejection_reasons) ).into()); } // Collect all generated events let mut events = Vec::new(); if let Some(event) = transport_result.economic_event { events.push(event); } if let Some(event) = repair_result.economic_event { events.push(event); } if let Some(event) = final_result.economic_event { events.push(event); } Ok(events) } }
4.3 Batch Processing
// TypeScript batch processing example
const batchUpdateResources = async (
updates: Array<{
resourceHash: string;
action: VfAction;
context: TransitionContext;
}>
) => {
const requests = updates.map(update => ({
action: update.action,
resource: await getResource(update.resourceHash),
requestingAgent: await getMyAgentPubKey(),
context: update.context,
}));
const results = await callZome<GovernanceTransitionResult[]>(
"zome_resource",
"batch_state_transitions",
requests
);
// Process results
const successful = results.filter(r => r.success);
const failed = results.filter(r => !r.success);
console.log(`Processed ${results.length} requests`);
console.log(`Successful: ${successful.length}`);
console.log(`Failed: ${failed.length}`);
if (failed.length > 0) {
console.error("Failed transitions:", failed);
}
return results;
};
5. Performance and Scalability
5.1 Rate Limiting
Rate limiting is enforced at the governance zome level:
#![allow(unused)] fn main() { // Rate limiting configuration pub const RATE_LIMITS: HashMap<&'static str, u32> = hashmap! { "evaluate_state_transition" => 100, // Per minute "check_agent_permissions" => 500, // Per minute "get_applicable_rules" => 200, // Per minute }; }
5.2 Batch Processing
For high-volume operations, use batch processing:
#![allow(unused)] fn main() { // Recommended batch sizes const OPTIMAL_BATCH_SIZE: usize = 10; const MAX_BATCH_SIZE: usize = 50; // Implementation validates and adjusts batch sizes pub fn validate_batch_size(size: usize) -> usize { if size > MAX_BATCH_SIZE { warn!("Batch size {size} exceeds maximum, truncating to {MAX_BATCH_SIZE}"); MAX_BATCH_SIZE } else { size.max(OPTIMAL_BATCH_SIZE) } } }
5.3 Caching Strategy
Cache frequently accessed data to improve performance:
#![allow(unused)] fn main() { // Cache configuration pub const CACHE_TTL_SECONDS: u64 = 300; // 5 minutes pub const RULE_CACHE_SIZE: usize = 100; pub const PERMISSION_CACHE_SIZE: usize = 200; }
This API specification provides a comprehensive reference for implementing cross-zome communication in the governance-as-operator architecture, with detailed examples and performance considerations for production deployment.
Private Participation Receipts (PPR)
Overview
Private Participation Receipts are cryptographically signed, cumulative records stored as private entries in an agent's source chain. They serve as proof of reliable participation in the nondominium network and form the foundation for a generative reputation system.
Core Principles
- Bi-directional Issuance: Receipts are issued between agents involved in each economic interaction
- Cryptographic Integrity: All receipts are cryptographically signed for authenticity
- Multi-role Support: Agents can accumulate receipts across multiple roles simultaneously
- Privacy Preservation: Receipt details remain private while enabling reputation derivation
- ValueFlows Compliance: Modeled as specialized Claims within the ValueFlows ontology
Fundamental Concepts
Commitments and Fulfillments
- Commitments: Actions (resource creation, transfer, maintenance) are formally committed by agents
- Validations: Fulfillments that confirm commitments have been properly executed
- Good Faith Usage: Users commit to honest usage practices (reporting damage, avoiding monopolization)
Receipt Generation Logic
- Two Receipts Per Action: Each economic interaction generates exactly 2 bi-directional receipts between participating agents
- Implicit Resource Validation: Resource validation is implicit through agent validation (except for creation events)
- Agent-Focused: Receipts track agent behavior and reliability, not resource state changes
TODO (G1, REQ-GOV-16 — post-MVP): The
counterpartyfield inPrivateParticipationClaimcurrently assumes an individual agent (AgentPubKey). Post-MVP, custody transfer to a collective agent (e.g., a project NDO) will requirecounterparty: AgentContext. Bot agents generate PPRs with their operator'sAgentPubKeyas the accountable counterparty.
PPR Issuance Categories
1. Genesis Role - Network Entry
Resource Creation Events
1.1 Resource Creation & Validation (Single Transaction)
- Trigger: A resource is registered on the network and validated by another agent
- Generated Receipts (2 total):
- Creator Agent: Receives "successful resource contribution" receipt
- Validator Agent: Receives "network validation performed" receipt
- Special Case: Resource creation is an event requiring explicit validation receipts, as it establishes the resource's entry into the network
2. Core Usage Role - Custodianship
Custody Transfer Events
2.1 Resource Custody Transfer
- Trigger: Resource custody is transferred between agents
- Generated Receipts (2 total):
- Outgoing Custodian: Receives "responsible custody transfer" receipt
- Incoming Custodian: Receives "custody acceptance" receipt
- Note: Resource validation is implicit through the custodian agents' reliability; no separate validation receipts needed
3. Intermediate Roles - Specialized Services
Specialized Service Receipts
Participant Structure: Involves 2 or 3 agents (original custodian, intermediate service provider, final recipient).Thus, the Resource is transferred from original custodian (User) to intermediate service provider, back to another or the same User.
3.1 Maintenance Service
- Commitment Phase: Service provider commits to maintenance duties
- Generated Receipts (2 total):
- Maintenance Agent: Receives "maintenance commitment accepted" receipt
- Custodian Agent: Receives "Good faith transfer" receipt
- Fulfillment Phase: Commitment is fulfilled through completed maintenance and resource available again
- Generated Receipts (2 total):
- Maintenance Agent: Receives "maintenance fulfillment completed" receipt
- Resource Recipient: Receives "custody acceptance" receipt
3.2 Storage Service
- Commitment Phase: Service provider commits to storage duties
- Generated Receipts (2 total):
- Storage Agent: Receives "storage commitment accepted" receipt
- Custodian Agent: Receives "Good faith transfer" receipt
- Fulfillment Phase: Commitment is fulfilled through resource custodian transfer
- Generated Receipts (2 total):
- Storage Agent: Receives "storage fulfillment completed" receipt
- Resource Recipient: Receives "custody acceptance" receipt
3.3 Transport Service
- Commitment Phase: Service provider commits to transport duties
- Generated Receipts (2 total):
- Transport Agent: Receives "transport commitment accepted" receipt
- Custodian Agent: Receives "Good faith transfer" receipt
- Fulfillment Phase: Commitment is fulfilled through completed transport and resource delivery
- Generated Receipts (2 total):
- Transport Agent: Receives "transport fulfillment completed" receipt
- Resource Recipient: Receives "custody acceptance" receipt
Role Chaining Mechanics
- Multi-role Agents: Agents can hold multiple intermediate roles simultaneously, ex. they can hold credencials for transport, maintenance and storage at the same time.
- Action Chaining: Service Agents can chain multiple actions (transport → repair → transport) within a single commitment
- Self-Managed Chains: Intermediate steps don't require external validation
- Atomic Transactions: Entire chain treated as single commitment/fulfillment cycle
Example Workflow: Transport + Repair Service
Initial State: Lynn (custodian) → Resource needs repair
Service Request: Lynn requests Bob (transport + repair credentials) to service resource
Commitment Phase:
1. Bob commits to: receive → transport → repair → transport → deliver
2. Mutual signatures create bi-directional receipts:
- Lynn → Bob: "Service commitment accepted" receipt
- Bob → Lynn: "Good faith transfer" receipt
Execution Phase:
3. Bob executes action chain without intermediate validation
4. Internal status changes (transport → repair → transport) for the resource are self-managed, pending validation.
Completion Phase:
5. Resource delivered to final recipient (Lynn or another recipient agent)
6. Final bi-directional receipts:
- Bob → Recipient: "custody acceptance" receipt
- Recipient → Bob: "Transport + Repair fulfillment completed" receipt
Additional PPR Contexts
4. Network Governance
- Dispute Resolution Participation: Receipts for constructive participation in conflict resolution
- Validation Activities: Receipts for performing validation duties beyond specific transactions
- Rule Compliance: Receipts for consistent adherence to governance protocols
5. Quality Assurance
- Economic Event Completion: Receipts for successfully completing any EconomicEvent
- Commitment Fulfillment: Receipts when claims properly link commitments to their fulfillment
- Performance Standards: Receipts for meeting or exceeding quality thresholds
ValueFlows Integration
PPRs are implemented as specialized PrivateParticipationClaim entries that extend the standard ValueFlows Claim structure:
#![allow(unused)] fn main() { pub struct PrivateParticipationClaim { // Standard ValueFlows fields pub fulfills: ActionHash, // References the commitment fulfilled pub fulfilled_by: ActionHash, // References the economic event pub claimed_at: Timestamp, // PPR-specific extensions pub claim_type: ParticipationClaimType, pub performance_metrics: PerformanceMetrics, pub bilateral_signature: CryptographicSignature, } }
This design maintains ValueFlows compliance while enabling the cumulative reputation system essential for nondominium governance.
Resource End-of-Life Management
6. Resource Decommissioning
Critical Lifecycle Completion
Resources require formal end-of-life processing to prevent abuse vectors and maintain network integrity.
6.1 Resource End-of-Life Declaration
- Trigger: Resource becomes permanently unusable, damaged beyond repair, or deliberately retired
- Security Concern: This event is a potential attack vector where agents might claim resources are "destroyed" to steal or monopolize them
- Generated Receipts (2 total):
- Declaring Agent: Receives "end-of-life declaration submitted" receipt
- Validator Agent: Receives "end-of-life validation performed" receipt
Strict Validation Requirements
To prevent end-of-life abuse:
- Multiple Validators Required: Minimum 2-3 validators must confirm end-of-life status
- The number of validators required can be adjusted based on the resource's value and sensitivity
- The declarator agent can't be a validator and even less than the disposal agent
- The validators must be experts (maintainers) that can validate the resource's condition and authenticity
- Evidence Documentation: Physical evidence (photos, inspection reports) required
- Validator Accountability: Validators become liable for false end-of-life approvals
- Historical Review: Past custodians notified and can challenge the declaration
- Time-Delayed Finalization: 7-14 day challenge period before final decommissioning
- Reputation Impact: False end-of-life declarations severely impact declaring agent's reputation
- Resource final transfer: Resource can not stay with the declaring agent. Validators can transfer the resource to a storage for broken resource in waiting for reparation attempt or definitively decommission it.
Complete Resource Lifecycle
Genesis → Active Use → Service Cycles → End-of-Life → Decommissioned
↓ ↓ ↓ ↓ ↓
Creation Transfers Maintenance Declaration Validation
Receipt Receipts Receipts Receipt Receipt
This comprehensive lifecycle ensures complete accountability from resource creation through final decommissioning, with enhanced security measures protecting against end-of-life abuse vectors.
PPR System Overview

Two sovereign agents (Agent A / Provider and Agent B / Receiver) exchange a Commitment, an Economic Event, and a Claim. Each agent stores a sealed Private PPR on their own source chain only. Both receipts feed into a derived Reputation Summary.
PPR Process Flow Diagram
flowchart TB
subgraph Genesis["Genesis Phase"]
RC["Resource Creation"]
Creator["Creator Agent"]
Validator1["Validator Agent"]
CreatorReceipt["Receipt: Resource Contribution"]
ValidatorReceipt["Receipt: Network Validation"]
RC --> Creator
RC --> Validator1
Creator --> CreatorReceipt
Validator1 --> ValidatorReceipt
end
subgraph ActiveUse["Active Use Phase"]
Transfer["Custody Transfer"]
CustodianOut["Outgoing Custodian"]
CustodianIn["Incoming Custodian"]
OutReceipt["Receipt: Responsible Transfer"]
InReceipt["Receipt: Custody Acceptance"]
Transfer --> CustodianOut
Transfer --> CustodianIn
CustodianOut --> OutReceipt
CustodianIn --> InReceipt
end
subgraph ServicePhase["Service Phase"]
ServiceCommitment["Service Commitment"]
ServiceFulfillment["Service Fulfillment"]
ServiceAgent["Service Provider"]
CustodianAgent["Custodian Agent"]
ResourceRecipient["Resource Recipient"]
CommitmentReceipt1["Receipt: Commitment Accepted"]
CommitmentReceipt2["Receipt: Good Faith Transfer"]
FulfillmentReceipt1["Receipt: Fulfillment Completed"]
FulfillmentReceipt2["Receipt: Custody Acceptance"]
ServiceCommitment --> ServiceAgent
ServiceCommitment --> CustodianAgent
ServiceAgent --> CommitmentReceipt1
CustodianAgent --> CommitmentReceipt2
ServiceFulfillment --> ServiceAgent
ServiceFulfillment --> ResourceRecipient
ServiceAgent --> FulfillmentReceipt1
ResourceRecipient --> FulfillmentReceipt2
end
subgraph EndOfLife["End-of-Life Phase"]
EOLDeclaration["End-of-Life Declaration"]
DeclaringAgent["Declaring Agent"]
ExpertValidator["Expert Validator<br/>(2-3 Required)"]
PastCustodians["Past Custodians<br/>Notification"]
ChallengePeriod["7-14 Day<br/>Challenge Period"]
FinalDisposal["Final Disposal/Storage"]
ValidationReview["Validation Review"]
EOLReceipt["Receipt: EOL Declaration"]
ValidationReceipt["Receipt: EOL Validation"]
EOLDeclaration --> DeclaringAgent
EOLDeclaration --> ExpertValidator
EOLDeclaration --> PastCustodians
ExpertValidator --> ChallengePeriod
ChallengePeriod -->|No Challenges| FinalDisposal
ChallengePeriod -->|Challenge Raised| ValidationReview
DeclaringAgent --> EOLReceipt
ExpertValidator --> ValidationReceipt
end
RC -->|Validated| Transfer
Transfer -->|May Need Service| ServiceCommitment
ServiceCommitment --> ServiceFulfillment
ServiceFulfillment -->|Return to Use| Transfer
Transfer -->|End of Lifecycle| EOLDeclaration
Key Process Features
- Bi-directional Receipts: Each economic interaction generates exactly 2 receipts between agents
- Security Constraints: Multi-validator requirement (2-3 experts) and challenge period for end-of-life restrictions
- Validation Requirements: Shows expert validators needed and time-based challenge periods
- Lifecycle Loops: Service phase can cycle multiple times during active resource utilization
- Complete Accountability: Every phase tracked with appropriate cryptographic receipts
Security Highlights
- Multi-Validator System: 2-3 expert validators required for end-of-life declarations
- Challenge Period: 7-14 day window for contesting end-of-life claims
- Past Custodian Notification: Historical custodians informed of end-of-life events
- Evidence Documentation: Physical evidence requirements for validation
- Reputation Impact: False declarations severely impact agent reputation
Post-MVP: Governance Ceremony PPRs
TODO (G6, REQ-GOV-15 — post-MVP): The
AffiliationRecordsigning ceremony generates a new PPR category. When an agent signs anAffiliationRecord(Terms of Participation, Nondominium & Custodian agreement, Benefit Redistribution Algorithm), theCommitment/EconomicEvent/Claimcycle inzome_governanceproduces anAffiliationRecordSignedPPR.
AffiliationRecordSigned PPR Properties
- Bilateral: The witness
AgentPubKeycountersigns if present at the ceremony - Non-transferable and private: Stored as a private entry; cannot be reassigned to another agent
- Affiliation trigger: The presence of this PPR is the evidence that
AffiliationStatederivation returnsActiveAffiliatefor the signing agent - New
ParticipationClaimTypevariant:AffiliationRecordSigned(seegovernance_zome.mdParticipationClaimTypefor the full TODO)
Governance Ceremony Flow (Post-MVP)
- Agent calls
create_affiliation_record()inzome_governance - A
Commitmentis created: agent commits to Terms of Participation - An
EconomicEventrecords the signing as a completed governance action - A
Claimfulfils the Commitment, producing theAffiliationRecordSignedPPR AffiliationStatederivation inzome_personreads DHT forAffiliationRecordentry → returnsActiveAffiliatefor this agent- Agent can now participate in governance processes gated by
min_affiliation: ActiveAffiliate(seeREQ-GOV-14andgovernance.md §3.6.2)
PPR System Security Implementation
Overview
This document outlines the cryptographic security enhancements implemented in the Private Participation Receipt (PPR) system to address the security recommendations from the analysis of GitHub issue #30. Note that the PPR system was inspired by Mark Lizar's work on Digital Notice Consent at the OPN lab https://github.com/0PN-lab
Security Improvements Implemented
1. Cryptographically Secure Hashing
Previous Implementation:
#![allow(unused)] fn main() { // Used non-cryptographic DefaultHasher use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; }
Enhanced Implementation:
#![allow(unused)] fn main() { // Uses BLAKE2b-256 for cryptographically secure hashing use hdk::hash::hash_blake2b; fn create_secure_hash(data: &[u8]) -> ExternResult<[u8; 32]> { // Use BLAKE2b-256 for cryptographically secure hashing (32 bytes output) let hash_output = hash_blake2b(data.to_vec(), 32)?; // Convert Vec<u8> to [u8; 32] array if hash_output.len() != 32 { return Err(wasm_error!(WasmErrorInner::Guest( "Hash output is not 32 bytes".into() ))); } let mut hash_array = [0u8; 32]; hash_array.copy_from_slice(&hash_output); Ok(hash_array) } }
Security Benefits:
- BLAKE2b is cryptographically secure and resistant to collision attacks
- 256-bit output provides excellent security margin
- Deterministic output for identical inputs
- Fast performance in WASM environment
2. Enhanced Ed25519 Signature Generation
Previous Implementation:
#![allow(unused)] fn main() { // Used placeholder signatures with minimal security fn create_placeholder_signature() -> ExternResult<Signature> { let agent_info = agent_info()?; let placeholder_data = b"placeholder_signature_data"; sign(agent_info.agent_initial_pubkey, placeholder_data.to_vec()) } }
Enhanced Implementation:
#![allow(unused)] fn main() { // Uses proper Ed25519 signing with contextual data use hdk::ed25519::sign; // Create provider-specific signing context fn create_provider_signing_context( input: &IssueParticipationReceiptsInput, base_data: &[u8], ) -> ExternResult<Vec<u8>> { let mut context_data = Vec::new(); // Add role identifier for context separation context_data.extend_from_slice(b"PROVIDER_PPR_SIGNATURE"); // Add base signing data context_data.extend_from_slice(base_data); // Add provider-specific context context_data.extend_from_slice(&input.provider.get_raw_39()); context_data.extend_from_slice(&input.receiver.get_raw_39()); // Add claim type for additional context if !input.claim_types.is_empty() { context_data.extend_from_slice(format!("{:?}", input.claim_types[0]).as_bytes()); } Ok(context_data) } }
Security Benefits:
- Uses Ed25519 digital signature algorithm (industry standard)
- Context separation prevents signature reuse attacks
- Includes participant identity in signing context
- Timestamp inclusion prevents replay attacks
3. Bilateral Authentication System
Enhanced Bilateral Signature Structure:
#![allow(unused)] fn main() { pub struct CryptographicSignature { /// Signature from the agent receiving the PPR pub recipient_signature: Signature, /// Signature from the counterparty agent pub counterparty_signature: Signature, /// Hash of the data that was signed (for verification) pub signed_data_hash: [u8; 32], /// Timestamp when the signatures were created pub signed_at: Timestamp, } }
Implementation Features:
- Both parties must cryptographically sign the PPR
- Each party signs with their own private key
- Different signing contexts prevent cross-contamination
- Mutual authentication ensures non-repudiation
4. Enhanced Signature Verification
Legacy Verification (Maintained for Compatibility):
#![allow(unused)] fn main() { pub fn validate_participation_claim_signature( input: ValidateParticipationClaimSignatureInput, ) -> ExternResult<bool> { // Verify against signed data hash let owner_valid = verify_signature( input.owner.clone(), input.signature.recipient_signature.clone(), input.signature.signed_data_hash.to_vec(), )?; let counterparty_valid = verify_signature( input.counterparty.clone(), input.signature.counterparty_signature.clone(), input.signature.signed_data_hash.to_vec(), )?; Ok(owner_valid && counterparty_valid) } }
Enhanced Verification with Full Context:
#![allow(unused)] fn main() { pub fn validate_participation_claim_signature_enhanced( input: EnhancedValidateParticipationClaimSignatureInput, ) -> ExternResult<bool> { // Get verification contexts from the integrity zome let (owner_context, counterparty_context) = input.signature.get_verification_context( &input.owner, &input.counterparty, &input.original_signing_data, &input.owner_claim_type, &input.counterparty_claim_type, ); // Verify with full context reconstruction let owner_valid = verify_signature( input.owner.clone(), input.signature.recipient_signature.clone(), owner_context, )?; let counterparty_valid = verify_signature( input.counterparty.clone(), input.signature.counterparty_signature.clone(), counterparty_context, )?; Ok(owner_valid && counterparty_valid) } }
Security Architecture
Context Separation Strategy
The implementation uses context separation to prevent signature reuse and cross-contamination:
-
Role-Based Contexts:
PROVIDER_PPR_SIGNATURE: For providers of services/resourcesRECEIVER_PPR_SIGNATURE: For receivers of services/resourcesBILATERAL_PPR_CLAIM: For general bilateral claims
-
Participant Identity Integration:
- Signer's public key included in context
- Counterparty's public key included in context
- Role-specific claim types included
-
Temporal Protection:
- Timestamp inclusion prevents replay attacks
- Each signature is temporally unique
- Clock skew tolerance through timestamp validation
Cryptographic Primitives Used
| Component | Algorithm | Key Size | Security Level |
|---|---|---|---|
| Digital Signatures | Ed25519 | 32 bytes | ~128 bits |
| Hashing | BLAKE2b | 256 bits | 256 bits |
| Key Generation | Ed25519 | 32 bytes | ~128 bits |
Security Properties Achieved
- Authenticity: Ed25519 signatures ensure message authenticity
- Integrity: BLAKE2b hashing detects any data tampering
- Non-repudiation: Both parties must sign, preventing denial
- Context Binding: Signatures tied to specific contexts
- Replay Protection: Timestamp inclusion prevents replay attacks
- Forward Security: Private keys never leave secure keystore
Testing and Validation
Cryptographic Test Suite
The implementation includes comprehensive cryptographic tests:
-
Signature Generation Tests:
- Validates unique signature generation
- Tests context separation
- Verifies timestamp inclusion
-
Hash Function Tests:
- Validates BLAKE2b deterministic output
- Tests collision resistance properties
- Verifies 256-bit output length
-
Bilateral Authentication Tests:
- Tests mutual signature validation
- Verifies counterparty authentication
- Tests signature tampering detection
-
Context Separation Tests:
- Validates different contexts produce different signatures
- Tests role-based context separation
- Verifies participant identity binding
Security Test Results
| Test Category | Test Count | Pass Rate | Security Level |
|---|---|---|---|
| Signature Generation | 5 | 100% | High |
| Hash Validation | 3 | 100% | High |
| Bilateral Auth | 4 | 100% | High |
| Context Separation | 3 | 100% | High |
| Tampering Detection | 2 | 100% | High |
Performance Impact
Cryptographic Performance Metrics
| Operation | Previous (ms) | Enhanced (ms) | Overhead |
|---|---|---|---|
| Signature Generation | ~1 | ~2-3 | 2-3x |
| Hash Generation | ~0.1 | ~0.5 | 5x |
| Signature Verification | ~1 | ~2-3 | 2-3x |
| PPR Creation | ~5 | ~10-15 | 2-3x |
Performance Optimizations
- Batch Operations: Multiple signatures processed together
- Context Caching: Signing contexts cached when possible
- Hash Reuse: Identical data hashes reused within session
- Lazy Verification: Verification only when explicitly requested
Migration Strategy
Backward Compatibility
The implementation maintains backward compatibility through:
- Legacy Verification Methods: Old verification API preserved
- Graceful Degradation: Falls back to hash-only verification if needed
- Incremental Adoption: Enhanced verification is opt-in
Migration Path
- Phase 1: Deploy enhanced cryptography alongside legacy
- Phase 2: Migrate new PPRs to enhanced signatures
- Phase 3: Gradually migrate existing PPRs (optional)
- Phase 4: Deprecate legacy methods after validation period
Security Recommendations
Production Deployment
-
Key Management:
- Ensure lair keystore is properly configured
- Regular key rotation policies
- Secure key backup procedures
-
Monitoring:
- Log signature failures for security analysis
- Monitor for unusual signature patterns
- Track verification performance metrics
-
Updates:
- Regular security updates for cryptographic libraries
- Monitor for algorithm deprecation announcements
- Implement algorithm agility for future migrations
Operational Security
-
Verification Requirements:
- Always verify signatures before trusting PPRs
- Use enhanced verification for critical operations
- Implement signature expiration policies
-
Audit Trail:
- Maintain logs of all signature operations
- Track verification results for compliance
- Regular security audits of PPR integrity
-
Incident Response:
- Procedures for handling signature failures
- Compromise detection and response
- Recovery procedures for key compromise
Future Enhancements
Planned Improvements
- Zero-Knowledge Proofs: For enhanced privacy-preserving reputation
- Threshold Signatures: For multi-party PPR validation
- Post-Quantum Cryptography: Preparation for quantum-resistant algorithms
- Hardware Security Modules: For enhanced key protection
Monitoring and Metrics
-
Security Metrics:
- Signature failure rates
- Verification performance
- Attack detection rates
-
Performance Metrics:
- Average signature generation time
- Verification throughput
- Storage overhead
-
Compliance Metrics:
- Audit trail completeness
- Key rotation compliance
- Security policy adherence
Conclusion
The enhanced PPR cryptographic implementation provides robust security through:
- Industry-standard Ed25519 digital signatures
- Cryptographically secure BLAKE2b hashing
- Bilateral authentication with context separation
- Comprehensive testing and validation
- Backward compatibility and migration support
This implementation addresses all critical security recommendations while maintaining performance and usability for the nondominium resource sharing network.
project: nondominium type: architecture status: active created: 2026-04-14 scope: post-mvp
Nondominium Lobby DNA — Architecture Design
⚠️ Superseded in part (2026-07-19). The Lobby DNA (PR #103) and Group DNA (PR #107) shipped with the registry model inverted relative to this design: the Lobby is a group registry (
GroupAnnouncement); NDOs are group-scoped, and the Lobby-levelNdoDescriptorregistry described below was removed in PR #107. The NDO-per-cell architecture (issue #112) partially resurrects theNdoDescriptoridea as the group-levelNdoAnchorentry, which carries the same clone coordinates (ndo_dna_hash,network_seed) at group scope. Implementation-accurate references:documentation/zomes/lobby_zome.mdanddocumentation/zomes/group_zome.md. This document is kept for the decision trail (entry sketches, Moss contract, ADRs).
Design session: 2026-04-14
Basis: Requirements discovery session + Moss/Weave ecosystem research
Scope: Lobby DNA + Group DNA (new) + NDO DNA extensions (zome_gouvernance)
Requirements: documentation/requirements/lobby-dna.md
Table of Contents
- System context (C4 L1)
- Container architecture (C4 L2)
- hApp DNA manifest
- Lobby DNA schema
- Group DNA schema
- NDO DNA extensions
- Key pipelines
- UI component architecture
- Moss integration contract
- Architecture decision records
- Post-MVP extension points
1. System Context (C4 L1)
graph TB
Agent["Agent (OVN Participant)\n--\nBrowser / Electron / Moss"]
Lobby["Nondominium hApp\n--\nLobby + Groups + NDOs"]
Moss["Moss / The Weave\n(optional host runtime)"]
Flowsta["Flowsta\n(post-MVP)\nCross-app DID + Vault"]
Unyt["Unyt\n(post-MVP)\nRAVE + Token settlement"]
Agent -->|"creates/joins groups,\nnavigates NDOs"| Lobby
Lobby -.->|"Tool applet (optional)"| Moss
Lobby -.->|"IsSamePersonEntry (post-MVP)"| Flowsta
Lobby -.->|"RAVE cascade (post-MVP)"| Unyt
Design principle: Nondominium runs fully standalone. Moss, Flowsta, and Unyt are optional integration layers that can be adopted independently (pay-as-you-grow). The same DNA code powers both standalone and Moss-hosted modes.
2. Container Architecture (C4 L2)
Agent identity layers
One physical agent has multiple pubkeys — one per DHT they join. The three-layer model produces three distinct identity records for the same person, bridged by the Group DHT:
Lobby DHT Group DHT NDO DHT
──────────────────── ───────────────────────── ────────────────────
LobbyAgentProfile GroupMembership Person (zome_person)
lobby_pubkey ────────→ ndo_pubkey_map ───→ (key that authored
(handle, avatar, bio) [{ndo_dna_hash, Person entry)
ndo_pubkey}]
| LobbyAgentProfile | Person | |
|---|---|---|
| Where | Lobby DHT (one global) | Per-NDO DHT (one per community joined) |
| Pubkey | lobby_pubkey | Fresh key per NDO DHT |
| Purpose | Cross-NDO public face | Constitutional identity within one NDO |
| Governs | Ecosystem-wide handle | Roles, PPRs, private data in that NDO |
GroupMembership.ndo_pubkey_map is the MVP bridge: it records lobby_pubkey → ndo_pubkey
for each NDO so the group can resolve cross-DHT identity without Flowsta.
Post-MVP, Flowsta IsSamePersonEntry replaces this with a cryptographic attestation
(REQ-LOBBY-INT-01; see flowsta-integration.md).
Implication for implementers: joining an NDO always produces a new AgentPubKey in that
DHT and a new Person entry. The LobbyAgentProfile is never modified by NDO joins — it
is the stable public handle. GroupMembership is what links the two.
Groups vs organization-NDOs
Groups and organization-NDOs are distinct concepts at different layers and must not be conflated.
A collective entity (cooperative, open value network, project-organisation) has two faces in
the Nondominium model: an agent face (AgentContext) through which it participates in
economic events, and a resource face (NondominiumIdentity) which is its digital twin as a
Resource. The table below describes the resource face; see agent.md §3.1 for the dual-face
model and the role of the agent face.
| Group | Organization-NDO (resource face) | |
|---|---|---|
| What it is | Lobby-layer coordination space | The NondominiumIdentity that is the collective's digital twin as a Resource |
| Has Layer 0 identity | No | Yes — lifecycle, property regime, governance |
| Governs | Agents: membership, work logs, soft links | How agents interact with the collective as a Resource |
| Can hold custody | No | No — custody is held by the collective's agent face (AgentContext as primary_accountable, post-MVP) |
| Accumulates reputation | No | No — reputation (EconomicEvents, PPRs) accrues to the agent face. Contribution links record individuals' association with the NDO. |
| Governance layer | Flat group rules (coordination, cultural) | Full NDO governance (AccountableAgents, lifecycle, Agreement) |
| Permanent | No — can be abandoned | Yes — NondominiumIdentity is immutable and permanent |
A group typically creates and coordinates around an organization-NDO but does not become it:
Group (coordination layer)
├── members: [Alice, Bob, Carol]
├── soft links: planned_action=Combine → [SensoricanNDO, LabSpaceNDO]
└── work logs → SensoricanNDO
SensoricanNDO (org-NDO resource face, its own DHT)
├── NondominiumIdentity { regime: Collective, lifecycle: Active }
├── AccountableAgents: [Alice, Bob] ← individual agents
├── Agreement { clauses: [...] }
└── Contributions from Carol, Dave, and other agents (not necessarily group members)
AgentContext { agent_type: Network(sensorica_ndo_hash) } ← agent face; participates in EconomicEvents
Key architectural rule: an agent does not need to be in a group to contribute to an organization-NDO. Group membership governs group-layer coordination only. NDO membership (joining the NDO DHT) is governed by the NDO's own rules and is independent of any group.
Post-MVP gap (REQ-AGENT-02): EconomicResource.custodian: AgentPubKey currently accepts
only individual agent keys. Post-MVP, the AgentContext extension allows the collective's
agent face to act as primary_accountable — collective custody, not NDO-as-resource custody.
Three-layer DHT model
graph TB
subgraph Conductor["Agent's Conductor (one device)"]
LC["Lobby Cell\nzome_lobby_integrity\nzome_lobby_coordinator"]
GC1["Group Cell A\nzome_group_integrity\nzome_group_coordinator"]
GC2["Group Cell B (solo)\nzome_group_integrity\nzome_group_coordinator"]
NC1["NDO Cell: Electronic Device\nzome_person + zome_resource\n+ zome_gouvernance"]
NC2["NDO Cell: Power Supply\nzome_person + zome_resource\n+ zome_gouvernance"]
end
subgraph LobbyDHT["Lobby DHT (canonical network_seed, global)"]
LA["LobbyAgentProfile entries"]
ND["NdoDescriptor entries (public registry)"]
end
subgraph GroupDHTs["Group DHTs (per-group, invite-only)"]
GD1["Group A DHT\nMembership + WorkLogs + SoftLinks"]
GD2["Group B DHT (solo)\nPersonal workspace"]
end
subgraph NdoDHTs["NDO DHTs (per-NDO, constitutional)"]
ND1["NDO 1: Electronic Device DHT"]
ND2["NDO 2: Power Supply DHT"]
end
LC --> LobbyDHT
GC1 --> GD1
GC2 --> GD2
NC1 --> ND1
NC2 --> ND2
GD1 -. "SoftLink (planning, group-governed,\ninvisible to NDO)" .-> ND1
GD1 -. "SoftLink" .-> ND2
ND1 == "NdoHardLink (on fulfillment,\nNDO-governed, OVN-licensed,\nimmutable)" ==> ND2
Trust boundaries
| Layer | Trust model | Data stored | Anti-spam |
|---|---|---|---|
| Lobby DHT | Zero-trust, public | Agent handles, NDO metadata stubs | Valid DnaHash required |
| Group DHT | Invite-trust | Membership, work logs, soft links, rules | DHT cost + invite gate |
| NDO DHT | Constitution-trust | Resources, events, contributions, hard links, smart agreements | Accountable Agent gate |
3. hApp DNA Manifest
Standalone deployment
# happ.yaml
manifest_version: '1'
name: nondominium
description: Nondominium OVN resource sharing network
roles:
- name: lobby
dna:
path: ./lobby/lobby.dna
modifiers:
network_seed: "nondominium-lobby-v1" # canonical, hardcoded
# No cloning: one global Lobby DHT
- name: group
dna:
path: ./group/group.dna
cloning_limit: 255
# Cloned per group: network_seed = invite code (or random on create)
- name: nondominium
dna:
path: ./nondominium/nondominium.dna
cloning_limit: 1024
# Cloned per NDO: network_seed random on create, shared via NdoDescriptor
New workspace structure
dnas/
lobby/
workdir/dna.yaml
zomes/
integrity/zome_lobby_integrity/src/lib.rs # NEW
coordinator/zome_lobby_coordinator/src/lib.rs # NEW
group/
workdir/dna.yaml
zomes/
integrity/zome_group_integrity/src/lib.rs # NEW
coordinator/zome_group_coordinator/src/lib.rs # NEW
nondominium/ # EXISTING, extended
zomes/
coordinator/zome_gouvernance/src/hard_link.rs # NEW file
coordinator/zome_gouvernance/src/contribution.rs # NEW file
coordinator/zome_gouvernance/src/agreement.rs # NEW file (VF: vf:Agreement)
integrity/zome_gouvernance/src/lib.rs # +NdoHardLink, +Contribution, +Agreement
4. Lobby DNA Schema
4.1 Entry types
#![allow(unused)] fn main() { /// Public profile for an agent in the Lobby DHT. Permissionless. #[hdk_entry_helper] pub struct LobbyAgentProfile { pub handle: String, // max 64 chars, non-empty pub avatar_url: Option<String>, // must be https:// if present pub bio: Option<String>, // max 500 chars pub lobby_pubkey: AgentPubKey, // must equal action.author pub created_at: Timestamp, } /// Public descriptor for a registered NDO. Mirrors NondominiumIdentity key fields. /// Registered by the NDO initiator; lifecycle_stage is the only mutable field. /// Cannot be deleted (mirrors permanence of NondominiumIdentity). #[hdk_entry_helper] pub struct NdoDescriptor { pub ndo_name: String, pub ndo_dna_hash: DnaHash, pub network_seed: String, pub ndo_identity_hash: ActionHash, // Layer 0 anchor inside the NDO DHT pub lifecycle_stage: LifecycleStage, pub property_regime: PropertyRegime, pub resource_nature: ResourceNature, pub description: Option<String>, pub registered_by: AgentPubKey, // must equal action.author pub registered_at: Timestamp, } }
4.2 Link types
#![allow(unused)] fn main() { #[hdk_link_types] pub enum LinkTypes { AllLobbyAgents, // Path("lobby.agents") -> LobbyAgentProfile AgentProfileUpdates, // LobbyAgentProfile -> LobbyAgentProfile (versioning) AllNdoDescriptors, // Path("lobby.ndos") -> NdoDescriptor NdoDescriptorByLifecycle, // Path("lobby.ndo.lifecycle.{Stage}") -> NdoDescriptor NdoDescriptorByNature, // Path("lobby.ndo.nature.{Nature}") -> NdoDescriptor NdoDescriptorByRegime, // Path("lobby.ndo.regime.{Regime}") -> NdoDescriptor AgentToRegisteredNdos, // registered_by pubkey -> NdoDescriptor NdoDescriptorUpdates, // NdoDescriptor -> NdoDescriptor (lifecycle chain) } }
4.3 Coordinator API
#![allow(unused)] fn main() { // Agent profiles pub fn upsert_lobby_agent_profile(input: LobbyAgentProfileInput) -> ExternResult<ActionHash>; pub fn get_lobby_agent_profile(agent: AgentPubKey) -> ExternResult<Option<LobbyAgentProfile>>; pub fn get_all_lobby_agents(_: ()) -> ExternResult<Vec<LobbyAgentProfileRecord>>; // NDO descriptor registry pub fn register_ndo_descriptor(input: RegisterNdoInput) -> ExternResult<ActionHash>; pub fn update_ndo_descriptor_lifecycle(input: UpdateNdoLifecycleInput) -> ExternResult<ActionHash>; pub fn get_all_ndo_descriptors(_: ()) -> ExternResult<Vec<NdoDescriptorRecord>>; pub fn get_ndo_descriptors_by_lifecycle(stage: LifecycleStage) -> ExternResult<Vec<NdoDescriptorRecord>>; pub fn get_ndo_descriptors_by_nature(nature: ResourceNature) -> ExternResult<Vec<NdoDescriptorRecord>>; pub fn get_ndo_descriptors_by_regime(regime: PropertyRegime) -> ExternResult<Vec<NdoDescriptorRecord>>; pub fn get_my_registered_ndos(_: ()) -> ExternResult<Vec<NdoDescriptorRecord>>; }
4.4 Validation rules
create LobbyAgentProfile:
handle non-empty, max 64 chars
lobby_pubkey == action.author
avatar_url starts with "https://" if present
update LobbyAgentProfile:
author == original.lobby_pubkey (self-only)
lobby_pubkey field immutable
delete LobbyAgentProfile: INVALID (permanent anchor)
create NdoDescriptor:
registered_by == action.author
ndo_name non-empty
lifecycle_stage not Deprecated or EndOfLife at registration
update NdoDescriptor:
author == original.registered_by
only lifecycle_stage may change
follows NondominiumIdentity state machine rules
delete NdoDescriptor: INVALID (mirrors Layer 0 permanence)
5. Group DNA Schema
5.1 Entry types
#![allow(unused)] fn main() { /// Immutable group descriptor. Created by the progenitor on first launch. #[hdk_entry_helper] pub struct GroupDescriptor { pub name: String, // max 128 chars pub description: Option<String>, pub progenitor: AgentPubKey, // must equal action.author pub is_solo: bool, // true = personal group-of-one pub created_at: Timestamp, } // Immutable after creation. /// Per-agent membership. Stores the cross-DHT pubkey map (Moss pattern). #[hdk_entry_helper] pub struct GroupMembership { pub agent_pubkey: AgentPubKey, // must equal action.author pub invited_by: Option<AgentPubKey>, pub ndo_pubkey_map: Vec<NdoPubkeyEntry>, // cross-DHT identity bridge (MVP) pub joined_at: Timestamp, } /// Maps group pubkey to NDO-DHT pubkey for one NDO. Stored inside GroupMembership. #[derive(Clone, PartialEq, Serialize, Deserialize)] pub struct NdoPubkeyEntry { pub ndo_dna_hash: DnaHash, pub ndo_pubkey: AgentPubKey, pub joined_ndo_at: Timestamp, } /// Informal work record. Lives in Group DHT only. Invisible to target NDO. /// VF alignment: maps to vf:Intent (expressed desire to perform work before committing). /// `provider` = VF provider (the intending agent) /// `action` = VF action (Work, Modify, Use, etc.) /// `effort_quantity` = VF effortQuantity (hours as numeric value) /// `note` = VF note (human-readable description) /// `input_of` = VF inputOf (string label for MVP; ActionHash of vf:Process post-MVP) #[hdk_entry_helper] pub struct WorkLog { pub provider: AgentPubKey, // VF: provider; must equal action.author pub action: VfAction, // VF: action (typically Work, Modify, Use) pub ndo_dna_hash: DnaHash, pub ndo_identity_hash: ActionHash, pub input_of: Option<String>, // VF: inputOf — process label ("maintenance", "development") // Post-MVP: becomes Option<ActionHash> referencing vf:Process pub note: String, // VF: note — max 2000 chars pub effort_quantity: Option<f64>, // VF: effortQuantity — hours; range [0.0, 10000.0] pub attachments: Vec<String>, pub has_point_in_time: Timestamp, // VF: hasPointInTime } /// Soft link: group-level planning relationship to an NDO. Permissionless. /// Invisible to target NDO. Subject to group governance only. /// VF alignment: maps to a group-side record of a vf:Intent toward an NDO. /// `planned_action` = the VF action being planned (Combine, Use, Cite). /// `fulfills` = optional reference to a vf:Commitment on the NDO DHT once created. #[hdk_entry_helper] pub struct SoftLink { pub from_ndo_dna_hash: Option<DnaHash>, pub from_ndo_identity_hash: Option<ActionHash>, pub to_ndo_dna_hash: DnaHash, pub to_ndo_identity_hash: ActionHash, /// VF action this link is planning toward: /// Combine — structural incorporation (Incorporation intent) /// Use — tool/equipment use /// Cite — lifecycle monitoring only pub planned_action: VfAction, pub fulfills: Option<ActionHash>, // VF: fulfills — NDO DHT Commitment hash when created pub created_by: AgentPubKey, // must equal action.author pub created_at: Timestamp, pub note: Option<String>, // VF: note } /// Group governance rule (flat string MVP; typed enum post-MVP). #[hdk_entry_helper] pub struct GroupGovernanceRule { pub rule_name: String, pub rule_data: String, pub created_by: AgentPubKey, // must be progenitor (MVP) pub created_at: Timestamp, } }
5.2 Link types
#![allow(unused)] fn main() { #[hdk_link_types] pub enum LinkTypes { AllMembers, // Path("group.members") -> GroupMembership MembershipUpdates, // GroupMembership -> GroupMembership (ndo_pubkey_map updates) AgentToMembership, // AgentPubKey -> GroupMembership (fast self-lookup) AllWorkLogs, // Path("group.worklogs") -> WorkLog AgentToWorkLogs, // AgentPubKey -> WorkLog NdoToWorkLogs, // ndo_identity_hash -> WorkLog AllSoftLinks, // Path("group.softlinks") -> SoftLink SoftLinkToNdo, // ndo_identity_hash -> SoftLink (by target NDO) AllGovernanceRules, // Path("group.rules") -> GroupGovernanceRule GovernanceRuleUpdates, // GroupGovernanceRule -> GroupGovernanceRule } }
5.3 Coordinator API
#![allow(unused)] fn main() { // Initialization pub fn init_group(input: InitGroupInput) -> ExternResult<ActionHash>; pub fn get_group_descriptor(_: ()) -> ExternResult<Option<GroupDescriptor>>; // Membership pub fn join_group(input: JoinGroupInput) -> ExternResult<ActionHash>; pub fn update_ndo_pubkey_map(input: UpdateNdoPubkeyMapInput) -> ExternResult<ActionHash>; pub fn get_all_members(_: ()) -> ExternResult<Vec<GroupMembershipRecord>>; pub fn get_member_ndo_pubkey(input: GetMemberNdoPubkeyInput) -> ExternResult<Option<AgentPubKey>>; // Work logs pub fn log_work(input: LogWorkInput) -> ExternResult<ActionHash>; pub fn get_work_logs(ndo_filter: Option<DnaHash>) -> ExternResult<Vec<WorkLogRecord>>; pub fn get_my_work_logs(_: ()) -> ExternResult<Vec<WorkLogRecord>>; // Soft links pub fn create_soft_link(input: CreateSoftLinkInput) -> ExternResult<ActionHash>; pub fn delete_soft_link(soft_link_hash: ActionHash) -> ExternResult<()>; pub fn get_all_soft_links(_: ()) -> ExternResult<Vec<SoftLinkRecord>>; pub fn get_soft_links_to_ndo(ndo_identity_hash: ActionHash) -> ExternResult<Vec<SoftLinkRecord>>; // Governance pub fn add_governance_rule(rule: GroupGovernanceRule) -> ExternResult<ActionHash>; pub fn get_governance_rules(_: ()) -> ExternResult<Vec<GroupGovernanceRuleRecord>>; }
5.4 Validation rules
create GroupDescriptor:
progenitor == action.author
name non-empty, max 128 chars
update GroupDescriptor: INVALID (immutable)
create GroupMembership:
agent_pubkey == action.author
create WorkLog:
provider == action.author
note non-empty, max 2000 chars
effort_quantity if present in [0.0, 10000.0]
action must be a valid VfAction (Work, Modify, Use, etc.)
create SoftLink:
created_by == action.author
to_ndo_dna_hash non-empty
planned_action must be Combine | Use | Cite
if planned_action == Combine: from_ndo_* fields must both be Some
delete SoftLink:
author == original.created_by OR author == progenitor
create GroupGovernanceRule:
MVP: author must be progenitor
rule_name non-empty
6. NDO DNA Extensions
New entry types and coordinator functions added to the existing zome_gouvernance. All existing entry types are unchanged.
6.1 New entry types
#![allow(unused)] fn main() { /// Permanent, validated structural link between two NDOs. /// Created only on EconomicEvent Fulfillment. Immutable and undeletable. /// Intrinsic to the NDO DHT (OVN license requirement). #[hdk_entry_helper] pub struct NdoHardLink { pub from_ndo_identity_hash: ActionHash, // Layer 0 hash of this (parent) NDO pub to_ndo_dna_hash: DnaHash, pub to_ndo_identity_hash: ActionHash, // Layer 0 hash of the component NDO pub link_type: NdoLinkType, pub fulfillment_hash: ActionHash, // EconomicEvent backing this link pub created_by: AgentPubKey, // must be AccountableAgent pub created_at: Timestamp, } #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] pub enum NdoLinkType { Component, // target is a structural component of source DerivedFrom, // source was derived/forked from target Supersedes, // source formally replaces target in the network } /// Peer-validated work contribution. Created after AccountableAgent acceptance. /// VF alignment: a validated vf:EconomicEvent (action: Work or Modify) with NDO-specific /// validation metadata. Field names follow VF vocabulary directly: /// `provider` = VF provider (contributing agent) /// `action` = VF action (Work, Modify, etc.) /// `effort_quantity` = VF effortQuantity /// `note` = VF note /// `input_of` = VF inputOf (Process ActionHash) /// `fulfills` = VF fulfills (Commitment ActionHash, when applicable) #[hdk_entry_helper] pub struct Contribution { pub provider: AgentPubKey, // VF: provider (the contributing agent) pub action: VfAction, // VF: action — typically Work or Modify pub work_log_group_dna_hash: Option<DnaHash>, // NDO extension: off-chain WorkLog reference pub work_log_action_hash: Option<ActionHash>, // NDO extension: off-chain WorkLog reference pub ndo_identity_hash: ActionHash, pub input_of: Option<ActionHash>, // VF: inputOf — Process ActionHash (NDO DHT) pub note: String, // VF: note pub effort_quantity: Option<f64>, // VF: effortQuantity (hours) pub validated_by: Vec<AgentPubKey>, // NDO extension: AccountableAgent validators (min 1) pub fulfills: Option<ActionHash>, // VF: fulfills — Commitment ActionHash if applicable pub has_point_in_time: Timestamp, // VF: hasPointInTime (when work was done) pub validated_at: Timestamp, // NDO extension: when AccountableAgents accepted } /// Benefit redistribution agreement. AccountableAgent-controlled. Versioned. /// VF alignment: extends vf:Agreement. The `clauses` field is an NDO extension — /// VF Agreement does not prescribe internal structure; NDO uses typed clauses for /// benefit distribution, which Unyt will execute as RAVE flows post-MVP. #[hdk_entry_helper] pub struct Agreement { // VF: vf:Agreement pub ndo_identity_hash: ActionHash, pub version: u32, // NDO extension: monotonic version counter pub clauses: Vec<BenefitClause>, // NDO extension: typed benefit distribution rules pub primary_accountable: Vec<AgentPubKey>, // VF: primaryAccountable (who governs this agreement) pub created_by: AgentPubKey, pub created_at: Timestamp, } /// One benefit distribution clause within an Agreement. /// NDO extension on VF — not in VF core. Executed via Unyt RAVE post-MVP. #[derive(Clone, PartialEq, Serialize, Deserialize)] pub struct BenefitClause { pub receiver: BeneficiaryRef, // VF: receiver (agent or component NDO) pub share_percent: f64, // 0.0 to 100.0 (NDO: proportion of total benefit) pub benefit_type: BenefitType, // NDO extension: Monetary | GovernanceWeight | AccessRight pub note: Option<String>, // VF: note (conditions, rationale) } #[derive(Clone, PartialEq, Serialize, Deserialize)] pub enum BeneficiaryRef { Agent(AgentPubKey), NdoComponent { ndo_dna_hash: DnaHash, ndo_identity_hash: ActionHash }, } #[derive(Clone, PartialEq, Serialize, Deserialize)] pub enum BenefitType { Monetary, // Unyt token distribution (post-MVP) GovernanceWeight, // voting weight in NDO governance AccessRight(String), // e.g. "use_equipment", "read_design" } }
6.2 New link types (additions to existing enum)
#![allow(unused)] fn main() { // Add to existing zome_gouvernance_integrity LinkTypes: NdoToHardLinks, // from_ndo_identity_hash -> NdoHardLink HardLinkByType, // Path("ndo.hardlink.{NdoLinkType}") -> NdoHardLink NdoToContributions, // ndo_identity_hash -> Contribution AgentToContributions, // VF: provider AgentPubKey -> Contribution ContributionToEvent, // VF: Contribution -> EconomicEvent (the fulfilling event) NdoToAgreement, // ndo_identity_hash -> Agreement (latest) [VF: vf:Agreement] AgreementUpdates, // Agreement -> Agreement (version chain) }
6.3 New coordinator functions
#![allow(unused)] fn main() { // hard_link.rs pub fn create_ndo_hard_link(input: CreateNdoHardLinkInput) -> ExternResult<ActionHash>; pub fn get_ndo_hard_links(_: ()) -> ExternResult<Vec<NdoHardLinkRecord>>; pub fn get_ndo_hard_links_by_type(link_type: NdoLinkType) -> ExternResult<Vec<NdoHardLinkRecord>>; // contribution.rs pub fn validate_contribution(input: ValidateContributionInput) -> ExternResult<ActionHash>; pub fn get_ndo_contributions(_: ()) -> ExternResult<Vec<ContributionRecord>>; pub fn get_agent_contributions(provider: AgentPubKey) -> ExternResult<Vec<ContributionRecord>>; // agreement.rs (VF: vf:Agreement — renamed from smart_agreement.rs) pub fn create_agreement(input: CreateAgreementInput) -> ExternResult<ActionHash>; pub fn update_agreement(input: UpdateAgreementInput) -> ExternResult<ActionHash>; pub fn get_current_agreement(_: ()) -> ExternResult<Option<AgreementRecord>>; }
6.4 Validation rules
create NdoHardLink:
author must hold AccountableAgent or PrimaryAccountableAgent role (cross-zome check)
fulfillment_hash must resolve to valid EconomicEvent in this DHT
event.action must be Work | Produce | Combine | Modify
from_ndo_identity_hash must exist in this DHT
update NdoHardLink: INVALID (hard links are immutable)
delete NdoHardLink: INVALID (hard links are permanent, OVN license requirement)
create Contribution:
validated_by must be non-empty (at least one AccountableAgent)
provider == action.author OR a delegated AccountableAgent
note non-empty
effort_quantity if present in [0.0, 10000.0]
action must be Work | Modify | Combine | Produce
create Agreement:
author must hold AccountableAgent or PrimaryAccountableAgent role (cross-zome check)
primary_accountable non-empty
all clause.share_percent in [0.0, 100.0]
sum of clause.share_percent <= 100.0
update Agreement:
author must hold AccountableAgent or PrimaryAccountableAgent role (cross-zome check)
version must equal previous.version + 1
ndo_identity_hash immutable
delete Agreement: INVALID (versioned history must be preserved; supersede via update)
7. Key Pipelines
7.1 Incorporation pipeline (Soft Link to Hard Link)
sequenceDiagram
participant GM as Group Member
participant GD as Group DHT
participant ND as NDO DHT (Device)
participant AA as Accountable Agent
GM->>GD: create_soft_link(planned_action: Combine, PowerSupplyNdo)
Note over GD: SoftLink created (dashed in UI)
GM->>ND: create_commitment(action: Combine, DeviceNdo, PowerSupplyRef)
GM->>GD: update soft_link.fulfills = commitment_hash
GM->>ND: propose EconomicEvent (like a pull request)
AA->>ND: validate_contribution(work_log_ref, event_hash)
Note over ND: Contribution created
AA->>ND: create_ndo_hard_link(PowerSupplyNdo, fulfillment_hash)
Note over ND: NdoHardLink created (solid, OVN-licensed, immutable)
AA->>ND: update_agreement (add BenefitClause: receiver = PowerSupplyNdo, X%)
Note over ND: Agreement updated: cascade clause to PowerSupplyNdo
GM->>GD: delete_soft_link (promoted)
7.2 Process pipeline (Work Log to Contribution)
sequenceDiagram
participant GM as Group Member
participant GD as Group DHT
participant ND as NDO DHT (Equipment)
participant AA as Accountable Agent
GM->>GD: create_soft_link(Use, EquipmentNdo)
GM->>GD: log_work(EquipmentNdo, "maintenance", 3h)
Note over GD: WorkLog: informal, invisible to NDO
GM->>ND: propose EconomicEvent(Work, Maintenance)
Note over ND: NDO state: Active -> InMaintenance
AA->>ND: validate_contribution(work_log_ref, event_hash)
Note over ND: Contribution created; agent in contributor list
AA->>ND: update_lifecycle_stage(Active)
Note over ND: NDO state: InMaintenance -> Active
7.3 Group join pipeline (with identity map)
sequenceDiagram
participant Bob
participant LC as Lobby Cell
participant GC as Group Cell
participant NC as NDO Cell
Bob->>LC: get_all_ndo_descriptors() [browse freely]
Note over Bob: finds group via invite code out-of-band
Bob->>GC: join_group(invite_code, ndo_pubkey_map=[])
Note over GC: GroupMembership created
Bob->>NC: [install nondominium.dna with NDO network_seed]
Note over NC: New AgentPubKey in this NDO DHT
Bob->>GC: update_ndo_pubkey_map({EquipmentNdo: bob_ndo_pubkey})
Note over GC: Identity bridge: group_pubkey -> ndo_pubkey stored
8. UI Component Architecture
Built with Svelte 5 + UnoCSS + Melt UI (matching existing stack).
App.svelte
conductorClient: AppClient
activeCells: Map<string, CellId> // lobby, group-N, ndo-N
LobbyView.svelte
GroupSidebar.svelte
GroupCard.svelte { name, member count, NDO count, solo badge }
CreateGroupModal.svelte
JoinGroupModal.svelte { invite code input }
NdoBrowser.svelte
NdoFilter.svelte { lifecycle, nature, regime }
NdoCard.svelte { name, lifecycle badge (color-coded), regime chip }
LobbyAgentProfile.svelte
GroupView.svelte
GroupHeader.svelte { name, member count, rules }
MemberList.svelte
NdoLinkList.svelte
SoftLinkCard.svelte { border-dashed, purpose badge, commitment status }
PromotedLinkCard.svelte { border-solid green, hard link confirmed }
AddNdoLinkModal.svelte { planned_action: Combine | Use | Cite }
WorkLogFeed.svelte
WorkLogCard.svelte { author, NDO, hours, status: pending|submitted|validated }
LogWorkModal.svelte
CommitmentBoard.svelte { Kanban: Planned -> Submitted -> Validated }
NdoView.svelte
NdoHeader.svelte { name, lifecycle badge, regime, nature, description }
CompositionGraph.svelte { D3: NDO nodes + hard link edges, zoomable }
NdoNode.svelte { color = lifecycle stage }
HardLinkEdge.svelte { solid line, NdoLinkType label }
ProcessTimeline.svelte { EconomicEvents, state transitions }
ContributorList.svelte { validated agents, contribution counts }
AgreementPanel.svelte { benefit clauses (VF: Agreement), read-only for non-AccountableAgents }
GovernancePanel.svelte { AccountableAgents, rules, create hard link action }
Visual conventions
| Element | Style | Meaning |
|---|---|---|
| Soft link card | border-dashed border-gray-400 | Planning, not yet real |
| Promoted link | border-solid border-green-500 | Hard link confirmed |
| Hard link edge | Solid 2px blue stroke | Permanent, OVN-licensed |
| AccountableAgent action | bg-amber-100 button | Governance-gated |
9. Moss Integration Contract
When deployed inside Moss, Nondominium appears as one Tool applet. Moss handles: group invites, agent identity at the surface, and the app sidebar. Nondominium owns its internal complexity (Group DHTs, NDO DHTs, hard links, smart agreements).
Moss vs standalone feature map
| Feature | Standalone | Inside Moss |
|---|---|---|
| Group creation | Lobby DNA (new DHT) | Moss group (Moss DHT) |
| Invite codes | Group DNA | Moss invite system |
| Agent identity (lobby) | LobbyAgentProfile | Moss profile |
| Cross-NDO identity | GroupMembership.ndo_pubkey_map | AppletToJoinedAgent links |
| NDO registry | Lobby DHT | Nondominium Lobby Tool DHT |
| Cross-tool asset refs | N/A | WAL (Weave Asset Locator) |
| NDO DHTs | Cloned cells | Cloned cells (same) |
Moss Tool entry point (TypeScript)
// ui/src/we-applet.ts
export default {
async appletServices(weaveClient: WeaveClient): Promise<AppletServices> {
return {
search: async (filter: string) => {
const ndos = await weaveClient.callZome(
{ role: 'lobby', zome: 'zome_lobby_coordinator' },
'get_all_ndo_descriptors', null
);
return ndos
.filter(ndo => ndo.entry.ndo_name.toLowerCase().includes(filter.toLowerCase()))
.map(ndo => ({
hrl: [ndo.entry.ndo_dna_hash, ndo.action_hash],
context: { type: 'ndo', lifecycle: ndo.entry.lifecycle_stage },
}));
},
getAssetInfo: async (hrl) => { /* resolve HRL to NDO metadata */ },
openAsset: (hrl) => { /* navigate to NdoView */ },
};
},
};
10. Architecture Decision Records
ADR-01: Group-per-DHT
Status: Accepted
Decision: Each Group occupies its own DHT (like Moss groups), not entries in the Lobby DHT.
Rationale: DHT isolation gives each group independent governance and natural anti-spam (creating a DHT has computational cost). Invite-only means no public spam registration. NDO discoverability is graph-based (through group relationships).
Trade-off: Conductor manages N group cells. Acceptable at expected OVN community scale.
ADR-02: Soft links are invisible to NDOs
Status: Accepted
Decision: Soft links live entirely in the Group DHT. NDOs are never aware of who links to them.
Rationale: Permissionless linking is safe when the NDO has zero awareness of it. NDO state changes require explicit AccountableAgent validation regardless. Groups can monitor any NDO freely without creating governance burden on the NDO.
ADR-03: Hard links require fulfillment, not commitment
Status: Accepted
Decision: NdoHardLink entries are created only on validated EconomicEvent Fulfillment. Commitments create soft links (planning). Fulfillments create hard links (reality).
Rationale: OVN license requirement: hard links represent what has actually happened, not what was planned. A hard link is cryptographically backed by a specific EconomicEvent.
ADR-04: Lobby network seed is canonical and hardcoded
Status: Accepted
Decision: network_seed: "nondominium-lobby-v1" is hardcoded in happ.yaml.
Rationale: All users must share one global Lobby DHT. A fork with a different seed creates a fragmented network. The canonical seed is the authoritative Nondominium network identifier.
Consequence: Seed changes require a coordinated migration; old Lobby DHT remains readable.
ADR-05: MVP identity via conductor bridge calls; Flowsta post-MVP
Status: Accepted
Decision: MVP uses GroupMembership.ndo_pubkey_map per Moss's AppletToJoinedAgent
pattern. Same conductor holds all cells; bridge calls resolve identity intra-conductor.
Rationale: Sufficient for single-conductor use (one device, one user). Multi-device and
multi-conductor federation requires Flowsta IsSamePersonEntry.
Forward compatibility: ndo_pubkey_map schema allows Flowsta DID addition without
breaking existing records.
ADR-06: NdoHardLink is immutable and undeletable
Status: Accepted
Decision: No updates or deletions permitted on NdoHardLink entries.
Rationale: OVN license semantics: if a power supply was incorporated into a device at time T, that historical fact is permanent even if the device is later disassembled. Allowing deletion would enable retroactive manipulation of contribution history and benefit attribution. The Agreement can be updated to change future benefit flows; the historical link stands.
ADR-07: Agreement is versioned, not replaced
Status: Accepted
Decision: Agreement (VF: vf:Agreement) updates create a new versioned entry linked via
AgreementUpdates. Full history preserved. version: u32 enables fast "is this latest?"
checks without full chain traversal.
Rationale: Contribution attribution at time T should reference the Agreement version active at T. Full audit history supports OVN accounting and Unyt RAVE integration.
11. Post-MVP Extension Points
Flowsta integration (REQ-NDO-CS-12 through CS-15)
Replace GroupMembership.ndo_pubkey_map with FlowstaIdentity capability slots on Person
entries. Each agent's lobby, group, and NDO pubkeys are linked via IsSamePersonEntry
dual-signed attestations. W3C DID becomes the stable cross-network identity anchor.
See documentation/requirements/post-mvp/flowsta-integration.md.
Unyt integration (benefit cascade)
Agreement.clauses with BenefitType::Monetary activate via Unyt:
- Validated
Contributiontriggers a RAVE event in the Unyt cell NdoHardLinkof typeComponenttriggers cascade: parent NDO RAVE distributions include a percentage flowing to the component NDO'sAgreement- Monetary contributions routed via Lobby:
donate_to_ndo(ndo_dna_hash, amount)
See documentation/requirements/post-mvp/unyt-integration.md.
Many-to-many flows (REQ-MMF-*)
NdoHardLink creation currently requires one AccountableAgent signature. Post-MVP:
multi-party consent for structural incorporation per
documentation/requirements/post-mvp/many-to-many-flows.md.
Typed group governance
GroupGovernanceRule.rule_data: String (JSON MVP) evolves to a typed enum matching the NDO
GovernanceRule pattern, enabling programmatic group governance evaluation.
ValueFlows DSL - Technical Specifications
Companion document to ValueFlows DSL Requirements
Table of Contents
- Language Syntax and Grammar
- Validation Pipeline
- Governance Rule DSL
- Security Model
- Performance Optimization
- Migration and Versioning
- Testing Framework
- CLI Interface Specification
- Parser Architecture
- Compilation Pipeline
1. Language Syntax and Grammar
1.1 Language Design Philosophy
The DSL follows a progressive enhancement strategy with three tiers:
Tier 1: Pure Declarative (MVP)
- Entity definitions with properties
- Static relationships and references
- Template-based bulk operations
- No variables or control flow
- Target: Network administrators bootstrapping networks
Tier 2: Template-Based Operations (Phase 2)
- Bulk operations with wildcards (
* 5syntax) - Conditional updates with
whereclauses - Template inheritance and composition
- Basic expression evaluation
- Target: Power users managing dynamic inventories
Tier 3: Full Scripting (Future)
- Variables and constants
- Loops and iteration
- Conditionals and branching
- Function definitions
- Target: Developers creating complex automation
1.2 Grammar Specification (EBNF-like)
<program> ::= <statement>*
<statement> ::= <network_decl>
| <agents_decl>
| <resources_decl>
| <resource_specs_decl>
| <governance_decl>
| <recipe_decl>
| <event_decl>
| <transaction_decl>
<entity_decl> ::= <identifier> ':' <type> '{' <property_list> '}'
<property_list> ::= <property>*
<property> ::= <identifier> ':' <value>
<value> ::= <string>
| <number>
| <boolean>
| <identifier> # reference
| <list>
| <duration>
<duration> ::= <number> <unit>
<unit> ::= 's' | 'm' | 'h' | 'd' | 'w'
1.3 Core Language Constructs
1.3.1 Network Declaration
network <identifier> {
created: <date>
jurisdiction: <string>
[optional properties...]
}
Example:
network FabLabMontreal {
created: 2025-01-15
jurisdiction: Quebec
}
1.3.2 Agent Declaration
agents {
organization <name> {
type: <org_type>
location: <string>
[...]
}
person <name> {
roles: [<role>, ...]
[...]
}
}
Organization Types:
OpenValueNetworkCooperativeNonProfitForProfitInformal
1.3.3 Resource Specification Declaration
resource_specifications {
<spec_name> {
governance: <governance_model>
accounting: <accounting_method>
[...]
}
}
Governance Models:
commons_stewardship- Shared resource managed by stewardspool_contribution- Contributory poolingprivate_ownership- Individual or group ownershipshared_custody- Joint custody arrangement
Accounting Methods:
use_tracking- Track usage eventsquantity_consumed- Track consumed quantitiestransfer_tracking- Track transfersnone- No accounting
1.3.4 Resource Declaration
resources {
<resource_name> : <specification> {
custodian: <agent>
location: <string>
quantity: <number> <unit>?
[...]
}
# Bulk creation
<fleet_name> : <specification> * <count> {
[...]
}
}
1.3.5 Governance Rule Declaration
See Section 3: Governance Rule DSL for complete syntax.
1.3.6 Recipe Declaration
recipe <name> {
inputs:
<resource> <quantity> <unit>? (<action>)
[...]
work:
<work_type> <duration>
[...]
outputs:
<resource> <quantity> <unit>? (<action>)
[...]
}
Action Types:
consume- Resource consumed in processuse- Resource used without consumptioncite- Referenced but not usedproduce- Resource produced by process
2. Validation Pipeline
2.1 Five-Phase Validation
The DSL implements a comprehensive validation pipeline:
Phase 1: Syntax Validation (Parse-Time)
- Grammar compliance checking
- Token and structural validation
- Immediate feedback with line/column numbers
Phase 2: Semantic Validation (Type Checking)
- Unit compatibility (e.g., cannot assign "hours" to "kilograms")
- Resource specification matching
- Agent role compatibility
- Data type validation
Phase 3: Reference Integrity (Existence Checks)
- Agent references must exist or be defined in script
- Resource specification references must be valid
- Location and organization references verified
- Forward references allowed within same script
Phase 4: Economic Logic Validation
- Process input/output balance checking
- Valid action sequences (e.g., cannot consume before produce)
- Quantity conservation laws
- Temporal consistency (events in chronological order)
Phase 5: Governance Compliance
- Rule coverage analysis (are all resources covered?)
- Conflict detection between rules
- Access control validation
- Approval workflow completeness
2.2 Error Handling Strategy
| Error Type | Severity | Recovery | Example |
|---|---|---|---|
| Syntax Error | Fatal | Must fix | Missing closing brace |
| Type Mismatch | Fatal | Must fix | Assigning "kg" to time field |
| Unknown Reference | Fatal | Must fix or create | Agent not found |
| Logic Warning | Warning | Optional fix | Process doesn't balance |
| Style Issue | Info | Optional fix | Inconsistent naming |
2.3 Validation Commands
nondom validate --strict script.vf # Treat warnings as errors
nondom validate --phase 2 script.vf # Stop after semantic validation
nondom validate --explain script.vf # Detailed explanations
2.4 Error Message Format
$ nondom validate script.vf
error[E0301]: unknown agent reference
--> script.vf:25:12
|
25 | custodian: UnknownOrg
| ^^^^^^^^^^ agent not found
|
= hint: create agent first or use `or_default` fallback
= help: see https://docs.nondominium.org/dsl/errors/E0301
warning[W0201]: process doesn't balance
--> script.vf:42:5
|
42 | recipe MakePart { ... }
| ---- outputs exceed inputs by 2 units
|
= note: this may be intentional for additive manufacturing
3. Governance Rule DSL
3.1 Rule Definition Syntax
governance {
rule <name> {
# Basic properties
applies_to: <resource_spec>
requires_role: <role>
max_booking_duration: <duration>
requires_approval_when: <condition>
approvers: [<role>, ...]
# Temporal constraints
valid_from: <date>
valid_until: <date>
# Condition composition
conditions {
operating_hours: <time_range>
excluded_days: [<day>, ...]
}
}
}
3.2 Rule Composition Operators
3.2.1 Logical Operators
rule AdvancedEquipment {
applies_to: Equipment AND category == "Precision"
requires: (role == Member OR role == Technician)
NOT blacklisted
}
Operators:
AND- Both conditions must be trueOR- At least one condition must be trueNOT- Condition must be false- Parentheses
()for grouping
3.2.2 Priority Specification
governance {
rule BasicAccess { priority: 100 }
rule EmergencyOverride { priority: 1000 } # Higher wins
}
Conflict Resolution Order:
- Priority ordering (higher wins)
- Most specific rule (more conditions wins)
- Most recent definition
- Explicit combination via
combine_with
3.2.3 Rule Inheritance and Composition
# Base rule template
template EquipmentRule {
requires_role: Member
max_booking: 4h
}
# Specialized rules inherit from template
rule CNC_Machines : EquipmentRule {
applies_to: CNC_Router
requires_approval_when: duration > 2h
approvers: [Senior_Technician]
}
rule BasicTools : EquipmentRule {
applies_to: HandTools
requires_approval: false # Override
}
3.3 Temporal Validity and Scheduling
rule SeasonalEquipment {
applies_to: Outdoor_Equipment
# Season-based availability
schedule {
available: April-September
unavailable: October-March
}
# Time-of-day restrictions
time_windows {
weekday: 9am-9pm
weekend: 10am-6pm
}
}
3.4 Rule Testing and Validation
# Test cases can be embedded
governance {
rule EquipmentBooking {
# ... rule definition ...
}
test "Weekend booking requires approval" {
given: EquipmentBooking
when: agent.role == Member AND day == Saturday
then: requires_approval == true
}
}
4. Security Model
4.1 Authentication and Authorization
Agent Authentication:
- Scripts execute with the permissions of the authenticated agent
- Agent identity verified through Holochain's signature system
- Cross-agent operations require explicit capability grants
# Script can declare required permissions
permissions {
require: [create_resource, transfer_resource]
as_agent: Alice
delegate_to: Bob # Allow Bob to act on behalf
}
4.2 Capability-Based Access Control
Capability Token Validation:
- All operations validated against Nondominium's capability tokens
- Role-based access enforced at zome level
- Temporary capabilities for time-limited operations
# Request specific capabilities for script execution
capabilities {
create_resources: 100 # Max 100 resources
duration: 1h # Session timeout
renewable: false # One-time execution
}
4.3 Data Privacy and Sensitive Information
Private Data Handling:
- Encrypted profile fields never exported in plain text
- PII (Personally Identifiable Information) redacted from logs
- Audit trails respect privacy settings
# Privacy-aware export
nondom export --privacy-mode minimal # Exclude private fields
nondom export --privacy-mode full # Include all accessible data
4.4 Audit Logging
# Enable detailed audit logging
nondom apply script.vf --audit --log-level debug
Log Contents:
- Script hash and timestamp
- Agent identity and capabilities used
- All zome calls performed
- Resource modifications (before/after)
- Governance rule evaluations
4.5 Sandboxing and Execution Safety
Declarative-Only Guarantee:
- No arbitrary code execution possible
- No filesystem access beyond script I/O
- No network access except to Holochain conductor
- No shell command execution
# Script can request resource limits
limits {
max_entities: 1000
max_execution_time: 5min
max_memory: 100MB
}
4.6 Rate Limiting and Abuse Prevention
Bulk Operation Limits:
- Rate limits on resource creation (e.g., 100/minute)
- Detection of bulk deletion patterns
- Require confirmation for destructive operations
# Interactive confirmation for dangerous operations
$ nondom apply mass_delete.vf
Warning: This script will delete 50 resources. Continue? [y/N]
5. Performance Optimization
5.1 Performance Metrics
Parsing Performance:
| Script Size | Parse Time Target | Complexity |
|---|---|---|
| Small (~50 entities) | < 100ms | O(n) |
| Medium (~500 entities) | < 500ms | O(n) |
| Large (~1000+ entities) | < 1s | O(n) |
Validation Performance:
| Validation Phase | Time Target | Complexity |
|---|---|---|
| Syntax | O(n) | < 100ms typical |
| Semantic | O(n²) worst-case | < 500ms typical |
| Reference Integrity | O(n) | Dependent on DHT |
| Economic Logic | O(n) | < 500ms typical |
| Governance | O(n×m) | n=entities, m=rules |
Execution Performance:
| Operation | Target | Notes |
|---|---|---|
| Create 100 resources | < 10s | Excluding DHT latency |
| Bulk update (where clause) | < 5s | For 100 resources |
| Export 1000 entities | < 5s | To DSL format |
| Diff two states | < 3s | For 500-entity networks |
5.2 Resource Limits
Memory Usage:
- Parser: < 10MB per 1000 entities
- Validation: < 50MB peak
- Execution: < 100MB (excluding DHT)
Script Size Limits:
- Maximum entities: 10,000 (configurable)
- Maximum file size: 5MB
- Maximum nesting depth: 10 levels
5.3 Optimization Strategies
Parallel Entity Creation:
#![allow(unused)] fn main() { // Order-independent entities created in parallel let (agents, resources, governance) = tokio::join!( create_agents(agent_batch), create_resources(resource_batch), create_governance(governance_batch) ); }
Batch DHT Operations:
# Configure batch size
nondom apply script.vf --batch-size 100
# Larger batches = fewer round-trips but higher memory
Lazy Validation:
# Skip expensive checks for trusted scripts
nondom apply script.vf --validation quick # Syntax + basic semantic only
nondom apply script.vf --validation full # All phases (default)
5.4 Progress Reporting
$ nondom apply bootstrap.vf
Processing: [████████░░░░░░░] 45% (450/1000 entities)
Created: 450 agents, 300 resources, 50 governance rules
ETA: 2s
5.5 Caching Strategy
Parse Cache:
# Cache parsed AST for repeated validation
nondom validate script.vf --cache
# Second run is instantaneous
Validation Cache:
# Cache validation results for unchanged scripts
nondom validate script.vf --incremental
# Only re-validates changed sections
DHT Query Cache:
- Cache reference integrity checks for 5 minutes
- Invalidation on entity updates
- LRU cache with 1000-entry limit
6. Migration and Versioning
6.1 State Export and Import
Export Format:
# Export entire network state
nondom export --format vf --output network_state.vf
# Export specific entity types
nondom export resources,governance --output partial.vf
# Export with filtering
nondom export --where "created > 2025-01-01" --output recent.vf
State Representation:
# Exported state script includes version metadata
# Generated: 2025-01-15T10:30:00Z
# Network: FabLabMontreal
# Version: 1.0
metadata {
export_date: 2025-01-15T10:30:00Z
dsl_version: "1.0"
network_hash: "abc123..."
}
# ... full entity definitions ...
6.2 State Diff and Migration
# Compare current state with exported baseline
nondom diff baseline.vf --output migration.vf
# Preview changes before applying
nondom diff baseline.vf --dry-run
# Generate detailed change report
nondom diff baseline.vf --report changes.md
Diff Output Format:
# Auto-generated migration script
# Changes: +15 resources, -3 resources, ~8 resources
# ADDED resources
resources {
New_Laser_Cutter : Equipment {
custodian: Sensorica
location: "Room 201"
added: 2025-01-15
}
}
# REMOVED resources
remove resource Old_3D_Printer # Deprecated
# MODIFIED resources
update resource CNC_Router {
location: "Room 101" # Changed from "Room 100"
}
6.3 Version Compatibility
DSL Versioning Strategy:
| DSL Version | Status | Migration Path |
|---|---|---|
| 1.0 | Current | N/A |
| 0.9 | Deprecated | nondom migrate --from 0.9 --to 1.0 |
| 0.8 | Unsupported | Manual migration required |
Backward Compatibility Guarantees:
- Scripts written in DSL 1.0 will work with DSL 1.x (minor versions)
- Breaking changes require major version increment (1.0 → 2.0)
- Migration tools provided for at least 2 previous major versions
Version Detection:
# Scripts declare required DSL version
#!/usr/bin/env nondom
# @version "1.0"
network MyNetwork { ... }
7. Testing Framework
7.1 Unit Testing Individual Constructs
# test/unit/resource_creation.vf
test "Create resource with minimal properties" {
input: {
resources { TestResource : Equipment { custodian: TestOrg } }
}
expect: {
created: 1
type: Equipment
has_property: custodian
}
}
7.2 Integration Testing
# test/integration/full_workflow.vf
test "Complete resource lifecycle" {
setup: {
# Create agents, specifications, governance
}
script: {
# Create resources, transfer, consume, produce
}
verify: {
# Check DHT state
# Verify governance rules applied
# Validate economic events
}
cleanup: {
# Remove test data
}
}
7.3 Golden File Testing
# Generate golden files
nondom compile test.vf --output test.golden.json
# Regression testing
nondom test --golden test.vf
# Compiles and compares with test.golden.json
7.4 Property-Based Testing
#![allow(unused)] fn main() { // Rust-based property tests proptest!(|(resources: Vec<Resource>)| { let script = compile_to_dsl(resources); let result = nondom_apply(&script); prop_assert!(result.is_valid()); }); }
Properties to Test:
- Idempotency: Running script twice produces same result
- Commutativity: Order of entity creation doesn't matter (where possible)
- Round-trip: Export → Import preserves data
7.5 Test Organization
tests/
├── unit/ # Single feature tests
│ ├── agent_creation.vf
│ ├── resource_spec.vf
│ └── governance_rules.vf
├── integration/ # Cross-feature tests
│ ├── full_workflow.vf
│ └── multi_agent.vf
├── golden/ # Expected compiler outputs
│ └── *.golden.json
└── snapshots/ # Governance evaluation results
└── *.snap.vf
7.6 Continuous Integration
# .github/workflows/dsl-tests.yml
test:
- bun run test:unit # Fast unit tests
- bun run test:integration # Integration tests
- bun run test:golden # Regression testing
- bun run test:property # Property-based tests
8. CLI Interface Specification
8.1 Command Reference
| Command | Description |
|---|---|
nondom apply <script.vf> | Execute a DSL script against the network |
nondom validate <script.vf> | Validate syntax and semantics without executing |
nondom apply --dry-run <script.vf> | Show what would change without applying |
nondom export --format vf | Export current state as DSL script |
nondom import <file> --mapping <map.vf> | Import from external format using mapping |
nondom repl | Interactive shell for exploratory scripting |
nondom diff <baseline.vf> | Compare states and generate migration script |
nondom migrate --from <ver> --to <ver> | Migrate scripts between DSL versions |
8.2 Common Options
# Validation options
--strict # Treat warnings as errors
--phase <number> # Stop at specific validation phase
--explain # Provide detailed explanations
# Execution options
--dry-run # Preview changes without applying
--batch-size <number> # Configure DHT operation batching
--validation <mode> # quick | full
--interactive # Prompt for confirmation on each change
# Performance options
--cache # Enable parse caching
--incremental # Use incremental validation
--profile # Show performance breakdown
--chunk-size <number> # Process large scripts in chunks
# Output options
--output <file> # Specify output file
--format <format> # vf | json | graphql
--privacy-mode <mode> # minimal | full
--audit # Enable audit logging
--log-level <level> # debug | info | warn | error
9. Parser Architecture
9.1 Technology Stack
- Implementation Language: Rust (aligns with Nondominium codebase)
- Parser Library: pest or nom parser combinators
- AST Representation: Serde-serializable structs
- Error Reporting: Custom diagnostic types with span information
9.2 Parser Components
#![allow(unused)] fn main() { // Core parser structure pub struct DslParser { lexer: pest::Parser<Rule>, ast_builder: AstBuilder, error_collector: ErrorCollector, } impl DslParser { pub fn parse(&mut self, input: &str) -> Result<Program, ParseError> { // Tokenization -> AST construction -> Validation } } }
9.3 AST Definition
#![allow(unused)] fn main() { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Program { pub version: Option<String>, pub statements: Vec<Statement>, pub metadata: Metadata, } #[derive(Debug, Clone, Serialize, Deserialize)] pub enum Statement { Network(NetworkDecl), Agents(AgentsDecl), Resources(ResourcesDecl), Governance(GovernanceDecl), Recipe(RecipeDecl), Transaction(TransactionBlock), // ... } }
9.4 Error Reporting
#![allow(unused)] fn main() { #[derive(Debug)] pub struct ParseError { pub kind: ErrorKind, pub span: Span, pub context: String, pub hints: Vec<String>, } pub type Span = std::ops::Range<usize>; }
10. Compilation Pipeline
10.1 Compilation Stages
DSL Source Code
↓
[Lexer] → Tokens
↓
[Parser] → AST
↓
[Validator] → Validated AST
↓
[Compiler] → hREA Function Calls
↓
[Executor] → Holochain DHT Operations
10.2 Target: hREA Zome Calls
The DSL compiles to Nondominium's zome function calls:
#![allow(unused)] fn main() { // DSL: resources { CNC : Equipment { custodian: Sensorica } } // // Compiles to: zome_resource::functions::create_resource(CreateResourceInput { resource_spec_id: "Equipment", custodian: "Sensorica", // ... }) }
10.3 Secondary Compilation Targets
JSON-LD Export:
nondom compile script.vf --target jsonld --output script.jsonld
GraphQL Mutations:
nondom compile script.vf --target graphql --output mutations.graphql
Appendix A: Error Codes
| Code | Category | Description |
|---|---|---|
| E0101-E0199 | Syntax | Grammar and parsing errors |
| E0201-E0299 | Semantic | Type checking and validation |
| E0301-E0399 | Reference | Unknown entity references |
| E0401-E0499 | Economic Logic | Balance and conservation errors |
| E0501-E0599 | Governance | Rule conflicts and violations |
Nondominium Architecture Overview
This document provides a comprehensive overview of the Nondominium Holochain application architecture, focusing on the cross-zome integration patterns, shared infrastructure, and development status. It reflects the implementation of resource management, Private Participation Receipt (PPR) reputation system, capability-based private data sharing, and governance workflows.
System Architecture

Lobby DNA (separate network seed) is the permissionless entry point — no DHT write required for browsing. The three NDO zomes handle identity, resource data, and governance. zome_gouvernance bridges to hREA DNA for canonical ValueFlows event recording.
Nondominium is a multi-DNA Holochain hApp implementing ValueFlows-compliant resource sharing with embedded governance rules, cryptographically-secured reputation tracking through Private Participation Receipts (PPRs), and agent capability progression.
Nondominium DNA (3-zome core)
zome_person: Agent identity, profiles, roles, capability-based private data sharing, PPR integration, access controlzome_resource: Resource specifications, Economic Resources, governance rules, lifecycle management, custody transferszome_gouvernance: Economic events, commitments, claims, validation workflows, PPR issuance, agent validation. NDO federation extensions (PR #103) added three entry types:NdoHardLink(immutable OVN-licensed cross-NDO link backed by an EconomicEvent),Contribution(peer-validated work record; VF:vf:EconomicEvent/Work), andAgreement(versioned benefit redistribution agreement; VF:vf:Agreement). Seedocumentation/zomes/governance_zome.md §NDO Federation Extensionsfor API details.
Lobby DNA (network seed nondominium-lobby-v1, deferred: false)
zome_lobby: Global group registry, agent presence. Entry types:LobbyAgentProfile,GroupAnnouncement.
Group DNA (cloned cell, deferred: true, clone_limit: 64)
zome_group: Per-group coordination with network isolation. Each group occupies its own cloned DHT provisioned viaclone_cell. Entry types:GroupProfile,GroupMembership,WorkLog,SoftLink,NdoAnchor. See PR #107 and issue #112.
NDO DNA (cloned cell, deferred: true, clone_limit: 512)
ndorole (dnas/ndo/workdir/dna.yaml): one clone per NDO, completing the fractal Lobby → Group → NDO holarchy. Bundles the existingzome_resourceandzome_gouvernanceWASMs (ADR-012, no code fork). The NDO's immutable Layer 0 fields (name, initiator, property regime, resource nature, created_at) live in the clone's DNA properties, so the resultingDnaHashis the NDO's permanent, organization-agnostic identity (ADR-010); theNondominiumIdentitygenesis entry inside the cell keeps the mutable lifecycle chain. Groups reference NDO cells throughNdoAnchorentries carrying the full clone coordinates (ADR-011). See issue #112.
Technology Foundation
- Backend: Rust (Holochain HDK ^0.6.0 / HDI ^0.7.0), WASM compilation
- Data Model: Agent-centric with public/private separation, progressive trust model (Simple → Accountable → Primary Accountable Agent)
- Security: Progressive capability-based access using Holochain capability tokens (general → restricted → full) with automatic advancement based on PPR milestones
- Compliance: ValueFlows standard for economic resource management with nondominium extensions (VfAction enum, Economic Processes)
- Governance: Embedded rules, multi-reviewer validation (2-of-3, N-of-M, simple_majority), cryptographically-signed reputation tracking through PPRs
- Economic Processes: Four structured workflows (Use, Transport, Storage, Repair) with role-based access control and specialized validation requirements
- Private Data Sharing: Request/grant workflows with time-limited grants (30-day maximum per capability metadata; shorter UI defaults possible), field-specific control, and Economic Process coordination integration
- Reputation System: 16 PPR categories, bi-directional receipt issuance, cryptographic signatures, privacy-preserving reputation derivation
Cross-Zome Integration Patterns
Enhanced Agent Capability Progression System
#![allow(unused)] fn main() { // Progressive trust model integration across all zomes with PPR milestone tracking let agent_capability = get_person_capability_level(agent_pubkey)?; let agent_reputation = derive_reputation_summary(agent_pubkey)?; match agent_capability.as_str() { "member" => { // Simple Agent: general capability token // Can create resources, make first transaction (InitialTransfer) // PPR eligibility: ResourceContribution upon resource validation // Promotion path: First transaction validation → Accountable Agent }, "stewardship" => { // Accountable Agent: restricted capability token // Can access resources, validate others, initiate Use processes // PPR eligibility: Service processes, validation activities // Promotion path: PPR milestones + specialized role validation → Primary Accountable Agent }, "coordination" | "governance" => { // Primary Accountable Agent: full capability token // Can hold custody, validate specialized roles, initiate all processes (Transport, Storage, Repair) // PPR eligibility: All 16 categories, including custodianship and governance participation // Advanced capabilities: Dispute resolution, end-of-life validation } } // Automatic capability token advancement based on PPR milestones if agent_reputation.total_interactions >= 5 && agent_reputation.completion_rate >= 0.8 { // Trigger capability token upgrade upgrade_capability_token(agent_pubkey, "restricted_access")?; } }
Enhanced Economic Process Role Enforcement
#![allow(unused)] fn main() { // Cross-zome role validation for specialized processes with validation history let process_type = "Transport"; // Use, Transport, Storage, Repair let required_role = match process_type { "Use" => None, // Accessible to all Accountable Agents "Transport" => Some("Transport"), "Storage" => Some("Storage"), "Repair" => Some("Repair"), _ => return Err(ProcessError::InvalidProcessType), }; if let Some(role) = required_role { // Check specialized role capability let has_role = has_person_role_capability((agent_pubkey, role.to_string()))?; if !has_role { return Err(ProcessError::InsufficientRole(role.to_string())); } // Validate role was properly validated by governance let role_validation = call( CallTargetCell::Local, "zome_gouvernance", "get_specialized_role_validation".into(), None, &GetRoleValidationInput { agent: agent_pubkey, role: role.to_string(), }, )?; if !role_validation.is_valid_and_current() { return Err(ProcessError::InvalidRoleValidation(role.to_string())); } } // Additional Economic Process workflow integration let process_creation_result = call( CallTargetCell::Local, "zome_resource", "initiate_economic_process".into(), None, &EconomicProcessInput { process_type: process_type.to_string(), name: format!("{} process for resource", process_type), resource_hashes: vec![resource_hash], location: Some(resource_location), }, )?; }
Enhanced Private Data Sharing Integration
#![allow(unused)] fn main() { // Automatic private data coordination for Economic Processes pub fn coordinate_process_private_data( process_hash: ActionHash, participants: Vec<AgentPubKey>, process_type: &str, ) -> ExternResult<Vec<ActionHash>> { let mut coordination_requests = Vec::new(); for participant in participants { // Determine required coordination fields based on process type let required_fields = match process_type { "Transport" => vec!["email", "phone", "location"], "Storage" => vec!["email", "phone", "emergency_contact"], "Repair" => vec!["email", "phone", "time_zone"], "Use" => vec!["email"], // Minimal coordination for use processes _ => vec![], }; if !required_fields.is_empty() { let request = call( CallTargetCell::Local, "zome_person", "request_private_data_access".into(), None, &DataAccessRequestInput { requested_from: participant, fields_requested: required_fields.iter().map(|s| s.to_string()).collect(), context: format!("{}_process_coordination", process_type), resource_hash: Some(resource_hash), justification: format!("Coordination required for {} process", process_type), }, )?; coordination_requests.push(request.request_hash); } } Ok(coordination_requests) } // Automatic grant approval for trusted Economic Process participants pub fn auto_approve_process_coordination( request_hash: ActionHash, requester: AgentPubKey, ) -> ExternResult<Option<ActionHash>> { // Check requester reputation and role validation let reputation = call( CallTargetCell::Local, "zome_gouvernance", "derive_reputation_summary".into(), None, &DeriveReputationSummaryInput { time_range: None, role_filter: None, include_recent_activity: false, }, )?; // Auto-approve for high-reputation, validated agents if reputation.completion_rate >= 0.9 && reputation.total_interactions >= 10 { let grant = call( CallTargetCell::Local, "zome_person", "respond_to_data_request".into(), None, &RespondToDataRequestInput { request_hash, approve: true, duration_days: Some(7), // Standard Economic Process coordination period }, )?; return Ok(grant); } Ok(None) // Requires manual approval } }
Enhanced PPR Integration Pattern
#![allow(unused)] fn main() { // Comprehensive PPR generation with 16 categories and bilateral signatures let ppr_result = call( CallTargetCell::Local, "zome_gouvernance", "issue_participation_receipts".into(), None, &IssueParticipationReceiptsInput { commitment_hash: commitment.hash(), event_hash: economic_event.hash(), counterparty: commitment.receiver, performance_metrics: calculate_performance_metrics(&commitment, &event)?, interaction_context: determine_interaction_context(&commitment.action, &process_context)?, role_context: get_role_context(&process_context)?, }, )?; // Bi-directional PPR issuance with cryptographic signatures let provider_ppr = PrivateParticipationClaim { fulfills: commitment_hash, fulfilled_by: event_hash, claimed_at: sys_time()?, claim_type: determine_provider_claim_type(&commitment.action, &process_context)?, counterparty: commitment.receiver, performance_metrics: ppr_result.provider_metrics, bilateral_signature: ppr_result.provider_signature, interaction_context: ppr_result.interaction_context, role_context: ppr_result.role_context, resource_reference: Some(commitment.resource_inventoried_as), }; let receiver_ppr = PrivateParticipationClaim { fulfills: commitment_hash, fulfilled_by: event_hash, claimed_at: sys_time()?, claim_type: determine_receiver_claim_type(&commitment.action, &process_context)?, counterparty: commitment.provider, performance_metrics: ppr_result.receiver_metrics, bilateral_signature: ppr_result.receiver_signature, interaction_context: ppr_result.interaction_context, role_context: ppr_result.role_context, resource_reference: Some(commitment.resource_inventoried_as), }; // PPRs stored as private entries, accessible only to owning agents // No DHT links created for privacy preservation }
PPR Category Determination Logic

VfAction + process_type → correct PPR claim type pair. Every interaction generates exactly 2 receipts (one per agent). Create/Produce → Genesis group. Transfer → Core Custody group. Service commitments branch by process_type (Maintenance/Storage/Transport) into commitment-phase and fulfillment-phase receipt pairs.
#![allow(unused)] fn main() { // Comprehensive PPR category assignment based on Economic Process context pub fn determine_ppr_categories( action: &VfAction, process_type: &str, agent_role: &str, interaction_context: &str, ) -> (ParticipationClaimType, ParticipationClaimType) { match (action, process_type, agent_role, interaction_context) { // Genesis Role - Network Entry (VfAction::InitialTransfer, _, "Simple Agent", "resource_creation") => ( ParticipationClaimType::ResourceContribution, ParticipationClaimType::NetworkValidation, ), // Core Usage Role - Custodianship (VfAction::TransferCustody, _, _, "custody_transfer") => ( ParticipationClaimType::ResponsibleTransfer, ParticipationClaimType::CustodyAcceptance, ), // Specialized Economic Processes (VfAction::Use, "Use", _, _) => ( ParticipationClaimType::ServiceCommitmentAccepted, ParticipationClaimType::ServiceFulfillmentCompleted, ), (VfAction::Work, "Transport", "Transport", _) => ( ParticipationClaimType::TransportFulfillment, ParticipationClaimType::ServiceCommitmentAccepted, ), (VfAction::Work, "Storage", "Storage", _) => ( ParticipationClaimType::StorageFulfillment, ParticipationClaimType::ServiceCommitmentAccepted, ), (VfAction::Modify, "Repair", "Repair", _) => ( ParticipationClaimType::MaintenanceFulfillment, ParticipationClaimType::ServiceFulfillmentCompleted, ), // Network Governance (_, _, _, "validation_activity") => ( ParticipationClaimType::NetworkValidation, ParticipationClaimType::GovernanceCompliance, ), (_, _, _, "end_of_life") => ( ParticipationClaimType::EndOfLifeDeclaration, ParticipationClaimType::EndOfLifeValidation, ), (_, _, _, "dispute_resolution") => ( ParticipationClaimType::DisputeResolutionParticipation, ParticipationClaimType::GovernanceCompliance, ), // Default case _ => ( ParticipationClaimType::ServiceCommitmentAccepted, ParticipationClaimType::ServiceFulfillmentCompleted, ), } } }
Resource-Governance Integration
#![allow(unused)] fn main() { // Resource validation triggering governance workflows let resource_validation = ResourceValidation { resource: resource_hash, validation_scheme: "2-of-3".to_string(), required_validators: 2, current_validators: 0, status: "pending".to_string(), }; // Cross-zome validation coordination let governance_result = call( CallTargetCell::Local, "zome_gouvernance", "initiate_resource_validation".into(), None, &resource_validation, )?; // Automatic PPR issuance for validation participation let validation_pprs = call( CallTargetCell::Local, "zome_gouvernance", "issue_validation_participation_receipts".into(), None, &ValidationPPRInput { resource_hash, validator: agent_pubkey, validation_type: "resource_approval".to_string(), }, )?; }
Shared Infrastructure
Signal Architecture
Enhanced Multi-Zome Signals
#![allow(unused)] fn main() { pub enum Signal { // Resource lifecycle signals EntryCreated { action, app_entry }, EntryUpdated { action, app_entry, original_app_entry }, EntryDeleted { action, original_app_entry }, LinkCreated { action, link_type }, LinkDeleted { action, link_type }, // Economic Process signals ProcessInitiated { process_hash, process_type, agent }, ProcessCompleted { process_hash, completion_event, performance_metrics }, ProcessValidated { process_hash, validator, approved }, // PPR system signals PPRIssued { recipient, claim_type, counterparty }, ReputationUpdated { agent, new_summary }, // Governance workflow signals ValidationRequired { item_hash, validation_type, scheme }, ValidationCompleted { item_hash, result, validators }, AgentPromoted { agent, from_level, to_level }, } }
Real-time Updates: Enables UI reactivity to all system changes Cross-Zome Coordination: Supports complex workflows spanning multiple zomes PPR Integration: Real-time reputation updates and participation tracking Process Management: Live updates on Economic Process status and completion
Discovery Performance
Anchor Path Strategy
- Categorized Discovery: O(1) lookup by category/tag
- Agent-Centric Queries: Direct agent -> owned resources links
- Versioning: Efficient latest version resolution
- Bulk Operations: Optimized for large result sets
Link Tag Optimization
#![allow(unused)] fn main() { // Category-based discovery with tag metadata create_link( category_path.path_entry_hash()?, spec_hash.clone(), LinkTypes::SpecsByCategory, LinkTag::new(category_name.as_str()), )?; }
Performance: Link tags enable efficient filtering without record retrieval
Common Patterns
Entry Creation Pattern
All zomes follow this standardized pattern for creating entries:
#![allow(unused)] fn main() { // Standard entry creation with discovery links let entry = EntryType { field: value, agent_pub_key: agent_info.agent_initial_pubkey, created_at: sys_time()?, }; let hash = create_entry(&EntryTypes::EntryType(entry.clone()))?; // Create discovery anchor links let path = Path::from("anchor_name"); create_link(path.path_entry_hash()?, hash.clone(), LinkTypes::AnchorType, LinkTag::new("tag"))?; }
Versioning Pattern
#![allow(unused)] fn main() { // Update pattern with version history tracking let updated_entry = update_entry(input.previous_action_hash, &updated_data)?; create_link( input.original_action_hash, updated_entry.clone(), LinkTypes::EntryUpdates, (), )?; }
Discovery Pattern
#![allow(unused)] fn main() { // Efficient anchor-based discovery let path = Path::from("discovery_anchor"); let links = get_links( GetLinksInputBuilder::try_new(path.path_entry_hash()?, LinkTypes::DiscoveryType)?.build(), )?; }
Privacy Architecture
Four-Layer Privacy Model

Absolute privacy by default. Outermost: public DHT (readable by all). Second: access-controlled via capability grants. Third: private source chain entries (owner only — PPRs, private PII). Innermost: derived summaries (agent-controlled selective disclosure, not stored on DHT).
1. Public Data Layer
- Person entries: Name, avatar, bio (discoverable by all agents)
- Role assignments: Role name, assignment metadata (auditable governance)
- Resource specifications: Name, description, category (community discovery)
- Economic events: Public record of economic activities (audit trail)
- Validation receipts: Public governance validation records
2. Private Data Layer
- PrivatePersonData entries: PII, contact info (owner-only access)
- PrivateParticipationClaims: Cryptographically-signed reputation receipts (private entries)
- Holochain Security: Private entry visibility enforced by conductor
3. Access-Controlled Layer
- Role-based permissions: Capability-driven resource access
- Governance rules: Community-managed access controls
- Custodian permissions: Resource-specific access rights
- Process validation: Specialized role validation for Economic Processes
4. Derived Data Layer
- Reputation summaries: Calculated from private PPRs, selectively shared
- Performance metrics: Aggregated from participation claims
- Trust scores: Derived reputation indicators for decision-making
Access Control Implementation
#![allow(unused)] fn main() { // Four-tier access pattern with PPR integration match access_level { Public => { // Anyone can read public entries get_public_data(entry_hash) }, Private => { // Only owner can access private entries (PPRs, PII) if caller == owner { get_private_data(entry_hash) } else { Err(NotAuthorized) } }, RoleBased => { // Check role-based permissions for processes let has_permission = check_role_capability(caller, required_role)?; if has_permission { get_controlled_data(entry_hash) } else { Err(InsufficientCapability) } }, ReputationBased => { // Access based on derived reputation metrics let reputation = get_agent_reputation_summary(caller)?; if reputation.meets_threshold(required_threshold) { get_reputation_gated_data(entry_hash) } else { Err(InsufficientReputation) } } } }
Private Participation Receipt (PPR) System
PPR Infrastructure Architecture
#![allow(unused)] fn main() { // PPR lifecycle: automatic generation for every economic interaction pub struct PPRGenerationWorkflow { // 1. Commitment created commitment: Commitment, // 2. Economic event occurs event: EconomicEvent, // 3. Claim links commitment to event (public governance record) claim: Claim, // 4. Bi-directional PPRs automatically generated (private entries) provider_ppr: PrivateParticipationClaim, receiver_ppr: PrivateParticipationClaim, } // Cross-zome PPR coordination impl PPRGenerationWorkflow { pub fn execute(&self) -> ExternResult<(ActionHash, ActionHash)> { // 1. Generate performance metrics let metrics = self.calculate_performance_metrics()?; // 2. Create cryptographic signatures let signatures = self.create_bilateral_signatures()?; // 3. Store PPRs as private entries in zome_person let provider_ppr_hash = self.store_provider_ppr(metrics.clone(), signatures.provider)?; let receiver_ppr_hash = self.store_receiver_ppr(metrics, signatures.receiver)?; // 4. Update agent reputation caches self.update_reputation_summaries()?; // 5. Emit signals for real-time UI updates self.emit_ppr_signals()?; Ok((provider_ppr_hash, receiver_ppr_hash)) } } }
PPR Categories and Issuance Patterns
#![allow(unused)] fn main() { // PPR issuance based on economic interaction context pub fn determine_ppr_category( action: &VfAction, process_type: &str, agent_role: &str, ) -> Vec<ParticipationClaimType> { match (action, process_type, agent_role) { // Simple Agent first transaction (VfAction::InitialTransfer, _, "Simple Agent") => vec![ ParticipationClaimType::ResourceContribution, ParticipationClaimType::NetworkValidation, ], // Core Use process (VfAction::Use, "Use", _) => vec![ ParticipationClaimType::ServiceCommitmentAccepted, ParticipationClaimType::ServiceFulfillmentCompleted, ], // Specialized Transport process (VfAction::Work, "Transport", "Transport") => vec![ ParticipationClaimType::TransportFulfillment, ParticipationClaimType::CustodyAcceptance, ], // Specialized Repair process (VfAction::Modify, "Repair", "Repair") => vec![ ParticipationClaimType::MaintenanceFulfillment, ParticipationClaimType::ServiceFulfillmentCompleted, ], // Custody transfer (VfAction::TransferCustody, _, _) => vec![ ParticipationClaimType::ResponsibleTransfer, ParticipationClaimType::CustodyAcceptance, ], // Validation activities (_, _, "Validator") => vec![ ParticipationClaimType::NetworkValidation, ParticipationClaimType::GovernanceCompliance, ], _ => vec![], // No PPR generation for this combination } } }
Reputation Derivation and Selective Sharing
#![allow(unused)] fn main() { // Privacy-preserving reputation calculation pub fn calculate_reputation_summary(agent: AgentPubKey) -> ExternResult<ReputationSummary> { // Access agent's private PPR collection let pprs = get_my_participation_claims()?; let mut summary = ReputationSummary { agent, total_interactions: pprs.len() as u32, average_timeliness: 0.0, average_quality: 0.0, average_reliability: 0.0, average_communication: 0.0, completion_rate: 0.0, role_performance: HashMap::new(), recent_activity: Vec::new(), calculated_at: sys_time()?, }; // Aggregate metrics from private claims for ppr in pprs { summary.aggregate_metrics(&ppr.performance_metrics)?; summary.update_role_performance(&ppr)?; summary.track_recent_activity(&ppr)?; } summary.finalize_calculations(); Ok(summary) } // Selective reputation sharing pub fn share_reputation_summary( target_agent: AgentPubKey, sharing_scope: ReputationSharingScope, ) -> ExternResult<SelectiveReputationShare> { let full_summary = calculate_reputation_summary(agent_info()?.agent_initial_pubkey)?; match sharing_scope { ReputationSharingScope::Basic => { // Share only overall scores and completion rate SelectiveReputationShare::basic(full_summary) }, ReputationSharingScope::RoleSpecific(role) => { // Share detailed metrics for specific role SelectiveReputationShare::role_specific(full_summary, role) }, ReputationSharingScope::Comprehensive => { // Share detailed breakdown (requires higher trust level) SelectiveReputationShare::comprehensive(full_summary) }, } } }
ValueFlows Compliance
Enhanced Agent-Centric Model
- Agents as Economic Actors: Every participant is an autonomous economic agent with progressive capability levels
- Identity and Reputation: Comprehensive agent profiles with role-based capabilities and cryptographically-signed reputation tracking
- Decentralized Coordination: No central authority, community-governed resource sharing with embedded governance rules
- Process-Aware Interactions: All economic activities occur within structured Economic Processes
Comprehensive Economic Resource Management
- Resource Specifications: Templates defining resource types, embedded governance rules, and process requirements
- Economic Resources: Actual resource instances with clear custodianship and lifecycle tracking
- Economic Processes: Structured activities (Use, Transport, Storage, Repair) with role-based access control
- Economic Events: VfAction-based event tracking with automatic PPR generation
- Governance Rules: Community-defined access and usage policies enforced programmatically
VfAction Enum Implementation
#![allow(unused)] fn main() { // Type-safe ValueFlows action representation with nondominium extensions #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] pub enum VfAction { // Standard ValueFlows actions Transfer, Move, Use, Consume, Produce, Work, Modify, Combine, Separate, Raise, Lower, Cite, Accept, // nondominium-specific extensions InitialTransfer, // Simple Agent first transaction AccessForUse, // Request access commitment TransferCustody, // Primary Accountable Agent custody transfer } impl VfAction { // Process-aware action classification pub fn requires_specialized_role(&self, process_type: &str) -> Option<String> { match (self, process_type) { (VfAction::Work, "Transport") => Some("Transport".to_string()), (VfAction::Work, "Storage") => Some("Storage".to_string()), (VfAction::Modify, "Repair") => Some("Repair".to_string()), (VfAction::Use, _) => None, // Accessible to all Accountable Agents _ => None, } } // PPR integration pub fn triggers_ppr_generation(&self) -> bool { matches!(self, VfAction::InitialTransfer | VfAction::Use | VfAction::Work | VfAction::Modify | VfAction::TransferCustody ) } } }
Enhanced Compliance Implementation
#![allow(unused)] fn main() { // Comprehensive ValueFlows compliance with nondominium extensions pub struct EconomicResource { pub conforms_to: ActionHash, // ResourceSpecification compliance pub quantity: f64, // Measurable resource quantity pub unit: String, // Standard measurement unit pub custodian: AgentPubKey, // Primary Accountable Agent pub current_location: Option<String>, // Resource location tracking pub operational_state: OperationalState, // Process condition (Layer 2 instance); lifecycle on NondominiumIdentity pub governance_rules: Vec<GovernanceRule>, // Embedded governance pub validation_status: String, // Peer validation status pub process_history: Vec<ActionHash>, // Economic Process audit trail } pub struct EconomicProcess { pub process_type: String, // Use, Transport, Storage, Repair pub required_role: String, // Role-based access control pub inputs: Vec<ActionHash>, // Input resources pub outputs: Vec<ActionHash>, // Output resources pub status: ProcessStatus, // Process lifecycle state pub validation_requirements: ProcessValidationRequirements, } pub struct EconomicEvent { pub action: VfAction, // Type-safe ValueFlows action pub provider: AgentPubKey, // Agent providing pub receiver: AgentPubKey, // Agent receiving pub resource_inventoried_as: ActionHash, // Affected resource pub input_of: Option<ActionHash>, // Parent Economic Process pub ppr_generated: bool, // Automatic PPR issuance flag } }
Multi-Layered Ontology Support
#![allow(unused)] fn main() { // ValueFlows three-layer ontology implementation pub enum OntologyLayer { Knowledge { // Resource specifications, governance rules, process templates resource_specs: Vec<ResourceSpecification>, governance_rules: Vec<GovernanceRule>, process_templates: Vec<ProcessTemplate>, }, Plan { // Commitments, process initiations, validation workflows commitments: Vec<Commitment>, planned_processes: Vec<EconomicProcess>, validation_schemes: Vec<ValidationScheme>, }, Observation { // Economic events, completed processes, issued PPRs economic_events: Vec<EconomicEvent>, completed_processes: Vec<CompletedProcess>, validation_receipts: Vec<ValidationReceipt>, participation_claims: Vec<PrivateParticipationClaim>, }, } }
Development Status
Phase 1: Foundation Layer ✅ COMPLETED (Existing Working Code)
- ✅ Agent Identity & Role System: Comprehensive identity with sophisticated three-tier privacy layers and 8-level role hierarchy
- ✅ Progressive Capability System: Complete Simple → Accountable → Primary Accountable Agent progression
- ✅ Resource Specifications: ValueFlows-compliant resource templates with embedded governance rules and process requirements
- ✅ Discovery Patterns: Optimized anchor-based queries with performance optimization and multi-dimensional filtering
- ✅ Governance Foundation: Multi-reviewer validation schemes (2-of-3, N-of-M, simple_majority) and rule enforcement framework
- ✅ Cross-Zome Integration: Complete authorization and capability checking across all three zomes
- ✅ VfAction Enum: Type-safe ValueFlows action implementation with nondominium extensions and helper methods
- ✅ Economic Resource Lifecycle: Complete resource instance management with state tracking and custody transfers
- ✅ Basic Governance Infrastructure: ValidationReceipt creation, economic event logging, cross-zome validation functions
Phase 2: Enhanced Governance & Process Integration ✅ COMPLETED
- ✅ Enhanced Private Data Sharing: Complete DataAccessRequest/Grant workflows with time-limited grants (30-day cap) and field-specific control
- ✅ Economic Process Infrastructure: Four structured processes (Use, Transport, Storage, Repair) with role-based access control
- ✅ Private Participation Receipt (PPR) System: Complete 14-category PPR system with bi-directional receipt issuance
- ✅ Agent Capability Progression: Complete Simple → Accountable → Primary Accountable Agent advancement with PPR integration
- ✅ Cross-Zome Coordination: Seamless coordination across person, resource, and governance zomes for complete workflows
- ✅ Validation Workflows: Resource validation, agent promotion, and specialized role validation fully operational
- ✅ Cryptographic Integrity: All PPRs cryptographically signed with bilateral authentication
- ✅ Performance Metrics Integration: Quantitative performance tracking embedded in all economic interactions
- ✅ Role-Based Process Access: Specialized roles (Transport, Repair, Storage) enabling restricted Economic Process participation
- ✅ Process-Aware Governance: Economic Process validation with quality assurance and completion validation
- ✅ Reputation Derivation: Privacy-preserving reputation calculation with selective disclosure control
- ✅ Economic Event Integration: Complete VfAction-based event tracking with automatic PPR generation
Phase 3: Advanced Security & Cross-Zome Coordination 🔄 IN PROGRESS
- 🔄 Progressive Capability Tokens: Automatic capability token progression based on PPR milestones (implementation underway)
- 🔄 Economic Process Access Control: Role-validated access to specialized processes with reputation influence
- 🔄 Transaction Consistency: Atomic operations across all three zomes with comprehensive rollback mechanisms
- 📋 Advanced Validation Schemes: PPR-weighted validator selection and reputation-based consensus
- 📋 Dispute Resolution: Edge-based conflict resolution with PPR context and private data coordination
Phase 3 — Agent Ontology Expansion 📋 PLANNED (see documentation/archives/agent.md)
TODO: The following agent-layer gaps were identified against the OVN wiki ontology (15 years of commons-based peer production practice). The current implementation models only individual agents. The items below must be incorporated into Phase 3 planning. See
documentation/zomes/person_zome.mdFuture Enhancements section anddocumentation/implementation_plan.mdPhase 3 for detailed task breakdowns.
Phase 3 Agent Items:
- 📋 [G1]
AgentEntityTypefield: Distinguish Individual, Collective, Project, Network, Bot, ExternalOrganisation agents (REQ-AGENT-01) - 📋 [G15] CapabilitySlot on Person: Stigmergic attachment surface for DID documents, credential wallets, reputation oracles (
REQ-AGENT-11) - 📋 [G3] Composable
AgentProfileview: Assembled from Person + ReputationSummary + Roles + CapabilitySlots + affiliations (REQ-AGENT-07) - 📋 [G4]
AgentRelationshiplink type: Bidirectional typed private peer relationships (REQ-AGENT-08) - 📋 [G5] Network affiliation links: Cross-NDO membership from Person hash to NDO instance hashes (
REQ-AGENT-09) - 📋 [G14] Configurable role taxonomy: Replace closed
RoleTypeenum with a community-configurable role registry (REQ-AGENT-06)
Phase 2 Agent Items (earlier priority):
- 📋 [G13] Fix
request_role_promotionstub: Real queryableRolePromotionRequestentry with discovery links (REQ-AGENT-16) - 📋 [G6]
AffiliationRecordentry: Formal Terms of Participation ceremony (REQ-AGENT-05) - 📋 [G2] Derived affiliation state: Computed from PPR activity — UnaffiliatedStranger → CloseAffiliate → ActiveAffiliate → CoreAffiliate → InactiveAffiliate (
REQ-AGENT-04)
Phase 4: Network Maturity & Advanced Features 📋 PLANNED
- 📋 Advanced Process Workflows: Multi-step process chaining with automated agent selection based on PPR reputation
- 📋 AI-Enhanced Reputation: Machine learning-based trust prediction and context-aware weighting
- 📋 Cross-Network Integration: PPR portability and federated identity management across multiple nondominium networks
- 📋 Performance Optimization: Large-scale network operation with predictive scaling and efficiency optimization
- 📋 Community Governance: Reputation-weighted validation and automated role progression based on performance metrics
Phase 4 Agent Items (see documentation/implementation_plan.md Phase 4):
- 📋 [G8]
PortableCredential: Bilaterally-signed, cross-network verifiable credential export (REQ-AGENT-12) - 📋 [G7] ZKP capability proofs: Prove eligibility without raw data disclosure (
REQ-AGENT-13) - 📋 [G9] Sybil resistance: Social vouching / Proof-of-Personhood configurable membrane proof (
REQ-AGENT-15) - 📋 [G10] Pseudonymous participation mode: Ephemeral key contribution, unlinkable to Person (
REQ-AGENT-14) - 📋 [G11] AI/bot delegation:
DelegatedAgentrelationship for scoped AI/bot acting on behalf of Person (REQ-AGENT-03) - 📋 [G12]
AgentNeedsWants: Optional profile extension for resource matching (REQ-AGENT-10)
Performance Considerations
Scalability Patterns
- Anchor-Based Discovery: O(1) category and tag lookups
- Agent-Centric Links: Direct ownership queries without scanning
- Lazy Loading: On-demand data retrieval for large datasets
- Batch Operations: Efficient bulk data processing
Optimization Strategies
- Link Tag Metadata: Rich link information without record retrieval
- Caching Strategies: Strategic data caching for frequent queries
- Pagination Support: Large result set management
- Selective Loading: Component-based data loading
Security Model
Holochain Security Features
- Agent Identity: Cryptographic agent verification
- Entry Validation: Comprehensive validation rules per entry type
- Private Entries: Conductor-enforced privacy
- Capability Tokens: Fine-grained access control (planned)
Application Security Layers
- Role-Based Authorization: Hierarchical capability system
- Governance Rule Validation: Community-enforced access controls
- Cross-Zome Verification: Multi-zome authorization checks
- Audit Trails: Complete action history and attribution
Error Handling Strategy
Comprehensive Error Types
Each zome implements domain-specific error enums with:
- Descriptive Messages: Clear error descriptions for debugging
- Error Categories: Logical grouping of related failures
- Recovery Guidance: Information for error resolution
- Cross-Zome Compatibility: Consistent error handling patterns
Error Propagation Pattern
#![allow(unused)] fn main() { // Standardized error handling across zomes match operation_result { Ok(data) => Ok(data), Err(domain_error) => { error!("Operation failed: {:?}", domain_error); Err(WasmError::from(domain_error)) } } }
Testing Architecture
Comprehensive Four-Layer Testing Strategy
- Foundation Tests: Basic zome function calls, connectivity, and individual component validation
- Integration Tests: Cross-zome interactions, multi-agent scenarios, and PPR generation workflows
- Scenario Tests: Complete user journeys, Economic Process workflows, and governance validation cycles
- Performance Tests: Load and stress testing for large-scale deployment (in progress)
Test Coverage Areas
- ✅ Person Management: Profiles, roles, privacy controls, PPR storage and retrieval
- ✅ Identity Storage: Public/private data separation, selective sharing mechanisms
- ✅ Role Assignment: Capability validation, specialized role validation, agent progression
- ✅ Resource Management: Specifications, Economic Resources, lifecycle management, embedded governance
- ✅ Governance Processes: Rule enforcement, validation workflows, multi-reviewer schemes
- ✅ Economic Processes: Use, Transport, Storage, Repair processes with role-based access control
- ✅ PPR System: Bi-directional receipt generation, cryptographic signatures, reputation derivation
- ✅ Agent Progression: Simple Agent promotion workflows, validation participation
- 🔄 End-of-Life Management: Resource decommissioning with enhanced security validation
- 🔄 Dispute Resolution: Edge-based conflict resolution mechanisms
- 📋 Performance Optimization: Large-scale network behavior and efficiency testing
This comprehensive architecture provides a production-ready, sophisticated foundation for ValueFlows-compliant resource sharing with advanced governance capabilities, Economic Process management, and privacy-preserving reputation tracking, including:
Core System Capabilities
- Progressive Trust Model: Three-tier agent capability system (Simple → Accountable → Primary Accountable Agent) with automatic PPR-based advancement
- Economic Process Management: Four structured workflows (Use, Transport, Storage, Repair) with role-based access control and specialized validation requirements
- Privacy-Preserving Reputation: 14-category PPR system with cryptographically-signed bilateral receipts enabling trust without compromising privacy
- Enhanced Private Data Sharing: Request/grant workflows with time-limited grants (30-day cap), field-specific control, and Economic Process coordination integration
- Embedded Governance: Community-defined rules enforced programmatically across all interactions with multi-reviewer validation schemes
- Cross-Zome Integration: Seamless coordination between identity, resource, and governance systems with atomic transaction support
Advanced Features
- Type-Safe Operations: VfAction enum with helper methods ensuring ValueFlows compliance with compile-time validation
- Cryptographic Integrity: All PPRs cryptographically signed with bilateral authentication for authenticity and non-repudiation
- Performance Metrics Integration: Quantitative performance tracking embedded in all economic interactions for quality assurance
- Scalable Infrastructure: Optimized discovery patterns, efficient anchor-based queries, and performance considerations for large-scale deployment
- Comprehensive Audit Trails: Complete tracking of all economic activities, governance decisions, and agent progression with privacy preservation
- Process-Aware Governance: Economic Process validation with completion requirements, state change validation, and automatic PPR generation
Production-Ready Implementation
The system demonstrates how decentralized, agent-centric architectures can support sophisticated governance models while maintaining the core principles of nondominium resources: organization-agnostic, capture-resistant, and permissionless access under transparent community governance.
With the completion of Phase 2, the system provides a comprehensive ecosystem for:
- Decentralized Resource Sharing with embedded governance and Economic Process support
- Privacy-Preserving Accountability through the PPR reputation system with selective disclosure
- Progressive Agent Capability advancement based on validated performance and community participation
- Sophisticated Economic Coordination through structured processes with role-based access control
- Cross-Zome Transaction Integrity ensuring atomic operations and comprehensive error handling
- Community-Driven Validation with configurable schemes and reputation-weighted participation
The nondominium hApp represents a mature, comprehensive implementation of ValueFlows principles extended with Economic Process management, private reputation tracking, and sophisticated governance workflows, providing a robust foundation for decentralized commons-based resource management at scale.
Person Zome (zome_person) Documentation
The Person zome provides the foundational identity, privacy, and access control infrastructure for the nondominium ecosystem. It implements Person-centric identity management, role-based access control, capability-based private data sharing, multi-device support, and integration with the Private Participation Receipt (PPR) reputation system.
Architecture Overview
The Person zome follows a Person-Centric Link Strategy with the relationship pattern: Agent → Person → Data
This architecture enables:
- Multi-device support: Multiple agents can represent the same person across different devices
- Unified identity: All data and roles are linked to the Person, not individual Agent devices
- Simplified link management: Single coherent strategy replacing multiple redundant approaches
- Scalable access control: Person-based permissions work across all devices
Core Data Structures
Person Entry
#![allow(unused)] fn main() { pub struct Person { pub name: String, // Public display name pub avatar_url: Option<String>, // Optional avatar URL (validated HTTP/HTTPS) pub bio: Option<String>, // Optional biography } }
TODO (G1 — AgentEntityType): Add an
agent_entity_type: AgentEntityTypefield to this struct (or to a companionAgentContextentry). This field distinguishes Individual, Collective, Project, Network, Bot, and ExternalOrganisation agents. Currently all agents are implicitly modelled as individual humans. Seeagent.md§6.1 andREQ-AGENT-01.TODO (G15 — CapabilitySlot on Agent): The
Personentry hash should serve as a stigmergic attachment surface — analogous to theNondominiumIdentityCapabilitySlot inndo_prima_materia.md§6. External credential wallets, DID documents, and reputation oracles should be attachable via typed DHT links from thePersonhash without modifying this entry. Flowsta is the first specified consumer:FlowstaIdentityslot →IsSamePersonEntry(ndo_prima_materia.md§6.5–6.7, REQ-NDO-CS-12–CS-15;documentation/requirements/post-mvp/flowsta-integration.md). Seedocumentation/archives/agent.md§3.2, §3.5 andREQ-AGENT-11.
Privacy: Public entry, discoverable by all agents Validation: Name required (1-100 chars), avatar URL format validation
PrivatePersonData Entry
#![allow(unused)] fn main() { pub struct PrivatePersonData { pub legal_name: String, // Full legal name pub email: String, // Contact email (validated) pub phone: Option<String>, // Optional phone number pub address: Option<String>, // Physical address pub emergency_contact: Option<String>, // Emergency contact info pub time_zone: Option<String>, // Time zone preference pub location: Option<String>, // Location/city } }
Privacy: Private entry, only accessible by owner Validation: Legal name and valid email required
Device Management Entries
AgentPersonRelationship Entry
#![allow(unused)] fn main() { pub struct AgentPersonRelationship { pub agent_pubkey: AgentPubKey, // Agent representing the person pub person_hash: ActionHash, // Person entry hash pub device_type: String, // Device type (mobile, desktop, web, etc.) pub device_name: Option<String>, // User-friendly device name pub created_at: Timestamp, // When relationship was created pub is_active: bool, // Whether device is currently active } }
Purpose: Links Agents to Persons, enabling multi-device scenarios Validation: One-to-one Agent-Person relationship prevents ambiguity
Device Entry
#![allow(unused)] fn main() { pub struct Device { pub device_id: String, // Unique device identifier pub device_type: String, // Device category pub device_name: String, // User-friendly name pub person_hash: ActionHash, // Associated person pub created_at: Timestamp, // Device registration time pub last_active: Timestamp, // Last activity timestamp pub capabilities: Vec<String>, // Device-specific capabilities } }
Purpose: Physical device management for security and access control Features: Activity tracking, capability management, device lifecycle
DeviceSession Entry
#![allow(unused)] fn main() { pub struct DeviceSession { pub device_id: String, // Device identifier pub session_start: Timestamp, // Session start time pub session_end: Option<Timestamp>, // Session end time (optional for active sessions) pub ip_address: Option<String>, // Network location pub user_agent: Option<String>, // Client information } }
Purpose: Session tracking for security and audit purposes Security: Enables device-based security policies and monitoring
PersonRole Entry
#![allow(unused)] fn main() { pub struct PersonRole { pub role_name: String, // Role name from RoleType enum pub description: Option<String>, // Role description pub assigned_to: AgentPubKey, // Agent receiving the role pub assigned_by: AgentPubKey, // Agent assigning the role pub assigned_at: Timestamp, // Assignment timestamp } }
Governance: Only predefined role types allowed Authorization: Role assignment tracked with metadata
Role Types Hierarchy
#![allow(unused)] fn main() { pub enum RoleType { SimpleAgent, // Simple Agent capabilities AccountableAgent, // Accountable Agent level PrimaryAccountableAgent, // Primary Accountable Agent level Transport, // Transport process access Repair, // Repair process access Storage, // Storage process access } }
TODO (G14 — Configurable Role Taxonomy): This enum is currently closed — only these six role types exist and communities cannot define their own. The OVN model requires that roles emerge from community needs, not from infrastructure decisions. Post-MVP,
RoleTypeshould become either an open string-tagged enum or a configurable registry of role entries defined per network. These six roles become sensible defaults, not constraints. Seeagent.md§5.3 andREQ-AGENT-06.
Agent Capability Progression:
- Simple Agent (Entry Level): Default capabilities
- Accountable Agent (Validated): Enhanced capabilities after resource validation
- Primary Accountable Agent (Custodian): Full governance rights and physical custody
- Specialized Roles: Transport, Repair, Storage for specific service types
Capability-Based Private Data Sharing
PrivateDataCapabilityMetadata Entry
#![allow(unused)] fn main() { pub struct PrivateDataCapabilityMetadata { pub grant_hash: ActionHash, // Hash of the capability grant pub granted_to: AgentPubKey, // Agent granted access pub granted_by: AgentPubKey, // Agent granting access (data owner) pub fields_allowed: Vec<String>, // Specific fields accessible pub context: String, // Context for the access pub expires_at: Timestamp, // When access expires pub created_at: Timestamp, // When grant was created pub cap_secret: CapSecret, // Capability secret for validation } }
FilteredPrivateData Structure
#![allow(unused)] fn main() { pub struct FilteredPrivateData { pub legal_name: Option<String>, // Never shared for privacy pub email: Option<String>, // Email if granted pub phone: Option<String>, // Phone if granted pub address: Option<String>, // Address if granted pub emergency_contact: Option<String>, // Emergency contact if granted pub time_zone: Option<String>, // Time zone if granted pub location: Option<String>, // Location if granted } }
Capability Access Patterns:
- Field-Level Control: Granular access to specific private data fields
- Time-Limited Access: Automatic expiration with configurable duration (max 30 days)
- Context-Aware Grants: Access linked to specific purposes and resource transfers
- Holochain Native Security: Uses CapGrant/CapClaim system for cryptographic access control
API Functions
Person Management
create_person(input: PersonInput) -> ExternResult<Record>
Creates a new person profile for the calling agent.
Input:
#![allow(unused)] fn main() { pub struct PersonInput { pub name: String, pub avatar_url: Option<String>, pub bio: Option<String>, } }
Business Logic:
- Validates one person per agent through AgentPersonRelationship (prevents duplicates)
- Creates discovery links for efficient queries
- Establishes Person-centric identity foundation
Links Created:
persons anchor -> person_hash(global discovery)agent_pubkey -> person_hash(via AgentPersonRelationship)person_hash -> agent_pubkey(reverse lookup for device management)
update_person(input: UpdatePersonInput) -> ExternResult<Record>
Updates an existing person profile with versioning support.
Authorization: Only the person's author can update Versioning: Creates update links for version history
get_latest_person(original_action_hash: ActionHash) -> ExternResult<Person>
Retrieves the latest version of a person profile.
Pattern: Follows update chain via PersonUpdates links
Performance: Optimized with timestamp-based latest selection
get_all_persons() -> ExternResult<GetAllPersonsOutput>
Discovers all person profiles in the network.
Discovery Pattern: Queries the persons anchor path
Output: Array of all public person profiles
get_person_profile(agent_pubkey: AgentPubKey) -> ExternResult<PersonProfileOutput>
Gets public profile information for a specific agent.
Privacy: Returns only public Person data, no private information
get_my_person_profile() -> ExternResult<PersonProfileOutput>
Gets complete profile information for the calling agent.
Privacy: Includes both public Person and private PrivatePersonData
Private Data Management
store_private_person_data(input: PrivatePersonDataInput) -> ExternResult<Record>
Stores private personal information for the calling agent.
Security: Private entry visibility enforced by Holochain Linking: Automatically links to person profile if it exists
update_private_person_data(input: UpdatePrivatePersonDataInput) -> ExternResult<Record>
Updates private personal information.
Authorization: Private entry visibility ensures only owner can update
get_my_private_person_data() -> ExternResult<Option<PrivatePersonData>>
Retrieves private data for the calling agent.
Security: Only accessible by the data owner
Device Management
register_device_for_person(input: RegisterDeviceInput) -> ExternResult<Record>
Registers a new device for the calling agent's person.
Input:
#![allow(unused)] fn main() { pub struct RegisterDeviceInput { pub device_type: String, // Device category (mobile, desktop, web, etc.) pub device_name: String, // User-friendly device name pub capabilities: Vec<String>, // Device-specific capabilities } }
Business Logic:
- Links device to agent's existing person profile
- Creates AgentPersonRelationship for device tracking
- Automatically generates unique device identifier
- Supports device-specific capability management
Multi-Device Support: Enables same person across multiple devices
get_my_devices() -> ExternResult<GetMyDevicesOutput>
Retrieves all devices registered for the calling agent's person.
Output:
#![allow(unused)] fn main() { pub struct GetMyDevicesOutput { pub devices: Vec<Device>, } }
Security: Only accessible by the person who owns the devices Features: Returns device metadata, activity status, and capabilities
update_device_activity(device_id: String) -> ExternResult<()>
Updates the last activity timestamp for a device.
Usage: Called automatically during user interactions to maintain device activity tracking Security: Only device owner can update activity Purpose: Enables device-based security policies and session management
get_agent_person(agent_pubkey: AgentPubKey) -> ExternResult<Option<ActionHash>>
Retrieves the person hash associated with a specific agent.
Cross-Zome Usage: Essential for other zomes to resolve Agent → Person relationships Person-Centric Pattern: Core function enabling unified data access across devices Returns: Person hash if Agent-Person relationship exists, None otherwise
Capability-Based Private Data Sharing
grant_private_data_access(input: GrantPrivateDataAccessInput) -> ExternResult<GrantPrivateDataAccessOutput>
Creates a Holochain-native capability grant for private data access.
Input:
#![allow(unused)] fn main() { pub struct GrantPrivateDataAccessInput { pub agent_to_grant: AgentPubKey, pub fields_allowed: Vec<String>, // ["email", "phone", "location", "time_zone", "emergency_contact", "address"] pub context: String, pub expires_in_days: Option<u32>, // Default 7 days, max 30 days } }
Output:
#![allow(unused)] fn main() { pub struct GrantPrivateDataAccessOutput { pub grant_hash: ActionHash, pub cap_secret: CapSecret, pub expires_at: Timestamp, } }
Security: Uses Holochain's native CapGrant system Validation: Only allowed fields can be granted Automatic Enforcement: Holochain runtime validates capability claims
create_private_data_cap_claim(input: CreatePrivateDataCapClaimInput) -> ExternResult<CreatePrivateDataCapClaimOutput>
Creates a capability claim to access private data.
Usage: Required before accessing protected data Validation: Automatic Holochain capability checking
get_private_data_with_capability(input: GetPrivateDataWithCapabilityInput) -> ExternResult<FilteredPrivateData>
Accesses private data using a valid capability claim.
Protection: Automatically validated by Holochain capability system Field Filtering: Only returns fields included in the capability grant Privacy: Legal name never included in shared data
grant_role_based_private_data_access(input: GrantRoleBasedAccessInput) -> ExternResult<GrantPrivateDataAccessOutput>
Creates capability grants based on predefined role configurations.
Role Configurations:
- Simple Agent: email only, 7 days
- Accountable Agent: email + phone, 14 days
- Primary Accountable Agent: email + phone + location, 30 days
- Transport/Repair/Storage: email + phone + location + time_zone, 21 days
create_transferable_private_data_access(input: CreateTransferableAccessInput) -> ExternResult<TransferableCapabilityOutput>
Creates transferable capability grants that can be shared between agents.
Use Case: Guest access, temporary coordination, flexible sharing Security: Shorter duration for transferable capabilities
revoke_private_data_access(grant_hash: ActionHash) -> ExternResult<()>
Revokes a previously granted data access.
Authorization: Only the granting agent can revoke
get_my_capability_grants() -> ExternResult<Vec<PrivateDataCapabilityMetadata>>
Gets all capability grants created by the calling agent.
validate_capability_grant(grant_hash: ActionHash) -> ExternResult<bool>
Validates whether a capability grant is still valid and not expired.
Role Management
assign_person_role(input: PersonRoleInput) -> ExternResult<Record>
Assigns a role to an agent in the community.
Input:
#![allow(unused)] fn main() { pub struct PersonRoleInput { pub agent_pubkey: AgentPubKey, pub role_name: String, // Must match RoleType enum pub description: Option<String>, } }
Validation: Role name must be from predefined RoleType enum
Cross-Zome Integration: For specialized roles, calls governance zome for validation
Metadata: Tracks who assigned the role and when
get_person_roles(agent_pubkey: AgentPubKey) -> ExternResult<GetPersonRolesOutput>
Retrieves all roles assigned to a specific agent.
Pattern: Follows AgentToPerson -> PersonToRoles link chain
Versioning: Gets latest version of each role
get_my_person_roles() -> ExternResult<GetPersonRolesOutput>
Gets all roles for the calling agent.
has_person_role_capability(input: (AgentPubKey, String)) -> ExternResult<bool>
Checks if an agent has a specific role capability.
Usage: Access control validation in other zomes Performance: Optimized boolean check
get_person_capability_level(agent_pubkey: AgentPubKey) -> ExternResult<String>
Determines the highest capability level for an agent based on their roles.
Returns: "governance" | "coordination" | "stewardship" | "member" Logic: Hierarchical evaluation of role capabilities
Agent Promotion and Validation
promote_agent_to_accountable(input: PromoteAgentInput) -> ExternResult<String>
Promotes a Simple Agent to Accountable Agent status through governance validation.
Input:
#![allow(unused)] fn main() { pub struct PromoteAgentInput { pub agent: AgentPubKey, pub first_resource_hash: ActionHash, } }
Cross-Zome Integration: Calls zome_gouvernance.validate_agent_identity
Governance: Implements agent validation workflow
Agent Progression: Transitions Simple Agent → Accountable Agent after validation
promote_agent_with_validation(input: PromoteAgentInput) -> ExternResult<Record>
Promotes an agent with comprehensive validation workflow.
Process: Multi-step validation with governance integration Validation: Creates validation receipt and triggers PPR generation
request_role_promotion(input: RolePromotionRequest) -> ExternResult<ActionHash>
Requests promotion to a higher role level.
Workflow: Creates request for existing agents to validate and approve
approve_role_promotion(input: ApprovePromotionInput) -> ExternResult<Record>
Approves a role promotion request.
Authorization: Only existing Primary Accountable Agents can approve promotions
Cross-Zome Integration Functions
validate_agent_private_data(input: ValidationDataRequest) -> ExternResult<ValidationResult>
Validates agent private data for governance workflows.
Purpose: Enables governance zome to validate agent identity and private data Privacy: Requires explicit consent for private data access
validate_agent_private_data_with_grant(input: ValidationDataRequestWithGrant) -> ExternResult<ValidationResult>
Validates agent private data using existing capability grant.
Usage: Optimized validation when access has already been granted
Link Architecture
The Person-Centric Link Strategy uses a unified Agent → Person → Data pattern that simplifies access while enabling multi-device scenarios.
Discovery Links
- AllPersons:
persons anchor -> person_hash- Global person discovery - AgentToPerson:
agent_pubkey -> person_hash- Agent-to-Person relationship lookup - PersonToAgent:
person_hash -> agent_pubkey- Reverse lookup for device management
Privacy Links (Person-Centric)
- PersonToPrivateData:
person_hash -> private_data_hash- Primary private data access - PrivateDataUpdates:
original_hash -> updated_hash- Private data version history
Key Improvement: Simplified from 3 redundant strategies to 1 unified Person-centric approach
Role Links (Person-Centric)
- PersonToRoles:
person_hash -> role_hash- Person role queries (works across all devices) - RoleUpdates:
original_hash -> updated_hash- Role version history
Multi-Device Benefit: Roles are assigned to Persons, not individual Agents, so they work across all devices
Versioning Links
- PersonUpdates:
original_hash -> updated_hash- Person version history
Device Management Links
- PersonToDevices:
person_hash -> device_hash- All devices belonging to a person - DeviceToSessions:
device_id -> session_hash- Device session tracking - AgentToRelationship:
agent_pubkey -> relationship_hash- AgentPersonRelationship tracking
Capability Management Links
- AgentToCapabilityMetadata:
agent_pubkey -> grant_hash- Track grants created by agent - RevokedGrantAnchor: Anchor for revoked capability grants
Cross-Zome Integration Pattern
#![allow(unused)] fn main() { // Other zomes use this pattern for Person-centric access let person_hash = call( CallTargetCell::Local, "zome_person", "get_agent_person".into(), None, &agent_pubkey, )?; if let Some(person) = person_hash { // Access Person's data, roles, resources let roles = call("zome_person", "get_person_roles", None, &person_hash)?; let resources = call("zome_resource", "get_person_resources", None, &person_hash)?; } }
Error Handling
PersonError Types
PersonError is defined in crates/utils/src/errors.rs and imported by zome_person.
#![allow(unused)] fn main() { pub enum PersonError { PersonAlreadyExists, // One person per agent restriction PersonNotFound(String), // Person lookup failures PrivateDataNotFound, // Private data access failures RoleNotFound(String), // Role lookup failures NotAuthor, // Authorization failures SerializationError(String), // Data serialization issues EntryOperationFailed(String), // DHT operation failures LinkOperationFailed(String), // Link operation failures InvalidInput(String), // Input validation failures InsufficientCapability(String), // Capability level restrictions } }
Pattern: Comprehensive error coverage with descriptive messages
Integration: Converts to WasmError for Holochain compatibility via From<PersonError> for WasmError in nondominium_utils::errors
Privacy Model
Public Data Layer
- Person entries: Name, avatar, bio (discoverable)
- Role assignments: Role name, assignment metadata (auditable)
- Capability metadata: Grant information for audit trails
Private Data Layer
- PrivatePersonData entries: PII, contact info (owner-only access)
- Holochain Security: Private entry visibility enforced by conductor
Controlled Sharing Layer
- Capability grants: Time-limited, field-specific access grants
- Allowed Fields: email, phone, location, time_zone, emergency_contact, address
- Grant Duration: Maximum 30 days, configurable by data owner
- Context-Aware: Grants linked to specific purposes and resource transfers
Integration with Other Zomes
The Person-Centric architecture provides a unified integration pattern for all zomes.
Person-Centric Access Pattern
#![allow(unused)] fn main() { // RESOLUTION PATTERN: Agent → Person → Data let person_hash = call( CallTargetCell::Local, "zome_person", "get_agent_person".into(), None, &agent_pubkey, )?; if let Some(person) = person_hash { // Access Person's unified data across all their devices let roles = call("zome_person", "get_person_roles", None, &person_hash)?; let private_data = call("zome_person", "get_person_private_data", None, &person_hash)?; let resources = call("zome_resource", "get_person_resources", None, &person_hash)?; } }
Cross-Zome Role Validation (Person-Centric)
#![allow(unused)] fn main() { // Check if PERSON (not agent) has required role for operation let person_hash = call("zome_person", "get_agent_person", None, &agent_pubkey)?; if let Some(person) = person_hash { let has_capability = call( CallTargetCell::Local, "zome_person", "has_person_role_capability".into(), None, &(person, "required_role".to_string()), )?; } }
Multi-Device Benefit: Role validation works consistently across all user devices
Agent Capability Level Validation
#![allow(unused)] fn main() { // Check PERSON's capability level (unified across devices) let person_hash = call("zome_person", "get_agent_person", None, &agent_pubkey)?; if let Some(person) = person_hash { let capability_level = call( CallTargetCell::Local, "zome_person", "get_person_capability_level".into(), None, &person, )?; } }
Private Data Validation for Governance
#![allow(unused)] fn main() { // Governance zome accessing PERSON's private data (not agent-specific) let person_hash = call("zome_person", "get_agent_person", None, &agent_pubkey)?; if let Some(person) = person_hash { let validation_result = call( CallTargetCell::Local, "zome_person", "validate_agent_private_data".into(), None, &ValidationDataRequest { agent_to_validate: agent_pubkey, validation_type: "agent_promotion".to_string(), requesting_validator: validator_pubkey, validation_context: validation_hash, }, )?; } }
Resource Zome Integration
#![allow(unused)] fn main() { // Resources linked to PERSON, not individual agents let person_hash = call("zome_person", "get_agent_person", None, &agent_pubkey)?; if let Some(person) = person_hash { // Get all resources belonging to this person (across all devices) let resources = call("zome_resource", "get_person_resources", None, &person_hash)?; // Create new resource linked to person let resource = call("zome_resource", "create_resource", None, &ResourceInput { person_hash: person, // ... other fields })?; } }
Implementation Status
✅ Completed Features
- Person-Centric Architecture: Unified Agent → Person → Data relationship pattern
- Multi-Device Support: Complete device management with AgentPersonRelationship tracking
- Person Profile Management: Public identity with name, avatar, bio
- Private Data Management: Simplified Person-centric private data access (1 unified strategy)
- Role-Based Access Control: 6-level role hierarchy with Person-centric assignment
- Capability-Based Sharing: Holochain native CapGrant/CapClaim system for private data
- Device Management: Complete device registration, tracking, and session management
- Agent Promotion Workflows: Simple Agent → Accountable Agent promotion with governance validation
- Cross-Zome Integration: Person-centric role and capability validation for all zomes
- Versioning Support: Complete update history for persons, roles, and devices
- Privacy Controls: Four-layer privacy model with Person-centric access control
- Validation Functions: Private data validation for governance workflows
🚀 New Person-Centric Capabilities
- Simplified Link Management: Reduced from 3 redundant strategies to 1 unified approach
- Multi-Device Identity: Same Person can operate across multiple devices seamlessly
- Unified Data Access: All data (roles, resources, private info) accessed through Person
- Device Security Policies: Device-based access control and session management
- Cross-Device Consistency: Roles and permissions work consistently across all devices
🔧 Current Limitations
- No Economic Processes: Specialized roles (Transport, Repair, Storage) defined but not fully integrated with process workflows
- Basic PPR Integration: PPR system exists but integration with person zome is primarily through validation workflows
- No Role Delegation: Temporary role assignments and delegation workflows not implemented
- Limited Audit Features: Capability grant tracking exists but comprehensive audit trails need enhancement
Agent Ontology Gaps (identified against OVN wiki — see documentation/archives/agent.md §2.6):
| Gap | Gap ID | OVN Relevance | Impact |
|---|---|---|---|
| Only individual agents modelled | G1 | OVN: groups, projects, networks, bots are also agents | Cannot model collective agency, AI participants, or network-level actors |
| Binary in/out membership | G2 | OVN: UnaffiliatedStranger/Close/Active/Core/Inactive affiliation spectrum | Cannot determine governance eligibility algorithmically; 1-9-90 engagement reality is invisible |
| No composable AgentProfile | G3 | OVN: profile aggregates roles, contributions, relations, credentials | Person, ReputationSummary, and Roles are separate and unconnected |
| No social graph | G4 | OVN: social relations are part of profile and social capital | Cannot surface network wealth or organisational reach |
| No network affiliations | G5 | OVN: agents participate simultaneously in multiple networks | Single-network only; agents cannot be bridge nodes |
| No AffiliationRecord | G6 | OVN: formal ToP ceremony creates accountability for active affiliates | No formal onboarding; no machine-readable agreement to Terms of Participation |
request_role_promotion stubbed | G13 | Promotion requests cannot be queried or tracked | Approvers cannot discover pending requests; workflow is broken |
| Roles are predefined/closed | G14 | OVN: roles emerge from community needs | Communities cannot extend the role taxonomy |
📋 Future Enhancement Opportunities
The following items map directly to the gap IDs in documentation/archives/agent.md and the REQ-AGENT-* requirements in documentation/requirements/requirements.md:
Phase 2 (Near-term):
- [G13] Fix
request_role_promotionstub: Create a real queryableRolePromotionRequestentry with bidirectional discovery links so approvers can find and act on pending requests (seeREQ-AGENT-16). - [G6]
AffiliationRecordentry: Implement formal Terms of Participation ceremony — agent cryptographically signs acknowledgement of ToP, Nondominium & Custodian agreement, and Benefit Redistribution Algorithm (seeREQ-AGENT-05). - [G2] Derived affiliation state: Implement
get_affiliation_state(agent)as a computed query over existing PPR + contribution data —f(person_exists, contributions_count, last_contribution_ts, reputation_summary, affiliation_record_exists)→UnaffiliatedStranger | CloseAffiliate | ActiveAffiliate | CoreAffiliate | InactiveAffiliate(seeREQ-AGENT-04).
Phase 3 (Medium-term):
- [G1]
AgentEntityTypefield: Addagent_entity_type: AgentEntityTypeto agent context (Individual, Collective, Project, Network, Bot, ExternalOrganisation). Collective agents reference an NDO hash rather than a Person entry (seeREQ-AGENT-01,REQ-AGENT-02). - [G15] CapabilitySlot on Person: Implement typed DHT links from
Personhash to external capabilities — DID documents, credential wallets, reputation oracles — without modifying thePersonentry (seeREQ-AGENT-11). - [G3] Composable
AgentProfileview: Implementget_agent_profile(agent)that assembles Person + ReputationSummary + PersonRole list + active commitment count + economic event counts + CapabilitySlot attachments + network affiliations into one queryable output (seeREQ-AGENT-07). - [G4]
AgentRelationshiplink type: Bidirectional, typed (colleague, collaborator, trusted, voucher), private peer relationship links. Social capital must be legible to governance (seeREQ-AGENT-08). - [G5] Network affiliation links: Typed links from
Personhash to NDO instance hashes, modelling cross-network membership (seeREQ-AGENT-09). - [G14] Configurable role taxonomy: Replace closed
RoleTypeenum with a configurable role registry defined per network; predefined roles become defaults (seeREQ-AGENT-06).
Phase 4 (Long-term):
- [G8]
PortableCredentialstructure: Bilaterally signed credential export (issuer + agent signatures) verifiable by other Holochain networks. Types:RoleCredential,ReputationCredential,CompetencyCredential,AffiliationCredential(seeREQ-AGENT-12). - [G7] ZKP capability proofs: Integration of ZKP library or ZKP-compatible VC layer;
prove_capability(condition)without raw data disclosure — e.g., "I have ≥10 completed maintenance commitments" without revealing counterparties or timestamps (seeREQ-AGENT-13). - [G9] Sybil resistance: Social vouching (existing agents vouch for new agents), biometric opt-in, or Proof-of-Personhood integration as configurable membrane proof (see
REQ-AGENT-15). - [G10] Pseudonymous participation mode: Allow contribution under a temporary ephemeral key without linking to
Person. Contribution is recorded but unlinkable to physical identity (seeREQ-AGENT-14). - [G11] AI/bot delegation:
DelegatedAgentrelationship allowing a Person to authorise an AI or bot to act within defined scope and duration (seeREQ-AGENT-03). - [G12]
AgentNeedsWantsprofile extension: Optional profile extension declaring what resources the agent needs and what they can offer, enabling network-level matching (seeREQ-AGENT-10). - Cross-Network Identity: Federated identity management using PortableCredential + Holochain membrane proofs.
- Device Trust Scoring: Reputation-based device security policies.
- Advanced Session Management: Multi-device session coordination and security.
The Person zome provides the foundational identity and privacy infrastructure for the nondominium ecosystem, enabling secure agent interactions with comprehensive role-based governance and sophisticated private data sharing capabilities.
Resource Zome (zome_resource) Documentation
The Resource zome implements the core resource management infrastructure for the nondominium ecosystem, providing ValueFlows-compliant resource specification management, Economic Resource lifecycle tracking, governance rule enforcement, and custody transfer workflows. It serves as the foundation for all resource-related activities and supports the Private Participation Receipt (PPR) reputation system through comprehensive audit trails.
NDO Layer 0 (
NondominiumIdentity) is implemented — see### NondominiumIdentity Entry (Layer 0)below.TODO (post-MVP — NDO Layers 1 & 2, ndo_prima_materia.md §§4, 8, 10): Cross-layer link types not yet implemented:
NDOToSpecification— Layer 0 identity hash toResourceSpecification(Layer 1 activation)NDOToProcess— Layer 0 identity hash toProcess(Layer 2 activation)NDOToComponent— Layer 0 identity hash to child NDO identity hash (holonic composition)CapabilitySlot— Layer 0 identity hash to capability targets (stigmergic attachment surface)Unyt (post-MVP): endorsed economic terms use typed
EconomicAgreementGovernanceRuledata (ndo_prima_materia.md§6.6, REQ-NDO-CS-09–CS-11;documentation/requirements/post-mvp/unyt-integration.md).Source-NDO (post-MVP):
NondominiumIdentitymay represent generative ecological systems (watersheds, rivers, fisheries) as Source-NDOs — a typed NDO specialization that usesPropertyRegime::NondominiumorCommonPool, adds a linkedSourceProfileentry (condition indicators,stewarded_by,regime_state, etc.), and extends the governance-as-operator pattern with an adaptive cybernetic loop. Source-NDOs require thevf:SourceValueFlows extension for flow endpoints (seedocumentation/requirements/post-mvp/source-ndo-requirements.mdanddocumentation/hREA/valueflows-1.0-compliance.md §P3-1). No breaking changes to existingNondominiumIdentityfields are required;SourceProfileis a separate linked entry.
Core Data Structures
NondominiumIdentity Entry (Layer 0)
Permanent identity anchor for any resource. Exists from the moment of conception through end-of-life. The original ActionHash from create_ndo is the stable Layer 0 identity — it never changes even as lifecycle_stage evolves.
#![allow(unused)] fn main() { pub struct NondominiumIdentity { pub name: String, pub initiator: AgentPubKey, // immutable after creation pub property_regime: PropertyRegime, // immutable after creation pub resource_nature: ResourceNature, // immutable after creation pub lifecycle_stage: LifecycleStage, // mutable — changes on every transition pub created_at: Timestamp, // immutable after creation pub description: Option<String>, // immutable after creation pub successor_ndo_hash: Option<ActionHash>, // set once on → Deprecated (REQ-NDO-LC-06) pub hibernation_origin: Option<LifecycleStage>, // set on → Hibernating, cleared on exit } }
LifecycleStage (10 stages):
| Phase | Stages |
|---|---|
| Emergence | Ideation → Specification → Development → Prototype |
| Maturity | Stable → Distributed |
| Operation | Active |
| Suspension (reversible) | Hibernating |
| Terminal | Deprecated → EndOfLife |
State machine transitions are enforced by the integrity zome (see ndo_prima_materia.md §5.3). Hibernating is a memory-preserving pause — it resumes to the exact stage that was paused, not necessarily Active. Deprecated and EndOfLife are terminal (REQ-NDO-LC-04). Any non-terminal stage may enter Hibernating, Deprecated, or EndOfLife.
PropertyRegime (7 variants): Private, Commons, Collective, Pool, CommonPool, Public, Nondominium
ResourceNature (5 variants): Physical, Digital, Service, Hybrid, Information
Mutability (three conditionally-mutable fields):
| Field | Rule |
|---|---|
lifecycle_stage | Changes on every transition |
successor_ndo_hash | Set exactly once when entering Deprecated; immutable after |
hibernation_origin | Set to the paused stage when entering Hibernating; cleared on exit |
All other fields are permanently immutable after creation. Delete is always Invalid — Layer 0 is permanent.
Design note — NDO as identifier, not chronicle: lifecycle_stage at creation reflects the resource's actual state at registration time, not a claim about when it was originally conceived. An existing physical resource registered into the system is created at its true current stage (e.g. Active), not forced through a synthetic Ideation entry. The NDO identity anchor behaves like a DOI or ISBN: it is assigned at the moment of system registration, which may be well after the resource began its life. Forcing Ideation-only initial stages would require fabricating DHT history for brownfield resources and block migration of existing EconomicResource entries when Layers 1/2 activate.
Discovery links: AllNdos (global anchor "ndo_identities" path → action hashes), AgentToNdo (initiator pubkey → action hashes), NdoByLifecycleStage / NdoByNature / NdoByPropertyRegime (categorization anchors — path pattern "ndo.lifecycle.{Stage:?}" etc. → action hashes, REQ-NDO-L0-05)
Lifecycle links: NdoToSuccessor (deprecated NDO → successor NDO, REQ-NDO-LC-06), NdoToTransitionEvent (NDO → triggering EconomicEvent, REQ-NDO-L0-05)
NDO membership
Status: Implemented. Coordinator functions live in
zome_resource/src/ndo_membership.rs; UI flow inNdoView.svelte. Distinct from GroupSoftLinkassociation (curated NDO list per group).
NDO membership lets an agent declare participation in an NDO independently of group membership.
It is not an access grant. Under the per-NDO-cell model (ADR-010 model A) an agent must already hold the cloned NDO cell to read the NDO at all, so cell possession is what confers access. NdoMembership makes participation listable; no code may treat its absence as a read denial.
Coordinator API (zome_resource):
| Function | Input | Output | Notes |
|---|---|---|---|
join_ndo | JoinNdoInput { ndo_identity_hash, role } | Record (NdoMembership) | Idempotent: a second join returns AlreadyMember. Verifies the identity exists in this cell. |
get_ndo_members | ndo_identity_hash: ActionHash | Vec<AgentPubKey> | Members read from link authors, never a per-link get (see below) |
is_ndo_member | (AgentPubKey, ActionHash) | bool | "Is this agent taking part", never "may this agent read" |
Integrity entry:
#![allow(unused)] fn main() { pub struct NdoMembership { pub ndo_identity_hash: ActionHash, pub role: Option<String>, // e.g. "contributor", "observer" — community-defined } }
The joining agent and join time are not stored in the entry: they come from the action header (record.action().author() / .timestamp()), matching the GroupMembership convention in the group DNA.
Links:
NdoToMembers— NDO identity hash →NdoMembership(discovery)MemberToNdos— member pubkey → NDO identity hash (duplicate-join guard, resolved from local state)
Why members come from link authors: get_ndo_members reads each NdoToMembers link's author rather than fetching the linked record. A per-link get can fail when another member's record has not yet gossiped to this shard, silently dropping that member so only the local agent appears. That exact bug was found and fixed in zome_group; do not reintroduce it.
Not in scope: leave_ndo (no UI affordance yet), and Person entry creation on join (REQ-UI-ID-03 names joining an NDO as a Level 3 trigger, but that is a separate change to the identity model).
TODO (post-MVP): get_ndo_transition_history(ndo_hash) -> Vec<NdoTransitionHistoryEvent> for lifecycle audit panel (TransitionHistoryPanel.svelte).
ResourceSpecification Entry
#![allow(unused)] fn main() { pub struct ResourceSpecification { pub name: String, // Resource specification name pub description: String, // Detailed description pub category: String, // Category for efficient queries pub image_url: Option<String>, // Optional resource image pub tags: Vec<String>, // Flexible discovery tags pub is_active: bool, // Active/inactive filter pub scope: ResourceScope, // Project | Network | Public (mutable) pub ndo_identity_hash: ActionHash, // Immutable Layer 0 pointer (original create_ndo hash) pub ndo_state_hash: ActionHash, // The NDO action the author observed at activation } }
Layer 1 activation: creating a spec writes an NdoToSpecification link from ndo_identity_hash and is gated to lifecycle stages Specification through Active (#132). governance_rules, created_by, and created_at are not fields on this entry: rules are separate GovernanceRule entries reached through SpecificationToGovernanceRule, and authorship comes from the action.
ValueFlows: Compliant with resource specification standards
Discovery: Category and tag-based efficient queries; Project-scoped specs skip the global anchor
EconomicResource Entry
#![allow(unused)] fn main() { pub struct EconomicResource { pub conforms_to: ActionHash, // Link to ResourceSpecification pub quantity: f64, // Resource quantity pub unit: String, // Unit of measurement pub custodian: AgentPubKey, // Primary Accountable Agent // TODO (G1, REQ-AGENT-02): replace custodian: AgentPubKey with custodian: AgentContext // post-MVP to support Collective, Project, Network, and Bot agents as Primary Accountable // Agents. AgentContext = union of AgentPubKey | CollectiveAgentHash. The same change is // needed in TransitionContext.target_custodian (governance-operator-architecture.md) and // NondominiumIdentity.initiator (ndo_prima_materia.md Section 8.1). pub created_by: AgentPubKey, // Resource creator pub created_at: Timestamp, // Creation timestamp pub current_location: Option<String>, // Physical/virtual location pub operational_state: OperationalState, // Layer 2 process condition (REQ-NDO-OS-01 ✅) } }
ValueFlows: Compliant economic resource implementation
Custody: Clear custodianship with Primary Accountable Agent pattern
State Management: Operational condition on instance; lifecycle maturity on NondominiumIdentity
OperationalState Enum
#![allow(unused)] fn main() { pub enum OperationalState { Available, Reserved, InTransit, InStorage, InMaintenance, InUse, PendingValidation, // default for newly created instances } }
Key principle: Transport, storage, and maintenance are processes that act on a resource at any lifecycle stage. A Development resource can be InTransit between R&D labs. An Active resource can be InMaintenance. These are operational conditions, not lifecycle milestones.
LifecycleStage vs OperationalState
Lifecycle (LifecycleStage on NondominiumIdentity): maturity/evolution (advances rarely, almost irreversibly). Faceted discovery via NdoByLifecycleStage.
Operational (OperationalState on EconomicResource): active process condition (cycles frequently; typically resets to Available when a process ends). Faceted discovery via ResourcesByOperationalState.
Governance transitions (REQ-NDO-OS-02/03): deferred — interim writes use update_operational_state in zome_resource; future governance-zome ownership will require valid EconomicEvent references.
GovernanceRule Entry
#![allow(unused)] fn main() { pub struct GovernanceRule { pub rule_data: RuleData, // Tagged payload; replaces the rule_type/rule_data strings pub enforced_by: Option<String>, // Role required for enforcement pub ndo_identity_hash: ActionHash, // Layer 0 pointer for constraint evaluation pub property_regime: PropertyRegime, // Denormalized from Layer 0 (zero-DHT-read validation) pub resource_nature: ResourceNature, pub rivalry_override: Option<Rivalry>, // TODO (post-MVP, governance.md §4.8): add `expires_at: Option<Timestamp>` for temporal // governance. Rules with an expiry become inactive after the deadline without requiring a // manual update. Enables sunset clauses and time-limited access grants. // TODO (post-MVP): add `EconomicAgreement` and `IdentityVerification` variants to `RuleData` // for Unyt and Flowsta integration. See ndo_prima_materia.md §6.6-6.7, REQ-NDO-CS-07–CS-15. } pub enum RuleData { AccessRequirement(AccessRequirementData), UsageLimit(UsageLimitData), TransferCondition(TransferConditionData), MaintenanceSchedule(MaintenanceScheduleData), } }
Typing: GovernanceRuleType is derived from the RuleData discriminant, never stored. created_by / created_at are not fields: authorship and time come from the action.
Constraints: each rule is checked against its NDO's classification by check_rule_data_permitted in crates/shared/src/constraints.rs. Hard violations are rejected by the integrity zome; Soft violations surface as advisory warnings.
Enforcement: Role-based rule enforcement delegation
API Functions
NDO Layer 0 Management
create_ndo(input: NdoInput) -> ExternResult<NdoOutput>
Creates a new NondominiumIdentity. Sets initiator from agent_info and created_at from sys_time. Creates two discovery links.
Input: NdoInput { name, property_regime, resource_nature, lifecycle_stage, description }
Output: NdoOutput { action_hash, entry } — action_hash is the stable Layer 0 identity.
Links created: AllNdos (global anchor "ndo_identities" → action hash), AgentToNdo (initiator pubkey → action hash), NdoByLifecycleStage (stage anchor → action hash), NdoByNature (nature anchor → action hash), NdoByPropertyRegime (regime anchor → action hash). Nature and regime anchors are immutable and never moved.
Validation: name must not be empty.
Initial stage: Any non-terminal stage is valid at creation (Hibernating, Deprecated, EndOfLife are rejected). Use the resource's actual current stage — do not fabricate a synthetic Ideation entry for resources that pre-date system registration (see design note above).
get_ndo(original_action_hash: ActionHash) -> ExternResult<Option<NondominiumIdentity>>
Returns the latest version of a NondominiumIdentity by resolving the HDK update chain. Always provide the original action hash — the function handles chain traversal internally.
update_lifecycle_stage(input: UpdateLifecycleStageInput) -> ExternResult<ActionHash>
Transitions the lifecycle_stage of a NondominiumIdentity. Only the initiator may call this. Enforced in both the coordinator (pre-flight check) and the integrity zome (state machine validation).
Input:
#![allow(unused)] fn main() { UpdateLifecycleStageInput { original_action_hash: ActionHash, new_stage: LifecycleStage, successor_ndo_hash: Option<ActionHash>, // required when new_stage == Deprecated transition_event_hash: Option<ActionHash>, // triggering EconomicEvent (REQ-NDO-L0-05) } }
Authorization: caller must equal entry.initiator.
State machine: The integrity zome enforces the §5.3 transition allowlist. Invalid transitions (e.g. EndOfLife → Ideation, Deprecated → Active) return a validation error.
Returns: new action hash. The original_action_hash remains the stable Layer 0 identity.
Links created / moved (conditional):
NdoToSuccessor(original_action_hash→successor_ndo_hash) — only whennew_stage == Deprecated(REQ-NDO-LC-06)NdoToTransitionEvent(original_action_hash→transition_event_hash) — whentransition_event_hashisSome(REQ-NDO-L0-05; full cross-zome event validation deferred)NdoByLifecycleStagelink is moved: the old stage's link is deleted and a new link is created at the new stage anchor (only when stage actually changes).
get_all_ndos(_: ()) -> ExternResult<GetAllNdosOutput>
Returns the latest version of all NondominiumIdentity entries via the global "ndo_identities" anchor. Entries unavailable on the DHT or failing deserialization are silently skipped (eventual consistency). Output: GetAllNdosOutput { ndos: Vec<NdoOutput> }.
get_my_ndos(_: ()) -> ExternResult<GetAllNdosOutput>
Returns all NondominiumIdentity entries created by the calling agent, resolved to their latest versions. Uses AgentToNdo links. Entries unavailable on the DHT or failing deserialization are silently skipped (eventual consistency). Output: GetAllNdosOutput { ndos: Vec<NdoOutput> }.
get_ndos_by_lifecycle_stage(stage: LifecycleStage) -> ExternResult<GetAllNdosOutput>
Returns all NDOs currently at the given LifecycleStage. Uses the NdoByLifecycleStage categorization anchor (path "ndo.lifecycle.{stage:?}"). The anchor is maintained by create_ndo and update_lifecycle_stage. Entries unavailable on the DHT or failing deserialization are silently skipped. REQ-NDO-L0-05, REQ-NDO-L0-07.
get_ndos_by_nature(nature: ResourceNature) -> ExternResult<GetAllNdosOutput>
Returns all NDOs of the given ResourceNature. Uses the NdoByNature categorization anchor (path "ndo.nature.{nature:?}"). The anchor is immutable — it is set at creation time and never moved. Entries unavailable on the DHT or failing deserialization are silently skipped. REQ-NDO-L0-05, REQ-NDO-L0-07.
get_ndos_by_property_regime(regime: PropertyRegime) -> ExternResult<GetAllNdosOutput>
Returns all NDOs under the given PropertyRegime. Uses the NdoByPropertyRegime categorization anchor (path "ndo.regime.{regime:?}"). The anchor is immutable — it is set at creation time and never moved. Entries unavailable on the DHT or failing deserialization are silently skipped. REQ-NDO-L0-05, REQ-NDO-L0-07.
Resource Specification Management
create_resource_specification(input: CreateResourceSpecificationInput) -> ExternResult<Record>
Creates a new resource specification template.
Input:
#![allow(unused)] fn main() { pub struct CreateResourceSpecificationInput { pub name: String, pub description: String, pub category: String, pub image_url: Option<String>, pub tags: Vec<String>, pub governance_rules: Vec<ActionHash>, } }
Business Logic:
- Validates required fields (name, description, category)
- Creates discovery links by category and tags
- Links to governance rules for embedded control
Links Created:
category anchor -> spec_hash(category discovery)tag anchors -> spec_hash(tag discovery)all_specs anchor -> spec_hash(global discovery)
update_resource_specification(input: UpdateResourceSpecificationInput) -> ExternResult<Record>
Updates an existing resource specification.
Authorization: Only the specification author can update Versioning: Creates update links for version history
get_latest_resource_specification(original_action_hash: ActionHash) -> ExternResult<ResourceSpecification>
Retrieves the latest version of a resource specification.
Pattern: Follows update chain via version links Performance: Optimized with timestamp-based latest selection
get_all_resource_specifications() -> ExternResult<GetAllResourceSpecificationsOutput>
Discovers all resource specifications in the network.
Discovery Pattern: Queries the resource_specifications anchor path
Output: GetAllResourceSpecificationsOutput — two parallel vectors of the same length and order:
specifications: Vec<ResourceSpecification>— all active resource specificationsaction_hashes: Vec<ActionHash>— the original creationActionHashof each spec (from the anchor link target); stable identity for routing (e.g./ndo/[id])
get_resource_specifications_by_category(category: String) -> ExternResult<Vec<Record>>
Finds resource specifications by category.
Pattern: Efficient category-based discovery via anchor links Use Case: Browse resources by type (tools, materials, services)
get_resource_specifications_by_tag(tag: String) -> ExternResult<Vec<Record>>
Finds resource specifications by tag.
Pattern: Tag-based discovery for flexible filtering Use Case: Find resources with specific attributes
get_resource_specification_with_rules(spec_hash: ActionHash) -> ExternResult<ResourceSpecificationWithRules>
Gets resource specification with associated governance rules.
Integration: Fetches linked governance rules for complete context Use Case: Understand resource access requirements before creation
Economic Resource Management
create_economic_resource(input: CreateEconomicResourceInput) -> ExternResult<Record>
Creates a new economic resource instance.
Input:
#![allow(unused)] fn main() { pub struct CreateEconomicResourceInput { pub conforms_to: ActionHash, // Resource specification pub quantity: f64, pub unit: String, pub current_location: Option<String>, } }
Business Logic:
- Validates caller has appropriate capability level
- Links resource to specification for compliance
- Sets initial state to
PendingValidation - Creates custody links to custodian
Authorization: Requires Accountable Agent capability level Validation: Cross-zome validation with governance zome
update_economic_resource(input: UpdateEconomicResourceInput) -> ExternResult<Record>
Updates an existing economic resource.
Authorization: Only resource custodian can update Fields Updateable: Quantity, location, state (with validation)
get_latest_economic_resource(original_action_hash: ActionHash) -> ExternResult<EconomicResource>
Retrieves the latest version of an economic resource.
Pattern: Follows update chain via version links Use Case: Get current resource state and attributes
get_all_economic_resources() -> ExternResult<GetAllEconomicResourcesOutput>
Discovers all economic resources in the network.
Privacy: Returns only public resource information Access Control: Respects resource visibility settings
get_my_economic_resources() -> ExternResult<Vec<Link>>
Gets resources created or custodied by the calling agent.
Pattern: Queries agent's resource links Use Case: Agent's personal resource inventory
get_agent_economic_resources(agent_pubkey: AgentPubKey) -> ExternResult<Vec<Link>>
Gets resources associated with a specific agent.
Pattern: Agent-centric resource discovery Use Case: View another agent's resource portfolio
get_resources_by_specification(spec_hash: ActionHash) -> ExternResult<Vec<Record>>
Finds all economic resources conforming to a specification.
Pattern: Specification to resource discovery Use Case: Find all instances of a particular resource type
get_economic_resource_profile(resource_hash: ActionHash) -> ExternResult<EconomicResourceProfile>
Gets complete resource profile with specification and governance rules.
Integration: Combines resource data with specification and rules Use Case: Full resource context for decision making
check_first_resource_requirement(agent_pub_key: AgentPubKey) -> ExternResult<bool>
Checks if an agent has created their first resource yet.
Use Case: Validation for Simple Agent promotion requirements Business Logic: Used in agent progression workflows
Custody Transfer Management
transfer_custody(input: TransferCustodyInput) -> ExternResult<TransferCustodyOutput>
Transfers custody of an economic resource to another agent.
Input:
#![allow(unused)] fn main() { pub struct TransferCustodyInput { pub resource_hash: ActionHash, pub new_custodian: AgentPubKey, pub transfer_note: Option<String>, } }
Authorization: Only current custodian can transfer Validation: Validates new custodian capability level Integration: Creates economic event for PPR generation
Business Logic:
- Validates transfer permissions
- Updates resource custodian
- Creates economic event (TransferCustody)
- Triggers validation workflow if required
update_operational_state(input: UpdateOperationalStateInput) -> ExternResult<Record>
Updates the operational state of an EconomicResource instance (REQ-NDO-OS-01). Lifecycle maturity transitions use update_lifecycle_stage on NondominiumIdentity (Layer 0).
Input:
#![allow(unused)] fn main() { pub struct UpdateOperationalStateInput { pub resource_hash: ActionHash, pub new_operational_state: OperationalState, } }
Authorization: Current agent (interim resource-zome writer; governance-zome ownership deferred per REQ-NDO-OS-02)
Side effects: Moves the ResourcesByOperationalState anchor link when the state changes
get_resources_by_operational_state(state: OperationalState) -> ExternResult<Vec<Record>>
Discovery via ResourcesByOperationalState anchor (ndo.opstate.{state}). Parallels get_ndos_by_lifecycle_stage.
Governance Rule Management
create_governance_rule(input: GovernanceRuleInput) -> ExternResult<Record>
Creates a new governance rule.
Input:
#![allow(unused)] fn main() { pub struct GovernanceRuleInput { pub rule_data: RuleData, pub enforced_by: Option<String>, pub ndo_identity_hash: ActionHash, pub property_regime: PropertyRegime, pub resource_nature: ResourceNature, pub rivalry_override: Option<Rivalry>, /// When set, also create `SpecificationToGovernanceRule` so the rule appears /// in `get_resource_specification_with_rules`. Omitting it creates an orphan /// rule that no read path surfaces. pub specification_hash: Option<ActionHash>, } }
Business Logic:
- Validates rule format and structure
- Links rule to creator for accountability
- Creates discovery links for rule lookup
update_governance_rule(input: UpdateGovernanceRuleInput) -> ExternResult<Record>
Updates an existing governance rule.
Authorization: Only rule creator can update Validation: Ensures rule data remains valid JSON
get_all_governance_rules() -> ExternResult<GetAllGovernanceRulesOutput>
Discovers all governance rules in the network.
Discovery Pattern: Queries the governance_rules anchor path
Use Case: Understand community governance framework
get_governance_rules_by_type(rule_type: String) -> ExternResult<Vec<Record>>
Finds governance rules by type.
Pattern: Type-based rule discovery Use Case: Find all access rules, usage rules, etc.
get_governance_rule_profile(rule_hash: ActionHash) -> ExternResult<GovernanceRuleProfile>
Gets governance rule with creator information.
Integration: Links rule to creator agent profile Use Case: Understand rule context and authority
Link Architecture
Resource Specification Links
- AllSpecs:
resource_specifications anchor -> spec_hash- Global discovery - CategoryLinks:
category anchor -> spec_hash- Category discovery - TagLinks:
tag anchor -> spec_hash- Tag discovery - SpecificationUpdates:
original_hash -> updated_hash- Version history
Economic Resource Links
- AllResources:
economic_resources anchor -> resource_hash- Global discovery - SpecificationToResources:
spec_hash -> resource_hash- Specification to instances - AgentToResources:
agent_pubkey -> resource_hash- Agent resource portfolio - CustodyLinks:
custodian -> resource_hash- Current custodian tracking - ResourceUpdates:
original_hash -> updated_hash- Version history
Governance Rule Links
- AllGovernanceRules:
governance_rules anchor -> rule_hash- Global discovery - RuleTypeLinks:
rule_type anchor -> rule_hash- Type-based discovery - RuleUpdates:
original_hash -> updated_hash- Version history
Cross-Reference Links
- SpecificationToRules:
spec_hash -> rule_hash- Embedded governance - ResourceToEvents:
resource_hash -> event_hash- Economic event tracking
Signal Architecture
The Resource zome emits signals for real-time UI updates:
#![allow(unused)] fn main() { pub enum Signal { EntryCreated { action, app_entry }, EntryUpdated { action, app_entry, original_app_entry }, EntryDeleted { action, original_app_entry }, LinkCreated { action, link_type }, LinkDeleted { action, link_type }, } }
Real-time Updates: Enables UI reactivity to resource changes Cross-Zome Coordination: Supports complex workflows with other zomes
Error Handling
ResourceError Types
ResourceError is defined in crates/utils/src/errors.rs and imported by zome_resource.
#![allow(unused)] fn main() { pub enum ResourceError { ResourceSpecNotFound(String), // Specification lookup failures EconomicResourceNotFound(String), // Resource lookup failures GovernanceRuleNotFound(String), // Rule lookup failures NotAuthor, // Authorization failures NotCustodian, // Custody validation failures SerializationError(String), // Data serialization issues EntryOperationFailed(String), // DHT operation failures LinkOperationFailed(String), // Link operation failures InvalidInput(String), // Input validation failures GovernanceViolation(String), // Rule enforcement failures } }
Pattern: Comprehensive error coverage with descriptive messages
Integration: Converts to WasmError for Holochain compatibility
Privacy and Access Control
Public Resource Information
- Resource Specifications: Name, description, category, tags (discoverable)
- Resource Status: Active status and basic availability (public)
- Governance Rules: Rule types and basic requirements (transparent)
Private Resource Information
- Resource Details: Specific locations, quantities, custodians (access-controlled)
- Economic Events: Detailed transaction history (participant access)
- Custody Transfers: Transfer details and participants (participant access)
Access Control Patterns
#![allow(unused)] fn main() { // Public resource discovery get_all_economic_resources() -> Basic resource info // Agent's own resources (full access) get_my_economic_resources() -> Complete resource details // Resource access by permission get_economic_resource_profile(resource_hash) -> Requires custodian permission }
Integration with Other Zomes
Cross-Zome Validation
#![allow(unused)] fn main() { // Validate agent has required capability level let capability_level = call( CallTargetCell::Local, "zome_person", "get_person_capability_level".into(), None, &agent_pubkey, )?; if capability_level != "governance" && capability_level != "coordination" { return Err(ResourceError::GovernanceViolation("Insufficient capability".to_string())); } }
Economic Event Integration
#![allow(unused)] fn main() { // Create economic event for custody transfer let event_output = call( CallTargetCell::Local, "zome_gouvernance", "log_economic_event".into(), None, &LogEconomicEventInput { action: VfAction::TransferCustody, provider: current_custodian, receiver: new_custodian, resource_inventoried_as: resource_hash, affects: resource_hash, resource_quantity: resource.quantity, note: transfer_note, }, )?; }
Governance Rule Enforcement
#![allow(unused)] fn main() { // Check resource access against governance rules let rules = get_governance_rules_by_type("access".to_string())?; for rule in rules { if rule_applies_to_operation(&rule, &operation, &agent_roles) { enforce_rule(&rule)?; } } }
Implementation Status
✅ Completed Features
- Resource Specification Management: Complete CRUD operations with discovery
- Economic Resource Lifecycle: Full resource creation, updates, and tracking
- Custody Transfer System: Secure custody transfers with validation
- Governance Rule Integration: Embedded rules for access control
- State Management: Complete resource state transitions
- Discovery System: Category and tag-based efficient resource discovery
- Cross-Zome Integration: Role validation and economic event creation
- Signal System: Real-time updates for UI reactivity
- Versioning Support: Complete update history for specifications and resources
🔧 Current Limitations
- No Economic Processes: Structured process workflows (Use, Transport, Storage, Repair) not implemented
- Basic Resource Validation: Simple validation without multi-reviewer schemes
- No Resource Dependencies: Resource relationships and dependencies not tracked
- Limited Location Support: Basic location tracking without spatial features
📋 Future Enhancement Opportunities
- Economic Process Integration: Implement structured process workflows
- Advanced Validation: Multi-reviewer validation schemes (2-of-3, N-of-M)
- Resource Relationships: Dependency tracking and resource bundling
- Spatial Features: Location-based resource discovery and services
- Resource Analytics: Usage statistics and availability optimization
- Automated Governance: AI-assisted rule creation and enforcement
TODO (post-MVP — PropertyRegime-driven governance defaults, resources.md §6.6 / implementation_plan §12.1.1 Phase B): Implement a
GovernanceDefaultsEnginethat derives default governance rule templates fromPropertyRegime + ResourceNatureclassification. For example, aNondominiumphysical resource gets default rules for custody rotation, maintenance obligations, and access-for-use; aCommonsdigital resource gets default rules for attribution and remix licensing. The defaults are suggestions populated intoResourceSpecification.governance_rulesat creation time; custodians can override them. Seeresources.md §6.6.
The Resource zome provides the foundational resource management infrastructure for the nondominium ecosystem, enabling ValueFlows-compliant resource sharing with embedded governance and comprehensive lifecycle tracking.
Governance Zome (zome_gouvernance) Documentation
The Governance zome implements the core economic coordination and validation infrastructure for the nondominium ecosystem, providing ValueFlows-compliant economic event logging, commitment management, Private Participation Receipt (PPR) reputation system, and comprehensive agent validation workflows. It serves as the governance backbone enabling decentralized resource sharing with embedded accountability and cryptographically-secured reputation tracking.
Post-MVP (target architecture): unified transition evaluation is specified to optionally enforce Unyt economic closure (EconomicAgreement rules, rave_hash; documentation/requirements/ndo_prima_materia.md §6.6) and Flowsta identity checks (IdentityVerification, FlowstaIdentity; §6.7). See documentation/archives/governance.md §3.7, documentation/requirements/post-mvp/unyt-integration.md, and documentation/requirements/post-mvp/flowsta-integration.md. MVP coordinator paths (e.g. promotion validation) precede that consolidation.
Core Data Structures
VfAction Enum
#![allow(unused)] fn main() { pub enum VfAction { // Standard ValueFlows transfer actions Transfer, // Transfer ownership/custody Move, // Move a resource from one location to another // Standard ValueFlows production/consumption actions Use, // Use a resource without consuming it Consume, // Consume/destroy a resource Produce, // Create/produce a new resource Work, // Apply work/labor to a resource // Standard ValueFlows modification actions Modify, // Modify an existing resource Combine, // Combine multiple resources Separate, // Separate one resource into multiple // Standard ValueFlows quantity adjustment actions Raise, // Increase quantity/value of a resource Lower, // Decrease quantity/value of a resource // Standard ValueFlows citation/reference actions Cite, // Reference or cite a resource Accept, // Accept delivery or responsibility // nondominium-specific actions InitialTransfer, // First transfer by a Simple Agent AccessForUse, // Request access to use a resource TransferCustody, // Transfer custody (nondominium specific) } }
ValueFlows Compliance: Complete economic action vocabulary supporting all standard and nondominium-specific actions Type Safety: Replaces string-based actions with compile-time validation Helper Methods: Resource validation, quantity modification, custody change detection
VfAction Helper Methods
#![allow(unused)] fn main() { impl VfAction { pub fn requires_existing_resource(&self) -> bool; // Resource validation pub fn creates_resource(&self) -> bool; // New resource detection pub fn modifies_quantity(&self) -> bool; // Quantity change detection pub fn changes_custody(&self) -> bool; // Custody transfer detection } }
ValidationReceipt Entry
#![allow(unused)] fn main() { pub struct ValidationReceipt { pub validator: AgentPubKey, // Agent providing validation // TODO (G1, REQ-GOV-16): replace AgentPubKey with AgentContext post-MVP. // For collective/bot validators, the signing authority is the designated // operator key. The governance evaluation must resolve AgentContext → // effective AgentPubKey before capability token validation. pub validated_item: ActionHash, // Item being validated (Resource, Event, etc.) pub validation_type: String, // Type: "resource_approval", "agent_promotion", "role_validation" pub approved: bool, // Validation result pub notes: Option<String>, // Optional validation notes pub validated_at: Timestamp, // Validation timestamp } }
Governance: Core validation infrastructure for all governance workflows Audit Trail: Complete tracking of all community validations Flexibility: Supports multiple validation types with contextual notes
EconomicEvent Entry
#![allow(unused)] fn main() { pub struct EconomicEvent { pub action: VfAction, // Economic action performed pub provider: AgentPubKey, // Agent providing the resource/service // TODO (G1, REQ-GOV-16): replace AgentPubKey with AgentContext post-MVP. pub receiver: AgentPubKey, // Agent receiving the resource/service // TODO (G1, REQ-GOV-16): replace AgentPubKey with AgentContext post-MVP. pub resource_inventoried_as: ActionHash, // Link to the EconomicResource pub affects: ActionHash, // Link to the affected EconomicResource pub resource_quantity: f64, // Quantity involved in the event pub event_time: Timestamp, // When the event occurred pub note: Option<String>, // Optional event description pub ndo_identity_hash: ActionHash, // Layer 0 pointer for action-constraint evaluation (#132) } }
ValueFlows Compliance: Complete economic event specification Resource Tracking: Links to affected resources for audit trails Action Integration: Uses type-safe VfAction enum
Commitment Entry
#![allow(unused)] fn main() { pub struct Commitment { pub action: VfAction, // Economic action committed to pub provider: AgentPubKey, // Provider of the commitment // TODO (G1, REQ-GOV-16): replace AgentPubKey with AgentContext post-MVP. pub receiver: AgentPubKey, // Receiver of the commitment // TODO (G1, REQ-GOV-16): replace AgentPubKey with AgentContext post-MVP. pub resource_inventoried_as: Option<ActionHash>, // Specific resource if applicable pub resource_conforms_to: Option<ActionHash>, // Resource specification if general pub input_of: Option<ActionHash>, // Optional link to a Process pub due_date: Timestamp, // Commitment due date pub note: Option<String>, // Optional commitment description pub committed_at: Timestamp, // When commitment was made pub ndo_identity_hash: ActionHash, // Layer 0 pointer for action-constraint evaluation (#132) } }
Planning: Economic planning and commitment tracking Flexibility: Supports both specific and general resource commitments Due Date Management: Time-bound commitments with expiry
Claim Entry
#![allow(unused)] fn main() { pub struct Claim { pub fulfills: ActionHash, // References the Commitment pub fulfilled_by: ActionHash, // References the resulting EconomicEvent pub claimed_at: Timestamp, // When claim was made pub note: Option<String>, // Optional claim description } }
Fulfillment Tracking: Links commitments to their actual execution Accountability: Creates audit trail of promise vs. delivery Performance Data: Basis for reputation calculation
ResourceValidation Entry
#![allow(unused)] fn main() { pub struct ResourceValidation { pub resource: ActionHash, // Link to the EconomicResource being validated pub validation_scheme: String, // e.g., "2-of-3", "simple_majority" pub required_validators: u32, // Number of validators required pub current_validators: u32, // Number of validators who have validated pub status: String, // "pending", "approved", "rejected" pub created_at: Timestamp, // Validation creation time pub updated_at: Timestamp, // Last update time } }
Multi-Reviewer Validation: Support for complex validation schemes Progress Tracking: Monitor validation progress in real-time Configurable Schemes: Flexible validation requirements
Private Participation Receipt (PPR) System
ParticipationClaimType Enum
#![allow(unused)] fn main() { pub enum ParticipationClaimType { // Genesis Role - Network Entry ResourceCreation, // Creator receives this for successful resource contribution ResourceValidation, // Validator receives this for network validation performed // Core Usage Role - Custodianship CustodyTransfer, // Outgoing custodian receives this for responsible custody transfer CustodyAcceptance, // Incoming custodian receives this for custody acceptance // Intermediate Roles - Specialized Services MaintenanceCommitmentAccepted, // Maintenance agent receives this for accepted commitment MaintenanceFulfillmentCompleted, // Maintenance agent receives this for completed fulfillment StorageCommitmentAccepted, // Storage agent receives this for accepted commitment StorageFulfillmentCompleted, // Storage agent receives this for completed fulfillment TransportCommitmentAccepted, // Transport agent receives this for accepted commitment TransportFulfillmentCompleted, // Transport agent receives this for completed fulfillment GoodFaithTransfer, // Custodian receives this for good faith transfer to service provider // Network Governance DisputeResolutionParticipation, // For constructive participation in conflict resolution ValidationActivity, // For performing validation duties beyond specific transactions RuleCompliance, // For consistent adherence to governance protocols // Resource End-of-Life Management EndOfLifeDeclaration, // Declaring agent receives this for end-of-life declaration EndOfLifeValidation, // Expert validator receives this for end-of-life validation // TODO (G6, REQ-GOV-15 — post-MVP): add new claim types for governance ceremonies: // AffiliationRecordSigned, // Issued when agent signs AffiliationRecord (ToP ceremony) // GovernanceRoleGranted, // Issued when collective agent is granted a governance role // These extend PPR tracking to cover formal governance participation beyond economic events. } }
Comprehensive Coverage: 16 claim types covering all economic interactions Role-Based Categories: Claims organized by agent roles and interaction types Reputation Foundation: Each claim type contributes to reputation calculation
PerformanceMetrics Structure
#![allow(unused)] fn main() { pub struct PerformanceMetrics { pub timeliness: f64, // Punctuality score (0.0 to 1.0) pub quality: f64, // Task quality score (0.0 to 1.0) pub reliability: f64, // Commitment fulfillment reliability (0.0 to 1.0) pub communication: f64, // Communication effectiveness (0.0 to 1.0) pub overall_satisfaction: f64, // Counterparty satisfaction (0.0 to 1.0) pub notes: Option<String>, // Optional contextual notes } }
Quantitative Assessment: Numerical scores for objective reputation calculation Weighted Average: Customizable weights for different aspects of performance Validation: All scores must be within valid range (0.0 to 1.0)
CryptographicSignature Structure
#![allow(unused)] fn main() { pub struct CryptographicSignature { pub recipient_signature: Signature, // Signature from PPR owner pub counterparty_signature: Signature, // Signature from counterparty pub signed_data_hash: [u8; 32], // Hash of signed data for verification pub signed_at: Timestamp, // When signatures were created } }
Bilateral Authentication: Both parties sign to acknowledge the interaction Cryptographic Security: Tamper-evident signatures for reputation integrity Verification Support: Complete context for signature verification
PrivateParticipationClaim Entry
#![allow(unused)] fn main() { pub struct PrivateParticipationClaim { // Standard ValueFlows fields pub fulfills: ActionHash, // References the commitment fulfilled pub fulfilled_by: ActionHash, // References the economic event pub claimed_at: Timestamp, // PPR-specific extensions pub claim_type: ParticipationClaimType, pub performance_metrics: PerformanceMetrics, pub bilateral_signature: CryptographicSignature, // Additional context pub counterparty: AgentPubKey, // The other agent involved in the interaction // TODO (G1, REQ-GOV-16): replace AgentPubKey with AgentContext post-MVP. // Bot agents generate PPRs with their operator's AgentPubKey as the // accountable counterparty. pub resource_hash: Option<ActionHash>, // Optional link to the resource involved pub notes: Option<String>, // Optional contextual notes } }
Privacy: Stored as private entry, accessible only to the claim owner Complete Context: Links commitment, event, performance, and cryptographic proof Reputation Data: Foundation for trust and reputation calculation
ReputationSummary Structure
#![allow(unused)] fn main() { pub struct ReputationSummary { pub total_claims: u32, // Total number of participation claims pub average_performance: f64, // Average performance score across all claims pub creation_claims: u32, // Resource creation and validation claims pub custody_claims: u32, // Custody-related claims pub service_claims: u32, // Service provision claims pub governance_claims: u32, // Governance participation claims pub end_of_life_claims: u32, // End-of-life management claims pub period_start: Timestamp, // Time period this summary covers pub period_end: Timestamp, // End of time period pub agent: AgentPubKey, // Agent this summary belongs to pub generated_at: Timestamp, // When summary was generated } }
Privacy-Preserving: Share reputation without revealing individual claims Category Breakdown: Reputation scores by interaction type Time-Period Based: Configurable time windows for reputation calculation
API Functions
Economic Event Management
log_economic_event(input: LogEconomicEventInput) -> ExternResult<LogEconomicEventOutput>
Logs an economic event to the distributed ledger.
Input:
#![allow(unused)] fn main() { pub struct LogEconomicEventInput { pub action: VfAction, pub provider: AgentPubKey, pub receiver: AgentPubKey, pub resource_inventoried_as: ActionHash, pub resource_quantity: f64, pub note: Option<String>, pub commitment_hash: Option<ActionHash>, // Commitment being fulfilled pub generate_pprs: Option<bool>, // Auto-generate PPR claims pub ndo_identity_hash: ActionHash, // Layer 0 identity, required (#132) } }
affects is not an input field: the coordinator sets it from resource_inventoried_as.
Business Logic:
- Validates action compatibility with resource state
- Creates economic event with timestamp
- Links to affected resource for audit trail
- Triggers PPR generation if applicable
Integration: Automatically generates appropriate PPR claims Validation: Cross-zome validation with resource and person zomes
log_initial_transfer(input: LogInitialTransferInput) -> ExternResult<LogEconomicEventOutput>
Special function for Simple Agent's first resource transfer.
Business Logic: Handles special case for agent progression Validation: Validates this is the agent's first transfer Integration: May trigger Simple Agent promotion workflow
get_all_economic_events() -> ExternResult<Vec<EconomicEvent>>
Retrieves all economic events (with appropriate access control).
Privacy: Filters events based on participant access rights Performance: Efficient query via economic event anchors
get_events_for_resource(resource_hash: ActionHash) -> ExternResult<Vec<EconomicEvent>>
Gets all economic events affecting a specific resource.
Pattern: Follows resource-to-events link chain Use Case: Complete resource lifecycle and history
get_events_for_agent(agent: AgentPubKey) -> ExternResult<Vec<EconomicEvent>>
Gets all economic events involving a specific agent.
Pattern: Queries agent participation in economic activities Use Case: Agent's economic activity history
Commitment Management
propose_commitment(input: ProposeCommitmentInput) -> ExternResult<ProposeCommitmentOutput>
Creates a new economic commitment.
Input:
#![allow(unused)] fn main() { pub struct ProposeCommitmentInput { pub action: VfAction, pub resource_hash: Option<ActionHash>, // Specific resource, if any pub resource_spec_hash: Option<ActionHash>, // Resource specification, if general pub provider: AgentPubKey, pub due_date: Timestamp, pub note: Option<String>, pub ndo_identity_hash: ActionHash, // Layer 0 identity, required (#132) } }
The caller is the receiver, so receiver is not an input field; input_of is set by the process path, not by this input.
Business Logic:
- Validates commitment feasibility
- Creates commitment with automatic expiration
- Links to resource specification if applicable
- Sets up claim fulfillment tracking
Integration: Creates framework for PPR generation upon fulfillment
get_all_commitments() -> ExternResult<Vec<Commitment>>
Retrieves all commitments (with appropriate access control).
Privacy: Filters commitments based on participant access rights
get_commitments_for_agent(agent: AgentPubKey) -> ExternResult<Vec<Commitment>>
Gets all commitments involving a specific agent.
Pattern: Queries agent as provider or receiver Use Case: Agent's commitment portfolio and obligations
claim_commitment(input: ClaimCommitmentInput) -> ExternResult<ClaimCommitmentOutput>
Claims fulfillment of a commitment, creating the link to an economic event.
Business Logic:
- Validates economic event fulfills commitment requirements
- Creates claim linking commitment to event
- Triggers PPR generation for both parties
- Updates reputation metrics
Integration: Core mechanism for PPR generation
get_all_claims() -> ExternResult<Vec<Claim>>
Retrieves all claims (with appropriate access control).
get_claims_for_commitment(commitment_hash: ActionHash) -> ExternResult<Vec<Claim>>
Gets all claims for a specific commitment.
Pattern: Track commitment fulfillment history Use Case: Commitment performance analysis
Validation System
create_validation_receipt(input: CreateValidationReceiptInput) -> ExternResult<Record>
Creates a validation receipt for any validated item.
Input:
#![allow(unused)] fn main() { pub struct CreateValidationReceiptInput { pub validated_item: ActionHash, pub validation_type: String, pub approved: bool, pub notes: Option<String>, } }
Business Logic:
- Records validator's assessment
- Links to validated item for audit trail
- Creates validation history
- May trigger PPR generation for validation activity
get_validation_history(item_hash: ActionHash) -> ExternResult<Vec<ValidationReceipt>>
Gets complete validation history for an item.
Pattern: Follows validated_item_to_receipt links Use Case: Comprehensive validation audit trail
get_all_validation_receipts() -> ExternResult<Vec<ValidationReceipt>>
Retrieves all validation receipts (with appropriate access control).
create_resource_validation(input: CreateResourceValidationInput) -> ExternResult<Record>
Creates a resource validation workflow.
Input:
#![allow(unused)] fn main() { pub struct CreateResourceValidationInput { pub resource: ActionHash, pub validation_scheme: String, // "2-of-3", "simple_majority", etc. pub required_validators: u32, } }
Business Logic:
- Creates validation workflow with specified scheme
- Tracks validation progress
- Manages validator assignments
- Determines final validation outcome
check_validation_status(validation_hash: ActionHash) -> ExternResult<String>
Checks the current status of a validation workflow.
Returns: "pending" | "approved" | "rejected" Use Case: Monitor validation progress
validate_new_resource(input: ValidateNewResourceInput) -> ExternResult<ValidationResult>
Validates a new resource according to community standards.
Cross-Zome Integration: Works with resource zome for validation Validation Logic: Applies governance rules and community standards Outcome: May approve resource or require further validation
Agent Validation and Promotion
validate_agent_identity(input: ValidateAgentIdentityInput) -> ExternResult<ValidationResult>
Validates agent identity and private information for promotion.
Input:
#![allow(unused)] fn main() { pub struct ValidateAgentIdentityInput { pub agent: AgentPubKey, pub resource_hash: ActionHash, pub private_data_hash: Option<ActionHash>, } }
Business Logic:
- Cross-zome call to person zome for private data access
- Validates agent meets promotion requirements
- Creates validation receipt for audit trail
- May trigger agent promotion workflow
Privacy: Respects private data access controls
validate_agent_for_promotion(input: ValidateAgentForPromotionInput) -> ExternResult<ValidationResult>
Comprehensive validation for agent promotion to higher capability levels.
Validation Logic:
- Checks resource creation requirements
- Validates community participation
- Evaluates PPR-based reputation
- Assesses governance understanding
validate_agent_for_custodianship(input: ValidateAgentForCustodianshipInput) -> ExternResult<ValidationResult>
Validates agent suitability for resource custodianship.
Validation Logic:
- Capability level validation
- PPR reputation assessment
- Custody history review
- Community standing evaluation
validate_specialized_role(input: ValidateSpecializedRoleInput) -> ExternResult<ValidationResult>
Validates agent for specialized roles (Transport, Repair, Storage).
Role-Specific Validation:
- Technical capability assessment
- Equipment/facility requirements
- Safety and compliance validation
- Performance history review
Private Participation Receipt (PPR) System
issue_participation_receipts(input: IssueParticipationReceiptsInput) -> ExternResult<IssueParticipationReceiptsOutput>
Issues PPRs to both parties involved in an economic interaction.
Input:
#![allow(unused)] fn main() { pub struct IssueParticipationReceiptsInput { pub fulfills: ActionHash, pub fulfilled_by: ActionHash, pub provider: AgentPubKey, pub receiver: AgentPubKey, pub claim_types: Vec<ParticipationClaimType>, pub provider_metrics: PerformanceMetrics, pub receiver_metrics: PerformanceMetrics, pub resource_hash: Option<ActionHash>, pub notes: Option<String>, } }
Business Logic:
- Creates private PPR entries for both parties
- Generates bilateral cryptographic signatures
- Links to commitment and economic event
- Stores performance metrics for reputation calculation
Privacy: Private entries accessible only to respective owners Security: Cryptographic signatures prevent tampering
sign_participation_claim(input: SignParticipationClaimInput) -> ExternResult<SignParticipationClaimOutput>
Signs a participation claim with bilateral authentication.
Cryptography: Creates cryptographic signatures for both parties Verification: Supports signature verification for authenticity Integration: Used in PPR creation and validation workflows
validate_participation_claim_signature(input: ValidateParticipationClaimSignatureInput) -> ExternResult<bool>
Validates the cryptographic signatures on a participation claim.
Security: Ensures claim authenticity and integrity Verification: Supports cross-agent claim verification
validate_participation_claim_signature_enhanced(input: ValidateParticipationClaimSignatureInput) -> ExternResult<EnhancedValidationResult>
Enhanced signature validation with detailed verification results.
Additional Features:
- Signature timestamp validation
- Agent verification status
- Claim context validation
- Detailed security assessment
get_my_participation_claims(filter: Option<PPRFilter>) -> ExternResult<Vec<PrivateParticipationClaim>>
Retrieves the calling agent's participation claims.
Privacy: Only returns claims owned by the calling agent Filtering: Optional filtering by claim type, time period, counterparty Use Case: Agent's reputation portfolio and history
derive_reputation_summary(input: DeriveReputationSummaryInput) -> ExternResult<ReputationSummary>
Derives a privacy-preserving reputation summary from participation claims.
Input:
#![allow(unused)] fn main() { pub struct DeriveReputationSummaryInput { pub period_start: Timestamp, pub period_end: Timestamp, pub include_categories: Option<Vec<String>>, // Optional category filtering } }
Business Logic:
- Calculates weighted average performance scores
- Categorizes claims by type
- Generates privacy-preserving summary
- Supports time-period based analysis
Privacy: Can be shared without revealing individual claim details
Private Data Validation
request_agent_validation_data(input: AgentValidationInput) -> ExternResult<ValidationResult>
Requests private data validation for agent validation workflows.
Input:
#![allow(unused)] fn main() { pub struct AgentValidationInput { pub agent_to_validate: AgentPubKey, pub validation_type: String, pub requesting_validator: AgentPubKey, pub validation_context: ActionHash, } }
Business Logic:
- Cross-zome call to person zome for private data access
- Validates specific data requirements based on validation type
- Creates validation receipt for audit trail
- Respects privacy and consent requirements
create_validation_with_private_data(input: CreateValidationWithPrivateDataInput) -> ExternResult<Record>
Creates validation with explicit private data access.
Privacy: Requires explicit consent for private data access Security: Creates audit trail of private data access Compliance: Ensures privacy requirements are met
NDO Federation Extensions
Added in PR #103. These three coordinator modules implement the NDO-to-NDO hard links,
peer-validated contributions, and benefit redistribution agreements specified in
documentation/requirements/post-mvp/lobby-dna.md (REQ-NDO-EXT-01–16).
Hard Links (hard_link.rs)
create_ndo_hard_link(input: CreateNdoHardLinkInput) -> ExternResult<ActionHash>
Creates a permanent, immutable OVN-licensed structural link between two NDOs.
The link is backed by a real EconomicEvent (its hash is stored and verified at creation time).
Input:
#![allow(unused)] fn main() { pub struct CreateNdoHardLinkInput { pub from_ndo_identity_hash: ActionHash, pub to_ndo_dna_hash: DnaHash, pub to_ndo_identity_hash: ActionHash, pub link_type: NdoLinkType, // Component | DerivedFrom | Supersedes pub fulfillment_hash: ActionHash, // must resolve to a record in this DHT } }
Business Logic:
- Verifies
fulfillment_hashresolves to an existing record - Creates a
NdoHardLinkentry (immutable, undeletable per OVN license requirement) - Creates
NdoToHardLinksanchor fromfrom_ndo_identity_hashfor global discovery - Creates
HardLinkByTypeanchor fromPath("ndo.hardlink.{type}")for filtered queries
get_ndo_hard_links(ndo_identity_hash: ActionHash) -> ExternResult<Vec<NdoHardLinkRecord>>
Returns all hard links originating from a given NDO identity hash. Resolves the latest update of each entry before returning.
get_ndo_hard_links_by_type(input: GetNdoHardLinksByTypeInput) -> ExternResult<Vec<NdoHardLinkRecord>>
Returns hard links filtered by NdoLinkType. Calls get_ndo_hard_links internally and filters client-side.
Input:
#![allow(unused)] fn main() { pub struct GetNdoHardLinksByTypeInput { pub ndo_identity_hash: ActionHash, pub link_type: NdoLinkType, } }
Contributions (contribution.rs)
validate_contribution(input: ValidateContributionInput) -> ExternResult<ActionHash>
Records and peer-validates a work contribution on an NDO. The calling agent is recorded
as the first validator in validated_by. The action field is constrained to
Work | Modify | Cite by integrity validation.
Input:
#![allow(unused)] fn main() { pub struct ValidateContributionInput { pub provider: AgentPubKey, pub action: VfAction, // Must be Work, Modify, or Cite pub work_log_group_dna_hash: Option<DnaHash>, pub work_log_action_hash: Option<ActionHash>, pub ndo_identity_hash: ActionHash, pub input_of: Option<ActionHash>, pub note: String, pub effort_quantity: Option<f64>, // hours [0.0, 10000.0] pub fulfills: Option<ActionHash>, pub has_point_in_time: Timestamp, } }
Business Logic:
- Creates a
Contributionentry with the calling agent asvalidated_by[0] - Creates
NdoToContributionsanchor fromndo_identity_hash - Creates
AgentToContributionsanchor frominput.provider(not the validator)
get_ndo_contributions(ndo_identity_hash: ActionHash) -> ExternResult<Vec<ContributionRecord>>
Returns all contributions for a given NDO identity hash via the NdoToContributions anchor.
get_agent_contributions(provider: AgentPubKey) -> ExternResult<Vec<ContributionRecord>>
Returns all contributions from a given agent (provider) via the AgentToContributions anchor.
Agreements (agreement.rs)
create_agreement(input: CreateAgreementInput) -> ExternResult<ActionHash>
Creates the first benefit redistribution Agreement (version 1) for an NDO.
Agreements are versioned (monotonic), undeletable, and linked to the NDO identity hash.
Input:
#![allow(unused)] fn main() { pub struct CreateAgreementInput { pub ndo_identity_hash: ActionHash, pub clauses: Vec<BenefitClause>, pub primary_accountable: Vec<AgentPubKey>, } }
Integrity validation:
primary_accountablemust be non-empty- Each
clause.share_percentmust be in[0.0, 100.0] - Sum of all
share_percentvalues must not exceed100.0
update_agreement(input: UpdateAgreementInput) -> ExternResult<ActionHash>
Updates an existing Agreement, incrementing its version monotonically.
Creates an AgreementUpdates chain link from the previous hash to the new one.
Input:
#![allow(unused)] fn main() { pub struct UpdateAgreementInput { pub original_action_hash: ActionHash, pub clauses: Vec<BenefitClause>, pub primary_accountable: Vec<AgentPubKey>, } }
Integrity validation: version must equal previous.version + 1 (enforced by HDI).
get_current_agreement(ndo_identity_hash: ActionHash) -> ExternResult<Option<AgreementRecord>>
Returns the latest version of the Agreement for a given NDO by walking the
AgreementUpdates chain from the NdoToAgreement anchor.
Link Architecture
Economic Event Links
- AllEconomicEvents:
economic_events anchor -> event_hash- Global discovery - ResourceToEvents:
resource_hash -> event_hash- Resource history - AgentToEvents:
agent_pubkey -> event_hash- Agent participation - EventToPrivateParticipationClaims:
event_hash -> claim_hash- PPR generation
Commitment Links
- AllCommitments:
commitments anchor -> commitment_hash- Global discovery - CommitmentToClaims:
commitment_hash -> claim_hash- Fulfillment tracking - CommitmentToPrivateParticipationClaims:
commitment_hash -> claim_hash- PPR tracking
Validation Links
- AllValidationReceipts:
validation_receipts anchor -> receipt_hash- Global discovery - ValidatedItemToReceipt:
validated_item -> receipt_hash- Validation history - ResourceToValidation:
resource_hash -> validation_hash- Resource validation - AllResourceValidations:
resource_validations anchor -> validation_hash- Validation discovery
PPR System Links
- AgentToPrivateParticipationClaims:
agent_pubkey -> claim_hash- Agent PPR portfolio - EventToPrivateParticipationClaims:
event_hash -> claim_hash- Event to PPR mapping - CommitmentToPrivateParticipationClaims:
commitment_hash -> claim_hash- Commitment to PPR mapping - ResourceToPrivateParticipationClaims:
resource_hash -> claim_hash- Resource to PPR mapping
Signal Architecture
The Governance zome emits signals for real-time UI updates:
#![allow(unused)] fn main() { pub enum Signal { LinkCreated { action }, LinkDeleted { action }, EntryCreated { action }, EntryUpdated { action }, EntryDeleted { action }, } }
Real-time Updates: Enables UI reactivity to governance changes Cross-Zome Coordination: Supports complex workflows with other zomes
Error Handling
GovernanceError Types
GovernanceError is defined in crates/utils/src/errors.rs and imported by zome_gouvernance.
#![allow(unused)] fn main() { pub enum GovernanceError { ValidationReceiptNotFound(String), // Validation lookup failures EconomicEventNotFound(String), // Event lookup failures ResourceValidationNotFound(String), // Resource validation lookup failures CommitmentNotFound(String), // Commitment lookup failures NotAuthorizedValidator, // Authorization failures InsufficientCapability(String), // Capability level restrictions ValidationAlreadyExists(String), // Duplicate validation prevention InvalidValidationScheme(String), // Validation scheme validation SerializationError(String), // Data serialization issues EntryOperationFailed(String), // DHT operation failures LinkOperationFailed(String), // Link operation failures InvalidInput(String), // Input validation failures CrossZomeCallFailed(String), // Cross-zome communication failures } }
Pattern: Comprehensive error coverage with descriptive messages
Integration: Converts to WasmError for Holochain compatibility
Privacy and Security Model
Private Data Protection
- Private Participation Claims: Stored as private entries, owner-only access
- Performance Metrics: Only accessible to claim owner
- Signature Verification: Cryptographic proof without revealing private data
- Reputation Summaries: Privacy-preserving reputation sharing
Cryptographic Security
- Bilateral Signatures: Both parties authenticate each interaction
- Tamper Evidence: Cryptographic hashes prevent undetected modifications
- Non-Repudiation: Agents cannot deny their participation in interactions
- Verification Support: Complete context for signature verification
Access Control
- Role-Based Access: Different functions require different capability levels
- Cross-Zome Validation: Private data access requires explicit validation
- Context-Aware Permissions: Access granted based on specific contexts and needs
- Audit Trails: Complete logging of all validation and access requests
Integration with Other Zomes
Resource Zome Integration
#![allow(unused)] fn main() { // Create economic event for resource custody transfer let event_output = call( CallTargetCell::Local, "zome_gouvernance", "log_economic_event".into(), None, &LogEconomicEventInput { action: VfAction::TransferCustody, provider: current_custodian, receiver: new_custodian, resource_inventoried_as: resource_hash, affects: resource_hash, resource_quantity: 1.0, note: Some("Custody transfer completed".to_string()), }, )?; }
Person Zome Integration
#![allow(unused)] fn main() { // Validate agent private data for promotion let validation_result = call( CallTargetCell::Local, "zome_gouvernance", "validate_agent_identity".into(), None, &ValidateAgentIdentityInput { agent: agent_to_validate, resource_hash: first_resource_hash, private_data_hash: Some(private_data_hash), }, )?; }
Implementation Status
✅ Completed Features
- Economic Event Logging: Complete ValueFlows-compliant economic event system
- Commitment Management: Full commitment lifecycle with claim tracking
- Validation System: Comprehensive validation workflows with receipt tracking
- PPR System: Complete Private Participation Receipt system with 16 claim types
- Reputation Management: Privacy-preserving reputation calculation and sharing
- Agent Validation: Comprehensive agent promotion and capability validation
- Cryptographic Security: Bilateral signatures and tamper-evident claims
- Private Data Protection: Secure private data validation workflows
- Cross-Zome Integration: Full integration with person and resource zomes
🔧 Current Limitations
- Basic Validation Schemes: Limited to simple approval, no complex multi-reviewer schemes
- No Economic Processes: Structured process workflows not implemented
- Limited Governance Rules: Basic rule enforcement without complex logic
- No Dispute Resolution: Structured dispute resolution workflows not implemented
📋 Future Enhancement Opportunities
- Advanced Validation Schemes: Implementation of 2-of-3, N-of-M, weighted voting
- Economic Process Integration: Structured workflows for Use, Transport, Storage, Repair
- Dispute Resolution System: Formal dispute resolution with mediator selection
- Smart Contract Integration: Automated rule enforcement and trigger conditions
- Reputation Analytics: Advanced reputation analysis and prediction
- Multi-Network Reputation: Cross-network reputation portability and validation
TODO (post-MVP — configurable GovernanceProcess, governance.md §6.2): Economic Process types (Use, Transport, Storage, Repair) are currently hardcoded strings. Post-MVP, introduce a
GovernanceProcessentry type so communities can define custom process types with their own role requirements, validation schemes, and operational state transitions. The current four process types become default instances, not compile-time constants.TODO (post-MVP — temporal governance, governance.md §4.8): Extend
GovernanceRulewith an optionalexpires_at: Timestampfield. The governance evaluation engine must skip expired rules duringevaluate_transition. Enables sunset clauses, seasonal access, and time-limited governance experiments.TODO (post-MVP — governance weight dampening, governance.md §6.4): When
governance_weight(agent)incorporatesunyt_credit_capacity, apply logarithmic dampening (e.g.,log(1 + credit_capacity)) to prevent a feedback loop where high reputation → high credit → higher governance weight → even higher reputation.
The Governance zome provides the foundational economic coordination infrastructure for the nondominium ecosystem, enabling ValueFlows-compliant resource sharing with comprehensive validation, cryptographically-secured reputation tracking, and sophisticated governance workflows.
Post-MVP Governance Architecture Gaps
The following TODOs summarise all governance-related post-MVP structural changes identified across
governance.md, agent.md, and the requirements suite. Use these as the canonical cross-reference
index when implementing each phase.
| Gap ID | Description | Affected Field(s) | Requirement(s) | governance.md ref |
|---|---|---|---|---|
| G1 | Collective/Bot agent governance | ValidationReceipt.validator, EconomicEvent.provider/receiver, Commitment.provider/receiver, PrivateParticipationClaim.counterparty, GovernanceTransitionRequest.requesting_agent, ResourceStateChange.initiated_by | REQ-GOV-16 | §3.6.1, §6.6 |
| G2 | AffiliationState governance gate | GovernanceRule.rule_data["min_affiliation"]; governance evaluate_transition | REQ-GOV-14 | §3.6.2, §6.4 |
| G6 | AffiliationRecord ceremony | New create_affiliation_record() + AffiliationRecordSigned PPR claim type | REQ-GOV-15 | §3.6.3, §4.4 |
| G9 | Sybil resistance for governance | Role promotion: N-of-M vouching or proof-of-personhood | REQ-GOV-17 | §5.3 |
| G10 | Pseudonymous governance participation | Pseudonymous path to ActiveAffiliate; block from legal-accountability roles | REQ-GOV-18 | §5.3 |
| G11 | Bot governance scope | Bot participation limited to declared capabilities; operator is accountable | — | §6.6 |
All fields marked with
TODO (G1, REQ-GOV-16)inline above must be migrated toAgentContextin Phase 3 of the implementation plan. Seeimplementation_plan.md §Phase 3 — Governance Agent Ontology Integrationfor detailed checklists.
Lobby Zome (zome_lobby) Documentation
The Lobby zome implements the global discovery and federation layer for the nondominium network. It is a separate Holochain DNA (not a zome inside the nondominium DNA) that uses the canonical network_seed: nondominium-lobby-v1 so all deployed hApps share the same Lobby DHT. The Lobby is the entry point of the Lobby → Groups → NDOs hierarchy: it maintains agent profiles and a registry of Group cells so agents can discover and join groups.
Design decisions: See ADR-LOBBY-01 through ADR-LOBBY-04 in PR #103 for the rationale behind the separate DNA and canonical network seed.
Core Data Structures
Entry Types
LobbyAgentProfile
Public agent presence in the Lobby DHT. Permissionless to create; permanent anchor (cannot be deleted).
#![allow(unused)] fn main() { pub struct LobbyAgentProfile { pub handle: String, // max 64 chars, non-empty pub avatar_url: Option<String>, // must start with "https://" if present pub bio: Option<String>, // max 500 chars pub lobby_pubkey: AgentPubKey, // must equal action.author at create time pub created_at: Timestamp, } }
Integrity constraints:
handlemust be non-empty and ≤ 64 charactersavatar_url, if present, must start with"https://"bio, if present, must be ≤ 500 characterslobby_pubkeymust equalaction.author(enforced invalidate_create_lobby_agent_profile)- Only the profile owner (
action.author == original.lobby_pubkey) may update their profile - Delete operations are unconditionally rejected
GroupAnnouncement
Registry entry for a group cloned cell. Stored in the Lobby DHT so agents can discover which groups exist and obtain their DnaHash for CellId addressing. Core fields are immutable after creation; the entry cannot be deleted.
#![allow(unused)] fn main() { pub struct GroupAnnouncement { pub group_name: String, // non-empty pub group_dna_hash: DnaHash, // stable CellId key for the cloned cell pub network_seed: String, // unique per group pub description: Option<String>, pub registered_by: AgentPubKey, // must equal action.author } }
Integrity constraints:
group_namemust be non-emptyregistered_bymust equalaction.author- Update operations are unconditionally rejected (immutable after creation)
- Delete operations are unconditionally rejected
Link Types
| Link type | Base | Target | Purpose |
|---|---|---|---|
AllLobbyAgents | Path("lobby.agents") | LobbyAgentProfile | Global agent discovery |
AgentProfileUpdates | LobbyAgentProfile (original hash) | LobbyAgentProfile (updated hash) | Update chain for profile versioning |
AgentToLobbyProfile | AgentPubKey | LobbyAgentProfile | Agent-centric lookup (used by get_lobby_agent_profile and upsert detection) |
AllGroupAnnouncements | Path("lobby.groups") | GroupAnnouncement | Global group discovery |
AgentToGroupAnnouncements | AgentPubKey | GroupAnnouncement | Agent-centric group discovery |
Functions
Agent Profile Functions
upsert_lobby_agent_profile(input: LobbyAgentProfileInput) -> ExternResult<ActionHash>
Create or update the calling agent's Lobby profile. Uses an update chain to avoid modifying the global discovery anchor.
Input:
#![allow(unused)] fn main() { pub struct LobbyAgentProfileInput { pub handle: String, pub avatar_url: Option<String>, pub bio: Option<String>, } }
Business Logic:
- Queries
AgentToLobbyProfilelinks from the agent's pubkey to detect an existing profile - If no profile exists: creates a new
LobbyAgentProfileentry, creates anAllLobbyAgentslink from the global anchor, and creates anAgentToLobbyProfilelink from the agent's pubkey - If a profile exists: calls
update_entryon the most recent profile hash, then creates anAgentProfileUpdateslink from the previous hash to the new one
Returns: Action hash of the created or updated entry.
get_lobby_agent_profile(agent: AgentPubKey) -> ExternResult<Option<LobbyAgentProfile>>
Get the lobby profile for a given agent, resolving to the latest version in the update chain.
Business Logic:
- Queries
AgentToLobbyProfilelinks from the agent's pubkey - Takes the most recent link by timestamp
- Returns the decoded
LobbyAgentProfileentry, orNoneif not found
get_all_lobby_agents(_: ()) -> ExternResult<Vec<LobbyAgentProfileRecord>>
Get all registered lobby agent profiles from the global discovery anchor. Each result contains the original action hash and the latest profile entry.
Returns: Vec<LobbyAgentProfileRecord> where each record contains action_hash: ActionHash and entry: LobbyAgentProfile.
Group Registry Functions
announce_group(input: AnnounceGroupInput) -> ExternResult<Record>
Register a group's cloned cell in the Lobby DHT so other agents can discover it.
Input:
#![allow(unused)] fn main() { pub struct AnnounceGroupInput { pub group_name: String, pub group_dna_hash: DnaHash, pub network_seed: String, pub description: Option<String>, } }
Business Logic:
- Creates a
GroupAnnouncemententry withregistered_by = agent_info().agent_initial_pubkey - Creates
AllGroupAnnouncementslink:Path("lobby.groups")→ entry (global discovery) - Creates
AgentToGroupAnnouncementslink: agent pubkey → entry (agent-centric discovery)
Returns: The created Record.
get_all_group_announcements(_: ()) -> ExternResult<Vec<Record>>
Get all group announcements from the global discovery anchor (Path("lobby.groups")).
Returns: Vec<Record> — decode each record's entry as GroupAnnouncement to access fields.
get_my_group_announcements(_: ()) -> ExternResult<Vec<Record>>
Get all group announcements registered by the calling agent, via the AgentToGroupAnnouncements links from the agent's pubkey.
get_group_announcement_by_dna_hash(dna_hash: DnaHash) -> ExternResult<Option<Record>>
Look up a group announcement by its group_dna_hash. Scans the AllGroupAnnouncements anchor and returns the first entry whose group_dna_hash matches.
Used by the UI to resolve a DnaHash (from a GroupDescriptorStub) back to the full GroupAnnouncement for display or joining.
get_my_groups(_: ()) -> ExternResult<Vec<GroupDescriptorStub>>
Returns lightweight stubs for all groups the calling agent has announced. Derives stubs from get_my_group_announcements().
#![allow(unused)] fn main() { pub struct GroupDescriptorStub { pub id: String, // network_seed — stable group identifier pub name: String, // group_name from the announcement pub is_solo: bool, // always false for real group cells } }
Helper Functions
resolve_update_chain(original: ActionHash) -> ExternResult<ActionHash>
Walks a LobbyAgentProfile update chain by following AgentProfileUpdates links until reaching the terminal hash. Used by get_lobby_agent_profile and get_all_lobby_agents.
Sweettest Coverage
Tests live in dnas/lobby/tests/src/lobby/mod.rs (package: lobby_sweettest).
| Test | Coverage |
|---|---|
upsert_lobby_agent_profile | Create + update profile, verify via get_lobby_agent_profile |
announce_group_single_agent | Single-agent group announcement + read via get_all_group_announcements |
announce_group_cross_conductor | Cross-conductor DHT consistency via await_consistency_20_s |
get_my_group_announcements_returns_own | Agent-centric lookup returns only own announcements |
get_my_groups_returns_real_group | get_my_groups returns a real GroupDescriptorStub with is_solo: false |
Run:
bun run build:happ
CARGO_TARGET_DIR=target/native-tests cargo test --package lobby_sweettest --test lobby
Group Zome (zome_group) Documentation
The Group zome implements per-group coordination within the Lobby → Group → NDO hierarchy. Each group occupies its own cloned cell (a separate DHT), providing network-level isolation between groups while sharing the same DNA template.
Architecture
The Group DNA uses the cloned-cell pattern: a single DNA template is installed once, and each new group is provisioned by calling clone_cell with a unique network seed. Each cloned cell has its own DHT — agents, memberships, work logs, and soft links are scoped to the cell, not the global nondominium DHT.
This gives groups:
- Network isolation: one group's data does not appear in another's DHT
- Shared validation: all cells use the same integrity rules
- Deferred provisioning: cells are created on demand, not at install time (
deferred: trueinworkdir/happ.yaml)
Entry Types
GroupProfile
Public profile for the group. Exactly one GroupProfile exists per cloned cell.
| Field | Type | Description |
|---|---|---|
name | String | Display name (1–100 characters) |
description | Option<String> | Optional description |
Derived from action header (not stored in entry): initiator = record.action().author(), created_at = record.action().timestamp().
Anchor: all_groups → GroupProfile (via LinkTypes::AllGroups)
GroupMembership
Records an agent's membership in the group. Created by join_group, orphaned (but not deleted) by leave_group (Holochain entries are append-only; the membership entry serves as an audit trail).
| Field | Type | Description |
|---|---|---|
group_hash | ActionHash | Hash of the GroupProfile entry |
role | Option<String> | Optional group-scoped role |
Derived from action header: member = record.action().author(), joined_at = record.action().timestamp().
WorkLog
Planning-level contribution record within the group context. Does not generate PPRs or EconomicEvent entries (ADR-GROUP-04).
| Field | Type | Description |
|---|---|---|
group_hash | ActionHash | Parent group hash |
description | String | Work description (non-empty) |
hours | f32 | Hours logged (> 0) |
Derived from action header: author = record.action().author(), logged_at = record.action().timestamp().
SoftLink
Link from a group to an NDO. This is the Group → NDO relationship in the Lobby → Groups → NDOs hierarchy. Agents who belong to multiple groups are the bridges for NDOs to travel group-to-group (organic, fractal propagation). Rendered as a dashed border in the UI to distinguish from hard (committed) links. Does not generate PPRs or EconomicEvent entries (ADR-GROUP-04).
| Field | Type | Description |
|---|---|---|
group_hash | ActionHash | Parent group hash |
target_ndo_hash | ActionHash | Target NDO action hash |
description | Option<String> | Optional link label |
Derived from action header: created_by = record.action().author(), created_at = record.action().timestamp().
NdoAnchor
Authoritative pointer from the group to an NDO cell (one NDO = one cloned DHT cell, ADR-010/ADR-011). Fixes the bare-ActionHash weakness of SoftLink: the anchor carries the full clone coordinates — (ndo_dna_hash, network_seed) plus the DNA property inputs — so any reader can re-derive the clone, verify ndo_dna_hash as a pinning check, and join the NDO network. Browsing NDOs never requires joining their cells: anchors carry enough cached descriptor data to render cards. SoftLink survives as a planning-level reference to anything, including NDOs the group does not participate in.
| Field | Type | Description |
|---|---|---|
group_hash | ActionHash | Parent group hash |
name | String | Cached from DNA properties (1–100 characters) |
description | Option<String> | Optional description |
ndo_dna_hash | DnaHash | THE permanent NDO identity (ADR-010) |
network_seed | String | Needed to clone/join the NDO cell (non-empty) |
identity_action_hash | ActionHash | Layer 0 genesis entry inside the NDO cell |
initiator | AgentPubKey | DNA property input — the NDO's initiator (not the anchor author) |
ndo_created_at | Timestamp | DNA property input — the NDO's creation time |
lifecycle_stage | LifecycleStage | Cached, best-effort synced via update_ndo_anchor |
property_regime | PropertyRegime | Immutable classification (DNA property) |
resource_nature | ResourceNature | Immutable classification (DNA property) |
Derived from action header: anchored_by = record.action().author(), anchored_at = record.action().timestamp().
Immutability split: the identity coordinates (ndo_dna_hash, network_seed, identity_action_hash, initiator, ndo_created_at, regime, nature) are copied from the original entry on every update — only the cached descriptor fields (name, description, lifecycle_stage) are mutable.
Link Types
| Link type | Source | Target | Purpose |
|---|---|---|---|
AllGroups | all_groups anchor | GroupProfile | Global discovery within cell |
GroupUpdates | GroupProfile | GroupProfile | Version chain |
GroupToMembers | GroupProfile | GroupMembership | Member enumeration |
MemberToGroups | AgentPubKey | GroupProfile | Reverse lookup |
GroupToWorkLogs | GroupProfile | WorkLog | Work log enumeration |
AgentToWorkLogs | AgentPubKey | WorkLog | Per-agent work log lookup |
GroupToSoftLinks | GroupProfile | SoftLink | Soft link enumeration |
GroupToNdoAnchors | GroupProfile | NdoAnchor | NDO anchor enumeration |
NdoAnchorUpdates | NdoAnchor | NdoAnchor | Cached descriptor version chain |
Coordinator Functions
Group Profile
| Function | Input | Output | Description |
|---|---|---|---|
create_group | GroupProfileInput { name, description } | Record | Creates a GroupProfile and the all_groups anchor link |
get_group | ActionHash | Option<Record> | Retrieves a group by its action hash |
get_my_group | () | Option<Record> | Returns the single GroupProfile in this cloned cell (one group per cell) |
update_group | UpdateGroupInput { previous_action_hash, original_action_hash, updated_name, updated_description } | Record | Updates the group name/description; only the initiator may update; creates a GroupUpdates link |
Membership
| Function | Input | Output | Description |
|---|---|---|---|
join_group | ActionHash (group hash) | Record | Creates a GroupMembership entry; guards against duplicate joins |
leave_group | ActionHash (group hash) | () | Deletes discovery links for the calling agent; entry remains on-chain as audit trail |
get_group_members | ActionHash (group hash) | Vec<AgentPubKey> | Returns the AgentPubKey of every current member, read from each GroupToMembers link's author in one get_links round-trip |
is_member | (AgentPubKey, ActionHash) | bool | Predicate: does the given agent appear in get_group_members? |
Work Logs
| Function | Input | Output | Description |
|---|---|---|---|
log_work | WorkLogInput { group_hash, description, hours } | Record | Creates a WorkLog entry with GroupToWorkLogs and AgentToWorkLogs links |
get_work_logs | ActionHash (group hash) | Vec<Record> | Returns Records for all work logs; author = record.action().author() |
get_my_work_logs | () | Vec<Record> | Returns Records for work logs authored by the calling agent (uses AgentToWorkLogs links) |
delete_work_log | ActionHash (work log hash) | ActionHash | Removes both discovery links and deletes the entry; only the original author may call this |
Soft Links
| Function | Input | Output | Description |
|---|---|---|---|
create_soft_link | SoftLinkInput { group_hash, target_ndo_hash, description } | Record | Creates a planning-only SoftLink entry |
get_soft_links | ActionHash (group hash) | Vec<Record> | Returns Records for all soft links; creator = record.action().author() |
delete_soft_link | ActionHash (soft link hash) | ActionHash | Removes the GroupToSoftLinks discovery link and deletes the entry; only the original creator may call this |
NDO Anchors
| Function | Input | Output | Description |
|---|---|---|---|
create_ndo_anchor | NdoAnchorInput { group_hash, name, description, ndo_dna_hash, network_seed, identity_action_hash, initiator, ndo_created_at, lifecycle_stage, property_regime, resource_nature } | Record | Anchors an NDO cell in this group's DHT with full clone coordinates |
get_ndo_anchors | ActionHash (group hash) | Vec<Record> | Returns the latest Record per anchor, resolving the NdoAnchorUpdates chain |
update_ndo_anchor | UpdateNdoAnchorInput { original_action_hash, previous_action_hash, updated_name, updated_description, updated_lifecycle_stage } | Record | Refreshes cached descriptor fields; identity coordinates are copied from the original entry |
Validation Rules
GroupProfile.namemust be non-empty and ≤ 100 charactersWorkLog.descriptionmust be non-emptyWorkLog.hoursmust be > 0NdoAnchor.namemust be non-empty and ≤ 100 charactersNdoAnchor.network_seedmust be non-empty
Hash fields (
group_hash,target_ndo_hash) are always 39 bytes and cannot be "empty". Existence of the referenced entry is validated at the coordinator level, not in the integrity zome (which has no DHT access).
Error Types
Domain errors are defined in nondominium_shared::GroupError:
| Variant | When raised |
|---|---|
AlreadyMember | join_group called when agent already has a membership entry |
NotMember | Membership expected but not found |
GroupNotFound(String) | Group hash resolves to nothing |
NotAuthor | Operation requires authorship check |
EntryOperationFailed(String) | create_entry / get failure |
LinkOperationFailed(String) | Link creation/deletion failure |
SerializationError(String) | Entry deserialization failure |
InvalidInput(String) | Caller-supplied value rejected |
Architectural Decisions
ADR-GROUP-03: The GroupService TypeScript interface takes groupCellId: CellId (DnaHash + AgentPubKey). Groups are cloned cells — CellId is the correct Holochain API for addressing a specific clone. The group_dna_hash from a GroupAnnouncement in the Lobby DHT is used to resolve the CellId via getGroupCellHandle(client, dnaHash). All Svelte components depend on GroupServiceTag — adding fields to the interface requires updating all callers.
ADR-GROUP-04: WorkLog and SoftLink entries are planning-only and do not generate EconomicEvent entries or PPRs. Generating PPRs for planning-level actions would misrepresent intent and inflate reputation counts.
ADR-010 / ADR-011 (NDO-per-cell): one NDO = one cloned cell of the ndo DNA (dnas/ndo/workdir/dna.yaml, bundling the existing zome_resource and zome_gouvernance WASMs). The NDO's immutable Layer 0 fields live in the clone's DNA properties, so the DnaHash is the permanent, organization-agnostic NDO identity. Groups hold NdoAnchor entries instead of a global NDO registry; the Lobby stays a group registry.
Testing
Tests live in dnas/group/tests/src/group/mod.rs (group lifecycle) and dnas/group/tests/src/ndo_anchor/mod.rs (NDO-per-cell + anchors). All tests use setup_two_agents() / ndo_dna_with_coordinates() from common::conductors and await_consistency_20_s for cross-agent DHT sync.
Group target coverage: group creation, get_group (fetch by hash), get_my_group, membership (join/leave/is_member/duplicate-join error), work logs (log_work, get_work_logs, get_my_work_logs, delete_work_log), soft links (create_soft_link, get_soft_links, delete_soft_link), update_group, and validation rejection cases (empty name, zero hours). 13 tests — --test-threads 6 required to avoid port exhaustion.
NDO anchor target coverage: DNA-hash-as-identity derivation (same coordinates → same hash, different properties → different network), genesis identity round trip inside an NDO cell, anchor round trip with clone coordinates, cached descriptor update chain, empty-name validation rejection, and the full second-agent join-via-anchor-coordinates flow with the DnaHash pinning check. 6 tests.
# Prerequisites
bun run build:happ
# Run all group tests (thread-limited — 13 tests × 2 conductors each)
CARGO_TARGET_DIR=target/native-tests cargo test --package group_sweettest --test group -- --test-threads 6
# Run the NDO anchor / NDO-per-cell tests
CARGO_TARGET_DIR=target/native-tests cargo test --package group_sweettest --test ndo_anchor -- --test-threads 6
# Run a specific test
CARGO_TARGET_DIR=target/native-tests cargo test --package group_sweettest --test group create_group_returns_profile
CARGO_TARGET_DIR=target/native-tests cargo test --package group_sweettest --test ndo_anchor second_agent_joins_ndo_via_anchor_coordinates
hREA Documentation
This folder contains documentation related to hREA, the Holochain implementation of the ValueFlows economic vocabulary. It covers Nondominium's integration strategy, the long-term maintainership roadmap, and a field-level compliance audit of hREA against the ValueFlows 1.0 ontology.
Documents
| Document | Description |
|---|---|
| Integration Strategy | How Nondominium integrates hREA as its ValueFlows backend engine: architecture, cross-DNA call patterns, migration plan |
| Strategic Roadmap | Phase 1+2 maintainership proposal: VF 1.0 gap closure, stub validation implementation, JSON-LD interoperability API |
| ValueFlows 1.0 Compliance Analysis | Field-by-field audit of hREA main-0.6 against VF 1.0 (~65% compliance), with P0/P1/P2 gap prioritization |
| v0.2 Release Plan | Nondominium v0.2 scope: two-phase migration onto hREA (native VF substitution, then extension modules), preconditions, and success criteria |
Context
hREA serves as Nondominium's economic primitive layer. Nondominium's three zomes (person, resource, governance) delegate core ValueFlows types (EconomicResource, EconomicEvent, Agent, Commitment) to hREA via cross-DNA calls, keeping Nondominium focused on its specialized concerns: governance, privacy, and the PPR reputation system.
NDO v1.0's full capabilities depend on hREA reaching the compliance targets described in the strategic roadmap. The P0 gaps (vf:Claim, effortQuantity) in hREA must land before Nondominium's work-event recording and claim-based reciprocity workflows are available.
Related Documents
- NDO v1.0 Architecture Design: NDO's dependency on hREA and dual-DNA architecture
- API Reference: Cross-DNA call patterns (Pattern 5: agent name resolution)
hREA Integration Strategy for Nondominium
Executive Summary
This document outlines the comprehensive integration strategy for incorporating hREA (Holochain Resource-Event-Agent) into Nondominium's architecture. The approach positions hREA as a backend economic engine while maintaining Nondominium's specialized focus on governance, privacy, and the Private Participation Receipt (PPR) system.
Key Decision: Use git submodule + cross-DNA calls via the Holochain HDK call() function to integrate hREA directly at the Rust/zome level. This bypasses hREA's GraphQL API entirely; integration happens in the backend, not the UI.
hREA Repository: https://github.com/h-REA/hREA (branch: main-0.6)
Architecture: Single DNA (hrea) with separate coordinator + integrity zomes
Architecture Vision
Strategic Positioning
┌─────────────────────────────────────────────────────────────┐
│ TrueCommon - Peer Production │
│ (Broader application using Nondominium as core engine) │
└─────────────────────┬───────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Nondominium - Peer Sharing │
│ (Specialized Engine - 3 Zomes) │
│ ┌─────────────────┬─────────────────┬─────────────────┐ │
│ │ Person │ Resource │ Governance │ │
│ │ (Private │ (Delegates to │ (PPR, Rules, │ │
│ │ PersonData + │ hREA for core │ Validation — │ │
│ │ ReaAgent) │ VF types) │ all custom) │ │
│ └─────────────────┴─────────────────┴─────────────────┘ │
│ Cross-DNA calls via CallTargetCell::OtherRole │
└─────────────────────┬───────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ hREA DNA │
│ (Standard ValueFlows Implementation) │
│ ┌───────────┬──────────────┬───────────────┬────────────┐ │
│ │ ReaAgent │ EcoResource │ ReaCommitment │ ReaEco │ │
│ │ │ (rich model) │ (full VF) │ Event │ │
│ └───────────┴──────────────┴───────────────┴────────────┘ │
│ ┌───────────┬──────────────┬───────────────┬────────────┐ │
│ │ ReaProcess│ ResourceSpec │ ReaAgreement │ ReaIntent │ │
│ │ │ │ │ │ │
│ └───────────┴──────────────┴───────────────┴────────────┘ │
└─────────────────────────────────────────────────────────────┘
Why Zome-Level Integration (Not GraphQL)
hREA exposes a GraphQL API intended for UI consumption. For Nondominium, integration must happen at the Rust/HDK layer because:
- Business logic integrity: Governance rules and PPR generation must fire atomically with economic events; this cannot be guaranteed through a UI-level API roundtrip
- Capability security: Cross-zome calls within the same conductor maintain Holochain's capability-based access model; GraphQL calls would bypass this
- Performance: Same-conductor bridge calls (~5-10ms) vs network roundtrips (~100-500ms)
- Atomicity: Creating a Commitment + generating a PPR claim must happen in the same zome call context
Gap Analysis: Current Nondominium vs hREA
Entity Comparison
EconomicResource
| Field | Nondominium (current) | hREA ReaEconomicResource |
|---|---|---|
| quantity | f64 (single field) | accounting_quantity: Option<QuantityValue> + onhand_quantity: Option<QuantityValue> (two separate quantities) |
| unit | String | unit_of_effort: Option<ActionHash> (Unit is a first-class entry) |
| custodian | AgentPubKey (direct) | primary_accountable: Option<ActionHash> (links to ReaAgent entry) |
| location | Option<String> | current_location: Option<String> (same) |
| operational_state | OperationalState enum on EconomicResource | state: Option<String> (string-based) |
| spec link | via SpecificationToResource link | conforms_to: Option<ActionHash> (embedded) |
| — | missing | contained_in: Option<ActionHash> (nested resources) |
| — | missing | stage: Option<ActionHash> (lifecycle stage entry) |
| — | missing | lot: Option<String> (batch tracking) |
| — | missing | name: Option<String> |
| — | missing | image: Option<String> |
| — | missing | tracking_identifier: Option<String> |
Key gap: Nondominium's EconomicResource uses a single quantity: f64 and a String unit. hREA uses QuantityValue { has_numerical_value: f64, has_unit: ActionHash } and tracks both accounting quantity (committed) and on-hand quantity (physically available) separately. This distinction is fundamental to ValueFlows and currently missing.
Also critical: hREA automatically updates onhand_quantity and accounting_quantity when an economic event is created, based on the action type's ActionEffect. Nondominium has no equivalent automatic quantity update system.
EconomicEvent
| Field | Nondominium (current) | hREA ReaEconomicEvent |
|---|---|---|
| action | VfAction (custom Rust enum) | rea_action: String (standard VF string + vf_actions crate) |
| provider | AgentPubKey (direct) | provider: Option<ActionHash> (links to ReaAgent) |
| receiver | AgentPubKey (direct) | receiver: Option<ActionHash> (links to ReaAgent) |
| resource | resource_inventoried_as: ActionHash | resource_inventoried_as: Option<ActionHash> |
| affects | affects: ActionHash (duplicate?) | to_resource_inventoried_as: Option<ActionHash> (destination resource) |
| quantity | resource_quantity: f64 | resource_quantity: Option<QuantityValue> |
| time | event_time: Timestamp | has_point_in_time: Option<Timestamp> + has_beginning + has_end |
| — | missing | input_of: Option<ActionHash> (Process) |
| — | missing | output_of: Option<ActionHash> (Process) |
| — | missing | fulfills: Option<Vec<ActionHash>> (Commitment links) |
| — | missing | satisfies: Option<Vec<ActionHash>> (Intent links) |
| — | missing | realization_of: Option<ActionHash> (Agreement) |
| — | missing | triggered_by: Option<ActionHash> (triggering Event) |
| — | missing | corrects: Option<ActionHash> (correction chain) |
Key gap: The Nondominium EconomicEvent has a field called affects which appears to duplicate resource_inventoried_as. hREA's to_resource_inventoried_as is the correct field for the destination resource in a transfer (a different concept). More critically, the entire fulfills relationship (Event fulfills Commitment) is absent from Nondominium's model.
Commitment
| Field | Nondominium (current) | hREA ReaCommitment |
|---|---|---|
| action | VfAction enum | rea_action: Option<String> |
| provider | AgentPubKey | provider: Option<ActionHash> (ReaAgent) |
| receiver | AgentPubKey | receiver: Option<ActionHash> (ReaAgent) |
| resource | resource_inventoried_as: Option<ActionHash> | same field name |
| spec | resource_conforms_to: Option<ActionHash> | resource_conforms_to: Option<ActionHash> (same) |
| process | input_of: Option<ActionHash> (stub, always None) | input_of: Option<ActionHash> + output_of: Option<ActionHash> |
| due date | due_date: Timestamp | due: Option<Timestamp> |
| — | missing | effort_quantity: Option<QuantityValue> |
| — | missing | resource_quantity: Option<QuantityValue> |
| — | missing | has_beginning / has_end / has_point_in_time |
| — | missing | clause_of: Option<ActionHash> (Agreement) |
| — | missing | planned_within: Option<ActionHash> (Plan) |
| — | missing | satisfies: Option<ActionHash> (Intent) |
| — | missing | finished: Option<bool> |
ResourceSpecification
| Field | Nondominium (current) | hREA ReaResourceSpecification |
|---|---|---|
| name | String | String (same, required) |
| description | String | (missing — hREA is simpler here) |
| category | String | (missing — Nondominium extension) |
| image_url | Option<String> | image: Option<String> |
| tags | Vec<String> | (missing — Nondominium extension) |
| is_active | bool | (missing — Nondominium extension) |
| — | missing | default_unit_of_effort: Option<ActionHash> |
| — | missing | default_unit_of_resource: Option<ActionHash> |
Note: For ResourceSpecification, Nondominium has more fields than hREA (category, tags, description, is_active). This is a case where the hybrid approach makes sense.
VfAction vs hREA Actions
Nondominium defines a custom Rust enum:
#![allow(unused)] fn main() { pub enum VfAction { Transfer, Move, Use, Consume, Produce, Work, Modify, Combine, Separate, Raise, Lower, Cite, Accept, InitialTransfer, AccessForUse, TransferCustody } }
hREA uses rea_action: String with standardized ValueFlows action names:
"transfer","move","use","consume","produce","work","modify","combine","separate","raise","lower","cite","accept","dropAll","pickup"
hREA's vf_actions crate maps action strings to ActionEffect variants that control how resource quantities change on event creation. Nondominium's custom enum lacks this system.
Concepts Entirely Missing from Nondominium
| hREA Type | Purpose | Priority |
|---|---|---|
ReaProcess | Groups events/commitments into production flows | Medium (Phase 3) |
ReaAgreement | Multi-party coordination framework | Low (Phase 4) |
ReaProposal / ReaIntent | What agents want to do / offer | Low (Phase 4) |
ReaPlan | Planned value flows | Low (Phase 4) |
ReaFulfillment | Explicit Event-fulfills-Commitment link | High (Phase 2) |
QuantityValue struct | Typed quantity with unit reference | High (Phase 2) |
| Unit entries | First-class unit of measure | High (Phase 2) |
| Auto quantity update | Resource quantities auto-update on event | High (Phase 2) |
Nondominium Types With No hREA Equivalent (Keep Custom)
These are Nondominium's unique innovations and must remain fully custom:
| Type | Reason |
|---|---|
PrivateParticipationClaim (PPR) | Core Nondominium innovation; no VF equivalent |
GovernanceRule | Governance-as-operator pattern; Nondominium-specific |
ResourceValidation | Community validation flow; Nondominium-specific |
ValidationReceipt | Validator attestation; Nondominium-specific |
PrivatePersonData | Private PII layer; hREA has no privacy model |
| Role-based access control | Capability grants tied to governance roles |
Decision Matrix
| Entity | Decision | Implementation |
|---|---|---|
EconomicResource | Use hREA | Call create_economic_event_with_resource in hREA; store returned hash in Nondominium link |
EconomicEvent | Use hREA | Call create_rea_economic_event in hREA; PPR generation fires after in Nondominium |
Commitment | Use hREA | Call create_rea_commitment; link to PPR claims via Nondominium-side links |
ResourceSpecification | Hybrid | Create ReaResourceSpecification in hREA for VF compliance; extend with a Nondominium ResourceSpecificationExtension entry (category, tags, description, is_active) linked to hREA hash |
VfAction enum | Replace with hREA strings | Use hREA action strings ("transfer", "use", etc.); map custom actions (InitialTransfer, AccessForUse, TransferCustody) to hREA-compatible strings or extensions |
PrivateParticipationClaim | Keep custom | No hREA equivalent; core innovation |
GovernanceRule | Keep custom | No hREA equivalent; governance-as-operator pattern |
ValidationReceipt / ResourceValidation | Keep custom | No hREA equivalent |
Person / Agent | Hybrid | ReaAgent in hREA DNA (public identity); PrivatePersonData stays in Nondominium DNA |
Cross-DNA Call Patterns (Rust / HDK)
All calls from Nondominium zomes to hREA use CallTargetCell::OtherRole("hrea".into()).
The hREA coordinator zome name is also "hrea".
Helper: Generic hREA Bridge Call
#![allow(unused)] fn main() { // In a shared utilities module accessible to coordinator zomes use hdk::prelude::*; pub fn call_hrea<I, O>(fn_name: &str, payload: &I) -> ExternResult<O> where I: serde::Serialize + std::fmt::Debug, O: serde::de::DeserializeOwned + std::fmt::Debug, { let response = call( CallTargetCell::OtherRole("hrea".into()), "hrea", fn_name.into(), None, payload, )?; match response { ZomeCallResponse::Ok(extern_io) => extern_io.decode::<O>().map_err(|e| { wasm_error!(WasmErrorInner::Guest(format!( "hREA response decode error for {}: {:?}", fn_name, e ))) }), ZomeCallResponse::Unauthorized(_, _, fn_name, _) => { Err(wasm_error!(WasmErrorInner::Guest(format!( "hREA call unauthorized: {}", fn_name )))) } ZomeCallResponse::NetworkError(e) => { Err(wasm_error!(WasmErrorInner::Guest(format!( "hREA network error: {}", e )))) } ZomeCallResponse::CountersigningSession(e) => { Err(wasm_error!(WasmErrorInner::Guest(format!( "hREA countersigning error: {}", e )))) } } } }
Pattern 1: Creating a Resource + Event (atomic)
hREA provides create_economic_event_with_resource which creates both in one call and automatically sets up quantities. Use this for resource registration:
#![allow(unused)] fn main() { // zome_resource coordinator — registers a new resource in hREA pub fn register_resource_in_hrea( hrea_agent_hash: ActionHash, hrea_spec_hash: ActionHash, quantity: f64, unit_hash: ActionHash, ) -> ExternResult<ActionHash> { #[derive(Serialize, Deserialize, Debug)] struct QuantityValue { has_numerical_value: f64, has_unit: ActionHash, } #[derive(Serialize, Deserialize, Debug)] struct ReaEconomicResource { id: Option<ActionHash>, conforms_to: Option<ActionHash>, primary_accountable: Option<ActionHash>, accounting_quantity: Option<QuantityValue>, onhand_quantity: Option<QuantityValue>, // other fields as None... } #[derive(Serialize, Deserialize, Debug)] struct ReaEconomicEvent { id: Option<ActionHash>, rea_action: String, provider: Option<ActionHash>, receiver: Option<ActionHash>, resource_quantity: Option<QuantityValue>, has_point_in_time: Option<Timestamp>, } #[derive(Serialize, Deserialize, Debug)] struct EconomicEventWithResource { economic_event: ReaEconomicEvent, resource: ReaEconomicResource, } let qty = QuantityValue { has_numerical_value: quantity, has_unit: unit_hash, }; let input = EconomicEventWithResource { economic_event: ReaEconomicEvent { id: None, rea_action: "produce".to_string(), provider: Some(hrea_agent_hash.clone()), receiver: Some(hrea_agent_hash.clone()), resource_quantity: Some(QuantityValue { has_numerical_value: quantity, has_unit: unit_hash.clone(), }), has_point_in_time: Some(sys_time()?), }, resource: ReaEconomicResource { id: None, conforms_to: Some(hrea_spec_hash), primary_accountable: Some(hrea_agent_hash), accounting_quantity: Some(qty), onhand_quantity: None, // set by hREA from event }, }; let record: Record = call_hrea("create_economic_event_with_resource", &input)?; Ok(record.action_address().clone()) } }
Pattern 2: Creating a Commitment in hREA
#![allow(unused)] fn main() { // zome_gouvernance coordinator — creates a commitment in hREA pub fn propose_commitment_in_hrea( rea_action: &str, provider_hrea_hash: ActionHash, receiver_hrea_hash: ActionHash, resource_hash: Option<ActionHash>, resource_spec_hash: Option<ActionHash>, quantity: f64, unit_hash: ActionHash, due: Option<Timestamp>, ) -> ExternResult<ActionHash> { #[derive(Serialize, Deserialize, Debug)] struct QuantityValue { has_numerical_value: f64, has_unit: ActionHash } #[derive(Serialize, Deserialize, Debug)] struct ReaCommitment { id: Option<ActionHash>, rea_action: Option<String>, provider: Option<ActionHash>, receiver: Option<ActionHash>, resource_inventoried_as: Option<ActionHash>, resource_conforms_to: Option<ActionHash>, resource_quantity: Option<QuantityValue>, due: Option<Timestamp>, finished: Option<bool>, } let input = ReaCommitment { id: None, rea_action: Some(rea_action.to_string()), provider: Some(provider_hrea_hash), receiver: Some(receiver_hrea_hash), resource_inventoried_as: resource_hash, resource_conforms_to: resource_spec_hash, resource_quantity: Some(QuantityValue { has_numerical_value: quantity, has_unit: unit_hash, }), due, finished: Some(false), }; let record: Record = call_hrea("create_rea_commitment", &input)?; Ok(record.action_address().clone()) } }
Pattern 3: Recording an Economic Event (fulfills Commitment)
When a commitment is fulfilled, create an economic event in hREA that references both the resource and the commitment. hREA automatically updates resource quantities.
#![allow(unused)] fn main() { // zome_gouvernance coordinator — records fulfillment of a commitment pub fn record_economic_event_in_hrea( rea_action: &str, provider_hrea_hash: ActionHash, receiver_hrea_hash: ActionHash, resource_hash: ActionHash, to_resource_hash: Option<ActionHash>, quantity: f64, unit_hash: ActionHash, fulfills: Vec<ActionHash>, // hREA commitment hashes ) -> ExternResult<ActionHash> { #[derive(Serialize, Deserialize, Debug)] struct QuantityValue { has_numerical_value: f64, has_unit: ActionHash } #[derive(Serialize, Deserialize, Debug)] struct ReaEconomicEvent { id: Option<ActionHash>, rea_action: String, provider: Option<ActionHash>, receiver: Option<ActionHash>, resource_inventoried_as: Option<ActionHash>, to_resource_inventoried_as: Option<ActionHash>, resource_quantity: Option<QuantityValue>, has_point_in_time: Option<Timestamp>, fulfills: Option<Vec<ActionHash>>, } let input = ReaEconomicEvent { id: None, rea_action: rea_action.to_string(), provider: Some(provider_hrea_hash), receiver: Some(receiver_hrea_hash), resource_inventoried_as: Some(resource_hash), to_resource_inventoried_as: to_resource_hash, resource_quantity: Some(QuantityValue { has_numerical_value: quantity, has_unit: unit_hash, }), has_point_in_time: Some(sys_time()?), fulfills: if fulfills.is_empty() { None } else { Some(fulfills) }, }; let record: Record = call_hrea("create_rea_economic_event", &input)?; Ok(record.action_address().clone()) } }
Pattern 4: Capability Grants for Cross-Role Calls
Depending on the hREA DNA's capability configuration, cross-role calls may need explicit unrestricted grants. Add to hREA DNA's init if required, or configure in the happ.yaml:
#![allow(unused)] fn main() { // In zome_gouvernance or zome_resource init() — grant hREA functions #[hdk_extern] pub fn init(_: ()) -> ExternResult<InitCallbackResult> { let mut fns: BTreeSet<(ZomeName, FunctionName)> = BTreeSet::new(); fns.insert(("hrea".into(), "create_rea_economic_event".into())); fns.insert(("hrea".into(), "create_economic_event_with_resource".into())); fns.insert(("hrea".into(), "create_rea_commitment".into())); fns.insert(("hrea".into(), "get_latest_rea_economic_resource".into())); create_cap_grant(CapGrantEntry { tag: "nondominium-hrea-bridge".into(), access: CapAccess::Unrestricted, functions: GrantedFunctions::Listed(fns), })?; Ok(InitCallbackResult::Pass) } }
Pattern 5: Person / Agent Hybrid
When creating a Person in Nondominium, also create a ReaAgent in hREA and store the cross-reference:
#![allow(unused)] fn main() { // zome_person coordinator — create_person now creates in both DNAs pub fn create_person_with_hrea_agent( name: String, avatar_url: Option<String>, private_data: Option<PrivatePersonDataInput>, ) -> ExternResult<PersonWithHreaRecord> { #[derive(Serialize, Deserialize, Debug)] struct ReaAgent { id: Option<ActionHash>, name: String, agent_type: String, image: Option<String>, classified_as: Option<Vec<String>>, note: Option<String>, } // 1. Create ReaAgent in hREA DNA let hrea_agent_input = ReaAgent { id: None, name: name.clone(), agent_type: "Person".to_string(), image: avatar_url.clone(), classified_as: None, note: None, }; let hrea_record: Record = call_hrea("create_rea_agent", &hrea_agent_input)?; let hrea_agent_hash = hrea_record.action_address().clone(); // 2. Create Nondominium Person entry (stores reference to hREA agent) let person = Person { name, avatar_url, hrea_agent_hash: Some(hrea_agent_hash.clone()), created_at: sys_time()?, }; let person_hash = create_entry(&EntryTypes::Person(person.clone()))?; // 3. Create PrivatePersonData if private data provided let private_data_hash = if let Some(private) = private_data { Some(create_entry(&EntryTypes::PrivatePersonData(private))?) } else { None }; Ok(PersonWithHreaRecord { person_hash, hrea_agent_hash, private_data_hash, }) } }
hApp Bundle Configuration
happ.yaml (dual-DNA setup)
manifest_version: "1"
name: nondominium
description: Nondominium peer-sharing hApp with hREA economic backend
roles:
- name: nondominium
provisioning:
strategy: create
deferred: false
dna:
bundled: nondominium.dna
modifiers:
network_seed: ~
properties: ~
- name: hrea
provisioning:
strategy: create
deferred: false
dna:
bundled: hrea.dna
modifiers:
network_seed: ~
properties: ~
The role name "hrea" in happ.yaml is what gets passed to CallTargetCell::OtherRole("hrea".into()) in coordinator zome code.
Git Submodule Setup
# Add hREA as a submodule (pin to stable main-0.6 branch commit)
git submodule add -b main-0.6 https://github.com/h-REA/hREA.git vendor/hrea
cd vendor/hrea
git checkout fc3b5e78e749e84b8738dc4813bba9037afd17bc
cd ../..
git add vendor/hrea .gitmodules
git commit -m "add hREA as submodule (main-0.6 branch)"
Cargo.toml Workspace
[workspace]
members = [
"dnas/nondominium/zomes/coordinator/*",
"dnas/nondominium/zomes/integrity/*",
# hREA zomes compiled separately via their own build system
]
# If sharing types directly (advanced integration):
[workspace.dependencies]
hrea_integrity = { path = "vendor/hrea/dnas/hrea/zomes/integrity/hrea" }
Note: The struct definitions in the call patterns above use local inline structs to avoid coupling Nondominium's crate graph to hREA's. For tighter integration, use hrea_integrity as a workspace dependency and import types directly.
Migration Strategy
Holochain DHT entries are immutable: existing entries cannot be deleted or migrated in-place. The migration path respects this constraint.
Phase 2 Migration (Current)
Goal: Route all new entry creation through hREA; existing entries remain valid.
- No changes to existing entries: Existing
Commitment,EconomicEvent, andEconomicResourceentries on the DHT remain as-is and continue to be queryable - New entries use hREA: All new function calls in coordinator zomes call hREA via bridge,
then store the returned
ActionHashin Nondominium-side link structures - Cross-reference links: Add a
HreaResourceHashlink type inzome_resource_integritylinkingEconomicResourceoriginal hash → hREAReaEconomicResourcehash - Dual-read query layer:
get_all_economic_resources()returns both legacy custom entries and hREA-backed entries, normalized through a shared response type
Dual-Read Response Type
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug)] pub enum ResourceResponse { // Legacy custom entry (Phase 1 data) Legacy { hash: ActionHash, resource: EconomicResource, }, // hREA-backed entry (Phase 2+ data) HreaBackd { nondominium_hash: ActionHash, hrea_hash: ActionHash, // normalized fields quantity: f64, custodian: AgentPubKey, }, } }
Phase 3: Type Deprecation
Once Phase 2 has been running for a defined period and all active resources are hREA-backed:
- Stop creating new
zome_gouvernance::Commitmententries; use onlyReaCommitmentvia hREA - Stop creating new
zome_gouvernance::EconomicEvententries; use onlyReaEconomicEventvia hREA - Keep the integrity types (they cannot be removed without breaking DHT validation of old entries)
- Mark coordinator functions as deprecated in documentation
Privacy Architecture
hREA's Privacy Model
hREA has no custom privacy implementation. All entries are public by design:
ReaAgententries contain only public-facing informationReaEconomicResourceentries are fully public- No encrypted or private entry types exist
Nondominium's Complementary Privacy Layer
Nondominium's PrivatePersonData system fills exactly the gap hREA leaves:
| Layer | What | Where |
|---|---|---|
| Public identity | ReaAgent (name, avatar, type) | hREA DNA — discoverable by all |
| Private PII | PrivatePersonData (email, phone, address) | Nondominium DNA — capability-gated |
| Economic coordination | ReaEconomicResource, ReaCommitment | hREA DNA — public ValueFlows |
| Participation tracking | PrivateParticipationClaim (PPR) | Nondominium DNA — private to agent |
This is not a conflict; it is a clean division of concerns:
- hREA handles economic visibility (what resources exist, what commitments are made)
- Nondominium handles relational privacy (who you are, what you've privately contributed)
Testing Strategy
Dual-DNA Tryorama Setup
// tests/src/multi-dna/hrea-integration.test.ts
import { runScenario, dhtSync } from "@holochain/tryorama";
describe("Nondominium-hREA integration", () => {
test("creating a resource creates ReaEconomicResource in hREA DNA", async () => {
await runScenario(async (scenario) => {
const appBundleSource = {
type: "path",
value: "workdir/nondominium.webhapp", // includes both DNAs
};
const [alice, bob] = await scenario.addPlayersWithApps([
{ appBundleSource },
{ appBundleSource },
]);
// Create resource via Nondominium interface
const resourceResult = await alice.appWs.callZome({
role_name: "nondominium",
zome_name: "zome_resource",
fn_name: "create_economic_resource",
payload: {
spec_hash: someSpecHash,
quantity: 1.0,
unit: "piece",
current_location: null,
},
});
await dhtSync([alice, bob], alice.cells[0].cell_id[0]);
// Verify ReaEconomicResource exists in hREA DNA
const hreaResource = await alice.appWs.callZome({
role_name: "hrea",
zome_name: "hrea",
fn_name: "get_latest_rea_economic_resource",
payload: resourceResult.hrea_resource_hash,
});
expect(hreaResource).toBeTruthy();
expect(hreaResource.entry.conforms_to).toEqual(someHreaSpecHash);
});
});
test("PPR claim generated after economic event", async () => {
await runScenario(async (scenario) => {
// ... setup
// Record event (creates in hREA AND generates PPR in Nondominium)
const eventResult = await alice.appWs.callZome({
role_name: "nondominium",
zome_name: "zome_gouvernance",
fn_name: "create_economic_event",
payload: {
rea_action: "use",
resource_hash: resourceHash,
quantity: 1.0,
// ...
},
});
// Verify event exists in hREA
const hreaEvent = await alice.appWs.callZome({
role_name: "hrea",
zome_name: "hrea",
fn_name: "get_latest_rea_economic_event",
payload: eventResult.hrea_event_hash,
});
expect(hreaEvent).toBeTruthy();
// Verify PPR claim generated in Nondominium (private — only Alice can see)
const pprClaims = await alice.appWs.callZome({
role_name: "nondominium",
zome_name: "zome_gouvernance",
fn_name: "get_my_participation_claims",
payload: null,
});
expect(pprClaims.length).toBeGreaterThan(0);
});
});
});
Performance Considerations
Call Latency Hierarchy
| Call Type | Approximate Latency | When to Use |
|---|---|---|
| Cross-zome, same DNA | ~1ms | Intra-Nondominium calls |
| Cross-DNA bridge (same conductor) | ~5-10ms | Nondominium → hREA |
| DHT get (local) | ~1-5ms | Reading own-authored entries |
| DHT get (remote) | ~100-500ms | Reading peer-authored entries |
| Remote agent call | ~200-1000ms | Agent-to-agent direct calls |
The bridge call overhead (~5-10ms) is acceptable because hREA integration happens at write time (creating resources/events), not at read time for every UI render.
Optimization Patterns
- Cache hREA hashes: Store returned hREA
ActionHashvalues in Nondominium links so reads don't need to re-query hREA - Batch event creation: Where multiple events are logically grouped, consider a single
create_economic_event_with_resourcecall over multiple separate calls - Lazy hREA sync: For non-critical metadata (e.g., updating
ReaAgentimage), defer the hREA call to a background signal rather than blocking the main operation
Implementation Roadmap
Phase 1: Foundation (Person Zome — CURRENT TARGET)
-
Set up hREA git submodule (
vendor/hrea,main-0.6branch) -
Configure
happ.yamlwithnondominiumandhrearoles -
Build hREA DNA and include in
.webhappbundle -
Add
hrea_agent_hash: Option<ActionHash>field toPersonintegrity entry -
Implement
create_rea_agentbridge call inzome_personcoordinator -
Update
create_personto createReaAgentin hREA first - Write Tryorama tests for dual-DNA person creation
-
Validate
get_rea_agents_from_action_hashescross-DNA read
Phase 2: Resource Lifecycle
-
Add
hrea_resource_hash: Option<ActionHash>field or link to resource entries -
Implement
create_economic_event_with_resourcebridge call -
Implement
create_rea_resource_specificationbridge call -
Implement
ResourceSpecificationExtensionhybrid pattern -
Re-enable cross-zome governance call (currently commented out in
economic_resource.rs) - Write dual-DNA resource lifecycle tests
Phase 3: Governance Integration
-
Implement
create_rea_commitmentbridge call -
Implement
create_rea_economic_eventbridge call (withfulfillsfield) - Wire PPR generation to fire after hREA event creation
- Implement dual-read query layer for legacy + hREA resources
- Write commitment → event → PPR end-to-end scenario tests
Phase 4: Production Readiness
- Security audit of cross-DNA capability grants
- Performance benchmarks for bridge call overhead at scale
- Submodule version pinning and upgrade process
- Community deployment guide
Risk Assessment
| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
hREA main-0.6 branch API changes | Medium | High | Pin to a specific commit hash, not a branch pointer |
| Cross-DNA call capability issues | Medium | High | Test cap grants early in Phase 1 |
| hREA DNA build incompatibility (HDK version mismatch) | Low | High | Confirmed: both use HDK ^0.6.0 / HDI ^0.7.0 on holonix main-0.6 |
| Performance degradation from bridge calls | Low | Medium | Benchmark early; cache hREA hashes in Nondominium links |
| Migration query complexity (dual-read layer) | Medium | Low | Keep migration period short; prioritize hREA-backed data |
Future: PPR System as hREA Enhancement
Nondominium's PPR system has no current hREA equivalent. It could eventually be contributed to hREA as a governance extension:
- Prove the pattern: Demonstrate PPR value in Nondominium production
- Document the spec: Formalize
PrivateParticipationClaimas a ValueFlows extension - Propose to community: Submit to ValueFlows spec and hREA governance
- Upstream contribution: Contribute proven patterns back to hREA once validated
Conclusion
Nondominium's integration strategy uses hREA as the economic data layer (EconomicResource, EconomicEvent, Commitment, Agent) while keeping Nondominium's governance and privacy layer entirely custom (PPR, GovernanceRule, ValidationReceipt, PrivatePersonData).
The bridge pattern (call(CallTargetCell::OtherRole("hrea"), "hrea", fn_name, ...)) is the mechanism that makes this work at the Rust/zome level without touching hREA's GraphQL API.
Key outcomes:
- ValueFlows compliance: hREA's battle-tested VF model handles all economic data correctly
- Privacy preserved: PrivatePersonData + PPR system layers over hREA's public economic data
- Governance innovation intact: PPR system remains Nondominium's unique contribution
- Migration safe: DHT immutability respected; legacy entries remain valid indefinitely
- Ecosystem interoperability: Other hREA-based apps can interoperate with Nondominium's economic data directly through the shared hREA DNA
Document Version: 2.0 Last Updated: 2026-03-02 Status: Implementation Ready hREA Source: https://github.com/h-REA/hREA (branch: main-0.6, commit: fc3b5e78)
hREA Strategic Roadmap
Phases 1 and 2: Stabilization, VF 1.0 Alignment, and Interoperability
Status: Draft, March 2026 Repository: github.com/h-REA/hREA
This document proposes Phases 1 and 2 for an hREA maintainership transition. Phase 3 (ValueFlows DSL) and Phase 4 (ADAM integration) are mentioned briefly as potential future directions but are out of scope for this proposal.
Context
hREA is the Holochain implementation of the ValueFlows economic vocabulary, built on the REA (Resource-Event-Agent) accounting ontology. Its GraphQL API layer has been effectively abandoned, leaving the zome API as the de facto interface, but without adequate documentation, stabilization, or alignment with ValueFlows v1.0.
This document proposes a two-phase roadmap: foundational stabilization with full VF 1.0 alignment, followed by an interoperability layer that makes hREA a first-class citizen of the distributed ValueFlows ecosystem. Phase 2 presents an open question for community discussion: whether to revive the existing GraphQL API or adopt a JSON-LD approach.
Phase 1: Stabilization and ValueFlows v1.0 Alignment
Immediate priority
Goals
- Bring hREA's zome API into stable, documented shape
- Close all known gaps against the ValueFlows v1.0 ontology
- Enforce correctness at the DHT validation layer
- Make direct zome-to-zome and DNA-to-DNA calls a first-class integration pattern
Work Items
ValueFlows v1.0 gap closure
A full compliance audit against the VF 1.0 TTL ontology (https://w3id.org/valueflows/ont/vf#) identified hREA main-0.6 at approximately 65% compliance. The following gaps are to be closed in priority order:
- P0 (Critical): Add
vf:Claimentry type (coordinator + integrity zomes); addsettlesfield toReaEconomicEvent. Required for contribution accounting and invoicing workflows. - P0 (Critical): Add
effortQuantitytoReaEconomicEvent. Required for allworkanddeliverServiceaction events, the primary use case in Open Value Networks. - P1: Add
reciprocalRealizationOftoReaEconomicEvent;reciprocalClauseOftoReaCommitment. Required for bilateral exchange event recording. - P1: Add
mediumOfExchangeandsubstitutabletoReaResourceSpecification. Required for currency token and fungibility workflows. - P1: Add
purposetoReaProposal(offer/request distinction). Required for Requests and Offers filtering. - P2:
vf:SpatialThingas a proper entry type (replaceOption<String>location fields);vf:BatchLotRecord; missing Action effect dimensions (locationEffect,stageEffect,stateEffect,containedEffect,createResource,eventQuantity).
Status update, 2026-09-10. hREA happ-0.5.0-beta is about to land, built on PR #408 (feat/vf-proposal-purpose, still open) and Holochain 0.7. Verified by reading that branch's integrity zome source directly: both P0 items close (vf:Claim as rea_claim.rs with EconomicEvent.settles; effortQuantity on ReaEconomicEvent), and so do four of the five P1 items (reciprocalRealizationOf, reciprocalClauseOf, mediumOfExchange, substitutable, purpose). Of the P2 items, vf:SpatialThing is added as its own entry type, though EconomicResource.currentLocation has not yet been migrated from a plain string to reference it. vf:BatchLotRecord remains genuinely absent, tracked on the PR itself as a named follow-up once the old ProductBatch concept was removed. The Action effect dimensions gap also remains open: git grep for location_effect, stage_effect, state_effect, contained_effect, create_resource, event_quantity across the branch's integrity zomes returns nothing. Full field-by-field gap analysis, plus the two corrections found while re-checking it against this update: hREA VF 1.0 Compliance Analysis
Stub validation implementation
Every integrity zome validation function was a stub returning ValidateCallbackResult::Valid with a // TODO comment, on the main-0.6 state this roadmap was originally written against. This was the most consequential correctness gap: invalid entries could be written to the DHT by any non-compliant client. Phase 1 called for implementing, at minimum:
- Action input/output constraint on
EconomicEventcreation (usingget_builtin_action()) - Temporal consistency:
has_beginning < has_endwhere both are present - Quantity positivity check
provider/receiverpresence validation for transfer actions
Status update, 2026-09-10. PR #408 (feat/vf-proposal-purpose) implements this and more, verified by reading the branch: shared validators for temporal consistency, quantity non-negativity, required-string presence, VF builtin-action validity and field immutability, with create and update validation wired for EconomicEvent, Commitment, Intent, EconomicResource, Process, Proposal, Claim, Unit and SpatialThing. This has not yet been re-audited entry type by entry type against the full rule list this section originally called for; treat it as substantially addressed rather than exhaustively verified.
This serves both the VF community (spec compliance) and any existing hREA users in production, meaning external communities who cannot absorb silent data corruption during the transition.
Zome API documentation
With GraphQL retired as the primary interface, the zome call surface becomes the public API. It needs to be documented as such: function signatures, input/output types, capability grant requirements, and cross-zome call patterns. A concise reference guide targeting Holochain developers building on hREA.
Direct call promotion
Actively promote zome calls as the integration pattern for:
- Cross-zome calls within the same DNA (same-network composition)
- Cross-DNA bridge calls (composing hREA with other hApps)
- UI-direct calls via Holochain's conductor API
This removes the GraphQL indirection entirely for native Holochain consumers, reducing latency and eliminating a maintenance surface.
Test coverage and CI
Stabilization without tests is fragile. This phase introduces or restores comprehensive integration tests against the Holochain conductor and a robust CI pipeline.
Phase 2: Semantic Interoperability
An invitation to the community
The Question
Phase 1 establishes a clean, documented zome API for native Holochain consumers. Phase 2 asks a broader question: how should hREA present itself to the wider semantic web?
The ValueFlows vocabulary is grounded in RDF and W3C linked data standards. hREA implements that vocabulary on an agent-centric substrate. The opportunity in Phase 2 is to make that implementation legible to the outside world, whether that means other ValueFlows nodes, external applications, or federated social and economic networks. The right approach depends on where the ecosystem is heading and where effort is best spent. This section presents three directions and invites community discussion before any Phase 2 work begins.
Option A: Maintain and Improve the GraphQL API
The existing GraphQL layer already exists as a codebase surface, and parts of the ecosystem may depend on it. Reviving it would mean:
- Auditing and updating the schema to match the Phase 1 VF 1.0 additions
- Restoring CI coverage for the GraphQL layer
- Continuing to maintain a translation layer between Holochain's entry model and GraphQL types
Tradeoffs: familiar to existing integrators, compatible with tools that already target the hREA GraphQL schema. Carries ongoing maintenance overhead. Does not provide semantic interoperability with non-GraphQL ValueFlows nodes.
Option B: JSON-LD Serialization Layer
Retire GraphQL as the primary external interface and replace it with a JSON-LD serialization layer grounded in the official ValueFlows vocabulary.
Tradeoffs: aligns with W3C linked data standards, enables federation with non-Holochain VF implementations, supports SPARQL querying and Solid pod interop. Requires migrating existing integrators away from GraphQL. A larger upfront investment than reviving the existing API.
On the transport layer: the Holochain Foundation's hc-http-gw (and Holo's Web Bridge for hosted deployments) already provides a ready-made HTTP-to-zome bridge, eliminating the need to build a custom gateway process. The architecture then reduces to building the translation zome only. External clients send an HTTP request, the gateway dispatches it as a zome call, and the translation zome returns a well-formed JSON-LD document directly.
External client
↓ HTTP GET
hc-http-gw / Holo Web Bridge
↓ zome call
vf_jsonld translation zome ← the only custom component
↓ JSON-LD string
hc-http-gw (passes through)
↓ HTTP response
External client receives JSON-LD
The full architecture for the translation zome and compliance versioning mechanism is specified below as a concrete reference, should the community choose this direction.
Option C: ActivityPub Federation
The ValueFlows community outside Holochain is already building federation through ActivityPub. Bonfire (the Fediverse platform) supports ValueFlows as an ActivityPub extension, and active Fediverse Enhancement Proposals (FEPs) address federated marketplaces and work coordination using the ValueFlows vocabulary. ActivityPub serializes natively in JSON-LD.
This path does not require building a new gateway or serialization layer. It means implementing the ActivityPub protocol on top of hREA's data, joining an existing and growing federation network.
Tradeoffs: strong community momentum, JSON-LD native, interoperable with the entire Fediverse. Requires ActivityPub protocol implementation, a meaningful additional scope. hREA would need to speak both its native zome API and ActivityPub.
The options are not mutually exclusive. A combination (for example, Option B as a read layer and Option C as a federation layer) is worth discussing. The goal of Phase 2 is not to select an architecture in isolation but to align with where the ValueFlows and Holochain communities are heading together.
Option B Reference Architecture
This section specifies the JSON-LD approach in detail as a concrete proposal. It is presented for community review, not as a decided direction.
Translation Zome (the only custom component)
A vf_jsonld coordinator zome inside the hREA DNA. Core functions:
#![allow(unused)] fn main() { get_as_jsonld(hash: ActionHash) -> ExternResult<String> get_vf_context(_: ()) -> ExternResult<String> get_vf_compliance(_: ()) -> ExternResult<VfCompliance> }
The zome reads any entry by hash, applies the official VF @context, and returns a well-formed JSON-LD document. Agent-controlled, meaning no external party can alter how the agent's data is expressed. Every Phase 1 addition (new fields, new entry types) propagates to JSON-LD output automatically because the serialization logic lives in the same codebase as the structs.
VF Compliance Versioning
VF compliance is not a semantic version number, it is an enumerable field mapping. The compliance analysis proves this: every implemented and missing VF 1.0 property is known precisely. The versioning mechanism makes this machine-readable.
Three artifacts working together:
1. A VF_CONTEXT_URI constant in the DNA
#![allow(unused)] fn main() { // In coordinator/hrea/src/lib.rs pub const VF_CONTEXT_URI: &str = "https://hrea.io/contexts/hrea-0.6_vf-1.0.jsonld"; }
The URI encodes both the hREA version and the VF version targeted. When structs change (new DNA), the constant changes. When VF updates, the constant changes. Both the translation zome and the external gateway read this single constant and cannot diverge during version transitions.
2. A versioned context document published at that URI
Generated directly from the compliance analysis. null values are explicit about gaps, not silent:
{
"@context": {
"vf": "https://w3id.org/valueflows/ont/vf#",
"hrea_version": "0.6",
"vf_version": "1.0.0",
"compliance_level": "partial",
"EconomicEvent": "vf:EconomicEvent",
"action": "vf:action",
"effortQuantity": null,
"settles": null
}
}
3. A get_vf_compliance() coordinator function
Returns the full compliance profile at runtime: hREA version, VF version, compliance level, context URI, and the explicit list of missing fields. Any consuming system can inspect this before connecting.
When VF updates arrive: update the constant, publish a new context document at the new versioned URI. No consistency gap between the translation zome and the gateway.
URI Strategy
Holochain action hashes are content-addressed and globally unique, making them natural JSON-LD subject URIs:
hc://[dna-hash]/[action-hash]
Resolvable by any node with the DNA installed, preserving agent-centric semantics while providing the stable identity that JSON-LD requires.
What This Unlocks
- Cross-implementation federation: Holochain-based and non-Holochain ValueFlows nodes can exchange
EconomicEventrecords because they share JSON-LD context - SPARQL querying: Aggregate ValueFlows data across a network for reporting and analysis
- Application bridges: Any application can consume and produce hREA data via standard linked data patterns without custom protocol translation
- Solid interop: ValueFlows data expressed as Linked Data Notifications flows naturally into Solid pods
Potential Future Directions
Phases 1 and 2 constitute the full scope of this proposal. Two directions are on the horizon as potential future evolutions, each subject to separate community discussion: a ValueFlows DSL (a human-writable scripting language compiling to native zome calls and JSON-LD) and ADAM integration (registering hREA data as traversable Perspectives in an agent-centric graph layer, made natural by the JSON-LD foundation from Phase 2).
Governance and Community
Taking on hREA maintainership is not only a technical commitment. It is a position of stewardship in the ValueFlows and Holochain ecosystems. The following principles should guide this work:
Upstream coordination: Changes that affect ValueFlows compliance should be discussed with the ValueFlows specification maintainers and community before implementation. hREA is an implementation of a shared vocabulary, not a fork.
Open maintainership: The goal is not to control hREA but to revive it. Active solicitation of co-maintainers, clear contribution guides, and a public roadmap support a healthy transition. Struct changes in Phase 1 (adding vf:Claim, effortQuantity, location type migration) are breaking changes for existing hREA users. Clear migration guides and a deprecation window are part of the stabilization commitment, not an afterthought.
Reference implementations: Active use of hREA in production hApps provides the most concrete test of the zome API's real-world fitness. Feedback flows upstream: what breaks in practice gets fixed in hREA. The compliance analysis at valueflows-1.0-compliance.md is the living source of truth for Phase 1 gap closure and the generator of the Phase 2 context documents.
Multi-hApp composition: hApps building on hREA should benefit from these improvements. The interoperability work should be designed with multi-hApp composition in mind from the start.
Summary Timeline
| Phase | Focus | Scope |
|---|---|---|
| 1 | Stabilization + VF 1.0 gap closure + stub validation | This proposal |
| 2 | Semantic interoperability (GraphQL, JSON-LD, or ActivityPub: open community discussion) | This proposal |
| 3 | ValueFlows DSL | Future discussion |
| 4 | ADAM integration | Future discussion |
References
- ValueFlows specification
- VF 1.0 ontology
- hREA repository
- Nondominium
- AD4M / ADAM
- JSON-LD
- Holochain
- REA Ontology
- Holochain HTTP Gateway (hc-http-gw)
- Holo Web Bridge
- ActivityPub specification
- Bonfire: ValueFlows + ActivityPub
- Compliance analysis
hREA ValueFlows 1.0 Compliance Analysis
Branch: vendor/hrea — detached HEAD at fc3b5e78
VF Spec Version: 1.0.0 (CC-BY-SA 4.0)
VF Ontology source: https://w3id.org/valueflows/ont/vf#
Analysis date: 2026-03-25
Analysts: Soushi888, SoushAI
Table of Contents
- Executive Summary
- Methodology
- Overall Compliance Score
- Missing Entity Types
- Field-Level Gaps by Entity
- Action Model Gaps
- Validation Gaps
- Naming and Structural Observations
- Recommendations
- Appendix: Full Field Mapping Tables
Executive Summary
hREA main-0.6 implements the structural core of the ValueFlows 1.0 ontology competently: the foundational economic flow cycle (Agent, EconomicResource, EconomicEvent, Process) is present and linked correctly. The planning layer (Intent, Commitment, Plan, Proposal) and the knowledge layer (ResourceSpecification, ProcessSpecification, Recipe*) are scaffolded with correct relational structure.
However, five VF 1.0 entity classes are entirely absent, the Action model covers only 4 of 10 effect dimensions, all entry validation functions are stubs with no business rule enforcement, and several field-level gaps break round-trip interoperability with other VF-compliant systems (e.g., Bonfire).
Overall estimated compliance: ~65%
The most consequential gap for immediate interoperability is the absence of vf:Claim and the missing effortQuantity on EconomicEvent. The most consequential gap for long-term correctness is the wholesale absence of validation logic.
Update: hREA v0.5.0-beta (2026-09-10)
hREA happ-0.5.0-beta is about to land, built on Holochain 0.7 (hdk 0.7.0 / hdi 0.8.0) and on the VF 1.0 work staged in PR #408 (h-REA/hREA, branch feat/vf-proposal-purpose, still open as of this writing). Verified locally: the zomes build clean, Sweettest is 10/10 and the GraphQL acceptance battery is 65/65 against a live 0.7 conductor with @holochain/client 0.21.
This closes most of the P0 and P1 gaps this analysis found, confirmed by reading feat/vf-proposal-purpose's integrity zome source directly.
Closed: vf:Claim (P0-1, dnas/hrea/zomes/integrity/hrea/src/rea_claim.rs) with settles: Option<ActionHash> added to ReaEconomicEvent; effortQuantity on ReaEconomicEvent (P0-2); reciprocalRealizationOf on ReaEconomicEvent (P1-1); reciprocalClauseOf on ReaCommitment (P1-2); mediumOfExchange and substitutable on ReaResourceSpecification (P1-3); purpose on ReaProposal, validated against {"offer", "request"} and made immutable on update (P1-5); vf:SpatialThing as rea_spatial_thing.rs (P2-1, see the caveat below); vf:AgreementBundle as rea_agreement_bundle.rs (P2-5). Every stub integrity validation this analysis flagged in the Validation Gaps section below is also replaced with real, DHT-wide checks on this branch: temporal consistency, quantity non-negativity, required-field presence, and VF builtin-action validity, wired for create and update on EconomicEvent, Commitment, Intent, EconomicResource, Process, Proposal, Claim, Unit and SpatialThing (P1-4, substantially addressed; not re-audited rule by rule here).
Caveat on SpatialThing: the entry type exists, but EconomicResource.currentLocation has not been migrated from Option<String> to reference it; that field-level wiring is an open follow-up on the PR itself.
Still open, checked directly against feat/vf-proposal-purpose and found absent: vf:BatchLotRecord (P2-2, the PR removes the old ProductBatch concept and tracks BatchLotRecord as a named, not-yet-implemented follow-up) and vf:ProposalList with listedIn (Missing Entity Type 5, below). The Action effect dimensions (P2-3: locationEffect, stageEffect, stateEffect, containedEffect, createResource, eventQuantity) also remain absent; git grep for each of those field names across the branch's integrity zomes returns nothing. RecipeProcess.hasDuration/.processClassifiedAs (P2-4) and Agent.primaryLocation (P2-6) were checked the same way and are also still absent.
Two corrections to this analysis, found while checking it against @valueflows/vf-graphql 0.9.1-alpha.6's own schema files, unrelated to the v0.5.0-beta timing: the vf:Agreement section below invents properties that VF 1.0 does not have (see the note there), and the ProposedIntent remark under Naming and Structural Observations has the compliance direction backwards (see the note there).
The module interface question (a separate axis from VF compliance, tracked in the strategic roadmap and the v0.2 release plan) is untouched by any of this. The ~65% overall score and the per-domain breakdown above predate this update and have not been recalculated; that recalculation should wait until happ-0.5.0-beta is tagged and the pieces above are confirmed against a released build rather than an open PR branch.
Methodology
Analysis performed by:
-
Reading the VF 1.0 TTL ontology via the HTML rendering at
http://ontprox.dev.opensourceecology.de/?uri=https://codeberg.org/valueflows/pages/raw/branch/main/assets/all_vf.TTLextracting all class definitions, properties, ranges, and named individuals. -
Reading every Rust integrity zome struct in
vendor/hrea/dnas/hrea/zomes/integrity/hrea/src/cataloguing all fields and their types. -
Reading the coordinator zome public function signatures in
vendor/hrea/dnas/hrea/zomes/coordinator/hrea/src/ -
Reading the action builtins in
vendor/hrea/dnas/hrea/zomes/coordinator/hrea/vf_actions/src/builtins.rs -
Cross-referencing hREA struct fields against VF 1.0 property names and ranges.
No compilation or runtime testing was performed. All findings are structural (type-level) only.
Overall Compliance Score
| Domain | Score | Notes |
|---|---|---|
| Core entity presence | 15/20 | 5 entities absent |
| Field coverage (present entities) | ~75% | See per-entity tables below |
| Action model | 4/10 effects | Missing 6 effect dimensions |
| Validation / business rules | 0% | All stubs |
| Overall | ~65% |
Missing Entity Types
These VF 1.0 classes have no corresponding entry type in hREA main-0.6.
1. vf:Claim (P0 — Critical)
VF 1.0 definition: "A claim for future economic event(s) in reciprocity for events already occurred."
Key properties:
vf:triggeredBy(EconomicEvent) — the event that triggers the claimvf:settleson EconomicEvent — the event that settles an open claim
Impact on hREA: ReaEconomicEvent has no settles field. Any VF workflow using claim-based reciprocity (invoicing, contribution tracking in OVNs) cannot be expressed. This breaks Nondominium's planned contribution accounting workflow.
Implementation path: Add ReaClaim integrity entry type; add settles: Option<Vec<ActionHash>> to ReaEconomicEvent.
Status (2026-09-10): closed in hREA v0.5.0-beta. See the Update section above.
2. vf:SpatialThing (P1)
VF 1.0 definition: "Data locating something relative to Earth, usually fixed location."
Key properties: latitude, longitude, altitude, mappableAddress, hasDetailedGeometry
Current hREA state: All location fields across all entry types (ReaEconomicEvent.at_location, ReaEconomicResource.current_location, ReaProcess implied) are Option<String>. This is a plain text field, not a structured location object.
Impact: Interoperability with location-aware VF clients or Bonfire's SpatialThing support is broken. Cross-system queries on location cannot be typed.
Implementation path: Add ReaSpatialThing entry type. Replace *_location: Option<String> fields with *_location: Option<ActionHash> referencing a ReaSpatialThing.
Status (2026-09-10): the entry type closes in hREA v0.5.0-beta (rea_spatial_thing.rs). EconomicResource.current_location has not been migrated from Option<String> to reference it; that field-level wiring is still open on the PR itself.
3. vf:BatchLotRecord (P2)
VF 1.0 definition: "Document containing detail related to production of particular batch or lot."
Key properties: batchLotCode (string), expirationDate (dateTimeStamp)
Current hREA state: ReaEconomicResource.lot: Option<String> — stores just a code string. Expiration date is not present.
Impact: Perishable goods tracking, pharmaceutical lot tracking, and any time-bounded batch workflow cannot express lot expiration.
Implementation path: Add ReaBatchLotRecord entry type. Change lot: Option<String> to of_batch_lot: Option<ActionHash> on ReaEconomicResource.
Status (2026-09-10): still genuinely absent. hREA v0.5.0-beta removes the old ProductBatch concept and tracks BatchLotRecord as its own named follow-up, not yet implemented.
4. vf:AgreementBundle (P2)
VF 1.0 definition: "Grouping of agreements for bundled line item reciprocity."
Current hREA state: No equivalent. ReaAgreement has no bundledIn field.
Impact: Multi-party trade agreements with line items cannot be grouped. Nondominium's multi-resource governance commitments may require this.
Implementation path: Add ReaAgreementBundle entry type; add bundled_in: Option<ActionHash> to ReaAgreement.
Status (2026-09-10): the entry type closes in hREA v0.5.0-beta (rea_agreement_bundle.rs). Whether bundled_in was also added to ReaAgreement itself was not checked.
5. vf:ProposalList (P2)
VF 1.0 definition: "Grouping of proposals for publishing."
Current hREA state: No equivalent. ReaProposal has no listed_in field.
Status (2026-09-10): still genuinely absent. Checked directly against feat/vf-proposal-purpose: no mention of ProposalList or listed_in anywhere in that branch's dnas/hrea tree.
Impact: Marketplace-style proposal catalogues (e.g., hAppenings Requests & Offers grouped by category) cannot be expressed at the VF ontology level.
Implementation path: Add ReaProposalList entry type; add listed_in: Option<ActionHash> to ReaProposal.
Field-Level Gaps by Entity
vf:EconomicEvent / ReaEconomicEvent
| VF 1.0 Property | hREA Field | Status | Notes |
|---|---|---|---|
vf:action | rea_action: String | PRESENT | Naming differs (rea_ prefix) |
vf:provider | provider: Option<ActionHash> | PRESENT | |
vf:receiver | receiver: Option<ActionHash> | PRESENT | |
vf:resourceInventoriedAs | resource_inventoried_as: Option<ActionHash> | PRESENT | |
vf:toResourceInventoriedAs | to_resource_inventoried_as: Option<ActionHash> | PRESENT | |
vf:resourceQuantity | resource_quantity: Option<QuantityValue> | PRESENT | |
vf:effortQuantity | (absent) | MISSING | P0 — needed for work/service events |
vf:hasBeginning | has_beginning: Option<Timestamp> | PRESENT | |
vf:hasEnd | has_end: Option<Timestamp> | PRESENT | |
vf:hasPointInTime | has_point_in_time: Option<Timestamp> | PRESENT | |
vf:toLocation | at_location: Option<String> | PARTIAL | String only, not SpatialThing |
vf:fulfills | fulfills: Option<Vec<ActionHash>> | PRESENT | |
vf:satisfies | satisfies: Option<Vec<ActionHash>> | PRESENT | |
vf:realizationOf | realization_of: Option<ActionHash> | PRESENT | |
vf:reciprocalRealizationOf | (absent) | MISSING | Needed for bilateral exchange events |
vf:corrects | corrects: Option<ActionHash> | PRESENT | |
vf:settles | (absent) | MISSING | Blocked by missing Claim entity |
vf:triggeredBy | triggered_by: Option<ActionHash> | PRESENT | Causal event chain |
vf:inScopeOf | in_scope_of: Option<Vec<ActionHash>> | PRESENT | |
vf:inputOf | input_of: Option<ActionHash> | PRESENT | |
vf:outputOf | output_of: Option<ActionHash> | PRESENT |
Gaps: effortQuantity (P0), reciprocalRealizationOf (P1), settles (blocked by Claim).
Extra hREA field: agreed_in: Option<String> — not in VF 1.0 ontology.
vf:EconomicResource / ReaEconomicResource
| VF 1.0 Property | hREA Field | Status | Notes |
|---|---|---|---|
vf:conformsTo | conforms_to: Option<ActionHash> | PRESENT | |
vf:trackingIdentifier | tracking_identifier: Option<String> | PRESENT | |
vf:accountingQuantity | accounting_quantity: Option<QuantityValue> | PRESENT | |
vf:onhandQuantity | onhand_quantity: Option<QuantityValue> | PRESENT | |
vf:currentLocation | current_location: Option<String> | PARTIAL | String, not SpatialThing |
vf:currentVirtualLocation | (absent) | MISSING | URI field for digital resources |
vf:currentCurrencyLocation | (absent) | MISSING | String field for financial assets |
vf:primaryAccountable | primary_accountable: Option<ActionHash> | PRESENT | |
vf:containedIn | contained_in: Option<ActionHash> | PRESENT | |
vf:ofBatchLot | lot: Option<String> | PARTIAL | Stored as string; BatchLotRecord absent |
vf:unitOfEffort | unit_of_effort: Option<ActionHash> | PRESENT | |
vf:resourceClassifiedAs | resource_classified_as (via conforms_to) | PARTIAL | |
vf:stage | stage: Option<ActionHash> | PRESENT | |
vf:state | state: Option<String> | PRESENT |
Extra hREA fields: name, image, note — supplementary, not in VF core ontology.
vf:Commitment / ReaCommitment
| VF 1.0 Property | hREA Field | Status | Notes |
|---|---|---|---|
vf:action | rea_action: Option<String> | PRESENT | Note: optional in hREA, implied required in VF |
vf:provider | provider: Option<ActionHash> | PRESENT | |
vf:receiver | receiver: Option<ActionHash> | PRESENT | |
vf:resourceInventoriedAs | resource_inventoried_as: Option<ActionHash> | PRESENT | |
vf:resourceQuantity | resource_quantity: Option<QuantityValue> | PRESENT | |
vf:effortQuantity | effort_quantity: Option<QuantityValue> | PRESENT | |
vf:hasBeginning | has_beginning: Option<Timestamp> | PRESENT | |
vf:hasEnd | has_end: Option<Timestamp> | PRESENT | |
vf:due | due: Option<Timestamp> | PRESENT | |
vf:clauseOf | clause_of: Option<ActionHash> | PRESENT | |
vf:reciprocalClauseOf | (absent) | MISSING | Needed for bilateral agreement commitments |
vf:independentDemandOf | independent_demand_of: Option<ActionHash> | PRESENT | |
vf:satisfies | satisfies: Option<ActionHash> | PRESENT | |
vf:finished | finished: Option<bool> | PRESENT | |
vf:inScopeOf | in_scope_of: Option<Vec<ActionHash>> | PRESENT |
Gap: reciprocalClauseOf (P1).
vf:Agent / ReaAgent
| VF 1.0 Property | hREA Field | Status | Notes |
|---|---|---|---|
vf:primaryLocation | (absent) | MISSING | Location of the agent |
| Subclasses: Person, Organization, EcologicalAgent | agent_type: String | PARTIAL | Flat string instead of proper subclassing |
Extra hREA fields: name (required), image, classified_as, note.
Structural observation: VF 1.0 defines Agent as an abstract class with three concrete subclasses. hREA uses a single ReaAgent with agent_type: String (e.g., "Person", "Organization"). This is pragmatic for Holochain (avoids three entry types with near-identical structure), but breaks strict ontology alignment. A VF-compliant GraphQL layer must map these correctly.
vf:ResourceSpecification / ReaResourceSpecification
| VF 1.0 Property | hREA Field | Status | Notes |
|---|---|---|---|
vf:defaultUnitOfResource | default_unit_of_resource: Option<ActionHash> | PRESENT | |
vf:defaultUnitOfEffort | default_unit_of_effort: Option<ActionHash> | PRESENT | |
vf:mediumOfExchange | (absent) | MISSING | Boolean — is this resource a currency? |
vf:substitutable | (absent) | MISSING | Boolean — fungible with same spec? |
Impact: Currency tokens and fungibility cannot be expressed. Nondominium's Unyt integration (§6.6 in NDO spec) depends on mediumOfExchange.
vf:Intent / ReaIntent
| VF 1.0 Property | hREA Field | Status | Notes |
|---|---|---|---|
vf:action | rea_action: String | PRESENT | |
vf:provider | provider: Option<ActionHash> | PRESENT | |
vf:receiver | receiver: Option<ActionHash> | PRESENT | |
vf:resourceQuantity | resource_quantity: Option<QuantityValue> | PRESENT | |
vf:effortQuantity | effort_quantity: Option<QuantityValue> | PRESENT | |
vf:availableQuantity | available_quantity: Option<QuantityValue> | PRESENT | |
vf:minimumQuantity | minimum_quantity: Option<QuantityValue> | PRESENT | |
vf:hasBeginning | has_beginning: Option<Timestamp> | PRESENT | |
vf:hasEnd | has_end: Option<Timestamp> | PRESENT | |
vf:due | due: Option<Timestamp> | PRESENT | |
vf:finished | finished: Option<bool> | PRESENT |
Intent is one of the more complete implementations. Extra hREA fields: image, agreed_in, in_scope_of.
vf:Proposal / ReaProposal
| VF 1.0 Property | hREA Field | Status | Notes |
|---|---|---|---|
vf:publishes | publishes: Option<Vec<ActionHash>> | PRESENT | |
vf:reciprocal | reciprocal: Option<Vec<ActionHash>> | PRESENT | |
vf:unitBased | unit_based: Option<bool> | PRESENT | |
vf:proposedTo | proposed_to: Option<Vec<ActionHash>> | PRESENT | |
vf:purpose | (absent) | MISSING | ProposalPurpose enum (offer/request) |
vf:eligibleLocation | (absent) | MISSING | SpatialThing — geographic eligibility |
vf:listedIn | (absent) | MISSING | ProposalList reference |
Extra hREA fields: name, has_beginning, has_end, created, note.
vf:Agreement / ReaAgreement
Correction (2026-09-10): the table below invented three properties, vf:stipulates, vf:stipulatesReciprocal and vf:realizesReciprocal, that do not exist in VF 1.0. Checked directly against @valueflows/vf-graphql 0.9.1-alpha.6's schemas/agreement.gql and its schemas/bridging/*.agreement.gql files: VF 1.0's Agreement is {id, revisionId, name, created, note}, with commitments (the inverse of Commitment.clauseOf) and economicEvents/unplannedEconomicEvents (the inverse of EconomicEvent.realizationOf) added by the bridging modules. grep -rn "stipulates\|realizes\b" across the whole @valueflows/vf-graphql schema tree returns nothing. There is no party-bound stipulation or realization pair, bilateral or otherwise, anywhere in the current ontology. The claim that ReaAgreement is "severely under-specified" was wrong: its name/created/note fields match VF 1.0's Agreement field-for-field.
| VF 1.0 property (corrected) | hREA field | Status | Notes |
|---|---|---|---|
clauseOf (on Commitment) | clause_of: Option<ActionHash> on ReaCommitment | PRESENT | Correct VF 1.0 name; the original table's vf:stipulates is not a real VF 1.0 property |
realizationOf (on EconomicEvent) | realization_of: Option<ActionHash> on ReaEconomicEvent | PRESENT | Correct VF 1.0 name; the original table's vf:realizes is not a real VF 1.0 property |
| (no VF 1.0 equivalent) | n/a | N/A | vf:stipulatesReciprocal is not a VF 1.0 property; bilateral reciprocity is Commitment.reciprocalClauseOf (Commitment table above), not an Agreement-side field |
| (no VF 1.0 equivalent) | n/a | N/A | vf:realizesReciprocal is not a VF 1.0 property; there is no reciprocal counterpart to realizationOf on Agreement |
vf:bundledIn | (absent on main-0.6) | MISSING, closed in hREA v0.5.0-beta | rea_agreement_bundle.rs on feat/vf-proposal-purpose adds ReaAgreementBundle; whether bundled_in was also added to ReaAgreement itself was not checked |
Bilateral exchange (the "I commit to X in exchange for Y" pattern OVN contexts need) is expressed through Commitment.reciprocalClauseOf, not through a bilateral Agreement. That field closes in hREA v0.5.0-beta (P1-2, see the Update section above).
vf:Plan / ReaPlan
| VF 1.0 Property | hREA Field | Status | Notes |
|---|---|---|---|
vf:planIncludes (Process) | (via links) | PRESENT | ReaPlanToReaProcesses link |
vf:planIncludes (Commitment) | (via links) | PRESENT | ReaPlanToReaCommitments link |
vf:hasIndependentDemand | independent_demand_of (inverse) | PRESENT | Expressed on Commitment side |
Plan is relatively well-implemented. Extra hREA fields: name, due, note, in_scope_of, created.
vf:Process / ReaProcess
| VF 1.0 Property | hREA Field | Status | Notes |
|---|---|---|---|
vf:basedOn | based_on: Option<ActionHash> | PRESENT | |
vf:hasInput | (via links) | PRESENT | ReaProcessToReaEconomicEventInputs |
vf:hasOutput | (via links) | PRESENT | ReaProcessToReaEconomicEventOutputs |
vf:inScopeOf | in_scope_of: Option<Vec<ActionHash>> | PRESENT | |
vf:hasBeginning | has_beginning: Option<Timestamp> | PRESENT | |
vf:hasEnd | has_end: Option<Timestamp> | PRESENT | |
vf:finished | finished: Option<bool> | PRESENT |
Process is well-implemented. Extra hREA fields: before, after, classified_as, planned_within, note.
vf:RecipeProcess / ReaRecipeProcess
| VF 1.0 Property | hREA Field | Status | Notes |
|---|---|---|---|
vf:hasRecipeInput | (via links) | PRESENT | |
vf:hasRecipeOutput | (via links) | PRESENT | |
vf:hasDuration | (absent) | MISSING | Measure — planned process duration |
vf:processConformsTo | process_conforms_to: Option<ActionHash> | PRESENT | |
vf:processClassifiedAs | (absent) | MISSING | Classification URI |
vf:Unit / ReaUnit
| VF 1.0 Property | hREA Field | Status | Notes |
|---|---|---|---|
vf:symbol | symbol: String | PRESENT | |
vf:omUnitIdentifier | om_unit_identifier: String | PRESENT |
Extra hREA field: label (human-readable name) — not in VF core but harmless.
Action Model Gaps
VF 1.0 defines the vf:Action class with 10 effect properties. hREA implements 4.
| VF 1.0 Effect Property | hREA Field | Status | Meaning |
|---|---|---|---|
vf:accountingEffect | accounting_effect (ActionEffect enum) | PRESENT | Change to rights/accounting |
vf:onhandEffect | onhand_effect (ActionEffect enum) | PRESENT | Change to physical custody |
vf:inputOutput | input_output (ProcessType enum) | PRESENT | Input / Output / NotApplicable |
vf:pairsWith | pairs_with: String | PRESENT | Reciprocal action ID |
vf:accountableEffect | (absent) | MISSING | Change to accountability |
vf:locationEffect | (absent) | MISSING | Change to current location |
vf:stageEffect | (absent) | MISSING | Change to stage/specification |
vf:stateEffect | (absent) | MISSING | Change to state string |
vf:containedEffect | (absent) | MISSING | Change to containedIn |
vf:createResource | (absent) | MISSING | Whether this action creates a new resource |
vf:eventQuantity | (absent) | MISSING | What quantity field(s) are used |
Impact: The missing action effects mean that rule-based resource mutation (auto-updating location, stage, state, containment when an event is recorded) cannot be derived from the action definition alone. Systems consuming hREA must hardcode these rules outside the action model.
This is particularly impactful for transfer_custody (no locationEffect to auto-update current_location) and modify/accept (no stageEffect or stateEffect).
Validation Gaps
Every integrity zome validation function in vendor/hrea that should enforce VF business rules is a stub:
#![allow(unused)] fn main() { // TODO: add the appropriate validation rules Ok(ValidateCallbackResult::Valid) }
This affects all entry types for create, update, and delete operations.
Specific rules that are absent at the DHT validation level:
| Rule | VF Requirement | Current State |
|---|---|---|
| Action input/output constraint | produce must have output_of; consume must have input_of | Unenforced |
| Temporal consistency | has_beginning must be before has_end | Unenforced |
| Quantity sign | Quantities must be positive | Unenforced |
| Inventory effect on event | Creating a produce event should increment resource quantity | Not auto-applied |
| Transfer agent consistency | transfer requires both provider and receiver | Unenforced |
| Commitment satisfaction | A satisfied commitment must reference a real intent | Unenforced |
| Claim settlement | A settled claim must match the original triggering event | Unenforced (Claim absent) |
| Action validity | rea_action string must reference a known action | Unenforced at integrity level |
Architectural note: Holochain's validation layer (integrity zome) is the correct place for these rules because validation runs deterministically on every peer. Leaving these as stubs means: (a) corrupted state can be written to the DHT by non-compliant clients, and (b) hREA cannot claim DHT-level VF correctness guarantees.
Naming and Structural Observations
These are not gaps but noteworthy observations for maintainers.
rea_ prefix vs vf: namespace. All hREA types use a ReaX / rea_x naming convention. This is internal to the Holochain zome layer and is correctly abstracted away by the GraphQL module. The GraphQL types should map to VF names (EconomicEvent, not ReaEconomicEvent). Verify this mapping is complete in modules/vf-graphql-holochain/.
agreed_in: Option<String> on EconomicEvent and Commitment. This field does not appear in the VF 1.0 ontology. It appears to be a legacy field or a custom extension. Its semantics overlap with realization_of (Agreement). Clarify intent and either map it to a proper VF property or document it as an hREA extension.
Correction (2026-09-10): this had the compliance direction backwards. ProposedIntent was removed from ValueFlows in the VF 1.0 refactor, along with Fulfillment and Satisfaction (@valueflows/vf-graphql CHANGELOG, entry 0.9.1-alpha.0: "Removed proposedIntent", "Removed satisfaction", "Removed fulfillment"). VF 1.0's Proposal carries publishes: [Intent!]! and reciprocal: [Intent!]! as direct fields (schemas/proposal.gql), exactly what ReaProposal implements as publishes: Option<Vec<ActionHash>> and reciprocal: Option<Vec<ActionHash>>. hREA's direct-field approach is the VF 1.0 compliant one, not a divergence from it. There is no ProposedIntent entity to be missing.
RecipeExchange vs Recipe. VF 1.0 defines a vf:Recipe class (with recipeIncludes and primaryOutput) distinct from vf:RecipeExchange. hREA's ReaRecipeExchange maps to VF's RecipeExchange but there is no equivalent of VF's Recipe wrapper class in hREA. If recipes need a primary output specification, this wrapper is needed.
Recommendations
Status (2026-09-10): P0-1, P0-2, P1-1, P1-2, P1-3, P1-5, P2-1 and P2-5 close in hREA v0.5.0-beta; P1-4 is substantially addressed. P2-2, P2-3, P2-4 and P2-6 remain open, confirmed still absent by reading feat/vf-proposal-purpose directly. Detail and citations: the Update section near the top of this document.
P0 — Critical (breaks core VF workflows)
P0-1: Add vf:Claim entry type
- Create
integrity/hrea/src/rea_claim.rswithtriggeredBy: ActionHash(required) and standard CRUD - Add
settles: Option<Vec<ActionHash>>toReaEconomicEvent - Add coordinator functions:
create_rea_claim,get_latest_rea_claim,get_claims_triggered_by_event - Required for: contribution accounting in Nondominium, invoicing workflows in hAppenings
P0-2: Add effortQuantity to ReaEconomicEvent
- Add
effort_quantity: Option<QuantityValue>to theReaEconomicEventstruct - Required for: all
workanddeliverServiceaction events, which are the primary use case in OVN contribution tracking
P1 — Important (breaks interoperability with other VF systems)
P1-1: Add reciprocalRealizationOf to ReaEconomicEvent
- Add
reciprocal_realization_of: Option<ActionHash>referencing aReaAgreement - Required for: bilateral exchange event recording (standard trade)
P1-2: Add reciprocalClauseOf to ReaCommitment
- Add
reciprocal_clause_of: Option<ActionHash>referencing aReaAgreement - Required for: bilateral agreement clauses (the "I commit to X in exchange for Y" pattern)
P1-3: Add mediumOfExchange and substitutable to ReaResourceSpecification
- Add
medium_of_exchange: Option<bool>andsubstitutable: Option<bool> - Required for: Nondominium Unyt integration (§6.6 NDO spec) and hAppenings fungible offer matching
P1-4: Implement core validation rules in integrity zome
- At minimum: action input/output constraint validation on
ReaEconomicEventcreation - Temporal constraint:
has_beginning < has_endwhere both present - The
validate_create_rea_economic_eventalready validates foreign keys — extend it with action-based process link validation usingget_builtin_action()
P1-5: Add purpose to ReaProposal
- Add
purpose: Option<String>(using a string enum:"offer"/"request") or a properProposalPurposeentry type - Required for: hAppenings Requests & Offers UI distinction between offers and requests
P2 — Significant (completes the ontology)
P2-1: Add vf:SpatialThing entry type and replace string location fields
- Create
ReaSpatialThingwithmappable_address,lat,lon,altfields - Replace
at_location: Option<String>withat_location: Option<ActionHash>everywhere - This is a breaking change — requires migration logic or a versioned approach
P2-2: Add vf:BatchLotRecord entry type
- Create
ReaBatchLotRecordwithbatch_lot_code: String,expiration_date: Option<Timestamp> - Replace
lot: Option<String>onReaEconomicResourcewithof_batch_lot: Option<ActionHash>
P2-3: Add missing Action effect fields
- Add
location_effect,stage_effect,state_effect,contained_effect,create_resource,event_quantityto theActionstruct - Update
builtins.rswith values from VF 1.0 spec for each action - This enables rule-based resource mutation derivation from action definitions
P2-4: Add hasDuration and processClassifiedAs to ReaRecipeProcess
- Add
has_duration: Option<QuantityValue>(time measure) andprocess_classified_as: Option<Vec<String>>
P2-5: Add vf:AgreementBundle and expand ReaAgreement
- Create
ReaAgreementBundleentry type - Add
bundled_in: Option<ActionHash>toReaAgreement
P2-6: Add primaryLocation to ReaAgent
- Add
primary_location: Option<ActionHash>(orOption<String>if SpatialThing not yet implemented)
P3 — Future (Nondominium-specific extensions beyond VF 1.0)
P3-1: vf:Source — Third flow endpoint primitive (Source-NDO)
ValueFlows 1.0 permits only vf:Agent and vf:EconomicResource as provider and receiver in economic events. The Source-NDO extension (source-ndo-requirements.md) requires a third typed role: vf:Source.
A vf:Source endpoint represents a generative ecological system (watershed, river, fishery, forest) that:
- yields economic resources when accessed (extraction events)
- receives ecological effects (loading/pollution events)
- conditions future events through a changing
SourceRegimeState - is not ownable and not agentive (neither
vf:Agentnorvf:EconomicResourcefits)
Proposed implementation:
vf:Source rdfs:subClassOf owl:Thing
rdfs:comment "A generative ecological system that yields resources,
receives ecological effects, and conditions future
possibilities without being ownable or intentional."
vf:EconomicEvent vf:fromSource vf:Source (extraction: Source as provider)
vf:EconomicEvent vf:toSource vf:Source (loading: Source as receiver)
Impact: Without this extension, Nondominium cannot express watershed governance, fishery commons, or any ecological commons under the Nondominium property regime without ontological fictions (false primaryAccountable, phantom raise events). This is a Nondominium-proposed extension to ValueFlows 1.0, not yet submitted to the VF working group.
Priority: Required for Source-NDO implementation (post-MVP). Does not affect hREA 1.0 compliance score; should be tracked as a future contribution to the VF standard.
Appendix: Full Field Mapping Tables
Actions — 18 built-in actions present
| Action ID | Accounting Effect | Onhand Effect | I/O | Pairs With |
|---|---|---|---|---|
| dropoff | Decrement | Decrement | Output | pickup |
| pickup | Increment | Increment | Input | dropoff |
| consume | Decrement | Decrement | Input | notApplicable |
| use | NoEffect | NoEffect | Input | notApplicable |
| work | NoEffect | NoEffect | Input | notApplicable |
| cite | NoEffect | NoEffect | Input | notApplicable |
| produce | Increment | Increment | Output | notApplicable |
| accept | NoEffect | Decrement | Input | modify |
| modify | NoEffect | Increment | Output | accept |
| pass | NoEffect | NoEffect | Output | accept |
| fail | NoEffect | NoEffect | Output | accept |
| deliver-service | NoEffect | NoEffect | Output | notApplicable |
| transfer-all-rights | DecrementIncrement | NoEffect | NotApplicable | notApplicable |
| transfer-custody | NoEffect | DecrementIncrement | NotApplicable | notApplicable |
| transfer | DecrementIncrement | DecrementIncrement | NotApplicable | notApplicable |
| move | DecrementIncrement | DecrementIncrement | NotApplicable | notApplicable |
| raise | Increment | Increment | NotApplicable | notApplicable |
| lower | Decrement | Decrement | NotApplicable | notApplicable |
All 18 VF 1.0 built-in actions are present. Action effect dimensions are missing (see Action Model Gaps above).
Entry Types — Presence Summary
| VF 1.0 Class | hREA Entry Type | Present |
|---|---|---|
| vf:Agent | ReaAgent | YES |
| vf:EconomicResource | ReaEconomicResource | YES |
| vf:EconomicEvent | ReaEconomicEvent | YES |
| vf:Process | ReaProcess | YES |
| vf:Commitment | ReaCommitment | YES |
| vf:Intent | ReaIntent | YES |
| vf:Agreement | ReaAgreement | YES |
| vf:Plan | ReaPlan | YES |
| vf:Proposal | ReaProposal | YES |
| vf:ResourceSpecification | ReaResourceSpecification | YES |
| vf:ProcessSpecification | ReaProcessSpecification | YES |
| vf:RecipeFlow | ReaRecipeFlow | YES |
| vf:RecipeProcess | ReaRecipeProcess | YES |
| vf:RecipeExchange | ReaRecipeExchange | YES |
| vf:Unit | ReaUnit | YES |
| vf:Claim | (absent) | NO |
| vf:SpatialThing | (absent) | NO |
| vf:BatchLotRecord | (absent) | NO |
| vf:AgreementBundle | (absent) | NO |
| vf:ProposalList | (absent) | NO |
Link Types — 30 relationship links defined
hREA defines 56 link types in the integrity zome covering: update chains (immutable), discovery anchors (AllX), process I/O links, agent-to-flow links, planning links (agreement/plan/commitment), satisfaction/fulfillment links, and recipe structure links. These are implementation-level constructs; VF 1.0 expresses these as object properties on the classes. No significant link-level gaps were identified beyond those caused by missing entry types.
Nondominium v0.2: hREA as the Economic Substrate
Type: Release Plan Created: 2026-08-21 Status: Draft, not yet a GitHub milestone Relates to: Integration Strategy, Strategic Roadmap, ValueFlows 1.0 Compliance, NDO Prima Materia
1. Thesis
v0.1.0 ships the peer mesh: Lobby, per-group Group DHTs, per-NDO Layer 0 cells. Its economic vocabulary is Nondominium's own, defined in zome_resource and zome_gouvernance.
v0.2 replaces that vocabulary with hREA's wherever ValueFlows already has the concept, and expresses everything else through hREA's module interface rather than through parallel entry types. The outcome we want is one economic substrate, not two that need reconciling.
This depends on work that does not exist yet: hREA has no module interface. Building it is the hREA-side prerequisite, planned as hREA v0.2 and proposed in the issue drafted alongside this document. Nondominium v0.2 cannot start until that lands.
2. Where the integration stands today
Verified against the working tree on 2026-08-21.
| Fact | Evidence |
|---|---|
| hREA is already a provisioned role in the bundle | workdir/happ.yaml, role hrea, DNA at vendor/hrea/dnas/hrea/workdir/hrea.dna |
| hREA is pinned as a submodule on the Sensorica fork | .gitmodules, vendor/hrea, branch main-0.6 |
| Phase 1 (agent bridge) is implemented | dnas/nondominium/zomes/coordinator/zome_person/src/hrea_bridge.rs, 39 lines: create_rea_agent_bridge, get_hrea_agents |
| The bridge is exercised by tests | person_create_populates_hrea_agent_hash in the Sweettest suite |
| Both sides run the same Holochain | HDI 0.7.0 / HDK 0.6.0 in vendor/hrea/Cargo.toml and in Nondominium |
| Upstream is mid-flight on VF 1.0 | h-REA/hREA PR #408, open, feat/vf-proposal-purpose into main-0.6, +5070/-834 across 74 files: VF 1.0 surface, Holochain 0.6.1, integrity validation hardening |
The bridge deliberately mirrors ReaAgent locally rather than taking a Cargo dependency on the hREA workspace. That choice is worth revisiting in v0.2: a shared types crate is the alternative, and the module interface may make it unnecessary.
3. Preconditions
v0.2 does not begin until all four hold.
- v0.1.0 is released. Milestone
v0.1.0 peer-meshclosed,.webhappproduced and smoke-tested (#121, #123). - hREA v0.2 ships a module interface. The design fork (compile-time composition versus runtime attachment) is resolved and implemented upstream. Proposed as an RFC issue on
h-REA/hREA, positioned as the design question that follows #408.
2b. #408's slices land and the submodule pin moves. Claim, EconomicEvent.effortQuantity, the Holochain 0.6.1 bump and the integrity validation hardening all reach main-0.6 in reviewable pieces. As of this writing (2026-09-10) #408 is still open on feat/vf-proposal-purpose, explicitly staged as a branch to cut smaller PRs from rather than to merge whole. main-0.6 itself has not moved past fc3b5e78, the commit this repo's vendor/hrea submodule is already pinned to. What has changed is that the VF 1.0 surface this precondition is waiting on now exists and has been run: see the correction to precondition 3 below.
3. The Holochain 0.7 upgrade is unblocked in principle, not yet in practice. hREA happ-0.5.0-beta is about to land, built on feat/vf-proposal-purpose and on Holochain 0.7 (hdk 0.7.0 / hdi 0.8.0), with the zomes building clean, Sweettest 10/10 and the GraphQL acceptance battery 65/65 verified against a live 0.7 conductor with @holochain/client 0.21. That resolves the version-parity half of #134: hREA now runs on the same Holochain minor version Nondominium's chore/holochain-0.7 branch targets. It does not by itself resolve #134, because of the submodule mismatch below.
4. The two P0 ValueFlows gaps are closed or consciously deferred. See section 6.
4. Migration in two phases
Phase A: native ValueFlows concepts
Concepts where ValueFlows already has the class and hREA already has the entry type. These are straight substitutions: Nondominium stops defining the type and starts calling hREA.
| Nondominium type | hREA target | Notes |
|---|---|---|
zome_resource::ResourceSpecification | ReaResourceSpecification | Nondominium's category and tags map onto resource_classified_as URIs |
zome_resource::EconomicResource | ReaEconomicResource | custodian has no hREA field; carried as a governance-module attachment, not lost |
zome_gouvernance::EconomicEvent | ReaEconomicEvent | effortQuantity exists on feat/vf-proposal-purpose and is verified working; still blocked for work events until that slice reaches main-0.6 and the submodule pin moves (section 6) |
zome_gouvernance::Commitment | ReaCommitment | effort_quantity already present on hREA's commitment |
zome_person::Person (economic face) | ReaAgent | Already done in Phase 1; the Person entry itself stays native |
Our action vocabulary is the sharpest test of the whole plan, and hREA PR #408 has already changed the answer. Nondominium defines 16 VfAction variants. Fourteen map onto hREA's canonical set once #408 lands, including TransferCustody, which becomes the builtin transfer-custody. The remaining two, InitialTransfer and AccessForUse, do not exist in ValueFlows.
On main-0.6 this did not matter: rea_action is an unvalidated String, so any verb could be written. #408 adds VF_BUILTIN_ACTIONS (21 ids) and vf_validate_action to the integrity zome, which returns Invalid for anything outside that set on EconomicEvent, Commitment, Intent and Claim. After #408, those two actions are rejected at DHT validation.
That is correct behaviour for a VF 1.0 compliant hREA, and it is precisely why the module interface has to exist before Phase A can complete. These two actions are the smallest end-to-end test case for the RFC, and they are named as such in it.
Phase B: concepts with no ValueFlows class
Expressed through the module interface once it exists. Each of these is a candidate module, and the order below is deliberate: smallest first, so the interface is tested before governance bends it.
| Module | Covers | Weight |
|---|---|---|
source | Resource provenance (Network, Partner, Purchased, Donated) and the rest of the classification axes in resources.md section 6.4 | Small: close to a classification, arguably expressible as classifiedAs URIs alone |
nondominium-identity | NondominiumIdentity, LifecycleStage, lifecycle transition validation | Medium, and constrained: Layer 0 is bound to its own cell's DnaHash (ADR-010/013), so it cannot physically move into the hREA DNA. The module carries the reference and the transition semantics, not the anchor |
governance | GovernanceRule, ValidationReceipt, ResourceValidation, governance-as-operator transition evaluation | Large. Enforcement, not annotation, which is exactly where a runtime attachment mechanism would be weakest |
federation | NdoHardLink, Contribution, Agreement | Contribution may reduce to ReaEconomicEvent with action: work; Agreement partly to ReaAgreement; NdoHardLink is cross-DNA and has no ValueFlows analogue |
Never migrates
PrivateParticipationClaim (the PPR system) stays as Nondominium private entries permanently. PPRs are user-sovereign, bilaterally signed, and stored on the owning agent's source chain. Putting them in a shared economic DNA would defeat their purpose. What can cross the boundary is attribution: a ReputationSummary derived locally and referenced from hREA, never the claims themselves.
The same holds for PrivatePersonData, PrivateDataCapabilityMetadata, RevokedGrantMarker, FilteredPrivateData, Device and AgentPersonRelationship. These are identity and privacy machinery with no economic face.
5. Sequencing
v0.1.0 ships
│
├─ hREA v0.2: module interface designed, RFC'd, implemented, released
│ └─ Nondominium contributes the first consumer and the acceptance tests
│
├─ Holochain 0.7 upgrade on both sides (#134)
│
└─ Nondominium v0.2
├─ Phase A: native VF substitution (spec, resource, event, commitment)
│ └─ Gate: dual-read parity tests green before any native type is removed
├─ Phase B1: `source` module (smallest real test of the interface)
├─ Phase B2: `nondominium-identity` module
├─ Phase B3: `governance` module
└─ Phase B4: `federation` module
Phase A must be reversible. Following the dual-read pattern already described in integration-strategy.md section "Migration Strategy", every migrated read path returns from both stores and compares before the native type is deprecated.
6. Open questions and risks
The two P0 hREA gaps are addressed on #408 and now verified running, but not yet released. On the pinned main-0.6 submodule, vf:Claim has no entry type in dnas/hrea/zomes/integrity/hrea/src/lib.rs and effort_quantity exists on ReaCommitment, ReaIntent and ReaRecipeFlow but not on ReaEconomicEvent. PR #408 (feat/vf-proposal-purpose) adds both, along with SpatialThing, AgreementBundle, EconomicEvent.reciprocalRealizationOf and .settles, Commitment.reciprocalClauseOf, ResourceSpecification.substitutable and .mediumOfExchange, and Proposal.purpose with immutability enforced on update. It also replaces the permissive validation stubs with real DHT-wide checks (temporal consistency, quantity non-negativity, action validity, required-field presence) across every entry type the PR touches, per its own description. That PR is explicitly a staging branch, not to be merged as-is: smaller targeted PRs are to be cut from it. Genuinely still absent, on this branch and in hREA generally: BatchLotRecord (the PR removes the old ProductBatch and tracks BatchLotRecord as a named follow-up, not yet implemented) and ProposalList with listedIn. Nondominium's Claim and its work-event recording depend on these slices landing and on the submodule pin moving forward, which is a bigger step than it looks (see the fork and pin risk below).
The submodule points at a fork, and the fork's own 0.7 port is not on the release lineage. .gitmodules:1-4 pins vendor/hrea at git@github.com:Sensorica/hREA.git branch main-0.6, not at h-REA/hREA where PR #408 will eventually land as tagged releases. Verified by walking the actual commit graph: this repo's chore/holochain-0.7 branch pins the submodule at 8735ca07 (chore(deps): port hREA zomes to hdk 0.7 / hdi 0.8, Sensorica fork only). 8735ca07's direct parent is fc3b5e78, and fc3b5e78 is an ancestor of upstream h-REA/hREA's main-0.6, sprout and feat/vf-proposal-purpose branches, but 8735ca07 itself is not reachable from any upstream branch (git branch -a --contains 8735ca07 returns only origin/chore/holochain-0.7). That means whatever Sweettest count is currently green on Nondominium's 0.7 branch was measured against a submodule commit that predates hREA's entire VF 1.0 surface: no Claim, no SpatialThing, no AgreementBundle, none of the new validation. Moving the submodule pin to track feat/vf-proposal-purpose (or whatever tag happ-0.5.0-beta lands as) changes the hREA DNA hash and turns on validation those tests have never run against. Re-running the full test suite after the move, not just re-pinning and trusting the old green, is part of the work #134 still requires.
One consumer is a weak basis for a framework. If Nondominium is the only user of the module interface, we will build an interface shaped exactly like Nondominium. R&O and CFN are the plausible second and third consumers; whether they are actually available to review the design changes how much upfront generality is justified.
Capacity. Nondominium is built by two unpaid part-time contributors, and hREA maintenance runs alongside. v0.2 is the larger of the two efforts and it sits behind an upstream dependency we also have to build. The realistic risk is not slow delivery, it is starting Phase B before Phase A is stable.
A module interface may change the hREA DNA hash. If the resolution is compile-time composition, every distinct module set produces a distinct network. Nondominium would run its own hREA build rather than joining a shared hREA network. That is acceptable for our topology (we already clone per group and per NDO) but it must be a decision, not a discovery.
7. Success criteria
v0.2 is done when all of these are demonstrably true, each falsifiable by a test or an inspection.
- No entry type in
zome_resourceorzome_gouvernanceduplicates a concept hREA already implements. - Every economic read path in the UI resolves through hREA, verified by removing the native fallback and watching tests stay green.
- The three Nondominium actions are registered through the module interface, not written as unvalidated strings.
- At least one module (
source) is proven portable: a second hApp can enable it without importing Nondominium. - PPR entries remain private entries on the owning agent's chain, verified by a test asserting a counterparty cannot read them.
- The dual-read parity suite passes for every Phase A type before that type's native definition is deleted.
8. Not in scope for v0.2
- Unyt and Flowsta integrations. Both remain post-MVP and neither should shape the module interface.
- Layers 1 and 2 activation beyond what the modules above require.
- The collective agent ontology (
AgentContext,AgentEntityType). It touches hREA'sReaAgentand deserves its own release.
nondominium Implementation Plan
1. Executive Summary
This plan details the phased implementation of the nondominium hApp, a decentralized, organization-agnostic resource management system built on Holochain and ValueFlows. The implementation builds incrementally on the existing working foundation to deliver Economic Processes, Private Participation Receipt (PPR) reputation, agent capability progression, and cross-zome coordination, while aligning with the generic Nondominium Object (NDO) model where that work is scheduled.
MVP vs post-MVP (normative boundary): Per requirements.md §2.3, the MVP resource substrate is ResourceSpecification, EconomicResource, and GovernanceRule. The repository has also implemented NDO Layer 0 (NondominiumIdentity), Lobby and Group DNAs, PPR prototypes, and NDO federation extensions. Governance-as-Operator remains specified rather than coded as a Request→Evaluate→Apply path. NDO-wide requirements beyond the implemented subset (Layers 1/2 activation, operational-state split, capability slots, migration, REQ-NDO-) remain governed by ndo_prima_materia.md. Phases 2–4 below distinguish implemented foundations from remaining production workflows. Post-MVP agent ontology (REQ-AGENT-, REQ-NDO-AGENT-) is specified in requirements.md §4.4. Source-NDO is an optional application profile (REQ-SOURCE-APP-, requirements.md §4.6) — not required for Project NDOs or resource-mutualisation apps; see §12.7.
1.1 Requirements map (normative sources)
This index is the entry point for phased delivery. Current implementation baseline: Layer 0 identity and lifecycle UI are implemented; Resources, Governance, and Activity tabs render existing service-backed data, while Composition remains a placeholder. Layer 1 activation (NDOToSpecification) and Layer 2 activation (NDOToProcess) are normative but not yet wired in DNA. The next work should connect those layers and complete Economic Process, governance-rule evaluation, and authenticated PPR workflows rather than recreate already-shipped entry types and APIs. Status cross-check: IMPLEMENTATION_STATUS.md.
Core normative (PRD, NDO model, UI, data model)
| Source | Role |
|---|---|
| requirements.md | PRD — REQ-USER-, REQ-RES-, REQ-GOV-, REQ-PROC-, REQ-AGENT-* (§4.4 post-MVP agent ontology); REQ-UI-* (§4.5 MVP UI); REQ-SOURCE-APP-* / REQ-SOURCE-* (§4.6 optional Source profile) |
| ndo_prima_materia.md | NDO layers (L0/L1/L2), lifecycle vs operational state, capability surface; REQ-NDO-L1-* (§9.2), REQ-NDO-L2-* (§9.3), REQ-NDO-* (§9), migration (§10) |
| ui_design.md | UI vision — MVP Layer 0 complete; Resources, Governance, and Activity tabs service-backed; Composition and Join NDO remain incomplete |
| specifications/ui_architecture.md | Implemented UI stack, routes, stores, services (resource.service.ts, governance.service.ts), component map |
| specifications/specifications.md | Technical data structures — ResourceSpecification, GovernanceRule, EconomicResource, EconomicProcess, VfAction, cross-zome governance interface |
Layer 1 — Specification (resource form)
| Source | Role |
|---|---|
| zomes/resource_zome.md | Implemented coordinator/integrity API — ResourceSpecification, GovernanceRule, EconomicResource; planned NDOToSpecification / DigitalAsset links |
| requirements/resources.md | Resource ontology — implemented vs planned; Layer 1 activation gap; governance defaults from PropertyRegime × ResourceNature (non-normative REQ IDs) |
| post-mvp/project-type-ndo-specifications.md | Structured know-how bundles for project-type NDOs (OSHWA / Open Know-How → Layer 1 assets); lifecycle-matched completeness |
| post-mvp/source-ndo-requirements.md | Source-NDO (optional profile) — Source as third flow endpoint when an application governs generative systems; SourceProfile, adaptive loop, vf:Source (REQ-SOURCE-); applicability REQ-SOURCE-APP- in requirements.md §4.6 |
| post-mvp/Source-NDO-brainstorming.md | Paper planning scaffold — thesis, Ostrom/VF argument structure (informative) |
| post-mvp/source-ndo-paper.md | Academic grounding: Occam's razor proof, river case study, Ostrom SES mapping (informative) |
| post-mvp/ndo-versioning.md | Version DAG — REQ-NDO-L1-03 (multiple ResourceSpecification links per NDO identity) |
| post-mvp/digital-resource-integrity.md | Content-addressed manifests, composable verification — REQ-NDO-L1-06 DigitalAsset capability slots (prima materia §9.2) |
| post-mvp/fractal-composable-resource-architecture.md | Archival design — atomic / component / composite nesting; informs integrity (R5–R6) and Composition tab (post-MVP) |
Governance (embedded rules → operator enforcement)
| Source | Role |
|---|---|
| requirements/governance.md | Governance ontology — governance-as-operator, PPR, validation, role tiers; gap analysis (non-normative REQ IDs) |
| specifications/governance/governance-operator-architecture.md | REQ-ARCH-07/09 — GovernanceTransitionRequest / evaluate_state_transition; rules on spec, enforcement in zome_gouvernance |
| specifications/governance/governance-operator-implementation-guide.md | Implementation patterns for rule evaluation and cross-zome calls |
| specifications/governance/private-participation-receipt.md | PPR categories and bilateral receipts — accountability after governed process completion |
| zomes/governance_zome.md | Coordinator API — commitments, events, claims, validation, PPR issuance |
| post-mvp/unyt-integration.md | Typed EconomicAgreement governance rules, RAVE settlement (REQ-NDO-CS-07–CS-11) — Layer 1 rule family |
| post-mvp/flowsta-integration.md | IdentityVerification / FlowstaIdentity slots (REQ-NDO-CS-12–CS-15) — agent identity gates on high-trust transitions |
Process (Layer 2 — what agents do with resources)
| Source | Role |
|---|---|
| requirements.md §5 | REQ-PROC-* — Use, Transport, Storage, Repair; role-gated initiation; process validation and chaining |
| ndo_prima_materia.md §4.4 | Layer 2 activation via NDOToProcess; hosts Commitments, Claims, EconomicEvents, PPRs (REQ-NDO-L2-*) |
| post-mvp/resource-transport-flow-protocol.md | Multi-dimensional transport/flow semantics (physical, custodial, value, legal, information) over EconomicEvent metadata — post-MVP |
| post-mvp/many-to-many-flows.md | N-ary custody and multi-party events — after shared custody / AgentContext model matures |
| post-mvp/valueflows-dsl.md | VF DSL for recipes, bulk bootstrap, scripted coordination — operational tooling track |
Federation, agent context, and supplementary ontology
| Source | Role |
|---|---|
| lobby-dna.md | Multi-network federation — Lobby / Group / NDO DNA extensions (REQ-LOBBY-, REQ-GROUP-, REQ-NDO-EXT-*) |
| requirements/agent.md | Agent ontology — roles, affiliation, AgentContext (post-MVP); background for governance participation and process access |
1.2 Status synchronization convention
- IMPLEMENTATION_STATUS.md is the evidence-based inventory of current code.
- In this plan,
[x]means the stated scope exists now;[ ]means remaining work. A checked foundation does not imply that its unchecked production workflow is complete. - When a feature ships, update both documents in the same change: record evidence and limitations in the status document, then close or split the corresponding plan task.
- Do not mark a whole phase complete while it still contains implementation tasks; use “foundation delivered” or “partial” for mixed phases.
2. Implementation Principles
Development follows Complexity Driven Development (CDD) and Complexity Oriented Programming (COP): software as an evolving coordination structure, not a deterministic machine. The design unit is agent → process → resource → relation → network, not function → class → module. Methodology reference: archives/complexity_oriented_programming.md; operational checklist: .claude/skills/complexity-oriented-programming/SKILL.md.
Judge outcomes by systemic viability — anti-fragility, evolvability, coordination capacity, holonic health, trust composability — not only delivery speed or defect rate.
2.1 CDD / COP foundations
| Principle | Implementation requirement |
|---|---|
| Dynamic complexity matching | Match governance overhead and schema rigidity to actual social complexity — not the imagined maximum. Apply subsidiarity: resolve decisions at the most local level that can handle them (agent, group, NDO, network); escalate only when broader context is genuinely required. |
| Progressive activation | Artifacts begin as low-complexity intent and accrue structure over time. Layer 0 identity always on; Layer 1 specification and Layer 2 process activate only when coordination demands it (REQ-NDO-L1-, REQ-NDO-L2-). UI and DNA must not force full spec/governance/process surfaces on Ideation-stage NDOs. |
| Governance-as-operator | Decouple the data substrate (zome_resource) from regulatory signaling (zome_gouvernance). Business and governance logic must not be hard-coded into core entry schemas; rules evolve as mutable data without destructive migrations (REQ-ARCH-07, REQ-ARCH-08). |
| Stigmergic coordination | Prefer discoverable traces, anchor links, reputation signals (PPRs), and CapabilitySlot attachments over central orchestrators. Agents coordinate by modifying a shared environment — the DHT — not by a mediating platform service. |
| Fractal composability | Use the same coordination primitives at agent, group, NDO, and federation scales. Trust and integrity compose through hierarchies (atomic → component → composite): local verification at each level yields global coherence; changes re-verify only affected paths (digital integrity, holonic NDO links — post-MVP). |
| Path-dependency awareness | Before refactors or major UI/API contracts, scan legacy choices (orphan ResourceSpecification entries, pre-NDO economic-resource flows, four-regime frontend types, and remaining placeholder surfaces). The localStorage Group shell has already migrated to cloned Group cells; only per-Group presentation preferences remain local. Document migration windows (REQ-NDO-MIG-*) when Layer 1 bridges old and new models. |
| Anti-fragility | Disruption should teach, not only hurt. Disputes, validation failures, and adversarial behaviour must generate auditable signals (PPRs, validation receipts, governance events) that improve future coordination — not merely error screens. |
2.2 Nondominium enactments
- Incremental enhancement: Extend working code through new modules and functions; avoid breaking MVP flows until migration windows are defined.
- ValueFlows compliance: Data structures and flows adhere to ValueFlows — Knowledge (
ResourceSpecification), Plan (Commitment), Observation (EconomicEvent,Claim) — with Economic Process integration (REQ-PROC-*). - Agent-centric design: Data and validation originate on each agent's source chain; capability progression (Simple → Accountable → Primary Accountable) gates sensitive actions. Post-MVP: requirements must hold for holonic actors (
AgentContext), not only individualAgentPubKeys (REQ-AGENT-01, REQ-GOV-16). - Resources as autonomous entities: Resources carry embedded governance, stable identity (Layer 0), and lifecycle — they are coordination objects, not passive CRUD rows. LifecycleStage (identity maturity) stays orthogonal to OperationalState (instance process condition) (REQ-NDO-LC-02, REQ-NDO-OS-02, REQ-NDO-OS-04).
- Embedded governance (Social DNA):
GovernanceRuleentries on Layer 1ResourceSpecificationdefine how agents may interact; the governance zome evaluates transitions against them. Rules are mutable data communities can amend; identity anchors are not. - Capability-based security: Holochain capability tokens plus role-gated process access (REQ-SEC-01, REQ-SEC-02); field-level private data grants with expiry and explicit revocation.
- Privacy-preserving accountability: Bilateral PPRs and derivable
ReputationSummary— user-sovereign, no global scoring aggregator (REQ-PPR-10, REQ-PPR-11). - Process-aware infrastructure: Use, Transport, Storage, Repair processes are first-class; initiation, validation, and chaining follow embedded rules and role credentials (REQ-PROC-01–REQ-PROC-09).
2.3 Layer 1 UI and cross-layer discipline
- Mirror the zome boundary in the UI: Specification tab → data model (
ResourceSpecification, assets, version links); Governance tab → embedded rules and their semantics; Activity / process surfaces → Layer 2 readiness gated by rules — do not collapse layers into a single undifferentiated form. - Complexity-matched affordances: Expose creation/editing depth proportional to
LifecycleStageand layer activation (e.g. lightweight spec atSpecification, full governance editor when rules matter, process actions only when Layer 2 or MVP process APIs exist). - Service-layer contract stability: UI calls Effect-TS services (
resource.service.ts,governance.service.ts); zome function names and shared types (@nondominium/shared-types) are the integration seam — keep components free of raw zome payloads. - Correctness over cleverness: Governance infrastructure for real economic relationships; a wrong validation rule on the DHT cannot be rolled back — prefer explicit, reviewable rule data over implicit UI magic.
3. Architecture alignment (NDO prima materia)
The three-layer model (ndo_prima_materia.md §4) structures resources as:
- Layer 0 — Identity:
NondominiumIdentity(stable anchor, tombstone at end of life); identity fields are immutable while lifecycle updates may changelifecycle_stage,hibernation_origin, and the one-timesuccessor_ndo_hash(REQ-NDO-L0-*). - Layer 1 — Specification: Activated by
NDOToSpecification→ResourceSpecification(governance rules, discoverable form); may be dormant/archived while L0 remains (REQ-NDO-L1-*). - Layer 2 — Process: Activated by
NDOToProcess→ ValueFlowsProcess; hosts commitments, claims, events, PPRs (REQ-NDO-L2-*).
Two state dimensions (§5): LifecycleStage lives on the identity (maturity of the artefact); OperationalState lives on EconomicResource (transient process condition). Transitions on one must not imply transitions on the other (REQ-NDO-OS-04).
flowchart TB
subgraph layers [Layer_stack]
L2[Layer2_Process]
L1[Layer1_Specification]
L0[Layer0_Identity_always_on]
L0 --> L1
L1 --> L2
end
4. Implementation tracks
Work below is grouped into parallel tracks so MVP delivery, NDO migration, agent ontology, integrations, and extended specs are not confused as a single serial timeline.
| Track | Intent | Primary references |
|---|---|---|
| MVP core | Phases 2–4 in Section 5: private data sharing, economic processes, PPR, promotion, security, cross-zome coordination | requirements.md REQ-USER / REQ-PROC / REQ-GOV |
| NDO model and migration | NondominiumIdentity, NDOToSpecification / NDOToProcess, holonic links, CapabilitySlot, lifecycle plus operational split, faceted discovery links, one-time migration (REQ-NDO-MIG-*) | ndo_prima_materia.md §§8–10, §9 |
| Agent ontology | REQ-AGENT-* / REQ-NDO-AGENT-* items under Phases 2–4 | requirements.md §4.4; requirements/agent.md for OVN background |
| Unyt / Flowsta | Phased integration; governance enforcement in later phases | Section 12.2–12.3; REQ-NDO-CS-07–CS-15 |
| Source-NDO application profile | Optional third VF primitive (vf:Source) for applications governing generative ecological/knowledge systems — not activated for ordinary Project NDOs or mature-resource mutualisation (e.g. shared 3D printer). Opt-in modules only; default UI stays Agent + Resource. | requirements.md §4.6 REQ-SOURCE-APP-*; source-ndo-requirements.md; §12.7 |
| Extended post-MVP | Many-to-many flows, full version DAG, digital integrity, RTP-FP, VF DSL, Moss contract, and remaining federation work. Lobby/Group DNAs and the first NDO federation primitives are already implemented. | documentation/requirements/post-mvp/*.md |
Phase 2.2 and the NDO track: NondominiumIdentity, LifecycleStage, lifecycle validation, and lifecycle facet links already exist. Remaining work implements OperationalState, NDOToSpecification / NDOToProcess, process-aware resource transitions, and the rest of REQ-NDO-LC-, REQ-NDO-OS-, and REQ-NDO-L2-. Legacy-resource migration remains in Section 12.1 and REQ-NDO-MIG-.
Source-NDO track (optional application profile): Follows dynamic complexity matching — Agent + Resource remain the universal baseline. Source modules activate only when an application's domain requires governing a generative system (watershed, river, fishery, knowledge commons) and its boundary effects. Not in scope for Project-type NDOs (e.g. open-hardware design) or resource-mutualisation NDOs (e.g. sharing a 3D printer within or between Groups). When enabled, the track adds SourceProfile, coupling links, the Steward role, vf:Source boundary events, and an adaptive governance loop. Full adaptive enforcement depends on Governance-as-Operator (§12.7); Phases A–B can proceed on opt-in data model and event recording without changing the default NDO creation UI.
5. Implementation Phases
Phase 1: Foundation Layer ✅ DELIVERED (Existing Working Code)
1.1 Agent Identity & Role System (zome_person) ✅ CORE IMPLEMENTED
-
Implement
Person(public info) andPrivatePersonData(private entry, PII). -
Implement
PersonRoleentry with validation metadata and links to validation receipts. -
Modular Architecture: Refactored into
person.rs,private_data.rs,role.rsmodules - Comprehensive Error Handling: PersonError enum with detailed error types
- Core Functions: Profile management, role assignment, private data storage
-
Multi-device identity:
DeviceandAgentPersonRelationshipentries, links, and coordinator APIs - Foundation testing: Active Person/hREA Sweettests
- Remaining testing: Complete capability, role, device, and promotion Sweettest coverage
1.2 Resource Management (zome_resource) ✅ CORE IMPLEMENTED
-
Implement
ResourceSpecificationwith separately stored and linkedGovernanceRuleentries. -
Implement
EconomicResourcewith custodian tracking and state management. -
Modular Architecture: Refactored into
resource_specification.rs,economic_resource.rs,governance_rule.rs - Comprehensive Error Handling: ResourceError enum with governance violation support
- Signal System: Complete post-commit signal handling for DHT coordination
- Core Functions: Resource specification and economic resource CRUD operations
-
NDO Layer 0:
NondominiumIdentity, 10-stage lifecycle validation, hibernation/successor metadata, and discovery facets - Foundation testing: Active Resource/NDO Sweettests
- Remaining testing: Close uncovered Resource/NDO integrity and workflow paths
1.3 Governance Foundation (zome_gouvernance) 🔄 FOUNDATION IMPLEMENTED
- Basic VfAction Enum: Type-safe economic action vocabulary
- Validation Infrastructure: ValidationReceipt creation and management
- Economic Event Logging: Basic economic event recording
- Cross-Zome Functions: Core validation functions for resource and agent validation
- Error Handling: GovernanceError enum with comprehensive error types
-
Governance-as-Operator path: Implement
GovernanceTransitionRequest/TransitionContext/GovernanceTransitionResult,evaluate_state_transition, and resource-zomerequest_resource_transition - Governance-as-Operator completion: Typed rule evaluation, consistent authorization, and automatic event/PPR generation
Phase 2: Enhanced Governance & Process Integration 🚀 HIGH PRIORITY
2.1 Enhanced Private Data Sharing (zome_person) 🔄 PARTIAL
Field-level direct grants are implemented. The outstanding work is the request/approval ceremony, lifecycle visibility, auditing, and full workflow tests.
-
Data Access Request System:
-
DataAccessRequestentry type with status tracking -
request_private_data_access()function for requesting specific fields -
respond_to_data_request()function for approving/denying requests - Bidirectional linking system for request tracking
-
-
Direct Capability Grant Foundation:
-
PrivateDataCapabilityMetadatawith allowed fields, context, expiry, grantor/grantee, and local capability secret -
Field filtering through
FilteredPrivateDataresponse views -
Grant, claim, retrieval, revoke, owned-grant, role-based, and transferable grant APIs under their current names (
grant_private_data_access,get_private_data_with_capability,revoke_private_data_access, etc.) - Governance-oriented private-data validation API
-
-
Grant Lifecycle Completion:
-
Enforce a true maximum grant duration; current callable grants accept arbitrary
expires_in_days - Remove mock/fallback retrieval paths and harden revocation discovery
-
get_expiring_grants()for proactive renewal/expiry handling - Auditable private-data access events
- End-to-end request→approval→access→revocation Sweettests
-
Enforce a true maximum grant duration; current callable grants accept arbitrary
-
Governance Integration Completion:
- Connect private-data eligibility checks to a real, queryable promotion-request workflow
- Replace specialized-role auto-approval with credential and approver validation
2.2 Economic Process Infrastructure (zome_resource) 📋 HIGH PRIORITY
Extending existing resource management with process-aware workflows. NDO track overlap: state split and discovery links map to REQ-NDO-LC-, REQ-NDO-OS-, REQ-NDO-OS-06; process and PPR linkage align with REQ-NDO-L2-* once Layer 2 is modeled via NDOToProcess (see ndo_prima_materia.md §4.4).
-
Economic Process Data Structures (NEW):
-
EconomicProcessentry type with status tracking and role requirements -
ProcessStatusenum (Planned, InProgress, Completed, Suspended, Cancelled, Failed) -
Split legacy
ResourceStateintoLifecycleStage+OperationalState(see ndo_prima_materia.md Section 5):-
LifecycleStageenum onNondominiumIdentity(Layer 0) — 10 stages with integrity-validated transitions -
OperationalStateenum onEconomicResource— 7 process states; defaultPendingValidationon create - Update governance zome state transition logic to manage both enums independently (REQ-NDO-OS-02/03 — deferred)
-
Add NDO lifecycle discovery through
NdoByLifecycleStage -
Replace legacy
ResourcesByStatewithResourcesByOperationalState; lifecycle discovery remains on Layer 0
-
-
OperationalStatetransitions aligned with process outcomes (begin/end of transport, storage, maintenance processes)
-
-
Process Management Functions (NEW):
-
initiate_economic_process()with role-based access control -
complete_economic_process()with state change validation - Process query functions by type, status, and agent
- Process-resource relationship tracking
-
-
Enhanced Cross-Zome Integration (EXTEND):
- Role validation calls to person zome for process initiation
- Governance zome integration for process validation and PPR generation
- Private data coordination for custody transfers
2.3 Private Participation Receipt (PPR) System (zome_gouvernance) 🔄 PROTOTYPE IMPLEMENTED
The private entry model, 16 categories, coordinator APIs, signature validation, and local summary calculation exist. The production milestone is authenticated bilateral coordination and automatic workflow integration.
-
PPR Data Structures:
-
PrivateParticipationClaimprivate entry type -
ParticipationClaimTypeenum with 16 claim categories -
PerformanceMetrics,CryptographicSignature, andReputationSummary
-
-
PPR Coordinator Prototype:
-
issue_participation_receipts() -
sign_participation_claim() -
validate_participation_claim_signature()and enhanced validation variant -
get_my_participation_claims()via DHT discovery links -
derive_reputation_summary()from the calling agent's linked receipts
-
-
Bilateral Authentication Completion:
- Remove the placeholder counterparty signature from initial issuance
- Complete a counterparty-authenticated signing exchange with replay/idempotency handling
- Eliminate DHT discovery links to private claim action hashes, or redefine the privacy model explicitly
- Add active multi-agent Sweettests for issuance, countersigning, validation, privacy, and summaries
-
Process Integration:
- Automatic PPR generation for all Commitment-Claim-Event cycles
- Economic Process completion triggers specialized PPR categories
- Agent promotion generates appropriate PPR types
2.4 Complete Agent Capability Progression 🔄 GOVERNANCE CRITICAL
Role entries, assignment APIs, promotion externs, and governance validation entry points exist. The request artifact and several authorization/credential checks remain incomplete.
-
Promotion Foundation:
-
PersonRoleentries and six predefined role variants - Promotion request/approval coordinator entry points
- Cross-zome governance and private-data validation entry points
-
-
Enhanced Agent Promotion:
-
Replace the placeholder request hash with a queryable
RolePromotionRequest - Enforce authorization and private-data quality requirements end-to-end
- Automatic PPR generation for promotion activities
- Capability token progression (general → restricted → full)
-
Replace the placeholder request hash with a queryable
-
Specialized Role Validation:
- Replace current auto-approval with credential checks for Transport, Repair, and Storage
- Primary Accountable Agent validation requirements
- Role-specific PPR generation for validation activities
-
Cross-Zome Validation Workflow Completion:
- Resource/process/agent validation entry types and coordinator APIs
- Connect resource validation to first-access events
- Enforce agent identity validation with private data verification
- Specialized role validation with existing role holder approval
Agent Ontology Items (Post-MVP, Phase 2 — see requirements.md §4.4 and requirements/agent.md §5.3; REQ-AGENT-*):
-
[G13] Fix
request_role_promotionstub (HIGH PRIORITY — broken workflow):-
Create a real
RolePromotionRequestentry type inzome_personintegrity, replacing the current placeholder hash return -
Add
AllPromotionRequestsanchor link for approver discovery -
Add
AgentToPromotionRequestandPromotionRequestToAgentbidirectional links -
Implement
get_pending_promotion_requests()query function for authorised approvers -
See
REQ-AGENT-16and code TODO inrole.rs
-
Create a real
-
[G6]
AffiliationRecordentry type (NEW):-
Define
AffiliationRecordstruct:agent,network_id,documents_acknowledged: Vec<DocumentAck>,signed_at,signature,witness: Option<AgentPubKey> -
Define
DocumentAckstruct:document_hash,document_title,document_version -
Implement
create_affiliation_record(input)— agent cryptographically signs ToP, Nondominium & Custodian agreement, Benefit Redistribution Algorithm -
Link:
agent_pubkey → affiliation_record_hash(AgentToAffiliation) -
UI: prompt agent to create
AffiliationRecordduringPersoncreation flow -
See
REQ-AGENT-05
-
Define
-
[G2] Derived affiliation state (NEW — computed, not stored):
-
Implement
get_affiliation_state(agent_pubkey) -> AffiliationStateas a composed query:UnaffiliatedStranger: noPersonentryCloseAffiliate:Personexists but noAffiliationRecordand zero contributionsActiveAffiliate:AffiliationRecordexists + tracked contributions (economic events) within configurable recency windowCoreAffiliate:ActiveAffiliatewhose PPR-derived contribution rate exceeds configurable thresholdInactiveAffiliate:AffiliationRecordexists, previously active, but no contributions within recency window
-
Expose affiliation state as part of
get_person_profile()response - Use affiliation state in governance access decisions (Active/Core affiliates for governance participation)
-
See
REQ-AGENT-04
-
Implement
Phase 3: Advanced Security & Cross-Zome Coordination 🔒 PRODUCTION READINESS
3.1 Enhanced Capability-Based Security
Building on existing capability infrastructure with Economic Process integration
-
Progressive Capability Tokens (EXTEND):
-
general_accesstokens for Simple Agents (existing foundation) -
restricted_accesstokens for Accountable Agents (PPR-enabled) -
full_accesstokens for Primary Accountable Agents (custodianship-enabled) - Automatic capability progression triggered by PPR milestones
-
-
Economic Process Access Control (NEW):
- Role-based process access validation (Transport, Repair, Storage)
- Dynamic capability checking for specialized Economic Processes
- PPR-derived reputation influencing process access permissions
-
Function-Level Security (EXTEND):
- Apply capability requirements to all new Economic Process functions
- Enhanced private data access control with granular field permissions
- Cross-zome capability validation for complex workflows
Agent Ontology Items (Post-MVP, Phase 3 — see requirements.md §4.4 and requirements/agent.md §5.3; REQ-AGENT-*):
-
[G1]
AgentEntityTypeconfiguration (NEW):-
Define
AgentEntityTypeenum inzome_personintegrity:Individual,Collective(String),Project(ActionHash),Network(ActionHash),Bot { capabilities: Vec<String>, operator: AgentPubKey },ExternalOrganisation(String) -
Define
AgentContextentry:agent_type: AgentEntityType,person_hash: Option<ActionHash>,created_at,network_seed -
Collective, Project, and Network types reference an NDO hash — no separate
Personentry required - Update governance role-gating logic to account for non-individual agent types
-
See
REQ-AGENT-01,REQ-AGENT-02
-
Define
-
[G15] CapabilitySlot on Person (NEW):
-
Implement
CapabilitySlotlink type fromPersonentry hash to external capability targets (DID documents, credential wallets, reputation oracles) -
Reuse
CapabilitySlotTag/SlotTypepattern fromndo_prima_materia.md§8.3 — same pattern applied at agent identity level -
Implement
attach_agent_capability_slot(person_hash, slot_type, target_hash)andget_agent_capability_slots(person_hash) -
See
REQ-AGENT-11
-
Implement
-
[G3] Composable
AgentProfileview (NEW):-
Implement
get_agent_profile(agent_pubkey) -> AgentProfileas a composed query — NOT a new stored entry:- Identity:
AgentPubKey,Person,AffiliationState,AgentEntityType - Capability:
roles: Vec<PersonRole>,capability_level,capability_slots: Vec<CapabilitySlotInfo> - Reputation:
reputation_summary: Option<ReputationSummary>,economic_reliability_score: Option<f64> - Participation:
active_commitments_count,economic_events_count,resource_custodianships_count - Social:
network_affiliations: Vec<NetworkAffiliation>,peer_vouches: Option<u32> - Temporal:
joined_at,last_active_at
- Identity:
- Agent controls which sections are exposed by granting access to constituent entries
-
See
REQ-AGENT-07
-
Implement
-
[G4]
AgentRelationshiplink type (NEW):-
Define bidirectional
AgentRelationshiplink type with typed tags:Colleague,Collaborator,Trusted,Voucher - Store as private links (agent-to-agent, not publicly discoverable)
-
Implement
create_agent_relationship(target, relationship_type)andget_my_relationships() -
See
REQ-AGENT-08
-
Define bidirectional
-
[G5] Network affiliation links (NEW):
-
Define
NetworkAffiliationlink type fromPersonhash to NDO instance hashes -
Implement
add_network_affiliation(person_hash, ndo_hash, affiliation_type)andget_network_affiliations(person_hash) -
An agent's multi-network membership is visible as part of the composable
AgentProfile -
See
REQ-AGENT-09
-
Define
-
[G14] Configurable role taxonomy (NEW):
-
Define
RoleDefinitionentry type:role_name,capability_level,description,validation_requirements,network_id -
Replace hard-coded
RoleTypeenum withRoleDefinitionregistry; predefined six roles created as default entries at network genesis -
Update
assign_person_roleto accept any role name present in the network'sRoleDefinitionregistry -
See
REQ-AGENT-06
-
Define
-
[G1+Resource] Collective agent custodianship (NEW — resource-agent integration):
-
Define
AgentContextunion type usable whereverAgentPubKeycurrently identifies a custodian or initiator -
Update
EconomicResource.custodianfromAgentPubKeytoAgentContext -
Update
TransitionContext.target_custodianfromOption<AgentPubKey>toOption<AgentContext> -
Update
NondominiumIdentity.initiatorfromAgentPubKeytoAgentContext - Update custody transfer validation to handle collective agent auth (no single private key — requires collective signature or designated operator key)
-
See
REQ-AGENT-02,resources.md §5.3,governance-operator-architecture.md §2.1
-
Define
-
[G2+Resource] Affiliation-gated resource access (NEW — resource-agent integration):
-
Extend
GovernanceRule.rule_dataJSON schema to supportmin_affiliationcondition:"min_affiliation": "ActiveAffiliate" | "CoreAffiliate" -
Extend governance zome
evaluate_transitionto cross-zome queryzome_personfor requesting agent'sAffiliationStatewhenmin_affiliationis present in an applicable GovernanceRule -
Surface affiliation state as an enumerated result field in
GovernanceDecision.role_permissionsentries -
Add
affiliation_gated_access: boolflag to governance defaults engine output so UIs can surface relevant access requirements -
Write integration tests: agent with
UnaffiliatedStrangerstate rejected formin_affiliation: ActiveAffiliategoverned resource;ActiveAffiliateagent accepted -
See
REQ-AGENT-03,REQ-AGENT-05,resources.md §5.3 (Affiliation-gated resource access row),governance-operator-architecture.md §2.1 TODO G2
-
Extend
Governance Agent Ontology Integration (Post-MVP, Phase 3 — see governance.md §3.6, §6.4, §6.6):
-
[G1+Governance] Extend core governance entry types to AgentContext:
-
GovernanceTransitionRequest.requesting_agent:AgentPubKey→AgentContext -
ResourceStateChange.initiated_by:AgentPubKey→AgentContext -
ValidationReceipt.validator:AgentPubKey→AgentContext -
EconomicEvent.providerand.receiver:AgentPubKey→AgentContext -
Commitment.providerand.receiver:AgentPubKey→AgentContext -
PrivateParticipationClaim.counterparty:AgentPubKey→AgentContext -
Implement
AgentContext→signing_keyresolution: forIndividual= the key itself; forCollective= designatedPrimaryAccountableAgentkey from collective NDO; forBot= operatorAgentPubKey -
See
REQ-GOV-16,governance.md §3.6.1,§6.6
-
-
[G6+Governance] AffiliationRecord governance ceremony:
-
Implement
create_affiliation_record()in governance zome usingCommitment/EconomicEventcycle -
Create
AffiliationRecordSignedPPR (bilateral, private) on ceremony completion -
Ensure
AffiliationStatederivation inzome_personreadsAffiliationRecordpresence from DHT -
See
REQ-GOV-15,governance.md §3.6.3,§4.4
-
Implement
-
[G2+Governance] Affiliation-gated governance access:
-
Extend governance
evaluate_transitionto checkGovernanceRule.rule_data["min_affiliation"]specifically for GOVERNANCE PARTICIPATION (distinct from resource access gating) -
Implement governance_weight formula from
governance.md §6.4:affiliation_stategate → 0 if< ActiveAffiliate;core_multiplierifCoreAffiliate -
See
REQ-GOV-14,governance.md §6.4
-
Extend governance
3.2 Comprehensive Cross-Zome Coordination
Ensuring atomic operations and consistency across the three-zome architecture
-
Transaction Consistency (NEW):
- Atomic custody transfer operations spanning resource and governance zomes
- Economic Process completion consistency across resource and governance validation
- PPR generation consistency with resource state changes
-
Error Handling Coordination (EXTEND):
- Standardized error translation between zomes (implemented in docs)
- Rollback mechanisms for failed cross-zome operations
- Comprehensive error context preservation across zome boundaries
-
State Synchronization (NEW):
- Resource state changes coordinated with Economic Process status
- Agent capability progression synchronized with PPR generation
- Role assignments coordinated with governance validation workflows
3.3 Advanced Validation & Dispute Resolution
Building on basic validation infrastructure with sophisticated governance
-
Enhanced Validation Schemes (EXTEND):
- 2-of-3, N-of-M reviewer support with PPR-weighted selection
- Reputation-based validator selection for Economic Process validation
- Multi-tiered validation for different resource and process types
-
Dispute Resolution Infrastructure (NEW):
- Edge-based dispute resolution involving recent interaction partners
- PPR-based reputation context for dispute resolution
- Private data access coordination for dispute mediation
-
Governance Rule Enforcement (NEW):
- Dynamic governance rule evaluation for Economic Processes
- Conditional logic support for complex resource access rules
- Community-driven governance parameter adjustment
Phase 4: Network Maturity & Advanced Features 🌐 SCALING & OPTIMIZATION
4.1 Advanced Economic Process Workflows
Building sophisticated process chaining and automation on established foundation
-
Process Chaining & Automation (NEW):
- Multi-step Economic Process workflows (Transport → Repair → Transport)
- Conditional process logic based on resource state and agent performance
- Automated process matching and agent selection based on PPR reputation
-
Advanced Resource Management (EXTEND):
- Resource booking and reservation system for Economic Processes
- Time-based resource availability and process scheduling
- Multi-agent process coordination and collaborative workflows
-
Performance Analytics (NEW):
- Economic Process performance tracking and optimization recommendations
- Resource utilization analytics and efficiency metrics
- Agent performance trends and specialization insights
Agent Ontology Items (Post-MVP, Phase 4 — see requirements.md §4.4 and requirements/agent.md §5.3; REQ-AGENT-*):
-
[G8]
PortableCredentialstructure and export (NEW):-
Define
PortableCredentialstruct:issuing_network(DNA hash),agent,credential_type: PortableCredentialType,claims,issued_at,valid_until,issuer_signature,agent_signature -
PortableCredentialTypevariants:RoleCredential(String),ReputationCredential,CompetencyCredential(String),AffiliationCredential -
Implement
issue_portable_credential(agent, credential_type)— requiresPrimaryAccountableAgentissuer + agent countersign -
Implement
verify_portable_credential(credential)— validates both signatures against issuing network DNA hash -
See
REQ-AGENT-12andREQ-PPR-15
-
Define
-
[G7] ZKP capability proofs (NEW — requires external ZKP library integration):
-
Research and select ZKP library compatible with Holochain WASM compilation target (e.g.,
bellman,arkworks, or ZKP-compatible VC layer) -
Define
prove_capability(condition: CapabilityCondition) -> ZKProof— e.g., "I have ≥ N claims of type T" without revealing counterparties or timestamps -
Allow governance functions to accept ZKProof in lieu of raw
ReputationSummaryfor access decisions -
See
REQ-AGENT-13andREQ-PPR-14
-
Research and select ZKP library compatible with Holochain WASM compilation target (e.g.,
-
[G9] Sybil resistance mechanism (NEW — configurable per network):
-
Option A — Social vouching: N existing
ActiveAffiliateagents must co-sign a new agent'sAffiliationRecord -
Option B — Biometric opt-in: integrate with external biometric verification service; store proof hash in
AffiliationRecord - Option C — Proof-of-Personhood: integrate with existing PoP protocols (e.g., Proof of Humanity, Worldcoin) as membrane proof
- Network genesis configuration selects which option(s) apply
-
See
REQ-AGENT-15
-
Option A — Social vouching: N existing
-
[G10] Pseudonymous participation mode (NEW):
-
Allow ephemeral
AgentPubKeyto contribute without creating aPersonentry orAffiliationRecord - PPRs are issued to the ephemeral key; reputation accumulates but is unlinkable to physical identity
-
Agent can optionally link an ephemeral key to their main
Personentry later (explicit opt-in de-anonymisation) -
See
REQ-AGENT-14
-
Allow ephemeral
-
[G11] AI/bot delegation (
DelegatedAgent) (NEW):-
Define
DelegatedAgententry:delegating_person: AgentPubKey,delegate_key: AgentPubKey,scope: Vec<String>,valid_until: Timestamp,signature - Bot/AI keys act within declared scope; their actions are attributed to the delegating person for PPR purposes
-
See
REQ-AGENT-03
-
Define
-
[G12]
AgentNeedsWantsprofile extension (NEW):-
Define optional
AgentNeedsWantsentry:needs: Vec<ResourceNeed>,offers: Vec<ResourceOffer>,updated_at -
Link from
Personhash; update viaupdate_agent_needs_wants(input) -
Enable network-level matching:
find_matching_agents(resource_type, quantity)queries NeedsWants entries -
See
REQ-AGENT-10
-
Define optional
4.2 Advanced PPR & Reputation Systems
Enhancing the reputation system with AI and cross-network capabilities
-
Advanced Reputation Algorithms (EXTEND):
- Machine learning-based trust prediction and recommendation systems
- Context-aware reputation weighting for different Economic Process types
- Dynamic reputation thresholds based on network maturity and agent density
-
Cross-Network Reputation (NEW):
- PPR reputation portability across multiple nondominium networks
- Federated identity management with reputation synchronization
- Inter-network agent validation and reputation verification
-
Reputation-Based Governance (NEW):
- Dynamic capability levels based on PPR-derived reputation scores
- Reputation-weighted validation schemes for community governance
- Automated role progression based on performance metrics and community recognition
4.3 Performance & Scalability Optimization
Optimizing the system for large-scale network operation
-
DHT & Query Optimization (EXTEND):
- Advanced DHT anchor strategies for efficient Economic Process discovery
- Parallel validation processing for large-scale governance operations
- Caching strategies for frequently accessed PPR and reputation data
-
Network Health & Monitoring (NEW):
- Real-time network health dashboards and metrics
- Automated performance bottleneck detection and resolution
- Predictive scaling based on Economic Process demand patterns
-
Cross-Zome Performance (OPTIMIZE):
- Optimized cross-zome call patterns for complex workflows
- Batched operations for multiple Economic Process coordination
- Efficient state synchronization across distributed agent networks
6. Quality Assurance
- Test-Driven Development: Write tests before implementation.
- Incremental Integration: Continuous integration between zomes.
- Documentation-First: Update specs before coding changes.
- Unit, Integration, and Network Testing: Validate all workflows, especially validation and promotion.
7. Risk Mitigation
- Cross-Zome Dependencies: Mitigated by interface design and testing.
- Validation Complexity: Addressed through modular validation functions.
- Performance Bottlenecks: Handled via incremental optimization and monitoring.
- Validation Gaming: Prevented through multi-reviewer schemes and audit trails.
8. Success Metrics & Implementation Tracking
Phase 1 Achievements ✅ FOUNDATION DELIVERED
- Person Management Foundation: Public/private identity, roles, capability metadata, Agent↔Person mapping, and devices
- Resource Management Foundation: ResourceSpecification/EconomicResource CRUD plus NDO Layer 0 lifecycle
- Governance Foundation: Validation infrastructure, EconomicEvents, and cross-zome validation helpers
- Governance-as-Operator: Request→Evaluate→Apply path and typed rule evaluation are still outstanding
- Modular Architecture: Clean separation of concerns across all three zomes
- Active Sweettest suites: Core Nondominium, Lobby, and Group DNA integration coverage
- Coverage completion: PPR, capability/device, promotion, ignored Agreement/Contribution, and partially stubbed governance workflows
- Error Handling: Robust error types and proper DHT signal handling
Phase 2 Targets 🎯 GOVERNANCE & PROCESSES
- Enhanced Private Data Sharing: Direct field-level grants are prototyped; complete request/approval, expiry enforcement, mock-path removal, audit, and workflow tests
- Economic Process Infrastructure: Four structured processes (Use, Transport, Storage, Repair) with role-based access
- PPR Reputation System: Prototype structures/APIs are implemented; complete authenticated bilateral exchange, privacy-model hardening, and automatic workflow issuance
- Agent Capability Progression: Complete Simple → Accountable → Primary Accountable Agent advancement
- Cross-Zome Integration: Implement and harden the Request→Evaluate→Apply Governance-as-Operator path
- Validation Workflows: Existing validation APIs must become fully authorized and connected to resource access, promotion, and specialized roles
Phase 3 Targets 🔒 PRODUCTION SECURITY
- Progressive Capability Security: Automatic capability token progression based on PPR milestones
- Economic Process Access Control: Role-validated access to specialized processes with reputation influence
- Transaction Consistency: Atomic operations across all three zomes with comprehensive rollback
- Advanced Validation Schemes: PPR-weighted validator selection and reputation-based consensus
- Dispute Resolution: Edge-based conflict resolution with PPR context and private data coordination
Phase 4 Targets 🌐 NETWORK MATURITY
- Advanced Process Workflows: Multi-step process chaining with automated agent selection
- AI-Enhanced Reputation: Machine learning-based trust prediction and context-aware weighting
- Cross-Network Integration: PPR portability and federated identity management
- Performance Optimization: Large-scale network operation with predictive scaling
- Community Governance: Reputation-weighted validation and automated role progression
9. UI Development Plan 🎨
Current Frontend Status
- MVP UI: ✅ Implemented — persistent Lobby sidebar + Group panel + NDO detail page with full NDO lifecycle management, Join NDO placeholder ("Coming soon"), Associate with group modal, multi-member group invites + DHT member lists + reactive join + idempotent membership self-heal (
ensureMembership), pull-based reactivity for shared-group items (tab focus + gentle poll;TODO(signals)for push), fork friction modal, and reliable NDO data display via cache + DHT refresh - NDO tabs: Resources, Governance, and Activity render current data; Composition remains a placeholder
- PropertyRegime: ✅ Seven canonical regimes (
Private,Commons,Collective,Pool,CommonPool,Public,Nondominium) in Rust and fully exposed in frontend shared types, schemas, creation controls, filters, and badges. Regime-driven governance enforcement is Phase B (see §12.8). - Stack: SvelteKit 2 + Svelte 5 runes + TypeScript + UnoCSS + Melt UI next-gen + Effect-TS
- Dev runtime: Browser (web) —
hc-spin/Electron superseded byscripts/launch-happ.mjs, which runs one Vite dev server per agent on consecutive ports (VITE_DEV_AGENT-pinned), writesui/static/hc-connection.json, and auto-opens a browser tab per agent (NO_OPEN=1to disable). Seeui_architecture.md §15 - Service Layer: ✅ Complete (PR #97 + MVP UI work) — all three zome services + NDO/Lobby services with Effect-TS
Context.Tag/Layer/E.genpattern - Architecture reference:
documentation/specifications/ui_architecture.md
Phase 1: Foundation UI ✅ COMPLETE
-
SvelteKit + UnoCSS + Melt UI next-gen: Fully scaffolded (see
vite.config.ts,uno.config.ts) - Effect-TS service layer: All three zome services + NdoService + LobbyService (PR #97 + MVP UI)
-
HolochainClientService:
wrapZomeCallWithErrorFactorypattern,Context.Taginjection
Phase 2: MVP UI — Lobby → Group → NDO 🔄 FOUNDATION IMPLEMENTED; GAPS TRACKED
Implements documentation/requirements/ui_design.md MVP section and reconciled requirements from GitHub Issue #102. Includes UI-restructure sprint that made the Lobby the persistent outer shell and fixed NDO data display.
Foundation (initial delivery)
-
Three-level identity model foundation:
LobbyUserProfile(localStorage),GroupMemberProfile(localStorage), and Person service/store wiring -
First-action Person creation: Enforce automatic
Personcreation on the agent's first DHT-active action in the UI flow -
Shared types foundation:
NdoInput,UpdateLifecycleStageInput,NdoTransitionHistoryEvent,LobbyUserProfile,GroupMemberProfile, extendedGroupDescriptorandNdoDescriptor -
PropertyRegime reconciliation: All seven canonical variants (
Private,Commons,Collective,Pool,CommonPool,Public,Nondominium) in frontend shared types, schemas, creation controls, filters, and display maps -
NDO service methods:
createNdo,updateLifecycleStage,getNdoTransitionHistory,getGroupNdoDescriptors,getLobbyNdoDescriptors—ndo.service.ts -
Resource service methods:
createNdo,getNdo(return type corrected toNondominiumIdentity | nullmatching RustOption<NondominiumIdentity>),updateLifecycleStage, filtered queries, history —resource.service.ts -
Lobby/Group service (Group + Lobby DNA):
getMyGroups,createGroup(clone cell →create_group→join_group→announce_group),joinGroup(clone cell +is_memberguard + best-effortjoin_group, gossip-retryfetchGroupProfileWithRetry+ invite-payload fallback for reactive sidebar;TODO(signals)),ensureMembership(idempotent membership self-heal so a joined agent always reconciles into the member list),generateInviteLink; only the Level 2GroupMemberProfilestays inlocalStorage—lobby.service.ts(Group DNA backend complete, PR #107) -
Shared-group pull reactivity:
group.store.refreshCurrentGroup()+GroupViewtab-focus/visibility + gentle ~8 s poll keep members/NDOs fresh as peers' changes gossip in, without a manual reload;loadGroupDatasilent mode avoids flicker. Push upgrade tracked asTODO(signals)(remote_signalfromzome_group) -
app.context:
lobbyUserProfilestate with localStorage hydration -
lobby.store:
activeFilters,filteredNdos,createGroup,joinGroup;loadLobby()now invoked from root layout -
group.store:
group,groupNdos,members,loadGroupData,refreshCurrentGroup,createNdo, andassociateNdoWithGroupbacked by Group-cellSoftLinkentries - ndo-cache.ts (new): in-memory descriptor cache keyed by hash; populated on card click to seed NDO page instantly
- UserProfileForm.svelte: Lobby profile create/edit, modal + page modes, nickname required
- GroupProfileModal.svelte: Per-group disclosure preferences (first visit only)
- NdoBrowser.svelte: Multi-select filter chips (LifecycleStage × ResourceNature × PropertyRegime); covers all seven regimes
-
NdoCard.svelte: Populates
ndo-cachebefore navigating to NDO page - NdoCreateModal.svelte: 5-field form (4-variant regime), uniqueness check, Effect-TS errors, navigation on success
- NdoIdentityLayer.svelte: Initiator profile link, lifecycle transition button (initiator-only), TransitionHistoryPanel; 4-variant regime color map
- LifecycleTransitionModal.svelte: Full state machine, Deprecated/Hibernating special cases
- TransitionHistoryPanel.svelte: Collapsible history panel with copy-to-clipboard
- ForkNdoModal.svelte: Informational fork friction modal, copy-pubkey CTA
-
AssociateNdoModal.svelte: multi-select modal of groups not already linked to this NDO; confirms via
associateNdoWithGroup, which creates a Group-cellSoftLink
UI-restructure sprint (persistent Lobby shell)
-
+layout.svelte(root):onMountinitialises agent key, callsloadLobby(), triggers first-time profile modal if no lobby profile exists — ensures sidebar data available on every route -
Sidebar.svelte(rewritten as LobbySidebar): Browse NDOs link, live groups list (/group/:id), inline "+ New Group" form, inline "→ Join Group" form, "My Profile / Edit profile" at bottom; global "New NDO" link removed (creation is group-scoped only) -
LobbyView.svelte(simplified): removed GroupSidebar and onMount data loading; renders page header + NdoBrowser only;$effectno longer assignsappContext.currentView = 'lobby'(that clobbered the NDO route when both Lobby and NDO views were reactive);currentViewis set where the routed page applies (e.g.NdoViewsets'ndo') -
GroupView.svelte: replacedonMountwith$effectso group name and NDO list reload correctly when navigating between groups via the sidebar -
NdoView.svelte(extended): NDO detail card (Description, Property Regime, Resource Nature, Lifecycle Stage, Created); loading skeleton; retry-able error banner; Join NDO placeholder (inline "Coming soon"); Associate with a group (always visible header button →AssociateNdoModal); Fork button (Holochain + agent connected); descriptor seeded fromndo-cache, refreshed from DHT in background;$effectthat setsselectedNdoIdmust decode into a localhashvariable — assigningselectedNdoId = specActionHashimmediately after mutating$state(specActionHash)created a self-referential dependency andeffect_update_depth_exceeded(broken header buttons); fixed by passing the localUint8Arrayreference only - NDO data tabs: Resources, Governance, and Activity render existing zome/service data
- Composition tab: Replace placeholder with hard-link/component/version graph data
- Join NDO: Implement backend membership and replace the current "Coming soon" UI
-
/group/[id]route:?createNdo=1query param still supported -
/ndo/newroute: redirects to active group or shows instruction screen
Phase 3: Service Layer (Post-MVP) 🏗️
-
PersonService extensions: Expose existing capability-grant/device APIs and add the new
DataAccessRequestapproval workflow - ResourceService: Economic Process initiation + state management + custody transfers
- GovernanceService: Expose the existing PPR prototype APIs, then support the completed bilateral workflow
- ProcessService: Economic Process lifecycle (initiate, track, complete, chain)
- ReputationService: PPR retrieval + selective disclosure
Phase 4: Store Architecture Extensions 📊
- PersonStore: Private data sharing + capability progression
- ProcessStore: Economic Process workflows + status tracking
- ReputationStore: PPR management + reputation calculation + selective sharing
- ValidationStore: Validation status + approval processes
Phase 5: Advanced UI Components 🖼️
- Person management components: Profile + private data sharing + role progression + reputation display (issue #8)
- Economic Process Workflows: Process initiation + tracking + completion + chaining interface (issues #28–#32)
- Governance & Validation Interface: Validation workflows + PPR generation + reputation context
- Role-Based Dynamic UI: Progressive capability unlocking + specialized process access
- Reputation Dashboard: PPR tracking + summaries + selective disclosure controls (issue #22)
Phase 6: Group DNA Backend & Post-MVP UI 🌐
-
Group DNA backend ✅ Complete for current scope (PR #107): cloned-cell
zome_group(4 entry types, 16 coordinator externs, 13 Sweettest cases);LobbyService/GroupServicecall the Group + Lobby DNAs directly (clone cells,announce_group,get_my_group, SoftLinks). Only the Level 2GroupMemberProfilepresentation choice remains inlocalStorage -
Push reactivity via Holochain signals (
TODO(signals)):zome_groupremote_signals members onjoin_group/create_soft_link/log_work; UI refreshesrefreshCurrentGroup()on those signals; the current pull layer (per-open reconcile + focus + poll) is kept only as an offline/missed-signal fallback. Design note indnas/group/zomes/coordinator/zome_group/src/lib.rs - NDO cell cloning: Per-NDO DHT, once Holochain cloning stabilises
- Fork submission flow: Claim, vote, and Unyt stake (after Unyt integration §12.2)
-
Moss WeApplet:
ui/src/we-applet.ts—search,getAssetInfo,openAsset(see §12.6)
10. Enhanced Roadmap & Future Enhancements
Immediate Development Priorities (Next 6 Months)
- Phase 2.1: Complete private-data request/approval, expiry enforcement, mock-path removal, audit, and tests on the grant prototype
- Phase 2.2: Economic Process infrastructure with four process types
- Phase 2.3: Complete authenticated bilateral PPR exchange, privacy-model hardening, and automatic issuance on the implemented prototype
- Governance-as-Operator: Implement the Request→Evaluate→Apply path, typed GovernanceRule evaluation, authorization hardening, and uniform event/PPR generation
- UI: ✅ Seven-variant PropertyRegime parity complete; next: Economic Process and PPR workflows
- PropertyRegime Phase B: Regime-driven governance enforcement (transfer-rights matrix, Nondominium/Public no-alienation guard, GovernanceDefaultsEngine) — see §12.8
Medium-Term Enhancements (6-18 Months)
- Phase 3: Production security with progressive capability tokens
- Phase 4.1: Advanced process workflows and automation
- NDO migration track (when scheduled): L0-first creation already exists; add retroactive anchoring for legacy specs, Layers 1/2 activation, operational state, and capability slots — Section 12.1 and REQ-NDO-MIG-*
- Source-NDO application profile (optional, when scheduled): Opt-in
SourceProfile, boundary events, adaptive stewardship — Section 12.7; only for applications whose domain requires it; not a dependency for Project or resource-sharing deployments - Cross-Network Integration: Federated nondominium networks with PPR portability
- Mobile Interface: Progressive Web App with full Economic Process support
Long-Term Vision (18+ Months)
- AI-Enhanced Governance: Machine learning-based validation and process optimization
- Interoperability: Deep integration with other ValueFlows and commons-based systems
- Network Federation: Multi-network reputation and resource sharing protocols
- Governance Evolution: Community-driven rule evolution with reputation-weighted decision making
Success Indicators
- Network Health: >1000 active agents with >90% successful Economic Process completion
- Reputation System: >80% agent participation in PPR system with meaningful reputation differentiation
- Process Efficiency: Average Economic Process completion time <24 hours with automated matching
- Community Governance: >70% community validation participation with dispute resolution <1% of transactions
- NDO readiness (when the track is active): new resources created via L0; legacy specs migrated without data loss; independent queries for lifecycle versus operational facets (REQ-NDO-MIG-01–MIG-05, REQ-NDO-OS-06)
11. Implementation Strategy Summary
This enhanced implementation plan transforms the nondominium hApp from a foundational resource management system into a comprehensive, production-ready ecosystem for decentralized commons governance. The plan:
MVP core (near-term)
- Ship user-visible flows in Section 5 Phases 2–4: private data access, four economic process types, PPR issuance and reputation summaries, promotion and specialized roles, capability hardening, and cross-zome consistency — measured against REQ-USER-, REQ-PROC-, and REQ-GOV-* in requirements.md.
Builds Incrementally on Existing Code
- Preserves all existing working functionality without breaking changes
- Extends current data structures and functions rather than replacing them
- Maintains backward compatibility while adding advanced features
Delivers Complete Economic Process Integration
- Four structured Economic Processes (Use, Transport, Storage, Repair) with role-based access
- Complete agent capability progression (Simple → Accountable → Primary Accountable Agent)
- Sophisticated cross-zome coordination ensuring atomic operations and consistency
Implements Privacy-Preserving Reputation
- Bi-directional Private Participation Receipts with cryptographic signatures
- Privacy-preserving reputation calculation with selective disclosure
- Performance metrics enabling quality assurance and trust without central authority
Ensures Production Readiness
- Progressive capability-based security with automatic token advancement
- Comprehensive error handling and rollback mechanisms across all zomes
- Advanced validation schemes with reputation-weighted consensus and dispute resolution
This plan ensures the nondominium hApp will fulfill its vision of decentralized, commons-based resource management with sophisticated governance, Economic Process management, privacy-preserving reputation tracking, and embedded accountability, in alignment with requirements.md and the remaining NDO work in ndo_prima_materia.md.
NDO track (when prioritized)
- Build from implemented Layer 0 into Layer 1/2 activation, legacy migration, and capability surfaces without breaking existing MVP flows (REQ-NDO-MIG-*).
- Preserve governance-as-operator invariants while splitting lifecycle and operational dimensions (REQ-ARCH-07, REQ-NDO-LC-02, REQ-NDO-OS-02).
Source-NDO application profile (optional — when domain requires it)
- Implement as opt-in profile modules per REQ-SOURCE-APP-*; do not block Project NDO or resource-mutualisation delivery on Source phases (§12.7).
- Default hApp and UI remain Agent + Resource complete; ecological/knowledge-commons deployments enable the profile explicitly.
12. Post-MVP design tracks (NDO, integrations, extensions)
Status: This section mixes implemented post-MVP foundations with unscheduled design tracks. Checked items are present in the current WASM/UI; unchecked items remain specifications until scheduled. Normative NDO requirements: ndo_prima_materia.md (§9 REQ-NDO-*, §10 migration). Integration stubs: unyt-integration.md, flowsta-integration.md. Supplementary ontology context: requirements/resources.md, requirements/agent.md, requirements/governance.md.
12.1 Generic NDO (three-layer model, lifecycle split)
-
Implement
NondominiumIdentityLayer 0 with permanent identity, sevenPropertyRegimevariants, fiveResourceNaturevariants, lifecycle metadata, and validated updates. -
Implement
LifecycleStageand Layer 0 discovery facets (NdoByLifecycleStage,NdoByNature,NdoByPropertyRegime). -
Add
NDOToSpecification,NDOToProcess, holonic links beyond the implemented federation primitives, and theCapabilitySlotsurface. -
Replace legacy
ResourceStatewithOperationalStateonEconomicResourceandResourcesByOperationalStatediscovery (REQ-NDO-OS-01,REQ-NDO-OS-06). - Integrate lifecycle transitions with Governance-as-Operator, required EconomicEvents, role authorization, and EndOfLife challenge periods.
- Implement retroactive anchoring/migration for legacy ResourceSpecifications (REQ-NDO-MIG-*).
12.1.1 PropertyRegime Phase B — regime-driven governance (post Phase A)
Phase A (complete): seven-variant enum + semantic helpers on nondominium_shared::PropertyRegime (is_rivalrous, permits_ownership_transfer, is_uncapturable, default_accessibility) + full UI/doc parity.
Phase B (tracked — not yet implemented; zome_gouvernance currently has zero PropertyRegime references):
-
Enforce the transfer-rights matrix per regime (ownership vs custody vs use vs benefit) —
resources.md§4.4.5 -
NondominiumandPublicno-alienation guard: reject ownership-changingTransfer/ ownership-assertingGovernanceRules; allowTransferCustody -
GovernanceDefaultsEngine: derive defaultGovernanceRuletemplates fromPropertyRegime×ResourceNature(× Rivalry when modelled) —resources.md§6.6 -
Wire into the governance-as-operator path (
request_resource_transition/evaluate_state_transition)
12.2 Unyt integration (three phases, parallel to prima materia §6.6)
-
Phase 1 — Capability surface:
UnytAgreementSlotType; Tier 1 proposals on NDO identity hashes (REQ-NDO-CS-07,REQ-NDO-CS-08). -
Phase 2 — Governance rules: typed
EconomicAgreementonGovernanceRule/GovernanceRuleType(REQ-NDO-CS-09); zome_resource / integrity changes only. -
Phase 3 — Governance zome:
evaluate_transition_requestrequires validrave_hashwhen rules trigger; cross-cell RAVE validation; PPRsettlement_rave_hash(REQ-NDO-CS-10,REQ-NDO-CS-11).
12.3 Flowsta integration (three phases, parallel to prima materia §6.7)
-
Phase 1 — DNA + slots:
FlowstaIdentityinSlotType; bundleflowsta-agent-linkingintegrity + coordinator zomes; Tier 1 linking only (REQ-NDO-CS-12,REQ-NDO-CS-13). - Phase 2 — UI / Vault UX: link flows, DID display, Vault backup APIs — see flowsta-integration.md §6.
-
Phase 3 — Governance enforcement:
IdentityVerification(or equivalent) + REQ-NDO-CS-15 checks in transition evaluation (REQ-NDO-CS-14); fold into same operator story as Unyt Phase 3.
12.4 Agent capability surface (G15)
-
Personentry hash as stigmergic attachment point forFlowstaIdentityand future slots (REQ-NDO-AGENT-07,REQ-AGENT-11) — see requirements/agent.md §3.2, person_zome.md Person TODO.
12.5 Extended post-MVP specifications
High-level ordering and dependencies (detailed requirements live in each file):
- many-to-many-flows.md: Shared custody and n-ary
EconomicEvent/Commitmentparticipants — plan after AgentContext / collective custodianship (Phase 3 agent ontology) stabilizes; PPR rules must be extended for multi-party flows. - ndo-versioning.md: DAG of versions across material, digital, and app-as-resource — complements REQ-NDO-L1-03 (multiple
ResourceSpecificationlinks per NDO); non-breaking addition over existing spec/resource entries. - digital-resource-integrity.md: Content-addressed manifests and hierarchical verification — attach via Layer 1 DigitalAsset capability slots (prima materia §9.2); aligns with distributed storage expectations for specs.
- resource-transport-flow-protocol.md: Multi-dimensional transport and flow semantics — builds on mature EconomicEvent metadata and process modeling; cross-link to operational state and RTP-style location/custody dimensions.
- valueflows-dsl.md: Scriptable network bootstrap and recipe definition — operational tooling; depends on stable VF entry types and governance evaluation surfaces in the DNA.
- source-ndo-requirements.md: Optional
Sourceapplication profile; progressive activation per REQ-SOURCE-APP-* — see §12.7; PRD anchor requirements.md §4.6 - lobby-dna.md: Federation foundation is implemented; remaining Moss, push-signal, per-NDO-cell, and integration work is tracked in §12.6.
12.6 Lobby DNA — multi-network federation
Requirements: lobby-dna.md (REQ-LOBBY-, REQ-GROUP-, REQ-NDO-EXT-*) Architecture: specifications/lobby-architecture.md
Two implementation sub-scopes with different delivery ordering:
Implemented federation foundation:
-
Lobby DNA:
zome_lobby_integrity+zome_lobby_coordinator—LobbyAgentProfile,GroupAnnouncement, discovery/update links, 9 coordinator externs, and 5 Sweettest scenarios -
Group DNA: isolated cloned cells with
GroupProfile,GroupMembership,WorkLog, andSoftLink; 16 coordinator externs and 13 Sweettest scenarios -
happ.yamlroles for fixed Lobby, core Nondominium, bundled hREA, and deferred Group cloning (clone_limit: 64) - Frontend Group clone provisioning, invites, Lobby announcement, DHT membership reconciliation, SoftLink-based NDO association, and pull reactivity
-
NdoHardLinkentry type +NdoToHardLinks/HardLinkByTypelink types — immutable, requires valid EconomicEvent fulfillment (REQ-NDO-EXT-01–06)- Stage 2 (pre-Lobby, single cell):
to_ndo_dna_hashequals the shared DNA hash (same cell for source and target). Stage 3 (per-NDO clone):to_ndo_dna_hashis the target cell's unique hash. Same struct, no breaking change. See lobby-architecture.md §6.1.
- Stage 2 (pre-Lobby, single cell):
-
Contributionentry type +NdoToContributions/AgentToContributions/ContributionToEventlink types — peer-validated Work/Modify contributions (REQ-NDO-EXT-07–11) -
Agreemententry type +NdoToAgreement/AgreementUpdateslink types — versioned benefit-redistribution clauses (REQ-NDO-EXT-12–16) - Note: federation Sweettests are partial — hard-link coverage is active; Agreement and Contribution scenarios are currently ignored.
Remaining federation work:
-
Push reactivity through Group
remote_signal, retaining focus/poll as an offline fallback -
Moss WeApplet contract (
ui/src/we-applet.ts) —search,getAssetInfo,openAsset - Per-NDO cloned cells and cross-cell hard-link operation when that deployment model is adopted
- Full version DAG and upstream contribution/benefit propagation
- Unyt activation of monetary Agreement clauses and Flowsta cross-app identity mapping
- Activate ignored Agreement/Contribution Sweettests and any missing AccountableAgent setup they require
Dependencies for the remaining work:
- Implementation of Governance-as-Operator Request→Evaluate→Apply for uniform typed rule and authorization checks
- Unyt integration (§12.2) for monetary Agreement execution
- Flowsta Phase 3 (§12.3) for cross-app identity attestations (REQ-LOBBY-INT-01)
12.7 Source-NDO — optional generative-commons application profile (post-MVP)
Normative requirements: source-ndo-requirements.md (REQ-SOURCE-); applicability and UI gating: requirements.md §4.6 (REQ-SOURCE-APP-01 – -04, REQ-UI-SOURCE-). Academic grounding: source-ndo-paper.md. Sibling NDO type (no Source required): project-type-ndo-specifications.md.
Profile boundary (dynamic complexity matching): The generic NDO baseline is Agent + Resource. Source is an opt-in application profile, not a mandatory third primitive in every hApp or NDO UI. Communities enable it only when coordination must govern a generative system's condition, boundary flows, regeneration, or assimilation capacity.
| Normally enable Source | Normally do not enable Source |
|---|---|
| Governance targets a resource system (watershed, river, fishery) not just appropriable units | Project NDO coordinating open-hardware design — Agents + Resources suffice |
| Extraction, loading, or regeneration must be visible on-ledger against the system | Mature-resource mutualisation (e.g. shared 3D printer) — custody, access, maintenance, Resource events suffice |
| Adaptive stewardship must respond to accumulated condition signals | No generative Source boundary is being governed (provenance from nature alone ≠ Source activation) |
REQ-SOURCE-APP checklist (implementation):
- Profile flag / membrane config: Application or DNA profile declares Source support enabled (REQ-SOURCE-APP-01)
- Complexity-matched code paths: Default flows complete with Agent/Resource only; Source zome modules and APIs load only when profile is on (REQ-SOURCE-APP-02, REQ-SOURCE-APP-04)
-
No universal UI burden: Default
REQ-UI-NDO-01creation form and Project/resource detail views unchanged when profile is off — no Source type selectors, regime panels, or steward workflows (REQ-SOURCE-APP-03, REQ-UI-SOURCE-01)
Problem addressed (when profile is on): ValueFlows models Agent and Resource. A watershed, river, forest, or knowledge commons fits neither honestly — forcing a river into EconomicResource implies ownership (primaryAccountable); avoiding it hides depletion via raise; typing it as Agent for pollution receivers imports false agency. Source is the third flow endpoint for those domains only: generative, non-ownable, partially unknowable systems that yield resources, absorb effects, and carry adaptive governance.
Ostrom / SES mapping (operationalised):
| SES concept | Source-NDO |
|---|---|
| Resource system | Source (SourceProfile on Layer 0) |
| Resource unit | EconomicResource |
| Governance system | GovernanceRule + adaptive loop (requirements §6.6) |
| Users / actors | Agents (+ Steward functional role, profile-only) |
Layer model: Same three layers as all NDOs. Layer 0 = NondominiumIdentity + linked SourceProfile. Layer 1 = SourceSpecification. Layer 2 = boundary EconomicEvents, commitments, claims, PPRs. property_regime SHALL be Nondominium or CommonPool only (REQ-SOURCE-ONT-02, REQ-SOURCE-GOV-02).
ValueFlows extension: Add vf:Source in Source-enabled applications so flows may originate from and terminate in Sources (REQ-SOURCE-EVENT-01 – -03).
Adaptive governance loop (profile Phase C+; beyond static rule evaluation):
boundary events → ledger on Source L0 hash → ecological interpretation
→ governance rule revision → access affordances → conditioned future events
Black-box stance: govern observable boundary signals and SourceRegimeState transitions; do not model ecological interiors (REQ-SOURCE-GOV-01 – -08).
Implementation phasing (from source-ndo-requirements.md §9; all phases assume profile enabled):
| Phase | Deliverable | Depends on |
|---|---|---|
| A — Data model | SourceProfile, SourceType, SourceRegimeState, SourceCouplingLink; Layer 0 ↔ SourceProfile link; Steward role (profile-only) | NDO Layer 0 ✅; REQ-SOURCE-APP-04 |
| B — Boundary events | vf:Source on EconomicEvent; extraction, loading, use, regeneration; governance-validated stock/assimilation updates | Phase A; VfAction vocabulary ✅ |
| C — Adaptive governance | Access-affordance rules; SourceRegimeState transitions; precautionary block at tipping_threshold; monitoring-obligation GovernanceRule type | Governance-as-Operator ❌; Phase B |
| D — Layer 1 value + PPR | Ecological value vector on SourceSpecification; stewardship PPR categories | PPR prototype 🔄; Phase C |
| E — Federation | Cross-DNA source hierarchies; federation-level source governance | Lobby/Group/federation ✅; Phase C |
Zome touchpoints (profile-only modules — do not alter default Agent/Resource paths):
zome_resource:SourceProfile, coupling links, opt-in Source-NDO creation API (separate from genericcreate_ndo)zome_gouvernance: Source-as-provider/receiver onEconomicEvent; regime-driven evaluation; ledger queries by Source L0 hashzome_person:StewardinRoleTypewhen profile enabled (REQ-SOURCE-GOV-07)
UI (Source-enabled applications only — REQ-UI-SOURCE-*):
-
Distinct Source-NDO creation variant (
Nondominium/CommonPool,SourceType, stewards); generic form unchanged when profile off - Source detail panels (regime state, condition indicators, stewards, boundary-event history) — omitted from Project/resource mutualisation views
- Source hierarchy / coupling visualization (Composition tab extension, profile apps)
- Steward dashboard (monitoring obligations, regime transitions, access-affordance proposals)
REQ traceability: REQ-SOURCE-APP-01 – -04 (profile), REQ-SOURCE-ONT-01 – -04, REQ-SOURCE-DATA-01 – -03, REQ-SOURCE-GOV-01 – -08, REQ-SOURCE-EVENT-01 – -03, REQ-USER-ST-01 – -09, REQ-UI-SOURCE-01 – -04. Does not modify REQ-NDO-* invariants or require existing NDOs to migrate.
Dependencies:
- NDO Layer 0 and lifecycle facets ✅
- Governance-as-Operator Request→Evaluate→Apply path ❌ (blocks full Phase C)
- Typed
GovernanceRuleevaluation ❌ - PPR authenticated bilateral workflow ❌ (Phase D)
- Seven-regime
PropertyRegimeUI parity ✅ (Source variant still needsNondominium/CommonPoolwhen profile on) - Explicit non-dependency: Project NDO track, resource mutualisation, and MVP UI completion do not require Source phases A–E
13. Open questions / research
- Coordination economics: How do the NDO model and the nondominium hApp mitigate coordination costs, communication overhead, and free-rider dynamics? See design rationale in ndo_prima_materia.md §2 (complexity economics, pay-as-you-grow layers) and COP/testing notes in §3.
nondominium Implementation Status
Overview
nondominium is a Holochain hApp implementing ValueFlows-compliant resource sharing with embedded governance and a Private Participation Receipt (PPR) reputation system.
This document tracks what is actually implemented and verified in the current codebase. Claims are grounded in code, not design documents.
Architecture Overview
Technology Stack
Canonical list: README.md § Technology Stack. Summary:
- Backend: Rust (Holochain HDK ^0.6.0 / HDI ^0.7.0), compiled to WASM
- Frontend: SvelteKit 2 + Svelte 5 + TypeScript + Vite 7 + UnoCSS + Melt UI next-gen + Effect-TS
- Testing: Sweettest (Rust, primary) — Tryorama (TypeScript) is deprecated
- Client: @holochain/client ^0.20.0 (UI); ^0.19.1 (root dev tooling)
Multi-DNA hApp Architecture
The packaged hApp declares five roles in workdir/happ.yaml:
lobby— fixed, permissionless federation DHT for Lobby profiles and Group discoverynondominium— the core NDO DNA, containing:zome_person— Agent identity, profiles, roles, capabilities, and deviceszome_resource— specifications, inventoried resources, governance-rule data, and NDO Layer 0zome_gouvernance— events, commitments, claims, validation, PPR prototypes, and federation extensions
hrea— bundled hREA DNA used by the Person/ReaAgent bridgegroup— deferred template role; each Group is provisioned as an isolated cloned cell (clone_limit: 64)ndo— deferred template role; each NDO is provisioned as an isolated cloned cell (clone_limit: 512, ADR-010/ADR-013)
Each local DNA domain follows the integrity/coordinator pattern; the Lobby and Group DNAs carry their own zomes (zome_lobby_coordinator, zome_group). The core Nondominium domain remains a three-zome architecture, but the installed hApp is a multi-DNA system. See ARCHITECTURE_COMPONENTS.md and zomes/architecture_overview.md.
Status Terminology
- Complete — implemented end-to-end for the stated scope and covered by active tests
- Implemented — working code/API exists, but may not be exposed in every UI
- Partial / prototype — code exists, but contains placeholders, incomplete workflow integration, or limited tests
- Not implemented — no operational implementation exists
Core Backend
Person Management 🔄 Core implemented; workflows partial
- Public Profiles:
Personentries with name, avatar, and bio - Private Data: private
PrivatePersonDataentries with legal name, email, phone, address, emergency contact, time zone, and location - Role-Based Access:
PersonRoleassignments —SimpleAgent,AccountableAgent,PrimaryAccountableAgent,Transport,Repair,Storage - Agent-to-Person Mapping: bidirectional Agent↔Person links supporting multiple agent keys per Person
- Profile APIs: create, update, latest-version resolution, global discovery, current-agent profile, and composed Person profile queries
Capability-Based Access Control 🔄 Prototype
- Capability Grants: Holochain capability grants plus
PrivateDataCapabilityMetadatawith field-level allowlists, context, expiry, and local capability secret - Filtered Data Access:
FilteredPrivateDataresponse views - Field-Level Control: Granular permissions for email, phone, location, time_zone, emergency_contact, address
- Time-Based Expiration: callable grants accept arbitrary
expires_in_days(default 7); role-based defaults top out at 30 days, but there is no global hard maximum enforcement - Implemented APIs:
grant_private_data_access,create_private_data_cap_claim,get_private_data_with_capability,revoke_private_data_access, owned/role-based/transferable grant helpers, and governance-oriented private-data validation - Prototype limitations: retrieval still contains mock/fallback paths for test situations, and comprehensive active Sweettests are missing
Multi-Device Support ✅ Implemented
Deviceentries withActive,Inactive, andRevokedstatusAgentPersonRelationshipentries withPrimary,Secondary, andDevicerelationship types- Device registration, per-Person and current-agent discovery, device lookup, activity updates, and deactivation
- Device and relationship integrity validation and bidirectional Person/device links
Partial or not yet implemented (person domain)
- Private data access request/approval workflow (#40)
- Audit trail for private data access events (#38)
get_expiring_grants()for proactive grant lifecycle management (#37)- Full agent promotion workflow (#33): promotion and approval externs exist, but
request_role_promotionstill returns a placeholder hash instead of a queryable request entry - Specialized role validation (#34): the governance extern exists but currently auto-approves and contains Phase 2 authorization/credential TODOs
- Complete active Sweettest coverage for capability sharing, roles, devices, and promotion workflows
Resource Management
Resource Specifications ✅
ResourceSpecificationentries with name, description, category- Tag-based discovery, governance rule linking, active/inactive status
Economic Resources ✅ Data model and CRUD implemented
EconomicResourceentries conforming to specifications- Quantity tracking with units, custodian assignment, location metadata
OperationalStateonEconomicResource:PendingValidation,Available,Reserved,InTransit,InStorage,InMaintenance,InUse(REQ-NDO-OS-01 ✅ data layer)- Creation, updates, latest-version resolution, queries by specification/custodian/operational state, first-resource checks, custody transfer, and
update_operational_state/get_resources_by_operational_stateAPIs
Note: Lifecycle maturity lives on
NondominiumIdentity(LifecycleStage). Process condition lives onEconomicResource(operational_state). Governance-zome ownership of operational transitions (REQ-NDO-OS-02/03) remains deferred.
Governance Rules 🔄 Persistence implemented; enforcement pending
GovernanceRuleCRUD, update chains, type discovery, and specification attachment- Extensible
rule_type, JSON-encodedrule_data, and optionalenforced_byrole metadata - Rule semantics are not yet evaluated programmatically; update integrity validation remains permissive pending Governance-as-Operator
NDO Layer 0 — Identity Anchor ✅
NondominiumIdentity provides a permanent identity anchor for any resource from conception through end-of-life. Implemented in PR #80.
- Entry type:
NondominiumIdentitywithname,initiator,property_regime,resource_nature,lifecycle_stage,created_at,description,successor_ndo_hash, andhibernation_origin - LifecycleStage: 10 stages — Ideation → Specification → Development → Prototype → Stable → Distributed → Active → Hibernating → Deprecated → EndOfLife
- PropertyRegime: 7 canonical variants —
Private,Commons,Collective,Pool,CommonPool,Public,Nondominium - ResourceNature: 5 variants —
Physical,Digital,Service,Hybrid,Information - Immutability: identity fields are permanent;
lifecycle_stagechanges through the validated state machine,successor_ndo_hashis set once on deprecation, andhibernation_originis set/cleared during suspension/resumption; deletes are always invalid - Authorization: Only the
initiatormay callupdate_lifecycle_stage(MVP simplification; full role-based authorization per REQ-NDO-LC-07 deferred to governance zome integration) - Discovery links:
AllNdos(global"ndo_identities"path anchor),AgentToNdo(per-initiator),NdoByLifecycleStage/NdoByNature/NdoByPropertyRegime(categorization anchors — PR #84) - API:
create_ndo,get_ndo(resolves update chain),get_all_ndos(global anchor traversal),get_my_ndos(resolved entries),update_lifecycle_stage,get_ndos_by_lifecycle_stage,get_ndos_by_nature,get_ndos_by_property_regime(PR #84) - REQ coverage: Layer 0 creation, permanence, lifecycle validation, and facet links are implemented. Link-level integrity hardening remains pending for categorization links. Also pending: required transition EconomicEvents, Governance-as-Operator evaluation, automatic event generation, EndOfLife challenge periods, and role-based lifecycle authorization.
Discovery and Query Patterns ✅
- Anchors:
AllResourceSpecifications,AllEconomicResources,AllGovernanceRules - Hierarchical links: Specification → Resource, Custodian → Resources
- Category-based, location-based, and state-based query support
ValueFlows and Governance Backend
ValueFlows Economic Framework
Action Vocabulary ✅
Standard ValueFlows actions (Transfer, Move, Use, Consume, Produce, Work, Modify, Combine, Separate, Raise, Lower, Cite, Accept) plus nondominium extensions (InitialTransfer, AccessForUse, TransferCustody).
Economic Events ✅ Entry/API implemented
EconomicEventcreation and retrieval with provider/receiver, resource references, quantity, timestamp, and optional note- Queries by Agent and EconomicResource
Commitments & Claims ✅ Entry/API implemented
- Future economic commitments with due dates
Claimentries for fulfillment tracking- Commitment proposal/acceptance and Claim creation/retrieval APIs
- Links from Agents/resources to Commitments and from Commitments to Claims
Economic Processes ❌ Not implemented end-to-end
Use, Transport, Storage, and Repair process workflows are specified but not implemented as EconomicProcess entries or coordinated state machines. Existing VfAction, Commitment, EconomicEvent, resource transition, and WorkLog primitives do not yet form these workflows. Tracked in #28, #29, #31, #32.
PPR Reputation System
Data Structures ✅
16 ParticipationClaimType variants are defined in zome_gouvernance/src/ppr.rs:
- Genesis:
ResourceCreation,ResourceValidation - Custody:
CustodyTransfer,CustodyAcceptance - Services:
MaintenanceCommitmentAccepted,MaintenanceFulfillmentCompleted,StorageCommitmentAccepted,StorageFulfillmentCompleted,TransportCommitmentAccepted,TransportFulfillmentCompleted,GoodFaithTransfer - Governance:
DisputeResolutionParticipation,ValidationActivity,RuleCompliance - End-of-Life:
EndOfLifeDeclaration,EndOfLifeValidation
Performance score fields (timeliness, quality, reliability, communication, satisfaction) and ReputationSummary struct with category breakdowns are implemented.
Cryptographic Authentication 🔄 Prototype
Signature structures, signed-data hashing, timestamp checks, score-range validation, and signer checks exist. However, issue_participation_receipts currently inserts a placeholder counterparty signature. The counterparty must subsequently call sign_participation_claim; this is not yet a fully authenticated, atomic bilateral issuance flow.
Implemented PPR coordinator surface 🔄
issue_participation_receiptssign_participation_claimvalidate_participation_claim_signaturevalidate_participation_claim_signature_enhancedget_my_participation_claimsderive_reputation_summary
These are operational prototypes. Claim discovery uses DHT links (AgentToPrivateParticipationClaims and related links), despite the broader design goal that PPRs remain private and unlinked. derive_reputation_summary summarizes only the calling agent's local linked receipts.
Not yet implemented (PPR domain)
- Fully authenticated bilateral issuance without placeholder signatures (#14)
- Privacy-preserving storage without DHT discovery links to private claim action hashes
- Automatic guaranteed PPR issuance for every Commitment→EconomicEvent→Claim cycle
- Complete genesis role and custody receipt workflows (#15, #16)
- End-of-life management with multi-validator security (#18)
- Challenge period mechanism for EOL declarations (#19)
- Historical review system for EOL abuse prevention (#20)
- Production-grade reputation sharing/verification workflow; the local
derive_reputation_summaryfunction exists, but portable or third-party-verifiable summaries do not
Governance and Validation 🔄 Partial
ValidationReceiptandResourceValidationentry types- Resource, process-event, process-completion, agent-identity, and specialized-role validation externs
- Multi-reviewer status tracking and validation history queries
- Person↔governance private-data validation helpers
Several checks are still simplified or stubbed: specialized-role validation auto-approves, authorization is incomplete in places, and event/PPR generation is not uniformly automatic. GovernanceRule classification semantics are now enforced (see below); per-rule runtime conditions are not.
Governance-as-Operator Architecture 🔄 Evaluate side implemented; Request side not wired
GovernanceTransitionRequest, TransitionContext, and GovernanceTransitionResult are defined in crates/shared/src/io/governance.rs, and evaluate_state_transition is a live #[hdk_extern] in zome_gouvernance/src/transition.rs (#132). It evaluates the Hard and Soft classification constraints from crates/shared/src/constraints.rs and returns advisory warnings plus structured soft_violations for UI dry-run parity.
Two pieces of the documented architecture are still absent: request_resource_transition (the resource-zome-side entry point) and evaluate_governance_transition. The evaluation path is therefore parallel and advisory rather than the mandatory funnel — propose_commitment and log_economic_event still write directly, with their own inline constraint checks, instead of routing through the operator. GovernanceTransitionResult.economic_event_hash is always None on this path because event generation is not yet wired. Tracked in #41–#44.
Lobby DNA ✅ Implemented
Purpose and Data Model
The Lobby is a fixed, permissionless DHT used as the federation entry point. It does not store NDO announcements directly.
LobbyAgentProfile—handle, optionalavatar_url, optionalbio,lobby_pubkey, andcreated_atGroupAnnouncement—group_name,group_dna_hash,network_seed, optionaldescription, andregistered_by(no stored announcement timestamp)- Discovery/update links:
AllLobbyAgents,AgentToLobbyProfile,AgentProfileUpdates,AllGroupAnnouncements, andAgentToGroupAnnouncements get_group_announcement_by_dna_hashscans the global announcement anchor; there is no dedicated DNA-hash→announcement link type
Coordinator API (9 externs)
init, upsert_lobby_agent_profile, get_lobby_agent_profile, get_all_lobby_agents, announce_group, get_all_group_announcements, get_my_group_announcements, get_group_announcement_by_dna_hash, get_my_groups
get_my_groups is a lightweight Lobby-side descriptor query over announcements. In the frontend, LobbyService.getMyGroups() instead enumerates the conductor's Group clone cells and calls each cell's get_my_group, because local clone-cell installation is the authoritative source for Groups the current agent has joined.
Sweettest Coverage
5 active scenarios in dnas/lobby/tests/src/lobby/mod.rs, covering profile create/update/discovery and Group announcement discovery/deduplication behavior.
Packaging
lobbyrole inworkdir/happ.yaml- Lobby integrity/coordinator WASM included in the hApp build
- Separate
lobby_sweettestpackage - Moss applet metadata in
workdir/moss.yaml
Group DNA ✅ Backend complete for current scope (PR #107)
DNA Architecture
Group cells use the cloned-cell pattern: a single Group DNA template is installed with the hApp (deferred: true in workdir/happ.yaml). Each new group provisions its own DHT via clone_cell, giving full network isolation between groups. clone_limit: 64 is the hard per-conductor ceiling.
Entry Types
GroupProfile— group name and optional description; one logical profile per cloned cellGroupMembership— agent membership record; links removed on leave, entry retained as audit trailWorkLog— planning-level contribution record (no PPRs; ADR-GROUP-04)SoftLink— planning-level link to an NDO (no PPRs; ADR-GROUP-04). No longer used for NDO association — superseded byNdoAnchor; retained for future planning-level linksNdoAnchor— the authoritative group→NDO pointer (ADR-011): full clone coordinates (ndo_dna_hash,network_seed,identity_action_hash) plus cached card fields. Onlyname/description/lifecycle_stageare mutable; integrity rejects an update that rewrites any identity coordinate
Coordinator API (20 externs)
init, create_group, get_group, update_group, get_my_group, join_group, leave_group, get_group_members, is_member, log_work, delete_work_log, get_work_logs, get_my_work_logs, create_soft_link, delete_soft_link, get_soft_links, create_ndo_anchor, get_ndo_anchors, update_ndo_anchor, refresh_ndo_anchor_lifecycle_stage
There is no get_all_groups extern in a Group cell; each cell represents one isolated Group. Cross-Group discovery belongs to the Lobby DNA.
Sweettest Coverage
13 test scenarios in dnas/group/tests/src/group/mod.rs: group creation, discovery, membership (join/leave/is_member/duplicate-join guard), work logs (group + per-agent query), soft links, get_my_group, update_group, and validation rejection cases (empty name, zero hours).
Shared Crate
GroupError added to crates/shared/src/errors.rs (gated behind coordinator feature), re-exported from crates/shared/src/lib.rs.
UI Service Layer
ui/src/lib/services/zomes/group.service.ts targets cloned cells and exposes the subset currently needed by the UI: Group lookup, members, WorkLog queries, and SoftLink queries/creation. The backend's update/delete and work-entry functions are not all surfaced through this service yet.
WorkLogFeed.svelte and SoftLinkList.svelte exist as early components, but are not currently integrated into GroupView; the visible Group page focuses on members and Group-associated NDOs.
NDO Federation Extensions ✅ Implemented (PR #103)
The governance zome includes three additional public entry families:
NdoHardLink— typed cross-NDO/cross-DNA links (Component,DerivedFrom,Supersedes) backed by an EconomicEvent fulfillment hashContribution— peer-validatedWork/Modifycontributions with optional effort and cross-DNA WorkLog referencesAgreement— versioned benefit-redistribution clauses with Primary Accountable Agent authorization
Implemented coordinator APIs:
- Hard links:
create_ndo_hard_link,get_ndo_hard_links,get_ndo_hard_link,get_ndo_hard_links_by_type - Contributions:
validate_contribution,get_ndo_contributions,get_agent_contributions,get_contribution - Agreements:
create_agreement,update_agreement,get_current_agreement,get_agreement
These are Nondominium-native federation primitives. They are not yet a full version DAG, automatic upstream benefit propagation, or Unyt Smart Agreement/RAVE integration. Sweettest coverage is partial: the hard-link scenario is active; Agreement and Contribution scenarios currently use #[ignore].
hREA Dual-DNA Integration
Phase 1: Complete ✅
- hREA git submodule (
vendor/hrea, Sensorica fork) happ.yamldual-DNA roles configuration- hREA DNA compiled and included in
.webhappbundle hrea_agent_hashfield added toPersonintegrity entrycreate_rea_agentbridge call inzome_personcoordinatorcreate_personcreates aReaAgentin hREA first- Cross-DNA validation tests in Sweettest
Phases 2–4: Not started ❌
Resource lifecycle, governance/PPR wiring, and production hardening via hREA are tracked under epic #47.
Frontend
Infrastructure ✅
- SvelteKit + UnoCSS + Melt UI next-gen project scaffolded (
vite.config.ts,svelte.config.js,uno.config.ts) HolochainProvider.svelte— Holochain client connection management- Effect-TS service layer (PR #97): all three zome services and stores converted to
Context.Tag/Layer/E.genpattern withisLoading+errorMessagestate wrapZomeCallWithErrorFactoryutility for consistent zome call error handling
MVP UI — Lobby → Group → NDO ✅ Implemented
Full three-level hierarchical UI as specified in documentation/requirements/ui_design.md (MVP section) and documentation/specifications/ui_architecture.md. Lobby and Group presentation layers are wired. Automatic Person creation on the agent's first DHT-active action is not currently enforced by the UI. The UI was substantially restructured in the UI-restructure sprint to make the Lobby the persistent outer shell with a permanent sidebar, and to fix NDO data display.
Shared Types
NdoDescriptor,NdoInput,UpdateLifecycleStageInput,NdoTransitionHistoryEvent—packages/shared-types/src/resource.types.ts- Rust's canonical
PropertyRegimehas 7 variants:Private,Commons,Collective,Pool,CommonPool,Public,Nondominium - Frontend shared types, schemas, creation form, filters, and badge maps expose all 7 variants
LobbyUserProfile,GroupMemberProfile— three-level identity model- Extended
GroupDescriptorwith clone-cell identifiers, derived/deprecatedndoHashes, localmemberProfile, and optional presentation metadata
Service Layer
resource.service.ts—createNdo,getNdo(returnsNondominiumIdentity | null, matching Rust'sOption<NondominiumIdentity>),updateLifecycleStage,getMyNdos,getNdosByLifecycleStage/Nature/Regime,getNdoTransitionHistoryndo.service.ts—getLobbyNdoDescriptors,createNdo(input, groupId),getGroupNdoDescriptors,getNdoTransitionHistory;getNdoDescriptorForSpecActionHashusesgetMyNdos → getAllNdos → ResourceSpeclookup chain with reliable base64 hash comparisonlobby.service.ts— Group + Lobby DNA backed:getMyGroups(enumerate group clone cells +get_my_group),createGroup(createCloneCell→create_group→join_group→announce_group),joinGroup(provision clone cell +is_memberguard + best-effortjoin_group, withfetchGroupProfileWithRetrygossip polling and invite-payload fallback so the group appears without a reload —TODO(signals)),ensureMembership(groupId)(idempotent membership self-heal — resolve group hash →is_member→join_groupif missing — so a joined agent always reconciles into the member list even if the original join missed),generateInviteLink. Only the Level 2GroupMemberProfilepresentation choice stays inlocalStorage(saveGroupMemberProfile)
Store Layer
app.context.svelte.ts—lobbyUserProfilestate with localStorage hydration + persistencelobby.store.svelte.ts—ndos,filteredNdos,activeFilters,groups,createGroup,joinGroup;loadLobby()now called from root layoutgroup.store.svelte.ts—group,groupNdos,members,loadGroupData(groupId, { silent? })(full load runsensureMembershipthen fetches NDOs + members; silent load skips reconcile, keeps data on transient failure, no spinner),refreshCurrentGroup()(silent re-fetch for the pull-based reactivity layer — driven byGroupViewtab-focus/visibility + ~8 s poll;TODO(signals)),createNdo,associateNdoWithGroup(ndoHashB64, groupId)(writes a secondNdoAnchoron the target group clone cell, copying the NDO's clone coordinates from an existing anchor)ndo-cache.ts(new) — in-memoryMap<hashB64, NdoDescriptor>populated on card click so the NDO detail page renders immediately without a DHT round-trip
Components — Shell / Layout
+layout.svelte(root) —onMountcallsgetMyAgentPubKey()+loadLobby()+ shows first-timeUserProfileFormif no lobby profile exists; ensures sidebar has data on every routeSidebar.svelte— rewritten as persistent LobbySidebar: Browse NDOs link, live groups list with/group/:idlinks, inline "+ New Group" form, inline "→ Join Group" form, "My Profile / Edit profile" at bottom; "New NDO" global link removed (NDO creation lives only inside Group)AppShell.svelte— unchanged layout wrapper
Components — Lobby Level
LobbyView.svelte— page header +NdoBrowser;$effectmirrorslobbyStore.myPersonintoappContextand triggersloadNdos()— it does not setappContext.currentViewso the lobby shell does not override'ndo'when an NDO page is mountedUserProfileForm.svelte— Lobby profile create/edit (modal + page modes; nickname required)NdoBrowser.svelte— multi-select filter chips: LifecycleStage × ResourceNature × PropertyRegime (all 7 regimes); "No NDOs yet" empty stateNdoCard.svelte— NDO summary card with lifecycle/nature/regime badges; populatesndo-cachebefore navigating
Components — Group Level
GroupView.svelte— group header, "Create NDO" button, group-scopedNdoBrowser; fixed: uses$effectinstead ofonMountso group data reloads correctly when navigating between groupsNdoCreateModal.svelte— 5-field form (name, regime, nature, stage, description), uniqueness check, Effect-TS errors, navigates to NDO page on success; currently exposes 4 of the backend's 6 regimesGroupProfileModal.svelte— per-group profile disclosure preferences (first visit only)
Components — NDO Level
NdoView.svelte— detail card with labeled Description / Property Regime / Resource Nature / Lifecycle Stage / Created; loading skeleton + retry-able DHT refresh error banner; Join NDO (inline Coming soon); Associate with a group opensAssociateNdoModal; Fork opensForkNdoModalwhen Holochain is connected. Descriptor is seeded fromndo-cachethen refreshed from the DHT.AssociateNdoModal.svelte— lists groups excluding those whosendoHashesalready contain this spec; loads groups vialobbyStore.loadGroups()on mountNdoIdentityLayer.svelte— initiator profile link, lifecycle transition button (initiator-only),TransitionHistoryPanel; its color map still covers only the 4 frontend regimesLifecycleTransitionModal.svelte— full state machine (mirrors Rust), Deprecated + Hibernating special casesTransitionHistoryPanel.svelte— collapsible history: from/to stage, agent, timestamp, event_hash + copy-to-clipboardForkNdoModal.svelte— informational fork friction modal with copy-initiator-pubkey CTA- NDO tabs: Resources, Governance, and Activity render current service-backed data; Composition is still a placeholder
Routing
/(LobbyView) — NDO browser across all user groups/group/[id](GroupView) — group-scoped NDO list + Create NDO;?createNdo=1auto-opens modal/ndo/[id](NdoView) — full NDO detail page with detail card, actions, and tabs
Multi-Agent Web Dev Harness ✅ Implemented
The dev runtime is the browser (Electron/hc-spin superseded). scripts/launch-happ.mjs (bun run start / AGENTS=N bun run network) orchestrates: kitsune2-bootstrap-srv → hc sandbox conductors → path-based installApp (avoids the websocket bundle-streaming timeout) → ui/static/hc-connection.json connection manifest → one Vite dev server per agent on consecutive ports (5173 + agent-1, pinned via VITE_DEV_AGENT) → auto-opened browser tab per agent (NO_OPEN=1 to disable).
- Each agent = dedicated port = dedicated origin = isolated
localStorage, with clean permalinks (no?agent=in URLs; the param is retained only as a manual override). connectHolochainClient(hc-connect.ts) resolveslauncher/manifest/envmodes;getDevAgentIndex()prefers?agent=N→VITE_DEV_AGENT→localStorage.- Signing credentials are authorized for provisioned and cloned cells, serialized with
authorizeWithRetryto survive "source chain head has moved";authorizeCellSigninghandles group clone cells created after connect. - UI-only
localStoragekeys are namespaced viadevStorageKey(base)(__a{agent}) for the shared-origin override case.
Not Yet Implemented (UI)
Complete seven-variant PropertyRegime support✅:Collective,Pool, andPublicare present in Rust and exposed in frontend shared types, schemas, forms, filter options, and display maps- "Join NDO" backend implementation (button is a placeholder; UI flow + API contract only)
- Person management components (issue #8)
- Resource management components (issue #9)
- Capability-based private data sharing UI (issue #39)
- PPR reputation visualization (issue #22)
- Economic Process workflow UI (issues #28–#32)
- Role management / agent progression UI (issues #33–#34)
Group DNA backend ✅ Complete for its current scope (PR #107) — cloned-cell architecture, 4 entry types, 16 coordinator externs, 13 Sweettest cases. Multi-member Group invites, DHT member lists, reactive join, idempotent membership self-heal (
ensureMembership), and pull-based reactivity (tab focus + gentle poll) for shared-group items are wired in the UI. Push reactivity via Holochainremote_signalis the documented next step.
Testing Infrastructure
Sweettest (Rust) — Primary ✅
All new backend integration tests use Sweettest. Core-DNA tests live in dnas/nondominium/tests/src/; Lobby and Group have separate Sweettest packages.
Shared setup utilities (common::conductors):
setup_two_agents()— two conductors, nondominium DNAsetup_three_agents()— three conductors, nondominium DNAsetup_dual_dna_two_agents()— two conductors, nondominium + hREA DNAs
Registered core test modules (dnas/nondominium/tests/Cargo.toml):
misc— zome connectivityperson— Person zome + hREA bridgeresource— ResourceSpecification, EconomicResource, GovernanceRule, transition, and NDO Layer 0 behaviorgovernance— federation hard links are active; Agreement and Contribution scenarios are currently ignorednondominium— NDO lifecycle/integrity scenarios
Separate DNA suites:
dnas/lobby/tests— 5 Lobby scenariosdnas/group/tests— 13 Group scenarios
Active Sweettest coverage is useful but incomplete. Across core + Lobby + Group suites there are about 33 active tests, with ignored governance Agreement/Contribution cases. The PPR coordinator prototype, Person capability/device paths, and several partially stubbed governance flows still lack complete active coverage.
Tryorama (TypeScript) — Deprecated ⚠
Tests in tests/ are deprecated. See tests/DEPRECATED.md for migration status. Do not write new tests there.
Development Environment & Tooling ✅
git submodule update --init --recursive # Initialize hREA submodule (REQUIRED)
nix develop # Reproducible environment (REQUIRED)
bun install # Dependency installation
bun run start # 2-agent development network with UIs
bun run build:zomes # WASM compilation
bun run build:happ # DNA packaging
bun run package # Final .webhapp distribution
# Sweettest (primary test runner)
CARGO_TARGET_DIR=target/native-tests cargo test --package nondominium_sweettest
Current Status Summary
| Area | Status |
|---|---|
| Multi-DNA hApp packaging (Lobby/NDO/hREA/Group) | ✅ Complete for current bundle |
| Person profiles and Agent↔Person mapping | ✅ Implemented |
| Person roles, capabilities, and device support | 🔄 Implemented APIs; capability sharing is still prototype-quality |
| Role promotion and specialized validation | 🔄 Partial; placeholder/auto-approval paths remain |
| Resource specifications and economic resources | ✅ CRUD/query model implemented |
| GovernanceRule persistence | ✅ Implemented |
| GovernanceRule classification constraints | ✅ Hard/Soft predicates enforced at integrity and in evaluate_state_transition (#132) |
| GovernanceRule per-rule runtime conditions | ❌ Not implemented (requires_validation, min_affiliation, quotas) |
| ValueFlows action vocabulary + EconomicEvents | ✅ Implemented |
| Commitments and Claims | ✅ Implemented |
| PPR types, validation, local queries, and summaries | 🔄 Prototype |
| Fully authenticated automatic bilateral PPR workflow | ❌ Not implemented |
| Governance validation APIs | 🔄 Partial |
| Governance-as-Operator Request→Evaluate→Apply path | ❌ Not implemented |
| NondominiumIdentity Layer 0 | ✅ Implemented |
| PropertyRegime backend enum (7 variants) | ✅ Implemented |
| PropertyRegime frontend support (all 7 variants) | ✅ Implemented |
| NDO federation hard links/contributions/agreements | 🔄 Implemented; Agreement/Contribution tests ignored |
| Lobby DNA backend | ✅ Implemented |
| Group DNA backend (cloned-cell architecture) | ✅ Complete for current scope |
| hREA Phase 1 (Person/ReaAgent bridge) | ✅ Implemented |
| hREA Phases 2–4 | ❌ Not started |
| SvelteKit + UnoCSS + Melt UI next-gen setup | ✅ Implemented |
| Effect-TS service layer | ✅ Complete (PR #97) |
| MVP UI — Persistent Lobby sidebar (all routes) | ✅ Complete |
| MVP UI — Lobby → Group → NDO hierarchy | ✅ Complete |
| MVP UI — Three-level identity (Lobby/Group/Agent) | 🔄 Lobby + Group presentation wired; first-action Person creation not enforced |
| MVP UI — NDO creation within Group context | ✅ Complete |
| MVP UI — NDO detail page | 🔄 Implemented; Join and Composition are placeholders |
| MVP UI — NDO filter browser (3-dimension chips) | 🔄 Complete for current 4 frontend regimes |
| MVP UI — Lifecycle transition + history panel | ✅ Complete |
| MVP UI — Fork friction modal | ✅ Complete |
| MVP UI — Associate NDO with group modal | ✅ Complete |
| MVP UI — Join NDO | ❌ Backend not implemented |
| MVP UI — First-time user profile modal (root layout) | ✅ Complete |
| MVP UI — Multi-member group invites + DHT member list | ✅ Complete |
| MVP UI — Reactive group join (gossip-retry + fallback) | ✅ Complete |
MVP UI — Membership self-heal (ensureMembership) | ✅ Complete |
| MVP UI — Pull reactivity for shared-group items (focus + poll) | ✅ Complete |
| Push reactivity via Holochain signals | ❌ Not started (TODO(signals)) |
| Dev harness — per-agent web instances (ports, auto-open) | ✅ Complete |
| Active Sweettest suites (core + Lobby + Group) | ✅ Implemented |
| Economic processes (Use/Transport/Storage/Repair) | ❌ Not started |
| Person management UI components | ❌ Not started |
| Economic Process UI | ❌ Not started |
| PPR reputation visualization | ❌ Not started |
Post-MVP Design Specifications
The following are documented and traceable to REQ-NDO-* in documentation/requirements/ndo_prima_materia.md but are not in scope for the current development milestone:
| Track | Design sources | Implementation status |
|---|---|---|
| NDO Layer 0 (identity anchor) | ndo_prima_materia.md §§4, 8; REQ-NDO-L0-01–07 | Implemented (#80/#84) — identity, lifecycle validation, and facet anchors exist; required EconomicEvent generation and complete link-integrity hardening remain pending |
| NDO Layers 1 & 2 | ndo_prima_materia.md §§4, 8, 10; resources.md §3 | 🔄 Layer 1 implemented (#132) — NdoToSpecification created on every create_resource_specification, with the Layer 0 pointer pair (ndo_identity_hash / ndo_state_hash) and a lifecycle gate. Layer 2 (NDOToProcess) not started |
| Lifecycle vs operational state split | ndo_prima_materia.md §5, §9.4 (REQ-NDO-OS-01, REQ-NDO-OS-06) | ✅ Data layer — OperationalState on EconomicResource; governance-operator transitions (REQ-NDO-OS-02–05) deferred |
| Unyt (EconomicAgreement, RAVE) | ndo_prima_materia.md §6.6, §11.5; unyt-integration.md; REQ-NDO-CS-07–CS-11 | Not started — no Unyt cell / RAVE validation in governance zome |
| Flowsta (agent linking, IdentityVerification) | ndo_prima_materia.md §6.7, §11.6; flowsta-integration.md; REQ-NDO-CS-12–CS-15 | Not started — flowsta-agent-linking zomes not bundled |
| Person capability slot (G15) | agent.md §3.2; person_zome.md; REQ-AGENT-11, REQ-NDO-AGENT-07 | Not started — no FlowstaIdentity links on Person hash |
| Lobby DNA (multi-network federation entry point) | requirements/lobby-dna.md REQ-LOBBY-*; specifications/lobby-architecture.md | Implemented (#103) — Lobby DNA with LobbyAgentProfile + GroupAnnouncement, 9 coordinator externs, 5 Sweettest scenarios, lobby role in happ.yaml, and Moss manifest. Group DNA complete for its current scope (#107). |
| NDO DNA extensions (NdoHardLink, Contribution, Agreement) | requirements/lobby-dna.md REQ-NDO-EXT-01–16; specifications/lobby-architecture.md §6 | Implemented (#103) — entry types, link types, and coordinator modules exist; hard-link Sweettest is active, while Agreement/Contribution scenarios are currently ignored. |
See documentation/implementation_plan.md Section 12 for a phased checklist aligned with the prima materia.
Nondominium Development Report
Executive Summary
This document provides a comprehensive overview of the Nondominium project's development progress, tracing its historical evolution from early research in peer production systems to its current implementation as a decentralized resource transfer engine. The report outlines the project's origins, current status, and future roadmap.
Historical Context and Project Origins
The Nondominium project builds upon more than a decade of research in peer production systems conducted by the Sensorica laboratory. Since 2011, Sensorica has been at the forefront of developing collaborative resource management systems that embody the principles of Open Value Networks.
Real-World Validation: PEP Master Venture
A critical milestone in shaping the Nondominium requirements is the PEP Master venture, a collaborative project creating open source DIY hardware and software for cystic fibrosis therapy. In collaboration with Sainte Justine Children's Hospital in Montreal and the Breathing Games community, PEP Master is developing a medical device that requires:
- Trust-based economy model: A system where trust between doctors and patients is established based on the quality (safety and efficiency) of medical instruments
- Certainty of provenance: Digital infrastructure providing proof of origin for device designs
- On-demand verification: Methods for validating fabrication quality in distributed manufacturing
- Contribution accounting: Fair reward distribution for everyone involved in producing the instruments
This real-world medical device context provides crucial validation for Nondominium's design, particularly around:
- Non-fungible tokens (NFTs) for digital certificates representing device provenance
- Third-generation DLT for contractual and transactional primitives
- Open value network governance models for collaborative ventures
The NRP-CAS Foundation
In 2013, Sensorica collaborated with Lynn Foster and Bob Haugen to develop the Network Resource Planning and Contribution Accounting System (NRP-CAS). This system was specifically designed to operationalize Open Value Network principles, providing a framework for managing resources and tracking contributions across collaborative projects. The initial prototype was implemented using Django and Python, serving as an internal tool for the laboratory's operations for several years.
However, the NRP-CAS prototype demonstrated stability and security limitations that precluded production deployment. Despite these technical constraints, the project established a crucial theoretical foundation: Foster and Haugen leveraged the NRP-CAS implementation to develop the Valueflows ontology, an extension of William E. McCarthy's Resource-Event-Agent (REA) framework. This ontology would later become a cornerstone of the Nondominium architecture.
Evolution to Web 3 and Architecture Refinement
The year 2025 marked a significant milestone with the initiation of Nondominium, a Holochain implementation designed to modernize the NRP-CAS concept. Nondominium leverages Holochain as its underlying infrastructure and plans to incorporate hREA, the Holochain-native implementation of the Valueflows ontology. The ambitious vision for Nondominium encompassed a comprehensive implementation of Valueflows to support complete peer production processes.
During the development process, a critical architectural insight emerged: the need to isolate the resource transfer mechanism as a distinct, reusable component. This recognition led to a strategic separation of concerns between two complementary systems.
First, Nondominium serves as the resource transfer and flow engine, designed as an organization-agnostic system that embeds governance rules directly within resource definitions. This approach enables resources to carry their own governance parameters, ensuring that transfer protocols remain consistent regardless of organizational context.builds upon the Nondominium foundation to provide a complete peer production system. Second, it incorporates additional capabilities including contribution accounting, benefit redistribution algorithms, and project management functionalities.
Current Development Scope
The initial release of Nondominium focuses on validating the core concept of non-proprietary resource transfer systems through the implementation of essential primitives. This first version encompasses three foundational components.
Core Resource Transfer System
The primary deliverable is a minimal viable implementation of the resource transfer mechanism, demonstrating the feasibility of governance-embedded, non-proprietary resource flows. This system establishes the technical foundation upon which future enhancements will be built.
Agent Management Foundation
The implementation includes fundamental person agent management capabilities with multi-device support, recognizing that modern collaborative workflows require seamless cross-device functionality.
Governance-as-Operator Architecture
The Resource and Governance zomes (modules) adopt a "governance as operator" paradigm, wherein resources remain static until explicitly modified through governance actions. This architectural approach ensures that all state transitions are governed by well-defined rules embedded within the resource itself.
Target Ecosystem Integration
The initial implementation targets the Moss ecosystem (https://moss.social), a peer-to-peer, privacy-first groupware platform designed for small teams. Moss provides an ideal deployment environment as it is built on Holochain and supports Holochain applications, enabling immediate integration and real-world validation of the Nondominium concepts.
Governance-as-Operator Architecture
Nondominium implements a sophisticated governance-as-operator architecture that establishes a clear separation between data management and business logic enforcement. This design pattern enables independent evolution of resource data structures and governance rules, providing modularity, testability, and swappability.
Core Architectural Principles:
The Resource zome operates as a pure data model responsible for resource specification management, economic resource lifecycle operations, and data persistence. It contains no business logic or validation rules, performing only CRUD operations on data structures. All governance decisions are delegated to the Governance zome through well-defined cross-zome interfaces.
The Governance zome functions as a state transition operator, evaluating governance rules and policies, validating agent permissions and roles, authorizing or rejecting state transitions, and generating economic events for audit trails. Its logic is implemented as pure functions that evaluate state transitions without side effects, enabling comprehensive unit testing and governance scheme swappability.
Cross-Zome Communication Protocol:
Status note (2026-09-22):
request_resource_transition()does not exist in the codebase.evaluate_state_transition()is implemented inzome_gouvernance/src/transition.rsand runs as a parallel, advisory path rather than the mandatory funnel described below. Current state: IMPLEMENTATION_STATUS.md; open design question: #145.
Communication between zomes follows a Request-Evaluate-Apply pattern implemented through the GovernanceTransitionRequest and GovernanceTransitionResult structures. When a resource state change is requested:
- The Resource zome calls
request_resource_transition()with the proposed action, current resource state, requesting agent, and transition context - The Governance zome evaluates the request via
evaluate_state_transition(), checking agent permissions, applicable governance rules, and state transition validity - The Resource zome applies approved state changes, records generated economic events, and updates state transition links
This architecture ensures that all resource state transitions are governed by well-defined rules embedded within the resource itself, with complete audit trails through economic event generation. The event-driven design integrates seamlessly with the PPR reputation system, enabling comprehensive tracking of agent participation and resource lifecycle history.
Implementation Status
The Nondominium project has achieved substantial implementation completeness across all core systems. The current development state represents a production-ready Holochain application with comprehensive ValueFlows compliance and advanced privacy features. Overall completion stands at approximately 85-90%, with all fundamental functionality operational and tested.
Architecture Context
Nondominium implements a custom ValueFlows-compliant architecture designed to validate novel governance and reputation mechanisms. This independent implementation was developed to prove the PPR (Private Participation Receipt) system concept and governance-as-operator paradigms before committing to deeper ecosystem integration.
The governance-as-operator architecture enables independent evolution of data structures and governance rules, providing modularity, testability, and swappability as fundamental design principles. This separation of concerns allows different governance schemes to be applied to the same resource types without modifying the core resource data model. The pure function approach to governance logic enables comprehensive unit testing and facilitates the substitution of governance mechanisms as organizational requirements evolve. This architectural flexibility positions Nondominium to support diverse collaborative models while maintaining consistent resource management primitives.
The project maintains a strategic distinction between current implementation and future architecture. While Nondominium currently operates as a standalone system with complete ValueFlows data structures, a separate roadmap exists for integrating hREA (the Holochain Regenerative Economics Architecture) as a backend engine. This future integration, detailed in the hREA/integration-strategy.md document, would position hREA as the foundational ValueFlows implementation layer while preserving Nondominium's specialized innovations in privacy, governance, and reputation tracking.
This architectural approach enables the project to demonstrate unique value propositions through practical implementation before adopting ecosystem standards, ensuring that innovations can be properly validated and potentially contributed back to the broader hREA community.
Phase 1: Foundation System
Person Management System (95% Complete)
The Person zome provides comprehensive agent identity management with full multi-device support and role-based access control. The system distinguishes between public profiles (name, avatar, bio) and private data (legal name, contact information, address), with capability-based access control governing sensitive information. Six role types have been implemented, ranging from SimpleAgent for basic network participation to PrimaryAccountableAgent for advanced governance capabilities. The multi-device support allows agents to register and manage multiple devices while maintaining a unified identity, with proper security validation and activity tracking.
Resource Management System (90% Complete)
The Resource zome implements a complete ValueFlows-compliant data model with resource specifications, economic resource instances, and embedded governance rules. Resource specifications define the template for resource types, including naming, categorization, and governance requirements. Economic resources represent individual instances with precise quantity tracking, custodian assignment, and location metadata. The system supports five resource states (PendingValidation, Active, Maintenance, Retired, Reserved) with comprehensive lifecycle management. The governance architecture allows rules to be directly embedded within resources, ensuring that all state transitions follow defined protocols.
Testing Infrastructure
A robust 4-layer testing strategy encompasses Foundation tests (basic zome functionality and connectivity), Integration tests (cross-zome interactions and multi-agent scenarios), Scenario tests (complete user journeys and end-to-end workflows), and Performance tests (load testing for the PPR system). This comprehensive approach ensures approximately 95% test coverage for the Person zome, 90% for the Resource zome, and 75% for the Governance zome.
Governance Architecture Implementation
The governance-as-operator architecture implementation is substantially complete, with core cross-zome communication protocols operational and state transition logic functional.
Cross-Zome Interface (85% Complete)
Status note (2026-09-22): the
request_resource_transition()claims in this section and under Backend Technical Debt are superseded; see the note under Cross-Zome Communication Protocol above.
The GovernanceTransitionRequest and GovernanceTransitionResult structures are defined and in use, providing the foundation for cross-zome communication. The Resource zome request_resource_transition() function is implemented and functional, while the Governance zome evaluate_state_transition() function is operational with permission checking and rule evaluation. Economic event generation for approved transitions is integrated with the PPR reputation system.
State Transition Logic (80% Complete)
The pure function governance engine is implemented with stateless evaluation logic. Agent permission and role checking is operational, supporting the progressive trust model. The governance rule evaluation framework is functional with support for resource-embedded governance rules. State calculation logic correctly determines new resource states based on requested actions and context.
Known Integration Gaps: Cross-zome integration points include some temporarily disabled validation calls due to integration challenges during development. These need to be re-enabled to complete the governance-as-operator architecture, specifically the bidirectional validation between Resource and Governance zomes for certain state transition scenarios.
Phase 2: Advanced Governance and Reputation
PPR Reputation System (70% Complete)
The Private Participation Receipt system provides the foundational infrastructure for cryptographic reputation tracking across 16 distinct claim categories. These categories encompass the full resource lifecycle: network entry (ResourceCreation, ResourceValidation), custodianship transfers (CustodyTransfer, CustodyAcceptance), specialized services (Maintenance, Storage, Transport with commitment and fulfillment tracking), network governance (DisputeResolutionParticipation, ValidationActivity, RuleCompliance), and resource end-of-life (EndOfLifeDeclaration, EndOfLifeValidation).
Implemented Core Features: All 16 claim categories are defined and functional with comprehensive performance metrics tracking (timeliness, quality, reliability, communication, and overall satisfaction). The reputation aggregation system calculates weighted averages across claims with category-based breakdowns. Private data storage ensures claim confidentiality while enabling privacy-preserving reputation summaries.
Critical Gaps: The bilateral authentication workflow requires completion before the system can achieve its intended cryptographic authenticity guarantees. Currently, PPR signatures use placeholder counterparty signatures rather than true bilateral signing. The automatic PPR generation function exists but requires test coverage validation. Multi-agent signing scenarios beyond 2-agent interactions need implementation for production scalability.
Production Readiness: The PPR system provides functional reputation tracking for single-agent scenarios and comprehensive metrics calculation. However, the missing bilateral authentication workflow represents a critical gap that must be addressed before the system can deliver its core value proposition of cryptographically-authenticated, peer-validated reputation tracking.
Economic Processes
Four structured economic processes with role-based access control have been implemented to govern resource interactions. The Use process enables resource utilization without ownership transfer, requiring Accountable Agent status and implementing time-limited access with usage tracking. The Transport process manages resource movement between locations, requiring Primary Accountable Agent status and implementing custody transfer with location tracking. The Storage process handles resource preservation and maintenance, while the Repair process manages resource restoration and improvement. Each process integrates with the PPR system for reputation tracking and generates appropriate economic events.
Progressive Trust Model
A three-tier progressive trust model enables agent advancement based on validated participation and reputation accumulation. Simple Agents represent basic network membership with general capability tokens, allowing resource creation and initial transactions. Accountable Agents represent stewardship-level participation with restricted capability tokens, enabling resource access and validation of other agents. Primary Accountable Agents represent coordination and governance-level participation with full capability tokens, permitting custody holding and validation of specialized roles. Advancement between tiers occurs through validated transaction participation and PPR milestone achievements.
Frontend Foundation
Svelte 5 + TypeScript frontend infrastructure has been established with Holochain integration components. However, the current UI implementation requires a complete rewrite to be functional and compatible with the Moss ecosystem. The technical foundation is in place, but user-facing components need redevelopment to align with Moss integration requirements and provide functional workflows for end users.
Remaining Technical Work
Frontend Development
The Svelte 5 + TypeScript infrastructure exists but requires a complete rewrite to create a functional, user-friendly interface compatible with the Moss ecosystem. This includes implementing profile management interfaces, resource browsing and discovery tools, role assignment capabilities, capability management controls, and real-time DHT synchronization. This represents a significant development effort rather than polish work.
Backend Technical Debt
Several backend items require attention for full production optimization. Cross-zome integration points require specific attention to complete the governance-as-operator architecture: some temporarily disabled validation calls between Resource and Governance zomes need to be re-enabled, specifically the bidirectional validation for state transition scenarios where request_resource_transition() must validate against evaluate_state_transition() results. Resource link management requires addressing duplicate resource links that occur during custody transfer scenarios, which affects resource counting accuracy. Code quality improvements include removing unused imports and ambiguous glob re-exports for cleaner compilation. These backend items represent polish and optimization work rather than missing core features, with the cross-zome validation re-enabling being the most significant for architectural completeness.
PPR System Completion
The Private Participation Receipt system requires completion of its bilateral authentication workflow to achieve full functionality. Current implementation uses placeholder counterparty signatures rather than true multi-party cryptographic signing. Required work includes: implementing a two-step signature collection mechanism, adding pending signature status tracking, creating counterparty notification systems, and developing automatic PPR finalization when both signatures are received. Additionally, the automatic PPR generation function exists but requires comprehensive testing to validate production behavior.
Future Roadmap: hREA Integration
A separate roadmap exists for integrating hREA as the foundational ValueFlows backend engine. This integration, detailed in hREA/integration-strategy.md, represents a future architectural enhancement rather than current implementation. The strategy employs a git submodule approach with cross-DNA calls, enabling Nondominium to leverage hREA's proven ValueFlows patterns while maintaining its specialized PPR system, private data innovations, and governance mechanisms.
The integration roadmap comprises four phases: Person zome pilot integration, Resource lifecycle expansion, Governance system integration with PPR enhancement, and Production readiness optimization. This future evolution positions Nondominium to contribute validated innovations back to the hREA ecosystem while achieving immediate ValueFlows compliance through its current custom implementation.
Post-MVP Development Roadmap
Following the completion of the initial release, the project team has identified several strategic enhancements designed to extend Nondominium's capabilities and establish it as a foundational technology for peer production systems.
Protocol Standardization
A primary objective is to standardize the Nondominium resource transfer system as a formal protocol, with the long-term vision of establishing it as an ISO standard for peer production systems. Documentation of this protocol is available in the resource-transport-flow-protocol specification.
Digital Resource Integrity
The team plans to implement a Digital Resource Integrity feature designed to ensure the authenticity and integrity of resources throughout their lifecycle. This capability will provide cryptographic proof that downloaded resource data remains identical to the original data uploaded to the Holochain DHT, addressing concerns about data integrity in distributed systems. Further details are available in the digital-resource-integrity specification.
Valueflows Domain-Specific Language
To enable more sophisticated resource management, the team is developing a Valueflows Domain-Specific Language (DSL). This DSL will facilitate the scripted definition and management of resource flows and transactions, enabling automated resource allocation and distribution based on predefined rules. The valueflows-dsl specification provides additional technical details on this initiative.
Testing Infrastructure for nondominium hApp
Overview
The nondominium hApp employs a comprehensive, multi-layered testing strategy covering all three zomes across two parallel test suites that are active simultaneously during migration.
Current status: Sweettest is in place for misc (ping), person (hREA bridge), resource, nondominium (NDO Layer 0 lifecycle tests, 8 scenarios), and governance (federation extensions from #103). The lobby_sweettest crate covers the Lobby DNA. Per-zome tests continue to be co-evolved alongside the NDO refactor (see documentation/requirements/ndo_prima_materia.md §10). Tryorama (TypeScript) remains active for UI-layer tests.
Sweettest (Rust) — Primary
Sweettest runs Holochain in-process, providing faster feedback and direct access to Holochain types without the WebSocket/msgpack round-trip.
Running Sweettest
nix develop # Required: provides Rust toolchain + Holochain binaries
# Build the .dna bundle first, then run Rust tests
bun run sweettest # build:happ + cargo test -p nondominium_sweettest
bun run sweettest:verbose # same + --nocapture for test output
bun run sweettest:only # skip build:happ (use when .dna is already built)
Test crate locations
dnas/
├── nondominium/tests/ # package: nondominium_sweettest
│ ├── Cargo.toml # [[test]] targets: misc, person, resource, nondominium, governance
│ └── src/
│ ├── common/
│ │ └── conductors.rs # setup_two_agents(), setup_three_agents(), setup_dual_dna_two_agents()
│ ├── misc/mod.rs # ping test — validates full build chain end-to-end
│ ├── person/mod.rs # Person zome + hREA bridge tests
│ ├── resource/mod.rs # zome_resource tests: get_all_resource_specifications (action_hashes field)
│ ├── nondominium/ # NondominiumIdentity lifecycle tests (8 scenarios, closes #76)
│ └── governance/mod.rs # Agreement, Contribution, NdoHardLink tests (#103)
└── lobby/tests/ # package: lobby_sweettest
├── Cargo.toml
└── src/
├── common/
│ └── conductors.rs # setup_two_lobby_agents()
└── lobby/mod.rs # announce_group, upsert_lobby_agent_profile, get_my_groups tests
Per-zome test modules are co-evolved alongside implementation PRs. Each PR that adds new #[hdk_extern] functions adds corresponding tests in the relevant module.
Environment requirement for Sweettest
The holonix shell (GCC-based) needs LIBCLANG_PATH and BINDGEN_EXTRA_CLANG_ARGS set
for the datachannel-sys bindgen step. These are exported automatically when using
nix develop after flake.nix adds llvmPackages_19.libclang.
Use CARGO_TARGET_DIR=target/native-tests to isolate from the WASM build artifacts.
Testing Philosophy
Our testing approach follows Holochain community best practices with emphasis on:
- Progressive Complexity: Start with basic connectivity, build to complex scenarios
- DHT-Aware Testing: Accounts for distributed timing and synchronization requirements
- Multi-Agent Focus: Validates true peer-to-peer interactions using Tryorama
- Real-World Scenarios: Tests actual governance and community workflows
- Privacy Validation: Ensures proper private entry storage and access control boundaries
Test Architecture
Layered Testing Approach
📊 Test Layers (Bottom-up approach)
├── 🔧 Foundation Tests - Basic connectivity & function calls
├── 🧩 Unit Tests - Individual zome functionality
├── 🔗 Integration Tests - Cross-zome & multi-agent interactions
├── 🎭 Scenario Tests - Real-world usage patterns
└── ⚡ Performance Tests - Scalability & timing validation
Technology Stack
Sweettest (Rust — new primary):
- Framework:
holochain = "=0.6.0"withtest_utilsfeature - Runtime:
tokiomulti-thread executor - Language: Rust, in-process Holochain
- CARGO_TARGET_DIR:
target/native-tests(isolated from WASM artifacts)
Tryorama (TypeScript — transitioning out):
- Framework: Vitest v3.2.4
- Holochain Testing: @holochain/tryorama v0.18.2
- Language: TypeScript with full type safety
- Environment: Nix development shell for consistent Holochain binaries
Test Structure
Directory Layout
tests/
├── src/nondominium/
│ ├── person/ # Person management tests
│ │ ├── person-foundation-tests.test.ts
│ │ ├── person-integration-tests.test.ts
│ │ ├── person-scenario-tests.test.ts
│ │ ├── person-capability-based-sharing.test.ts
│ │ └── common.ts
│ ├── resource/ # Resource lifecycle tests
│ │ ├── resource-foundation-tests.test.ts
│ │ ├── resource-integration-tests.test.ts
│ │ ├── resource-scenario-tests.test.ts
│ │ ├── resource-update-test.test.ts
│ │ └── common.ts
│ ├── governance/ # Governance system tests
│ │ ├── governance-foundation-tests.test.ts
│ │ ├── ppr-system/ # PPR system tests
│ │ │ ├── ppr-foundation.test.ts
│ │ │ ├── ppr-integration.test.ts
│ │ │ ├── ppr-scenarios.test.ts
│ │ │ ├── ppr-cryptography.test.ts
│ │ │ ├── ppr-debug.test.ts
│ │ │ └── common.ts
│ │ └── common.ts
│ └── misc/ # Miscellaneous tests
│ └── misc.test.ts
├── package.json # Test dependencies & scripts
├── tsconfig.json # TypeScript configuration
└── vitest.config.ts # Test framework configuration
Test Command System
Pattern-Based Test Execution
The testing system uses Vitest's file filtering capabilities with the bun tests command:
# Main test command (builds zomes, packages hApp, runs tests)
bun tests
# Pattern-based selection
bun tests person # All files starting with "person-"
bun tests resource # All files starting with "resource-"
bun tests governance # All files starting with "governance-"
bun tests ppr # All files starting with "ppr-"
# Layer-based selection
bun tests foundation # All files containing "foundation"
bun tests integration # All files containing "integration"
bun tests scenario # All files containing "scenario"
# Specific test files
bun tests person-foundation
bun tests ppr-integration
bun tests resource-scenario
Test Command Options
# Development workflows
bun tests --watch person # Hot reload during development
bun tests --reporter=verbose ppr-debug # Detailed output for debugging
bun tests --coverage # Generate coverage reports
bun tests --typecheck # Run with TypeScript checking
# Quality assurance
bun tests foundation && bun tests --typecheck # Pre-commit validation
bun tests && bun tests --coverage # Full validation
Test Categories
🔧 Foundation Tests
Purpose: Validate basic zome connectivity and entry creation
Scope: Single agent operations, individual function calls
Files: *-foundation-tests.test.ts
Test Coverage:
- Person Foundation: Basic profile creation, private data storage, community discovery
- Resource Foundation: Resource specification creation, basic validation
- Governance Foundation: Basic governance operations, rule validation
- PPR Foundation: Private Participation Receipt creation and validation
Key Features:
- Immediate feedback on API compatibility issues
- Basic entry validation and error boundary testing
- Foundation for more complex multi-agent tests
- Single-conductor Tryorama scenarios
🔗 Integration Tests
Purpose: Validate multi-agent interactions and DHT synchronization
Scope: Multiple agents, cross-zome functionality, distributed operations
Files: *-integration-tests.test.ts
Test Coverage:
- Person Integration: Multi-agent discovery, cross-agent role assignment
- Resource Integration: Resource sharing between agents, access validation
- PPR Integration: Cross-agent PPR validation, cryptographic verification
Key Features:
- Multi-conductor Tryorama setup with 2+ agents
- DHT timing validation and synchronization delays
- Cross-agent visibility and access control testing
- Distributed state consistency validation
🎭 Scenario Tests
Purpose: Simulate complete real-world usage patterns and workflows
Scope: End-to-end user journeys, complex governance scenarios
Files: *-scenario-tests.test.ts
Test Scenarios:
1. Complete Resource Sharing Workflow
- Resource creation and specification
- Capability-based access grants
- Multi-agent resource discovery
- Usage validation and governance
2. PPR System End-to-End
- PPR creation for resource access
- Cryptographic validation chain
- Multi-step approval workflows
- Governance rule enforcement
3. Community Onboarding Scenarios
- New member profile creation
- Role assignment and capability grants
- Resource access integration
- Privacy boundary verification
Key Features:
- Complete user journey testing
- Real governance workflow simulation
- Privacy and security validation
- Complex multi-step transaction flows
Specialized Tests
PPR Cryptography Tests: Validation of cryptographic primitives and security PPR Debug Tests: Development debugging and edge case validation Capability-Based Sharing: Advanced access control scenarios Resource Update Tests: Resource lifecycle and modification workflows
Test Utilities & Infrastructure
Data Factories (common.ts)
Standardized test data creation for each domain:
// Person management
createTestPerson() → Standard person profile
createTestPersonVariation(suffix) → Unique profiles for multi-agent tests
// Resource management
createTestResource() → Sample resource specification
createTestResourceVariant() → Resource variations
// PPR system
createTestPPR() → Basic PPR structure
createTestValidationBlock() -> Cryptographic validation data
Validation Helpers
Comprehensive response validation across domains:
validatePersonCreation() → Complete person entry validation
validateResourceCreation() → Resource specification validation
validatePPRCreation() → PPR structure and cryptographic validation
validateAgentProfile() → Profile retrieval validation
Multi-Agent Management
Tryorama-specific tools for complex distributed scenarios:
createMultipleAgents(count) → Setup multiple test conductors
waitForDHTSync(delay) → DHT synchronization delays
setupTryoramaScenario() → Standard scenario initialization
cleanupTryorama(scenario) → Proper cleanup and shutdown
Test Configuration
Timeout Settings: 4 minutes for complex multi-agent scenarios Concurrency: Single fork execution for DHT consistency Agent Simulation: Supports 2+ distributed agents per test Environment: Requires Nix development shell
Running Tests
Prerequisites
-
Nix Development Environment: Required for Holochain binaries
nix develop # Enter reproducible environment (REQUIRED) -
Dependencies: Automatically installed by test scripts
bun install # Install all dependencies
Test Execution Commands
From Project Root:
# Build and run all tests
bun tests
# Pattern-based test selection
bun tests person # Person-related tests
bun tests resource # Resource-related tests
bun tests governance # Governance-related tests
bun tests ppr # PPR system tests
# Layer-based selection
bun tests foundation # All foundation tests
bun tests integration # All integration tests
bun tests scenario # All scenario tests
# Specific test files
bun tests person-foundation
bun tests ppr-integration
bun tests resource-scenario
Development Workflows:
# Watch mode for development
bun tests --watch person
# Debug mode with verbose output
bun tests --reporter=verbose ppr-debug
# Coverage analysis
bun tests --coverage
# Type checking integration
bun tests --typecheck
Environment Requirements
Critical: Tests must run inside the Nix development environment to access required Holochain binaries:
kitsune2-bootstrap-srv- Holochain networking servicehc- Holochain CLI tool- Other Holochain runtime dependencies
Without Nix Environment: Tests will fail with "Failed to spawn kitsune2-bootstrap-srv" and "spawn hc ENOENT" errors.
Test Development Features
Test Isolation: Use .only() for focused development:
describe.only('specific test suite', () => { ... })
it.only('specific test', async () => { ... })
Rust Debugging: Use warn! macro in zome functions:
#![allow(unused)] fn main() { warn!("Debug info: variable = {:?}", some_variable); warn!("Checkpoint reached in function_name"); }
Current Test Coverage
Phase 1 Foundation Layer ✅
| Domain | Foundation | Integration | Scenarios | Specialized | Status |
|---|---|---|---|---|---|
| Person Management | ✅ Complete | ✅ Complete | ✅ Complete | ✅ Capability | Ready |
| Resource Management | ✅ Complete | ✅ Complete | ✅ Complete | ✅ Update | Ready |
| Governance System | ✅ Complete | 🔲 Planned | 🔲 Planned | 🔲 Planned | Ready |
| PPR System | ✅ Complete | ✅ Complete | ✅ Complete | ✅ Crypto/Debug | Ready |
Test File Inventory
Person Tests (4 files):
person-foundation-tests.test.ts- Basic connectivity and profile managementperson-integration-tests.test.ts- Multi-agent discovery and interactionperson-scenario-tests.test.ts- Complete user workflowsperson-capability-based-sharing.test.ts- Advanced access control
Resource Tests (4 files):
resource-foundation-tests.test.ts- Resource creation and validationresource-integration-tests.test.ts- Cross-agent resource sharingresource-scenario-tests.test.ts- Complete resource lifecycle workflowsresource-update-test.test.ts- Resource modification and versioning
Governance Tests (1 file):
governance-foundation-tests.test.ts- Basic governance operations
PPR System Tests (5 files):
ppr-foundation.test.ts- Basic PPR creation and validationppr-integration.test.ts- Cross-agent PPR workflowsppr-scenarios.test.ts- Complete PPR usage scenariosppr-cryptography.test.ts- Cryptographic validationppr-debug.test.ts- Development debugging
Miscellaneous Tests (1 file):
misc.test.ts- Additional test scenarios
Technology Stack Status
| Component | Version | Status |
|---|---|---|
| Sweettest (Rust) | holochain 0.6.0 | ✅ Active — new primary |
| Vitest | 3.2.4 | ✅ Active — transitioning out |
| Tryorama | 0.18.2 | ✅ Active — transitioning out (last supported pair with HDK 0.6) |
| Holochain Client | 0.19.0 | ✅ Active |
| TypeScript | 5.6.3 | ✅ Active |
| HDK | ^0.6.0 | ✅ Active |
| HDI | ^0.7.0 | ✅ Active |
Development Workflow Integration
Test-Driven Development
- Foundation First: Start with
bun tests foundationfor basic connectivity - Build Integration: Add multi-agent tests with
bun tests integration - Validate Scenarios: Create real-world usage with
bun tests scenario - Iterate & Debug: Use pattern matching for focused testing
Debugging Strategy
The layered approach enables systematic debugging:
- Foundation Failure → API compatibility or basic functionality issue
- Integration Failure → DHT timing or multi-agent logic issue
- Scenario Failure → Business logic or user workflow issue
Environment Debugging
Common issues and solutions:
- Missing Binaries: Run tests inside
nix developenvironment - Bundle Not Found: Verify automatic packaging creates
workdir/nondominium.happ - API Errors: Check HDK version compatibility (^0.6.0/^0.7.0)
- Timeout Issues: Tests have extended 4-minute timeouts for complex operations
Continuous Integration
Tests are designed for CI environments with:
- Deterministic test data and timing
- Proper cleanup between test runs via Tryorama
- Clear pass/fail indicators
- Detailed logging for failure diagnosis
- Automatic build and packaging steps
Best Practices
Pattern-Based Test Selection
Use the file naming conventions for efficient testing:
# Efficient development workflow
bun tests person-foundation # Fast: single test file
bun tests foundation # Medium: multiple foundation tests
bun tests person # Slower: all person tests
bun tests # Slowest: complete test suite
Multi-Agent Testing with Tryorama
Use consistent Tryorama patterns:
const [alice, bob] = await scenario.addPlayersWithApps([
{ appBundleSource: getAppBundleSource() },
{ appBundleSource: getAppBundleSource() },
]);
// Allow DHT synchronization
await waitForDHTSync(2000);
DHT Synchronization
Always account for distributed timing in Tryorama tests:
await waitForDHTSync(2000); // Basic operations
await waitForDHTSync(5000); // Complex multi-agent operations
Validation Consistency
Use provided validation helpers for consistency across tests:
validatePersonCreation(result, input, agentPubKey);
validatePPRCreation(pprResult, expectedData);
validateResourceCreation(resourceResult, specification);
Error Testing
Include negative test cases with proper Tryorama error handling:
await expect(async () => {
await cell.callZome({
zome_name: "person",
fn_name: "create_person",
payload: invalidData,
});
}, "Expected error pattern");
Environment Management
Always run tests in the correct environment:
# Correct way - includes Nix environment
nix develop --command bun tests person
# Incorrect way (will fail) - missing Holochain binaries
bun tests person
Performance and Scalability
Test Execution Performance
- Parallel Execution: Tests run in parallel by default for maximum speed
- Smart Filtering: Use specific patterns to reduce test execution time
- Build Optimization: Automatic incremental builds and WASM compilation
- Memory Management: Proper Tryorama cleanup prevents memory leaks
Timeout Configuration
- Standard Tests: 5 minutes (Vitest default)
- Complex Scenarios: 4 minutes (custom configured)
- Integration Tests: Extended timeouts for DHT synchronization
- Foundation Tests: Standard timeouts for quick validation
Future Enhancements
Planned Test Coverage
- Governance Integration: Cross-zome governance workflows
- Performance Testing: Load testing with multiple agents
- Security Testing: Advanced cryptographic validation
- Cross-DNA Testing: Multi-application interaction scenarios
Infrastructure Improvements
- Enhanced Debugging: Better Tryorama logging and error reporting
- Mock Services: External service mocking for complex scenarios
- Test Data Management: Improved test data factories and management
- CI/CD Integration: Enhanced continuous integration workflows
Conclusion
This testing infrastructure provides a robust foundation for ensuring the reliability and functionality of the nondominium hApp using Tryorama. The pattern-based test execution system enables efficient development workflows while the comprehensive layered approach ensures thorough validation of distributed functionality.
Current Status: All foundation, integration, and scenario tests are actively maintained and passing with Tryorama 0.18.2 and Holochain HDK ^0.6.0 / HDI ^0.7.0.
Key Strengths:
- Pattern-based test selection for efficient development
- Comprehensive Tryorama integration for realistic testing
- Proper DHT synchronization and multi-agent validation
- Full TypeScript support and type safety
- Robust build and packaging automation
Next Steps:
- Expand governance test coverage for complex workflows
- Add performance and load testing capabilities
- Enhance debugging and error reporting features
- Integrate additional security and cryptographic validation
This infrastructure supports the complete development lifecycle from foundation testing to complex multi-agent scenario validation using the official Holochain testing framework.
Test Commands Reference
Canonical command reference for running tests from the project root. This is the one place that lists every suite; other docs link here rather than restating commands.
Suite status: Sweettest (Rust) is the primary suite and the only place new tests are
written. Tryorama (TypeScript, tests/) is deprecated — see tests/DEPRECATED.md.
E2E (Playwright) covers the UI-to-conductor seam — see ui/tests/README.md.
🦀 Sweettest (Rust) — Primary
Runs Holochain in-process. Faster, no WebSocket round-trip, direct Rust types.
Each DNA has its own Sweettest package. [[test]] binaries (targets for cargo test --test <name>):
| Package | Binaries |
|---|---|
nondominium_sweettest | misc — ping test, validates full build chain end-to-endperson — Person zome + hREA bridge testsresource — Resource zome testsgovernance — Governance zome tests (hard links, contributions, agreements)nondominium — NDO Layer 0 (NondominiumIdentity) lifecycle tests |
group_sweettest | group — group lifecycle, membership, work logs, soft linksndo_anchor — NDO anchor tests |
lobby_sweettest | lobby — agent profiles and group announcements |
# Build .dna bundle then run all Rust tests
bun run sweettest
# Same with --nocapture (see test output in real time)
bun run sweettest:verbose
# Skip build:happ if .dna is already built
bun run sweettest:only
Cargo commands directly (inside nix develop):
# Requires LIBCLANG_PATH and BINDGEN_EXTRA_CLANG_ARGS to be set (exported by nix develop)
CARGO_TARGET_DIR=target/native-tests cargo test -p nondominium_sweettest
CARGO_TARGET_DIR=target/native-tests cargo test -p nondominium_sweettest -- --nocapture
# Run a specific test module
CARGO_TARGET_DIR=target/native-tests cargo test --package nondominium_sweettest --test misc
CARGO_TARGET_DIR=target/native-tests cargo test --package nondominium_sweettest --test person
CARGO_TARGET_DIR=target/native-tests cargo test --package nondominium_sweettest --test resource
CARGO_TARGET_DIR=target/native-tests cargo test --package nondominium_sweettest --test governance
Lobby DNA Sweettest
# Prerequisites: build:happ must have been run first
bun run build:happ
# Run all Lobby Sweettest tests
CARGO_TARGET_DIR=target/native-tests cargo test --package lobby_sweettest --test lobby
# With test output visible
CARGO_TARGET_DIR=target/native-tests cargo test --package lobby_sweettest --test lobby -- --nocapture
# Run a single test
CARGO_TARGET_DIR=target/native-tests cargo test --package lobby_sweettest --test lobby announce_group_cross_conductor
Group DNA Sweettest
Tests live in dnas/group/tests/src/group/mod.rs. Covers group creation, get_group (fetch by hash), get_my_group, membership (join/leave/is_member/duplicate-join guard), work logs (log_work, get_work_logs, get_my_work_logs, delete_work_log), soft links (create_soft_link, get_soft_links, delete_soft_link), update_group, and validation rejection cases (empty name, zero hours).
Note: Each test spins up 2 Holochain conductors. Running all 13 tests concurrently requires
--test-threads 6(12 conductors max) to avoid port/resource contention.
# Prerequisites: build:happ must have been run first
bun run build:happ
# Run all Group Sweettest tests (thread-limited to avoid conductor contention)
CARGO_TARGET_DIR=target/native-tests cargo test --package group_sweettest --test group -- --test-threads 6
# With test output visible
CARGO_TARGET_DIR=target/native-tests cargo test --package group_sweettest --test group -- --test-threads 6 --nocapture
# Run a single test (no thread limit needed)
CARGO_TARGET_DIR=target/native-tests cargo test --package group_sweettest --test group join_group_creates_membership
# NDO anchor tests (second binary in the same package)
CARGO_TARGET_DIR=target/native-tests cargo test --package group_sweettest --test ndo_anchor
NDO Layer 0 tests (--test nondominium)
# Run all NDO Layer 0 tests
CARGO_TARGET_DIR=target/native-tests cargo test --test nondominium
# Run a single scenario
CARGO_TARGET_DIR=target/native-tests cargo test --test nondominium ndo_cross_agent_discovery
🎭 E2E (Playwright + real conductors)
Browser-level coverage of the Lobby → Group → NDO holarchy against real conductors. Full
detail, architecture, and debugging notes: ui/tests/README.md.
bun run build:happ # once, or after zome changes — e2e does NOT rebuild
bun run e2e # headless
bun run e2e:ui # Playwright UI mode (debugging)
E2E_PLAYGROUND=1 bun run e2e # also start `hc playground` for DHT inspection
📋 Tryorama (TypeScript) — DEPRECATED
Do not write new tests here. Everything below documents the legacy Tryorama suite in
tests/, kept as historical reference only and no longer maintained. New tests go in Sweettest (above). Migration status:tests/DEPRECATED.md.
Basic Test Commands (legacy)
All commands automatically build zomes and package the hApp before running tests.
# Run all tests
bun tests
# Run tests with verbose output
bun tests --reporter=verbose
# Run tests in watch mode for development
bun tests --watch
# Generate coverage reports
bun tests --coverage
🎯 Pattern-Based Test Selection
The test system uses file name pattern matching to run specific test subsets:
# Run all person-related tests
bun tests person
# Run all resource-related tests
bun tests resource
# Run all governance-related tests
bun tests governance
# Run all PPR system tests
bun tests ppr
📂 Layer-Specific Test Patterns
# Run all foundation tests (basic connectivity)
bun tests foundation
# Run all integration tests (multi-agent interactions)
bun tests integration
# Run all scenario tests (complete user workflows)
bun tests scenario
🔧 Specific Test Files
# Run specific test files using partial name matching
bun tests person-foundation
bun tests person-integration
bun tests person-scenario
bun tests resource-foundation
bun tests resource-integration
bun tests resource-scenario
bun tests ppr-foundation
bun tests ppr-integration
bun tests ppr-scenarios
bun tests ppr-cryptography
bun tests ppr-debug
bun tests person-capability
bun tests governance-foundation
🎯 Development Workflow Commands
# Development with hot reload
bun tests --watch person
# Debug specific test with verbose output
bun tests --reporter=verbose ppr-foundation
# Run tests for a specific feature area
bun tests resource
bun tests governance
bun tests person
🧹 Test Quality & Type Checking
# Run tests with type checking
bun tests --typecheck
# Run type checking only (from tests directory)
cd tests && npm run check
# Run tests with coverage analysis
bun tests --coverage
💡 Test Development Tips
Test Isolation During Development
Sweettest (Rust): mark unfinished tests #[ignore], or filter by name with cargo test <name>.
Tryorama (legacy): use .only() on specific test blocks to run single tests:
describe.only('specific test suite', () => { ... }) // Run only this suite
it.only('specific test', async () => { ... }) // Run only this test
test.only('specific test', async () => { ... }) // Run only this test
Rust Zome Debugging
Use the warn! macro in Rust zome functions to log debugging info:
#![allow(unused)] fn main() { warn!("Debug info: variable = {:?}", some_variable); warn!("Checkpoint reached in function_name"); warn!("Processing entry: {}", entry_hash); }
📦 Tryorama legacy reference (deprecated)
Everything in this section describes the deprecated
tests/suite. Kept for archaeology.
📊 Test File Structure
tests/src/nondominium/
├── person/ # bun tests person
│ ├── person-foundation-tests.test.ts
│ ├── person-integration-tests.test.ts
│ ├── person-scenario-tests.test.ts
│ └── person-capability-based-sharing.test.ts
├── resource/ # bun tests resource
│ ├── resource-foundation-tests.test.ts
│ ├── resource-integration-tests.test.ts
│ ├── resource-scenario-tests.test.ts
│ └── resource-update-test.test.ts
├── governance/ # bun tests governance
│ ├── governance-foundation-tests.test.ts
│ └── ppr-system/ # bun tests ppr
│ ├── ppr-foundation.test.ts
│ ├── ppr-integration.test.ts
│ ├── ppr-scenarios.test.ts
│ ├── ppr-cryptography.test.ts
│ └── ppr-debug.test.ts
└── misc/ # bun tests misc
└── misc.test.ts
🎯 Recommended Testing Workflow
- Feature Development:
bun tests --watch <feature-area> - Specific Test Debugging:
bun tests --reporter=verbose <specific-test> - Pre-commit Validation:
bun tests foundation && bun tests --typecheck - Full Validation:
bun tests && bun tests --coverage
🔍 Pattern Matching Rules
The bun tests command uses Vitest's file filtering:
- Prefix Matching:
bun tests personmatches all files starting with "person-" - Partial Matching:
bun tests foundationmatches all files containing "foundation" - Specific Files: Use unique parts of filenames for precise selection
- Multiple Patterns: Chain multiple patterns for broader coverage
⚡ Performance Tips
- Use Specific Patterns:
bun tests person-foundationis faster thanbun tests person - Foundation First: Run foundation tests before integration/scenario tests
- Parallel Execution: Tests run in parallel by default for maximum speed
- Verbose Output: Use
--reporter=verbosefor debugging but not for routine runs
All commands run from the project root and automatically handle the complete build → test cycle! 🚀
Environment: Requires Nix development environment (nix develop) for Holochain binaries.
E2E Test Suite (Playwright + real conductors)
Browser-level end-to-end coverage of the Lobby → Group → NDO holarchy against
real Holochain conductors — no mocks. Sweettest (dnas/nondominium/tests/)
remains the primary backend suite; this suite covers the UI-to-conductor
integration seam and the multi-agent UX (invite join, member self-heal,
cross-agent visibility) that Sweettest cannot exercise through the UI.
Running
# From the repo root, inside the nix dev shell:
bun run build:happ # once, or after zome changes
nix develop --command bun run e2e # headless run
nix develop --command bun run e2e:ui # Playwright UI mode (debugging)
bun run e2e does NOT rebuild the happ — global-setup fails fast with a hint
if workdir/nondominium.happ is missing. First run of bun install may also
need cd packages/shared-types && bun run build (types resolve from its
gitignored dist/).
To inspect DHT state interactively alongside a run, set E2E_PLAYGROUND=1
(the launcher then also starts hc playground).
Architecture
- Conductor manager:
scripts/launch-happ.mjsin E2E mode (E2E=1) — the same harness asbun run network. Two conductors + two Vite dev servers, one origin per agent (ports 6173/6174, deliberately distinct from the dev network's 5173+ so leftover-process port guards can never kill a dev session). Sandboxes live under the fixed short workdir/tmp/ndo-e2e/sandbox(lair-keystore's unix-socket path must stay under the ~108-byte SUN_LEN limit, and$TMPDIRis unstable across nestednix developshells). - Setup/teardown:
tests/setup/global-setup.tsspawns the launcher detached (own process group) and polls/tmp/ndo-e2e/ready.json+ HTTP 200 per UI origin;global-teardown.tskills the whole process group and then reaps by port. Leftovers are killed by port, neverpkill -f <workdir>(which matches the killing shell's own argv). - Seeding client:
tests/setup/harness.tscreateSeedClient()— direct zome calls from Node for prerequisites and DHT read-backs. Node ws clients must send an explicitOriginheader, and must re-authorize signing credentials in their own process (credentials are per-process in @holochain/client). Never seed the exact thing a test claims to verify. - Specs: ordered stories, single worker (
workers: 1) — Holochain state is shared and ordered.core-flows.spec.ts(Phase 0 harness guards + Phase 1 single-agent flows),multi-agent.spec.ts(Phase 2 two-agent flows). Cross-agent assertions always poll viaexpectEventually, which drives the UI's own pull-refresh (focus/visibility triggers) rather than reloading.
Conventions
- Discovered app bugs: when a spec fails because of a real application bug
(not a test bug), capture it in
.local/e2e-discovered-bugs.md(local handoff doc), TODO-mark the spec with a reference, and fix the bug in its own PR — never paper over it in the test. - Pending-backend assertions: features tied to unmerged PRs are TODO-marked in the specs with the PR number (currently #114 profile sync, #117 NDO-per-cell anchors, backend Phase 2.3 transition history).
ArtCoin
ArtCoin is a protocol for the circulation and stewardship of physical artworks, built on the Nondominium protocol.
Core Documentation
- ArtCoin Overview (Non-Technical) - A standalone description of the project vision and goals for artists and stakeholders.
- ArtCoin Integration (Technical) - Mapping of ArtCoin onto the Nondominium architecture (NDO layers, PPR categories, implementation status).
- Original Main Doc (External) - Project planning and external links.
User Stories
- ArtCoin Lifecycle - Maya the artist, Amara the individual adopter, and the journey of an artwork.
- Art Distribution - Touring exhibitions and venue-to-venue coordination.
- Art Production - Collaborative creation and hREA/TrueCommon integration.
External Links
Nondominium Support for Artcoin
Status: Application design document. Maps the Artcoin use case onto the current Nondominium architecture (NDO three-layer model, governance-as-operator, PPR reputation). Where a flow depends on capabilities that are not yet in the MVP code, this is called out explicitly in §5 Implementation Status.
See also:
artcoin_main_doc.md,user-story/user-story-artcoin.md,user-story/user-story-art-distribution.md,user-story/user-story-art-production.md.
1. Summary of Artcoin in the Context of Nondominium
Artcoin (also referred to as the Internet of Art, or IoA) is a platform designed to disintermediate the art market and enable the scalable circulation of artworks. It builds on the "Soogart" and "L'Artothèque" models, where artworks are displayed in public and private venues (restaurants, offices, cafés) rather than traditional galleries, allowing the public to discover, enjoy, rent, or adopt art in their daily environments.
In the context of Nondominium, Artcoin is a specific application domain built on top of the generic Nondominium hApp. The core philosophy of Artcoin — making art accessible, creating a sharing economy for creative works, and ensuring fair compensation for creators — aligns closely with Nondominium's goal of organization-agnostic, capture-resistant, self-governed resources.
By leveraging Nondominium's infrastructure, Artcoin can transition from a centralized or low-tech agency model to a fully distributed, peer-to-peer ecosystem where:
- Artworks are modelled as Nondominium Objects (NDOs). Each artwork carries a
permanent identity anchor (
NondominiumIdentity, Layer 0) whoseproperty_regimecan bePrivate(the artist retains ownership and control),Commons, orNondominium(uncapturable, contribution-based access). The regime is chosen at creation and governs which transfers and agreements are valid for that artwork — giving artists explicit, machine-readable control over how their work circulates while still enabling permissionless discovery and display. - Reputation for every party involved (artists, venues, individual art lovers, and support agents such as transporters and storers) is tracked via Private Participation Receipts (PPRs) — bilaterally signed, private, user-sovereign receipts — establishing trust without a central middleman.
2. Supporting Artcoin with Nondominium
Nondominium provides the primitives to model the entire lifecycle of an artwork within the Artcoin ecosystem: from creation, through display and circulation, to adoption, storage, or end-of-life.
2.1 Core Agents and Roles
The Artcoin ecosystem maps directly onto Nondominium's agent and role model
(RoleType in zome_person):
- Artists (Accountable Agents):
- Create a
ResourceSpecificationfor a body of work (the artwork template). - Create the artwork's NDO: a
NondominiumIdentity(Layer 0) plus itsEconomicResourceinstance (the physical piece), starting in the artist's custody. - Define embedded
GovernanceRuleentries (e.g. "70% of any sale goes to the artist", "rent is $30/month", "must be displayed in a smoke-free environment").
- Create a
- Venue Owners (Primary Accountable Agents / Custodians):
- Café, restaurant, or office owners who act as Custodians of an artwork.
- Accept
Commitmententries to store and display the art. - Are accountable for the well-being of the resource while it is in their custody.
- Transporters (Accountable Agents with the
Transportrole):- Move art between a current custodian and a new one (artist → venue, venue → venue, or venue/artist → an individual art lover).
- Require a validated
Transportrole (e.g. proof of insurance or suitable vehicle), granted through peer validation.
- Storers (Accountable Agents with the
Storagerole):- Temporarily hold art between custodians — for example when an adoption or rental period ends and no new custodian is immediately ready.
- Require a validated
Storagerole (e.g. proof of insurance or suitable, climate-controlled space).
- Individuals / Art Lovers (Simple or Accountable Agents, and Custodians):
- Discover art in venues or by searching Nondominium.
- Can buy, rent, or adopt art, becoming Custodians in their own right.
- Initiate Use interactions (viewing/renting) or custody transfers (buying/adopting).
A Simple Agent joins permissionlessly; after their first validated transaction they are promoted to Accountable Agent (
REQ-GOV-02,REQ-GOV-03). Specialized roles (Transport,Storage,Repair) require validation by existing role holders (REQ-GOV-04).
2.2 Modelling an Artwork as an NDO
Artcoin uses the NDO three-layer model
(documentation/requirements/ndo_prima_materia.md):
| NDO Layer | Entry | Artcoin meaning |
|---|---|---|
| Layer 0 — Identity | NondominiumIdentity | The artwork's permanent, immutable identity anchor. Carries property_regime (Private/Commons/Nondominium), resource_nature (Physical for a canvas, Hybrid for a physical piece with a digital twin), and lifecycle_stage. Its action_hash is the stable artwork ID for provenance. |
| Layer 1 — Specification | ResourceSpecification + GovernanceRule | The artwork's form and rules: title, medium, dimensions, images, care instructions, and embedded governance (revenue split, rental fee, display conditions). |
| Layer 2 — Process | EconomicEvent, Commitment, Claim, PPRs | The activity around the artwork: custody transfers, display commitments, transport/storage services, and the receipts they generate. |
Two orthogonal state dimensions apply:
LifecycleStage(on Layer 0) tracks the artwork's maturity — e.g.Ideation→Specification→Stable→Active, and eventuallyDeprecated/EndOfLife.OperationalState(on theEconomicResourceinstance) tracks the current process condition —Available,Reserved,InTransit,InStorage,InMaintenance,InUse,PendingValidation. A freshly registered artwork startsPendingValidation; while displayed at a venue it isInUse; en route it isInTransit; while held by a storer it isInStorage.
2.3 Core Processes and Transactions
Nondominium's economic model captures the circulation of art. Each step below names
the ValueFlows action (VfAction) and the PPRs it generates.
Process 1 — Onboarding and Creation
- The artist creates a
ResourceSpecificationfor a collection (e.g. "Oil on Canvas 2025"). - The artist creates the artwork's
NondominiumIdentityand itsEconomicResourceinstance. The resource starts in the artist's custody withOperationalState::PendingValidation. - Peer validation (
validate_new_resource) moves it toAvailableand generates aResourceCreationPPR for the artist and aResourceValidationPPR for the validator.
Process 2 — Distribution (current custodian → venue or individual)
- A venue owner or individual signals interest in displaying or holding the art.
- Transport process (
VfAction::TransferCustody,Transportrole):- A transporter commits to move the piece (
Commitment). - Custody transfer: the current custodian (often the artist) transfers custody to
the transporter →
CustodyTransferPPR for the sender; the resource becomesInTransit. - The transporter delivers to the new custodian.
- Custody acceptance: the venue owner or individual accepts custody →
CustodyAcceptancePPR; the transporter also earns aTransportFulfillmentCompletedPPR. - The artwork is now
InUse(on display) at the venue, or held by the individual.
- A transporter commits to move the piece (
Process 3 — Storage (current custodian → storer → future custodian)
- The current custodian (e.g. a venue) signals that a rental/adoption period has ended and no new custodian is immediately ready, requesting storage.
- Storage process (
VfAction::TransferCustody,Storagerole):- A storer commits to hold the piece until a new agent wants to buy, rent, or
adopt it (per the artwork's governance rules) —
StorageCommitmentAcceptedPPR. - Custody transfer: the current custodian transfers custody to the storer →
CustodyTransferPPR; the resource becomesInStorage. - Custody acceptance: the storer accepts custody →
CustodyAcceptancePPR; on release the storer earns aStorageFulfillmentCompletedPPR.
- A storer commits to hold the piece until a new agent wants to buy, rent, or
adopt it (per the artwork's governance rules) —
Process 4 — Display and Renting (the "Soogart" model)
- Use interaction (display): the venue "uses" the artwork to enhance its space.
- Governance rules may stipulate a fee paid to the artist and any support agents (transport, storage).
- Modelled as a continuous
Useinteraction or periodicAccessForUse(VfAction::AccessForUse) events; the resource sits inOperationalState::InUse.
- Discovery: an individual visits the venue and scans a QR code on the piece
(linked to its NDO
action_hash) to view the artwork's history, the artist's profile, and its terms.
Process 5 — Adoption (custody transfer / sale)
- Scenario: an individual decides to adopt (buy or take custody of) the piece.
- Commitment: the individual makes a
Commitmentto fulfil the adoption terms (payment, if integrated, or simply the adoption rules). - Validation: the governance zome (
zome_gouvernance) evaluates the transition between the current custodian (venue, artist, or any accountable agent) and the new custodian. - Transfer (
VfAction::TransferCustody):- The current custodian initiates
transfer_custody. - Custody moves from the current custodian to the new custodian; custodian and
location metadata are updated.
CustodyTransfer/CustodyAcceptancePPRs are generated. - Revenue sharing: where the system settles value (see §5), payment is split
according to the artwork's embedded benefit rules — modelled as an
AgreementwithBenefitClauseentries (e.g. 70% artist, 20% support actors, 10% protocol/DAO).
- The current custodian initiates
2.4 Governance and Trust
- Reputation: if a custodian damages a piece, that shows up in the performance
metrics of the PPRs they receive, lowering the reliability signal in their derived
ReputationSummary. Governance rules and counterparties can filter on this signal. Reputation is private and user-sovereign — there is no global scoreboard; agents selectively disclose a derived summary. - Validation: high-value art can require multi-reviewer validation
(
REQ-GOV-06, e.g. a 2-of-3 scheme) before a custody transfer is finalized. - Provenance / hard to clone: the NDO's permanent Layer 0
action_hashand its append-only event history prove the authenticity and lineage of the physical piece, addressing provenance and forgery.
By using Nondominium, Artcoin becomes a self-governed, capture-resistant ecosystem where art flows directly between creators and the custodians/appreciators who value it — realizing the vision of a "true sharing economy" for art.
3. Property Regimes for Art
A key strength of the NDO model for Artcoin is that artists choose the property regime per artwork, and this choice constrains what can happen to the piece:
PropertyRegime | Artcoin use | Transfer semantics |
|---|---|---|
Private | The artist (or a collector) retains full ownership; the piece can be sold, rented, or lent. | Ownership and custody transfers allowed. |
Commons | Shared cultural works — e.g. an open, remixable digital piece or a community-stewarded work. | Ownership transfer blocked; custody/stewardship and use allowed. |
Collective | Cooperative studio ownership of a shared piece. | Ownership transfer among members; custody and use allowed. |
Pool | Shared physical tools/spaces in a studio pool. | Ownership stays in pool; temporary custody scheduling. |
CommonPool | Rivalrous consumable cultural stock (e.g. limited edition materials pool). | Quota-limited extraction; no ownership alienation. |
Public | Works under public/governmental stewardship (e.g. municipal collection). | Non-alienable by the public body; custody/stewardship and use allowed. |
Nondominium | Works the artist wants to remain permanently uncapturable and contribution-access based. | Ownership transfer architecturally impossible; custody, use, and benefit flows allowed. |
Protocol and UI expose all seven regimes (
Private,Commons,Collective,Pool,CommonPool,Public,Nondominium) — seecrates/shared/src/types.rsanddocumentation/requirements/resources.md §6.3. For most Artcoin scenarios,Privateis the default, withCommons/Nondominiumavailable for artists who want stronger anti-enclosure guarantees.
4. What Nondominium Provides Today (UI)
The Nondominium reference UI (ui/) already implements the identity and NDO
foundations Artcoin builds on:
- Lobby → Group → NDO navigation. Art lovers browse a lobby of all NDOs and filter by lifecycle stage, resource nature, and property regime — the discovery surface for a gallery/venue catalog.
- Groups (DNA-backed). A venue network, an artist collective, or a city's art scene can be modelled as a group (cloned Group cell) with its own members and NDO set.
- NDO creation and lifecycle. Artists create an artwork NDO (name, property regime, nature, lifecycle stage, description) inside a group, and drive its lifecycle transitions.
- Read-only resource, governance, and activity views. Each NDO shows its specifications and economic-resource instances, its governance rules and the viewer's roles, and its economic-event history.
- Three-level identity. Level 1 (lobby profile), Level 2 (per-group disclosure
preference), Level 3 (
Personon-chain, created on first DHT-active action).
5. Implementation Status
Artcoin flows map onto Nondominium capabilities at different maturities. This section keeps the design honest about what is code-complete versus planned.
| Artcoin capability | Nondominium mechanism | Status |
|---|---|---|
| Artist/venue/individual identity, roles | zome_person (Person, PersonRole, capability tokens) | ✅ Implemented |
| Artwork identity + classification | NondominiumIdentity (Layer 0), PropertyRegime, ResourceNature, LifecycleStage | ✅ Implemented |
| Artwork spec + embedded rules | ResourceSpecification, GovernanceRule | ✅ Implemented (rules are weakly-typed JSON) |
| Artwork instance + custodian | EconomicResource, transfer_custody | ✅ Implemented (single custodian; governance/PPR wiring on transfer is Phase 2) |
| Operational condition (in transit/storage/use) | OperationalState + update_operational_state | ✅ Implemented (governance-operator transitions deferred) |
| PPR reputation (16 categories, bilateral) | zome_gouvernance PPR system | ✅ Implemented (data model); UI display not built |
| Commitments / claims / economic events | zome_gouvernance (propose_commitment, claim_commitment, events) | ✅ Implemented (backend); no user-facing UI |
| Revenue split / benefit redistribution | Agreement + BenefitClause | 🔄 Partial — data model exists; not wired to settlement |
| Payment settlement | Unyt integration (post-MVP) | 🔄 Planned (documentation/requirements/post-mvp/unyt-integration.md) |
| Structured Economic Processes (Use/Transport/Storage/Repair as first-class process entries) | initiate_economic_process / complete_economic_process (spec §4.2) | 🔄 Planned — modelled today via custody transfers + operational state + service PPRs |
| Custody UI, process UI, PPR/reputation UI, payments UI | Frontend | 🔄 Not started — service/store layers exist for custody; the rest is planned |
| Multi-custodian / co-custody (e.g. fractional adoption) | Many-to-many flows (post-MVP) | 🔄 Planned (documentation/requirements/post-mvp/many-to-many-flows.md) |
Bottom line: the identity, artwork-as-NDO, custody, and reputation primitives exist in the backend today. The Artcoin experience layer — process orchestration UI, revenue settlement (Unyt), and PPR-driven reputation display — is the roadmap ahead.
Digital Dairy Chain (DDC): Deep Dive and Nondominium Fit
This document synthesizes public materials (project sites, consortium pages, press, funding portals, and the open farm-twin repository) with the Nondominium project so we can reason about collaboration, farmer value, ecosystem role, and sustainable revenue.
1. Nondominium context (brief)
Nondominium is a Holochain hApp aligned with ValueFlows: agents, resource specifications and instances, embedded GovernanceRules, Commitments / EconomicEvents / Claims, and Private Participation Receipts (PPRs) for cryptographically grounded, selectively disclosable accountability. It targets organization-agnostic, capture-resistant coordination: peer validation, role and custody progression, process-aware flows (use, transport, storage, repair), and a roadmap toward richer identity, digital-asset integrity, and optional settlement integrations.
2. What the Digital Dairy Chain is
The Digital Dairy Chain is a UKRI Strength in Places programme (£21 million, five years) led by SRUC, aimed at transforming the dairy sector in Cumbria and South and West Scotland—described as covering the largest milk field in the UK. It is not a single product: it is a regional innovation hub combining grants, R&D access, accelerators, maker spaces, workforce planning, STEM outreach, and open-source tooling (notably farm-twin).
Public economic framing (CENSIS / partner materials): the programme is associated with ambitions on the order of 600+ new jobs and ~£60 million added to annual regional output, alongside renewal and decarbonisation of a sector producing on the order of 1.9 billion litres of milk per year in the area (figures as stated on partner pages—use for strategic context, not as audited forecasts).
Lead and consortium (SRUC page): SRUC (lead), University of Strathclyde, University of the West of Scotland, CENSIS, First Milk Ltd, Lactalis McLelland Ltd, Kendal Nutricare Ltd, Cows and Co Group Ltd, National Milk Records Plc, SmartSTEMs—10 grant-drawing partners.
3. Strategic pillars and eight initiatives
SRUC’s programme summary groups delivery into overlapping initiatives:
| Initiative | Role |
|---|---|
| Supply chain digitisation | “Digitalisation Demonstrator”; grass-to-glass connectivity; sensing and data-handling tech. |
| Innovation Brokers | Match businesses to solutions; Innovation Vouchers for novel university–business projects. |
| Collaborative R&D and growth | Large innovation grants for eligible businesses . |
| Transformational dairy research | Dairy Nexus co-innovation hub at SRUC Barony; on-farm and processing innovation; energy/waste reduction. |
| Maker Spaces | Cumbria and Ayrshire facilities for NPD, scale-up from kitchen to commercial, mentorship. |
| Milk Round Accelerator | CENSIS-led multi-year accelerator; proof-of-concept → demonstration/testing; net-zero and efficiency focus. |
| STEM engagement | SmartSTEMs-led schools/events (see §8). |
| Workforce for the future | 10–25 year skills needs review across the value chain; links education and industry. |
The public website adds cross-cutting themes: cyber security content (“farm to fork”), Think Dairy Careers, events, and case studies.
4. farm-twin: open-source digital twin (verified)
Official repository: https://github.com/digitaldairychain/farm-twin
License: GNU Affero General Public License v3.0 (AGPL-3.0) (confirmed from repository LICENSE). Implication for integrators: network-facing deployments may trigger source-offer obligations; any Nondominium integration should be reviewed with legal/compliance if farm-twin is offered as a service.
What it does (DDC announcement + BBC + GitHub blurb):
- Unified model of the whole farm system (animals to infrastructure) using real-time sensor/telemetry and other digital inputs.
- Multi-vendor data integration (e.g. health records, milk, feed, environment).
- Dashboards and predictive signals for health/productivity issues; examples include combining milk trends with health data, alerts, and automated responses (e.g. shedding gate to isolate an animal) with farmer notification.
- Simulations and legacy data import for backward compatibility.
- Positioned as scalable across farm sizes and tech maturity.
Funding attribution (public copy): Digital Dairy Chain / UKRI Strength in Places; additional mentions (e.g. Borderlands Inclusive Growth Deal) appear in third-party summaries—verify in SRUC/DDC primary sources for any formal claim.
5. Role in the farming and food ecosystem
DDC sits at the regional systems level:
| Stakeholder | How DDC engages |
|---|---|
| Dairy farmers | Digitisation demonstrator, farm-twin, brokers, vouchers, accelerators, research access; eligibility in some competitions for farming businesses. |
| Processors & manufacturers | Consortium includes major processors; NPD via Maker Space; decarbonisation and high-value products. |
| Tech / sensor / robotics SMEs | Accelerator, R&D competitions, CENSIS IoT/engineering strength. |
| Academia | SRUC, Strathclyde, UWS, CENSIS; translation to commercial impact. |
| Skills pipeline | SmartSTEMs scale; workforce review; careers narrative. |
| Policy / place | Strength in Places = place-based industrial strategy; aligns with Scottish/Cumbrian natural economy and net zero narratives. |
DDC is public–private R&D infrastructure with strong industry and university governance—not a membership co-op, though farmers can lead or collaborate on funded innovation projects.
6. Collaborative R&D portal (Innovate UK Business Connect)
The page archived below described a Digital Dairy Chain competition administered with Innovate UK: up to £2m in the round described, individual project grants £50k–£350k, 70% funding rate (subject to rules), duration 6–24 months, regional work and exploitation in Cumbria / South / West Scotland, themes including novel products, decarbonisation, waste and circularity, environment (biodiversity, soil, air, water), sensors and digitisation, animal and staff welfare, value addition. Plant-based milk alternatives and purely routine installs were out of scope in that call.
Note: The published open/close dates on that page are historical (2023). Treat as evidence of programme shape; current calls require checking Digital Dairy Chain and Innovate UK live competitions.
7. Third-party and research links
BBC (Oct 2025): Virtual dairy farm aims to transform industry — farm-twin as free to download, SRUC Barony, near–real-time multi-source aggregation, automation potential; contextual mention of satellite/wildlife tooling (separate firm).
A closely related open record is Queen’s University Belfast Pure entry for Digital-twin enabled dairy farming for greenhouse gas emission tracking (AICS 2023):
8. SmartSTEMs partnership (scale)
Per SmartSTEMs’ project page: 8,000+ pupils in DDC-themed STEM activities; 1,325+ schools (farm visits, workshops, Think Dairy events); 136+ organisations, 313+ volunteer days. This quantifies social licence and talent pipeline work adjacent to farm-twin and digitisation.
9. Compatibility: DDC and Nondominium
9.1 Strong alignment
| DDC theme | Nondominium angle |
|---|---|
| Traceable, integrated supply chain | Auditable commitment → event → claim chains; future digital resource integrity slots for attestations. |
| Multi-party R&D and grants | ValidationReceipt / ResourceValidation patterns; PPRs for delivery and collaboration quality. |
| Data from many vendors | Farm-twin aggregates upstream; Nondominium could record who attested what and under which governance rule without replacing the twin’s analytics layer. |
| Cyber security narrative | Holochain local-first and capability model reduces single-vault honeypots; complements organisational security training (not a substitute). |
| Net zero / emissions | Economic events can anchor MRV hand-offs (meter readings, management actions) as mutually signed claims between farmer, verifier, and buyer—subject to scheme rules. |
9.2 Tensions and design notes
- Architecture split: farm-twin is a Python digital-twin stack; Nondominium is a Rust/Holochain coordination layer. Pragmatic pattern: event bus or signed export from farm-twin (or lab systems) into EconomicEvents / PPRs, not a monolith.
- AGPL: Offering farm-twin as a hosted service may require AGPL compliance (source offer, etc.). A “Nondominium attestation sidecar” that is separate AGPL-wise still needs review if bundled.
- Processor power asymmetry: Consortium includes large processors; Nondominium’s uncapturable narrative must be configured so farmer-generated data and claims are not structurally subordinated—e.g. explicit custody and governance rules on resource specs for farm-origin attestations.
Overall: Compatibility is complementary. DDC solves integration, simulation, and regional capacity; Nondominium can solve portable trust, mutual accountability, and less platform lock-in for the contracts and attestations that sit around the twin.
10. Where Nondominium can help DDC add farmer value
- Innovation project integrity — Voucher and CR&D projects get tamper-evident milestones: deliverables, data handovers, and IP/contributions traced as events where parties agree.
- Milk field data dignity — Farmers retain agent-centric records of what they shared, to whom, and for which purpose (important next to NMR-class data flows).
- Processor–farmer alignment — Commitments for sustainability premiums or collection windows with claims on fulfilment reduce dispute cost.
- Accelerator outcomes — Startups ship integrations with a standard attestation hook (PPR-friendly), improving due diligence for follow-on funders.
- Regional brand — “Digitally connected and cryptographically accountable” strengthens the South Scotland / Cumbria cluster story for export and retail narratives.
11. How DDC can strengthen its value proposition and ecosystem role
- Publish a “trust stack” reference architecture — farm-twin (observation) + governance/attestation layer (Nondominium-class or other VC/ledger tech) + scheme/regulatory exports—so SMEs know where to plug in.
- Farmer data governance playbook — Template data-sharing agreements tied to technical enforcement (capabilities, expiry, scope)—aligned with existing cyber content.
- Co-op and farmer-led pilots — Balance processor-led digitisation with first-mile pilots where farmers lead grant applications (already allowed in competition rules).
- Open metrics for the programme — Jobs/GVA claims should trend toward auditable public reporting; even partial transparency builds credibility vs generic “innovation washing.”
- Interoperability, not monoculture — Encourage adapters in farm-twin for export to open standards; avoids the twin becoming the only gatekeeper.
- Post-UKRI sustainability plan — Strength in Places ends; hosted services, certification, or consortium fees for maintained infrastructure should be designed without capturing farmer data rents.
12. How Nondominium can serve farmers who participate through DDC
- Proof of participation: Workshops, trials, and demonstrator deployments recorded as reputation-relevant participation without exposing commercial secrets.
- Portability: If a farmer switches tech vendor or processor, cryptographic history of their contributions and validations can remain with their agent identity (subject to integration maturity).
- Fair dispute memory: Bilateral PPRs on loading, quality, or service visits support small operators in asymmetric supply chains.
- Selective disclosure to schemes: SFI-style or carbon narratives backed by summaries derived from structured events, not raw full-farm dumps.
13. How DDC (and partners) can improve financial returns from offering Nondominium-class infrastructure
Strategic patterns only—not tax, legal, or investment advice.
- B2B “trust module” — Charge processors and tech vendors for reference integration and support while keeping core Nondominium-style tooling FOSS or low fee for farmers.
- Verification services — Regional economy of scope: package farm-twin analytics + attested event packs for retailer audits at lower marginal cost than ad hoc consultants.
- Follow-on funding — Use audited impact traces to unlock place-based finance and green bonds; SRUC/CENSIS can capture legitimate facilitation fees.
- Training and certification — Paid courses for developers and agronomists on building adapters and interpreting attested graphs.
- Reduced programme risk — Better project accounting lowers fraud and under-delivery exposure in large grants, protecting future UKRI competitiveness.
- Premium regional products — Provable low-carbon or high-welfare batches support price premium capture shared back to farmers (contract design, not tech alone).
14. Suggested next steps (for the Nondominium project)
- Pick one DDC pathway (e.g. Milk Round winner, Maker Space cohort, or farm-twin adapter) and map three bilateral PPR stories end-to-end.
- Prototype export from a mock farm-twin event stream into EconomicEvent + Claim (file-based or API stub).
- Engage SRUC/CENSIS on non-capturing farmer data as a design constraint for any joint demo.
- Legal review of AGPL + Holochain hApp distribution if farm-twin and Nondominium are shipped together.
15. Original desk summary (archived)
The Digital Dairy Chain (DDC) is a large-scale, UK-funded initiative focused on regional economic transformation rather than a single software product. Unlike farmer-owned mutuals that act primarily as a program-based service layer, the DDC has explicitly released open-source digital infrastructure (farm-twin) to support its mission.
Digital Infrastructure & Open Source: Farm-twin is a free, open-source platform developed by SRUC agri-tech scientists. It enables farmers to build a digital model of their farming system by integrating data from animal health, milk yields, feed, environment, and more.
Architecture & Design: Public materials describe a three-layer mental model for digital twins: physical (IoT/sensors), digital (knowledge graphs/simulations), application (insights)—Nondominium fits best as an accountability and agreement layer adjacent to the application/strategy tier, not as a replacement for the twin’s simulation core.
Repository status: The official GitHub organisation is **digitaldairychain; the canonical repo is **farm-twin. Unrelated hobby repos should be ignored for diligence.
16. Official and reference links
Distributed journalism — citizen investigation
Source: Citizen Investigation (Google Doc, via MCP).
This note summarizes that document: a design-oriented treatment of peer-to-peer (P2P) citizen investigations as organizational and socio-technical systems—framed as analysis of decentralized sense-making under pressure, not as operational guidance.
Framing
The text argues that decentralized investigations should be modeled as distributed sense-making protocols, not as conventional media production. Centralized “citizen” efforts that hinge on one visible coordinator recreate a Napster-style failure mode (single choke point for pressure, law, and economics); a BitTorrent-style pattern spreads initiation, visibility, and monetization so no one node is required for the process to continue.
Conceptual model (defensive P2P)
- Pattern: Central control and intermediaries become choke points; demand diverges; repression targets visible nodes; protocols can replace platforms. P2P is framed here primarily as defensive (smaller attack surface), not only as emancipation.
- Design goals: Initiation does not imply ownership; visibility does not imply control; contribution is not tied to public attribution by default; leadership is process-shaped, not personality-shaped; value accrual is indirect, delayed, and distributed.
- Infrastructure themes: Federated or protocol-level communication; content-addressed publishing and mirroring; append-only, tamper-evident evidence logs; separation of raw data, analysis, and interpretation; pseudonymous identities with reputation from contribution quality.
- Methodology: Modular tasks (gather, verify, cross-reference, test hypotheses, synthesize); stigmergic coordination (signals on artifacts, not central directives); explicit uncertainty and coexisting interpretations; no forced consensus.
- Governance: No final “truth” authority; validation, challenge, and revision processes; forkability of datasets and narratives as a safety valve; minimal rules (formats, review, dispute signaling).
- Economics: Reward verification, sourcing, and methodology—not headline visibility; indirect monetization for initiators (reputation, future collaboration, voluntary patronage); avoid exclusive ownership of evidence, paywalls on raw material, and platform lock-in (commons-style peer production).
- Culture: Norms favor evidence over authority, process over fixed outcome, forking over faction fights; anti-hero framing—visibility rotated or diffused so the system does not depend on a spokesperson.
Commons-oriented stack (architecture sketch)
The doc specifies layers: ontology (evidence artifacts, claims, analyses, reviews, forkable narratives, contributions); infrastructure (content-addressed redundant storage; separation of storage, indexing, presentation); coordination (federated or relayed messaging; subscriptions to objects/claims); identity (pseudonymous crypto IDs; non-transferable, non-financial-by-default reputation—references to ideas like Flowsta in the original); methodology (artifact fingerprinting/time-stamping; claims that reference artifacts and decay if unmaintained; validation as privileged labor); governance (no editorial sovereign; forking as governance; boundary rules without defining “truth”); economics (monetize labor and infrastructure, not access to evidence/claims; contribution accounting with value signals that can connect to external settlement); culture (anti-celebrity UI, epistemic humility, defensive participant mindset). It explicitly asks whether stacks like Nondominium / ValueFlows could map to this.
Concrete tool landscape (excerpt)
The document surveys social protocols (e.g. Nostr, ActivityPub/Fediverse, AT Protocol, Farcaster, SSB), storage (IPFS, Filecoin, Arweave, blog tooling), and collaboration/leaks (Matrix, SecureDrop, encrypted DMs)—as a composable “off–Web2” stack for independent work.
Failure-mode analysis
Major risks analyzed include: informal re-centralization (power-law attention on a few interpreters); signal flooding (DoS on attention); ideological capture (monoculture, moralized review); economic capture via funders; legal chilling through identification; procedural ossification; fork fatigue without shared evidence pools; reputational laundering; success-induced capture (institutional absorption). The meta-point: dominant failure is often re-institutionalization, not raw shutdown. Design heuristic: mechanisms that maximize efficiency often raise capture risk; resilience favors redundancy, friction, plurality, and procedural humility.
Economics of creators and “independent investigators”
A long tab reviews influencer business models (platform ads, sponsorships, affiliates, products, subscriptions, IP, hybrids) and contrasts them with independent investigator models (direct audience funding, grants, ideological or hybrid outlets, platform monetization, merchandise, consultancy, crowdsourced investigation). It discusses competitive fragmentation in decentralized media (attention markets, tournament dynamics, Nash-style equilibria favoring conflict) and outlines a Decentralized Media Commons (DMC) direction: OVN- and DAO-inspired ideas—shared infrastructure, contribution accounting, reputation, and incentives that make collaboration economically rational (with references to commons-based peer production, Sensorica-style OVNs, and tooling such as ValueFlows / SourceCred-style accounting in the blueprint).
Closing thread
The piece ends by arguing that much infrastructure already exists; the open question is whether participants adopt coordination and value models that treat investigation as a shared epistemic substrate rather than a sequence of branded media products.
Nondominium in this context
Nondominium is a Holochain application that implements ValueFlows-shaped, agent-centric resource sharing with embedded governance and Private Participation Receipts (PPRs) for participation-backed reputation. It is explicitly aimed at a peer sharing economy and uncapturable, collaboratively governed resources (see README.md, requirements.md, and DOCUMENTATION_INDEX.md). Citizen investigation appears among the project’s adjacent application targets in strategic_development.md.
What is implemented today (relevant capabilities)
At a high level, the codebase delivers a three-zome split—person (identity, roles, capabilities, private-data access), resource (resource specifications and EconomicResource state as the data layer), governance (rule evaluation, commitments, economic events, claims, validation, PPR issuance)—documented in the index and zome docs.
For distributed investigation–style workflows, the following are concrete affordances:
- Agents and membranes: Public profiles and pseudonymous operation, role assignments, capability progression (e.g. Simple → Accountable → Primary Accountable), and time-bounded private data sharing—so participants can separate “public investigator” presence from sensitive fields without a central account database.
- Resources as first-class objects: ResourceSpecification and EconomicResource with lifecycle and governance rules attached to resources—suitable for modeling investigation bundles (e.g. a dataset, a verified extract, a collaborative case file) as resources whose access, transfer, and process use are rule-governed rather than platform-governed.
- Auditability and contribution structure: Commitments, economic events, and claims provide a traceable record of who did what to which resource and when—aligned with the Citizen Investigation doc’s emphasis on provenance, modular tasks, and accounting for verification labor rather than only narrative output.
- Peer validation: Multi-reviewer validation workflows (e.g. N-of-M) and governance-driven transitions support collective checking without a single editorial authority—overlapping the doc’s “validation / challenge / revision” and “review as labor” themes.
- Reputation from participation, not vanity metrics: PPRs (multi-category participation receipts tied to economic activity) are designed so reputation accrues from signed participation in flows, not from follower counts—closer to “review reputation” and contribution quality than to influencer economics.
The Svelte UI and Tryorama test suites exercise these paths end-to-end for the resource sharing domain; applying the same primitives to journalism-specific resource specs and governance patterns is largely a modeling and UX exercise on top of existing APIs.
What is planned or in flight (how the fit improves)
Roadmap and architecture docs describe directions that strengthen the match to commons-based and OVN-style investigation economics:
- hREA integration (
integration-strategy.md): richer ValueFlows types and cross-DNA economic operations—useful when investigations need full VF graphs (processes, agreements, fuller commitment/event semantics) while keeping governance and PPR generation atomic with events. - NDO / generic object model (
ndo_prima_materia.md): a more explicit Nondominium Object lifecycle, capability surface, and migration story—relevant if “evidence artifact / claim / narrative fork” become first-class product concepts beyond today’s resource-centric MVP. - Optional post-MVP bridges: Unyt (economic settlement / proofs) and Flowsta (portable identity across apps)—sketched in
post-mvp/—for teams that want external settlement or cross-app identity without re-centralizing the investigation graph.
Requirements also spell out post-MVP agent and organization modeling (collectives, projects, bots, affiliation rules); today’s MVP emphasizes individual agents, so newsroom- or collective-as-agent patterns are design targets, not fully realized in code yet.
How this maps to the Citizen Investigation stack
The Google Doc asks for a protocolized commons: separation of raw data / analysis / interpretation, stigmergic coordination on artifacts, forkability, contribution accounting, and defensive economics. Nondominium does not replace broadcast (Nostr, Fediverse), large-file permanence (IPFS, Arweave), or anonymous drops (SecureDrop)—those remain complementary layers. Where it does plug in is as a coordination and accounting substrate:
| Citizen investigation theme | Role of Nondominium |
|---|---|
| No single owner of the investigation graph | Peer-hosted Holochain data; governance on resources instead of a platform operator |
| Traceable contributions and verification labor | Economic events, commitments, PPRs, validation workflows |
| Reputation without “hero” centrality | PPR categories and role/capability progression tied to validated participation |
| Forkable interpretations | Composable resources and distinct resource specs / instances can represent parallel lines of inquiry; fuller fork semantics may deepen with NDO/hREA |
| Commons-compatible value flows | ValueFlows alignment and planned hREA depth for OVN-style value accounting |
In short: Nondominium can serve citizen investigation and distributed journalism as the Holochain-native layer for governed shared resources, auditable contributions, and participation-based reputation—with public narrative and bulk evidence storage still typically composed from federated or content-addressed tools the stack was designed to interoperate with conceptually, not to duplicate wholesale.
ERP-Holochain Bridge: Connecting ERPLibre to Nondominium
1. Introduction
This document outlines a strategy for bridging traditional Enterprise Resource Planning (ERP) systems with Nondominium's peer-to-peer resource-sharing infrastructure using a Node.js Bridge Service powered by the official @holochain/client library. The goal is to enable organizations using centralized ERP systems to participate in decentralized resource economies without abandoning their existing business infrastructure.
2. Problem Statement
2.1 The Challenge
Organizations currently manage their inventory, equipment, and resources using centralized ERP systems (e.g., Odoo, SAP, ERPNext). While these systems excel at internal management, they create data silos that prevent resource sharing across organizational boundaries.
Current limitations:
- No cross-organizational visibility: Organization A cannot see if Organization B has idle equipment that could be borrowed.
- Trust barriers: Ad-hoc resource sharing requires manual coordination, legal contracts, and trust-building overhead.
- Platform dependency: Centralized marketplaces (e.g., equipment rental platforms) extract rent and control access.
- Data sovereignty concerns: Organizations are reluctant to upload sensitive inventory data to third-party platforms.
2.2 The Opportunity
Nondominium offers a peer-to-peer, organization-agnostic resource-sharing layer that can complement existing ERP systems:
- Resources can be selectively published from ERP inventory to Nondominium without migrating away from the ERP.
- Organizations retain full sovereignty over their data and participation.
- Reputation tracking (PPR system) replaces heavy legal contracts with cryptographic accountability.
- Emergent coordination via stigmergy reduces the need for manual negotiation.
3. The ERPLibre Context
3.1 What is ERPLibre?
ERPLibre is an open-source "soft fork" of Odoo Community Edition, released under the AGPLv3 license. It automates deployment, development, and maintenance of Odoo.
Key characteristics:
- Language: Python (backend), JavaScript (frontend)
- Architecture: Monolithic web application with PostgreSQL database
- Modules: Inventory management, sales, purchases, accounting, manufacturing
- API: XML-RPC and JSON-RPC endpoints
- Deployment: Docker-based, with
docker-compose.ymlfor easy setup
3.2 ERPLibre Inventory Management
ERPLibre (via Odoo) manages inventory through:
- Product Templates: Define product specifications (SKU, name, category, unit of measure)
- Product Variants: Specific instances of products (size, color, etc.)
- Stock Locations: Warehouses, storage zones, etc.
- Stock Moves: Transfers between locations, with full traceability
- Quants: Quantities on hand for each product/location combination
Relevant Odoo Models:
product.product: Individual productsstock.quant: Available quantities per locationstock.move: Movement history and planned transfersstock.warehouse: Physical locations
4. The Nondominium Context
4.1 What Nondominium Offers
Nondominium is a Holochain-based, ValueFlows-compliant application for distributed resource management:
- Agent-centric: Each organization runs its own node
- Peer-to-peer: No central server; resources exist in a shared DHT
- Embedded governance: Rules are encoded in
ResourceSpecifications - Reputation layer: Private Participation Receipts (PPRs) track reliability
4.2 Key Data Structures
To bridge ERP inventory to Nondominium, we need to map:
| ERP Concept | Nondominium Concept | Notes |
|---|---|---|
| Product Template | ResourceSpecification | Defines what can be shared |
| Product Variant | EconomicResource | Specific instance available for sharing |
| Stock Location | Resource location field | Where the resource is physically located |
| Available Quantity | quantity in EconomicResource | How much is available |
| Stock Move | EconomicEvent (Transfer, Use) | History of resource movements |
5. Implementation Scope
5.1 Minimal Viable Demonstration
Objective: Demonstrate that inventory from two organizations running ERPLibre can be synchronized to Nondominium and made discoverable for sharing.
Scenario:
- Organization A has a 3D printer listed in its ERPLibre inventory
- Organization B has a laser cutter listed in its ERPLibre inventory
- Both organizations publish their available equipment to Nondominium via the Node.js Bridge
- Each organization can discover the other's equipment via Nondominium
- Organization B initiates a Use process for Organization A's 3D printer
- The usage is recorded as an
EconomicEventin Nondominium - Real-time signals notify Organization A of the resource usage
- The usage is reflected back to Organization A's ERPLibre as a "Loan" or "External Use" stock move
5.2 Requirements
Functional Requirements:
- FR-1: Read inventory data from ERPLibre via its API
- FR-2: Map ERPLibre products to Nondominium
ResourceSpecificationentries - FR-3: Publish selected inventory items as
EconomicResourceentries in Nondominium - FR-4: Query Nondominium for available resources from other organizations
- FR-5: Initiate a
Useprocess in Nondominium for a discovered resource - FR-6: Record the
EconomicEventand generate PPRs for both parties - FR-7: Subscribe to Holochain signals for real-time updates
- FR-8: Handle bidirectional sync (Nondominium → ERPLibre)
Non-Functional Requirements:
- NFR-1: The bridge should not require modifications to ERPLibre core code
- NFR-2: The bridge should be deployable as a separate service/container
- NFR-3: Support real-time synchronization via WebSocket signals
- NFR-4: Handle proper zome call signing and capability management
- NFR-5: Provide caching, batching, and retry logic
6. Bridge Architecture: Node.js Bridge Service
6.1 Architecture Overview
The bridge uses a Node.js service that wraps the official @holochain/client library to provide a RESTful API for ERPLibre while maintaining full WebSocket connectivity to Holochain.
Architecture:
ERPLibre (Python) <--HTTP/JSON--> Node.js Bridge (@holochain/client) <--WebSocket--> Holochain Conductor <--> Nondominium DHT
Key Components:
- Node.js Bridge Service: Express/Fastify server exposing RESTful endpoints
- @holochain/client: Official Holochain WebSocket client
- Webhook Handler: Push real-time signals from Holochain to ERPLibre
- Cache Layer: Redis for frequently accessed data
- Queue System: Bull/BullMQ for async operations
6.2 Why Node.js Bridge?
Advantages:
- ✅ Full feature support: Access to all
@holochain/clientfeatures (signals, zome call signing, etc.) - ✅ Real-time signals: Subscribe to Holochain signals and push to ERPLibre via webhooks or SSE
- ✅ Official library: Maintained by Holochain core team with ongoing support
- ✅ Flexible: Can customize bridge logic (caching, batching, request aggregation)
- ✅ Production-ready: Built-in error handling, retry logic, and connection management
- ✅ Proper signing: Full control over zome call signing and capability token management
Trade-offs:
- ⚠️ Extra runtime: Requires Node.js alongside Python
- ⚠️ Custom code: Need to write and maintain the bridge service
- ⚠️ Polyglot stack: Python + Node.js + Holochain
6.3 Alternative Approaches (Not Recommended)
HTTP Gateway (hc-http-gw):
- ❌ Limited to GET requests with Base64-encoded payloads
- ❌ No native signal support
- ❌ Requires workarounds for RESTful patterns
- ❌ Performance constraints (single call per request)
Direct Python WebSocket Client:
- ❌ Must implement entire Conductor API protocol
- ❌ Complex Ed25519 signing in Python
- ❌ High maintenance burden (no official client)
- ❌ Must track Holochain protocol changes
7. Node.js Bridge Implementation
7.1 Core Bridge Service
// bridge-service.js
import { AppWebsocket, AdminWebsocket } from '@holochain/client';
import express from 'express';
import { createClient } from 'redis';
import Bull from 'bull';
class NondominiumBridge {
constructor(config) {
this.appWs = null;
this.adminWs = null;
this.redis = createClient({ url: config.redisUrl });
this.queue = new Bull('nondominium', config.redisUrl);
this.config = config;
}
async connect() {
// Connect to Holochain Admin API
this.adminWs = await AdminWebsocket.connect({
url: new URL(this.config.adminWsUrl),
wsClientOptions: { origin: this.config.appId }
});
// Connect to App WebSocket
const token = await this.adminWs.issueAppAuthenticationToken({
installed_app_id: this.config.appId
});
this.appWs = await AppWebsocket.connect({
url: new URL(this.config.appWsUrl),
token: token.token,
wsClientOptions: { origin: this.config.appId }
});
// Subscribe to signals
this.appWs.on('signal', this.handleSignal.bind(this));
await this.redis.connect();
console.log('Bridge connected to Holochain and Redis');
}
async handleSignal(signal) {
console.log('Received signal:', signal);
// Push signal to ERPLibre via webhook
await this.notifyERPLibre(signal);
}
async notifyERPLibre(signal) {
// POST to ERPLibre webhook endpoint
const response = await fetch(this.config.erpWebhookUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
type: signal.data.type,
payload: signal.data.payload
})
});
console.log('Notified ERPLibre:', response.status);
}
async callZome(cellId, zomeName, fnName, payload) {
const cacheKey = `zome:${zomeName}:${fnName}:${JSON.stringify(payload)}`;
// Check cache for read operations
if (fnName.startsWith('get_')) {
const cached = await this.redis.get(cacheKey);
if (cached) return JSON.parse(cached);
}
try {
const result = await this.appWs.callZome({
cell_id: cellId,
zome_name: zomeName,
fn_name: fnName,
payload: payload
}, 30000);
// Cache read operations
if (fnName.startsWith('get_')) {
await this.redis.setEx(cacheKey, 300, JSON.stringify(result));
}
return result;
} catch (error) {
console.error('Zome call failed:', error);
throw error;
}
}
async createResource(cellId, specHash, quantity, unit, custodian) {
return this.callZome(cellId, 'zome_resource', 'create_economic_resource', {
conforms_to: specHash,
quantity: quantity,
unit: unit,
custodian: custodian
});
}
async searchResources(cellId, query = null) {
return this.callZome(cellId, 'zome_resource', 'get_all_resources', {
query: query
});
}
async initiateUseProcess(cellId, resourceHash, receiver, startTime, endTime) {
return this.callZome(cellId, 'zome_resource', 'initiate_use_process', {
resource_hash: resourceHash,
receiver: receiver,
start_time: startTime,
end_time: endTime
});
}
async getReputationSummary(cellId, agentId) {
return this.callZome(cellId, 'zome_gouvernance', 'get_reputation_summary', {
agent: agentId
});
}
}
// Initialize bridge
const bridge = new NondominiumBridge({
adminWsUrl: process.env.HC_ADMIN_WS_URL || 'ws://localhost:8000',
appWsUrl: process.env.HC_APP_WS_URL || 'ws://localhost:8888',
appId: process.env.HC_APP_ID || 'nondominium',
redisUrl: process.env.REDIS_URL || 'redis://localhost:6379',
erpWebhookUrl: process.env.ERP_WEBHOOK_URL || 'http://localhost:8069/nondominium/webhook'
});
await bridge.connect();
7.2 REST API Endpoints
// api-routes.js
const app = express();
app.use(express.json());
// Helper to extract cell_id from request
function getCellId(req) {
return [req.body.dna_hash || req.query.dna_hash, req.body.agent_key || req.query.agent_key];
}
// Resource Management
app.post('/api/resources', async (req, res) => {
try {
const cellId = getCellId(req);
const result = await bridge.createResource(
cellId,
req.body.spec_hash,
req.body.quantity,
req.body.unit,
req.body.custodian
);
res.json({ success: true, data: result });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
app.get('/api/resources', async (req, res) => {
try {
const cellId = getCellId(req);
const resources = await bridge.searchResources(cellId, req.query.q);
res.json({ success: true, data: resources });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
app.post('/api/resources/:hash/use', async (req, res) => {
try {
const cellId = getCellId(req);
const result = await bridge.initiateUseProcess(
cellId,
req.params.hash,
req.body.receiver,
req.body.start_time,
req.body.end_time
);
res.json({ success: true, data: result });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
// Reputation
app.get('/api/reputation/:agent_id', async (req, res) => {
try {
const cellId = getCellId(req);
const summary = await bridge.getReputationSummary(cellId, req.params.agent_id);
res.json({ success: true, data: summary });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
// Batch operations
app.post('/api/batch', async (req, res) => {
try {
const cellId = getCellId(req);
const results = await Promise.all(
req.body.operations.map(op =>
bridge.callZome(cellId, op.zome, op.function, op.payload)
)
);
res.json({ success: true, data: results });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
// Health check
app.get('/health', (req, res) => {
res.json({
status: 'ok',
holochain: bridge.appWs ? 'connected' : 'disconnected',
redis: bridge.redis.isOpen ? 'connected' : 'disconnected'
});
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Bridge service running on port ${PORT}`);
});
8. ERPLibre Integration
8.1 Reading ERPLibre Inventory (Python)
import xmlrpc.client
import requests
import os
class ERPLibreNondominiumSync:
def __init__(self, erp_url, erp_db, erp_user, erp_password, bridge_url):
self.erp_url = erp_url
self.erp_db = erp_db
self.erp_user = erp_user
self.erp_password = erp_password
self.bridge_url = bridge_url
# Authenticate with ERPLibre
common = xmlrpc.client.ServerProxy(f'{erp_url}/xmlrpc/2/common')
self.uid = common.authenticate(erp_db, erp_user, erp_password, {})
self.models = xmlrpc.client.ServerProxy(f'{erp_url}/xmlrpc/2/object')
def get_available_products(self):
"""Fetch products with available quantity from ERPLibre"""
products = self.models.execute_kw(
self.erp_db, self.uid, self.erp_password,
'product.product', 'search_read',
[[('qty_available', '>', 0)]],
{'fields': ['name', 'default_code', 'qty_available', 'uom_id', 'categ_id']}
)
return products
def publish_to_nondominium(self, product, dna_hash, agent_key):
"""Publish a single product to Nondominium via Node.js bridge"""
# Create ResourceSpecification
spec_payload = {
'dna_hash': dna_hash,
'agent_key': agent_key,
'name': product['name'],
'description': f"SKU: {product['default_code']}",
'category': product['categ_id'][1] if product['categ_id'] else 'General',
'governance_rules': []
}
spec_response = requests.post(
f"{self.bridge_url}/api/resource-specifications",
json=spec_payload
)
spec_response.raise_for_status()
spec_hash = spec_response.json()['data']
# Create EconomicResource
resource_payload = {
'dna_hash': dna_hash,
'agent_key': agent_key,
'spec_hash': spec_hash,
'quantity': product['qty_available'],
'unit': product['uom_id'][1],
'custodian': agent_key
}
resource_response = requests.post(
f"{self.bridge_url}/api/resources",
json=resource_payload
)
resource_response.raise_for_status()
# Store Nondominium hash in ERPLibre product
resource_hash = resource_response.json()['data']
self.models.execute_kw(
self.erp_db, self.uid, self.erp_password,
'product.product', 'write',
[[product['id']], {'x_nondominium_hash': resource_hash}]
)
return resource_hash
def sync_all_products(self, dna_hash, agent_key):
"""Sync all available products to Nondominium"""
products = self.get_available_products()
results = []
for product in products:
try:
resource_hash = self.publish_to_nondominium(product, dna_hash, agent_key)
results.append({
'product_id': product['id'],
'product_name': product['name'],
'resource_hash': resource_hash,
'status': 'success'
})
print(f"✓ Published: {product['name']}")
except Exception as e:
results.append({
'product_id': product['id'],
'product_name': product['name'],
'error': str(e),
'status': 'failed'
})
print(f"✗ Failed: {product['name']} - {e}")
return results
# Usage
sync = ERPLibreNondominiumSync(
erp_url='http://localhost:8069',
erp_db='erplibre_db',
erp_user='admin',
erp_password='admin',
bridge_url='http://localhost:3000'
)
results = sync.sync_all_products(
dna_hash=os.getenv('NONDOMINIUM_DNA_HASH'),
agent_key=os.getenv('ORGANIZATION_AGENT_KEY')
)
8.2 ERPLibre Webhook Handler (Python)
# odoo_addon/nondominium_bridge/controllers/webhook.py
from odoo import http
from odoo.http import request
import logging
_logger = logging.getLogger(__name__)
class NondominiumWebhook(http.Controller):
@http.route('/nondominium/webhook', type='json', auth='none', methods=['POST'], csrf=False)
def handle_signal(self, **kwargs):
"""Handle real-time signals from Nondominium via Node.js bridge"""
data = request.jsonrequest
signal_type = data.get('type')
payload = data.get('payload')
_logger.info(f"Received Nondominium signal: {signal_type}")
if signal_type == 'resource.use.initiated':
self._handle_resource_use(payload)
elif signal_type == 'resource.transferred':
self._handle_resource_transfer(payload)
elif signal_type == 'ppr.issued':
self._handle_ppr_update(payload)
return {'status': 'ok'}
def _handle_resource_use(self, payload):
"""Update ERPLibre when a resource is used"""
resource_hash = payload.get('resource_hash')
receiver = payload.get('receiver')
# Find product by Nondominium hash
Product = request.env['product.product'].sudo()
product = Product.search([('x_nondominium_hash', '=', resource_hash)], limit=1)
if product:
# Create a stock move for "External Use"
StockMove = request.env['stock.move'].sudo()
StockMove.create({
'name': f'Nondominium Use: {receiver}',
'product_id': product.id,
'product_uom_qty': 1,
'product_uom': product.uom_id.id,
'location_id': product.property_stock_production.id,
'location_dest_id': request.env.ref('stock.stock_location_customers').id,
'state': 'done'
})
_logger.info(f"Created stock move for product {product.name}")
def _handle_resource_transfer(self, payload):
"""Update custody when resource is transferred"""
# Update internal tracking
pass
def _handle_ppr_update(self, payload):
"""Update organization reputation score"""
# Update reputation field in res.partner or custom model
pass
9. Deployment Architecture
9.1 Docker Compose Setup
# docker-compose.yml
version: '3.8'
services:
erplibre:
image: erplibre/erplibre:latest
ports:
- "8069:8069"
environment:
- POSTGRES_HOST=postgres
- POSTGRES_DB=erplibre
depends_on:
- postgres
holochain:
image: holochain/holochain:latest
ports:
- "8000:8000" # Admin WebSocket
- "8888:8888" # App WebSocket
volumes:
- ./nondominium.happ:/happ/nondominium.happ
- holochain_data:/data
command: holochain -c /data/conductor-config.yml
bridge:
build: ./bridge-service
ports:
- "3000:3000"
environment:
- HC_ADMIN_WS_URL=ws://holochain:8000
- HC_APP_WS_URL=ws://holochain:8888
- HC_APP_ID=nondominium
- REDIS_URL=redis://redis:6379
- ERP_WEBHOOK_URL=http://erplibre:8069/nondominium/webhook
depends_on:
- holochain
- redis
redis:
image: redis:7-alpine
ports:
- "6379:6379"
postgres:
image: postgres:14-alpine
environment:
- POSTGRES_DB=erplibre
- POSTGRES_USER=odoo
- POSTGRES_PASSWORD=odoo
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
holochain_data:
postgres_data:
9.2 Bridge Service Dockerfile
# bridge-service/Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "index.js"]
10. Implementation Roadmap
Phase 1: Foundation (Week 1-2)
- ✅ Set up development environment (Docker Compose)
- ✅ Deploy ERPLibre, Holochain, and Nondominium hApp
- ✅ Implement core Node.js Bridge Service with
@holochain/client - ✅ Create basic REST API endpoints
- ✅ Test WebSocket connectivity and signal handling
Phase 2: ERP Integration (Week 3-4)
- ✅ Implement Python sync script for ERPLibre inventory
- ✅ Create ERPLibre webhook handler for real-time updates
- ✅ Implement bidirectional data mapping
- ✅ Add error handling and retry logic
- ✅ Test with 2 organizations and cross-organizational discovery
Phase 3: Advanced Features (Week 5-6)
- ✅ Implement batch operations for bulk sync
- ✅ Add caching layer (Redis) for performance
- ✅ Implement queue system for async operations
- ✅ Add proper zome call signing with delegation support
- ✅ Create PPR reputation dashboard integration
Phase 4: Production Readiness (Week 7-8)
- ✅ Add comprehensive logging and monitoring
- ✅ Implement health checks and alerting
- ✅ Security audit and penetration testing
- ✅ Load testing and performance optimization
- ✅ Documentation and deployment guides
11. Next Steps
- Organizational Delegation: Implement the delegation pattern where ERPLibre users act as delegates of the organization
- UI Integration: Build native ERPLibre module for resource discovery and management
- Governance Rules: Allow organizations to configure access rules via ERPLibre UI
- Financial Integration: Connect resource usage to invoicing and accounting modules
- Multi-warehouse Support: Handle complex inventory scenarios across locations
- Mobile App: QR code scanning for custody transfers
12. References
- ERPLibre GitHub
- Holochain Client JS
- Holochain Client JS API Docs
- Odoo API Documentation
- ValueFlows Ontology
- Nondominium Requirements
- Nondominium Specifications
13. Future Architecture: Pure P2P vs. Organizational Variants
As Nondominium evolves, we envision two distinct deployment contexts: a Pure P2P context for individuals and an Organizational context (often bridged from ERPs). While the core ValueFlows logic remains consistent, the governance and identity layers diverge significantly.
The following analysis highlights key differences that may necessitate a fork or a modular architecture to support both use cases.
13.1 Identity & Delegation (The Agency Gap)
-
Pure P2P Context:
- Structure: 1 Human = 1 Agent Key.
- Agency: Direct. The individual is the sole signer and decision-maker.
- Implication: Simplifies the security model. Private keys live on the user's personal device.
-
Organizational Context:
- Structure: 1 Organization = 1 Identity (or a group of Agents).
- Agency: Delegated. The "Agent" on the DHT represents a legal entity (e.g., "Acme Corp"), but the actual signing is done by employees (e.g., Alice, Bob).
- Requirement: We need a Delegation Pattern.
- Representative Keys: Employees need their own keys that are authorized to sign on behalf of the Organization's root identity.
- Scope & Expiry: Alice might only be authorized to "Transport" resources, not "Sell" them. Bob might only be authorized to "Use" resources up to a certain value.
- Revocation: If Alice leaves the company, her delegation must be revoked immediately without changing the Organization's identity.
13.2 Reputation (PPR) Aggregation
-
Pure P2P Context:
- Accrual: Reputation (PPRs) sticks directly to the individual.
- Portability: High. The user carries their reputation everywhere.
-
Organizational Context:
- Accrual: External reputation accrues to the Organization. If Alice (the driver) delivers late, "Acme Corp" gets the negative PPR for timeliness.
- Internal Attribution: The ERP needs to track which employee caused the outcome. Nondominium might need to include a "performed_by" field in the metadata that links to an internal employee ID (hashed/private) so the organization can audit performance without exposing internal staff structures to the public DHT.
- Inheritance: A new employee starts with the Organization's reputation (trust by association), whereas a new P2P user starts from zero.
13.3 Governance: Autonomy vs. Policy
-
Pure P2P Context:
- Decision Making: Ad-hoc and autonomous. "I like your profile, I'll lend you my camera."
- Rules: Often negotiated socially or via simple template rules.
-
Organizational Context:
- Decision Making: Policy-driven and automated.
- Automated Governance: The ERP bridge might automatically approve requests based on strict criteria (e.g., "Borrower Credit Score > 700" AND "Inventory > 5 units").
- Multi-Sig/Thresholds: High-value transactions (e.g., transferring a vehicle) might require signatures from 2+ delegates (e.g., Warehouse Manager + Logistics Coordinator).
13.4 Custody vs. Ownership
-
Pure P2P Context:
- Convergence: Custody and Ownership are often the same person.
- Transfers: Usually implies a temporary transfer of possession (lending) or permanent transfer of ownership (giving/selling).
-
Organizational Context:
- Divergence: The Organization owns the resource, but an employee holds custody.
- Internal Transfers: When a drill moves from the "Warehouse" to "Service Truck 4", Nondominium might not need to know (it's internal to the agent). However, if Nondominium tracks Location, these internal shifts might need to be published without triggering a "Change of Ownership" event.
- Legal Wrapper: Interactions often imply a legal contract. The bridge might need to hash a PDF contract generated by the ERP and attach it to the
CommitmentorEconomicEvent.
13.5 Device Management & Security
-
Pure P2P Context:
- Device: Personal, single-user devices.
- Security: Biometrics or simple passwords.
-
Organizational Context:
- Device: Shared terminals (e.g., a warehouse tablet used by 10 people) or BYOD (Bring Your Own Device).
- Session Management: A shared device needs to support rapid "login/logout" of different delegates using the same Holochain Conductor, or manage multiple Agent keys securely.
- IAM Integration: Corporate users expect Single Sign-On (SSO). The bridge might need to map an OAuth token (from the ERP) to a Holochain Capability Token.
HealthNet: Rebuilding Trust in Open Medical Innovation
The Vision: An Ecosystem for Open Healthcare
Some of the world's most urgent health needs go unmet, not because solutions are impossible, but because they are unprofitable. Rare diseases, affordable therapies, and do-it-yourself (DIY) medical devices rarely attract the investment of large manufacturers. HealthNet is a project designed to change that.
HealthNet is a new model for creating, verifying, and sharing open source medical devices and software. It brings together developers, researchers, medical professionals, and patients into a single collaborative ecosystem, one where high-quality, life-improving solutions can be built in the open and trusted by everyone who depends on them. Our goal is to prove that healthcare innovation can be transparent, collaborative, and accessible to all, without sacrificing safety or quality.
The Core Concept: Trust Without Gatekeepers
Traditional medicine builds trust through a closed, accredited supply chain: a small number of certified companies design, manufacture, and distribute devices under strict regulatory oversight. This system works, but it leaves out the many valuable solutions that emerge from open communities and local makers.
HealthNet asks a simple question: How do we rebuild trust in a distributed system of production, as a genuine alternative to the traditional supply chain? The answer is a chain of trust that follows an open source design from its first sketch to certified clinical use. Every contribution, every improvement, and every validation is recorded transparently, so that a device designed by a global network of volunteers and fabricated by local makers can earn the same confidence as one produced by a traditional manufacturer.
The First Use Case: PEP Master
HealthNet grows out of a real-world initiative called PEP Master, an open venture nurtured within the Sensorica network, in collaboration with the Breathing Games network. PEP Master develops an affordable, DIY therapy instrument, a computer game paired with a hardware controller, that helps children living with cystic fibrosis practice positive expiratory pressure (PEP) physiotherapy.
Because cystic fibrosis affects a relatively small number of people worldwide, the private sector has little incentive to invest in dedicated tools. PEP Master, developed with partners including Sainte-Justine Hospital in Montreal and Breathing Games, shows how an open, community-driven approach can serve patients that the market overlooks. It is HealthNet's first proof that decentralized innovation can deliver tangible, trustworthy healthcare solutions.
Learn more about PEP Master: sensorica.co/ventures/scientific-instruments/pep-master
The Participants: A Collaborative Community
HealthNet brings together everyone who plays a role in the life of an open medical solution:
- Developers & Designers: The open source software and hardware creators who bring new devices to life. HealthNet lets them catalog their creations, collaborate across organizational boundaries, and be recognized and rewarded for their contributions.
- Researchers & Academic Institutions: University labs and clinical teams (such as Sainte-Justine Hospital and Western University) who scientifically evaluate designs, validate safety and efficacy, and mature solutions to the standards patients deserve.
- Medical Professionals: Doctors and healthcare workers who can confidently recommend open source solutions, backed by peer-reviewed evidence and a transparent record of provenance.
- Patients: The people at the heart of it all, who gain access to affordable, effective therapies and can trust the devices they rely on every day.
- Partners & Stewards: The wider network of collaborators, non-profits, technology-transfer intermediaries, and regulators (like Health Canada) that help open solutions cross the bridge from community project to certified care.
The Journey of a Medical Innovation
HealthNet provides the tools to guide an open medical solution through its entire life, without a central authority owning the process:
- Creating an Open Design: A developer registers a device or software design, defining how it may be used, shared, and improved. This "digital twin" becomes the permanent anchor for the solution's identity and history.
- Cataloging and Discovery: Contributors and communities can find existing designs, understand their provenance, and build on proven work, reducing wasteful duplication and competition.
- Fork, Remix, and Improve: Like collaborative software tools, HealthNet lets developers safely fork and remix existing creations while preserving a clear lineage. Every improvement is traceable back to what came before, so credit and provenance are never lost.
- Scientific Validation: A feedback loop connects designers with academic labs, maturing each solution to the required level of safety. When a design meets the standard, its validation is published in peer-reviewed journals, anchoring trust in independent evidence.
- A Path to Certification: With a transparent record of quality, safety, and provenance in hand, HealthNet supports the journey toward regulatory approval, offering institutions like Health Canada a new, credible pathway for solutions built outside the traditional supply chain.
- Fair Rewards and Sustainability: Every meaningful contribution, design, validation, or refinement, is recognized. HealthNet's "Trust Economy" ensures developers can earn a fair return for their work, sustaining the ecosystem over the long term.
Why HealthNet Matters
For developers, it means recognition, protection for their open work, and a sustainable way to be rewarded for building solutions that matter.
For patients and communities, it means access to affordable, trustworthy medical devices, especially for conditions the market ignores.
For the healthcare system, it means a proven, replicable model for trusting distributed innovation, opening the door to solutions that would otherwise never reach the people who need them.
HealthNet is more than a platform; it is a new way to build, verify, and share the medical innovations that improve and save lives.
Powered by Nondominium: The Foundation of Trust
HealthNet is built on the Nondominium protocol, a specialized infrastructure designed for sharing and governing resources without centralized ownership. Nondominium provides the underlying building blocks that make HealthNet's chain of trust possible:
- Nondominium Objects (NDOs): Every device design and piece of software is represented as an NDO, a permanent "digital twin" that lives on a distributed network. Its identity and full history cannot be deleted or quietly rewritten by any single operator, ensuring provenance is preserved from first draft to certified use.
- Embedded Governance: The rules that keep a design safe and open, quality standards, licensing that prevents it from being privately enclosed, and conditions for who may modify it, are baked directly into the NDO. This is what guarantees an open source solution stays open and trustworthy as it travels through the network.
- Version Tracking with Provenance: Nondominium links related designs together (as components, derivations, or successors), so that forking and remixing never severs the trail of authorship. This gives HealthNet the "Git-like" collaboration it needs while maintaining a rigorous record of lineage.
- Private Participation Receipts (PPRs): Every contribution, whether writing code, validating a device, or refining a design, generates a bilateral receipt of that "act of contribution." Stored privately by each participant, these receipts build a verifiable reputation and form the basis of HealthNet's Trust Economy, ensuring recognition and fair rewards.
- Agent-Centric Infrastructure: Every participant, developer, researcher, clinician, or patient, is a first-class "agent" who owns their own data, with no central server in the middle. This makes the HealthNet community sovereign, resilient, and private by design, well-suited to the sensitivity of the medical field.
Regen Farmers Mutual: Deep Dive and Nondominium Fit
This document synthesizes public materials, partner handbooks, and the Nondominium project requirements so we can reason about collaboration, farmer value, and business model alignment.
1. Nondominium project context (for this analysis)
Nondominium is a Holochain hApp implementing ValueFlows-aligned resource economics: agents, resources, commitments, economic events, embedded governance rules, and Private Participation Receipts (PPRs) for cryptographically grounded, privacy-preserving accountability and reputation.
At a product level it targets organization-agnostic, capture-resistant resources.
Relevance to land and environmental markets: the roadmap explicitly contemplates traceability, verifiable digital assets, DID-style identity slots , and settlement-oriented integrations, not as a single vendor stack, but as portable accountability that can attach to landscape-scale, multi-stakeholder transactions.
2. Regen Farmers Mutual (RFM): what it is
Legal form: Company limited by guarantee; farmer-governed mutual (one member, one vote; Member Council; constitution with co-designed principles). Public materials emphasize no ordinary shareholders and alignment with member interests rather than external equity maximization.
Formation: Co-designed by a large founding cohort.
Mission (consistent across sources): Help Australian farmers aggregate market power and landscape impact; engage environmental and investment markets with credible, verifiable transactions; reduce reliance on non-aligned intermediaries.
Core service pillars (from site + case studies):
- Discovery and structuring — Grants, carbon, biodiversity, philanthropy, supply chains, local economic networks; landscape-scale “investment-ready” framing.
- Digital infrastructure — “Regen Digital” — Farm-level digital twin / environmental farm assessment: mapping, environmental value metrics, scenario modelling (“what if” actions and income effects), support for compliance and market narratives.
- Collective / landscape programs — Structured engagement of farmers and landcare networks (e.g. Landscape Impact Program), Land Management Units (LMUs), pilot landholder cohorts, stakeholder mapping, theory of change, pools of capital, investor conversations.
- Human infrastructure — Regen Advisors (capacity building, onboarding, regional delivery); collaboration with Landcare, NRM, universities, Traditional Owner groups (esp. in handbook narrative).
- Governance and economics of the broker function — Farmer-owned structure; public case study material describes a 80% / 10% / 10% revenue split (farmer / supporting farmer group / mutual overheads)—use as indicative of design intent, not as legal advice.
Public positioning: “Good for the farm, good for the farmer”; regenerative practices tied to soil, carbon, biodiversity, water, drought resilience; examples include Box Gum Grassy Woodland restoration and linked carbon/planting projects (e.g. STAR / Southern Tablelands narrative on the homepage).
Scale signals (media): Reporting around a $5M raise (2022) to scale Regen Digital; references to 500+ waitlist for digital property readings and rapid growth in assessment demand; earlier equity crowdfunding (~$500k) noted in press coverage.
Traceability / standards: National traceability strategy materials and GS1 / distributed identity directions; RFM’s public story fits a broader move toward supply-chain and natural-capital attestations. Nondominium’s post-MVP digital-integrity and identity-slot work is directionally compatible with that ecosystem without requiring RFM to adopt any one chain or vendor.
3. Role in the farming ecosystem
RFM sits at a junction between:
| Layer | RFM’s role |
|---|---|
| Farm practice | Onboarding farmers to regen and natural-capital thinking; farm assessments; advisor network. |
| Landscape & community | Partner in landcare-led landscape action planning; “Pilot 10” style engagement; Working Group facilitation; regional aggregation. |
| Markets & finance | Broker / structurer for carbon, biodiversity, and blended finance; tests landscape-scale transactions; connects to investors and programs. |
| Data & platforms | Regen Digital as the system of record for farm environmental narrative and, increasingly, transaction support. |
Compared with commercial brokers, RFM stresses member ownership, surpluses returned as rebates (per case studies), and redirecting value to farmers and local farmer-support groups. Compared with industry associations, it is more market- and instrument-facing and digital-product-centric.
4. Deep dive: New Futures handbook
Landcare Victoria “Landscape Action Plan Handbook” (New Futures for Victorian Landcare), authored/published in connection with Landcare Victoria Inc. It is primary evidence for how RFM plugs into formal landscape methodology.
Partners named: Landcare Victoria, Regen Farmers Mutual, ANU Sustainable Farms, Landscape Finance Lab; funders include Ian Potter Foundation, Natural Resources Conservation Trust, and Landcare Victoria.
Methodology blend:
- 4 Returns Framework (inspiration, natural, social, financial returns) with a 20+ year horizon emphasis.
- Regen Farmers Mutual Landscape Impact Program integrated into landcare’s grassroots, self-organising model.
- Landscape Finance Lab incubation guidance—stakeholder workshops, field trips, path to investment-ready propositions.
Operational pattern:
- Working Group (diverse roles: engagement, finance, local knowledge broker, Landscape Impact Advisor, pilot landholder advocate).
- Landscape Coordinator (paid, ≥2 days/week) and Workshop Facilitator.
- Pilot 10 landholders — representative farmers; receive farm assessment (emissions estimate, LMU assessment, opportunities dialogue).
- Modules spanning onboarding, environmental markets 101, stakeholder mapping, LMUs, mapping and “farm–landscape story,” theory of change, pools of capital, investor session, financial model, plan launch, learning and improvement.
Scale of the pilot program (as stated in handbook): 1300+ people engaged; four co-designed Landscape Action Plans; ~1.75 million hectares across pilot landscapes; evaluation input from ANU Sustainable Farms.
Implication for Nondominium: the handbook describes a repeatable multi-stakeholder process with explicit farm-to-landscape linkage, assessment artefacts, and capital formation steps. That is exactly the kind of process that generates many bilateral and collective commitments—a fit for structured economic events, validation workflows, and PPR-style attestations once product maturity allows.
5. Source notes and link hygiene
- https://www.regenfarmersmutual.com/
- https://www.regenfarmersmutual.com/about
- https://www.sustainabletable.org.au/journal/case-study-regen-farmers-mutual
- https://farmingtogether.com.au/regen-farmers-mutual-case-study/
- https://www.businessnewsaustralia.com/articles/regen-farmers-mutual-launches--5m-raise.html
National traceability PDF:
https://www.agriculture.gov.au/sites/default/files/documents/national-agricultural-traceability-strategy-implementation-plan-2023-2028.pdf
6. Compatibility: RFM and Nondominium
6.1 Strong alignment
| Theme | RFM need | Nondominium capability (directional) |
|---|---|---|
| Verifiability | Credible environmental transactions; due diligence for investors and schemes. | Signed participation receipts, validation schemes, auditable commitment/event chains on Holochain. |
| Multi-party landscapes | Landcare networks, farmers, advisors, investors, Traditional Owners. | Agent-centric model; federation/holonic constructs; process-aware resources. |
| Anti-extraction narrative | Farmer-owned mutual; limit middleman capture. | Organization-agnostic resources and explicit governance-as-data; reduces platform lock-in if adopted as open protocol layer. |
| Data dignity | Farmers sensitive to surveillance and misuse of farm data. | Local-first Holochain; private entries; selective disclosure via reputation summaries (PPR design intent). |
| From assessment to market | Digital twin → instruments → payments. | ValueFlows lifecycle from specification through commitments/events; future settlement hooks (per integration stubs). |
6.2 Tensions and gaps to plan for
- Product maturity: Nondominium is still in development; RFM already operates a live Regen Digital stack. A pragmatic path is hybrid: Nondominium as attestation and contract graph alongside existing GIS/analytics tools—not a rip-and-replace GIS.
- Regulatory reporting: Carbon and biodiversity markets require compliance with scheme rules (methodologies, auditors). Nondominium can anchor what was agreed and performed between parties; scheme submission may still export to PDF/registries maintained by regulators.
- Many-to-many economics: Landscape pools may need N-ary flows. Early pilots should model pairwise attestations (farmer–advisor, farmer–buyer, landcare–farmer) until many-to-many is fully developed on nondominium.
- Adoption cost: Mutual’s advantage is shared cost of compliance; any new layer must reduce total transaction cost, not add another silo.
Overall: Compatibility is strategic and architectural, not a claim that the current Nondominium repo replaces Regen Digital today. The mutual’s theory of change (aggregate trust and verification without extractive intermediaries) is conceptually isomorphic to Nondominium’s uncapturable resource thesis.
7. Where Nondominium can help RFM add farmer value
- Mutual accountability for services — Transport, storage, advisory visits, and monitoring jobs become commitments and events with PPRs, improving dispute resolution and Regen Advisor quality signals without exposing raw farm data.
- Landscape-scale provenance — Link Pilot 10 assessments to non-repudiable records of who contributed data, who validated, and what changed over time—supporting investor-grade transparency without central data hoarding.
- Member governance in the same ledger as economics — Votes and mandates can eventually align with governance events (per OVN/REA parallel in Nondominium's
governance), reinforcing “farmer-owned” with inspectable alignment—not just marketing. - Composable “natural capital” artefacts — Treat methodologies, LMU definitions, and project recipes as resource specifications with embedded rules, enabling forking and regional adaptation (hard-to-clone through network effects and validation, not secrecy).
- Buyer and scheme confidence — Selective disclosure of reputation summaries and validation outcomes can shorten due diligence for landscape transactions RFM already pilots.
8. How RFM can strengthen its value proposition and ecosystem position
- Own the “trust layer” explicitly — Position Regen Digital as measurement + narrative, and a partner-agnostic attestation layer (potentially Nondominium-class tech) as integrity + contracts—clear buyer story.
- Standardize the Landscape Impact Program outputs — Export machine-readable project graphs (even if internal first) so every handbook iteration produces comparable LMU + intervention + capital objects.
- Double down on farmer-group economics — The 80/10/10 story is compelling; publish auditable examples of rebates and group distributions to differentiate from brokers.
- Deeper landcare + finance co-design — The handbook proves the model; scaling is templates + coordinators + honoraria—productize the role pack (Working Group job descriptions are already specified).
- Interoperability leadership — Map RFM data once to national traceability and GS1 directions so farmers are not re-keying for every scheme.
- Indigenous and ecological co-stewardship — The handbook foregrounds Traditional Owner rights; operationalize consent, benefit-sharing, and governance as first-class programme modules (Nondominium could later record agreements with appropriate privacy).
9. How Nondominium can serve farmers who are RFM clients
- Clearer rights: Custody and role semantics for who controls farm-derived attestations when advisors, schemes, and buyers interact.
- Portability: If a farmer changes broker or scheme, cryptographic history of commitments and validations can move with agent identity (subject to integration maturity), weakening lock-in.
- Fair dispute memory: Bilateral receipts mean both sides attest to what happened—reducing “he said, she said” in service failures or payment disagreements.
- Reputation without doxxing: Performance in delivery of plantings, monitoring, logistics can accumulate as summaries farmers choose to show buyers.
- Local resilience: Holochain’s offline-friendly posture can suit patchy connectivity in rural field work better than purely cloud SaaS—when implemented with deliberate UX.
10. How RFM can improve financial returns by offering Nondominium-class infrastructure
Important: This is strategic analysis, not tax or securities advice.
- New fee line: “integrity and contracts” — Charge a modest per-hectare or per-transaction fee for attested workflows layered on assessments—complementing, not replacing, existing advisory and brokerage revenue.
- Reduce churn and support costs — Fewer disputes and clearer event history lower manual case work; savings drop to mutual surplus or lower member prices.
- Premium landscape deals — Investors pay for lower diligence friction; RFM captures structuring fees or success fees on larger pooled transactions where verification depth is the differentiator.
- Partnership revenue — License methodology packs to other landcare peaks or regional NRMs with shared attestation standards—RFM becomes standards + capacity hub.
- Data without surveillance capitalism — Offer trusted analytics on aggregated, opt-in graphs; farmers pay for insights, buyers pay for confidence, RFM avoids selling raw farm surveillance as the product.
- Retention of the 80% farmer share — If integrity tooling trims broker-like leakage in the wider market, RFM’s economic story strengthens membership growth—top-line scales with trust, not only with headcount.
11. Suggested next steps (for the Nondominium team)
- Map one end-to-end RFM workflow (e.g. Pilot 10 assessment → carbon project commitment → annual monitoring) to ValueFlows primitives and identify minimum PPR types needed.
- Prototype selective disclosure for a buyer diligence packet derived from on-DHT events (mock UI acceptable).
- Engage RFM technically on whether Regen Digital APIs could emit signed events Nondominium can reference (even before full hApp integration).
- Track many-to-many flows—landscape pools will hit limits of pairwise modelling; align roadmap to landscape finance use cases early.
12. Original link list (archived)
- Regen Farmers Mutual about: https://www.regenfarmersmutual.com/about
- Main website: https://www.regenfarmersmutual.com
- Case study (Sustainable Table): https://www.sustainabletable.org.au/journal/case-study-regen-farmers-mutual
- Farming Together case study: https://farmingtogether.com.au/regen-farmers-mutual-case-study/
- Business News Australia (raise / Regen Digital): https://www.businessnewsaustralia.com/articles/regen-farmers-mutual-launches--5m-raise.html
- National agricultural traceability strategy (implementation plan PDF): https://www.agriculture.gov.au/sites/default/files/documents/national-agricultural-traceability-strategy-implementation-plan-2023-2028.pdf
Social Forests Protocol × Nondominium, a Comparative Analysis
Prepared: 2026-04-30 Revised: 2026-08-27 Scope: Architectural, economic, and governance comparison. A forest is treated as a Source (generative system), not as an owned RWA. Extracted units (timber, carbon credits, seedling lots) and financial instruments derived from them remain Resources / RWAs. Source-NDO is a specified post-MVP application profile; Layer 0 identity, Lobby → Group → NDO holarchy, and per-NDO cells are implemented.
1. Executive Summary
Social Forests Protocol and Nondominium are both working on the same hard problem: making real-world ecological systems legible, accountable, and governable on distributed infrastructure. But they solve it from opposite ends.
Social Forests enters from the market side. It builds a B2B2C commercial stack on Stellar to financialize physical trees as NFTs, distribute green cashback to consumers, and give companies verifiable ESG compliance. It is a product with a supply chain, a fiat on-ramp, and a gamified consumer loop. It tokenizes nature to make sustainability profitable.
Nondominium enters from the commons side. It builds a governance-first data layer on Holochain to track resources through their full lifecycle, with contribution-based access, bilateral accountability, and Ostromian governance rules baked in at the protocol level. Since the original version of this analysis, that model has a third ontological primitive: Source. A forest, watershed, or fishery is neither an owned EconomicResource nor an intentional Agent. It is a generative, non-ownable, partially unknowable system that yields resources, receives ecological effects, and conditions future possibilities. Nondominium models the forest as something held in common and stewarded — not something owned.
The NDO primitive is not a token. It is a permanent identity anchor (NondominiumIdentity, bound to a per-NDO cloned cell whose DnaHash is the network identity) with a property regime, a resource nature, and a lifecycle — from ideation through active use to tombstone. Applied to Social Forests' domain:
- The forest (and, at larger scale, the watershed that contains it) is a Source-NDO. It has no
primaryAccountableowner. Stewards carry obligations, not alienation rights. Boundary events — planting, harvest, biomass measurement, restoration — accumulate on its Layer 0 hash. Governance adapts from that ledger. - A tree, timber lot, or carbon quantity is a Resource yielded by that Source: inventoriable, custodied, transferable under rules.
- A MOGNO NFT / LEAF position is a financial instrument derived from those yields. It attaches to the NDO via a
CapabilitySlot::DigitalAsset(and, later,UnytAgreement) without becoming the identity of the forest.
The two projects remain deeply complementary at the infrastructure layer, have significant conceptual convergences (both invented similar two-layer asset models independently; both treat the physical system as something you measure at the boundary rather than fully model), and have six irreconcilable exclusion zones where they do the same job in architecturally incompatible ways. The sixth — ontological category — was not nameable in the April 2026 draft. It is now the deepest structural split: Social Forests makes the tree an RWA; Nondominium makes the forest a Source.
2. Project Overviews
2.1 Social Forests Protocol
| Dimension | Detail |
|---|---|
| Network | Stellar Soroban (WASM smart contracts, global ledger) |
| RWA type | African Mahogany tree (Khaya senegalensis), Brazil/Ceará |
| Token | LEAF (SEP-41 fungible, 100M cap) + MOGNO (fractional NFT, 0.001–0.1 MOGNO) |
| Business model | B2B2C — companies buy ESG impact via Stripe; consumers earn green cashback |
| Governance | Admin-key controlled (Phase 1); $FLORA DAO planned (Phase 3) |
| Oracle | Proof of Flourishing (PoF) — AI + satellite biomass/carbon validation |
| Physical supply chain | Viveiro Maravilha (seedlings) → field growth → Sómogno (processing) → Pecém Port (export) |
| Status | Phase 1 — Testnet; contracts rwa_vault, sbt_reputation, hero_journey in development |
Core loop: Company enters via Stripe → buys RWA fractions → configures green cashback → consumer earns LEAF tokens via missions → consumer burns LEAF to forge NFT → NFT represents real tree fraction → oracle validates physical growth annually → company earns ESG badge.
Three smart contracts:
rwa_vault(MognoVault): LEAF token mint/burn, B2B investment with community fund split, supply cap enforcement.sbt_reputation: Soulbound (non-transferable) impact points distributed by verified companies to consumers.hero_journey: NFT forging, rarity evolution (Plantador → Cultivador → Guardiao → Protetor → Lenda), annual tree growth records (TreeAnnualRecord), B2B mission pools, ESG Merkle root bridge (Vereda.Verify).
Architecturally notable: The hero_journey contract explicitly decouples Rarity (user commitment — driven by LEAF burned) from TreeAnnualRecord (physical tree growth — written by the oracle). A Plantador NFT can represent a 10-year-old tree. This is a deliberate and sophisticated design choice.
2.2 Nondominium — NDO, Resource, and Source
| Dimension | Detail |
|---|---|
| Network | Holochain (agent-centric DHT, no global ledger) |
| What can be an NDO | Any Resource (Physical, Digital, Service, Hybrid, Information) or a Source (generative ecological / knowledge system) |
| Identity anchor | NondominiumIdentity (Layer 0) inside a cloned ndo cell per NDO. Permanent identity is the cell's DnaHash, bound to immutable classification fields via DNA properties (ADR-010 / ADR-013). Deletes are always invalid. |
| Holarchy | Lobby DHT (federation entry) → Group cloned cells → NDO cloned cells. Groups discover NDOs via NdoAnchor. Cross-NDO composition via NdoHardLink (Component, DerivedFrom, Supersedes). |
| Economic model | ValueFlows 1.0 (Agent + Resource, via hREA DNA). Post-MVP Source profile: vf:Source as a third flow endpoint, plus extract / loading / regeneration boundary events. |
| Governance | Ostromian GovernanceRule — specified as evaluated before every state transition (Governance-as-Operator: specified, not yet coded). Source-NDOs add an adaptive loop: boundary events → ledger → ecological interpretation → rule revision → conditioned access. |
| Accountability | PPR (PrivateParticipationClaim) — bilateral cryptographic, 16-category, non-deletable (prototype issuance; privacy-preserving storage still incomplete). |
| Property regimes | Seven variants: Private, Commons, Collective, Pool, CommonPool, Public, Nondominium. Source-NDOs may only be Nondominium or CommonPool. |
| Status | Layer 0 + Lobby/Group/NDO holarchy implemented. Layers 1–2 activation links, CapabilitySlots, Governance-as-Operator, and Source-NDO (SourceProfile, vf:Source) are specified, not yet in code. |
Three ontological categories (Source-enabled applications):
AGENT — acts, intends, commits, bears responsibility
RESOURCE — appropriable, inventoriable output (timber, water m³, a tool, a carbon lot)
SOURCE — generative system that yields Resources, receives effects,
conditions other Sources; not owned, not an agent
Ostrom's SES mapping is direct: Source = resource system; Resource = resource unit; GovernanceRule = governance system; Agents (+ Steward role) = users.
The NDO three-layer model (same layers for Resource-NDOs and Source-NDOs):
Layer 2 — PROCESS (EconomicEvents, Commitments, PPRs; for Sources: boundary events)
↑ activated by NDOToProcess link
Layer 1 — SPECIFICATION (ResourceSpecification + GovernanceRules;
for Sources: SourceSpecification + ecological value vector)
↑ activated by NDOToSpecification link
Layer 0 — IDENTITY (NondominiumIdentity — permanent;
for Sources: + linked SourceProfile)
A Ceará mahogany forest as Source-NDO (the object Social Forests financializes from):
- Layer 0:
NondominiumIdentity— name,PropertyRegime::Nondominium,ResourceNature::Physical,LifecycleStage(governance maturity of the NDO artefact). LinkedSourceProfile:SourceType::Biological,complex_interior: true,regime_state(Pristine → Transformed), stock / flux / assimilation / resilience / tipping threshold,stewarded_by(obligations, never ownership). Permanent. Undeletable. NoprimaryAccountable. - Layer 1:
SourceSpecification— spatial boundary, species mix, monitoring plan, access-affordance templates (harvest quotas, restoration-per-extraction, seasonal closures), ecological value vector (Sustenance, Regeneration, Resilience, Adaptive Capacity, Generative Capacity, Commons Value, Learning Value). - Layer 2: Boundary
EconomicEvents —extract(timber, seedlings leaving the nursery), loading (agrochemical runoff into a coupled river Source),raise/ regeneration (replanting, riparian restoration). PPRs for stewardship, monitoring, and restoration work.
What the forest yields (these are Resources, and these are what can become RWAs):
- Seedling lots, standing timber, processed mahogany, kg CO₂ —
EconomicResourceinstances withaccounting_quantity/onhand_quantity, custodian,OperationalState. - Source-to-Source coupling: the forest conditions a river / watershed Source (infiltration, flow stability). A watershed Source yields the forest as a sub-Source.
Capability surface (specified, not yet coded): CapabilitySlot::DigitalAsset on Layer 0 is the designed attachment point for Social Forests' Stellar NFT / vault contract address. UnytAgreement is the later settlement-attachment point. Neither slot is the forest.
3. Convergences — Where Both Projects Arrived Independently at the Same Design
These are structural homologies: places where the two projects, working independently on different stacks, invented the same solution.
3.1 The Two-Layer Asset State Model — now three on the NDO side
This remains the most striking convergence.
Social Forests explicitly separates Rarity (user commitment) from TreeAnnualRecord (physical reality). The contract code comment reads: "This rarity represents the USER's effort (leaves burned), NOT the age or growth stage of the physical tree."
Nondominium explicitly separates LifecycleStage (on NondominiumIdentity, the resource's or Source-NDO's maturity as a social / governance artefact) from OperationalState (on EconomicResource, the current physical/operational condition of a unit). Source-NDOs add a third orthogonal dimension: SourceRegimeState on SourceProfile — ecological condition of the generative system (Pristine, Stable, Stressed, Degraded, Critical, Transformed). That third dimension has no counterpart in Social Forests' NFT identity; it is closest to fields inside TreeAnnualRecord (health, carbon, height), which NDO would treat as condition signals on the Source, not as attributes of a token.
Both projects discovered that a real-world ecological asset has (at minimum) two orthogonal state dimensions: the social/commitment state and the physical/material state. Neither can be reduced to the other. NDO now says there are three for a forest: artefact maturity, unit condition, and Source regime.
| Dimension | Social Forests | Nondominium |
|---|---|---|
| Social / commitment state | Rarity (Plantador → Lenda) | LifecycleStage (Ideation → Active → EndOfLife) — maturity of the NDO artefact |
| Physical / material state (unit) | TreeAnnualRecord (height, carbon, health) | OperationalState + EconomicEvent history on yielded Resources |
| Ecological regime (system) | Implicit in oracle records; not a first-class object | SourceRegimeState on SourceProfile (governance-validated) |
| Who writes social state | User (burns LEAF) | Governance (validated transitions; MVP: initiator-only) |
| Who writes physical / regime state | Oracle (PoF, AI + satellite) | Custodian (units) / Stewards + validators (Source condition) |
| Decoupled? | ✅ Explicitly | ✅ By design |
3.2 Non-Transferable Contribution Records
Social Forests: SoulboundNonTransferable — transfer_reputation always panics. Impact points accumulate per address, cannot be moved. Enforced at the smart contract level.
Nondominium: PPR entries are private, bilaterally signed, and permanently immutable. Deleting a Person is invalid. The protocol makes it architecturally impossible to erase contribution history. For Source-NDOs, stewardship (monitoring, restoration, rule compliance, succession) is PPR-eligible — standing accrues from contribution to Source health, not from token burn.
Both projects independently concluded that contribution records must be soul-bound to their author. Neither allows reputation laundering.
3.3 Validation-Gated State Transitions
Social Forests: PoF oracle must validate physical growth before tokens are minted. admin_mint is gated by oracle confirmation. Tree records require the oracle's admin signature.
Nondominium: Every lifecycle transition is specified to be gated by zome_gouvernance evaluating GovernanceRule entries. Prototype → Stable requires N-of-M peer validation (Accept action). Source-NDO SourceRegimeState transitions (e.g. Stable → Stressed) MUST be governance-validated with evidence — not a unilateral write, and not an admin key. (Governance-as-Operator evaluation is specified, not yet coded; MVP lifecycle updates are initiator-only.)
Both require external validation before economic state advances. The oracle in Social Forests maps to the validator / steward network in Nondominium — with the difference that NDO treats the oracle as one kind of agent among others, not as a privileged writer.
3.4 Permanent, Undeletable Identity Anchors
Social Forests: NFT IDs are permanent on-chain (no burn mechanism for the NFT identity itself; burning the NFT via the evolution mechanic transforms it, not deletes it).
Nondominium: NondominiumIdentity deletion is always invalid. Person entries cannot be deleted. Per-NDO cloned cells bind immutable classification (name, property regime, resource nature) into the DnaHash itself: changing those fields is a different network, not an edit (ADR-013). Source-NDOs use the same permanence: the forest's Layer 0 hash is the ledger of every extraction, loading, and restoration event for as long as the record exists, including as an EndOfLife tombstone.
Both treat the identity anchor as something that must outlive any particular use of the asset.
3.5 Quantity Duality (Accounting vs Physical)
Social Forests: MOGNO fraction (mogno_fraction_for_rarity) represents the on-books ownership share; TreeAnnualRecord carries the physical quantity (height, carbon_kg). These are separate fields, separately updated.
Nondominium: EconomicResource has both accounting_quantity (committed / on-books) and onhand_quantity (physically available). VF 1.0 compliance requires both. For a Source, a further split appears: unit quantities live on yielded Resources; system quantities (current_stock, flux_rate, assimilation_capacity) live on SourceProfile and are debited/credited by boundary events. Token fractions are a third quantity, and they do not belong on the Source.
3.6 Black-Box Measurement of a Complex System
Social Forests' PoF does not attempt to simulate the mahogany stand's interior (mycorrhizae, understory, hydrology). It observes periphery: satellite biomass, carbon, annual growth. The oracle writes a boundary record.
Source-NDO states the same epistemic rule as architecture: complex_interior: true. Stewards do not model the forest's full interior. They record boundary events, sense regime, and adapt governance (Ashby; Cynefin probe–sense–respond; Holling / Panarchy). The PoF feed is, in NDO terms, one class of monitoring input among others — including qualitative and community-validated observations (REQ-SOURCE-GOV-07).
Both projects independently refused the high-modernist fantasy of a complete ecological twin as a precondition for action.
4. Complementarities — Where Each Project Fills the Other's Gap
4.1 Infrastructure Layers (Non-Overlapping)
Social Forests provides what Nondominium does not have:
- DeFi rails — Stellar's AMM, secondary marketplace, USDC/USDT liquidity
- Fiat on-ramp — Stripe MPP (Master Payment Platform) for institutional B2B entry
- NFT standard — SEP-41, tradeable fractional ownership
- Carbon credit tokenization — C-CRED/C-DEBT accounting (planned Phase 3)
- Export infrastructure — Pecém Port, physical supply chain from seedling to export
- Oracle product — PoF as a working (or near-working) measurement pipeline
Nondominium provides what Social Forests does not have:
- Source primitive — an honest object for the forest as resource system, so extraction is not a phantom
raiseand the stand is not assigned a fictional owner - Governance distribution —
GovernanceRuleevaluated before every action; no master admin key required (specified invariant; operator path not yet coded) - Rich agent identity — layered individual/person model, field-level capability grants, portable credentials, W3C DID via Flowsta (specified)
- Contribution accounting — ValueFlows-compliant EconomicEvents, effort tracking, commitment history; stewardship PPRs
- Commons governance — Ostromian rules, property-regime taxonomy, non-alienable Nondominium regime; adaptive loop for complex Sources
- Holonic composition — Lobby → Group → NDO cells; NDOs compose via
NdoHardLink; a watershed Source can yield a forest Source which yields timber Resources
Integration scenario: A forest estate registered as a Source-NDO (stewardship, regime state, contribution accounting, coupling to a watershed) could have its tokenizable yields — tree fractions, carbon lots — issued via Social Forests' rwa_vault on Stellar (DeFi, cashback, ESG). The Source-NDO provides the governance and accountability layer for the system. Social Forests provides the financial layer for instruments derived from yields. CapabilitySlot::DigitalAsset on the Source (or on a child Resource-NDO for a specific stand / vintage) is the designed attachment point for the Stellar NFT.
Directional asymmetry — which expansion is easier? NDO expanding toward Social Forests' complementary capabilities is still architecturally easier than the reverse. NDO already has a designed bridge surface — CapabilitySlot::DigitalAsset — whose purpose is to reference an external digital asset (including a Stellar contract address) without NDO implementing DeFi. Unyt (UnytAgreement slot) is the in-family settlement path for the same job. The expansion is additive: NDO's governance-as-operator invariant is untouched; financial instruments live elsewhere.
Social Forests expanding toward NDO's complementary capabilities is the harder direction. Distributed governance without an admin override, private bilateral contribution records, non-alienable property regimes, and a non-ownable Source are not features that bolt onto Stellar. They conflict with global shared state, a public ledger, admin-key trust, and the RWA premise that the tree is the token. Social Forests' own roadmap acknowledges part of this: Phase 3's DAO transition is where they would rebuild governance from scratch. NDO is already what that DAO would need to become — and Source-NDO is already what the forest object in that DAO would need to be.
The practical first integration move remains NDO-led: register the forest as a Source-NDO first, attach the Stellar contract via CapabilitySlot, and let Social Forests remain the financial interface without requiring changes to its current architecture.
4.2 Governance Evolution
Social Forests' governance roadmap explicitly targets DAO transition in Phase 3 ($FLORA governance token). The current admin-key model is acknowledged as temporary.
Nondominium's governance layer is designed to be exactly what Social Forests would transition to: role-based access, rules evaluated before transitions, N-of-M validation for sensitive operations. For a forest, that layer is adaptive: quotas, restoration obligations, and seasonal closures revise as SourceRegimeState and the event ledger change — not a one-shot constitution.
Complementarity: Social Forests' Phase 3 DAO could be built on Nondominium's GovernanceRule infrastructure. The $FLORA token could be a ResourceSpecification with medium_of_exchange: true on the NDO side, with allocation governed by contribution-based access (PPR → ReputationSummary → governance participation), including stewardship PPRs from local monitors and restoration crews. PoF becomes a ValidationReceipt issuer — a recognized validator role — not a bypass of the operator.
4.3 Consumer Identity vs. Agent Identity
Social Forests treats consumers as Stellar wallet addresses + SBT impact point accumulators. There is no composable consumer profile, no portable reputation beyond the single contract, no cross-protocol identity.
Nondominium's agent model (even in MVP form) provides: field-level capability grants, multi-device support, permanent Person anchors, role-based access, and a roadmap to Flowsta-based W3C DID portability (FlowstaIdentity CapabilitySlot on the Person hash). Source-enabled applications add a Steward functional role: obligations without alienation rights, distinct from PrimaryAccountableAgent custody of timber lots.
Complementarity: Social Forests consumers could have their LEAF/SBT history attributed to a Nondominium Person (via CapabilitySlot::FlowstaIdentity or DigitalAsset). Their Nondominium PPR reputation could then be used as a governance signal in Social Forests' DAO phase — e.g., active contributors and forest stewards (algorithmically derived from PPR activity) get governance weight, not just token holders.
4.4 Carbon Measurement vs. Resource and Source Accounting
Social Forests has specific, oracle-validated carbon data: carbon_kg in TreeAnnualRecord, carbon credits derived from leaf circulation.
Nondominium has generic, ValueFlows-compliant quantity tracking: QuantityValue { has_numerical_value: f64, has_unit: ActionHash }. With a Unit of { label: "kilogram CO2", symbol: "kgCO2" }, Nondominium can track carbon as an EconomicResource quantity yielded by the forest Source. It has no oracle infrastructure of its own. Source-NDO additionally records whether sequestration is a system condition (flux / generative capacity on SourceProfile) or an appropriated credit (a Resource that can be sold). Collapsing those two is how carbon markets greenwash: they sell the instrument as if it were the forest.
Complementarity: Social Forests' PoF oracle generates trusted physical measurements. Nondominium's ResourceValidation + ValidationReceipt (and Source monitoring-obligation rules) provide the peer-reviewed audit trail. Together: oracle produces the raw data; NDO governance validates and records it — as a boundary event on the Source and/or as a Modify / quantity update on a carbon Resource, depending on whether the number describes system condition or an appropriated unit.
4.5 B2B ESG vs. Commons / Source Governance
Social Forests' B2B model serves institutional buyers who need verifiable ESG compliance for regulatory and marketing purposes. The ESG Merkle root (set_esg_merkle_root) enables auditable certification.
Nondominium's commons governance serves communities managing shared resource systems under Ostromian rules — not corporations buying carbon offsets. Source-NDO makes that distinction executable: the forest is not for sale; services derived from its yields can be.
Complementarity: These are different customer segments that can coexist around the same physical forest. The forest is governed as a Source (NDO side: Nondominium regime, stewardedBy, GovernanceRules, PPR-based contribution accounting among local stewards). Its carbon sequestration credits — Resources yielded, not the Source itself — are sold to institutional ESG buyers via Social Forests' B2B pipeline. Local stewards earn from the cashback model while retaining governance control via NDO's non-alienable property regime. Harvest of mahogany for export is an extract event against the Source, gated by access affordances (quota, restoration obligation), not a mint of the forest's identity.
4.6 Source Ledger vs. RWA Market (new)
Social Forests is strong at making a tree fraction liquid. Nondominium (Source profile) is strong at making a forest accountable as a system: depletion visible, pollution visible, regeneration visible, coupling to watershed visible.
Neither job replaces the other. A liquid NFT with no Source ledger can still hide over-extraction behind a healthy-looking token. A Source ledger with no market rails can still leave stewards unpaid. The complementarity is: NDO records what happened to the system; Social Forests prices claims on yields.
5. Zones of Exclusion — Where Both Do the Same Thing Incompatibly
These are the places where a joint deployment must choose one model and abandon the other. They cannot be run simultaneously for the same object without producing contradictions.
5.1 ⛔ RWA / Source Identity Model
| Social Forests | Nondominium | |
|---|---|---|
| Identity anchor | NFT nft_id: u32 (counter, integer, mutable rarity) | NondominiumIdentity in a cloned cell; network identity = DnaHash (immutable classification) |
| What the identity is | A property of the current owner's commitment level (rarity evolves) | A property of the object itself. For a forest: a Source — unowned. For timber: a Resource. |
| Permanence | NFT can be evolved / transformed (rarity changes) | Identity immutable after creation; lifecycle_stage and Source condition are the mutable faces |
| Deletion | No explicit burn for identity (transformation only) | Explicitly always invalid to delete |
| What it carries | Owner address, rarity, MOGNO fraction | Name, property regime, resource nature, initiator, lifecycle; SourceProfile: regime, stewards, stock/flux |
Why incompatible: The NFT model treats identity as a property of the current owner's commitment level. The NDO model treats identity as a property of the object, independent of any owner — and for a forest, forbids an owner altogether (REQ-SOURCE-ONT-02). A tree cannot simultaneously be a u32 NFT (whose meaning changes when the owner burns LEAF) and a Source-NDO (whose meaning is fixed at creation and whose regime forbids alienation). Deploying both as the identity of the same forest produces two divergent truths about what the forest is. The resolution is not a merge: the NFT may identify a claim on a yield; the Source-NDO identifies the system.
5.2 ⛔ Contribution / Reputation Record
Social Forests (sbt_reputation) | Nondominium (PPR) | |
|---|---|---|
| Type | i128 integer counter per address | Structured entry with 16 categories, performance metrics |
| Directionality | Unilateral (company distributes to user) | Bilateral (both parties sign) |
| Privacy | Public on-chain (Stellar storage) | Private by default (Holochain private entry) |
| Portability | Non-transferable but permanently public | Non-transferable and private (agent-controlled disclosure) |
| Semantics | "How much green cashback you received" | "What you did, how well, with whom, in what category" — including stewardship of a Source |
Why incompatible: Both claim to be the system of record for a user's contribution to a sustainability mission. The SBT is a public accumulator of cashback; the PPR is a private bilateral receipt of work and care. They encode different answers to "what counts as a contribution." Deploying both for the same action creates two incompatible contribution records with no canonical resolution. A joint deployment should pick PPR as the contribution record and treat SBT as a derived marketing / cashback counter — or the reverse, and accept that stewardship quality is invisible.
5.3 ⛔ Governance Access Control
| Social Forests | Nondominium | |
|---|---|---|
| Model | Single admin key controls: pause, mint, oracle, company whitelist | GovernanceRule evaluated by zome_gouvernance before every state transition |
| Override | Admin can call any function at any time | No transition possible without rule evaluation; no admin bypass |
| Company verification | register_company / revoke_company (admin-only) | GovernanceRule::AccessRequirement + role-based CapabilityLevel; Source access affordances (quotas, restoration-per-extract) |
| Trust assumption | Admin key holder is trusted | No single point of trust; rules are evaluated, not bypassed |
| Source-specific | n/a | Precautionary blocking at tipping_threshold; regime transitions multi-validated |
Why incompatible: Nondominium's non-negotiable boundary is that zome_gouvernance evaluates rules before any economic action — this is described as non-negotiable. It enables swappable governance without touching the data model. An admin key that can directly mint, pause, or whitelist is architecturally incompatible with this invariant. You cannot graft Social Forests' admin model onto NDO governance — least of all onto a Source-NDO, whose entire point is that no agent can own or override the forest. Social Forests may keep an admin key on the financial contracts (the outside); it cannot be the governor of the Source.
5.4 ⛔ Lifecycle Progression Semantics
| Social Forests (Rarity) | Nondominium (LifecycleStage) | Nondominium (SourceRegimeState) | |
|---|---|---|---|
| What progresses | The owner's commitment (LEAF burned) | The artefact's maturity (peer-validated) | The system's ecological regime |
| Who triggers | User voluntarily burns tokens | Governance evaluates agent-submitted transition | Stewards + validators, with evidence |
| Reversible? | No (no downgrade mechanic) | Yes — any stage can go to Hibernating; can return | Yes — both directions, governance-validated |
| External validation | Not required for rarity evolution | Required for Prototype → Stable (N-of-M) | Required for every regime change |
| Terminal state | Lenda (maximum commitment) | EndOfLife (tombstone) | Transformed (post-regime-shift) or EndOfLife (collapse) |
Why incompatible: These progressions answer different questions. Social Forests asks "how committed is this owner?" NDO LifecycleStage asks "how mature is this governance object?" NDO SourceRegimeState asks "how is this forest doing?" Representing Rarity as LifecycleStage would erase owner-commitment semantics. Representing LifecycleStage or SourceRegimeState as Rarity would erase peer validation, reversibility, and ecology. They cannot be merged. In a joint deployment, Rarity stays on the NFT; LifecycleStage stays on the NDO artefact; SourceRegimeState stays on the forest.
5.5 ⛔ Execution Environment
| Social Forests | Nondominium | |
|---|---|---|
| Platform | Stellar Soroban (WASM, global ledger, EVM-adjacent) | Holochain (agent-centric DHT, no global consensus) |
| State model | Global shared state (all nodes agree) | Agent-owned source chains + local DHT shards; one cloned cell per NDO |
| Contract calls | Synchronous cross-contract calls (Soroban) | Async cross-zome / cross-DNA calls (Holochain) |
| Token standard | SEP-41 (Stellar) | No native token standard (ValueFlows via hREA; Unyt settlement specified) |
| DeFi interop | Native (Stellar DEX, USDC, AMM) | None natively (CapabilitySlot / Unyt bridge planned) |
Why incompatible: A Soroban contract cannot call a Holochain zome. A Holochain DHT entry cannot be read by a Soroban contract. The two platforms have fundamentally different execution models (global consensus vs. agent-local validation), different storage models (contract storage vs. source chain + DHT), and different token semantics (fungible global balance vs. ValueFlows EconomicResource / Source boundary event). Any integration requires an explicit bridge layer — it cannot be implicit.
5.6 ⛔ Ontological Category (new)
| Social Forests | Nondominium (Source profile) | |
|---|---|---|
| What the forest is | A bundle of tokenizable trees (RWAs) | A Source: generative, non-ownable, black-boxed |
| What the tree is | The RWA | Either a Resource unit yielded by the Source, or a measurement target — not an owner-keyed identity |
| Ownership | Fractional NFT ownership of the tree | Forbidden on the Source (Nondominium / CommonPool only). Ownership, if any, applies to yields (timber lots, credits) under governance |
| Economic event for harvest | Implicit in supply chain / mint | extract from Source → Resource in an Agent's custody; Source current_stock decrements |
| Primary accountable | Token owner / admin | None on the Source; stewardedBy obligations |
Why incompatible: This is the exclusion the April draft could only phrase as philosophy. ValueFlows 1.0 has Agent and Resource. Modeling a forest as EconomicResource forces a primaryAccountable — the inverse of the Nondominium regime — and makes harvest a raise (resource-from-nowhere) unless a fictional stock is pre-minted. Modeling it as an Agent attributes intention it does not have. Social Forests' RWA is that first fiction, made liquid: the tree is owned because the token is owned. Source-NDO exists specifically to refuse that fiction. You can sell claims on yields. You cannot, on the NDO side, sell the Source. A joint deployment that registers "the forest" as both NFT collection and Source-NDO without a yield/instrument boundary will contradict REQ-SOURCE-ONT-02 on day one.
6. Integration Architecture Proposals
Given the above analysis, three integration patterns remain feasible. All three now assume the forest is a Source-NDO, not an RWA.
6.1 Source-NDO as Governance Layer, Social Forests as Financial Layer
Physical forest (Ceará mahogany stand)
│
▼
Source-NDO (Holochain cloned cell; DnaHash identity)
├── SourceProfile (Biological, regime_state, stock/flux, stewardedBy)
├── GovernanceRules (quotas, restoration-per-extract, monitoring obligations)
├── Boundary EconomicEvents (extract, loading, regeneration)
├── PPRs (bilateral accountability among local stewards)
├── Coupling → Watershed Source (forest conditions hydrology)
└── CapabilitySlot::DigitalAsset ──────────────────────────────┐
│
▼
rwa_vault on Stellar
├── LEAF tokens (consumer cashback)
├── MOGNO NFT fractions (claims on yields)
└── CompanyBadge (ESG certification)
The Source-NDO anchors governance and contribution accounting for the stewards managing the forest. Social Forests handles tokenization, DeFi, and B2B ESG sales of derived instruments. The NFT is not the forest. CapabilitySlot::DigitalAsset links the Source (or a child Resource-NDO for a vintage / plot) to the Stellar contract address.
Harvest / export (Viveiro → field → Sómogno → Pecém) appears on the NDO side as extract events against the Source, producing timber Resources whose custody can move through the physical chain. Minting MOGNO is a financial event about those yields, not a second identity for the stand.
6.2 Social Forests' Phase 3 DAO Built on NDO Governance
Replace Social Forests' admin key for forest governance with an NDO governance layer (the financial contracts may retain operational keys):
- $FLORA token becomes an NDO
ResourceSpecificationwithmedium_of_exchange: true - Token holder governance weight derived from NDO
ReputationSummary(PPR-based contribution, including stewardship) rather than token count alone - Company verification (
register_company) becomes aGovernanceRule::AccessRequirementevaluated by NDO'szome_gouvernance - PoF oracle becomes a
ValidationReceiptissuer — a recognized validator / monitoring agent within the NDO's agent model, feedingSourceProfilecondition updates - Harvest, mint, and ESG badge issuance become downstream of Source access affordances (quota not exceeded, restoration committed, regime not past
tipping_threshold)
6.3 Shared Consumer / Steward Identity via Flowsta DID
Social Forests consumers (and, separately, local stewards) get a Flowsta W3C DID. This DID is simultaneously:
- The identity behind their Stellar wallet (Social Forests' LEAF/SBT holder)
- A
FlowstaIdentityCapabilitySlot on their NDO Person entry
Their LEAF/SBT history is then attributable to their NDO agent identity, enabling:
- Portable reputation across protocols
- Affiliation state derivation (active/core affiliate based on mission completion and stewardship PPRs)
- Governance weight in any NDO-governed Source that chooses to recognize Social Forests participation as contribution evidence — without making cashback the definition of contribution
7. Summary Table
| Dimension | Social Forests | Nondominium | Relationship |
|---|---|---|---|
| What the forest is | Bundle of tokenizable trees (RWA) | Source (generative, unowned) | ⛔ Exclusion |
| RWA / unit identity | NFT id (u32, owner-evolving) | Resource-NDO / EconomicResource yielded by the Source; DnaHash + NondominiumIdentity | ⛔ Exclusion (if used as forest identity) |
| Two-/three-layer asset model | Rarity + TreeAnnualRecord | LifecycleStage + OperationalState + SourceRegimeState | ✅ Convergence |
| Black-box measurement | PoF (satellite / AI at the boundary) | complex_interior + boundary-event ledger | ✅ Convergence |
| Non-transferable reputation | SBT (public, unilateral) | PPR (private, bilateral; stewardship-eligible) | ⛔ Exclusion |
| Validation-gated transitions | PoF oracle required | N-of-M peer / steward validation required | ✅ Convergence |
| Permanent identity anchors | NFT permanence | Layer 0 undeletable; DnaHash binding | ✅ Convergence |
| Governance model | Admin key (Phase 1) / DAO (Phase 3) | GovernanceRule (distributed, evaluated) + Source adaptive loop | ⛔ Exclusion |
| Lifecycle progression | Owner commitment (Rarity) | Artefact maturity (LifecycleStage) ≠ ecological regime | ⛔ Exclusion |
| Execution environment | Stellar Soroban | Holochain DHT (Lobby / Group / per-NDO cells) | ⛔ Exclusion |
| Financial instruments | LEAF, MOGNO NFT, AMM, Stripe | Unyt Agreement stub, no native DeFi; DigitalAsset / UnytAgreement slots | 🔄 Complementary |
| Supply chain | Full (seedlings → export) | None natively; extract + custody events can record it | 🔄 Complementary |
| Agent / consumer identity | Wallet address + SBT counter | Layered identity + PPR + DID; Steward role | 🔄 Complementary |
| Carbon measurement | Oracle-specific (PoF, kgCO2) | Generic QuantityValue + Source flux / generative capacity | 🔄 Complementary |
| B2B / institutional layer | Stripe MPP, ESG badge, C-DEBT | None natively | 🔄 Complementary |
| Commons / Source governance | None (DAO stub) | Ostromian rules, Nondominium regime, adaptive Source loop | 🔄 Complementary |
| Holonic composition | Single-asset / collection contracts | Lobby → Group → NDO; Source yields Source; NdoHardLink | 🔄 Complementary |
Legend: ✅ Convergence (independently invented the same solution) · 🔄 Complementary (fills the other's gap) · ⛔ Exclusion (mutually incompatible for the same object)
8. Conclusion
Social Forests and Nondominium are not competitors. They serve different actors (B2B2C market participants vs. commons stewards), run on different infrastructure (Stellar vs. Holochain), and have different economic philosophies (programmable prosperity vs. contribution-based commons governance).
Their convergences are intellectually significant: two independent teams building on different stacks both arrived at a two-layer asset state model, permanent non-transferable contribution records, validation-gated transitions, and a refusal to fully model the interior of a living stand. This suggests these patterns are load-bearing solutions to real problems in ecological-economic infrastructure, not implementation accidents.
Their complementarities are practically significant: a forest that needs both commons / Source governance (for the stewards) and carbon-market access (for institutional ESG buyers) needs both protocols. NDO provides the governance and accountability substrate for the system; Social Forests provides the financial and commercial rails for claims on yields. The CapabilitySlot surface on NDO Layer 0 is the designed integration point.
Their exclusion zones are real but bounded: they concern identity models, governance models, reputation models, lifecycle semantics, execution environments, and — now explicitly — ontological category. A joint deployment must choose one model in each exclusion zone. The most natural resolution is Source-NDO for the forest (the inside) and Social Forests for financialization of yields (the outside interface to markets), with an explicit bridge at the boundary. Do not register the forest as an NFT collection and as a Source without that split.
The deepest tension is philosophical: Social Forests makes nature profitable to protect it. Nondominium makes nature ungovernable-for-extraction to protect it. These are not the same bet about how change happens — but they are not mutually exclusive bets either, once the object of each bet is named correctly. A forest stewarded as a Source-NDO can still have carbon sequestration credits sold commercially via Social Forests. The NDO's PropertyRegime::Nondominium (uncapturable, contribution-based access, no alienation, stewardedBy not primaryAccountable) governs who can steward the forest. Social Forests' RWA mechanism governs who can own a financial instrument derived from the forest's yields. These can coexist if the boundary between Source and instrument is kept explicit and respected.
The philosophical / economic approach between these two projects runs deep.
Social Forests inherits the web3 philosophy and economic paradigm: greed, if properly framed, leads to good.
The model is the following: you need an institution (UN + local governments) to enforce SDGs. That creates a cost for companies that exploit the resource. A percentage of that cost is passed to people and to locals who replenish the resource. The resource is an RWA. The tree is the token.
Nondominium inherits from the commons philosophy and economic paradigm: commons, if properly governed, leads to good.
The model is the following: no need for higher-level institutions to enforce doing good. Locals steward the commons. Access is gated by local governance associated with the object. Changes in the state of the object are governance-gated (no tree is cut if the rules are not respected). Companies must respect the rules before accessing yields. They can be bound by that governance (legal binding) to pay local agents to replenish, and those locals are also bound to do so. Accountability on both sides.
With Source, that object is named. The forest is not a Resource waiting to be owned. It is a generative system. Harvest is extract, not mint. Pollution of a coupled river is a loading event into a Source, not an externality off-ledger. Restoration is raise of Source condition, not a press release. The RWA, if it exists, is a claim on a yield — timber, a carbon lot, a seedling — not a title to the Source.
The source of truth differs in both cases: an oracle (a special agent) in Social Forests; locals plus other types of agents (local government, national government, agencies, scientists, indigenous knowledge holders) in Nondominium. Validation and oversight is more diversified and can be distributed in Nondominium; all agents are bound through agreements related to the Source's governance. PoF can sit inside that set as a monitor. It cannot replace it, and it cannot be the owner of the forest.
Appendix — What changed in this revision
This document was originally prepared 2026-04-30, treating the NDO primitive as an RWA throughout. Comments on that draft asked that Source be inserted as a new primitive. This revision does that, and updates Nondominium facts that have landed since:
| Area | April 2026 draft | August 2026 |
|---|---|---|
| Forest ontology | Tree as NDO-RWA | Forest as Source-NDO; timber / carbon as Resources; NFT as instrument |
| Identity | NondominiumIdentity as ActionHash | Per-NDO cloned cell; identity = DnaHash (ADR-010–013) |
| Architecture | Three-zome DNA, design phase | Lobby → Group → NDO holarchy implemented; Layer 0 shipped (PR #80) |
| Property regimes | Six listed | Seven (Public added); Sources restricted to Nondominium / CommonPool |
| State model | LifecycleStage vs OperationalState | Plus SourceRegimeState for Sources |
| Exclusion zones | Five | Six (ontological category) |
| Integration | CapabilitySlot::DigitalAsset | Unchanged as bridge; Source is the inside object the slot hangs from |
| Honesty about code | Implied more completeness | Source-NDO, CapabilitySlots, Governance-as-Operator: specified, not implemented |
Social Forests Protocol facts are unchanged from the April draft (Phase 1 testnet, three contracts, PoF, B2B2C loop).
Goal
Build a development steategy that represents the highest leverage, exploiting the sweatspot for all the adjacent possibles, which are possible applications of Nondominium.
- Reduce friction for flows of resources between organizations that use traditional open source ERP, CMS and groupware systems.
- Make Open and Collaborative Spaces (OCS) interoperable at the economic level.
- Help artists spread their art more sustainably.
- Legitimize open source DIY medical devices.
- Power citizen journalism
All these applications are low hanging fruits for us, as we can boast 15 years of uninterrupted experience in (material) peer production, and acting as an advocate for p2p and as a catalyst to federate open and collaborative initiatives.
Ordered list of immediate applications
Ordering criteria
ToDo: define the ordering criteria and method for the list of applications.
Table ToDo: build ordered table of applications
Lowest commun denominator
ToDo: Extract the lowest commun denominator (as a list of basic features) for all the immadiate applications, while prioritizing the ones that score high on our list.
To be continued.
ToDo:
- create UX mockup for this application
- analyze source doc, versions 3 and 4, and produce a clean doc where the user of Nondominium with the new Source-NDO primitive becomes the technological support, together with other Holochain-based hApps as capability slots for completing the digital environment or infrastructure.
Document source kept by Tibi, in pdf, see version 3 and 4.
Name of the doc: Constitution universelle de leau version Sensorica.pdf
User Story: ArtCoin - Art Circulation and Discovery
Scenario: Artist Sharing Artwork Through Venues or directly with art lovers (individuals) Using Nondominium
Context: An independent artist wants to circulate their paintings through a network of venues (cafes, restaurants, offices) or directly with individual art lovers, to gain exposure and generate income, using the Artcoin platform built on Nondominium infrastructure. This scenario primarily demonstrates Nondominium's resource sharing capabilities, with optional extension for a more comprehensive cultural network economics.
See also artcoin_main_doc.md and nondominium_artcoin.md.
How to read this story. The artwork is a Nondominium Object (NDO): a permanent
NondominiumIdentity(Layer 0) plus aResourceSpecification(Layer 1) and the economic activity around it (Layer 2). Custody moves viatransfer_custody; every interaction generates bilateral Private Participation Receipts (PPRs). Sequence diagrams below use real Nondominium zome functions where they exist; some steps are Artcoin platform-layer conveniences over those primitives. For the capability-by-capability status (what is code-complete vs. planned — e.g. payment settlement), see nondominium_artcoin.md §5.
🏗️ System Architecture Context
Resource Sharing Focus (Nondominium Sweet Spot)
graph TB
subgraph "Nondominium - Perfect Match for Art Circulation"
Person[Person Zome - Artist/Venue/Individual Profiles]
Resource[Resource Zome - Artwork Registry]
Governance[Governance Zome - Display Rules]
PPR[PPR Reputation System]
end
subgraph "Art Network Capabilities"
Discovery[Artwork Discovery]
Access[Venue/Individual Access Control]
Transactions[Rental/Sales/Adoption Transactions]
Reputation[Artist/Venue/Individual Reputation]
end
Person --> Discovery
Resource --> Access
Governance --> Transactions
PPR --> Reputation
Why Nondominium Excels for Art Networks:
- Perfect fit for bilateral resource sharing (artwork ↔ venue/individual)
- PPR system captures artistic and custodial reputation effectively
- Economic events handle rental, sales or adoption transactions cleanly
- Governance rules protect artwork and ensure proper care
Optional Enhancement (Cultural Economics Analysis)
graph TB
subgraph "Nondominium - Cultural Network Analytics"
REA[Cultural Economics Analysis]
Impact[Social Impact Measurement]
Accounting[Cultural Accounting]
Planning[Network Growth Planning]
end
subgraph "Enhanced Capabilities Optional"
ArtistDevelopment[Artist Career Tracking]
CulturalMetrics[Community Impact Analysis]
WealthCreation[Creative Wealth Measurement]
NetworkOptimization[Venue/Individual Network Optimization]
end
Enhancement:
- Cultural value beyond simple sales or rental income — beyond the transactional
- Social impact measurement of public art access
- Artist career development analytics
- Community cultural enrichment metrics
🎨 The Players
Maya Rodriguez - Independent Visual Artist
- Role: Accountable Agent (Creator & Resource Owner)
- Goal: Circulate artwork to gain public recognition and generate sustainable income
- Reputation: Emerging artist with growing local following, strong craftsmanship record
Jean-Pierre Dubois - Café Owner
- Role: Primary Accountable Agent (Custodian)
- Goal: Enhance café ambiance with rotating art while supporting local artists
- Reputation: Established venue owner with excellent art care track record
Amara Okafor - Individual Art Lover
- Role: Simple → Accountable Agent (Custodian)
- Goal: Discover and adopt art encountered in everyday venues, becoming custodian of a piece she loves
- Reputation: New to the network; builds custodial reputation through her first adoption
Support Agents - Transporter & Storer
- Roles: Accountable Agents holding the validated
TransportandStorageroles - Goal: Move and safely hold artworks between custodians, earning service PPRs
- Reputation: Specialized service providers vetted through role validation (
REQ-GOV-04)
The Artwork
- Piece: "Urban Rhythms" - Oil on Canvas, 36" x 48"
- Current Location: Maya's Studio, Montreal
- Governance Rules: 70% artist commission on sales, $40/month rental fee, smoke-free display required
🔄 Art Circulation Journey
Phase 1: Artwork Creation & Onboarding (Week 1)
sequenceDiagram
participant Maya as Maya Rodriguez
participant Artcoin as Artcoin Platform
participant ND as Nondominium
participant Res as Resource Zome
participant Gov as Governance Zome
Maya->>Artcoin: Register as artist
Artcoin->>ND: create_person(Maya)
ND->>Res: Create public Person profile (Accountable Agent)
Maya->>Artcoin: Submit artwork details
Maya->>ND: create_resource_specification(Oil Painting)
ND->>Res: Store art specification template (Layer 1)
Maya->>ND: create_ndo("Urban Rhythms", regime=Private, nature=Physical)
ND->>Res: Register NondominiumIdentity (Layer 0, permanent anchor)
Maya->>ND: create_economic_resource(spec, custodian=Maya)
ND->>Res: Register artwork instance (OperationalState: PendingValidation)
Maya->>ND: attach GovernanceRule entries (70/30 split, rental, care)
ND->>Gov: Link governance rules to the artwork spec
Artwork Onboarding Process:
- Artist Registration: Maya creates her artist profile with portfolio and credentials
- Resource Specification: Defines artwork type (Oil on Canvas 2025 collection)
- Artwork Registration: Registers "Urban Rhythms" with:
- Physical specifications (size, medium, weight)
- High-resolution images and provenance
- Governance rules: 70/30 split, $40/month rental, insurance requirements
- Care instructions and display preferences
Phase 2: Venue Discovery & Matching (Week 2)
sequenceDiagram
participant JeanPierre as Jean-Pierre Dubois
participant Artcoin as Artcoin Platform
participant ND as Nondominium
participant PPR as PPR System
participant Gov as Governance Zome
JeanPierre->>Artcoin: Browse available artworks
Artcoin->>ND: get_all_ndos() / get_ndos_by_nature(Physical)
ND->>Res: Query available artwork NDOs
Res-->>ND: Return artwork catalog with governance rules
ND-->>Artcoin: Display curated selection
JeanPierre->>Artcoin: View "Urban Rhythms" details
Artcoin->>ND: get_resource_specification_with_rules(spec_hash)
ND->>Gov: Return governance rules and requirements
JeanPierre->>ND: derive_reputation_summary(Maya)
ND->>PPR: Aggregate Maya's private PPRs (self-disclosed)
PPR-->>ND: Return artist reputation (3 PPRs, 4.8/5 quality)
JeanPierre->>Artcoin: Submit display commitment
Artcoin->>ND: propose_commitment(AccessForUse)
ND->>Gov: Create venue display agreement
Venue Discovery Process:
- Artwork Browsing: Jean-Pierre searches Artcoin platform for café-appropriate artwork
- Artist Review: Evaluates Maya's portfolio and reputation:
- 3 previous successful venue displays
- 4.8/5 artwork quality rating
- Positive venue feedback comments
- Governance Review: Analyzes display terms:
- $40/month rental fee ✅
- 70% artist commission on sales ✅
- Smoke-free environment requirement ✅
- Quarterly rotation option
- Display Commitment: Jean-Pierre submits AccessForUse commitment for 3-month initial period
Phase 3: Validation & Trust Building (Week 3)
sequenceDiagram
participant Maya as Maya Rodriguez
participant JeanPierre as Jean-Pierre Dubois
participant Artcoin as Artcoin Platform
participant ND as Nondominium
participant PPR as PPR System
ND->>Maya: Notify of venue interest
Maya->>Artcoin: Review Jean-Pierre's venue profile
Artcoin->>ND: derive_reputation_summary(JeanPierre)
ND->>PPR: Aggregate venue's disclosed PPRs
PPR-->>ND: Return venue data (8 PPRs, 4.9/5 art care)
Maya->>ND: accept_commitment(display agreement)
ND->>Gov: Create ValidationReceipt for the display commitment
Gov-->>Artcoin: Display commitment approved
JeanPierre->>ND: propose_commitment(AccessForUse, 3 months)
ND->>Gov: Record custodianship + display commitment
Gov->>PPR: record ValidationActivity for both parties
Mutual Validation Process:
- Venue Vetting: Maya reviews Jean-Pierre's café reputation:
- 8 previous art displays completed
- 4.9/5 artwork care rating
- No damage incidents in 2 years
- Active art promotion on social media
- Insurance Verification: Jean-Pierre provides liability insurance certificate
- Display Agreement: Both parties sign smart contract with automated revenue sharing
- Trust Confirmation: PPR system records mutual validation for future partnerships
Phase 4: Artwork Preparation & Transport (Week 4)
stateDiagram-v2
[*] --> Available: "Urban Rhythms" validated (PendingValidation → Available)
Available --> Reserved: Display commitment approved
Reserved --> InTransit: Transporter accepts custody (TransferCustody)
InTransit --> InUse: Delivery + CustodyAcceptance at venue
note right of Reserved
OperationalState: Available → Reserved
Display agreement activated
Insurance verification complete
end note
note right of InTransit
Maya signs certificate of authenticity
Transporter (Transport role) holds custody
CustodyTransfer PPR issued to Maya
end note
Transport & Installation:
- Artwork Preparation: Maya prepares "Urban Rhythms" for transport:
- Professional packaging and framing
- Certificate of authenticity signed
- Installation and care instructions
- Transport Coordination: Verified transport agent arranges delivery
- Custody Transfer: Maya transfers custody to transport agent (CustodyTransfer PPR)
- Venue Installation: Transport agent delivers and installs artwork at café
- Acceptance Confirmation: Jean-Pierre accepts custody (CustodyAcceptance PPR)
Phase 5: Public Display & Engagement (Months 1-3)
graph LR
subgraph "Display Process"
A[Artwork Installed] --> B[Public Discovery]
B --> C[Engagement Tracking]
C --> D[Rental Revenue]
D --> E[Monthly PPRs]
end
subgraph "Engagement Metrics"
F[QR Code Scans]
G[Social Media Shares]
H[Viewer Comments]
I[Sales Inquiries]
end
C --> F
C --> G
C --> H
C --> I
Public Display Experience:
- Physical Installation: "Urban Rhythms" prominently displayed in café seating area
- Digital Integration: QR code links to artwork's Nondominium profile showing:
- Artist biography and artistic statement
- Previous display history and public engagement
- Purchase inquiries and rental information
- Authenticity verification and provenance
- Engagement Tracking: Platform monitors:
- Daily viewer interactions via QR code scans
- Social media mentions and shares
- Sales inquiries and appreciation requests
- Public comments and ratings
- Monthly Revenue: Automated payment processing with 70/30 revenue split
Phase 6: Extended Discovery & Sales Opportunity (Month 2)
sequenceDiagram
participant Amara as Amara Okafor (Art Lover)
participant JeanPierre as Jean-Pierre Dubois
participant Artcoin as Artcoin Platform
participant ND as Nondominium
participant Gov as Governance Zome
participant PPR as PPR System
Amara->>JeanPierre: Inquire about "Urban Rhythms"
JeanPierre->>Artcoin: Scan QR code (NDO action_hash)
Artcoin->>ND: get_ndo(hash) + get_economic_resource(hash)
ND-->>Artcoin: Display artwork + provenance, price: $2,800
Amara->>Artcoin: Submit adoption intent
Artcoin->>ND: propose_commitment(TransferCustody)
ND->>Gov: Evaluate transfer (regime, rules, validators)
Gov-->>Artcoin: Transfer approved
JeanPierre->>ND: transfer_custody(resource, new_custodian=Amara)
ND->>Gov: Apply Agreement/BenefitClause split (70% Maya, 20% support, 10% protocol)
Gov->>PPR: issue_participation_receipts() (CustodyTransfer / CustodyAcceptance)
Adoption Process Integration:
- Discovery: Amara, an individual art lover, discovers the artwork during a café visit
- Authenticity Verification: The QR code resolves the NDO's permanent Layer 0
action_hash, providing verifiable provenance - Governed Transfer: The governance zome evaluates the custody transfer against the artwork's
PropertyRegimeandGovernanceRuleentries before it is finalized - Custody Handover: Custody moves from Jean-Pierre to Amara; she becomes the new Custodian (Simple → Accountable Agent after her first validated transaction)
- Receipts: Both parties receive bilateral PPRs (
CustodyTransfer/CustodyAcceptance); revenue split viaAgreement/BenefitClauseis applied where value settlement is enabled (see nondominium_artcoin.md §5)
Alternative Path: Storage Between Custodians
Not every display period ends in an adoption. When a rental/display period ends and no new custodian is immediately ready, the current custodian (e.g. the venue) requests storage rather than returning the piece to the artist:
- A Storer (Accountable Agent with the validated
Storagerole) commits to hold the piece until a new agent wants to buy, rent, or adopt it —StorageCommitmentAcceptedPPR - Custody transfers from the venue to the storer (
transfer_custody); the artwork moves toOperationalState::InStorage—CustodyTransfer/CustodyAcceptancePPRs - When a new custodian appears, the storer releases the piece (earning a
StorageFulfillmentCompletedPPR) and the circulation cycle continues
This keeps artworks in safe, accountable custody throughout their circulation, with every hand-off recorded and reputation-scored.
📊 Network Effects & Artist Growth
Artist Reputation Development
graph LR
subgraph "Before Artcoin Integration"
Maya_Before["Maya: Emerging Artist<br/>3 PPRs - 4.8/5 rating<br/>Local recognition only"]
end
subgraph "Artcoin Network Effects"
Phase1[Venue Display]
Phase2[Public Engagement]
Phase3[Sales Success]
Phase4[Network Expansion]
Phase1 --> Phase2
Phase2 --> Phase3
Phase3 --> Phase4
end
subgraph "After 3 Months"
Maya_After["Maya: Established Artist<br/>8 PPRs - 4.9/5 rating<br/>Multiple venue offers<br/>+$1,960 revenue"]
end
Maya_Before --> Phase1
Phase4 --> Maya_After
Maya's PPR Growth (real ParticipationClaimType categories):
- +1
ResourceCreation(registering "Urban Rhythms" as an NDO) - +1
CustodyTransfer(handing custody to the transporter for display) - +1
CustodyTransfer(custody handover on adoption/sale) - +1
RuleCompliance(adherence to the artwork's display governance rules) - +1
ValidationActivity(participating in the venue/commitment validation) - Reputation Impact: 4.8 → 4.9 overall rating (derived from PPR
PerformanceMetrics: timeliness, quality, reliability, communication, overall satisfaction)
Venue Benefits Expansion
mindmap
root((Café Art Integration))
Business Benefits
Customer Experience
Enhanced ambiance
Increased dwell time
Social media buzz
Marketing Advantage
Cultural destination status
Art community engagement
Local media coverage
Financial Benefits
Direct Revenue
Rental fee sharing
Sales commissions
Event hosting opportunities
Indirect Benefits
Increased foot traffic
Customer loyalty
Premium positioning
Community Impact
Artist Support
Emerging artist platform
Cultural contribution
Creative ecosystem building
Cultural Enrichment
Public art access
Arts education
Community beautification
🌐 Platform Integration Architecture
Artcoin Platform Integration
graph TB
subgraph "Artcoin Web Platform"
Gallery[Virtual Gallery]
Discovery[Art Discovery]
Booking[Venue Booking]
Analytics[Engagement Analytics]
end
subgraph "Nondominium Art Network"
Person[Person Zome - Artist Profiles]
Resource[Resource Zome - Artworks]
Governance[Governance Zome - Smart Contracts]
end
subgraph "Art Ecosystem Integration"
Social[Social Media Integration]
Payment[Payment Processing]
Logistics[Transport & Installation]
CRM[Customer Relationship Mgmt]
end
Gallery --> Resource
Discovery --> Person
Booking --> Governance
Analytics --> Resource
Person -.-> |Artist Authentication| Social
Governance -.-> |Revenue Sharing| Payment
Resource -.-> |Artwork Logistics| Logistics
Analytics -.-> |Patron Data| CRM
Artist-Centric Features
Creative Empowerment Tools:
- Portfolio Management: Comprehensive artwork catalog with exhibition history
- Revenue Analytics: Real-time tracking of rental income and sales performance
- Audience Insights: Data on artwork engagement across different venue types and locations
- Network Discovery: Connection with complementary venues and art communities
Smart Contract Capabilities:
- Dynamic Pricing: Automated pricing adjustments based on artist reputation and demand
- Royalty Enforcement: Droit de suite compliance for secondary sales
- Multi-Venue Management: Simultaneous display across multiple venues
- Flexibility Options: Easy modification of governance rules for different artwork collections
💡 Artistic Innovation Benefits
Creative Independence & Sustainability
- Direct Artist Income: Elimination of gallery commissions and intermediaries
- Artistic Control: Artists retain ownership and creative direction
- Sustainable Career: Ongoing passive income through rental rather than one-time sales
- Audience Building: Direct connection with art enthusiasts and collectors
Cultural Democratization
mindmap
root((Artcoin Cultural Impact))
Public Access
Everyday Art Exposure
Art in daily environments
No gallery intimidation
Spontaneous discovery
Economic Accessibility
Rental options for enjoyment
Fractional ownership possibilities
Support for emerging collectors
Artist Empowerment
Creative Freedom
Direct patron connection
Community-based validation
Experimental art support
Economic Justice
Fair revenue sharing
Transparent pricing
Royalty protection
Community Building
Local Art Ecosystems
Venue-artist partnerships
Cultural district development
Cross-disciplinary collaboration
Social Cohesion
Shared cultural experiences
Community identity
Intergenerational connection
Technology-Enhanced Art Experience
- Provenance Tracking: Complete artwork history with blockchain verification
- Interactive Engagement: QR codes enabling deeper artist and artwork stories
- Community Curation: Decentralized validation of artistic quality and relevance
- Global Reach: Local physical display with global digital discovery
🎯 Strategic Outcomes
Immediate Artist Benefits
- ✅ Revenue Generation: $1,960 total ($120 rental + $1,840 sale commission)
- ✅ Exposure Expansion: Artwork viewed by ~2,000 café visitors over 2 months
- ✅ Network Growth: Invitations from 4 other venues for future displays
- ✅ Reputation Building: Enhanced artist profile with verifiable success metrics
Long-Term Career Development
- Sustainable Practice: Ongoing rental income providing financial stability
- Direct Patron Relationships: Building collector base without gallery intermediation
- Artistic Freedom: Ability to experiment with new styles and mediums
- Community Recognition: Established as contributor to local cultural ecosystem
Platform Evolution
- Artist Success Stories: Growing database of artist career development case studies
- Venue Network Expansion: Increasing number of quality venues seeking art partnerships
- Collector Community: Developing base of art enthusiasts engaged with platform
- Cultural Impact Metrics: Quantifiable data on art accessibility and community enrichment
🔮 Future Possibilities
Extended Art Forms Integration
- Digital Art: NFTs with physical display components
- Performance Art: Bookable performances in venue spaces
- Interactive Installations: Technology-enhanced artwork experiences
- Multi-Sensory Art: Integration with venue's ambiance and customer experience
Advanced Economic Models
- Artist Cooperatives: Collective ownership and management of shared studio spaces
- Patronage Systems: Community-supported artist funding models
- Cultural Investment: Artwork as appreciating community assets
- Cross-Disciplinary Collaboration: Joint projects between artists, musicians, and performers
This user story demonstrates how Nondominium enables artists to transform their relationship with the art market, creating sustainable careers through direct community engagement while maintaining creative independence and building verifiable reputations in a decentralized cultural ecosystem.
Artwork "Urban Rhythms" was adopted by Amara Okafor, an individual art lover, after 2 months of café display — a direct artist-to-individual custody transfer governed entirely by the artwork's embedded rules. Maya now has 3 other artworks circulating across venues and individual custodians, held in safe storage between hand-offs, earning consistent income while building a verifiable, self-sovereign reputation.
User Story: Artist Distribution - Gallery Network & Exhibition Logistics
Scenario: Artist Coordinating Multi-Venue Exhibition Tour Through Distributed Gallery Network
Context: An artist organizes a traveling exhibition across multiple galleries, alternative venues, and individual patrons, coordinating logistics, artwork transport, and installation through the Artcoin distribution network built on Nondominium.
See also artcoin_main_doc.md, user-story-artcoin.md and nondominium_artcoin.md.
How to read this story. Each artwork in the tour is a Nondominium Object (NDO) — a permanent
NondominiumIdentity(Layer 0) whose custody moves between galleries, transporters, storers, and patrons viatransfer_custody. Each hand-off changes the instance'sOperationalState(InTransit,InStorage,InUse) and generates bilateral Private Participation Receipts (PPRs). Reputation labels shown in the diagrams (e.g. "TouringExcellence") are Artcoin-domain summaries derived from the real PPR categories (CustodyTransfer,TransportFulfillmentCompleted,ValidationActivity,RuleCompliance, …). For which capabilities are code-complete versus planned (e.g. structured Economic Processes, payment settlement), see nondominium_artcoin.md §5.
🖼️ The Players
David Kim - Contemporary Artist
- Role: Accountable Agent (Exhibition Artist & Tour Director)
- Goal: Tour "Fragments of Memory" photography exhibition across 5 cities in 6 months
- Reputation: Emerging photographer with growing international recognition
Sophie Laurent - Gallery Network Coordinator
- Role: Primary Accountable Agent (Distribution Manager & Exhibition Logistics)
- Goal: Coordinate multi-venue exhibition tour while maintaining artwork integrity and artist vision
- Reputation: Expert in contemporary art logistics with experience in international exhibition management
The Distribution Network
- Exhibition Venues: 3 galleries, 2 alternative spaces (community center, university gallery)
- Logistics Assets: Climate-controlled transport, professional art handlers, installation teams
- **Governance Rules: Conservation standards, insurance verification, installation quality requirements
🔄 Art Distribution Journey
Phase 1: Exhibition Planning & Venue Coordination (Month 1)
sequenceDiagram
participant David as David Kim
participant Artcoin as Artcoin Distribution Platform
participant ND as Nondominium
participant Res as Resource Zome
participant Gov as Governance Zome
David->>Artcoin: Submit exhibition tour proposal
David->>ND: create_person(David) [Accountable Agent]
ND->>Res: Create artist Person profile with exhibition history
David->>ND: create_resource_specification(PhotographyExhibition)
ND->>Res: Store exhibition spec (Layer 1) + create_ndo per piece (Layer 0)
ND->>Gov: Attach GovernanceRule (conservation standards, insurance)
David->>Artcoin: Define tour schedule and venue requirements
Artcoin->>ND: propose_exhibition_tour_workflow()
ND->>Gov: Create multi-venue distribution commitment
Exhibition Planning Process:
- Tour Specification: David defines "Fragments of Memory" exhibition requirements:
- Artistic content: 24 large-format photographs, 6 video installations
- Technical requirements: Specific lighting, climate control (18-22°C, 45-55% humidity)
- Exhibition timeline: 6 months, 3 weeks per venue
- Conservation requirements: UV protection, limited exposure time, professional handling
- Conservation Protection: Embedded governance rules ensure artwork preservation and insurance compliance
- Venue Matching: Platform identifies galleries with appropriate space, climate control, and curatorial alignment
- Transport Planning: Climate-controlled logistics requirements and professional art handler coordination
Phase 2: Gallery Network Formation & Logistics Coordination (Month 2)
sequenceDiagram
participant Sophie as Sophie Laurent
participant David as David Kim
participant Artcoin as Artcoin Distribution Platform
participant ND as Nondominium
participant PPR as PPR System
Sophie->>Artcoin: Review exhibition tour opportunities
Artcoin->>ND: get_exhibition_tour_requirements()
ND->>Res: Query photography exhibition specifications
Res-->>ND: Return technical and curatorial requirements
Sophie->>ND: derive_reputation_summary(David)
ND->>PPR: Aggregate David's disclosed PPRs and exhibition history
PPR-->>ND: Return profile (4 PPRs, 4.7/5 artistic merit, 1 previous tour)
Sophie->>ND: validate_new_resource(exhibition pieces)
ND->>Gov: Verify venue specifications and exhibition standards
Gov-->>Artcoin: Gallery capability validated (ValidationReceipt)
Sophie->>Artcoin: Submit venue participation proposal
Artcoin->>ND: propose_commitment(ExhibitionHosting)
ND->>Gov: Create tour hosting agreement with conservation requirements
Gallery Network Formation:
- Venue Selection and Validation: Five venues selected with complementary characteristics:
- Gallery A (Downtown): Commercial gallery with established collector base
- Gallery B (University): Academic context with educational programming
- Gallery C (Alternative): Community-focused space with local engagement
- Gallery D (Regional): Suburban location with diverse audience
- Gallery E (International): Final venue with exposure to international collectors
- Capability Verification: Each venue's exhibition standards verified:
- Climate control and environmental monitoring ✅
- Professional installation capabilities ✅
- Security and insurance coverage ✅
- Curatorial alignment and audience engagement ✅
- Tour Coordination Agreement: Smart contract outlines:
- Conservation standards and artwork handling requirements
- Installation quality and lighting specifications
- Tour schedule with buffer time for transport and installation
- Revenue sharing and commission structures
Phase 3: Artwork Preparation & Tour Logistics (Month 2-3)
stateDiagram-v2
[*] --> StudioReady: Artworks completed
StudioReady --> ConservationChecked: Professional art conservation review
ConservationChecked --> TourPackaged: Custom crating and documentation
TourPackaged --> FirstVenueReady: Transport to first gallery
FirstVenueReady --> InstallationComplete: Professional installation
InstallationComplete --> PublicOpening: Curatorial preparation and opening
note right of ConservationChecked
Conservation report: All artworks in excellent condition
UV protection glass installed on all pieces
Custom archival mounting completed
Insurance valuation confirmed
end note
note right of TourPackaged
Custom crates for each artwork size
Climate control monitoring devices
Installation instructions and lighting specifications
Complete documentation and condition reports
end note
Tour Preparation and Logistics:
- Artwork Conservation Review: Professional conservator reviews all artworks:
- Condition assessment and documentation
- UV protection glass installation for photographs
- Archival mounting and framing to conservation standards
- Insurance valuation and risk assessment
- Tour Packaging and Documentation:
- Custom crates designed for each artwork with climate control
- Digital condition reporting with before/after documentation
- Installation specifications and lighting requirements for each piece
- Complete provenance and exhibition history documentation
- Transport Planning: Climate-controlled transport with:
- Professional art handlers trained in photography conservation
- Temperature and humidity monitoring throughout transport
- GPS tracking and security protocols
- Insurance coverage for entire tour duration
Custody chain note. Every leg of the tour is a custody transfer. Transporters hold the validated
Transportrole and storers theStoragerole (REQ-GOV-04); between venues, pieces move toOperationalState::InTransitand, during scheduling gaps,OperationalState::InStorage. Each hand-off emitsCustodyTransfer/CustodyAcceptancePPRs plusTransportFulfillmentCompleted/StorageFulfillmentCompletedservice PPRs — building the reputation of the support agents alongside the artist. A final "venue" may equally be an individual patron who adopts a piece at the end of the tour.
Phase 4: Multi-Venue Exhibition Tour (Months 3-8)
graph TB
subgraph "Tour Schedule & Logistics"
A[Month 3: Gallery A - Downtown]
B[Month 4: Gallery B - University]
C[Month 5: Gallery C - Community]
D[Month 6: Gallery D - Regional]
E[Month 7: Gallery E - International]
F[Month 8: Return to Studio]
end
subgraph "Distribution Process"
G[Professional Installation]
H[Climate Monitoring]
I[Curatorial Programming]
J[Visitor Engagement]
end
subgraph "Quality Assurance"
K[Pre-Installation Inspection]
L[Ongoing Conservation Checks]
M[Post-Exhibition Review]
N[Tour Documentation]
end
A --> G
B --> H
C --> I
D --> J
E --> K
F --> L
G --> M
H --> N
I --> O[Artist Reputation Growth]
Tour Execution Process:
- Venue 1 - Downtown Gallery (Month 3):
- Professional installation with gallery technician coordination
- Artist-led curatorial walk-through and collector preview
- Sales representative training and artwork pricing coordination
- Visitor engagement tracking and collector relationship development
- Venue 2 - University Gallery (Month 4):
- Integration with academic curriculum and student programs
- Artist lecture series and educational programming
- Research collaboration and interdisciplinary engagement
- Student mentorship and portfolio review sessions
- Venue 3 - Community Center (Month 5):
- Community outreach and local artist engagement
- Workshop series and public programming
- School group visits and educational tours
- Community dialogue and cultural exchange initiatives
- Venue 4 - Regional Gallery (Month 6):
- Regional media coverage and broader audience engagement
- Local collector development and community building
- Cultural tourism promotion and regional networking
- Satellite programming and community partnerships
- Venue 5 - International Gallery (Month 7):
- International collector exposure and market development
- Cross-cultural dialogue and artistic exchange
- Museum and institutional relationship building
- International press coverage and critical recognition
Phase 5: Tour Completion & Impact Assessment (Month 8)
sequenceDiagram
participant David as David Kim
participant Sophie as Sophie Laurent
participant Artcoin as Artcoin Distribution Platform
participant ND as Nondominium
participant PPR as PPR System
Sophie->>ND: initiate_tour_completion_process()
ND->>Gov: Execute final venue de-installation and artwork return
Gov-->>ND: Tour completion confirmation and condition reports
David->>Artcoin: Review tour performance and impact metrics
Artcoin->>ND: validate_tour_success()
ND->>Gov: Verify conservation standards and artistic outcomes
Gov-->>Artcoin: Tour excellence confirmation
David->>ND: claim_commitment(tour completion)
ND->>Gov: Record fulfilling EconomicEvent for the tour
Gov->>PPR: issue_participation_receipts() [RuleCompliance, ValidationActivity]
All Venues->>ND: claim_commitment(hosting completion)
ND->>PPR: issue_participation_receipts() [CustodyTransfer / CustodyAcceptance per venue]
Tour Completion and Assessment:
- Artwork Condition Verification: Final conservation review confirms all artworks maintained in excellent condition throughout tour
- Tour Impact Analysis:
- Visitor engagement: 15,000+ total visitors across all venues
- Sales performance: 8 artworks sold to collectors, 3 institutional acquisitions
- Critical recognition: 12 reviews, 3 feature articles, 2 television interviews
- Artist reputation: Significant enhancement with international recognition
- Network Performance Evaluation: All venues receive quality ratings and collaboration feedback
- Documentation Completion: Complete tour documentation for archival and educational purposes
📊 Tour Analytics & Distribution Performance
Exhibition Tour Monitoring Dashboard
graph LR
subgraph "Artistic Impact Metrics"
A[Visitor Engagement: 15,234]
B[Critical Recognition: 4.8/5]
C[Sales Performance: 45% sold]
D[Artist Reputation: 4.9/5]
end
subgraph "Tour Efficiency"
E[Conservation Compliance: 100%]
F[On-Time Performance: 98%]
G[Cost Efficiency: 12% under budget]
H[Audience Diversity: High]
end
subgraph "Network Performance"
I[Venue Satisfaction: 4.7/5]
J[Installation Quality: 4.9/5]
K[Visitor Engagement: 4.8/5]
L[Collaboration Excellence: 4.8/5]
end
A --> E
B --> F
C --> G
D --> H
E --> I
F --> J
G --> K
H --> L
Tour Distribution Outcomes:
- Artistic Success: Significant critical recognition and collector interest
- Conservation Excellence: Perfect maintenance of artwork condition throughout tour
- Network Performance: High satisfaction ratings across all participating venues
- Economic Impact: Strong sales results and artist career advancement
Artist Reputation Development
graph LR
subgraph "Before Exhibition Tour"
David_Before["David: Emerging Artist<br/>4 PPRs - 4.7/5 rating<br/>Local recognition only"]
Sophie_Before["Sophie: Gallery Manager<br/>6 PPRs - 4.6/5 rating<br/>Single venue focus"]
Network_Before["Gallery Network: Disconnected<br/>Limited touring experience"]
end
subgraph "Tour Coordination Process"
Phase1[Tour Planning]
Phase2[Network Formation]
Phase3[Multi-Venue Execution]
Phase4[Impact Assessment]
Phase1 --> Phase2
Phase2 --> Phase3
Phase3 --> Phase4
end
subgraph "After Exhibition Tour"
David_After["David: International Artist<br/>9 PPRs - 4.9/5 rating<br/>plus 1 TouringExcellence<br/>plus 1 InternationalRecognition"]
Sophie_After["Sophie: Tour Network Director<br/>10 PPRs - 4.8/5 rating<br/>plus 2 TourCoordination<br/>plus 1 NetworkBuilding"]
Network_After["Gallery Network: Enhanced<br/>Plus 1 ExhibitionTour<br/>Plus collaborative programming"]
end
David_Before --> Phase1
Sophie_Before --> Phase1
Network_Before --> Phase1
Phase4 --> David_After
Phase4 --> Sophie_After
Phase4 --> Network_After
🏗️ Exhibition Distribution Architecture
Tour Coordination Management System
graph TB
subgraph "Artcoin Distribution Platform"
Touring[Tour Management]
Scheduling[Venue Scheduling]
Logistics[Transport Coordination]
Quality[Conservation Management]
end
subgraph "Nondominium Exhibition Distribution"
Person[Person Zome - Artist/Gallery Profiles]
Resource[Resource Zome - Artwork Assets]
Governance[Governance Zome - Conservation Standards]
end
subgraph "External Systems"
CRM[Gallery Management]
Shipping[Transport Logistics]
Conservation[Art Conservation]
Press[Media Relations]
end
Touring --> Person
Scheduling --> Resource
Logistics --> Governance
Quality --> Governance
Person -.-> |Artist Relationship| CRM
Resource -.-> |Artwork Status| Conservation
Governance -.-> |Compliance| Shipping
Advanced Tour Distribution Features
Exhibition Coordination Tools:
- Tour Planning: Integrated scheduling and timeline management for multi-venue exhibitions
- Conservation Monitoring: Real-time environmental monitoring and artwork condition tracking
- Professional Network: Verified database of art handlers, conservators, and installation technicians
- Documentation System: Complete digital records of exhibition history and artwork provenance
Gallery Network Capabilities:
- Venue Matching: Intelligent pairing of artists with appropriate exhibition spaces
- Quality Assurance: Standardized installation and conservation requirements across all venues
- Revenue Management: Transparent commission structures and payment processing
- Audience Development: Coordinated marketing and programming across exhibition network
💡 Exhibition Distribution Innovation Benefits
Touring Exhibition Advantages
- Career Development: Artists gain exposure across multiple markets and collector communities
- Cost Efficiency: Shared transport and installation costs reduce financial barriers to touring
- Conservation Assurance: Professional art handling and conservation standards protect artwork integrity
- Network Building: Relationships with galleries, collectors, and institutions across geographic regions
Art Market & Cultural Impact
mindmap
root((Exhibition Tour Network))
Artist Benefits
Career Development
Multi-market exposure
International recognition
Collector relationships
Economic Opportunities
Artwork sales
Commission opportunities
Grant funding eligibility
Gallery Network Benefits
Curatorial Excellence
Diverse programming
Artist relationships
Community engagement
Financial Sustainability
Shared exhibition costs
Increased visitor traffic
Commission revenue
Cultural Impact
Public Access
Broader audience reach
Educational programming
Cultural dialogue
Community Building
Local engagement
Cultural tourism
Community partnerships
Technology-Enhanced Exhibition Distribution
- Real-Time Monitoring: Environmental conditions and artwork status tracked throughout tour
- Digital Documentation: Complete exhibition history with installation records and visitor analytics
- Network Optimization: Data-driven venue selection and tour scheduling for maximum impact
- Market Intelligence: Collector engagement tracking and sales opportunity identification
🎯 Strategic Distribution Outcomes
Immediate Tour Benefits
- ✅ Career Advancement: Artist achieved international recognition and representation
- ✅ Sales Success: 45% of exhibition sold, with 3 institutional acquisitions
- ✅ Critical Acclaim: Strong reviews and media coverage across all tour markets
- ✅ Network Expansion: Established relationships with galleries and collectors internationally
Long-Term Market Development
- Touring Model: Established framework for artist touring exhibitions
- Gallery Network: Ongoing collaboration opportunities for network artists
- Market Intelligence: Data on collector behavior and market preferences across regions
- Cultural Exchange: Platform for international artistic dialogue and exchange
Platform Evolution
- Tour Templates: Standardized workflows for different types of exhibition tours
- Quality Standards: Industry benchmarks for artwork conservation and touring excellence
- Network Growth: Expansion to include more galleries and alternative exhibition spaces
- Educational Resources: Case studies and best practices for exhibition touring
🔮 Future Exhibition Distribution Scenarios
Advanced Touring Models
- Virtual Reality Integration: Digital twins of exhibitions for remote viewing and collector engagement
- International Collaborations: Cross-border touring with cultural diplomacy and exchange programs
- Site-Specific Adaptation: Touring exhibitions adapted to each venue's unique characteristics
- Collector Education: Programming and events designed to educate and engage new collectors
New Distribution Channels
- Pop-Up Exhibitions: Temporary exhibitions in non-traditional spaces using the touring framework
- Corporate Exhibitions: Art programming in corporate environments with employee engagement
- Hospitality Partnerships: Exhibitions in hotels and resorts with tourist audience development
- Digital Exhibitions: Hybrid physical-digital exhibitions reaching global audiences
This user story demonstrates how Nondominium enables artists to coordinate complex touring exhibitions through distributed gallery networks, ensuring artwork conservation while maximizing career opportunities and artistic impact through decentralized coordination and reputation-based trust.
"Fragments of Memory" tour completed successfully with critical acclaim in all cities. David Kim secured gallery representation in 3 countries and 2 institutional acquisitions. The touring model has been adopted by 4 other artists for upcoming international exhibitions, and the gallery network has expanded to include 12 venues across North America and Europe.
User Story: Artist Production - Collaborative Art Creation & Fabrication
Scenario: Artists Co-producing Large-Scale Installation Using Shared Studio Resources
Context: A collective of artists collaborates to create a large-scale public art installation, sharing specialized equipment and studio space through the Artcoin production platform. This scenario demonstrates both the current Nondominium resource sharing capabilities and the need for broader TrueCommon implementation with full REA integration for complete peer production network management through Network Resource Planning (NRP).
See also artcoin_main_doc.md, user-story-artcoin.md, user-story-art-distribution.md and nondominium_artcoin.md.
How to read this story. Shared equipment and studio space are Nondominium Objects (NDOs) — permanent
NondominiumIdentityanchors with aproperty_regime(typicallyCommonsorPoolfor shared tools) whose custody and use are governed by embeddedGovernanceRuleentries. Collaboration, fabrication, and maintenance generate bilateral Private Participation Receipts (PPRs). This story is deliberately the most REA-heavy of the three art scenarios: it highlights where the Nondominium resource-sharing core meets its edge and a fuller REA/hREA layer ("TrueCommon", with Network Resource Planning) is needed. For the Nondominium-side capability status, see nondominium_artcoin.md §5.
🏗️ System Architecture Context
Current Nondominium Implementation (Resource Sharing Economics)
graph TB
subgraph "Nondominium - Resource Sharing Focus"
Person[Person Zome - Artist Profiles]
Resource[Resource Zome - Studio Resources]
Governance[Governance Zome - PPR System]
end
subgraph "Current Capabilities"
ResourceSharing[Resource Access & Sharing]
Reputation[PPR Reputation Tracking]
Transactions[Economic Event Logging]
end
Nondominium excels at: Resource discovery, access governance, reputation tracking through PPRs, and secure economic transactions.
Required TrueCommon Integration (Full REA + Network Resource Planning)
graph TB
subgraph "TrueCommon - Complete REA Implementation"
REA[Full REA Integration]
NRP[Network Resource Planning]
Accounting[Integrated Accounting]
Planning[Resource Planning]
end
subgraph "Enhanced Capabilities Needed"
ProductionPlanning[Production Workflow Planning]
ResourceOptimization[Network-wide Resource Optimization]
DemandForecasting[Demand & Supply Planning]
FinancialAccounting[Complete Financial Accounting]
ImpactMeasurement[Social & Environmental Impact]
end
TrueCommon provides: Complete REA economics model, Network Resource Planning for production coordination, integrated accounting, and comprehensive impact measurement.
🎨 The Players
Elena Vasquez - Lead Artist & Concept Designer
- Role: Accountable Agent (Creative Director & Project Lead)
- Goal: Produce "Urban Canopy" - a 12-meter interactive light sculpture for public plaza
- Reputation: Established public artist with successful installations in 3 cities
Marcus Chen - Fabrication Specialist
- Role: Primary Accountable Agent (Production Manager & Technical Lead)
- Goal: Coordinate multi-studio fabrication while maintaining artistic vision and technical integrity
- Reputation: Expert in large-scale sculpture fabrication with architectural integration experience
The Production Network
- Collaborating Studios: 4 artist studios with complementary capabilities
- Specialized Equipment: Metal fabrication, 3D printing, electronics, lighting systems
- Governance Rules: Quality validation at each stage, intellectual property protection, safety compliance
🔄 Art Production Journey
Phase 1: Concept Development & Production Planning (Week 1-2)
sequenceDiagram
participant Elena as Elena Vasquez
participant Artcoin as Artcoin Production Platform
participant ND as Nondominium
participant Res as Resource Zome
participant Gov as Governance Zome
Elena->>Artcoin: Submit public art commission
Elena->>ND: create_person_with_role(PublicArtist)
ND->>Res: Create lead artist profile with portfolio
Elena->>ND: create_resource_specification(InteractiveLightSculpture)
ND->>Res: Store technical requirements and artistic vision
ND->>Gov: Link IP protection and public safety requirements
Elena->>Artcoin: Define production workflow and collaboration needs
Artcoin->>ND: propose_art_production_workflow()
ND->>Gov: Create multi-studio production commitment
Art Production Planning Process:
- Commission Specification: Elena defines "Urban Canopy" requirements:
- Artistic vision: Interactive light sculpture responding to pedestrian movement
- Technical specifications: 12m span, 500 LED nodes, weather-resistant
- Timeline: 12 weeks from concept to installation
- Budget: $85,000 including materials and studio time
- IP Protection: Embedded governance rules protect artistic concept and collaboration agreements
- Capability Assessment: Platform identifies studios with required fabrication equipment and expertise
- Safety Compliance: Public art safety requirements and structural engineering standards embedded
Phase 2: Studio Network Discovery & Collaboration Formation (Week 3)
sequenceDiagram
participant Marcus as Marcus Chen
participant Elena as Elena Vasquez
participant Artcoin as Artcoin Production Platform
participant ND as Nondominium
participant PPR as PPR System
Marcus->>Artcoin: Browse collaborative art opportunities
Artcoin->>ND: get_art_production_requirements()
ND->>Res: Query sculpture production specifications
Res-->>ND: Return technical and artistic requirements
Marcus->>ND: derive_reputation_summary(Elena)
ND->>PPR: Calculate artist reputation and collaboration history
PPR-->>ND: Return profile (7 PPRs, 4.9/5 artistic vision, 3 public installations)
Marcus->>ND: validate_studio_capability(MetalFabrication)
ND->>Gov: Verify equipment and artistic collaboration experience
Gov-->>Artcoin: Studio capability validated
Marcus->>Artcoin: Submit fabrication collaboration proposal
Artcoin->>ND: propose_commitment(ArtProductionService)
ND->>Gov: Create collaboration agreement with IP protection
Studio Collaboration Formation:
- Studio Network Assembly: Four studios with complementary capabilities:
- Studio A (Marcus): Metal fabrication and structural engineering
- Studio B: 3D printing and prototyping
- Studio C: Electronics and interactive systems
- Studio D: Lighting design and programming
- Expertise Validation: Each studio's artistic and technical capabilities verified:
- Previous public art collaborations ✅
- Equipment specifications and certifications ✅
- Artistic alignment and portfolio quality ✅
- Collaboration reputation and reliability ✅
- Creative Agreement: Smart contract outlines:
- Creative attribution and ownership percentages
- Quality standards and artistic vision adherence
- Timeline coordination and milestone payments
- Exhibition rights and documentation requirements
Phase 3: Multi-Studio Production Coordination (Weeks 4-9)
graph TB
subgraph "Production Stage 1: Component Fabrication"
A[Structural Frame - Metal Work<br/>Studio A: Marcus]
B[Interactive Elements - 3D Printing<br/>Studio B]
C[Sensor Arrays - Electronics<br/>Studio C]
D[Light Modules - Custom LEDs<br/>Studio D]
end
subgraph "Production Stage 2: Assembly & Integration"
E[Frame Assembly<br/>Studio A]
F[Electronics Integration<br/>Studio C]
G[Light Installation<br/>Studio D]
H[Software Programming<br/>Studio C + Studio D]
end
subgraph "Production Stage 3: Artistic Refinement"
I[Visual Testing<br/>All Studios]
J[Interactive Calibration<br/>Studio C + Elena]
K[Artistic Review<br/>Elena + All Studios]
L[Final Artistic Approval<br/>Elena]
end
A --> E
B --> F
C --> G
D --> H
E --> I
F --> J
G --> K
H --> L
Distributed Art Production Process:
- Stage 1 - Specialized Component Creation (Weeks 4-6):
- Studio A: Fabricate structural aluminum frame with weather-resistant coating
- Studio B: 3D print interactive sensor housings and artistic decorative elements
- Studio C: Develop custom sensor arrays and microcontroller systems
- Studio D: Program custom LED lighting sequences and create light diffusers
- Stage 2 - Technical Integration (Weeks 6-7):
- Assembly of structural frame with mounting points for electronics
- Integration of sensor systems and interactive response programming
- Installation of lighting systems with power distribution and control
- Software development for pedestrian interaction and light response patterns
- Stage 3 - Artistic Refinement (Weeks 8-9):
- Visual testing and artistic adjustments based on Elena's creative vision
- Calibration of interactive responses for optimal public engagement
- Quality assurance for weather resistance and public safety
- Final artistic approval and documentation of creative process
Phase 4: Creative Validation & Documentation (Week 10-11)
sequenceDiagram
participant Elena as Elena Vasquez
participant Marcus as Marcus Chen
participant Artcoin as Artcoin Production Platform
participant ND as Nondominium
participant PPR as PPR System
Marcus->>ND: initiate_artistic_validation()
ND->>Gov: Execute multi-studio quality and artistic validation
Gov-->>ND: Artistic vision compliance results
Elena->>Artcoin: Review artistic implementation and creative vision
Artcoin->>ND: validate_artistic_integrity()
ND->>Gov: Verify artistic standards and innovation achievement
Gov-->>Artcoin: Creative excellence confirmation
Elena->>ND: validate_specialized_role(PublicArtist)
ND->>Gov: Issue artistic innovation PPR
Gov->>PPR: record_creative_collaboration_achievement()
All Studios->>ND: claim_production_completion()
ND->>PPR: issue_collaborative_creation_receipts()
Artistic Validation Process:
- Creative Vision Verification: Elena validates that the installation meets her artistic concept:
- Visual impact and aesthetic quality ✅
- Interactive engagement effectiveness ✅
- Technical innovation and artistic merit ✅
- Public safety and durability standards ✅
- Collaboration Documentation: Creative contributions from each studio documented and attributed
- Innovation Recognition: New techniques and approaches recorded for artistic community knowledge sharing
- Production Completion: All studios receive PPRs for their creative and technical contributions
📊 Art Production Analytics & Creative Collaboration
Creative Production Monitoring Dashboard
graph LR
subgraph "Artistic Metrics"
A[Creative Vision Fidelity: 98%]
B[Innovation Score: 4.9/5]
C[Technical Complexity: Advanced]
D[Artistic Impact: High]
end
subgraph "Collaboration Efficiency"
E[Inter-Studio Coordination: 95%]
F[Resource Sharing: 3x Efficiency]
G[Timeline Adherence: On Schedule]
H[Budget Utilization: 97%]
end
subgraph "Quality & Innovation"
I[Technical Quality: 4.8/5]
J[Artistic Merit: 4.9/5]
K[Public Safety: 100% Compliant]
L[Documentation: Complete]
end
A --> E
B --> F
C --> G
D --> H
E --> I
F --> J
G --> K
H --> L
Creative Collaboration Outcomes:
- Artistic Achievement: Successful realization of complex interactive public art vision
- Innovation Recognition: New approaches to interactive sculpture and pedestrian engagement
- Collaboration Excellence: Seamless coordination across 4 studios with complementary expertise
- Technical Quality: Museum-level fabrication and weather resistance for public installation
Artistic Reputation Development
graph LR
subgraph "Before Collaborative Production"
Elena_Before["Elena: Public Artist<br/>7 PPRs - 4.9/5 rating<br/>3 successful installations"]
Marcus_Before["Marcus: Fabrication Expert<br/>5 PPRs - 4.7/5 rating<br/>Technical specialist"]
Studios_Before["Production Network: 4 studios<br/>Limited large-scale collaboration"]
end
subgraph "Artistic Collaboration Process"
Phase1[Concept & Planning]
Phase2[Multi-Studio Production]
Phase3[Artistic Integration]
Phase4[Creative Validation]
Phase1 --> Phase2
Phase2 --> Phase3
Phase3 --> Phase4
end
subgraph "After Collaborative Production"
Elena_After["Elena: Innovation Leader<br/>10 PPRs - 5.0/5 rating<br/>plus 1 LargeScaleInstallation<br/>plus 1 CreativeCollaboration"]
Marcus_After["Marcus: Art-Tech Integration Expert<br/>8 PPRs - 4.9/5 rating<br/>plus 1 ArtisticFabrication<br/>plus 1 TechnicalInnovation"]
Studios_After["Production Network: Enhanced<br/>Plus 1 CollaborativeCreation<br/>Plus resource sharing models"]
end
Elena_Before --> Phase1
Marcus_Before --> Phase1
Studios_Before --> Phase1
Phase4 --> Elena_After
Phase4 --> Marcus_After
Phase4 --> Studios_After
🏗️ Integrated Platform Architecture: Nondominium + TrueCommon
Complete Peer Production Management System
graph TB
subgraph "Current Nondominium Implementation"
ND_Person[Person Zome - Artist Profiles]
ND_Resource[Resource Zome - Studio Resources]
ND_Governance[Governance Zome - Creative Standards]
PPR[PPR Reputation System]
end
subgraph "Required TrueCommon Implementation"
TC_REA[Full REA Economics Model]
TC_NRP[Network Resource Planning]
TC_Accounting[Integrated Accounting]
TC_Planning[Production Planning]
TC_Impact[Impact Measurement]
end
subgraph "Enhanced Production Platform"
Creative[Concept Management]
Scheduling[Production Timeline]
Quality[Artistic Validation]
Documentation[Process Documentation]
Financial[Cost Accounting]
Impact[Social Impact Tracking]
Workflow[Production Workflow]
end
%% Current Nondominium Connections
Creative --> ND_Person
Scheduling --> ND_Resource
Quality --> ND_Governance
Documentation --> PPR
%% TrueCommon Integration
Financial --> TC_Accounting
Workflow --> TC_NRP
Impact --> TC_Impact
Scheduling --> TC_Planning
Creative --> TC_REA
%% Cross-system integration
TC_NRP -.-> |Resource Optimization| ND_Resource
TC_Accounting -.-> |Transaction Data| PPR
TC_REA -.-> |Agent Identities| ND_Person
Where Nondominium Ends and TrueCommon Must Begin
Nondominium Provides (Current):
- ✅ Resource discovery and access governance
- ✅ Agent reputation through PPR system
- ✅ Secure economic event logging
- ✅ Bilateral transaction coordination
TrueCommon Must Provide (Missing):
- ❌ Network Resource Planning: Coordinated multi-studio production scheduling
- ❌ Full REA Integration: Complete economic relationships beyond simple transactions
- ❌ Production Workflow Management: Multi-stage production process coordination
- ❌ Integrated Accounting: Complete financial tracking across production network
- ❌ Demand-Supply Planning: Resource allocation optimization across network
- ❌ Social/Environmental Impact: Comprehensive impact measurement and reporting
Advanced Art Production Features
Creative Collaboration Tools:
- Concept Sharing: Secure development environment for sharing early-stage artistic concepts
- Progressive Reveal: Staged sharing of technical details while protecting artistic IP
- Creative Feedback: Structured artistic critique and validation processes
- Documentation: Automatic creation of process documentation for archival and educational purposes
Resource Sharing Capabilities:
- Equipment Marketplace: Shared access to expensive specialized fabrication equipment
- Studio Time Trading: Token-based system for trading studio access and expertise
- Material Sourcing: Collective purchasing power for bulk art material acquisition
- Skill Exchange: Knowledge sharing and skill development between collaborating artists
💡 Artistic Innovation Benefits
Creative Collaboration Advantages
- Scale Enablement: Artists can undertake larger, more ambitious projects than possible individually
- Specialization Access: Access to specialized technical skills without becoming expert in all areas
- Risk Distribution: Shared financial and creative risks across collaborative network
- Innovation Cross-Pollination: New ideas emerging from intersection of different artistic approaches
Economic & Artistic Impact
mindmap
root((Collaborative Art Production))
Creative Benefits
Artistic Vision Expansion
Larger scale projects
Technical complexity
Multi-disciplinary integration
Innovation Acceleration
New techniques development
Cross-studio learning
Creative problem solving
Economic Advantages
Resource Efficiency
Shared equipment costs
Studio time optimization
Material bulk purchasing
Market Access
Larger project opportunities
Public art commissions
Gallery representation
Community Building
Artist Network
Collaboration opportunities
Skill development
Knowledge sharing
Cultural Impact
Public art enhancement
Cultural dialogue
Community engagement
Technology-Enhanced Art Creation
- Digital Fabrication: Integration of traditional art techniques with advanced manufacturing
- Interactive Art: New possibilities for art that responds to audience and environment
- Process Documentation: Complete digital record of creative process for educational purposes
- Innovation Sharing: Platform for sharing new techniques and approaches with artistic community
🎯 Strategic Art Production Outcomes
Immediate Creative Benefits
- ✅ Artistic Achievement: Successfully completed complex interactive sculpture
- ✅ Innovation Recognition: Developed new approaches to pedestrian-responsive art
- ✅ Collaboration Excellence: Established model for multi-studio artistic production
- ✅ Public Impact: Installation received critical acclaim and community engagement
Long-Term Artistic Development
- Production Network: Established ongoing collaborative relationships for ambitious projects
- Technical Innovation: Developed new fabrication and integration techniques now being adopted by other artists
- Artistic Growth: All collaborating artists expanded their creative capabilities and portfolios
- Community Building: Created framework for supporting large-scale public art in the community
Platform Evolution
- Production Templates: Standardized workflows for different types of collaborative art production
- Innovation Library: Growing database of new techniques and approaches developed through collaboration
- Artist Marketplace: Enhanced platform connecting artists with complementary skills and resources
- Educational Resources: Documentation and case studies for artistic community learning
🔮 Future Art Production Scenarios
Advanced Creative Collaboration
- Virtual Reality Collaboration: Immersive collaborative design environments for distributed artistic teams
- AI-Assisted Creation: Integration of AI tools for concept development and technical problem-solving
- Blockchain Art History: Complete provenance tracking for collaborative artworks with attribution recorded on blockchain
- Global Production Networks: International collaboration between artists across different cultural contexts
New Art Forms Enabled
- Generative Art: Collaborative creation of art that evolves and responds to environmental inputs
- Participatory Installation: Large-scale works involving community members in creation process
- Responsive Architecture: Art that becomes integrated with building systems and responsive to occupancy
- Digital-Physical Hybrid: Works that exist simultaneously in physical and digital realms
This user story demonstrates how Nondominium enables artists to scale their creative vision through collaborative production networks, combining artistic creativity with technical expertise while maintaining creative control and fair attribution through decentralized governance and reputation systems.
"Urban Canopy" installation successfully completed and installed in downtown plaza, receiving widespread public acclaim. The collaborative production model has since been adopted by 3 other artist collectives for projects ranging from interactive museum installations to responsive environmental artworks.
User Story: Resource Sharing / Mutualization
Scenario: Two Organizations Sharing Equipment via an open source ERP
Context: Sensorica (a maker space) and FabLab (a fabrication lab) want to share a CNC machine through their traditional open source ERP platform integration with Nondominium. This scenario represents Nondominium's core strength - bilateral resource sharing between organizations - with potential enhancement for broader equipment network optimization.
See also erp_holochain_bridge.md
How to read this story (grounding note). The CNC machine is an NDO: a permanent Layer 0
NondominiumIdentity, a Layer 1ResourceSpecificationwith accessGovernanceRules (certified operators, insurance), and a Layer 2EconomicResourceinstance whosecustodianmoves Sarah → Marco → Sarah and whoseOperationalStatecyclesAvailable → Reserved → InTransit → InUse(lifecycle maturity stays on Layer 0). Custody handoffs usetransfer_custody, which records aTransferCustodyeconomic event and issues bilateral PPRs from the 16-category set:CustodyTransfer/CustodyAcceptancefor the handoff,TransportCommitmentAccepted/TransportFulfillmentCompletedfor Marco's transport service, andGoodFaithTransferfor the trust-based lend. Narrative labels likeUseService,ServiceValidation, andCommitmentFulfillmentare shorthand for these realParticipationClaimTypevalues. The ERP, mobile app, and REST API are the Web2 host platform (the Node.js bridge); steps againstNDare the ValueFlows/governance zome calls. Organizational-agent delegation (org owns, employee holds custody) is post-MVP (seespecifications.md §6); the MVP treats each participant as an individual agent.
🏗️ System Architecture Context
Perfect Nondominium Use Case (Equipment Sharing)
graph TB
subgraph "Nondominium - Equipment Sharing Excellence"
Person[Person Zome - Organization Reps]
Resource[Resource Zome - Equipment Registry]
Governance[Governance Zome - Access Rules]
PPR[PPR Reputation System]
end
subgraph "Equipment Sharing Capabilities"
Discovery[Equipment Discovery]
Access[Secure Access Control]
Validation[Operator Certification]
Reputation[Custodial Reputation]
end
Person --> Discovery
Resource --> Access
Governance --> Validation
PPR --> Reputation
Nondominium Perfectly Supports:
- Equipment discovery and availability management
- Access governance with certification requirements
- Reputation tracking for equipment care and responsible usage
- Secure transaction logging and audit trails
Enhancement Option (Equipment Network Optimization)
graph TB
subgraph "Network Resource Planning (NRP)"
NRP[Equipment Network Planning]
Utilization[Utilization Optimization]
Maintenance[Shared Maintenance Planning]
Costing[Usage-Based Costing]
end
subgraph "Enhanced Equipment Management"
Scheduling[Network-wide Scheduling]
Capacity[Capacity Planning]
Maintenance[Preventive Maintenance]
CostAllocation[Fair Cost Allocation]
end
Post MVP Would Add:
- Multi-equipment network optimization
- Predictive maintenance scheduling
- Utilization analytics and bottleneck identification
- Fair cost allocation across network participants
🎯 The Players
Sarah - Sensorica Resource Coordinator
- Role: Primary Accountable Agent (Custodian)
- Goal: Make expensive equipment available to partner organizations
- Reputation: High PPR scores in ResourceValidation and CustodyTransfer
Marco - FabLab Technical Manager
- Role: Accountable Agent with Transport & Repair specializations
- Goal: Access CNC machine for prototype production
- Reputation: Strong performance in TransportFulfillmentCompleted and MaintenanceFulfillmentCompleted
The Resource
- CNC Machine Model: Proxxon MF70 (modified)
- Current Location: Sensorica Workshop, Montreal
- Governance Rules: Requires certified operators, insurance validation
🔄 Transaction Journey
Phase 1: Discovery & Intent (Day 1)
sequenceDiagram
participant Marco as Marco (FabLab)
participant ERP as ERP
participant ND as Nondominium
participant Res as Resource Zome
participant Gov as Governance Zome
Marco->>ERP: Search for CNC equipment
ERP->>ND: get_all_economic_resources()
ND->>Res: Query available resources
Res-->>ND: Return CNC machine specs
ND-->>ERP: Resource with governance rules
ERP-->>Marco: Display CNC machine details
Marco->>ERP: Review governance rules
ERP->>ND: get_resource_specification_with_rules()
ND->>Gov: Return rules (certification, insurance)
Marco->>ERP: Submit AccessForUse commitment
ERP->>ND: propose_commitment()
ND->>Gov: Create commitment
Sarah's Actions:
- Resource Discovery: Marco searches the ERP for available fabrication equipment
- Governance Review: Marco reviews CNC machine's embedded governance rules:
- Requires Transport certification ✅
- Proof of facility insurance required
- Minimum 48-hour notice for transport
- Intent Signaling: Marco submits
AccessForUsecommitment through ERP interface
Phase 2: Validation & Trust Building (Day 2)
sequenceDiagram
participant Sarah as Sarah (Sensorica)
participant ERP as ERP
participant ND as Nondominium
participant PPR as PPR System
ND->>Sarah: Notify of new commitment
Sarah->>ERP: Review Marco's credentials
ERP->>ND: derive_reputation_summary(Marco)
ND->>PPR: Calculate reputation scores
PPR-->>ND: Return reputation data (98% on-time, 4.8/5 quality)
ND-->>ERP: Display Marco's reputation
Sarah->>ND: validate_agent_for_custodianship()
ND->>Gov: Create validation receipt
Gov-->>ERP: Commitment approved
Multi-Party Validation:
- Identity Verification: Sarah validates Marco's credentials and insurance
- Capability Check: System validates Marco's Transport certification
- Reputation Assessment: Sarah reviews Marco's PPR summary:
- 98% on-time delivery rate
- 4.8/5 quality score
- 12 successful transport completions
Phase 3: Resource Preparation (Day 3)
stateDiagram-v2
[*] --> Available: CNC Machine Available
Available --> Reserved: Sarah prepares for transport
Reserved --> InTransit: Documentation complete, handoff begins
note right of Reserved
OperationalState: Available → Reserved → InTransit
(LifecycleStage stays Active on Layer 0)
Transport protocols linked
Insurance certificate uploaded
end note
Sarah's Preparation:
- Resource State Update: Changes CNC
OperationalStatefromAvailabletoReserved(Layer 0LifecycleStagestaysActive) - Transport Documentation: Creates transport checklist and safety protocols
- Insurance Coordination: Uploads facility insurance certificate
Phase 4: Transport Process (Day 4)
sequenceDiagram
participant Marco as Marco (FabLab)
participant Sarah as Sarah (Sensorica)
participant ERP as ERP
participant ND as Nondominium
participant Res as Resource Zome
participant PPR as PPR System
Marco->>ERP: Arrive for transport
ERP->>ND: update_operational_state(InTransit)
ND->>Gov: Validate Marco's Transport role (validate_specialized_role)
Sarah->>ERP: Scan QR code on CNC machine
Marco->>ERP: Scan QR code confirmation
ERP->>ND: transfer_custody()
ND->>Res: Update custodian: Sarah → Marco
Note over ND,Gov: transfer_custody logs the TransferCustody economic event
Gov->>PPR: issue_participation_receipts()
PPR-->>ND: Generate bilateral PPRs for both agents
ND-->>ERP: Update transport status
The Physical Transfer:
- Transport Initiation: Marco arrives with certified transport equipment
- Custody Transfer Ceremony: Both agents scan QR codes on CNC machine
- Multi-Signature Process: Bilateral cryptographic signatures executed
- Real-time Updates: ERP shows live transport status
Phase 5: Usage & Monitoring (Week 1-2)
graph LR
subgraph "Usage Process"
A[Start Use] --> B[Log Daily Usage]
B --> C[Performance Metrics]
C --> D[PPR Generation]
D --> E[Quality Monitoring]
end
subgraph "PPR Categories (16-category set)"
F[RuleCompliance]
G[ValidationActivity]
H[TransportFulfillmentCompleted]
end
D --> F
D --> G
D --> H
Resource Utilization:
- Use Process Activation: Marco initiates CNC machine for prototype production
- Quality Monitoring: System tracks usage hours and maintenance needs
- Progress Reporting: Daily usage logs through ERP interface
- Performance Metrics: Automatic PPR generation for each use session
Phase 6: Return & Completion (Day 15)
sequenceDiagram
participant Marco as Marco (FabLab)
participant Sarah as Sarah (Sensorica)
participant ERP as ERP
participant ND as Nondominium
participant PPR as PPR System
Marco->>ERP: Complete maintenance checklist
ERP->>ND: claim_commitment()
Marco->>ERP: Initiate return transport
ERP->>ND: update_operational_state(InTransit)
Sarah->>ERP: Scan return QR code
ERP->>ND: transfer_custody()
ND->>Res: Update custodian: Marco → Sarah
Sarah->>ERP: Inspect and approve return
ERP->>ND: validate_specialized_role()
ND->>Gov: Create validation receipts
Gov->>PPR: issue_participation_receipts()
PPR-->>ND: Update reputation scores
ND-->>ERP: Transaction complete
Return Process:
- Maintenance Check: Marco performs routine maintenance and documents condition
- Return Transport: Reverse transport with same validation process
- Final Assessment: Sarah inspects returned equipment
- Bilateral PPR Issuance: Both agents receive participation receipts
🏆 Transaction Outcomes
Immediate Benefits
- ✅ Cost Savings: FabLab saves $15,000 on equipment purchase
- ✅ Revenue: Sensorica earns $800 usage fee
- ✅ Capacity Building: Both organizations expand fabrication capabilities
- ✅ Trust Enhancement: PPR scores improved for both agents
Reputation Impact
graph LR
subgraph "Before Transaction"
Sarah_Before[Sarah: 4.7/5<br/>12 PPRs]
Marco_Before[Marco: 4.6/5<br/>8 PPRs]
end
subgraph "Transaction Process"
Phase1[Discovery & Validation]
Phase2[Transport Process]
Phase3[Usage Period]
Phase4[Return Process]
Phase1 --> Phase2
Phase2 --> Phase3
Phase3 --> Phase4
end
subgraph "After Transaction"
Sarah_After[Sarah: 4.9/5<br/>15 PPRs<br/>+1 CustodyTransfer<br/>+1 GoodFaithTransfer]
Marco_After[Marco: 4.8/5<br/>11 PPRs<br/>+1 CustodyAcceptance<br/>+1 TransportFulfillmentCompleted]
end
Sarah_Before --> Phase1
Marco_Before --> Phase1
Phase4 --> Sarah_After
Phase4 --> Marco_After
Sarah's PPR Updates:
- +1 CustodyTransfer (outgoing)
- +1 GoodFaithTransfer
- Performance: 5.0/5 reliability score
Marco's PPR Updates:
- +1 CustodyAcceptance (incoming)
- +1 TransportFulfillmentCompleted
- Performance: 4.9/5 overall satisfaction
Network Effects
- New Resource Discovery: Two other organizations express interest in similar sharing
- Process Optimization: Transport protocol refined for future transactions
- Community Building: Sensorica and FabLab plan collaborative training workshop
🔗 Web2 Integration Features
System Architecture Integration
graph TB
subgraph "Web2 Platform Layer"
ERP[ERP Platform]
Mobile[Mobile App]
API[REST API]
end
subgraph "Nondominium Core"
Person[Person Zome]
Resource[Resource Zome]
Governance[Governance Zome]
end
subgraph "PPR System"
Claims[Private Participation Claims]
Reputation[Reputation Summary]
Crypto[Cryptographic Signatures]
end
subgraph "External Systems"
Inventory[Inventory Management]
Insurance[Insurance Systems]
Finance[Financial Reporting]
end
ERP --> API
Mobile --> API
API --> Person
API --> Resource
API --> Governance
Governance --> Claims
Claims --> Reputation
Reputation --> Crypto
Resource --> Inventory
Governance --> Insurance
API --> Finance
Person -.-> |Identity Management| Resource
Resource -.-> |Resource Lifecycle| Governance
Governance -.-> |Validation & PPR| Person
ERP Interface
- Resource Gallery: Visual catalog with availability calendars
- Agent Profiles: Public reputation summaries with privacy controls
- Workflow Dashboard: Step-by-step transaction tracking
- Notification System: Real-time updates via email and ERP messages
Enterprise Integration
- Synchronization: Resource status synced with inventory management systems
- Reporting: Usage analytics and financial reconciliation
- Compliance: Automatic audit trail for insurance and regulatory requirements
- API Access: RESTful endpoints for custom workflow integrations
User Experience
- Mobile App: Field operations with QR code scanning
- Document Management: Secure storage of certificates and agreements
- Communication Hub: Integrated messaging for coordination
- Analytics Dashboard: Usage patterns and cost optimization insights
💡 Key Innovation Highlights
Trust Without Platforms
- No central authority controlling the resource
- Direct peer-to-peer governance through embedded rules
- Cryptographic reputation that travels with agents
Privacy-Preserving Transparency
- Economic events publicly visible for accountability
- Private operational details protected through capability access
- Selective disclosure of sensitive information
Progressive Trust Building
- Start with basic resource sharing
- Build reputation through successful transactions
- Unlock more complex collaborative opportunities
Composable Workflows
- Transport → Use → Maintenance → Return processes
- Multi-agent coordination for complex projects
- Automated governance enforcement at each step
🎯 Business Value Proposition
Web2 Integration Benefits
mindmap
root((Nondominium + Web2))
Platform Enhancement
New Revenue Streams
Transaction fees
Premium features
User Engagement
Reputation system
Gamified participation
Network Effects
Growing ecosystem
Resource discovery
Business Value
Cost Reduction
Shared access to equipment
Reduced capital investment
Risk Management
Insured transactions
Clear accountability
Innovation Enablement
Democratized access
Collaborative opportunities
Technical Features
Familiar Interface
ERP integration
Mobile accessibility
Enterprise Ready
API integration
Reporting dashboard
Trust Layer
Cryptographic reputation
Privacy-preserving transparency
For Web2 Platforms
- New Revenue Streams: Transaction fees and premium features
- User Engagement: Increased platform stickiness through reputation
- Network Effects: Growing ecosystem of shared resources
- Competitive Advantage: Differentiation through decentralized trust
For Organizations
- Resource Optimization: Better utilization of expensive equipment
- Cost Reduction: Shared access to specialized tools and facilities
- Risk Management: Insured transactions with clear accountability
- Innovation Enablement: Access to resources without capital investment
For the Community
- Sustainability: Reduced waste through resource sharing
- Accessibility: Democratized access to expensive equipment
- Skill Development: Knowledge sharing through collaboration
- Economic Resilience: Distributed resource ownership
This user story demonstrates how Nondominium enables Web2 platforms to transform from simple content management systems into powerful engines for decentralized resource sharing, combining the familiarity of existing platforms with the trust and transparency of blockchain-based governance.
Transaction completed successfully in 15 days with both organizations reporting high satisfaction and expressing interest in expanding their sharing partnership.
User Story: Food Basket - Last-Mile Logistics Coordination
Scenario: Cooperative Distribution Network for Local Food Systems
Context: A network of local farms and food producers coordinates last-mile delivery to urban customers through a distributed logistics system powered by Nondominium, optimizing routes and sharing delivery resources.
How to read this story (grounding note). Produce batches and shared logistics assets (refrigerated vehicles, cold-storage) are NDOs: a permanent Layer 0
NondominiumIdentity(create_ndo), an optional Layer 1ResourceSpecificationfor the produce type and food-safetyGovernanceRules, and a Layer 2EconomicResourceinstance (create_economic_resource) whosecustodianandOperationalState(Available → Reserved → InTransit → InStorage) move as the basket travels farm → hub → customer. Custody handoffs between producer, hub, and courier usetransfer_custody, which logs aTransferCustodyeconomic event and issues bilateral Private Participation Receipts (PPRs) — here mainly the service categoriesTransportCommitmentAccepted/TransportFulfillmentCompletedandStorageCommitmentAccepted/StorageFulfillmentCompleted, plusCustodyTransfer/CustodyAcceptance. Route optimization, temperature IoT, and payment settlement are host-platform responsibilities layered on top of Nondominium; steps shown againstNDare the ValueFlows/governance calls, while platform-orchestration steps are illustrative of the surrounding system. Multi-producer, N-to-M consolidation is a post-MVP many-to-many flow (seedocumentation/requirements/post-mvp/many-to-many-flows.md); the MVP models each leg as one-to-one custody events.
🚚 The Players
Maria Garcia - Organic Farm Owner
- Role: Accountable Agent (Producer & Shipper)
- Goal: Efficiently distribute fresh produce to urban customers while maintaining quality
- Reputation: Certified organic producer with excellent delivery track record
James Chen - Logistics Coordinator
- Role: Primary Accountable Agent (Distribution Manager)
- Goal: Optimize delivery routes and coordinate multi-producer distribution
- Reputation: Expert in cold chain logistics and route optimization
The Distribution Network
- Network Members: 8 local farms, 3 community kitchens, 2 urban distribution hubs
- Assets: Refrigerated vehicles, bike couriers, temperature monitoring devices
- Governance Rules: Food safety compliance, temperature tracking, delivery time windows
🔄 Distribution Journey
Phase 1: Production Planning & Distribution Needs (Monday)
sequenceDiagram
participant Maria as Maria Garcia
participant Platform as Distribution Platform
participant ND as Nondominium
participant Res as Resource Zome
participant Gov as Governance Zome
Maria->>Platform: Submit weekly harvest and delivery needs
Maria->>ND: create_person(Maria) + assign_person_role(Transport/Storage where applicable)
ND->>Res: Create producer profile with certifications
Maria->>ND: create_resource_specification(OrganicProduce) + attach GovernanceRule
ND->>Res: Store produce specifications and quality standards
ND->>Gov: Link food safety requirements and temperature controls
Maria->>ND: create_ndo(ProduceBatch) + create_economic_resource(WeeklyHarvest)
ND->>Res: Register produce batches with lot tracking (OperationalState: Available)
ND->>Gov: Embed governance rules for food safety
Production & Distribution Planning:
- Harvest Registration: Maria registers weekly production:
- Mixed vegetables: 250 kg total
- Temperature requirements: 2-4°C throughout delivery
- Delivery windows: Tuesday and Thursday, 6-9 PM
- Quality standards: Organic certification, freshness guarantees
- Food Safety Setup: HACCP compliance and temperature monitoring requirements
- Batch Tracking: Lot numbers and timestamps for complete traceability
- Distribution Scheduling: Integration with weekly delivery planning system
Phase 2: Route Optimization & Network Coordination (Tuesday Morning)
sequenceDiagram
participant James as James Chen
participant Platform as Distribution Platform
participant ND as Nondominium
participant PPR as PPR System
participant Gov as Governance Zome
James->>Platform: Review weekly distribution requirements
Platform->>ND: get_all_ndos() / get_all_economic_resources()
ND->>Res: Query all registered produce batches for week
Res-->>ND: Return consolidated resource list
James->>Platform: optimize_delivery_routes() (host-platform logistics)
Note over Platform: Route optimization is a platform concern, not a zome call
James->>ND: derive_reputation_summary(Producers)
ND->>PPR: Calculate producer reliability scores
PPR-->>ND: Return producer quality ratings (avg 4.8/5)
James->>ND: propose_commitment(TransferCustody/AccessForUse) per producer
ND->>Gov: Generate delivery commitments with all producers
Network Optimization Process:
- Delivery Consolidation: James reviews all producer delivery needs:
- 8 producers with 250-400 kg each
- 150 urban delivery addresses
- Geographic clustering optimization
- Route Planning: Algorithm optimizes for:
- Minimum total distance: 127 km reduced to 89 km
- Temperature maintenance requirements
- Customer delivery time windows
- Vehicle capacity constraints
- Producer Validation: All producers verified for food safety compliance and on-time performance
- Resource Sharing: Refrigerated vehicles and bike couriers coordinated across network
Phase 3: Multi-Producer Consolidation & Hub Operations (Tuesday Afternoon)
stateDiagram-v2
[*] --> HarvestComplete: All producers ready
HarvestComplete --> PickupScheduled: Route optimization complete
PickupScheduled --> InTransitToHub: First pickup initiated
InTransitToHub --> HubProcessing: Arrive at distribution hub
HubProcessing --> ConsolidationReady: Quality verification complete
ConsolidationReady --> LastMileDelivery: Final route loading
note right of HubProcessing
OperationalState: InTransit → InStorage → Reserved
Temperature verification: 3.2°C ✅
Quality inspection: All produce fresh
Lot scanning: Complete traceability
Mixed-produce consolidation
end note
Consolidation & Hub Operations:
- Producer Pickup: James coordinates pickup sequence to minimize total travel distance
- Temperature Verification: Each pickup scanned for temperature compliance and quality
- Hub Processing: At urban distribution hub:
- Quality verification for all produce
- Mixed-produce consolidation for final delivery efficiency
- Customer order assembly and packaging
- Final route planning optimization
- Blockchain Tracking: Each produce batch logged with complete temperature and handling history
Phase 4: Last-Mile Delivery & Customer Interaction (Tuesday Evening)
graph TB
subgraph "Delivery Fleet Coordination"
A[Refrigerated Van - High Volume Routes]
B[Bike Couriers - Urban Core]
C[Electric Cargo Bikes - Eco Zones]
end
subgraph "Delivery Process"
D[Route 1: Downtown - 45 deliveries]
E[Route 2: Residential West - 38 deliveries]
F[Route 3: University District - 32 deliveries]
end
subgraph "Customer Experience"
G[Real-time Tracking]
H[QR Code Verification]
I[Quality Confirmation]
J[Feedback Collection]
end
A --> D
B --> E
C --> F
D --> G
E --> H
F --> I
I --> J
Last-Mile Delivery Execution:
- Fleet Deployment: Mixed transportation approach:
- 1 refrigerated van for high-volume suburban routes
- 2 bike couriers for dense urban core delivery
- 1 electric cargo bike for environmentally sensitive zones
- Real-Time Tracking: Customers receive live delivery updates and ETAs
- Quality Verification: QR codes on each package enable:
- Producer verification and origin confirmation
- Temperature history verification
- Freshness guarantee validation
- Customer Interaction: Delivery confirmation and immediate feedback collection
Phase 5: Quality Assurance & Network Payment Processing (Wednesday)
sequenceDiagram
participant Maria as Maria Garcia
participant James as James Chen
participant Platform as Distribution Platform
participant ND as Nondominium
participant PPR as PPR System
James->>ND: claim_commitment() per delivery leg
ND->>Gov: Validate deliveries completed against commitments
Gov-->>ND: Delivery completion confirmation
Maria->>Platform: Review delivery performance report
Platform->>ND: validate_new_resource() / check_validation_status()
ND->>Gov: Verify temperature compliance and on-time delivery
Gov-->>Platform: Quality metrics confirmed
Maria->>ND: issue_participation_receipts(TransportFulfillmentCompleted, StorageFulfillmentCompleted)
ND->>Gov: Record bilateral service PPRs with PerformanceMetrics
Gov->>PPR: Persist private participation claims
James->>ND: create_agreement(BenefitClause) for revenue split
Note over ND: Automatic settlement (payment rails) is post-MVP (Unyt); Agreement/BenefitClause captures the split on-DHT
Quality Assurance & Settlement:
- Delivery Metrics Analysis:
- 98% on-time delivery rate
- 100% temperature compliance maintained
- 4.9/5 average customer satisfaction rating
- Quality Verification: All produce maintained freshness standards with zero quality complaints
- Payment Processing: Smart contract automatically distributes payments:
- 85% to producers based on volume delivered
- 10% to logistics network for distribution services
- 5% to platform maintenance and development
- Reputation Enhancement: All network participants receive PPRs for successful collaboration
📊 Distribution Analytics & Network Performance
Real-Time Delivery Monitoring Dashboard
graph LR
subgraph "Operational Metrics"
A[Delivery Success Rate: 98%]
B[Temperature Compliance: 100%]
C[Route Efficiency: 30% improvement]
D[Customer Satisfaction: 4.9/5]
end
subgraph "Environmental Impact"
E[CO2 Reduction: 40% vs individual delivery]
F[Food Waste Reduction: 95% vs traditional]
G[Local Food Access: +250 households]
H[Economic Circulation: $12,500 local]
end
subgraph "Network Efficiency"
I[Vehicle Utilization: 87%]
J[Resource Sharing: 3x efficiency]
K[Scalability: Ready for 2x expansion]
L[Adaptability: Weather-optimized routing]
end
A --> E
B --> F
C --> G
D --> H
E --> I
F --> J
G --> K
H --> L
Network Performance Impact Analysis
graph LR
subgraph "Before Network Distribution"
Maria_Before["Maria: Individual Delivery<br/>4.2/5 efficiency<br/>High overhead costs"]
James_Before["James: Single Route Planning<br/>Limited network effect"]
System_Before["Food System: Fragmented<br/>High environmental impact"]
end
subgraph "Network Coordination Process"
Phase1[Production Planning]
Phase2[Route Optimization]
Phase3[Hub Consolidation]
Phase4[Last-Mile Delivery]
Phase1 --> Phase2
Phase2 --> Phase3
Phase3 --> Phase4
end
subgraph "After Network Distribution"
Maria_After["Maria: Network Producer<br/>4.9/5 delivery reliability<br/>40% cost reduction<br/>+2 TransportFulfillmentCompleted<br/>+1 CustodyTransfer"]
James_After["James: Logistics Network Manager<br/>+3 CustodyAcceptance<br/>+1 ValidationActivity"]
System_After["Food System: Integrated<br/>Sustainable & Efficient<br/>Local economic multiplier"]
end
Maria_Before --> Phase1
James_Before --> Phase1
System_Before --> Phase1
Phase4 --> Maria_After
Phase4 --> James_After
Phase4 --> System_After
🏗️ Distribution Platform Architecture
Logistics Coordination System
graph TB
subgraph "Distribution Management Platform"
Planning[Route Planning]
Tracking[Real-Time Tracking]
Quality[Quality Monitoring]
Payments[Automated Settlement]
end
subgraph "Nondominium Distribution Integration"
Person[Person Zome - Producer/Courier Profiles]
Resource[Resource Zome - Food Assets & Vehicles]
Governance[Governance Zome - Food Safety Rules]
end
subgraph "External Systems"
GPS[GPS Navigation]
IoT[Temperature Sensors]
Payment[Payment Processing]
Compliance[Food Safety Compliance]
end
Planning --> Resource
Tracking --> Person
Quality --> Governance
Payments --> Governance
Resource -.-> |Asset Status| IoT
Person -.-> |Location Tracking| GPS
Governance -.-> |Compliance Verification| Compliance
Advanced Distribution Features
Smart Logistics Capabilities:
- Dynamic Route Optimization: Real-time adjustment based on traffic, weather, and delivery constraints
- Predictive Quality Monitoring: AI-powered temperature prediction and spoilage prevention
- Automated Resource Matching: Intelligent assignment of vehicles and couriers based on delivery requirements
- Customer Preference Integration: Personalized delivery time windows and communication methods
Network Coordination Tools:
- Capacity Sharing: Shared utilization of refrigerated vehicles and cold storage facilities
- Cross-Training Programs: Multi-skilled couriers capable of handling diverse food products
- Emergency Response: Rapid response system for delivery failures or quality issues
- Seasonal Adaptation: Flexible network scaling for harvest season variations
💡 Distribution Innovation Benefits
Food System Resilience
- Local Food Security: Increased reliability of fresh food access in urban areas
- Producer Sustainability: Improved economic viability for small-scale farmers
- Environmental Benefits: Reduced food miles and transportation emissions
- Quality Preservation: Maintained food safety and nutritional value through optimized logistics
Economic & Social Impact
mindmap
root((Local Food Distribution))
Economic Benefits
Producer Revenue
Direct market access
Reduced middlemen costs
Predictable cash flow
Consumer Value
Fresher produce
Competitive pricing
Traceability assurance
Environmental Sustainability
Reduced Food Miles
Consolidated delivery
Optimized routing
Alternative transport modes
Waste Reduction
Better inventory management
Extended shelf life
Composting partnerships
Community Building
Food Access
Underserved neighborhoods
Elderly and mobility limited
Food desert remediation
Local Economy
Job creation
Skill development
Community wealth building
Technology-Enhanced Food Systems
- Complete Traceability: Blockchain-based farm-to-table tracking with temperature and quality data
- Predictive Analytics: Machine learning for demand forecasting and resource optimization
- Quality Automation: Computer vision and sensors for automated quality assessment
- Customer Education: Rich data about food origins, nutrition, and preparation
🎯 Strategic Distribution Outcomes
Immediate Network Benefits
- ✅ Cost Reduction: 35% lower distribution costs through consolidation and sharing
- ✅ Quality Improvement: 15% reduction in food waste and spoilage
- ✅ Customer Satisfaction: 4.9/5 rating with 92% customer retention
- ✅ Environmental Impact: 40% reduction in CO2 emissions from optimized logistics
Long-Term Food System Evolution
- Food Security: Established reliable local food distribution network serving 5,000+ households
- Producer Viability: 25 small farms achieved economic sustainability through direct market access
- Community Resilience: Local food system capable of adapting to supply chain disruptions
- Scalable Model: Framework replicable in other cities and regions
Platform Development
- Distribution Templates: Standardized workflows for different food types and delivery models
- Quality Standards: Developing industry benchmarks for local food distribution excellence
- Network Marketplace: Growing platform for connecting additional producers and customers
- Innovation Pipeline: Continuous improvement through feedback and data analytics
🔮 Future Distribution Scenarios
Advanced Food Logistics Integration
- Autonomous Delivery: Integration with autonomous vehicles and delivery drones for last-mile delivery
- Smart Packaging: IoT-enabled packaging that monitors and reports on food quality in real-time
- Blockchain Integration: Enhanced traceability with smart contracts for automatic quality enforcement
- AI-Powered Demand: Predictive analytics for production planning and inventory optimization
Network Expansion Models
- Regional Hubs: Scaling to multiple cities with inter-connected regional distribution centers
- Multi-Modal Integration: Combining different transportation modes (water, rail, road) for maximum efficiency
- Community Integration: Partnering with schools, hospitals, and community organizations for institutional delivery
- International Networks: Cross-border local food distribution with appropriate compliance and certification
This user story demonstrates how Nondominium enables distributed logistics networks to coordinate complex last-mile delivery operations, optimizing resource utilization while maintaining quality standards and creating resilient local food systems through decentralized governance and reputation-based trust.
Distribution network now serves 5,000+ households weekly with 98% customer satisfaction. The network has expanded to include 12 additional producers and is planning expansion to neighboring cities. The collaborative model has become a blueprint for sustainable local food systems nationwide.
User Story: peer production (makerspace) - Collaborative Manufacturing
Scenario: Makerspace Network Producing Custom Equipment Using Nondominium
Context: A distributed network of makerspaces collaborates to produce custom scientific equipment for research institutions. This scenario clearly demonstrates the limitations of Nondominium's resource sharing economics and the critical need for extension (ex. full REA integration with Network Resource Planning (NRP) for complete peer production network management).
How to read this story (grounding note). Components, designs, and the finished sensors are NDOs: a permanent Layer 0
NondominiumIdentity, a Layer 1ResourceSpecificationcarrying quality/IPGovernanceRules (a design shared under theCommonsproperty regime), and Layer 2EconomicResourceinstances that move between makerspaces viatransfer_custody(withOperationalStatecyclingAvailable → Reserved → InTransit → InUse). Custody handoffs and validations issue bilateral PPRs from the 16-category set —ResourceCreation/ResourceValidationfor contributions,CustodyTransfer/CustodyAcceptancefor component movement,ValidationActivityandRuleCompliancefor cross-site QA. Narrative labels likeProductDesign,MultiSiteProduction, andQualityExcellenceare shorthand for these realParticipationClaimTypevalues.This story is deliberately written to expose where the MVP stops: multi-site production planning, workflow sequencing, cost accounting, and network-wide optimization are not Nondominium primitives. They belong to a full REA / NRP layer (referred to here as TrueCommon, i.e. hREA-based Network Resource Planning). Cross-NDO composition is partially served today by
NdoHardLink(Component/DerivedFrom/Supersedes) andContribution/Agreemententries inzome_gouvernance; the rest is post-MVP. Steps againstNDare the ValueFlows/governance zome calls; steps that name planning/workflow/accounting functions are TrueCommon/host-platform concerns, not existing zome externs.
🏗️ System Architecture Context
Production Network Requirements Analysis
graph TB
subgraph "Nondominium Capabilities (Resource Sharing)"
ResourceSharing[Resource Access & Sharing]
Transactions[Transaction Logging]
Reputation[PPR Reputation System]
Governance[Basic Governance Rules]
end
subgraph "TrueCommon Requirements (Production Network)"
NRP[Network Resource Planning]
REA[Full REA Economics]
Workflow[Production Workflow Mgt]
Accounting[Integrated Accounting]
Planning[Demand-Supply Planning]
Impact[Social/Environmental Impact]
end
subgraph "Production Network Gap Analysis"
Gap1["Multi-site Coordination"]
Gap2["Production Workflow Mgt"]
Gap3["Resource Optimization"]
Gap4["Cost Accounting"]
Gap5["Impact Measurement"]
end
ResourceSharing -.-> |Insufficient for| Gap1
Transactions -.-> |Limited| Gap2
Reputation -.-> |No workflow support| Gap3
Governance -.-> |No planning tools| Gap4
Governance -.-> |No impact tracking| Gap5
NRP --> Gap1
Workflow --> Gap2
Planning --> Gap3
Accounting --> Gap4
Impact --> Gap5
Critical Missing Capabilities for Production Networks
What Nondominium Cannot Provide:
- Multi-site Production Planning: Coordinated scheduling across distributed facilities
- Production Workflow Management: Multi-stage production process coordination
- Resource Optimization: Network-wide equipment and material allocation
- Cost Accounting: Complete production cost tracking and allocation
- Supply Chain Integration: Material procurement and inventory management
- Quality Management: Cross-facility quality assurance processes
New capabilities required:
- Network Resource Planning (NRP): Distributed production coordination
- Full REA Integration: Complete economic relationships and value flows
- Production Accounting: Comprehensive cost and contribution tracking
- Supply Chain Management: Material flow optimization across network
- Impact Assessment: Environmental and social impact measurement
🏭 The Players
Dr. Sarah Mitchell - Research Project Lead
- Role: Accountable Agent (Product Designer & Commissioning Agent)
- Goal: Produce custom environmental monitoring sensors for climate research
- Reputation: Successful track record in research equipment design and project management
Alex Thompson - Advanced Fabrication Specialist
- Role: Primary Accountable Agent (Production Facilitator)
- Goal: Coordinate multi-site manufacturing while maintaining quality standards
- Reputation: Expert in precision manufacturing with ISO certification
The Production Network
- Specialized Facilities: 3 makerspaces with complementary capabilities
- Equipment: CNC mills, 3D printers, electronics assembly, calibration labs
- Governance Rules: Quality validation required at each stage, intellectual property protection
🔄 Production Journey
Phase 1: Project Design & Production Planning (Week 1)
sequenceDiagram
participant Sarah as Dr. Sarah Mitchell
participant Platform as Production Platform
participant ND as Nondominium
participant Res as Resource Zome
participant Gov as Governance Zome
Sarah->>Platform: Submit production project
Sarah->>ND: create_person(Sarah) + assign_person_role(where applicable)
ND->>Res: Create project lead profile
Sarah->>ND: create_resource_specification(EnvironmentalSensor) + attach GovernanceRule
ND->>Res: Store technical specifications (Commons regime, IP protection)
ND->>Gov: Link quality standards and IP protection
Sarah->>Platform: Define production workflow
Platform->>Platform: propose_production_workflow() (TrueCommon/NRP — post-MVP)
Note over Platform: Multi-stage workflow sequencing is not a Nondominium zome extern
Sarah->>ND: create_ndo(SensorDesign) as the shared design NDO
Production Planning Process:
- Project Specification: Sarah defines environmental sensor requirements:
- Technical specifications (accuracy, durability, connectivity)
- Quality standards (ISO 9001 compliance)
- Timeline (8 weeks total production)
- Budget allocation ($45,000 total)
- IP Protection: Embedded governance rules protect research against IP enclosure (Commons property regime)
- Workflow Design: Multi-stage production process with validation gates
- Capability Matching: Platform identifies makerspaces with required equipment and expertise
Phase 2: Network Discovery & Capability Matching (Week 2)
sequenceDiagram
participant Alex as Alex Thompson
participant Sarah as Dr. Sarah Mitchell
participant Platform as Production Platform
participant ND as Nondominium
participant PPR as PPR System
Alex->>Platform: Browse production opportunities
Platform->>ND: get_ndo() + get_resource_specification_with_rules()
ND->>Res: Query sensor design specs
Res-->>ND: Return technical requirements
Alex->>ND: derive_reputation_summary(Sarah)
ND->>PPR: Calculate research lead reputation
PPR-->>ND: Return profile (5 PPRs, 4.9/5 project success)
Alex->>ND: validate_specialized_role(Repair/Transport as needed)
ND->>Gov: Verify equipment and certification
Gov-->>Platform: Capability validated
Alex->>Platform: Submit production bid
Platform->>ND: propose_commitment(Work/Modify)
ND->>Gov: Create production commitment (+ create_agreement for benefit split)
Capability Validation Process:
- Production Facility Review: Alex's makerspace capabilities verified:
- CNC precision manufacturing ✅
- Clean room assembly area ✅
- ISO 9001 quality certification ✅
- Electronics testing equipment ✅
- Team Expertise Assessment: Technical team qualifications validated
- Capacity Planning: Production schedule alignment across network facilities
- Quality Assurance: Multi-site quality control procedures established
Phase 3: Multi-Site Production Coordination (Weeks 3-6)
graph TB
subgraph "Production Stage 1: Component Fabrication"
A[Sensor Casings - CNC Machining<br/>Makerspace A]
B[PCB Boards - Precision Milling<br/>Makerspace B]
C[Mounting Hardware - 3D Printing<br/>Makerspace C]
end
subgraph "Production Stage 2: Assembly & Testing"
D[Electronics Assembly<br/>Makerspace B]
E[Sensor Calibration<br/>Makerspace A]
F[Quality Assurance Testing<br/>All Sites]
end
subgraph "Production Stage 3: Integration & Validation"
G[Final Assembly<br/>Makerspace A]
H[Environmental Testing<br/>Makerspace B]
I[Research Validation<br/>Sarah's Lab]
end
A --> D
B --> D
C --> G
D --> E
E --> G
G --> H
H --> I
Distributed Manufacturing Process:
- Stage 1 - Component Production (Weeks 3-4):
- Makerspace A: CNC machining of precision sensor casings
- Makerspace B: PCB fabrication with micro-controller integration
- Makerspace C: 3D printing of mounting brackets and protective components
- Stage 2 - Assembly & Testing (Weeks 4-5):
- Electronics assembly with quality control checkpoints
- Sensor calibration against certified reference standards
- Multi-site cross-validation of test results
- Stage 3 - Integration (Weeks 5-6):
- Final assembly with complete system integration
- Environmental chamber testing for durability validation
- Research team acceptance testing
Phase 4: Quality Assurance & Certification (Week 7)
sequenceDiagram
participant Sarah as Dr. Sarah Mitchell
participant Alex as Alex Thompson
participant Platform as Production Platform
participant ND as Nondominium
participant PPR as PPR System
Alex->>ND: validate_new_resource() per site
ND->>Gov: Execute multi-site quality checks (ValidationReceipts)
Gov-->>ND: Quality validation results
Sarah->>Platform: Review production quality report
Platform->>ND: check_validation_status()
ND->>Gov: Verify ISO compliance
Gov-->>Platform: Certification confirmed
Sarah->>ND: validate_new_resource() (research acceptance)
ND->>Gov: Record ValidationReceipt for finished sensors
Gov->>PPR: issue_participation_receipts(ResourceValidation)
Alex->>ND: claim_commitment()
ND->>PPR: issue_participation_receipts(ResourceCreation, CustodyTransfer)
Quality Assurance Process:
- Multi-Site Validation: Independent quality verification at each production facility
- Cross-Certification: Each site validates work of other sites for redundancy
- Research Acceptance: Sarah's team validates equipment meets research specifications
- Certification Issuance: ISO compliance documented on blockchain
- Performance Tracking: All production stages recorded with PPRs for future reference
📊 Production Analytics & Network Performance
Real-Time Production Monitoring
graph LR
subgraph "Production Metrics"
A[Component Production Rate] --> B[Quality Pass Rate]
B --> C[Timeline Adherence]
C --> D[Cost Efficiency]
end
subgraph "Quality Metrics"
E[Defect Rate: 0.02%]
F[Calibration Accuracy: 99.8%]
G[Environmental Test Pass: 100%]
H[Research Acceptance: 100%]
end
subgraph "Network Performance"
I[Inter-Site Coordination]
J[Resource Utilization]
K[Knowledge Sharing]
L[Continuous Improvement]
end
D --> E
D --> F
D --> G
D --> H
I --> J
J --> K
K --> L
Production Outcomes:
- Quality Achievement: 99.8% calibration accuracy, 100% research acceptance
- Timeline Performance: On-time delivery with 2-day buffer for contingencies
- Cost Optimization: 12% under budget through resource sharing
- Network Efficiency: 85% equipment utilization across all sites
Reputation Development Analysis
graph LR
subgraph "Before Production"
Sarah_Before["Sarah: Research Lead<br/>5 PPRs - 4.9/5 rating"]
Alex_Before["Alex: Production Manager<br/>8 PPRs - 4.8/5 rating"]
Network_Before["Production Network: 3 sites<br/>Avg 4.7/5 rating"]
end
subgraph "Production Collaboration Process"
Phase1[Design & Planning]
Phase2[Multi-Site Fabrication]
Phase3[Quality Assurance]
Phase4[Research Validation]
Phase1 --> Phase2
Phase2 --> Phase3
Phase3 --> Phase4
end
subgraph "After Production"
Sarah_After["Sarah: Research Innovation Leader<br/>8 PPRs - 5.0/5 rating<br/>plus 1 ResourceCreation<br/>plus 1 ResourceValidation"]
Alex_After["Alex: Advanced Manufacturing Expert<br/>12 PPRs - 4.9/5 rating<br/>plus 2 CustodyTransfer<br/>plus 1 ValidationActivity"]
Network_After["Production Network: Enhanced<br/>Avg 4.9/5 rating<br/>plus 1 RuleCompliance"]
end
Sarah_Before --> Phase1
Alex_Before --> Phase1
Network_Before --> Phase1
Phase4 --> Sarah_After
Phase4 --> Alex_After
Phase4 --> Network_After
🏗️ Integrated Production Architecture: Nondominium + TrueCommon
Complete Production Network Management System
graph TB
subgraph "Current Nondominium (Resource Sharing Layer)"
ND_Person[Person Zome - Agent Profiles]
ND_Resource[Resource Zome - Equipment Registry]
ND_Governance[Governance Zome - Basic Rules]
ND_PPR[PPR Reputation System]
end
subgraph "Required TrueCommon (Production Management Layer)"
TC_REA[Full REA Economics]
TC_NRP[Network Resource Planning]
TC_Workflow[Production Workflows]
TC_Accounting[Integrated Accounting]
TC_SupplyChain[Supply Chain Management]
TC_Quality[Quality Management]
TC_Planning[Demand-Supply Planning]
end
subgraph "Enhanced Production Platform"
Design[Design Management]
Scheduling[Production Scheduling]
Quality[Quality Assurance]
Inventory[Resource Inventory]
Costing[Cost Accounting]
Planning[Capacity Planning]
Impact[Impact Assessment]
end
%% Nondominium provides foundation
Design --> ND_Person
Scheduling -.-> |Basic access control| ND_Resource
Quality -.-> |Reputation data| ND_PPR
%% TrueCommon provides production management
Costing --> TC_Accounting
Planning --> TC_NRP
Inventory --> TC_SupplyChain
Quality --> TC_Quality
Scheduling --> TC_Workflow
Design --> TC_REA
Impact --> TC_NRP
%% Integration points
TC_NRP -.-> |Resource data| ND_Resource
TC_Accounting -.-> |Transaction base| ND_PPR
TC_REA -.-> |Agent identities| ND_Person
Production Network Capability Gap Analysis
| Capability | Nondominium | TrueCommon Required | Impact on Production Networks |
|---|---|---|---|
| Resource Discovery | ✅ Excellent | - | Foundation layer works well |
| Access Governance | ✅ Strong | - | Basic access control sufficient |
| Reputation Tracking | ✅ PPR System | - | Individual reputation works |
| Multi-site Planning | ❌ Not Available | ✅ NRP Module | Critical Gap - Production coordination |
| Production Workflows | ❌ Not Available | ✅ Workflow Module | Critical Gap - Process management |
| Cost Accounting | ❌ Transaction only | ✅ Accounting Module | Critical Gap - Financial tracking |
| Supply Chain | ❌ Not Available | ✅ Supply Chain Module | Critical Gap - Material flow |
| Quality Management | ❌ Not Available | ✅ Quality Module | Critical Gap - Cross-site QA |
| Impact Measurement | ❌ Not Available | ✅ Impact Module | Critical Gap - Sustainability |
Why Nondominium Alone Cannot Support Production Networks
Limitation 1: Bilateral Transaction Focus
- Nondominium is designed for 1-to-1 resource sharing
- Production networks require N-to-M coordination (multiple facilities, multiple workflows)
- No support for complex multi-party production relationships
Limitation 2: No Production Planning
- Resource sharing ≠ production planning
- No capability for capacity planning, bottleneck analysis, or production optimization
- Missing workflow sequencing and dependency management
Limitation 3: Limited Economic Model
- Economic events track resource movements, not value creation
- No support for work-in-progress, value-added processes, or production costs
- Missing comprehensive accounting for production networks
TrueCommon's Network Resource Planning (NRP) bridges these gaps by providing complete REA integration with production-specific capabilities.
Advanced Production Features
Smart Manufacturing Capabilities:
- Predictive Maintenance: IoT sensors predict equipment maintenance needs
- Automated Quality Control: Computer vision and sensor-based quality verification
- Dynamic Resource Allocation: Real-time equipment scheduling across network
- Supply Chain Integration: Automated material procurement and inventory management
Collaborative Tools:
- Design Sharing: Secure multi-site design collaboration with version control
- Knowledge Transfer: Expertise sharing between production facilities
- Best Practice Library: Growing database of production techniques and innovations
- Performance Benchmarking: Cross-facility comparison and improvement identification
💡 Production Innovation Benefits
Distributed Manufacturing Advantages
- Resource Optimization: Shared access to expensive specialized equipment
- Risk Mitigation: Production redundancy across multiple sites
- Local Expertise: Leveraging regional manufacturing capabilities
- Scalability: Flexible production capacity based on demand
Quality & Compliance Enhancement
mindmap
root((Distributed Production))
Quality Assurance
Multi-Site Validation
Independent verification
Cross-site quality checks
Redundant testing procedures
Continuous Improvement
Real-time feedback loops
Process optimization
Knowledge sharing
Operational Efficiency
Resource Sharing
Specialized equipment access
Expertise pooling
Cost distribution
Flexible Manufacturing
Distributed capacity
Parallel production streams
Rapid reconfiguration
Innovation Enablement
Collaborative Design
Multi-disciplinary input
Rapid prototyping
Iterative improvement
Technology Transfer
Skill development
Best practice sharing
Advanced technique adoption
Economic & Environmental Impact
- Cost Reduction: 40% lower capital investment through equipment sharing
- Reduced Waste: Optimized material usage and precision manufacturing
- Local Production: Reduced transportation costs and carbon footprint
- Job Creation: Distributed employment opportunities in local communities
🎯 Strategic Production Outcomes
Immediate Project Benefits
- ✅ Research Acceleration: Custom sensors delivered 2 weeks ahead of schedule
- ✅ Cost Savings: $5,400 under budget through collaborative production
- ✅ Quality Excellence: 100% research acceptance with enhanced accuracy
- ✅ Network Growth: All three makerspaces secured additional production contracts
Long-Term Manufacturing Evolution
- Production Network: Established ongoing collaborative manufacturing relationships
- Technology Enhancement: Upgraded equipment capabilities through shared investment
- Skill Development: Cross-trained workforce with multi-facility expertise
- Market Expansion: Access to larger projects requiring diverse capabilities
Platform Development
- Production Templates: Standardized workflows for common equipment types
- Expert Marketplace: Growing database of specialized manufacturing capabilities
- Quality Standards: Developing industry-wide benchmarks for distributed production
- Innovation Pipeline: Continuous improvement through collaborative R&D
🔮 Future Production Scenarios
Advanced Manufacturing Integration
- AI-Optimized Production: Machine learning for process optimization and quality prediction
- Digital Twins: Virtual production planning and simulation before physical manufacturing
- Blockchain Supply Chain: Complete material traceability from source to final product
- Autonomous Quality Control: Self-correcting production processes with minimal human intervention
Industry Expansion Models
- Medical Device Manufacturing: Distributed production of customized medical equipment
- Aerospace Components: Specialized parts production across certified facilities
- Renewable Energy: Collaborative manufacturing of solar and wind energy components
- Consumer Electronics: Localized production with global quality standards
This user story demonstrates how Nondominium enables distributed manufacturing networks to collaborate on complex production projects, combining the capabilities of multiple facilities while maintaining quality standards and protecting intellectual property through decentralized governance and reputation systems.
Production completed successfully with 50 environmental sensors delivered to research institution. The production network has since secured 3 additional collaborative projects and expanded to include 2 more makerspaces with complementary capabilities.
User Story: Open Science - Resource Usage Process
Scenario: University Research Team Using Shared Laboratory Equipment
Context: A university research team needs specialized laboratory equipment for a critical experiment, accessing it through their institutional platform integrated with Nondominium. This scenario demonstrates Nondominium's capabilities for specialized equipment access, with post MVP capabilities providing enhanced research network coordination and impact measurement.
How to read this story (grounding note). The shared instrument (CEM-3000) is an NDO: a permanent Layer 0
NondominiumIdentity, a Layer 1ResourceSpecificationcarrying accessGovernanceRules (certification, protocol approval, monitoring), and a Layer 2EconomicResourceinstance whoseOperationalStatecyclesAvailable → Reserved → InUseduring the experiment (lifecycle maturity stays on Layer 0). Access is a Use process: the researcher submitspropose_commitment(AccessForUse), the custodian evaluates trust viaderive_reputation_summary, and completion issues bilateral PPRs from the 16-category set — hereCustodyAcceptance/CustodyTransferfor the access grant,ValidationActivityandRuleCompliancefor protocol adherence, and (for the custodian's service) the maintenance/service categories. Narrative labels likeUseService,ServiceValidation, andCommitmentFulfillmentare shorthand for these realParticipationClaimTypevalues. Real-time monitoring, LIMS, and publication tooling are host-platform concerns; steps againstNDare the ValueFlows/governance zome calls. Multi-institution coordination and impact accounting are post-MVP (hREA/NRP).
🏗️ System Architecture Context
Research Equipment Access (Nondominium Core Strength)
graph TB
subgraph "Nondominium - Specialized Equipment Sharing"
Person[Person Zome - Researcher Profiles]
Resource[Resource Zome - Lab Equipment Registry]
Governance[Governance Zome - Access Protocols]
PPR[PPR Reputation System]
end
subgraph "Research Access Capabilities"
Certification[Research Certification Management]
Access[Secure Equipment Access]
Protocol[Experimental Protocol Validation]
Reputation[Research Responsibility Tracking]
end
Person --> Certification
Resource --> Access
Governance --> Protocol
PPR --> Reputation
Nondominium Excellently Handles:
- Researcher certification and qualification verification
- Specialized equipment access with safety protocols
- Research reputation and responsible usage tracking
- Secure audit trails for research compliance
Post MVP Research Network Enhancement
graph TB
subgraph "Research Network Coordination"
NRP[Research Network Planning]
Impact[Research Impact Measurement]
Accounting[Research Cost Accounting]
Planning[Resource Capacity Planning]
end
subgraph "Enhanced Research Management"
Collaboration[Cross-Institution Collaboration]
Scheduling[Research Project Scheduling]
ImpactTracking[Research Impact Analytics]
ResourceOptimization[Equipment Network Optimization]
end
Post MVP enhancement:
- Multi-institution research coordination
- Research impact measurement beyond equipment usage
- Collaborative project planning and resource allocation
- Research network efficiency optimization
🎯 The Players
Dr. Elena Rodriguez - University Research Director
- Role: Accountable Agent with Research specialization
- Goal: Access high-end laboratory equipment for climate research project
- Reputation: Strong background in scientific collaboration and responsible equipment use
Professor Chen Wei - Laboratory Manager
- Role: Primary Accountable Agent (Custodian)
- Goal: Monetize laboratory equipment while ensuring proper scientific usage
- Reputation: Excellent track record in equipment maintenance and research support
The Resource
- Equipment: Cryogenic Electron Microscope (CEM-3000)
- Current Location: Advanced Materials Research Lab, MIT
- Governance Rules: Requires research certification, experimental protocol approval, real-time monitoring
🔄 Resource Usage Journey
Phase 1: Research Planning & Equipment Discovery (Week 1)
sequenceDiagram
participant Elena as Dr Elena Rodriguez
participant Platform as University Platform
participant ND as Nondominium
participant Res as Resource Zome
participant Gov as Governance Zome
Elena->>Platform: Search for electron microscopes
Platform->>ND: get_all_ndos() / get_ndos_by_nature(Physical)
ND->>Res: Query CEM-3000 availability
Res-->>ND: Return microscope specs and calendar
ND-->>Platform: Display equipment with governance rules
Platform-->>Elena: Show available slots and requirements
Elena->>Platform: Review research certification requirements
Platform->>ND: get_resource_specification_with_rules()
ND->>Gov: Return research protocol requirements
Elena->>Platform: Submit research proposal and credentials
Platform->>ND: propose_commitment(AccessForUse)
ND->>Gov: Create research usage commitment
Research Planning Process:
- Equipment Discovery: Elena searches institutional platform for cryogenic electron microscopes
- Requirement Analysis: Reviews governance rules including:
- PhD-level research certification ✅
- Experimental protocol approval required
- Real-time usage monitoring and logging
- Minimum 2-week advance booking
- Research Proposal Submission: Elena submits detailed experimental protocol through institutional review
Phase 2: Research Validation & Protocol Approval (Week 2)
sequenceDiagram
participant Chen as Prof Chen Wei
participant Elena as Dr Elena Rodriguez
participant ND as Nondominium
participant PPR as PPR System
participant Gov as Governance Zome
ND->>Chen: Notify of new research request
Chen->>ND: Access Elena's research credentials
ND->>PPR: derive_reputation_summary(Elena)
PPR-->>ND: Return research collaboration history
ND-->>Chen: Display Elena's research reputation
Chen->>ND: validate_specialized_role(Research) / check_validation_status()
ND->>Gov: Review experimental methodology, create ValidationReceipt
Gov-->>ND: Protocol validation result
Chen->>ND: create_agreement(BenefitClause) + monitoring GovernanceRule
ND->>Gov: Record usage agreement with monitoring conditions
Research Validation Process:
- Credentials Verification: Chen validates Elena's research background and institutional affiliation
- Protocol Review: Experimental methodology reviewed for equipment compatibility and safety
- Reputation Assessment: Elena's research collaboration history analyzed:
- 15 successful research collaborations
- 4.9/5 equipment care rating
- 0 protocol violations in 5 years
- Usage Agreement: Custom agreement created with real-time monitoring requirements
Phase 3: Usage Preparation & Training (Week 3)
stateDiagram-v2
[*] --> Available: CEM-3000 Ready
Available --> Reserved: Research protocol approved
Reserved --> PreparedForUse: Elena completes training
PreparedForUse --> UsageReady: System calibration complete
note right of Reserved
OperationalState: Available → Reserved
(LifecycleStage stays Active on Layer 0)
Research protocol linked
Monitoring systems activated
end note
note right of PreparedForUse
Elena completes safety training
Calibration procedures verified
Real-time logging configured
end note
Usage Preparation:
- Equipment Reservation: CEM-3000 status changed from Available to Reserved
- Research Training: Elena completes specialized equipment safety and usage training
- System Configuration: Real-time monitoring and data logging systems configured for research requirements
- Calibration Verification: Equipment calibrated to meet experimental specifications
Phase 4: Research Usage & Real-Time Monitoring (Week 4-5)
sequenceDiagram
participant Elena as Dr Elena Rodriguez
participant System as Monitoring System
participant ND as Nondominium
participant Res as Resource Zome
participant PPR as PPR System
Elena->>ND: update_operational_state(InUse)
ND->>Gov: Evaluate access commitment (AccessForUse)
Elena->>System: Start experimental procedure
loop Research Duration (2 weeks)
Elena->>System: Log experimental data (platform-side telemetry)
System->>Chen: send_usage_reports() (host-platform)
end
Elena->>ND: claim_commitment() + update_operational_state(Available)
ND->>Gov: Record Use economic event against the resource
Gov->>PPR: issue_participation_receipts() with PerformanceMetrics
Research Usage Process:
- Experiment Initiation: Elena begins cryogenic microscopy experiments with real-time monitoring
- Continuous Tracking: System logs usage hours, experimental parameters, and equipment performance
- Performance Monitoring: Real-time alerts for any deviations from approved protocols
- Data Integration: Research data automatically linked to usage logs for compliance verification
Phase 5: Research Completion & Data Verification (Week 5)
graph TB
subgraph "Research Completion Workflow"
A[Experiment Complete] --> B[Data Validation]
B --> C[Equipment Condition Check]
C --> D[Usage Report Generation]
D --> E[PPR Issuance]
E --> F[Research Publication Support]
end
subgraph "PPR Categories Generated (16-category set)"
G[CustodyAcceptance - Researcher took responsibility]
H[RuleCompliance - Protocol adherence]
I[CustodyTransfer - Custodian granted access]
J[ValidationActivity - Equipment care & validation]
end
E --> G
E --> H
E --> I
E --> J
subgraph "Quality Metrics"
K["Equipment Care: 5.0 out of 5"]
L["Protocol Adherence: 4.9 out of 5"]
M["Data Quality: 4.8 out of 5"]
N["Overall Satisfaction: 4.9 out of 5"]
end
E --> K
E --> L
E --> M
E --> N
Research Completion Process:
- Experimental Validation: Research data verified against expected outcomes and equipment usage parameters
- Equipment Assessment: CEM-3000 inspected for wear and calibration maintenance
- Usage Documentation: Comprehensive usage report generated with experimental parameters and performance metrics
- Research Support: System generates usage documentation for research publication and reproducibility
📊 Usage Analytics & Performance Metrics
Real-Time Monitoring Dashboard
graph LR
subgraph "Live Monitoring"
A[Equipment Status] --> B[Usage Hours]
B --> C[Performance Metrics]
C --> D[Alert System]
end
subgraph "Research Metrics"
E[Experimental Progress] --> F[Data Quality]
F --> G[Protocol Compliance]
G --> H[Research Milestones]
end
subgraph "Equipment Health"
I[Temperature Monitoring] --> J[Vibration Analysis]
J --> K[Calibration Status]
K --> L[Maintenance Alerts]
end
D --> E
H --> I
Usage Analytics Delivered:
- Equipment Utilization: 87% efficiency rate during research period
- Research Productivity: 3 experimental phases completed ahead of schedule
- Equipment Health: No performance degradation, routine maintenance only
- Research Quality: High-quality data suitable for peer-reviewed publication
Performance Impact Analysis
graph LR
subgraph "Before Research Usage"
Elena_Before["Elena: Research Reputation<br/>4.7 out of 5 - 8 PPRs"]
Chen_Before["Chen: Equipment Management<br/>4.8 out of 5 - 12 PPRs"]
end
subgraph "Research Collaboration Process"
Phase1[Planning & Discovery]
Phase2[Validation & Approval]
Phase3[Usage & Monitoring]
Phase4[Completion & Documentation]
Phase1 --> Phase2
Phase2 --> Phase3
Phase3 --> Phase4
end
subgraph "After Research Usage"
Elena_After["Elena: Research Specialist<br/>4.9 out of 5 - 12 PPRs<br/>plus 1 CustodyAcceptance<br/>plus 1 RuleCompliance"]
Chen_After["Chen: Research Support Leader<br/>4.9 out of 5 - 15 PPRs<br/>plus 1 CustodyTransfer<br/>plus 1 ValidationActivity"]
end
Elena_Before --> Phase1
Chen_Before --> Phase1
Phase4 --> Elena_After
Phase4 --> Chen_After
🏗️ Platform Integration Architecture
Research Platform Integration
graph TB
subgraph "University Research Platform"
LMS[Learning Management System]
Research[Research Portal]
Scheduling[Equipment Scheduling]
Compliance[Compliance Dashboard]
end
subgraph "Nondominium Research Integration"
Person[Person Zome - Research Profiles]
Resource[Resource Zome - Lab Equipment]
Governance[Governance Zome - Research Protocols]
end
subgraph "Research Support Systems"
LIMS[Laboratory Information System]
Publishing[Publication Support]
Grants[Grant Management]
Ethics[Ethics Review System]
end
LMS --> Person
Research --> Resource
Scheduling --> Governance
Compliance --> Governance
Person -.-> |Research Credentials| LIMS
Resource -.-> |Equipment Status| LIMS
Governance -.-> |Protocol Compliance| Ethics
Publishing -.-> |Usage Data| Research
Research-Specific Features
Platform Capabilities:
- Research Protocol Management: Integration with institutional review boards
- Grant Funding Integration: Automatic usage tracking for research grants
- Publication Support: Usage documentation for research reproducibility
- Compliance Reporting: Automated generation of regulatory compliance reports
Advanced Monitoring:
- Equipment Performance: Real-time sensor data and predictive maintenance
- Research Progress: Integration with project management systems
- Quality Assurance: Automated data quality validation and alerts
- Collaboration Tools: Multi-institutional research coordination
💡 Research Innovation Benefits
Scientific Advancement
- Equipment Access: Democratized access to expensive research equipment
- Collaborative Research: Cross-institutional collaboration without equipment duplication
- Research Reproducibility: Detailed usage logs and parameter tracking
- Grant Efficiency: Optimized equipment utilization for research funding
Academic Partnership Models
mindmap
root((Research Resource Sharing))
Institutional Benefits
Cost Optimization
Shared equipment costs
Reduced maintenance overhead
Efficient space utilization
Research Enhancement
Access to specialized equipment
Interdisciplinary collaboration
Advanced research capabilities
Academic Collaboration
Cross-Institutional Projects
Joint research initiatives
Shared facility management
Collaborative grant applications
Student Development
Advanced training opportunities
Research skill development
Network building
Technical Innovation
Smart Laboratory Integration
IoT sensor networks
Real-time monitoring systems
Predictive maintenance
Automated compliance reporting
Research Support Systems
Publication assistance
Data management tools
Protocol optimization
Sustainability Impact
- Equipment Longevity: Optimized usage schedules extending equipment lifespan
- Energy Efficiency: Reduced idle time and improved scheduling algorithms
- Waste Reduction: Shared usage reduces redundant equipment purchases
- Knowledge Sharing: Collaborative research reduces duplicated experimental efforts
🎯 Strategic Outcomes
Immediate Research Benefits
- ✅ Research Acceleration: 6-month research project completed in 5 weeks
- ✅ Cost Savings: University saved $250,000 in equipment purchase costs
- ✅ Publication Quality: High-quality data leading to Nature publication
- ✅ Reputation Building: Both researchers gained specialized equipment PPRs
Long-Term Academic Impact
- Research Network: Established ongoing equipment sharing agreement between institutions
- Grant Success: Improved grant applications through documented equipment access
- Student Training: Enhanced research training opportunities for graduate students
- Innovation Ecosystem: Contributed to regional research infrastructure optimization
Platform Evolution
- Research Module: University platform now includes specialized research equipment sharing
- Protocol Library: Growing database of validated research protocols and procedures
- Collaboration Network: Expanding network of research institutions sharing equipment
- Funding Model: New revenue streams through research equipment monetization
This user story demonstrates how Nondominium enables research institutions to transform expensive laboratory equipment from isolated assets into shared research infrastructure, combining the power of Web2 platforms with the trust and accountability of decentralized governance while accelerating scientific discovery and optimizing research funding.
Research collaboration completed successfully with breakthrough results published in high-impact journal. Both institutions have expanded their equipment sharing network to include 5 additional research facilities.
pai/ — AI Agent Integration
This directory is the single source of truth for all AI agent configuration in the
nondominium project. It feeds Claude Code, Cursor, and any AGENTS.md-compatible agent
through one authoring location and a Nix-driven materialization pipeline.
Quick Mental Model
pai/ ← you edit here
↓ nix develop
.claude/ ← Claude Code reads this
.cursor/ ← Cursor reads this
.agents/ ← other agents read this
The .rules file at the project root is the canonical agent instruction file. CLAUDE.md,
AGENTS.md, and GEMINI.md are all symlinks pointing at it. When you run nix develop,
the shellHook materializes everything else from pai/.
Architecture Overview
graph TD
subgraph "Source of Truth (pai/)"
RULES[".rules<br/>(canonical agent rules)"]
CONV["pai/conventions.md"]
CR10["pai/cursor-rules/10-domain-enums.md"]
CR20["pai/cursor-rules/20-architecture.md"]
CR30["pai/cursor-rules/30-rust-zomes.md"]
CR40["pai/cursor-rules/40-svelte-ui.md"]
CR50["pai/cursor-rules/50-tests.md"]
HOOK["pai/claude/hooks/LoadProjectDocs.hook.ts"]
CSET["pai/claude/settings.json"]
CSKILL["pai/claude/skills/nondominium-domain/SKILL.md"]
end
subgraph "Project Root Symlinks"
CLAUDE_MD["CLAUDE.md → .rules"]
AGENTS_MD["AGENTS.md → .rules"]
GEMINI_MD["GEMINI.md → .rules"]
end
subgraph "Nix Materialized (nix develop)"
CLAUDE_DIR[".claude/<br/>settings.json<br/>hooks/<br/>skills/"]
CURSOR_DIR[".cursor/rules/<br/>*.mdc files<br/><br/>.cursor/skills/<br/>holochain/<br/>nondominium-domain/"]
AGENTS_DIR[".agents/skills/<br/>holochain/<br/>nondominium-domain/"]
end
subgraph "External Inputs"
HC_SKILL["holochain-agent-skill<br/>(flake input)"]
end
RULES --> CLAUDE_MD
RULES --> AGENTS_MD
RULES --> GEMINI_MD
CONV --> CURSOR_DIR
CR10 --> CURSOR_DIR
CR20 --> CURSOR_DIR
CR30 --> CURSOR_DIR
CR40 --> CURSOR_DIR
CR50 --> CURSOR_DIR
HOOK --> CLAUDE_DIR
CSET --> CLAUDE_DIR
CSKILL --> CLAUDE_DIR
CSKILL --> CURSOR_DIR
CSKILL --> AGENTS_DIR
HC_SKILL --> CLAUDE_DIR
HC_SKILL --> CURSOR_DIR
HC_SKILL --> AGENTS_DIR
The .rules File and Its Symlinks
.rules is a single Markdown file that every AI agent reads. It covers:
@mentionreferences to the 6 canonical documentation files- Development environment setup (nix, bun, build commands)
- Architecture overview (3-zome structure, technology stack)
- Key development patterns (entry creation, privacy model, function naming)
- Test architecture summary
Three root-level files are symlinks to it so each tool finds its expected filename:
| File | Used by |
|---|---|
CLAUDE.md | Claude Code (CLI reads this filename by convention) |
AGENTS.md | OpenAI Codex, Windsurf, and any AGENTS.md-spec agent |
GEMINI.md | Gemini Code Assist |
Editing .rules updates all three simultaneously. Never edit the symlinks directly.
@ References in .rules
Claude Code natively resolves @path mentions and auto-loads the referenced files into
context. The 6 mentions in .rules are:
@documentation/TELOS.md
@documentation/requirements/requirements.md
@documentation/requirements/agent.md
@documentation/requirements/resources.md
@documentation/requirements/governance.md
@documentation/specifications/specifications.md
Other agents that do not support @ syntax receive only the text of .rules itself.
The session hook (below) compensates for this in Claude Code, and Cursor rules cover
it through embedded content in .mdc files.
Nix Materialization Pipeline
Running nix develop triggers the shellHook in flake.nix, which materializes three
IDE-specific directories from the pai/ source:
flowchart LR
subgraph "nix develop shellHook"
A["rsync pai/claude/ → .claude/"]
B["cursor-pai.nix\n→ .cursor/rules/*.mdc"]
C["agent-skills.nix\n→ .claude/skills/\n .cursor/skills/\n .agents/skills/"]
end
subgraph "Sources"
S1["pai/claude/"]
S2["pai/cursor-rules/*.md\npai/conventions.md\ndocumentation/TELOS.md"]
S3["holochain-agent-skill (flake input)"]
S4["pai/claude/skills/nondominium-domain/"]
end
S1 --> A
S2 --> B
S3 --> C
S4 --> C
A --> D[".claude/\n settings.json\n hooks/LoadProjectDocs.hook.ts\n skills/holochain/\n skills/nondominium-domain/"]
B --> E[".cursor/rules/\n 00-telos.mdc\n 10-conventions.mdc\n 20-architecture.mdc\n 25-domain-enums.mdc\n 30-rust-zomes.mdc\n 40-svelte-ui.mdc\n 50-tests.mdc"]
C --> F[".cursor/skills/holochain/\n.agents/skills/holochain/\n.claude/skills/nondominium-domain/\n.cursor/skills/nondominium-domain/\n.agents/skills/nondominium-domain/"]
The .claude/, .cursor/, and .agents/ directories are generated artifacts. Do not
edit them directly. Changes belong in pai/ and take effect on the next nix develop.
How Each Agent Gets Context
The pipeline gives different agents context through different mechanisms:
sequenceDiagram
participant Dev as Developer
participant Nix as nix develop
participant CC as Claude Code
participant Cur as Cursor
participant Other as Other Agents
Dev->>Nix: nix develop
Nix->>CC: materializes .claude/ (settings, hook, skills)
Nix->>Cur: materializes .cursor/rules/*.mdc + .cursor/skills/
Nix->>Other: materializes .agents/skills/
Note over CC: Session Start
CC->>CC: reads CLAUDE.md → .rules
CC->>CC: auto-resolves @mention paths in .rules
CC->>CC: runs LoadProjectDocs.hook.ts (SessionStart hook)
CC->>CC: injects 6 docs as <system-reminder>
CC->>CC: loads nondominium-domain SKILL.md
Note over Cur: File Open
Cur->>Cur: reads .cursor/rules/*.mdc (alwaysApply:true rules)
Cur->>Cur: reads glob-matched rules (*.rs, *.svelte, tests/)
Cur->>Cur: loads .cursor/skills/ on demand
Note over Other: Session Start
Other->>Other: reads AGENTS.md → .rules
Other->>Other: reads .agents/skills/ on demand
Claude Code Context Chain
CLAUDE.md→.rules: base instructions +@auto-loads 6 docsLoadProjectDocs.hook.ts(SessionStart): reads the same 6 docs independently and injects them as<system-reminder>content — ensures docs are present even if@resolution fails or context is freshnondominium-domainSKILL.md: provides task-based routing table to all documentation
Cursor Context Chain
Cursor rules are generated from pai/ by nix/cursor-pai.nix. Each .mdc file embeds
source content directly (not @ references):
| File | Source | alwaysApply | Glob |
|---|---|---|---|
00-telos.mdc | documentation/TELOS.md | true | all files |
01-requirements.mdc | documentation/requirements/requirements.md | true | all files |
02-agent.mdc | documentation/requirements/agent.md | true | all files |
03-resources.mdc | documentation/requirements/resources.md | true | all files |
04-governance.mdc | documentation/requirements/governance.md | true | all files |
05-specifications.mdc | documentation/specifications/specifications.md | true | all files |
10-conventions.mdc | pai/conventions.md | true | all files |
20-architecture.mdc | pai/cursor-rules/20-architecture.md | true | all files |
25-domain-enums.mdc | pai/cursor-rules/10-domain-enums.md | true | all files |
30-rust-zomes.mdc | pai/cursor-rules/30-rust-zomes.md | false | **/*.rs |
40-svelte-ui.mdc | pai/cursor-rules/40-svelte-ui.md | false | **/*.svelte |
50-tests.mdc | pai/cursor-rules/50-tests.md | false | dnas/**/tests/**/*.rs |
The LoadProjectDocs.hook.ts Hook
Located at pai/claude/hooks/LoadProjectDocs.hook.ts (materialized to .claude/hooks/).
Triggered by the SessionStart event in .claude/settings.json:
{
"hooks": {
"SessionStart": [{ "hooks": [{ "type": "command", "command": "bun .claude/hooks/LoadProjectDocs.hook.ts" }] }]
}
}
The hook reads six documentation files from PROJECT_DIR (two levels up from the hook
file) and writes them to stdout as a <system-reminder> block:
flowchart TD
A["SessionStart event fires"] --> B["LoadProjectDocs.hook.ts runs via bun"]
B --> C{"For each of 6 doc paths"}
C --> D["Read file content"]
D --> E["Append as ### path + content"]
C -->|"all docs processed"| F["Print to stdout:<br/><system-reminder><br/># nondominium Project Documentation<br/>...all 6 docs...<br/></system-reminder>"]
F --> G["Claude Code injects output<br/>into context as system message"]
G --> H["Agent has full docs in context<br/>before first user message"]
The 6 injected files are:
documentation/TELOS.md— vision, mission, AI operating principlesdocumentation/requirements/requirements.md— REQ-* IDs, user roles, economic processesdocumentation/requirements/agent.md— agent ontology, roles, affiliation spectrumdocumentation/requirements/resources.md— resource ontology, property regimesdocumentation/requirements/governance.md— governance model, governance-as-operatordocumentation/specifications/specifications.md— entry types, zome functions, UI specs
Skills Architecture
Two skills are distributed to all agent systems:
graph LR
subgraph "holochain-agent-skill (external flake input)"
HC["SKILL.md<br/>Architecture.md<br/>Patterns.md<br/>AccessControl.md<br/>CellCloning.md<br/>Deployment.md<br/>ErrorHandling.md<br/>Testing.md<br/>TypeScript.md<br/>WindTunnel.md<br/>Scaffold.md<br/>Workflows/..."]
end
subgraph "nondominium-domain (pai/claude/skills/)"
ND["SKILL.md<br/>(routing-only;<br/>no content duplication)"]
end
subgraph "Distribution targets"
CC2[".claude/skills/"]
CU[".cursor/skills/"]
AG[".agents/skills/"]
end
HC --> CC2
HC --> CU
HC --> AG
ND --> CC2
ND --> CU
ND --> AG
holochain-agent-skill — general Holochain HDK knowledge (zome patterns, testing,
TypeScript client, access control). Sourced from an external Nix flake input. Use this
for generic Holochain questions not specific to nondominium.
nondominium-domain — routing-only skill. Its SKILL.md is a table that maps tasks
to the correct documentation section. It does not duplicate content; it redirects.
All actual domain knowledge lives in documentation/. The skill is the index, not the book.
The nondominium-domain skill activates automatically in Claude Code when working on:
- resource zome, governance zome, or person zome
- lifecycle transitions or NDO layer activation
- PPR issuance or reputation derivation
- capability slots or stigmergic attachment patterns
pai/ Editing Workflow
flowchart TD
A["What do you want to change?"] --> B{Decision}
B -->|"AI operating principles,<br/>vision, mission"| C["Edit documentation/TELOS.md"]
B -->|"Dev commands, patterns,<br/>architecture overview"| D["Edit .rules directly"]
B -->|"Conventions quick-ref<br/>(branch model, commit format)"| E["Edit pai/conventions.md"]
B -->|"Domain enums<br/>(PropertyRegime, LifecycleStage...)"| F["Edit pai/cursor-rules/10-domain-enums.md"]
B -->|"Architecture quick-ref<br/>(zome structure, NDO layers)"| G["Edit pai/cursor-rules/20-architecture.md"]
B -->|"Rust HDK patterns"| H["Edit pai/cursor-rules/30-rust-zomes.md"]
B -->|"Svelte UI patterns"| I["Edit pai/cursor-rules/40-svelte-ui.md"]
B -->|"Test patterns"| J["Edit pai/cursor-rules/50-tests.md"]
B -->|"Claude Code skill routing"| K["Edit pai/claude/skills/nondominium-domain/SKILL.md"]
B -->|"Claude Code settings/hook"| L["Edit pai/claude/settings.json<br/>or pai/claude/hooks/"]
C --> M["Run nix develop to regenerate .cursor/rules/00-telos.mdc"]
D --> N["CLAUDE.md, AGENTS.md, GEMINI.md all update immediately via symlink"]
E --> O["Run nix develop to regenerate .cursor/rules/10-conventions.mdc"]
F --> P["Run nix develop to regenerate .cursor/rules/25-domain-enums.mdc"]
G --> Q["Run nix develop to regenerate .cursor/rules/20-architecture.mdc"]
H --> R["Run nix develop to regenerate .cursor/rules/30-rust-zomes.mdc"]
I --> S["Run nix develop to regenerate .cursor/rules/40-svelte-ui.mdc"]
J --> T["Run nix develop to regenerate .cursor/rules/50-tests.mdc"]
K --> U["Run nix develop to regenerate .claude/skills/ and .cursor/skills/"]
L --> V["Run nix develop to regenerate .claude/"]
Rule: Always edit in pai/ (or .rules / documentation/), never in .claude/,
.cursor/, or .agents/. Those directories are generated by nix develop and will be
overwritten on the next shell entry.
File Map
pai/
├── README.md ← this file
├── conventions.md ← conventions quick-reference (all agents)
├── cursor-rules/
│ ├── 10-domain-enums.md ← canonical enum reference
│ ├── 20-architecture.md ← zome structure, NDO layers
│ ├── 30-rust-zomes.md ← HDK patterns, cross-zome calls
│ ├── 40-svelte-ui.md ← Svelte 5, Effect-TS, Melt UI
│ └── 50-tests.md ← Sweettest patterns
└── claude/
├── settings.json ← Claude Code project settings + hook wiring
├── hooks/
│ └── LoadProjectDocs.hook.ts ← SessionStart: injects 6 docs into context
└── skills/
└── nondominium-domain/
└── SKILL.md ← routing skill (task → documentation section)
.rules ← canonical agent rules (CLAUDE.md/AGENTS.md/GEMINI.md → here)
nix/
├── cursor-pai.nix ← builds .cursor/rules/*.mdc from pai/
└── agent-skills.nix ← rsyncs skills to .claude/, .cursor/, .agents/
flake.nix ← shellHook runs both nix helpers
Adding a New Documentation File to Agent Context
To inject a new documentation file into Claude Code sessions:
- Add the relative path to the
DOCSarray inpai/claude/hooks/LoadProjectDocs.hook.ts - Add an
@mention in.rulesat the appropriate section - If the file belongs in Cursor context, add a new rule entry in
nix/cursor-pai.nix - Run
nix developto regenerate materialized files
Adding a New Cursor Rule
- Create
pai/cursor-rules/NN-name.mdwith the rule content - Add a
rulesentry innix/cursor-pai.nixpointing at the new file - Set
alwaysApplyandglobsappropriately - Run
nix develop
Adding a New Agent Skill
- Create the skill directory under
pai/claude/skills/<name>/ - Add the skill to the
agentSkillsHookcall inflake.nix - Run
nix developto distribute it to.claude/skills/,.cursor/skills/,.agents/skills/
Nondominium: A Solution for Frictionless Mutualization
1. Introduction
Mutualization—the sharing of resources, expertise, and services among organizations—is a powerful strategy for increasing resilience, impact, and efficiency. However, as highlighted in the Petit Guide orange du partage des ressources et de la mutualisation (RCAAQ), the path to successful mutualization is fraught with hidden costs and structural risks.
Nondominium is designed specifically to address these challenges by providing a decentralized, agent-centric infrastructure that embeds trust, transparency, and governance directly into the resource-sharing process.
2. Costs and Risks of Mutualization
Based on the RCAAQ methodology and industry experience, mutualization involves several categories of friction:
2.1 Hidden Costs
- Concertation Overhead: Significant time and energy are often consumed in meetings, negotiations, and consensus-building. This "hidden tax" on collaboration can often offset the marginal economic gains of sharing.
- Legal & Administrative Complexity: Establishing partnerships often requires complex contracts, changes to bylaws, or the creation of new legal entities to manage shared assets.
- Sustained Communication: Maintaining alignment requires constant, intensive communication to ensure all partners remain on the "same wavelength."
2.2 Structural Risks
- Loss of Sovereignty: Organizations fear losing control over their own resources, decision-making processes, or institutional identity.
- Trust and Reliability (The "Free Rider" Problem): Collaborative efforts can fail if some participants contribute less than they consume, or if promised services (maintenance, transport) are not reliably fulfilled.
- Informational Asymmetry: Without a shared, real-time view of resource status and history, misunderstandings and conflicts are inevitable.
- Dependency Risks: Relying on a partner's specific expertise or equipment creates vulnerability if that partner withdraws or fails to deliver.
3. How Nondominium Reduces Mutualization Friction
Nondominium leverages Holochain and the ValueFlows standard to transform mutualization from a high-maintenance social contract into a low-friction, automated economic process.
3.1 Reducing Concertation with Machine-Readable Governance
Instead of relying solely on verbal agreements and manual oversight, Nondominium embeds governance rules directly into the Resource Specifications.
- Automated Rules: Rules for access, usage, and transfer are enforced programmatically. This reduces the need for constant "concertation" over routine interactions.
- Standardized Language: By using the ValueFlows ontology (Resources, Events, Commitments), Nondominium provides a common "economic grammar" that eliminates the ambiguity often found in collaborative projects.
3.2 Automated Accountability through PPRs
The Private Participation Receipt (PPR) system directly addresses the risks of trust and reliability.
- Proof of Participation: Every interaction (creating a resource, fulfilling a commitment, performing a repair) generates a cryptographically signed receipt.
- Privacy-Preserving Reputation: Agents build a reputation based on their actual performance (timeliness, quality, reliability) without needing to reveal sensitive private data. This replaces the need for complex, manual performance reviews with a data-driven trust layer.
3.3 Preserving Sovereignty in an Agent-Centric Framework
Nondominium is built on Holochain's agent-centric architecture, which is fundamentally different from centralized platforms.
- Organization-Agnostic Resources: Resources in Nondominium are not "owned" by a single organization or platform. They exist in a shared DHT (Distributed Hash Table) and are governed by peer-validated rules.
- Local Control: Each agent manages their own identity and private data. They "own" their participation history, which they can selectively share to prove their reliability to new partners.
3.4 Managing Complexity with Specialized Roles
Nondominium supports a sophisticated role-based system that allows for unequal but fair participation:
- Flexible Roles: Participants can act as Simple Agents, Accountable Agents, or Custodians. Specialized roles like Transport, Repair, and Storage allow organizations to contribute according to their specific strengths.
- Full Provenance: Every Economic Resource has a complete, immutable history of its lifecycle and the Economic Events that affected it. This transparency prevents disputes and simplifies the "who, what, when, and how" of resource management.
4. The P2P Dimension: Engineering vs. Emergence
Instead of the "manual engineering" of collaboration, Nondominium enables stigmergic coordination and emergence, which are more appropriate for complex, real-world situations.
4.1 From Planning to Stigmergy
- Traditional Engineering (RCAAQ): Relies on top-down planning and pre-negotiated rigid structures. This approach assumes a closed set of organizations that must harmonize their internal rules before any action can be taken.
- Stigmergic Coordination (Nondominium): Agents coordinate by leaving "traces" in the shared environment (ValueFlows events and commitments). When a resource is updated to "In Storage," it signals availability for "Transport" or "Use" to any qualified agent. This is edge sensing in action—decisions are made at the periphery where the needs are identified, rather than at a central committee.
4.2 Self-Organization in Complex Environments
- Emergent Allocation: Resource acquisition and allocation aren't engineered; they emerge from the aggregate actions of autonomous agents responding to real-time signals. This allows the network to adapt to complex situations where static plans quickly become obsolete.
- Open Value Networks (OVN): Nondominium follows OVN principles where anyone can contribute and be recognized through the PPR system. This removes the administrative bottlenecks of traditional "membership" models and allows for a truly open, self-organizing economy.
4.3 Economic Benefits of Emergence
- Zero-Concertation Scaling: As the network grows, the coordination cost does not increase exponentially (as it does with committees and planning), but remains low due to automated signaling.
- Agility and Resilience: The system can rapidly reorganize itself around local failures or opportunities without waiting for a central directive or a new round of "mutualization engineering."
5. Conclusion: Moving Beyond the Guide
The RCAAQ guide proposes a methodology to manage the risks of mutualization through better planning and communication. Nondominium goes a step further by encoding the solution into the infrastructure itself.
By automating trust, standardizing resource language, and enabling emergent coordination, Nondominium significantly lowers the barrier to collaboration. It offers a path away from heavy-handed planning towards a more agile, resilient, and economically efficient sharing economy.
Traduction française
Nondominium : Une solution pour une mutualisation sans friction
1. Introduction
La mutualisation — le partage de ressources, d'expertises et de services entre organisations — est une stratégie puissante pour accroître la résilience, l'impact et l'efficacité. Cependant, comme le souligne le Petit Guide orange du partage des ressources et de la mutualisation (RCAAQ), le chemin vers une mutualisation réussie est parsemé de coûts cachés et de risques structurels.
Nondominium est conçu spécifiquement pour relever ces défis en fournissant une infrastructure décentralisée et centrée sur l'agent qui intègre la confiance, la transparence et la gouvernance directement dans le processus de partage des ressources.
2. Coûts et risques de la mutualisation
Basée sur la méthodologie du RCAAQ et l'expérience du secteur, la mutualisation implique plusieurs catégories de friction :
2.1 Coûts cachés
- Surcharge de concertation : Un temps et une énergie considérables sont souvent consommés dans les réunions, les négociations et la recherche de consensus. Cette « taxe cachée » sur la collaboration peut souvent annuler les gains économiques marginaux du partage.
- Complexité juridique et administrative : L'établissement de partenariats nécessite souvent des contrats complexes, des modifications aux règlements généraux ou la création de nouvelles entités juridiques pour gérer les actifs partagés.
- Communication soutenue : Maintenir l'alignement exige une communication constante et intensive pour s'assurer que tous les partenaires restent sur la « même longueur d'onde ».
2.2 Risques structurels
- Perte de souveraineté : Les organisations craignent de perdre le contrôle de leurs propres ressources, de leurs processus de décision ou de leur identité institutionnelle.
- Confiance et fiabilité (Le problème du « passager clandestin ») : Les efforts collaboratifs peuvent échouer si certains participants contribuent moins qu'ils ne consomment, ou si les services promis (entretien, transport) ne sont pas fournis de manière fiable.
- Asymétrie informationnelle : Sans une vue partagée et en temps réel de l'état et de l'historique des ressources, les malentendus et les conflits sont inévitables.
- Risques de dépendance : Compter sur l'expertise ou l'équipement spécifique d'un partenaire crée une vulnérabilité si ce partenaire se retire ou ne livre pas ses prestations.
3. Comment Nondominium réduit les frictions de la mutualisation
Nondominium s'appuie sur Holochain et le standard ValueFlows pour transformer la mutualisation, d'un contrat social lourd en maintenance vers un processus économique automatisé et fluide.
3.1 Réduire la concertation grâce à une gouvernance lisible par machine
Au lieu de s'appuyer uniquement sur des accords verbaux et une surveillance manuelle, Nondominium intègre les règles de gouvernance directement dans les Spécifications de Ressources.
- Règles automatisées : Les règles d'accès, d'utilisation et de transfert sont appliquées par programme. Cela réduit le besoin de « concertation » constante pour les interactions de routine.
- Langage standardisé : En utilisant l'ontologie ValueFlows (Ressources, Événements, Engagements), Nondominium fournit une « grammaire économique » commune qui élimine l'ambiguïté souvent rencontrée dans les projets collaboratifs.
3.2 Responsabilité automatisée via les PPR
Le système de Reçus de Participation Privés (PPR) répond directement aux risques de confiance et de fiabilité.
- Preuve de participation : Chaque interaction (création d'une ressource, respect d'un engagement, réalisation d'une réparation) génère un reçu signé cryptographiquement.
- Réputation préservant la vie privée : Les agents se forgent une réputation basée sur leur performance réelle (ponctualité, qualité, fiabilité) sans avoir besoin de révéler des données privées sensibles. Cela remplace les évaluations de performance manuelles complexes par une couche de confiance basée sur les données.
3.3 Préserver la souveraineté dans un cadre centré sur l'agent
Nondominium est construit sur l'architecture centrée sur l'agent de Holochain, ce qui est fondamentalement différent des plateformes centralisées.
- Ressources agnostiques à l'organisation : Dans Nondominium, les ressources ne sont pas « possédées » par une seule organisation ou plateforme. Elles existent dans une DHT (Table de Hachage Distribuée) partagée et sont régies par des règles validées par les pairs.
- Contrôle local : Chaque agent gère sa propre identité et ses données privées. Il « possède » son historique de participation, qu'il peut partager sélectivement pour prouver sa fiabilité à de nouveaux partenaires.
3.4 Gérer la complexité avec des rôles spécialisés
Nondominium prend en charge un système sophistiqué basé sur les rôles qui permet une participation inégale mais équitable :
- Rôles flexibles : Les participants peuvent agir en tant qu'Agents Simples, Agents Responsables ou Gardiens (Custodians). Des rôles spécialisés comme le Transport, la Réparation et le Stockage permettent aux organisations de contribuer selon leurs forces spécifiques.
- Traçabilité complète : Chaque Ressource Économique possède un historique complet et immuable de son cycle de vie et des Événements Économiques qui l'ont affectée. Cette transparence prévient les litiges et simplifie le « qui, quoi, quand et comment » de la gestion des ressources.
4. La dimension P2P : Ingénierie vs Émergence
Au lieu d'une « ingénierie manuelle » de la collaboration, Nondominium permet la coordination stigmergique et l'émergence, qui sont plus appropriées pour les situations réelles et complexes.
4.1 De la planification à la stigmergie
- Ingénierie traditionnelle (RCAAQ) : Repose sur une planification descendante et des structures rigides pré-négociées. Cette approche suppose un ensemble fermé d'organisations qui doivent harmoniser leurs règles internes avant toute action.
- Coordination stigmergique (Nondominium) : Les agents se coordonnent en laissant des « traces » dans l'environnement partagé (événements et engagements ValueFlows). Lorsqu'une ressource est mise à jour avec le statut « En Stockage », cela signale sa disponibilité pour un « Transport » ou une « Utilisation » à tout agent qualifié. C'est la détection aux bords (edge sensing) en action : les décisions sont prises à la périphérie, là où les besoins sont identifiés, plutôt qu'au sein d'un comité central.
4.2 Auto-organisation dans les environnements complexes
- Allocation émergente : L'acquisition et l'allocation des ressources ne sont pas « ingénierées » ; elles émergent des actions globales d'agents autonomes répondant à des signaux en temps réel. Cela permet au réseau de s'adapter à des situations complexes où les plans statiques deviennent rapidement obsolètes.
- Réseaux de Valeur Ouverts (OVN) : Nondominium suit les principes des OVN où n'importe qui peut contribuer et être reconnu par le système PPR. Cela élimine les goulots d'étranglement administratifs des modèles traditionnels d'« adhésion » et permet une économie véritablement ouverte et auto-organisée.
4.3 Avantages économiques de l'émergence
- Passage à l'échelle sans concertation : À mesure que le réseau grandit, le coût de coordination n'augmente pas de manière exponentielle (comme c'est le cas avec les comités et la planification), mais reste bas grâce à la signalisation automatisée.
- Agilité et résilience : Le système peut se réorganiser rapidement autour des défaillances locales ou des opportunités sans attendre une directive centrale ou un nouveau cycle d'« ingénierie de mutualisation ».
5. Conclusion : Aller au-delà du guide
Le guide du RCAAQ propose une méthodologie pour gérer les risques de la mutualisation par une meilleure planification et communication. Nondominium va plus loin en encodant la solution directement dans l'infrastructure.
En automatisant la confiance, en standardisant le langage des ressources et en permettant une coordination émergente, Nondominium abaisse considérablement la barrière à la collaboration. Il offre une voie alternative à la planification lourde vers une économie de partage plus agile, résiliente et économiquement efficace.
Digital Fabrics: A Conceptual Framework
Executive Summary
Digital Fabrics represent a new paradigm of decentralized, coordination-focused infrastructure that enables autonomous interactions without centralized control. Unlike platforms that mediate and control user interactions, Digital Fabrics provide the underlying substrate for self-organizing, stigmergic coordination between autonomous digital entities.
Core Definition
Digital Fabric:
A decentralized, interconnected infrastructure that enables autonomous digital entities to coordinate, interact, and self-organize through embedded coordination mechanisms, without requiring centralized mediation or platform control.
Fabric Metaphor in Digital Context
Physical Fabric Properties → Digital Analogues
| Physical Fabric Property | Digital Fabric Equivalent |
|---|---|
| Interwoven Threads | Interconnected autonomous agents/resources |
| Flexible & Resilient | Adaptive, fault-tolerant network topology |
| Pattern & Structure | Emergent coordination patterns and governance |
| Stretchable & Malleable | Scalable, recomposable system architecture |
| Tear-Resistant | Anti-fragile, capture-resistant design |
| Breathable & Permeable | Permissionless access and interoperability |
| Self-Repairing | Autonomous healing and adaptation mechanisms |
Distinguishing Characteristics
From Platforms to Fabrics
Platform Architecture
┌─────────────────────┐
│ Applications │ ← Built ON platform
├─────────────────────┤
│ Platform Layer │ ← Controls & mediates
│ - Rules │ - Access control
│ - APIs │ - Rate limiting
│ - Algorithms │ - Content moderation
│ - Monetization │ - Data extraction
├─────────────────────┤
│ Infrastructure │ ← Owned by platform
└─────────────────────┘
Digital Fabric Architecture
┌─────────────────────┐
│ Autonomous │ ← Self-governing entities
│ Digital Entities │
├─────────────────────┤
│ Coordination │ ← Embedded coordination
│ Fabric │ - Stigmergic signaling
│ - Rules │ - Resource-based triggers
│ - Patterns │ - Self-enforcing protocols
│ - Signals │ - Indirect communication
├─────────────────────┤
│ Peer-to-Peer │ ← Decentralized substrate
│ Infrastructure │
└─────────────────────┘
Core Principles of Digital Fabrics
1. Subsidiarity-Based Coordination
- Local autonomy: Decisions made at the most local level possible
- Emergent coordination: Global patterns emerge from local interactions
- Embedded governance: Rules embedded within resources themselves
2. Stigmergic Communication
- Indirect coordination: Entities modify environment, others respond
- Signal-based: Traces and patterns guide future interactions
- Asynchronous interaction: No need for direct messaging or synchronization
3. Anti-Fragile Architecture
- Improves with stress: System becomes stronger through use and disruption
- Capture-resistant: No single point of control or failure
- Self-healing: Automatic recovery from damage or partitioning
4. Resource-Centric Design
- First-class resources: Resources are primary actors, not data
- Embedded rules: Governance travels with resources
- Autonomous existence: Resources exist independently of any host
5. Permissionless Participation
- Open access: Anyone can participate under established rules
- Identity-agnostic: Coordination doesn't require identity verification
- Meritocratic contribution: Value determined by contribution quality
Types of Digital Fabrics
1. Coordination Fabrics
- Purpose: Enable stigmergic resource coordination
- Examples: Nondominium, supply chain coordination systems
- Key Features: Resource tracking, event flows, governance embedding
2. Identity Fabrics
- Purpose: Decentralized identity and reputation management
- Examples: Self-sovereign identity systems, reputation networks
- Key Features: Verifiable credentials, portable reputation
3. Compute Fabrics
- Purpose: Distributed computational coordination
- Examples: Decentralized AI agent systems, distributed computing
- Key Features: Autonomous computation, resource allocation
4. Data Fabrics
- Purpose: Decentralized data coordination and governance
- Examples: Data commons, shared scientific datasets
- Key Features: Data sovereignty, usage tracking, fair compensation
5. Social Fabrics
- Purpose: Human coordination and social organization
- Examples: Decentralized social networks, community governance
- Key Features: Community moderation, reputation systems, collective decision-making
Architectural Patterns
Weaving Patterns
- Plain Weave: Simple peer-to-peer coordination
- Twill Weave: Complex multi-layered coordination
- Satin Weave: High-performance optimized coordination
- Jacquard Weave: Complex programmable coordination patterns
Fiber Types
- Resource Fibers: Autonomous digital resources
- Agent Fibers: Human and AI participants
- Protocol Fibers: Coordination rules and standards
- Signal Fibers: Communication and coordination channels
Fabric Structures
- Monolithic: Single unified coordination system
- Composite: Multiple fabric types woven together
- Layered: Hierarchical coordination fabrics
- Hybrid: Mixed centralized/decentralized elements
Implementation Characteristics
Technical Properties
- Distributed Hash Tables (DHTs): Resource location and discovery
- Cryptographic Verification: Trust without central authorities
- Event Sourcing: Complete coordination history
- Gossip Protocols: Information propagation
- Crdt (Conflict-free Replicated Data Types): Convergent data structures
Economic Properties
- ValueFlows Integration: Economic activity tracking
- Contribution Accounting: Fair value distribution
- Tokenless Coordination: Coordination without financial tokens
- Resource Economics: Resource-based value systems
Governance Properties
- Embedded Rules: Governance in resource definitions
- Evolutionary Governance: Rules adapt through usage
- Multi-level Governance: Local, regional, global coordination layers
- Dispute Resolution: Automated and community-based resolution
Comparison with Existing Concepts
Digital Fabrics vs. Platforms
| Aspect | Platforms | Digital Fabrics |
|---|---|---|
| Control | Centralized | Decentralized |
| Access | Permission-based | Permissionless |
| Value Capture | Extractive | Distributive |
| Governance | Top-down | Bottom-up |
| Data Ownership | Platform-owned | User/Resource-owned |
| Interoperability | Walled gardens | Open protocols |
Digital Fabrics vs. Networks
| Aspect | Networks | Digital Fabrics |
|---|---|---|
| Purpose | Connectivity | Coordination |
| Intelligence | Layer 3/4 | Layer 7 (Application) |
| State Management | Stateless | Stateful coordination |
| Governance | Technical protocols | Social/economic rules |
| Value Creation | Connectivity utility | Coordination value |
Digital Fabrics vs. dApps
| Aspect | dApps | Digital Fabrics |
|---|---|---|
| Infrastructure | Blockchain-dependent | Infrastructure-agnostic |
| Coordination | Transaction-based | Stigmergic signaling |
| Governance | Token voting | Embedded rules |
| Scalability | Blockchain-limited | P2P scalable |
| Economic Model | Token speculation | Real value flows |
Use Cases and Applications
True Commons as Coordination Fabric
- Digital Resource Management: Autonomous lifecycle management
- Collaborative Production: Stigmergic coordination of creative work
- Supply Chain Coordination: Multi-party resource tracking
- Knowledge Commons: Scientific and educational resource sharing
Future Fabric Applications
- Autonomous Supply Chains: Self-organizing logistics networks
- Decentralized Science: Research coordination without institutions
- Community Energy: Local energy production and distribution
- Digital Manufacturing: Distributed production coordination
Development Roadmap
Phase 1: Foundation
- Core fabric protocols and standards
- Basic resource coordination mechanisms
- Initial governance frameworks
Phase 2: Weaving
- Multi-fabric integration
- Advanced coordination patterns
- Cross-fabric interoperability
Phase 3: Ecosystem
- Fabric development tools and frameworks
- Application layers and user interfaces
- Ecosystem governance and evolution
Conclusion
Digital Fabrics represent a fundamental shift from platform-mediated to fabric-enabled coordination. By embedding governance and coordination directly into digital resources and their interactions, fabrics enable autonomous, self-organizing systems that are more resilient, equitable, and adaptable than traditional platform architectures.
True Commons stands as a pioneering implementation of a Coordination Fabric, demonstrating how digital resources can exist, coordinate, and evolve independently of any centralized control structure. This paradigm shift from platforms to fabrics may be as significant as the shift from mainframes to networks, opening new possibilities for decentralized collaboration and value creation.
This framework provides a foundation for understanding and developing Digital Fabrics as a new category of decentralized infrastructure that enables post-platform coordination and collaboration.
Derived Work
Concepts from this document — subsidiarity-based coordination, anti-fragile architecture, resource-centric design, and the platform-to-fabric paradigm shift — have been integrated into the Complexity Driven Development methodology and AI skill:
- Methodology:
nondominium-design-system/.cursor/skills/complexity-oriented-programming/methodology.md - AI Skill:
nondominium-design-system/.cursor/skills/complexity-oriented-programming/SKILL.md
Holochain File Storage and Verification Patterns
Created: 2025-12-11 Status: ARCHIVAL - Research Complete Context: Digital Resource Integrity Implementation Research for nondominium
Research Overview
This document archives the research findings on implementing robust file storage and cryptographic verification within the Holochain DHT environment, specifically for the nondominium resource sharing application with fractal composable resource architecture.
Holochain Storage Architecture Research
1. Content-Addressed Storage Patterns
Holochain DHT Characteristics
- Content Addressing: Data stored and retrieved by cryptographic hash
- Distributed Storage: Data distributed across network nodes automatically
- Redundancy: Multiple copies maintained for availability
- Validation: All entries validated before network acceptance
- Gossip Protocol: Data propagation through peer-to-peer gossip
Implementation Strategy for File Storage
#![allow(unused)] fn main() { // File chunking strategy const CHUNK_SIZE: usize = 64 * 1024; // 64KB chunks // Chunk storage entry structure #[hdk_entry(id = "file_chunk")] struct FileChunk { chunk_hash: Vec<u8>, // SHA-256 hash of chunk data chunk_data: Vec<u8>, // Actual chunk data (max 64KB) chunk_index: u32, // Index within file file_hash: Vec<u8>, // Parent file hash for grouping created_at: u64, // Timestamp agent_pub_key: AgentPubKey, // Storage agent } }
Chunk Management Strategy
- Size Optimization: 64KB chunks balance DHT performance and retrieval efficiency
- Hash-based Addressing: Each chunk addressable by its SHA-256 content hash
- Metadata Separation: File metadata stored separately from chunk data
- Redundancy Handling: Automatic redundancy through Holochain DHT replication
2. Manifest System Architecture
File Manifest Structure
#![allow(unused)] fn main() { #[hdk_entry(id = "file_manifest")] struct FileManifest { file_hash: Vec<u8>, // Root hash of entire file file_name: String, // Original filename file_size: u64, // Total file size in bytes chunk_count: u32, // Number of chunks chunk_hashes: Vec<Vec<u8>>, // Hash of each chunk in order merkle_root: Vec<u8>, // Merkle tree root hash created_at: u64, // Creation timestamp agent_pub_key: AgentPubKey, // Original uploader mime_type: String, // File MIME type integrity_metadata: IntegrityMetadata, // Additional integrity info } #[derive(Serialize, Deserialize)] struct IntegrityMetadata { verification_algorithm: String, // "SHA-256", "SHA-3", etc. chunk_size: u32, // Chunk size used compression: Option<String>, // Compression algorithm if used encryption: Option<EncryptionInfo>, // Encryption information } }
Merkle Tree Implementation
#![allow(unused)] fn main() { // Merkle tree node structure #[derive(Clone, Debug)] struct MerkleNode { hash: Vec<u8>, left: Option<Box<MerkleNode>>, right: Option<Box<MerkleNode>>, is_leaf: bool, } // Merkle tree verification function fn verify_merkle_proof( merkle_root: &[u8], chunk_hash: &[u8], proof: &[Vec<u8>], index: usize ) -> bool { let mut current_hash = chunk_hash.to_vec(); let mut current_index = index; for sibling_hash in proof { if current_index % 2 == 0 { // Current node is left child current_hash = hash_children(¤t_hash, sibling_hash); } else { // Current node is right child current_hash = hash_children(sibling_hash, ¤t_hash); } current_index /= 2; } current_hash == merkle_root } }
3. Fractal Resource Storage Patterns
Component Reference Structure
#![allow(unused)] fn main() { #[hdk_entry(id = "resource_component")] struct ResourceComponent { component_id: ResourceHash, // Hash of component resource parent_resource: ResourceHash, // Hash of parent resource quantity: f64, // Quantity required unit: String, // Unit of measurement required: bool, // Whether component is required alternatives: Vec<ResourceHash>, // Alternative components version_constraints: VersionConstraints, // Version compatibility created_at: u64, agent_pub_key: AgentPubKey, } #[derive(Serialize, Deserialize)] struct VersionConstraints { min_version: Option<String>, max_version: Option<String>, exact_version: Option<String>, compatible_versions: Vec<String>, } }
Composite Resource Manifest
#![allow(unused)] fn main() { #[hdk_entry(id = "composite_resource")] struct CompositeResource { resource_hash: ResourceHash, // Hash of this resource resource_name: String, // Human-readable name resource_type: ResourceType, // ATOMIC, COMPONENT, COMPOSITE components: Vec<ResourceComponent>, // List of components assembly_rules: AssemblyRules, // Assembly constraints integrity_hash: Vec<u8>, // Hash of component structure merkle_root: Vec<u8, // Merkle root of all components created_at: u64, agent_pub_key: AgentPubKey, } #[derive(Serialize, Deserialize)] struct AssemblyRules { min_components: u32, max_components: u32, required_components: Vec<ResourceHash>, optional_components: Vec<ResourceHash>, exclusions: Vec<(ResourceHash, ResourceHash)>, // Mutually exclusive } }
4. Verification System Architecture
Multi-Level Verification Strategy
#![allow(unused)] fn main() { // Verification result enumeration #[derive(Serialize, Deserialize, Debug)] enum VerificationResult { Verified, PartiallyVerified, Failed(String), NotFound, InProgress, } // Verification status tracking #[hdk_entry(id = "verification_status")] struct VerificationStatus { resource_hash: ResourceHash, verification_level: VerificationLevel, result: VerificationResult, timestamp: u64, verified_by: AgentPubKey, component_status: HashMap<ResourceHash, VerificationResult>, trust_level: TrustLevel, } #[derive(Serialize, Deserialize)] enum VerificationLevel { Chunk, // Individual chunk verification File, // Complete file verification Component, // Component resource verification Assembly, // Assembly verification System, // Complete system verification } }
Hierarchical Verification Algorithm
#![allow(unused)] fn main() { // Recursive verification function fn verify_resource_hierarchically( resource_hash: &ResourceHash, level: VerificationLevel, ) -> Result<VerificationResult, HolochainError> { match level { VerificationLevel::Chunk => { // Verify individual chunk verify_chunk(resource_hash) } VerificationLevel::File => { // Verify file by checking all chunks let manifest = get_file_manifest(resource_hash)?; let mut all_verified = true; for chunk_hash in &manifest.chunk_hashes { if verify_chunk(chunk_hash)? != VerificationResult::Verified { all_verified = false; } } if all_verified { Ok(VerificationResult::Verified) } else { Ok(VerificationResult::PartiallyVerified) } } VerificationLevel::Component => { // Verify component resource verify_component_resource(resource_hash) } VerificationLevel::Assembly => { // Verify assembly by checking all components let composite = get_composite_resource(resource_hash)?; let mut component_results = HashMap::new(); let mut all_required_verified = true; for component in &composite.components { let result = verify_resource_hierarchically( &component.component_id, VerificationLevel::Component )?; component_results.insert(component.component_id.clone(), result.clone()); if component.required && result != VerificationResult::Verified { all_required_verified = false; } } if all_required_verified { Ok(VerificationResult::Verified) } else { Ok(VerificationResult::PartiallyVerified) } } VerificationLevel::System => { // Verify complete system recursively verify_system_recursively(resource_hash) } } } }
5. Trust Propagation System
Trust Level Management
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] enum TrustLevel { NoTrust, PartialTrust, ConditionalTrust, FullTrust, } // Trust propagation rules impl TrustLevel { fn propagate_to_parent(&self, parent_level: &TrustLevel) -> TrustLevel { match (self, parent_level) { (TrustLevel::FullTrust, _) => parent_level.clone(), (TrustLevel::ConditionalTrust, TrustLevel::FullTrust) => TrustLevel::ConditionalTrust, (TrustLevel::PartialTrust, TrustLevel::FullTrust) => TrustLevel::PartialTrust, (TrustLevel::NoTrust, _) => TrustLevel::NoTrust, (_, _) => parent_level.clone().min(self.clone()), } } fn can_skip_verification(&self) -> bool { matches!(self, TrustLevel::FullTrust) } } }
Trust Relationship Storage
#![allow(unused)] fn main() { #[hdk_entry(id = "trust_relationship")] struct TrustRelationship { resource_hash: ResourceHash, trusted_by: AgentPubKey, trust_level: TrustLevel, trust_reason: String, expires_at: Option<u64>, created_at: u64, verification_history: Vec<VerificationEvent>, } #[derive(Serialize, Deserialize)] struct VerificationEvent { timestamp: u64, result: VerificationResult, verification_type: VerificationLevel, agent: AgentPubKey, } }
6. Performance Optimization Patterns
Parallel Verification Implementation
#![allow(unused)] fn main() { use futures::future::join_all; // Parallel chunk verification async fn verify_chunks_parallel( chunk_hashes: &[Vec<u8>], ) -> Vec<VerificationResult> { let verification_futures: Vec<_> = chunk_hashes .iter() .map(|chunk_hash| async move { verify_chunk_async(chunk_hash).await.unwrap_or(VerificationResult::Failed("Async error".to_string())) }) .collect(); join_all(verification_futures).await } // Parallel component verification async fn verify_components_parallel( components: &[ResourceComponent], ) -> HashMap<ResourceHash, VerificationResult> { let verification_futures: Vec<_> = components .iter() .map(|component| { let component_id = component.component_id.clone(); async move { let result = verify_resource_hierarchically_async( &component_id, VerificationLevel::Component ).await.unwrap_or(VerificationResult::Failed("Async error".to_string())); (component_id, result) } }) .collect(); let results = join_all(verification_futures).await; results.into_iter().collect() } }
Caching Strategy
#![allow(unused)] fn main() { // Verification cache entry #[hdk_entry(id = "verification_cache")] struct VerificationCache { resource_hash: ResourceHash, verification_result: VerificationResult, cache_timestamp: u64, expires_at: u64, verification_level: VerificationLevel, trust_level: TrustLevel, } // Cache management functions impl VerificationCache { fn is_valid(&self, current_time: u64) -> bool { current_time < self.expires_at } fn can_reuse(&self, requested_level: VerificationLevel) -> bool { matches!((self.verification_level, requested_level), (VerificationLevel::System, _) | (VerificationLevel::Assembly, VerificationLevel::Component) | (VerificationLevel::File, VerificationLevel::Chunk) | (_, _) // Same level ) } } }
7. Error Handling and Recovery
Error Classification and Handling
#![allow(unused)] fn main() { #[derive(Debug, thiserror::Error)] enum VerificationError { #[error("Chunk not found: {hash:?}")] ChunkNotFound { hash: Vec<u8> }, #[error("Hash mismatch for chunk {hash:?}")] HashMismatch { hash: Vec<u8> }, #[error("Component missing: {component_id:?}")] ComponentMissing { component_id: ResourceHash }, #[error("Assembly rule violation: {rule}")] AssemblyRuleViolation { rule: String }, #[error("Network timeout during verification")] NetworkTimeout, #[error("Insufficient storage agents")] InsufficientStorage, } // Error recovery strategies impl VerificationError { fn can_retry(&self) -> bool { match self { VerificationError::NetworkTimeout => true, VerificationError::InsufficientStorage => true, VerificationError::ChunkNotFound { .. } => true, VerificationError::HashMismatch { .. } => false, VerificationError::ComponentMissing { .. } => false, VerificationError::AssemblyRuleViolation { .. } => false, } } fn should_fallback(&self) -> bool { match self { VerificationError::NetworkTimeout => true, VerificationError::InsufficientStorage => true, VerificationError::ChunkNotFound { .. } => true, _ => false, } } } }
Recovery Mechanisms
#![allow(unused)] fn main() { // Recovery strategy implementation async fn verify_with_recovery( resource_hash: &ResourceHash, max_retries: u32, ) -> Result<VerificationResult, VerificationError> { let mut retry_count = 0; loop { match verify_resource(resource_hash).await { Ok(result) => return Ok(result), Err(error) if error.can_retry() && retry_count < max_retries => { retry_count += 1; // Exponential backoff let delay = 2_u64.pow(retry_count) * 1000; // milliseconds tokio::time::sleep(Duration::from_millis(delay)).await; if error.should_fallback() { // Try alternative verification strategies if let Ok(fallback_result) = try_fallback_verification(resource_hash).await { return Ok(fallback_result); } } } Err(error) => return Err(error), } } } }
8. Integration with ValueFlows
ValueFlows Resource Enhancement
#![allow(unused)] fn main() { // Enhanced ResourceSpecification with integrity #[derive(Serialize, Deserialize)] struct EnhancedResourceSpecification { // Base ValueFlows fields name: String, note: Option<String>, resource_classification: ResourceClassification, // Integrity extensions integrity_metadata: Option<ResourceIntegrity>, component_structure: Option<ComponentStructure>, verification_requirements: Option<VerificationRequirements>, } #[derive(Serialize, Deserialize)] struct ResourceIntegrity { resource_hash: ResourceHash, merkle_root: Vec<u8>, verification_algorithm: String, last_verified: Option<u64>, trust_level: TrustLevel, } #[derive(Serialize, Deserialize)] struct ComponentStructure { is_composite: bool, components: Vec<ComponentReference>, assembly_rules: Option<AssemblyRules>, version_matrix: Option<VersionMatrix>, } }
Economic Event Integration
#![allow(unused)] fn main() { // Enhanced EconomicEvent with verification #[derive(Serialize, Deserialize)] struct VerifiedEconomicEvent { // Base EconomicEvent fields action: VfAction, resource_inventoried: Option<ResourceAddress>, resource_quantity: Option<Quantity>, provider: AgentAddress, receiver: AgentAddress, // Verification requirements and results verification_required: bool, verification_result: Option<VerificationResult>, verification_timestamp: Option<u64>, // Component-specific verification component_verifications: HashMap<ResourceHash, VerificationResult>, } }
9. Security Considerations
Cryptographic Security
#![allow(unused)] fn main() { // Cryptographic operations use sha2::{Sha256, Digest}; fn compute_chunk_hash(chunk_data: &[u8]) -> Vec<u8> { let mut hasher = Sha256::new(); hasher.update(chunk_data); hasher.finalize().to_vec() } fn compute_merkle_root(chunks: &[Vec<u8>]) -> Vec<u8> { let mut level = chunks.iter().map(|chunk| compute_chunk_hash(chunk)).collect::<Vec<_>>(); while level.len() > 1 { let mut next_level = Vec::new(); for pair in level.chunks(2) { if pair.len() == 2 { let combined = [&pair[0], &pair[1]].concat(); next_level.push(compute_chunk_hash(&combined)); } else { // Odd number of elements, duplicate the last one next_level.push(pair[0].clone()); } } level = next_level; } level.into_iter().next().unwrap_or_default() } }
Access Control Integration
#![allow(unused)] fn main() { // Capability-based access control for verification #[hdk_entry(id = "verification_capability")] struct VerificationCapability { granted_to: AgentPubKey, granted_by: AgentPubKey, resource_hash: Option<ResourceHash>, // None for global capability verification_level: VerificationLevel, granted_at: u64, expires_at: Option<u64>, conditions: Vec<String>, // Additional conditions } // Access control check fn check_verification_capability( agent: &AgentPubKey, resource_hash: &ResourceHash, level: VerificationLevel, ) -> Result<bool, HolochainError> { // Check for global capabilities first let global_caps = get_global_capabilities(agent)?; for cap in global_caps { if can_verify_level(&cap.verification_level, level) && !cap.is_expired() { return Ok(true); } } // Check for resource-specific capabilities let resource_caps = get_resource_capabilities(agent, resource_hash)?; for cap in resource_caps { if can_verify_level(&cap.verification_level, level) && !cap.is_expired() { return Ok(true); } } Ok(false) } }
10. Testing and Validation Strategy
Verification Testing Patterns
#![allow(unused)] fn main() { // Test data generation fn generate_test_chunks(count: usize) -> Vec<Vec<u8>> { (0..count) .map(|i| format!("Test chunk data {}", i).into_bytes()) .collect() } // Verification testing framework #[cfg(test)] mod verification_tests { use super::*; #[tokio::test] async fn test_chunk_verification() { let chunk_data = b"test chunk data".to_vec(); let chunk_hash = compute_chunk_hash(&chunk_data); // Store chunk let chunk_entry = FileChunk { chunk_hash: chunk_hash.clone(), chunk_data: chunk_data.clone(), chunk_index: 0, file_hash: vec![1, 2, 3], // dummy hash created_at: 0, agent_pub_key: AgentPubKey::from_raw_bytes(vec![0; 32]).unwrap(), }; // Verify chunk let result = verify_chunk(&chunk_hash).await.unwrap(); assert_eq!(result, VerificationResult::Verified); } #[tokio::test] async fn test_merkle_tree_verification() { let chunks = generate_test_chunks(5); let merkle_root = compute_merkle_root(&chunks); // Test merkle proof for second chunk let chunk_hash = compute_chunk_hash(&chunks[1]); let proof = generate_merkle_proof(&chunks, 1); let is_valid = verify_merkle_proof(&merkle_root, &chunk_hash, &proof, 1); assert!(is_valid); } #[tokio::test] async fn test_hierarchical_verification() { // Create test composite resource let composite = create_test_composite_resource(); // Verify at assembly level let result = verify_resource_hierarchically( &composite.resource_hash, VerificationLevel::Assembly, ).await.unwrap(); assert_eq!(result, VerificationResult::Verified); } } }
Implementation Recommendations
1. Performance Priorities
- Chunk Size Optimization: 64KB chunks provide good balance between DHT performance and retrieval efficiency
- Parallel Verification: Implement parallel verification at all levels to maximize performance
- Caching Strategy: Comprehensive caching reduces redundant verification operations
- Selective Verification: Allow users to verify only necessary components for time-sensitive operations
2. Security Priorities
- Cryptographic Standards: Use SHA-256 for hash computations with potential migration to SHA-3
- Access Control: Integrate with existing capability-based access control system
- Audit Trails: Maintain comprehensive audit trails for all verification operations
- Key Management: Secure storage and management of cryptographic keys
3. Usability Priorities
- Clear Feedback: Provide users with clear, hierarchical verification status information
- Error Recovery: Graceful handling of verification failures with recovery options
- Progress Indicators: Real-time progress reporting for long-running verification operations
- Trust Management: Intuitive trust level management and propagation
4. Integration Priorities
- ValueFlows Compatibility: Seamless integration with existing ValueFlows resource management
- Governance Integration: Respect existing governance rules and access controls
- Standards Compliance: Follow relevant industry standards for digital integrity
- Extensibility: Design for future standards updates and new requirements
Future Research Directions
1. Advanced Cryptographic Techniques
- Zero-Knowledge Proofs: Privacy-preserving verification of encrypted data
- Homomorphic Verification: Verification of encrypted data without decryption
- Quantum-Resistant Algorithms: Future-proof cryptographic approaches
2. Performance Optimization
- Machine Learning: AI-powered verification optimization and anomaly detection
- Edge Computing: Distributed verification at network edge
- GPU Acceleration: Hardware-accelerated cryptographic operations
3. Cross-Platform Integration
- Interoperability Standards: Cross-platform verification protocols
- Blockchain Bridges: Integration with other blockchain systems
- IoT Integration: Direct verification from IoT devices in manufacturing
Research Status: COMPLETE - Implementation patterns identified and documented Next Phase: Technical specification development and prototype implementation Confidence Level: HIGH - Comprehensive research coverage achieved
"Complexity Oriented Programming" doesn't exist as a formal paradigm yet, which makes it worth thinking through carefully. Here's how I'd frame it:
The core intuition
Most paradigms are reduction strategies. OOP encapsulates. FP eliminates side effects. Procedural linearizes. They all try to make complexity disappear through abstraction. Complexity Oriented Programming (COP) would invert this: instead of hiding complexity, it would model it faithfully and work with it as the primary material.
What it would draw from
Complexity science offers a clear vocabulary: emergence, feedback loops, attractors, phase transitions, edge of chaos, adaptive agents. COP would translate these into first-class programming concepts. You wouldn't fight emergence, you'd design for it. You wouldn't isolate components from their environment, you'd model the coupling.
Key principles that could define it
Rather than single sources of truth, you'd have distributed state with coherence protocols. Rather than deterministic pipelines, you'd have adaptive feedback architectures. Side effects wouldn't be contained, they'd be typed as relational events flowing through a graph. Time and context would be primary, not afterthoughts.
Where it already exists implicitly
Some things already approximate COP without naming it:
- Holochain's agent-centric model, where global coherence emerges from local validation rules
- Reactive/dataflow systems (signals, FRP)
- Actor model concurrency
- Cellular automata as computational substrate
- ValueFlows/REA, which models economic reality as flowing events rather than static entities
The epistemological shift
In classical paradigms, the programmer is a god who designs a closed system. In COP, the programmer is more like an ecologist who designs conditions for emergence. You write rules, thresholds, feedback sensitivity, and then you observe what arises. The system is never fully knowable from the source code alone.
The honest tension
The hard challenge is tooling. Debuggers, type systems, tests, all assume reducibility. COP would need new verification paradigms, probably closer to simulation and formal methods than unit tests.
Given your work on Nondominium and the recognition architecture framework, there's a strong argument that what you're building is COP in practice: protocol-level rules that produce economic coordination as emergent behavior, without a central orchestrator. The ValueFlows ontology isn't modeling a machine, it's modeling a living economic ecosystem.