Skip to content

Commit 3ce6c55

Browse files
authored
Ndo (#65)
* refactor: split ResourceState into LifecycleStage and OperationalState - Updated the ResourceState enum to clarify the distinction between the maturity/evolutionary phase of a resource (LifecycleStage) and the current process acting on a resource instance (OperationalState). - Introduced detailed documentation on the new enums, outlining their values and the implications for resource management within the Nondominium framework. - Adjusted related documentation to reflect the changes in state management, ensuring clarity on how lifecycle transitions and operational conditions are governed. - This refactor aims to enhance the accuracy of resource state tracking and improve the governance model by separating concerns. * feat(happ): add hrea role to happ.yaml dual-DNA config (#49) * feat(build): integrate hREA DNA into build and CI pipeline (#50) * ci(build): fix nix flake reproducibility, add rust caching, split test:only script - Replace nix_path channel override with github_access_token to preserve flake.nix pinned nixpkgs (holonix) and avoid non-reproducible unstable builds - Add Swatinem/rust-cache@v2 for both nondominium and hREA target/ dirs to avoid 30-50min cold WASM compilation on every CI run - Add test:only script to package.json so CI can build once then test once, eliminating redundant double-compilation from calling 'tests' script in CI - Update Run tests step to use test:only instead of tests * ci(build): add bun install step before build vitest and other test deps were not installed on the runner, causing 'vitest: command not found' (exit code 127) * ci(build): set continue-on-error on test step during suite stabilization * ci(build): skip tests until suite is stabilized * docs(claude): add submodule init step to dev setup * chore(github): add issue and PR templates Adds bug report, feature/task issue templates, and PR template following the project's PR_GUIDELINES.md structure with conventional commit prefixes, acceptance criteria, and architectural notes sections. * feat(role): implement role promotion request structure and validation - Added a detailed TODO for implementing a `RolePromotionRequest` entry type to facilitate queryable promotion requests in the DHT, addressing the current limitation of out-of-band communication for pending requests. - Updated `role.rs` to outline necessary changes for storing promotion requests and querying them by authorized approvers. - Enhanced `lib.rs` with plans for an `agent_entity_type` field to distinguish various agent types and their capabilities, supporting future extensibility. - Documented the need for a configurable role taxonomy to allow communities to define their own roles, moving beyond the current hardcoded enum. - Adjusted related documentation to reflect these enhancements and their implications for governance and resource management.
1 parent 4c49baa commit 3ce6c55

21 files changed

Lines changed: 1113 additions & 128 deletions

.github/pull_request_template.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@
2323

2424
## Related
2525

26-
Closes #[issue]
27-
Closes #[issue]
26+
Related issues:
27+
- Closes #[issue]
28+
- Closes #[issue]
2829

2930
- Depends on: #
3031
- Follow-up: #

dnas/nondominium/zomes/coordinator/zome_person/src/role.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,39 @@ pub fn promote_agent_with_validation(input: PromoteAgentInput) -> ExternResult<R
333333
assign_person_role(role_input)
334334
}
335335

336+
// TODO (G13 — Queryable Promotion Requests): This function currently validates the request and
337+
// then returns a placeholder hash (the hash of the ValidationReceipt). The actual
338+
// `RolePromotionRequest` is never written to the DHT as a queryable entry, which means
339+
// authorised approvers have no way to discover pending requests without out-of-band
340+
// communication.
341+
//
342+
// Required changes (see `documentation/archives/implementation_plan.md` Phase 2.4):
343+
//
344+
// 1. Define a `RolePromotionRequest` entry type in `zome_person_integrity/src/lib.rs`:
345+
// ```rust
346+
// pub struct RolePromotionRequest {
347+
// pub requesting_agent: AgentPubKey,
348+
// pub target_role: String,
349+
// pub justification: String,
350+
// pub created_at: Timestamp,
351+
// pub status: PromotionRequestStatus, // Pending, Approved, Rejected
352+
// }
353+
// pub enum PromotionRequestStatus { Pending, Approved, Rejected }
354+
// ```
355+
//
356+
// 2. Store the request as a real DHT entry with these links:
357+
// - `AllPendingPromotions` anchor → `request_hash` (so approvers can discover all requests)
358+
// - `agent_pubkey` → `request_hash` (so the requesting agent can track their request)
359+
// - `request_hash` → `agent_pubkey` (reverse lookup)
360+
//
361+
// 3. Implement `get_pending_promotion_requests() -> ExternResult<Vec<RolePromotionRequest>>`
362+
// for authorised approvers to query (filtered by their capability level).
363+
//
364+
// 4. Update `approve_role_promotion` to change the `PromotionRequestStatus` to `Approved` via
365+
// an `update_entry` call, rather than acting on an out-of-band hash.
366+
//
367+
// See `REQ-AGENT-16` in `documentation/requirements/requirements.md` and
368+
// `agent.md` §2.6 (Known Gaps, G13).
336369
/// Request promotion to a higher role
337370
/// This creates a request that can be approved by authorized agents
338371
#[hdk_extern]

dnas/nondominium/zomes/integrity/zome_person/src/lib.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,38 @@
11
use hdi::prelude::*;
22
use std::{fmt::Display, str::FromStr};
33

4+
// TODO (G1 — AgentEntityType): Add an `agent_entity_type` field (or a companion `AgentContext`
5+
// entry) to distinguish Individual, Collective, Project, Network, Bot, and ExternalOrganisation
6+
// agents. Currently all agents are implicitly modelled as individual humans. The post-MVP
7+
// design proposes:
8+
//
9+
// pub enum AgentEntityType {
10+
// Individual,
11+
// Collective(String),
12+
// Project(ActionHash), // references an organisational NondominiumIdentity hash
13+
// Network(ActionHash), // references a network NondominiumIdentity hash
14+
// Bot { capabilities: Vec<String>, operator: AgentPubKey },
15+
// ExternalOrganisation(String),
16+
// }
17+
//
18+
// pub struct AgentContext {
19+
// pub agent_type: AgentEntityType,
20+
// pub person_hash: Option<ActionHash>, // None for bots / external orgs
21+
// pub created_at: Timestamp,
22+
// pub network_seed: String,
23+
// }
24+
//
25+
// See `documentation/archives/agent.md` §6.1, `REQ-AGENT-01` in requirements.md, and
26+
// `documentation/requirements/ndo_prima_materia.md` §8.7.
27+
//
28+
// TODO (G15 — CapabilitySlot on Agent): The `Person` entry hash should serve as a stigmergic
29+
// attachment surface for external capabilities — analogous to the NondominiumIdentity
30+
// CapabilitySlot in ndo_prima_materia.md §6. Add a `PersonCapabilitySlot` link type:
31+
// PersonCapabilitySlot: Person hash → capability target (DID document, credential wallet,
32+
// reputation oracle, external registry)
33+
// Implement `attach_agent_capability_slot` and `get_agent_capability_slots` coordinator
34+
// functions. See `REQ-AGENT-11` and `ndo_prima_materia.md` §6.5.
35+
436
/// Represents a person's public profile with basic information
537
#[hdk_entry_helper]
638
#[derive(Clone, PartialEq)]
@@ -54,7 +86,31 @@ pub struct PersonRole {
5486
pub assigned_at: Timestamp,
5587
}
5688

89+
// TODO (G14 — Configurable Role Taxonomy): This enum is closed — communities cannot define
90+
// their own role types. The OVN model requires roles to emerge from community needs, not
91+
// from infrastructure decisions. Post-MVP, this should become a configurable role registry:
92+
//
93+
// // In integrity: remove `RoleType` enum entirely, or keep as default-role constants.
94+
// // Add a `RoleDefinition` entry type:
95+
// pub struct RoleDefinition {
96+
// pub role_name: String,
97+
// pub capability_level: String, // "member" | "stewardship" | "coordination" | "governance"
98+
// pub description: Option<String>,
99+
// pub validation_requirements: Option<String>,
100+
// pub network_id: String, // Which network defined this role
101+
// pub created_at: Timestamp,
102+
// }
103+
//
104+
// // In coordinator: `assign_person_role` accepts any role name present in the network's
105+
// // RoleDefinition registry. The six predefined roles below become genesis entries.
106+
// // The validate_person_role function must stop hard-rejecting unknown role names and
107+
// // instead look up the RoleDefinition registry.
108+
//
109+
// See `documentation/archives/agent.md` §5.3 (G14), `REQ-AGENT-06` in requirements.md, and
110+
// `documentation/zomes/person_zome.md` Future Enhancements.
111+
57112
/// Allowed role types in the system
113+
// NOTE: These are the MVP defaults. Post-MVP they become configurable registry entries.
58114
#[derive(Debug, Clone, PartialEq)]
59115
pub enum RoleType {
60116
SimpleAgent, // Simple Agent capabilities

dnas/nondominium/zomes/integrity/zome_resource/src/lib.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,37 @@
11
use hdi::prelude::*;
22

3-
// TODO: Add transport state
3+
// TODO: Split ResourceState into two orthogonal enums:
4+
//
5+
// 1. LifecycleStage — the maturity/evolutionary phase of the resource (advances rarely, usually
6+
// irreversibly). Maps to NondominiumIdentity.lifecycle_stage in the NDO three-layer model.
7+
// Values: Ideation, Specification, Development, Prototype, Stable, Distributed,
8+
// Active, Hibernating, Deprecated, EndOfLife
9+
//
10+
// 2. OperationalState — the current process acting on this specific resource instance (cycles
11+
// frequently as processes begin and end). Governance-zome controlled.
12+
// Values: Available, Reserved, InTransit, InStorage, InMaintenance, InUse, PendingValidation
13+
//
14+
// The current enum CONFLATES both dimensions:
15+
// PendingValidation → OperationalState::PendingValidation (pre-activation gate)
16+
// Active → LifecycleStage::Active + OperationalState::Available
17+
// Maintenance → OperationalState::InMaintenance (repair process active; LifecycleStage
18+
// remains whatever it was before, typically Active)
19+
// Retired → LifecycleStage::Deprecated or EndOfLife
20+
// Reserved → OperationalState::Reserved (pre-allocation; LifecycleStage unchanged)
21+
//
22+
// Transport, Storage, and Maintenance are PROCESSES that act on a resource at any lifecycle stage.
23+
// A Prototype can be InTransit (moved between labs). An Active resource can be InStorage.
24+
// These are NOT lifecycle stages.
25+
//
26+
// See: documentation/requirements/ndo_prima_materia.md — Section 5 (LifecycleStage + OperationalState)
27+
// See: documentation/archives/resources.md — Section 2.4 (known gaps)
28+
//
29+
// TODO: Implement PropertyRegime enum when NondominiumIdentity (Layer 0) is introduced.
30+
// Canonical 6-variant enum: Private, Commons, Collective, Pool, CommonPool, Nondominium.
31+
// Each variant implies default governance templates via GovernanceDefaultsEngine.
32+
// See: documentation/requirements/ndo_prima_materia.md — Section 8.2
33+
// See: documentation/archives/resources.md — Section 6.3 (canonical definition)
34+
// See: documentation/archives/resources.md — Section 6.6 (PropertyRegime → governance defaults)
435
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, Default)]
536
pub enum ResourceState {
637
#[default]
@@ -83,6 +114,10 @@ pub enum LinkTypes {
83114
SpecsByCategory, // Category -> ResourceSpecs
84115
ResourcesByLocation, // Location -> EconomicResources
85116
ResourcesByState, // ResourceState -> EconomicResources
117+
// TODO (REQ-NDO-OS-06): Split ResourcesByState into two independent link types:
118+
// ResourcesByLifecycleStage — NondominiumIdentity lifecycle facet queries
119+
// ResourcesByOperationalState — EconomicResource operational facet queries
120+
// See: documentation/requirements/ndo_prima_materia.md — Section 9.4 (REQ-NDO-OS-06)
86121

87122
// Governance patterns
88123
RulesByType, // RuleType -> GovernanceRules

documentation/ARCHITECTURE_COMPONENTS.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ graph TB
210210
211211
subgraph "Economic Resource"
212212
EconRes[EconomicResource<br/>Resource Instance]
213-
ResState[ResourceState<br/>State Tracking]
213+
ResState[LifecycleStage + OperationalState<br/>State Tracking (TODO: split ResourceState)]
214214
ResHistory[ResourceHistory<br/>Audit Trail]
215215
ResCustody[ResourceCustody<br/>Custody Tracking]
216216
end
@@ -258,7 +258,8 @@ graph TB
258258
│ │
259259
│ 2.2 ECONOMIC RESOURCE │
260260
│ ├── EconomicResource Entry (resource instance) │
261-
│ ├── ResourceState Entry (current state tracking) │
261+
│ ├── LifecycleStage (on NondominiumIdentity) + OperationalState (on EconomicResource) │
262+
│ │ TODO: split current ResourceState into these two enums │
262263
│ ├── ResourceHistory Entry (audit trail) │
263264
│ └── ResourceCustody Entry (custody tracking) │
264265
│ │
@@ -630,7 +631,7 @@ graph TD
630631
P2[Hold Custody]
631632
P3[Validate Specialized Roles]
632633
P4[Initiate All Processes]
633-
P5[All 14 PPR Categories<br/>Including Custodianship]
634+
P5[All 16 PPR Categories<br/>Including Custodianship]
634635
end
635636
636637
subgraph "Advanced Agent Capabilities"
@@ -665,7 +666,7 @@ Accountable Agent (stewardship)
665666
Primary Accountable Agent (coordination/governance)
666667
├── Full Capability Token (comprehensive access)
667668
├── Can: Hold custody, validate specialized roles, initiate all processes
668-
├── PPR Eligibility: All 14 categories including custodianship
669+
├── PPR Eligibility: All 16 categories including custodianship
669670
└── Advanced: Dispute resolution, end-of-life validation
670671
```
671672

documentation/DOCUMENTATION_INDEX.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ Accountable Agent (stewardship)
354354
Primary Accountable Agent (coordination/governance)
355355
├── Full capability token
356356
├── Can hold custody & validate specialized roles
357-
├── PPR eligibility: All 14 categories
357+
├── PPR eligibility: All 16 categories
358358
└── Advanced: Dispute resolution & end-of-life validation
359359
```
360360

documentation/archives/agent.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ An individual agent can hold a `PersonRole` in both their own profile and in an
216216

217217
This means the generic NDO's agent model does not need a separate "organisation agent" type — it needs organisational NDOs and a clear mapping between individual agents and the NDOs they participate in.
218218

219+
Agent-NDOs use the same three-layer structure as resource-NDOs (see `resources.md §3.1`) but may use a subset of `LifecycleStage` values — a working group does not go through `Prototype` or `Distributed`, for example. The `PropertyRegime` and `ResourceNature` fields on `NondominiumIdentity` remain applicable: a working group's shared knowledge base is a `Commons`/`Digital` NDO; a collectively owned workshop is a `Collective`/`Physical` NDO.
220+
219221
### 3.2 CapabilitySlot on Agent Identity
220222

221223
The NDO CapabilitySlot surface (from `nondominium-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.
@@ -429,8 +431,8 @@ affiliation_state(agent) = f(
429431
governance_claims_count(agent) // From PPRs
430432
)
431433
432-
Unaffiliated | CloseAffiliate | ActiveAffiliate(contribution_count) |
433-
CoreAffiliate(governance_weight) | InactiveAffiliate
434+
UnaffiliatedStranger | CloseAffiliate | ActiveAffiliate |
435+
CoreAffiliate | InactiveAffiliate
434436
```
435437

436438
`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.

0 commit comments

Comments
 (0)