From 66150ea2242ffc3d06d0c36ed0a4f0ce2d6676ed Mon Sep 17 00:00:00 2001 From: VinPropane Date: Sat, 2 May 2026 19:21:20 -0400 Subject: [PATCH] NEO-33: Add implementation plan after kickoff clarifications --- docs/plans/NEO-33-implementation-plan.md | 83 ++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 docs/plans/NEO-33-implementation-plan.md diff --git a/docs/plans/NEO-33-implementation-plan.md b/docs/plans/NEO-33-implementation-plan.md new file mode 100644 index 0000000..ba2f7ad --- /dev/null +++ b/docs/plans/NEO-33-implementation-plan.md @@ -0,0 +1,83 @@ +# NEO-33 — Implementation plan + +## Story reference + +| Field | Value | +|--------|--------| +| **Key** | NEO-33 | +| **Title** | E2.M1: Lock prototype SkillDef trio + CI catalog contract | +| **Linear** | https://linear.app/neon-sprawl/issue/NEO-33/e2m1-lock-prototype-skilldef-trio-ci-catalog-contract | + +## Kickoff clarifications + +| Topic | Question | Answer | +|--------|------------|--------| +| Prototype `SkillDef.id` freeze | Lock **salvage**, **refine**, **intrusion** (gather + process + tech)? | **Yes** — freeze these three ids as-is. | +| Designer note placement | Where should the short note on `allowedXpSourceKinds` + grant call sites live? | **Both** — brief pointer in `content/README.md`, fuller text in `docs/decomposition/modules/E2_M1_SkillDefinitionRegistry.md`. | +| `allowedXpSourceKinds` meaning | (User asked in chat.) | Explained in session: per-skill allowlist for XP grant channels (`activity`, `mission_reward`, `trainer`, `book_or_item`); E2.M2 rejects grants outside the set; combat encounter XP stays on gigs, not skills. | + +## Goal, scope, and out-of-scope + +**Goal:** Treat the repo as the source of truth for the **Slice 1 prototype skill catalog**: exactly **three** non-combat `SkillDef` rows covering **gather**, **process** (or make), and **tech**, with stable **`id`** values, validated on every PR against `content/schemas/skill-def.schema.json`, and documented for designers and downstream issues (NEO-34+). + +**In scope (from Linear):** + +- Align `content/skills/prototype_skills.json` (and schema only if contract gaps appear) with [`docs/game-design/skills.md`](../../game-design/skills.md) prototype trio policy (one Gather, one Process/Make, one Tech). +- Confirm [`.github/workflows/pr-gate.yml`](../../.github/workflows/pr-gate.yml) runs [`scripts/validate_content.py`](../../scripts/validate_content.py); close small gaps if any (e.g. clearer validation errors, doc pointers). +- Short designer note (**README + E2.M1** per kickoff): each row **must** declare non-empty `allowedXpSourceKinds` and what each kind implies for grant call sites. +- Call out the **frozen** `id` list in-repo for downstream references (E2.M2, E3, quests). + +**Out of scope (from Linear):** + +- Server runtime catalog load (NEO-34+). +- XP grant implementation (E2.M2 / NEO follow-ups). + +## Acceptance criteria checklist + +- [ ] PR / CI fails on invalid catalog rows, schema mismatch, or **duplicate** skill `id` across `content/skills/*.json`. +- [ ] Exactly **three** prototype skills with category coverage **gather** + **process** (or make) + **tech**; **`id`** values **salvage**, **refine**, **intrusion** recorded as **stable / frozen** in decomposition or authoring docs. +- [ ] CT.M1 and E2.M1 doc pointers remain accurate relative to what ships in this story. +- [ ] Designer-facing note on `allowedXpSourceKinds` appears in **`content/README.md`** (brief) and **`E2_M1_SkillDefinitionRegistry.md`** (detail). + +## Technical approach + +1. **Catalog:** Keep `content/skills/prototype_skills.json` as the single skills JSON under `content/skills/` for the prototype trio (already matches gather / process / tech). Adjust rows or schema only if validation or design review finds drift from `skills.md` policy. +2. **CI:** Rely on existing `validate_content.py` + PR gate; optionally tighten messages or add explicit checks (e.g. total distinct `id` count equals three for Slice 1) if product wants fail-fast on accidental extra files—only if agreed during implementation without scope creep. +3. **Docs:** Update **E2.M1** with a **Prototype Slice 1 freeze** subsection: frozen ids, category coverage, and a **grant channels** subsection expanding `allowedXpSourceKinds` for designers (link to schema enum). Update **content/README.md** with a short pointer to that section and a one-line “do not rename ids” reminder. +4. **Cross-doc:** Update `skills.md` “Next pass” / prototype language so it points at the **locked** ids (no longer an open pick). Refresh [`documentation_and_implementation_alignment.md`](../decomposition/modules/documentation_and_implementation_alignment.md) E2.M1 row if it still implies NEO-33 work is only backlog. +5. **No application server or C# changes** in this story unless an unexpected coupling appears (unlikely). + +## Files to add + +| Path | Purpose | +|------|---------| +| **None** | All contracts and catalogs already exist; this story is documentation alignment, optional validation tightening, and explicit freeze callouts—not new modules. | + +## Files to modify + +| Path | Rationale | +|------|------------| +| `docs/decomposition/modules/E2_M1_SkillDefinitionRegistry.md` | Add frozen trio + designer-oriented `allowedXpSourceKinds` / grant call-site guidance (canonical). | +| `content/README.md` | Brief pointer to E2.M1 detail and freeze reminder for content authors. | +| `docs/game-design/skills.md` | Point “prototype trio” at locked ids so design doc matches data. | +| `docs/decomposition/modules/documentation_and_implementation_alignment.md` | Update E2.M1 / NEO-33 row to match shipped state after implementation. | +| `scripts/validate_content.py` | Only if a concrete gap appears (clearer errors, optional Slice-1 count guard); default is leave as-is if CI already satisfies acceptance. | + +## Tests + +| Item | Coverage | +|------|----------| +| **Automated** | Existing **PR gate** job runs `python scripts/validate_content.py` — primary regression signal for schema + duplicate `id`. No dedicated pytest module exists in-repo today; introducing one is **optional** and not required for NEO-33 acceptance if CI + local script remain the contract. | +| **Manual** | Run `pip install -r scripts/requirements-content.txt && python scripts/validate_content.py` locally after doc/catalog edits; skim PR gate workflow in GitHub on the story PR. | + +## Open questions / risks + +- **Extra skill JSON files:** If someone adds another `content/skills/*.json` before process is agreed, total skill count could exceed three without failing today—mitigation is optional validation or team convention; note if we add a hard “exactly three ids” check. +- **None** otherwise at kickoff. + +## Decisions + +| Decision | Rationale | +|----------|------------| +| Frozen ids **salvage**, **refine**, **intrusion** | User confirmation during kickoff. | +| Designer note in **README + E2.M1** | User picked option **3**. |