Skip to content

Index

spec

Specification corpus loading and management.

Provides the SpecCorpusLoader for reading venue spec directories into SpecFragment models for injection into agent prompts.

Classes

SpecCorpusLoader

Loads specification fragments from a directory.

The loader reads all recognized files from the spec directory and produces SpecFragment instances. YAML files are parsed for structured content (name, tags, kind, content, data). Markdown files become text fragments with the filename stem as the name.

Binary files and unrecognized extensions are silently skipped.

Functions
load staticmethod
load(spec_dir)

Load all spec fragments from a directory.

Parameters:

Name Type Description Default
spec_dir str | Path

Path to the specification directory. Must exist.

required

Returns:

Type Description
list[SpecFragment]

List of loaded SpecFragment instances, sorted by name for

list[SpecFragment]

deterministic ordering.

Raises:

Type Description
SpecCorpusError

If the directory does not exist or cannot be read.

Source code in src/marianne/spec/loader.py
@staticmethod
def load(spec_dir: str | Path) -> list[SpecFragment]:
    """Load all spec fragments from a directory.

    Args:
        spec_dir: Path to the specification directory. Must exist.

    Returns:
        List of loaded SpecFragment instances, sorted by name for
        deterministic ordering.

    Raises:
        SpecCorpusError: If the directory does not exist or cannot
            be read.
    """
    spec_path = Path(spec_dir)

    if not spec_path.exists():
        raise SpecCorpusError(
            f"Spec directory does not exist: {spec_path}. "
            f"Set spec.spec_dir in your configuration to a valid directory."
        )

    if not spec_path.is_dir():
        raise SpecCorpusError(
            f"Spec path is not a directory: {spec_path}"
        )

    fragments: list[SpecFragment] = []
    errors: list[str] = []

    # Only read top-level files (no recursion into subdirectories).
    # This is deliberate: spec files are a flat collection, not a tree.
    for file_path in sorted(spec_path.iterdir()):
        if not file_path.is_file():
            continue

        suffix = file_path.suffix.lower()
        if suffix not in _RECOGNIZED_EXTENSIONS:
            _logger.debug(
                "skipping_unrecognized_file",
                path=str(file_path),
                suffix=suffix,
            )
            continue

        try:
            if suffix in _YAML_EXTENSIONS:
                fragment = _load_yaml_fragment(file_path)
            else:
                fragment = _load_markdown_fragment(file_path)
            fragments.append(fragment)
            _logger.debug(
                "loaded_fragment",
                name=fragment.name,
                kind=fragment.kind,
                tags=fragment.tags,
                content_length=len(fragment.content),
            )
        except Exception as exc:
            error_msg = f"{file_path.name}: {exc}"
            errors.append(error_msg)
            _logger.warning(
                "fragment_load_error",
                path=str(file_path),
                error=str(exc),
            )

    if errors:
        _logger.warning(
            "spec_corpus_load_warnings",
            error_count=len(errors),
            errors=errors,
        )

    # Sort by name for deterministic ordering regardless of filesystem
    fragments.sort(key=lambda f: f.name)

    _logger.info(
        "spec_corpus_loaded",
        fragment_count=len(fragments),
        error_count=len(errors),
        directory=str(spec_path),
    )

    return fragments
load_claude_md staticmethod
load_claude_md(project_root)

Load CLAUDE.md as a spec fragment if it exists.

Parameters:

Name Type Description Default
project_root str | Path

Path to the project root directory.

required

Returns:

Type Description
SpecFragment | None

SpecFragment with name='claude_md' and kind='text', or None

SpecFragment | None

if CLAUDE.md does not exist.

Source code in src/marianne/spec/loader.py
@staticmethod
def load_claude_md(project_root: str | Path) -> SpecFragment | None:
    """Load CLAUDE.md as a spec fragment if it exists.

    Args:
        project_root: Path to the project root directory.

    Returns:
        SpecFragment with name='claude_md' and kind='text', or None
        if CLAUDE.md does not exist.
    """
    claude_path = Path(project_root) / "CLAUDE.md"
    if not claude_path.is_file():
        return None

    try:
        content = claude_path.read_text(encoding="utf-8")
        if not content.strip():
            return None
        return SpecFragment(
            name="claude_md",
            content=content,
            tags=[],
            kind="text",
        )
    except Exception as exc:
        _logger.warning(
            "claude_md_load_error",
            path=str(claude_path),
            error=str(exc),
        )
        return None