4.6 KiB
Code review — NEO-112 (E7M1-01)
Date: 2026-05-31
Scope: Branch NEO-112-e7m1-prototype-questdef-catalog-schemas-ci vs 47105cc (merge-base on main) — commits be1dae3 … 765075f
Base: 47105cc (main at branch point, post NEO-111 merge)
Verdict
Approve with nits
Summary
NEO-112 delivers the Epic 7 Slice 1 content foundation: three JSON Schemas (quest-def, quest-step-def, quest-objective-def), a four-row prototype_quests.json catalog aligned to the E7.M1 freeze table, and ~300 lines of CI gates in validate_content.py (four-id allowlist, acyclic prerequisites, item/recipe/encounter cross-refs, operator-chain terminal token gate, duplicate quest/step/objective ids). Documentation is thorough—implementation plan reconciliation, CT.M1 paragraph, content/README.md, alignment register, and the full E7M1 prototype backlog land together. No server, C#, or Godot changes (correct for E7M1-01). Risk is low: pattern mirrors NEO-100/NEO-87; happy-path validation passes locally.
Documentation checked
| Path | Result |
|---|---|
docs/plans/NEO-112-implementation-plan.md |
Matches — acceptance checklist checked; reconciliation section accurate. |
docs/plans/E7M1-prototype-backlog.md (E7M1-01) |
Matches — AC checked; scope/out-of-scope correct; client counterpart none. |
docs/decomposition/modules/E7_M1_QuestStateMachine.md |
Partially matches — freeze table and CI enforcement line match shipped gates; Status still says “implementation not started” though E7M1-01 catalog is landed. |
docs/decomposition/modules/CT_M1_ContentValidationPipeline.md |
Matches — quest catalog PR gate paragraph describes shipped validators. |
docs/decomposition/modules/documentation_and_implementation_alignment.md |
Matches — E7.M1 row notes NEO-112 catalog; register stays Planned until NEO-113. |
docs/decomposition/modules/module_dependency_register.md |
Partially matches — E7.M1 note added; “until NEO-112 lands” is stale (should reference NEO-113 server load, per alignment row). |
content/README.md |
Matches — quests/ table row + E7M1 prototype paragraph. |
docs/decomposition/epics/epic_07_quest_faction.md |
Matches — Slice 1 backlog link + Godot DoD clarification. |
| Full-stack epic decomposition | N/A — infrastructure-only story; no client counterpart required until NEO-122/NEO-123. |
Blocking issues
(none)
Suggestions
-
Refresh
module_dependency_register.mdE7.M1 note — Change “Register row stays Planned until NEO-112 lands” to “until NEO-113 server load lands” so it matchesdocumentation_and_implementation_alignment.mdafter this merge. -
Clarify E7.M1 module Status line — Replace “implementation not started” with wording that E7M1-01 catalog (NEO-112) is landed and runtime work starts at NEO-113.
Nits
-
Nit: E7M1 kickoff table row “Onboarding order: gather → refine → combat → chain” oversimplifies prerequisites —
prototype_quest_combat_introhas no prereq (parallel path); freeze table and catalog are correct. -
Nit:
quest-objective-def.schema.jsonlists all kind-specific fields inpropertiesplusoneOfbranches, so schema validation may accept wrong-field-at-wrong-kind (e.g.recipeIdonencounter_complete) if both are present — plan adopted this tradeoff; CI cross-ref gate still catches unknown ids. -
Nit: Duplicate step/objective ids are enforced within a quest only, not globally across quests — acceptable for prototype; E7M1-04 HTTP projection should namespace by quest id.
-
Nit: Branch bundles the full E7M1 backlog decomposition (~390 lines) with E7M1-01 implementation — large diff but intentional and documented.
Verification
# Happy path (primary regression signal — also runs in pr-gate.yml)
python3 -m pip install -r scripts/requirements-content.txt
python3 scripts/validate_content.py
# Manual negative cases (from NEO-112 plan)
# 1. Duplicate quest id across or within files → non-zero exit
# 2. Remove a frozen quest id from catalog → four-id gate error
# 3. Unknown itemId/recipeId/encounterId in objective → cross-ref error
# 4. Cyclic prerequisiteQuestIds → prerequisite gate error
# 5. Unknown prerequisite id → prerequisite gate error
# 6. Chain terminal step not inventory_has_item contract_handoff_token ×1 → chain gate error
# 7. Invalid kind or missing required field per kind → schema error
Reviewer note: Happy path executed successfully in review environment (content OK … 4 unique quest id(s)).