This document provides essential context and guidelines for AI-assisted development on the MetaGraph project.
MetaGraph is a high-performance C23 library implementing a mathematical hypergraph foundation for asset management systems. The project embodies the principle that "everything is a graph" - from neural networks to game worlds to dependency trees.
- Language: C23 with bleeding-edge compiler features (GCC 15+, Clang 18+)
- Architecture: 12 interconnected features forming a complete system
- Libraries: BLAKE3 (cryptography), mimalloc (memory), uthash (data structures), tinycthread (threading)
- Performance: Sub-200ms load times for 1GB bundles, lock-free concurrent access
- Quality: Zero tolerance for warnings, 100% test coverage, comprehensive static analysis
- Do exactly what is asked - nothing more, nothing less
- Edit existing files rather than creating new ones
- Never create documentation files unless explicitly requested
- Follow existing patterns and conventions rigorously
- Use C23 features wherever appropriate
ALWAYS use metagraph_result_t for ANY function that could fail:
// ✅ CORRECT - Every fallible function returns metagraph_result_t
metagraph_result_t metagraph_node_add(metagraph_graph_t* graph,
const metagraph_node_metadata_t* metadata,
metagraph_id_t* out_id) {
METAGRAPH_CHECK_NULL(graph);
METAGRAPH_CHECK_NULL(metadata);
METAGRAPH_CHECK_NULL(out_id);
// Allocation could fail
metagraph_node_t* node = metagraph_pool_alloc(graph->pool, sizeof(*node));
METAGRAPH_CHECK_ALLOC(node);
// Any operation that could fail must be checked
METAGRAPH_CHECK(metagraph_id_generate(&node->id));
*out_id = node->id;
return METAGRAPH_OK();
}
// ❌ WRONG - Using int/bool for error handling
int add_node(graph_t* graph, node_t* node) {
if (!graph || !node) return -1; // NO! Use METAGRAPH_CHECK_NULL
return 0; // NO! Use METAGRAPH_OK()
}Key error handling patterns:
- Use
METAGRAPH_CHECK()to propagate errors up the call stack - Use
METAGRAPH_CHECK_NULL()for null pointer validation - Use
METAGRAPH_CHECK_ALLOC()after any allocation - Use
METAGRAPH_ERR()to return errors with context - Never use
int,bool, or custom error codes - alwaysmetagraph_result_t
// Use auto for type inference
auto result = metagraph_graph_create(&config, &graph);
// Use typeof for generic programming
#define POOL_ALLOC(pool, type) \
((type*)metagraph_pool_alloc(pool, sizeof(type), _Alignof(type)))
// Use [[attributes]] for optimization hints
[[nodiscard]] metagraph_result_t metagraph_graph_add_node(
metagraph_graph_t* restrict graph,
const metagraph_node_metadata_t* restrict metadata,
metagraph_id_t* restrict out_id
);
// Use _BitInt for precise bit widths
typedef _BitInt(128) metagraph_id_t;
typedef _BitInt(40) metagraph_offset_t; // For files up to 1TB// Always use restrict for pointer parameters
void metagraph_copy_nodes(
const metagraph_node_t* restrict source,
metagraph_node_t* restrict dest,
size_t count
);
// Align structures for atomic operations
typedef struct alignas(64) { // Cache line aligned
_Atomic(uint64_t) ref_count;
metagraph_id_t id;
// ... rest of structure
} metagraph_node_t;The project uses lowercase snake_case with module prefixes:
// Pattern: metagraph_[module]_[action]
metagraph_graph_create()
metagraph_graph_destroy()
metagraph_node_add()
metagraph_edge_connect()
metagraph_bundle_load()
metagraph_pool_alloc()Note: API naming is enforced by clang-tidy - let the tools handle compliance.
MANDATORY: All scripts must be POSIX-compliant - NO bash-isms allowed.
#!/bin/sh # NOT #!/bin/bash
set -eu # NOT set -euo pipefail
# POSIX conditionals only
if [ "$var" = "value" ]; then # NOT [[ "$var" == "value" ]]
echo "correct"
fi
# No arrays, no mapfile, no process substitution
# Scripts must work on minimal /bin/sh environments# Development setup
./scripts/setup-dev-env.sh
# Build with all checks
cmake -B build -DCMAKE_BUILD_TYPE=Debug -DMETAGRAPH_DEV=ON
cmake --build build
# Run quality checks
./scripts/run-clang-format.sh --fix
cmake --build build --target static-analysis
ctest --test-dir build --output-on-failure
# Performance profiling
./scripts/profile.sh all- F.010: Platform abstraction layer
- F.011: Error handling and validation
- Start with these before any other features
- F.001: Hypergraph data model
- F.007: Asset ID system
- F.009: Memory pool management
- F.002: Binary bundle format
- F.003: Memory-mapped I/O
- F.004: BLAKE3 integrity
- F.005: Graph traversal
- F.006: Dependency resolution
- F.008: Thread-safe access
- F.012: Bundle creation and serialization
- 100% test coverage for all functions
- Zero clang-tidy warnings - fix, don't suppress
- Clean sanitizer runs - ASan, MSan, UBSan, TSan must all pass
- No memory leaks - Valgrind must report zero issues
- Performance targets met - <5% regression tolerance
Every function needs:
- Success case tests
- Error case tests
- Edge case tests
- Concurrent access tests (where applicable)
- Performance benchmarks (for critical paths)
- Use streaming API for large files
- Enable SIMD optimizations
- Integrate with memory pool for hash contexts
- Create custom arenas on top of mimalloc
- Use thread-local heaps for hot paths
- Override malloc/free globally in release builds
- Wrap in type-safe macros
- Integrate with memory pool
- Use HASH_ADD_KEYPTR for string keys
- Combine with C11 atomics for lock-free patterns
- Use condition variables sparingly
- Prefer atomic operations over mutexes
- Don't assume libraries exist - always check package.json/CMakeLists.txt first
- Don't create new patterns - study existing code and follow conventions
- Don't skip tests - every function must have comprehensive tests
- Don't use non-POSIX shell - scripts must work on minimal /bin/sh
- Don't ignore performance - profile critical paths and optimize
- Don't use int/bool for errors - ALWAYS use metagraph_result_t for fallible functions
MUST use metagraph_result_t when:
- Function performs any allocation (could fail with OOM)
- Function does any I/O operations (file, network, etc.)
- Function validates input parameters
- Function calls other functions that return metagraph_result_t
- Function could fail for ANY reason
Can use void when:
- Function is a simple getter that cannot fail
- Function only modifies already-validated internal state
- Function is a destructor/cleanup function
// ✅ Correct usage examples
metagraph_result_t metagraph_graph_create(...); // Allocates memory
metagraph_result_t metagraph_node_add(...); // Modifies graph, allocates
metagraph_result_t metagraph_bundle_load(...); // I/O operation
metagraph_result_t metagraph_validate(...); // Input validation
// ✅ Correct void usage
void metagraph_graph_destroy(graph); // Cleanup, can't fail
void metagraph_node_get_id(node, out_id); // Simple getter- Never create files unless absolutely necessary
- Always prefer editing existing files
- Never proactively create documentation
- Follow C23 best practices rigorously
- Let clang-tidy enforce naming conventions
- Use Task tool for complex searches
- Run linting/type checking after implementation
When implementing a new feature:
- Read the feature specification in
docs/features/ - Study existing code for patterns and conventions
- Implement with comprehensive tests
- Run all quality checks
- Profile performance if on critical path
Remember: The goal is mathematical purity, extreme performance, and absolute reliability. Every line of code should reflect these values.