Metadata-Version: 2.4
Name: gluthag-schema
Version: 1.0.1
Summary: The Gluthag TOML contract — schema types, parser, and validator. Shared source of truth between Erzgrimm (emitter) and Gluthag (consumer).
Project-URL: Homepage, https://pypi.org/project/gluthag-schema/
Project-URL: Source, https://pypi.org/project/gluthag-schema/
Author: Bollwerk / Erzgrimm
License: MIT
License-File: LICENSE
Keywords: bollwerk,contract,erzgrimm,gluthag,schema,toml
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.11
Description-Content-Type: text/markdown

# gluthag-schema

The **Gluthag TOML contract** — parser, schema types, and validator.

This package is the single source of truth for the `gluthag.toml` file
shape (contract version `1.0`). It is shared by:

- **Erzgrimm** — the build platform that emits Gluthag bundles.
- **Gluthag** — the local test-server / runner that consumes them.
- **Third parties** who want to author or verify bundles by hand.

## Install

```bash
pip install gluthag-schema
```

Requires Python `>=3.11` (uses the stdlib `tomllib`). Zero runtime
dependencies.

## Quick example

```python
from gluthag_schema import (
    parse_gluthag_toml,
    validate_gluthag_toml,
    cross_check_env,
    SUPPORTED_CONTRACT_VERSIONS,
)

toml_text = '''
contract_version = "1.0"

[app]
name = "smiths-anvil"
primary_service = "backend"

[run]
target_default = "local"
mode_default = "ephemeral"

[env]
required = ["DATABASE_URL", "JWT_SECRET"]
generated = ["JWT_SECRET"]

[network]
policy = "allow"
allow = ["api.stripe.com"]
'''

# Parse — raises ValueError if TOML is malformed
manifest = parse_gluthag_toml(toml_text)
assert manifest["contract_version"] in SUPPORTED_CONTRACT_VERSIONS

# Validate — never raises; returns ALL findings so you get a
# complete error picture in one pass.
result = validate_gluthag_toml(toml_text)
if not result.ok:
    for f in result.findings:
        print(f"{f.severity} {f.path}: {f.message}")

# Cross-check env against a companion .env.example
env_example = "DATABASE_URL=postgres://...\nJWT_SECRET=change-me\n"
cross = cross_check_env(manifest, env_example)
assert cross.ok, cross.findings
```

## Public API

Everything the package exports is stable at `1.0.x`:

| Name                          | Kind      | Purpose                                                        |
| ----------------------------- | --------- | -------------------------------------------------------------- |
| `parse_gluthag_toml(text)`    | function  | Parse TOML text → typed `GluthagManifest`. Raises `ValueError` on malformed TOML. |
| `validate_gluthag_toml(text)` | function  | Parse + validate; returns `ValidationResult` (never raises).   |
| `cross_check_env(manifest, env_example_text)` | function | Cross-check `[env].required` vs `.env.example` and `[env].generated ⊆ required`. |
| `SUPPORTED_CONTRACT_VERSIONS` | constant  | Tuple of contract versions this release understands, **newest-first**. `("1.0",)` at v1.0.1. |
| `DEFAULT_EMIT_VERSION`        | constant  | The contract version an emitter SHOULD write when producing a fresh bundle. `"1.0"` at v1.0.1. Introduced in v1.0.1 as an explicit escape hatch from `SUPPORTED_CONTRACT_VERSIONS[0]`. |
| `GluthagManifest`             | type      | `TypedDict` describing the parsed shape.                        |
| `ValidationResult`            | dataclass | `.ok: bool`, `.findings: list[Finding]`.                        |
| `Finding`                     | dataclass | `.severity: Literal["error"]`, `.path: str`, `.message: str`.   |

### Design notes

- **Content-based API.** All functions take TOML *text*. The library
  never touches the filesystem. This lets Erzgrimm (which builds the
  document in memory) and Gluthag (which reads it from disk) call
  identical code paths.
- **Findings, not exceptions.** Validation returns every problem in one
  pass. Consumers iterate for a full error picture rather than
  discover-fix-repeat cycles.
- **No dependencies.** `tomllib` is stdlib; that is the only import.
- **Typed.** Full type hints + `py.typed` marker for downstream mypy /
  pyright users.

## Contract reference

The v1.0 shape is documented in the Erzgrimm spec, Section 13.
Required tables: `[app]`, `[run]`, `[env]`, `[network]`. Optional:
`[services.*]`, `[seed]`. See the tests directory for the canonical
example.

## License

MIT. See `LICENSE`.
