Codebase Conventions

This appendix summarizes the layout and conventions used in the Asset Core codebase for external readers and contributors.

Overview

Asset Core follows consistent patterns across all crates for structure, naming, and documentation. Understanding these conventions helps you navigate the code and maintain consistency when contributing.

Detailed explanation

Repository Layout

asset-core/
├── core/                 # Runtime engine (L1/L2/L3)
├── daemon-write/         # HTTP write daemon
├── daemon-read/          # HTTP read daemon
├── acctl/                # CLI tool
├── telemetry/            # Shared metrics crate
├── api-contract/         # OpenAPI spec generation
├── assetcore-adapters/   # Protocol adapters
├── system-tests/         # E2E test harness
├── sdk-python/           # Python SDK
└── Docs/                 # Architecture documentation

Crate Structure

Each crate follows this pattern:

crate/
├── Cargo.toml
├── README.md            # Crate overview
├── AGENTS.md            # Rules for LLM agents
└── src/
    ├── lib.rs           # Public API
    ├── mod.rs files     # Module organization
    └── tests/           # Unit tests

Layer Architecture (L1/L2/L3)

The core crate enforces strict layer separation:

LayerLocationResponsibility
L1core/src/storage/Raw data structures
L2core/src/operations/Business logic, events
L3core/src/runtime/Transactions, undo

Rules:

  • L2 may call L1, not vice versa
  • L3 may call L2, not vice versa
  • No cross-layer imports except downward

Naming Conventions

Files: snake_case

ingress_orchestrator.rs
commit_log_driver.rs

Types: PascalCase

struct ValidatedCommit { ... }
enum ContainerKind { ... }

Functions: snake_case

fn prepare_commit(&mut self) -> Result<...>

Constants: SCREAMING_SNAKE_CASE

const MAX_BATCH_SIZE: usize = 1000;

Documentation Headers

Every source file includes a header:

// =============================================================================
// Module: ingress/orchestrator
// Description: Coordinates request sequencing and commit pipeline
// Purpose: Provide backpressure-aware ingestion
// Dependencies: worker, append, state
// =============================================================================

This helps LLM agents understand context without reading full implementations.

Error Handling

Errors use typed enums with context:

#[derive(Debug, thiserror::Error)]
pub enum CommitError {
    #[error("Container {0} not found")]
    ContainerNotFound(ContainerId),

    #[error("Insufficient balance: requested {requested}, available {available}")]
    InsufficientBalance {
        requested: u64,
        available: u64,
    },
}

Errors map to HTTP status codes via the API layer.

Metrics Naming

Metrics follow a consistent pattern:

assetcore_{daemon}_{subsystem}_{metric}_{unit}

Examples:

  • assetcore_write_ingress_queue_depth
  • assetcore_read_snapshot_publish_duration_seconds
  • assetcore_write_commit_log_lag

Testing Patterns

Unit tests: Inline in source files

#[cfg(test)]
mod tests {
    use super::*;
    // ...
}

Integration tests: Under tests/ directory

System tests: In system-tests crate

AGENTS.md Files

Each crate has an AGENTS.md with rules for code-generation agents:

  • Invariants to preserve
  • Patterns to follow
  • Files to consult before changes
  • Common pitfalls

Read the relevant AGENTS.md before modifying any crate.

Implementation notes

No Unsafe in Hot Paths

Performance comes from data layout, not unsafe code:

  • Structure-of-Arrays (SoA) for cache efficiency
  • Dense IDs instead of hashing
  • Pre-allocated buffers

No Strings on Hot Paths

Identifiers are integers:

type ContainerId = u64;
type ClassId = u64;
type InstanceId = u64;

Strings are only for user-facing names and configuration.

Determinism Requirements

Operations must be deterministic:

  • No system time during replay
  • No random values
  • No external dependencies during commit

Events carry post-state so replay is idempotent.

When to read this

Read this appendix when:

  • Onboarding to the codebase
  • Contributing changes
  • Understanding metric names
  • Navigating unfamiliar areas

For API usage, the reference docs are more relevant.

See also