Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Specialized skill for nondominium Holochain DNA development, focusing on zome creation, entry patterns, integrity/coordinator architecture, ValueFlows compliance, and WASM optimization. Use when creating new zomes, implementing entry types, or modifying Holochain DNA code.
.claude/skills/microck-nondominium-holochain-dna-dev/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 263% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 191% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 142% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 176% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 384% | 0% |
This skill transforms Claude into a specialized nondominium Holochain DNA development assistant, providing expert guidance for creating zomes, implementing entry patterns, and following ValueFlows standards.
Use this skill when:
Do NOT use for:
Create new zomes following nondominium's 3-zome architecture pattern:
bash ./scripts/create_zome.sh <zome_name> both
lib.rsassets/entry_types/ for templatesuse zome_<name>_integrity::*;assets/function_templates/ for patternstoml # Cargo.toml [zome_traits] hdk_integrity = "zome_<name>_integrity"
bash ./scripts/sync_integrity_coordinator.sh <zome_name>
Follow ValueFlows-compliant entry patterns:
rust #hdk_entry_helper] #derive(Clone, PartialEq)] pub struct EconomicResource { // Business fields pub resource_specification: ActionHash, // Link to spec pub current_state: String,
// Agent information (NO timestamps!) pub created_by: AgentPubKey, }
rust #[derive(Serialize, Deserialize, Debug)] pub struct CreateEconomicResourceInput { pub resource_specification: ActionHash, pub current_state: String, }
agent_info()?.agent_initial_pubkeycreated_at fieldrust // Global anchor - discoverable by everyone let path = Path::from("resources"); create_link(path.path_entry_hash()?, entry_hash, LinkTypes::AllResources, LinkTag::new("resource"))?;
// Agent link - discoverable by agent create_link(agent_pubkey, entry_hash, LinkTypes::AgentToResources, LinkTag::new("created"))?;
// Hierarchical link - facility to its specification create_link(facility_hash, spec_hash, LinkTypes::SpecificationToFacility, LinkTag::new("implements"))?;
rust let record = get(entry_hash, GetOptions::default())?; let action = record.action().as_create()?; let created_at = action.timestamp();
bash ./scripts/build_wasm.sh release [zome_name]
bash ./scripts/validate_entry.sh <zome_name>
bash ./scripts/package_happ.sh production
NEVER use SQL-style foreign keys in entry fields!
rust// ❌ WRONG - Direct ActionHash references struct BadFacility { pub facility_hash: ActionHash, // SQL-style foreign key pub owner: ActionHash, // Should be a link instead } // ✅ CORRECT - Use links for relationships struct GoodFacility { pub conforms_to: ActionHash, // Link to specification // No direct references to other entries } // ✅ CORRECT - Link patterns for relationships create_link(facility_hash, owner_hash, LinkTypes::FacilityToOwner, LinkTag::new("managed_by"))?;
Use Holochain's built-in header metadata:
rust// ❌ WRONG - Manual timestamps struct BadEntry { pub created_at: Timestamp, // Redundant! pub updated_at: Timestamp, // Redundant! } // ✅ CORRECT - No timestamps in entries struct GoodEntry { pub name: String, pub description: String, // No created_at/updated_at fields } // Get timestamps from action header when needed: let record = get(entry_hash, GetOptions::default())?; let action = record.action().as_create()?; let created_at = action.timestamp();
Use #[hdk_entry_helper] macro with proper validation requirements:
rust#[hdk_entry_helper] #[derive(Clone, PartialEq)] pub struct FacilitySpecification { pub name: String, pub description: String, pub facility_type: String, // Use Display impl for enums pub created_by: AgentPubKey, pub is_active: bool, // NO ActionHash fields for relationships } #[hdk_entry_types] #[unit_enum(UnitEntryTypes)] pub enum EntryTypes { #[entry_def(required_validations = 2)] // Specify validation requirements FacilitySpecification(FacilitySpecification), #[entry_def(required_validations = 2)] EconomicFacility(EconomicFacility), #[entry_def(required_validations = 3)] // Higher validation for bookings FacilityBooking(FacilityBooking), #[entry_def(required_validations = 2, visibility = "private")] PrivateFacilityData(PrivateFacilityData), }
🆕 NEW - Advanced Validation Options:
rust#[hdk_entry_types] #[unit_enum(UnitEntryTypes)] pub enum EntryTypes { // Public entry with standard validation #[entry_def(required_validations = 2)] PublicEntry(PublicEntry), // Private entry with higher validation #[entry_def(required_validations = 5, visibility = "private")] PrivateEntry(PrivateEntry), // Entry with custom name #[entry_def(name = "custom_entry", required_validations = 3)] CustomEntry(CustomEntry), }
🆕 NEW - Base64 Agent Keys Option: For web-compatible applications, consider base64 encoded agent keys:
rust#[hdk_entry_helper] #[derive(Clone, PartialEq)] pub struct FacilitySpecification { pub name: String, pub description: String, pub created_by: AgentPubKeyB64, // Base64 encoded for web compatibility pub is_active: bool, }
Use comprehensive link types for discovery:
rust#[hdk_link_types] pub enum LinkTypes { // Discovery anchors AllFacilitySpecifications, AllEconomicFacilities, // Hierarchical relationships SpecificationToFacility, // FacilitySpec -> EconomicFacility FacilityToBookings, // EconomicFacility -> FacilityBookings // Agent-centric patterns AgentToOwnedSpecs, // Agent -> FacilitySpecs they created AgentToManagedFacilities, // Agent -> EconomicFacilities they manage // Type-based discovery SpecsByType, // FacilityType -> FacilitySpecs FacilitiesByLocation, // Location -> EconomicFacilities FacilitiesByState, // FacilityState -> EconomicFacilities }
create_[entry_type] - Creates new entries with validation and linksget_[entry_type] - Retrieves single entry by hashget_all_[entry_type] - Global discovery via anchor linksget_my_[entry_type] - Agent-specific entries onlyupdate_[entry_type] - Updates existing entries with permission checksdelete_[entry_type] - Soft deletes with author validationDefine custom error types for each zome:
rust#[derive(Debug, thiserror::Error)] pub enum ZomeError { #[error("Entry not found: {0}")] EntryNotFound(String), #[error("Insufficient capability: {0}")] InsufficientCapability(String), #[error("Validation failed: {0}")] ValidationError(String), } impl From<ZomeError> for WasmError { fn from(err: ZomeError) -> Self { error!(err.to_string()) } }
Use structured link tagging for efficient queries:
rust// Discovery anchors LinkTag::new("facility") LinkTag::new("category") // Status-based tags LinkTag::new("available") LinkTag::new("occupied") // Relationship tags LinkTag::new("created") LinkTag::new("managed_by")
Implement standard ValueFlows entities:
Use standard ValueFlows actions:
produce, accept, modifytransfer, move, deliver_serviceconsume, use, worktransfer-custody, certify, reviewValidate ValueFlows compliance:
Call integrity functions across zomes:
rustlet result: ExternResult<ValidationStatus> = call_integrity( zome_info()?.zome_id, "validate_resource_access".into(), CapSecret::default(), ValidateAccessInput { agent: agent_pubkey, resource: resource_hash, }, )?;
Call functions on other agents' zomes:
rustlet result: ExternResult<ResourceDetails> = call_remote( agent_pubkey, zome_zome_resource.zome_name, "get_resource_details".into(), CapSecret::default(), resource_hash, )?;
✅ CORRECT Cross-Zome Data Access
Use link queries to find related data, then retrieve entries:
rust// Find all resources managed by agent let links = get_links(agent_pubkey, LinkTypes::AgentToResources, None)?; let resource_hashes: Vec<ActionHash> = links.iter() .map(|link| link.target.clone()) .collect(); // Retrieve each resource entry let mut resources = Vec::new(); for hash in resource_hashes { if let Some(record) = get(hash, GetOptions::default())? { if let Some(entry) = record.entry().as_app_entry() { if let EntryTypes::EconomicResource(resource) = entry { resources.push(resource); } } } }
❌ WRONG - Direct Cross-Zome Entry Access
Never access entries from other zomes directly in your entry fields:
rust// WRONG - Never store direct references like this struct BadResource { pub owner: ActionHash, // SQL-style foreign key! pub facility: ActionHash, // Direct reference! } // CORRECT - Use links instead struct GoodResource { pub name: String, pub description: String, // No direct ActionHash references } // Create relationships with links create_link(resource_hash, owner_hash, LinkTypes::ResourceToOwner, LinkTag::new("owned_by"))?; create_link(resource_hash, facility_hash, LinkTypes::ResourceToFacility, LinkTag::new("located_at"))?;
Based on recent Holochain projects, here's the modern validation pattern:
rust#[hdk_extern] pub fn validate(op: Op) -> ExternResult<ValidateCallbackResult> { match op { Op::StoreRecord(_) => Ok(ValidateCallbackResult::Valid), Op::StoreEntry { .. } => Ok(ValidateCallbackResult::Valid), Op::RegisterCreateLink(create_link) => { let (create, _action) = create_link.create_link.into_inner(); let link_type = LinkTypes::try_from(ScopedLinkType { zome_index: create.zome_index, zome_type: create.link_type, })?; // Link-specific validation logic match link_type { LinkTypes::AgentToResource => { // Validate agent has permission to create this link Ok(ValidateCallbackResult::Valid) } LinkTypes::ResourceToSpecification => { // Validate resource exists and specification is valid let _resource: Resource = must_get_entry(create.target_address.clone().into())?.try_into()?; Ok(ValidateCallbackResult::Valid) } _ => Ok(ValidateCallbackResult::Invalid("Unknown link type".to_string())), } } Op::RegisterDeleteLink(_) => { Ok(ValidateCallbackResult::Invalid("Deleting links isn't valid".to_string())) } Op::RegisterUpdate { .. } => { Ok(ValidateCallbackResult::Invalid("Updating entries isn't valid".to_string())) } Op::RegisterDelete { .. } => { Ok(ValidateCallbackResult::Invalid("Deleting entries isn't valid".to_string())) } Op::RegisterAgentActivity { .. } => Ok(ValidateCallbackResult::Valid), } }
Modern projects use link tags for validation data:
rustOp::RegisterCreateLink(create_link) => { let link_type = LinkTypes::try_from(ScopedLinkType { zome_index: create.zome_index, zome_type: create.link_type, })?; if link_type == LinkTypes::Attestation { // Extract agent from link tag and validate against entry let agent = AgentPubKey::try_from( SerializedBytes::try_from(create.tag.clone()) .map_err(|e| wasm_error!(e))? ).map_err(|e| wasm_error!(e))?; let attestation: Attestation = must_get_entry(create.target_address.clone().into())?.try_into()?; if AgentPubKey::from(attestation.about) == agent { Ok(ValidateCallbackResult::Valid) } else { Ok(ValidateCallbackResult::Invalid("Tag doesn't point to about".to_string())) } } else { Ok(ValidateCallbackResult::Valid) } }
wee_alloc for memory allocationImplement hierarchical capability levels:
rust// Check capability before operations if !agent_has_capability(&agent_pubkey, "create_resource") { return Err(ZomeError::InsufficientCapability( "Agent lacks 'create_resource' capability".to_string() ).into()); } // Store capability grants as entries let capability = CapabilityEntry { agent: target_agent, role: "contributor".to_string(), capability_level: 300, granted_by: agent_pubkey, expires_at: Some(expiration_time), // ... other fields };
Critical Pattern Validation:
#[hdk_entry_helper] macro usage on all structsStandard Validation:
#[hdk_entry_helper] macro on all entry structscreated_at or updated_at to entriesExecutable automation scripts for DNA development:
create_zome.sh - Creates new zomes with integrity/coordinator structurebuild_wasm.sh - Compiles Rust code to WASM with optimizationvalidate_entry.sh - Validates entry creation patterns and conventionssync_integrity_coordinator.sh - Ensures layer consistency across zomespackage_happ.sh - Packages hApp bundles for distributionComprehensive documentation for DNA development patterns:
zome_patterns.md - Core architectural patterns and conventionsvalueflows_compliance.md - ValueFlows implementation guidelinesentry_creation_patterns.md - Detailed entry creation workflowsperformance_patterns.md - Optimization techniques and best practicesCode templates and boilerplate for rapid DNA development:
zome_template/ - Complete integrity/coordinator zome templatesentry_types/ - Common entry type patterns (basic, ValueFlows, capabilities)function_templates/ - CRUD and query function templatesNote: This skill is specifically tailored for the nondominium project's ValueFlows-based economic resource sharing architecture and should not be used for generic Holochain development outside this context.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 9,448 | 17,816 | +89% | 1 | 1 | 0% | 1,837 | 6,662 | +263% | 0 | 0 | — |
case-02 | fail→pass | 13,064 | 10,016 | -23% | 1 | 1 | 0% | 2,337 | 6,799 | +191% | 0 | 0 | — |
case-03 | fail→pass | 19,240 | 16,990 | -12% | 1 | 1 | 0% | 3,417 | 8,276 | +142% | 0 | 0 | — |
case-04 | pass→fail | 15,920 | 16,663 | +5% | 1 | 1 | 0% | 3,124 | 8,006 | +156% | 0 | 0 | — |
case-05 | pass→pass | 19,135 | 14,299 | -25% | 1 | 1 | 0% | 3,666 | 7,804 | +113% | 0 | 0 | — |
case-06 | fail→fail | 4,433 | 8,800 | +99% | 1 | 1 | 0% | 764 | 6,418 | +740% | 0 | 0 | — |
case-07 | fail→fail | 7,446 | 8,015 | +8% | 1 | 1 | 0% | 1,165 | 6,486 | +457% | 0 | 0 | — |
case-08 | fail→pass | 14,685 | 10,255 | -30% | 1 | 1 | 0% | 2,558 | 7,063 | +176% | 0 | 0 | — |
case-09 | fail→pass | 6,845 | 2,797 | -59% | 1 | 1 | 0% | 1,112 | 5,387 | +384% | 0 | 0 | — |
case-10 | fail→pass | 12,150 | 4,747 | -61% | 1 | 1 | 0% | 2,137 | 5,875 | +175% | 0 | 0 | — |
case-11 | fail→pass | 9,193 | 3,137 | -66% | 1 | 1 | 0% | 1,637 | 5,467 | +234% | 0 | 0 | — |
case-12 | pass→pass | 12,307 | 6,116 | -50% | 1 | 1 | 0% | 2,146 | 5,961 | +178% | 0 | 0 | — |
case-13 | fail→fail | 11,686 | 8,894 | -24% | 1 | 1 | 0% | 2,245 | 6,765 | +201% | 0 | 0 | — |
case-14 | pass→pass | 13,458 | 11,349 | -16% | 1 | 1 | 0% | 2,608 | 7,126 | +173% | 0 | 0 | — |
case-15 | fail→fail | 8,178 | 7,997 | -2% | 1 | 1 | 0% | 1,610 | 6,497 | +304% | 0 | 0 | — |
case-16 | fail→fail | 16,128 | 10,460 | -35% | 1 | 1 | 0% | 3,019 | 6,907 | +129% | 0 | 0 | — |
case-17 | fail→pass | 13,265 | 4,766 | -64% | 1 | 1 | 0% | 2,200 | 5,788 | +163% | 0 | 0 | — |
case-18 | pass→pass | 8,151 | 3,292 | -60% | 1 | 1 | 0% | 1,511 | 5,554 | +268% | 0 | 0 | — |
case-19 | fail→pass | 10,761 | 3,976 | -63% | 1 | 1 | 0% | 1,996 | 5,654 | +183% | 0 | 0 | — |
case-20 | fail→pass | 7,762 | 2,679 | -65% | 1 | 1 | 0% | 1,406 | 5,367 | +282% | 0 | 0 | — |
case-21 | fail→fail | 9,067 | 6,463 | -29% | 1 | 1 | 0% | 1,789 | 6,199 | +247% | 0 | 0 | — |
case-22 | pass→pass | 20,253 | 11,421 | -44% | 1 | 1 | 0% | 1,820 | 7,138 | +292% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +41 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.