Files
sow-tools/internal/topdata/CLASS_FEAT_GLOBAL_INJECTS_CONTRACT.md
T

2.4 KiB

Class Feat Global Injection Contract

Status Snapshot

Current state as of 2026-06-05:

  • Preferred class feat injection policy is authored in topdata/data/classes/feats/global.json.
  • global.json rows flow through the ordinary class feat expansion pipeline, including successor expansion, masterfeat expansion, class-skill filtering, reference resolution, deduplication, and final 2DA emission.
  • Legacy topdata.class_feat_injections YAML still loads only as a compatibility path when no applicable class feat global.json exists.
  • Toolkit hardcoded defaults are compatibility-only and must not be the normal source of project policy.

Objective

Native class feat generation must produce deterministic, legacy-equivalent effective output while keeping project policy in topdata authoring files.

Requirements

  • For each class skill, inject the configured skill-focus masterfeat rows from classes/feats/global.json using FeatIndex.filter = "classskills".
  • Inject feat:literate only when the class table does not already include feat:illiterate.
  • Inject the shared combat/menu feat rows declared in the manifest unless a class already authors the equivalent FeatIndex.
  • Explicit class feat rows take precedence over injected rows.
  • Injections must be deterministic for identical inputs.

Manifest Shape

{
  "position": "prepend",
  "injections": [
    {
      "row": {
        "FeatIndex": { "id": "feat:literate" },
        "GrantedOnLevel": 1,
        "List": 3,
        "OnMenu": 0
      },
      "unless_present": [
        { "field": "FeatIndex", "id": "feat:illiterate" }
      ]
    },
    {
      "row": {
        "FeatIndex": {
          "id": "masterfeats:skill_focus",
          "filter": "classskills"
        },
        "GrantedOnLevel": -1,
        "List": 1,
        "OnMenu": 0
      }
    }
  ]
}

position defaults to append. The module uses prepend for class feat injections to keep generated policy rows before per-class authored rows.

Acceptance Criteria

  • Class feat output contains the same effective shared feats as the prior YAML policy.
  • Literacy injection is skipped for illiterate classes.
  • Skill-focus masterfeat rows expand only for class skills.
  • YAML compatibility continues to work for consumers that have not migrated.
  • A project with classes/feats/global.json does not also receive YAML or hardcoded default class feat injections.