Skip to main content

A declarative repository governance and automation framework using skeletal templates and Pydantic.

Project description

Skelantic Icon

Skelantic

A declarative file-tree processing and governance engine for Python.

PyPI version CI

Skelantic allows you to enforce repository structures, parse unstructured text files (like Markdown) into strictly typed Pydantic models using "Skeletal Templates", and execute Python-based processor functions over your file tree to ensure referential integrity and consistency.

It is particularly useful for:

  • AI Coding Agents: Providing strict guardrails and architecture enforcement for autonomous agents.
  • Documentation Governance: Ensuring that documentation folders conform to a specific structure and that cross-references are valid.
  • Declarative Repositories: Managing complex, heavily structured projects (like Data Lakes, Content Management, or Architecture Decision Records) where files must adhere to strict templates.

🚀 Quick Start

1. Installation

Install Skelantic via pip:

pip install skelantic

2. Define the Repository Structure

Skelantic operates on a "Strict-by-Default" (Default-Deny) philosophy. By defining cascading .skelantic/config.yaml files throughout your repository, you explicitly allow files and directories. Anything not explicitly permitted is flagged as an error. For a full list of configuration options, wildcards, and path variables, see the Configuration Guide (config.yaml).

Create a .skelantic/config.yaml at the root of your project:

description: "Global configuration"
files:
  "README.md":
    description: "Main Readme"
directories:
  "docs":
    description: "Documentation directory"
    directories:
      "issues":
        description: "Task tracking"
        files:
          "{slug}.md":
            description: "An issue file"
            template: ".skelantic/templates/issue.md"

3. Write a Skeletal Template

Skeletal Templates verify the contents of text files and extract data using a custom, readable AST. For a full list of available variables, block structures, and multiline extractions, see the Skeletal Templates Syntax Guide.

Create .skelantic/templates/issue.md:

# Issue: {{title:str}}
Status: {{status:enum[OPEN,IN_PROGRESS,DONE]}}

## Description
[[block:description]]
{{text}}
[[/block]]

4. Generate Pydantic Models

Before writing your custom logic, use the Skelantic CLI to automatically generate strongly-typed Pydantic models from your Skeletal Templates:

skelantic generate -o "my_project/models"

This will create Python files (e.g., my_project/models/issue.py) containing the strictly-typed representation of your template:

# Auto-generated by Skelantic
from pydantic import BaseModel
from typing import Optional

class IssueTemplate(BaseModel):
    title: Optional[str] = None
    status: Optional[str] = None
    description: Optional[str] = None

5. Write Processors

Processors are written in pure Python and execute validation logic. Use the @processor decorator to bind them to specific files matching a glob pattern.

Skelantic automatically instantiates your generated Pydantic models and injects them, along with context and trace loggers, directly into your function. For a deep dive into the injected parameters, the different phases, and cross-file relational checks, see Writing Processors & Understanding Context and the File System Nodes API.

from typing import List, Callable, cast
from skelantic.commons.decorators import processor
from skelantic.commons.context import LinterContext
from skelantic.commons.nodes import FileNode
from my_project.models.issue import IssueTemplate # Your generated model!

@processor(match="docs/issues/*.md", phase=2)
def validate_issue_status(node: FileNode, ctx: LinterContext, tracer: Callable[[str], None] = lambda x: None) -> List[str]:
    tracer(f"Validating issue: {node.rel_path.name}")

    # 1. Fetch the raw data extracted from the template
    full_path = node.rel_path.as_posix()
    data = ctx.extracted_data.get(full_path, {})
    if not data:
        return []

    # 2. Cast the raw data into your strictly-typed Pydantic model
    model = IssueTemplate.model_validate(data)

    # 3. Perform type-safe business logic validations
    if model.status == "DONE" and not "resolution" in (model.description or "").lower():
        return ["DONE issues must have a resolution in their description."]

    # You can also use ctx.extracted_data to iterate through other files in the workspace
    # to perform relational checks (e.g. checking if linked files exist).

    return []

6. Run the Engine

Use the Skelantic CLI to execute the workflow engine against your repository.

# Run the engine to validate the repository
# -p specifies the package containing your @processor functions
# -m specifies the package containing your generated Pydantic models
skelantic run -p "my_project.processors" -m "my_project.models"

⚙️ Advanced Features

  • Dependency Injection: The engine automatically injects arguments into your processor functions based on their signature (node, ctx, tracer, and dynamic path variables like slug).
  • Strictness Flags: In your config.yaml, use optional: true for warnings instead of errors, silent: true to suppress warnings, or authorize: false to apply patterns without implicitly authorizing existence.
  • Pydantic Integration: Skelantic natively supports Pydantic. If you map a Pydantic model to a template, the engine will automatically instantiate and inject the strongly-typed model into your processors.

🤝 Contributing

If you want to contribute to the development of the Skelantic engine itself, please see our CONTRIBUTING.md guide.

📚 More Documentation

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

skelantic-0.1.3.tar.gz (289.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

skelantic-0.1.3-py3-none-any.whl (26.1 kB view details)

Uploaded Python 3

File details

Details for the file skelantic-0.1.3.tar.gz.

File metadata

  • Download URL: skelantic-0.1.3.tar.gz
  • Upload date:
  • Size: 289.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for skelantic-0.1.3.tar.gz
Algorithm Hash digest
SHA256 f8976290b741a5546993d18008ee0074b95e0a6f67ffb279d395d6e1724859b5
MD5 9f3f2fde7aba66a1a05d769ef7bb1a41
BLAKE2b-256 d64221e2d8cc0d727f79fa929ea8d32fbd8978a6e68f82d6a0644e57fb1b8a4f

See more details on using hashes here.

Provenance

The following attestation bundles were made for skelantic-0.1.3.tar.gz:

Publisher: ci.yml on ghackenberg/skelantic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file skelantic-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: skelantic-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 26.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for skelantic-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 fcf09a7199c41bbf1d77987ff5005719f16157eb1122dd911a74209f98f76e7f
MD5 85b3cb7b3d7def9dbcd442e43c4fe5ad
BLAKE2b-256 063a764b67d2ab463121386aa061d43491c3236a95682ee40aa7f16af30a7dd1

See more details on using hashes here.

Provenance

The following attestation bundles were made for skelantic-0.1.3-py3-none-any.whl:

Publisher: ci.yml on ghackenberg/skelantic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page