# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

RTC.ex is an Elixir implementation of [RDF Triple Compounds](https://w3id.org/rtc) - a spec for nestable sub-graphs embedded in RDF-star graphs. It depends on the RDF.ex ecosystem.

The implemented spec is available in `magma/kb/rtc-spec.bs` (Bikeshed format).

## Common Commands

```bash
# Run all tests
mix test

# Run a single test file
mix test test/rtc/compound_test.exs

# Run a single test (by line number)
mix test test/rtc/compound_test.exs:42

# Run SPARQL client tests (excluded by default, requires a triple store)
mix test.sparql_client

# Quality checks (clean, deps check, compile warnings, format, test, credo)
mix check

# Format code
mix format

# Static analysis
mix dialyzer

# Generate documentation
mix docs
```

## Architecture

The library has a minimal module structure:

- `RTC` - Top-level module with ID generation and namespace delegation
- `RTC.Compound` - Core struct and API for working with triple compounds. Contains:
  - Asserted/unasserted triple management
  - Sub-compound and super-compound hierarchies
  - RDF serialization via `to_rdf/2` and `from_rdf/2`
  - SPARQL integration via `from_sparql/3` (optional, requires `sparql_client` dependency)
- `RTC.NS` - RDF vocabulary namespace for the RTC vocabulary
- `RTC.SPARQL` - SPARQL endpoint integration (conditionally compiled when `sparql_client` is available)

## Key Concepts

- **Compound**: A set of triples with an ID, annotations, and optional sub/super-compound relationships
- **Asserted vs Unasserted**: Triples can be marked as asserted (present in the graph) or unasserted (metadata only)
- **Element styles**: `to_rdf/2` supports `:element_of` (annotation syntax) and `:elements` (compound-centric) serialization styles

## Testing

Tests use `RTC.Case` as a common ExUnit template which imports:
- RDF structs and sigils
- Test namespaces `EX` and `FOAF` (defined in `test/support/test_ns.ex`)
- Factories from `test/support/factories.ex`

SPARQL client tests are excluded by default and tagged with `@tag :sparql_client`.

### Style

- Use `==` comparisons with expected result on right side for complete struct comparison
- Prefer comparing complete structs over asserting individual fields (easier to identify tests needing updates when structs change)
- Pattern matching only when exact comparison is impractical (e.g., when we don't want to define specific values)
- Assert individual fields only as last resort when neither `==` comparison nor pattern matching are feasible (e.g., when values must be computed functionally)


## Configuration

Application config supports:
- `:id` - Resource generator config for auto-generated compound IDs
- `:element_style` - Default element style (`:element_of` or `:elements`)
- `:assertion_mode` - Default assertion mode (`:asserted` or `:unasserted`)
- `:from_sparql_opts` - Default options for SPARQL client calls
