Metadata-Version: 2.4
Name: lantern-grammar
Version: 0.3.0
Summary: Authoritative semantic model for Lantern governed workflow
License-Expression: Apache-2.0
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: black==24.1.1; extra == "dev"
Requires-Dist: coverage==7.6.10; extra == "dev"
Requires-Dist: mypy==1.14.1; extra == "dev"
Requires-Dist: pylint==3.3.4; extra == "dev"
Requires-Dist: pytest==8.3.4; extra == "dev"
Requires-Dist: ruff==0.1.13; extra == "dev"
Requires-Dist: tomli==2.0.1; extra == "dev"
Provides-Extra: release
Requires-Dist: build==1.2.2.post1; extra == "release"
Requires-Dist: cyclonedx-bom==4.1.1; extra == "release"
Requires-Dist: twine==6.0.1; extra == "release"
Dynamic: license-file

# Lantern Grammar

**The authoritative language of governed development.**

Lantern Grammar defines the authoritative semantics of artifacts, gates, statuses, and relations used across the Lantern governed-workflow surface. It is expressed as an ECT-conforming model artifact set and evolves through structured change control.

## What it defines

- **Artifact classes** — the recognized artifact kinds in the workflow (CH, CI, DB, DC, DIP, SPEC, ARCH, TD, Initiative, Issue, Question, EV, DEC)
- **Gate entities** — the named semantic checkpoints (GT-030 through GT-130) and their input dependencies
- **Status values** — the lifecycle states artifacts may occupy
- **Relation types** — `requires_input`, `requires_evidence`, `requires_status`, `decomposes_to`
- **Vocabulary terms** — canonical definitions for each artifact and status class

## Repository layout

```
model/
  manifest.json       model identity and namespace declaration
  index.json          flat index of all objects with locators
  objects/
    Entity/           entity objects (artifacts, gates, statuses, relation types)
    Relation/         relation instances encoding the semantic dependency graph
    Term/             vocabulary term definitions
docs/
  gates/GATES.md      non-authoritative semantic summary of gate definitions
```

## Authoritative semantics

The ECT-conforming JSON objects under `model/` are the model truth. `docs/` content is documentation only and is not model truth.

---

## Python package

The `lantern-grammar` Python package exposes the model above through a
stable, read-only `Grammar` API.  Consumers should use this API rather than
parsing the `model/` JSON files directly.

### Requirements

- Python ≥ 3.11

### Installation

```bash
# Install from the repository (editable, for development)
pip install -e .

# Install a released distribution
pip install lantern-grammar
```

### Basic usage

```python
from lantern_grammar import Grammar, LanternGrammarLoadError

# Load the model bundled with the installed distribution
grammar = Grammar.load()

# Inspect manifest / version
manifest = grammar.manifest()
print(manifest["model_id"])       # "lantern-grammar.model"
print(manifest["model_version"])  # "0.3.0"
print(grammar.package_version())   # "0.3.0" on the first published package release

# Validate before using in CI / tooling
report = grammar.validate_integrity()
if not report["ok"]:
    raise RuntimeError(f"Lantern Grammar invalid: {report['errors']}")

# Resolve a model entity
ch = grammar.get_entity("lg:artifacts/ch")
print(ch["definition"])

# Iterate all gates
for gate in grammar.iter_entities(prefix="lg:gates/", status="Released"):
    print(gate["id"], "-", gate["definition"][:60])

# Query what GT-115 requires as inputs
deps = grammar.gate_dependencies("lg:gates/gt_115")
print("GT-115 requires inputs:", deps["requires_input"])
print("GT-115 requires statuses:", deps["requires_status"])

# Find all relations from GT-120
rels = list(grammar.find_relations(source_entity_id="lg:gates/gt_120"))
for r in rels:
    print(r["relation_type_id"], "->", r["target_entity_id"])

# Term lookup
term = grammar.get_term("lg:vocab/term_ch")
if term:
    print(term["definition"])  # "Canonical term for Change Intent (CH)."
```

### Loading from an explicit directory

For local validation, development fixtures, or consumer smoke tests:

```python
from pathlib import Path
from lantern_grammar import Grammar, LanternGrammarLoadError

try:
    grammar = Grammar.from_directory(Path("path/to/lantern-grammar/model"))
except FileNotFoundError:
    print("directory not found")
except LanternGrammarLoadError as exc:
    print(f"model invalid: {exc}")
```

### Authority boundary

The `Grammar` API is a **read-only projection** over the authoritative
`model/` artifacts.  It does not invent or reinterpret model meaning.

What it provides:
- model entities (artifacts, gates, statuses, relation types, record classes)
- model relations
- vocabulary terms
- manifest / version metadata
- integrity validation
- gate-dependency queries

What stays outside this package:
- workbench IDs and entry/exit policy
- intent classification
- runtime posture and stage resolution
- workflow resource grouping
- guided execution logic

### Running the tests

```bash
pip install -e ".[dev]"
pytest
```

### Release readiness

The authoritative Python package version source is `[project].version` in `pyproject.toml`.
The authoritative semantic model version source remains `model/manifest.json` via `model_version`.

For the first published `lantern-grammar` package release, keep those two values equal.
The current release baseline is package `0.3.0` and model `0.3.0`.
After the first package release, any divergence between package and model versions must follow the governance rules in `DN-LGR-PROP-003`.

Run the same checks locally that the main CI release lane enforces:

```bash
pip install -e ".[dev,release]"
python scripts/check_version_alignment.py --require-package-model-equality
pylint --fail-under=7.5 src/lantern_grammar/
ruff check src/lantern_grammar/ tests/ scripts/ setup.py
mypy src/lantern_grammar/
black --check src/lantern_grammar/ tests/ scripts/ setup.py
python scripts/check_license_headers.py
coverage run -m pytest --maxfail=1 -q
coverage report
python -m build
python -m twine check dist/*

python -m venv .venv-smoke
. .venv-smoke/bin/activate
python -m pip install --upgrade pip
python -m pip install dist/*.whl
python scripts/smoke_test_installed_package.py \
    --expected-package-version "$(python scripts/check_version_alignment.py --print-package-version)" \
    --expected-model-version "$(python scripts/check_version_alignment.py --print-model-version)"
python scripts/generate_license_report.py --output artifacts/license-report.json
deactivate
python scripts/generate_sbom.py --python .venv-smoke/bin/python --output artifacts/sbom.cyclonedx.json
```

This release boundary is intentionally stronger than `python -m build` alone:
the package must build, the installed wheel must be able to load the bundled model, the pinned toolchain must agree locally and in CI, and the release lane must emit SBOM and license-report artifacts.

### Publishing

The publish job consumes the exact `dist/` artifacts already built and verified earlier in CI; it does not rebuild on the publish step.

To release:

```bash
PACKAGE_VERSION="$(python scripts/check_version_alignment.py --print-package-version)"
git tag -a "v${PACKAGE_VERSION}" -m "lantern-grammar ${PACKAGE_VERSION}"
git push origin "v${PACKAGE_VERSION}"
```

The tagged GitHub Actions run will:
- re-run lint, typing, tests, build, `twine check`, and clean-environment smoke validation,
- upload `dist/*.whl`, `dist/*.tar.gz`, `artifacts/sbom.cyclonedx.json`, and `artifacts/license-report.json`, and
- publish the verified distributions to PyPI via GitHub OIDC trusted publishing.

Downstream consumers, including Lantern Runtime package closeout, should validate against the published `lantern-grammar` package boundary and the smoke path above rather than a sibling source checkout.

### Compatibility posture

The `Grammar` class and the methods documented above constitute the
**stability-governed public core** (`lantern_grammar` namespace).  Breaking
changes to this core require a major version increment.  Additive stable-core
changes may land in minor versions.

Experimental helpers, if any, live under `lantern_grammar.experimental` and
carry no compatibility guarantee until explicitly promoted into this
documentation.

## License

Lantern Grammar is released under the **Apache License 2.0**.

See [LICENSE](LICENSE) for the full license text.

**Copyright 2025 Lantern Authors**
