56 lines
3.7 KiB
Markdown
56 lines
3.7 KiB
Markdown
# CT.M1 — ContentValidationPipeline
|
||
|
||
## Summary
|
||
|
||
| Field | Value |
|
||
|--------|--------|
|
||
| **Module ID** | CT.M1 |
|
||
| **Track** | [Content tooling — internal authoring](../tooling/internal_authoring.md) (cross-cutting; not E1–E9) |
|
||
| **Stage target** | Prototype |
|
||
| **Status** | Planned (see [dependency register](module_dependency_register.md)) |
|
||
|
||
## Purpose
|
||
|
||
Own **content schema artifacts**, **automated validation** in CI and locally, and (when wired) **server-side smoke loading** so file-backed catalogs cannot drift from enforced contracts.
|
||
|
||
## Responsibilities
|
||
|
||
- Publish and version **JSON Schema** (or agreed equivalent) for catalogs consumed by **E2.M1**, **E3.M2–M3**, **E4.M1**, **E7.M1**.
|
||
- Run **structural** and **cross-reference** validation before merge; expose the same rules to **CT.M2**.
|
||
- Optional: **C#** deserialize test or boot check aligned with `ContentCatalogRegistry` (or successor).
|
||
|
||
## Key contracts
|
||
|
||
| Contract | Role |
|
||
|----------|------|
|
||
| Content schema files | `$id` + versioning per [contracts.md](contracts.md) |
|
||
| Validation CLI | Stable exit codes and machine-readable errors for CI and studio |
|
||
|
||
## Module dependencies
|
||
|
||
- **Soft:** Gameplay modules above must define or stabilize the **shapes** being validated; pipeline can ship **minimal** schemas first.
|
||
|
||
## Dependents (by design)
|
||
|
||
- **CT.M2** — AuthoringStudioApplication
|
||
- **CT.M3** — ContentReferenceAndBundleWorkflows
|
||
|
||
## Related implementation slices
|
||
|
||
Content tooling **Slice 1** — schemas + CI; **Slice 4** — server parity hardening.
|
||
|
||
## CI (prototype)
|
||
|
||
**Skill catalogs:** the repo **PR gate** workflow ([`.github/workflows/pr-gate.yml`](../../../.github/workflows/pr-gate.yml)) runs [`scripts/validate_content.py`](../../../scripts/validate_content.py) on every push and pull request. It validates each object in `content/skills/*.json` under the top-level `skills` array against [`content/schemas/skill-def.schema.json`](../../../content/schemas/skill-def.schema.json) (Python **jsonschema**, Draft 2020-12), rejects **duplicate `id`** across files, and (Slice 1 / [NEO-33](https://linear.app/neon-sprawl/issue/NEO-33)) enforces the **frozen prototype trio** ids plus **gather + tech + (process or make)** category coverage.
|
||
|
||
**Mastery catalogs ([NEO-45](https://linear.app/neon-sprawl/issue/NEO-45)):** the same script validates `content/mastery/*_mastery.json` against [`content/schemas/mastery-catalog.schema.json`](../../../content/schemas/mastery-catalog.schema.json), cross-checks track `skillId` against loaded `SkillDef` ids, rejects **duplicate `perkId`**, enforces **branch integrity** (tier branch sets match; `perkIds` reference defined perks), and (Slice 4) requires **exactly one** track for **`salvage`** only.
|
||
|
||
**Item catalogs ([NEO-50](https://linear.app/neon-sprawl/issue/NEO-50)):** the same script validates each row in `content/items/*_items.json` against [`content/schemas/item-def.schema.json`](../../../content/schemas/item-def.schema.json), rejects **duplicate `id`** across files, and (Slice 1) enforces the **frozen six-item** id set plus **exactly one row per `prototypeRole`** (`material` through `equip_stub`). Extend the script when additional catalogs and schemas ship.
|
||
|
||
**Decomposition vocabulary:** the same workflow runs [`scripts/check_decomposition_language.py`](../../../scripts/check_decomposition_language.py) (stdlib only) over `docs/decomposition/**/*.md` to catch wording that treats **combat** as a leveled **`SkillDef`** line instead of **gig** progression (see script docstring for patterns). Adjust the script if a future doc needs a documented exception.
|
||
|
||
## Source anchors
|
||
|
||
- Plan: [`internal-content-authoring.md`](../../plans/internal-content-authoring.md)
|
||
- [Module dependency register](module_dependency_register.md)
|