Topdata Migration (#2)
Native topdata migration summary - Replaced the legacy 2dabuilder runtime path with the native topdata builder. - Native build, validate, compare, and convert flows now cover the canonical topdata pipeline. - compare-topdata is now a native self-check; legacy reference-builder runtime usage was removed. - Parts generation follows the native asset-scan contract and uses sow-assets via project asset resolution. - Generated feat families, class-feat injects, masterfeat/successor expansion, and dataset-derived feat generation were brought to parity and regression-covered. - Remaining mirrored datasets were migrated into native-owned canonical data while preserving lock IDs. - normalize-topdata bridge behavior and migration-era ownership markers were removed. - Documentation was rewritten around the native workflow and active contracts were cleaned up. - Final hardening pass removed stale validator assumptions and cleaned ignored/generated artifacts for PR readiness. Reviewed-on: https://gitea.westgate.pw/ShadowsOverWestgate/sow-tools/pulls/2 Co-authored-by: vickydotbat <vickydotbat@tutamail.com> Co-committed-by: vickydotbat <vickydotbat@tutamail.com>
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
# Global Feat Injection — Specification
|
||||
|
||||
## Objective
|
||||
|
||||
Ensure the native class feat generation pipeline produces **functionally identical output** to the legacy system by applying deterministic global feat injections.
|
||||
|
||||
---
|
||||
|
||||
## Requirements
|
||||
|
||||
### R1 — Skill-based master feats
|
||||
|
||||
For every **class skill**, inject:
|
||||
|
||||
- `masterfeats:skillfocus`
|
||||
- `masterfeats:greaterskillfocus`
|
||||
|
||||
With properties:
|
||||
|
||||
````json
|
||||
{
|
||||
"GrantedOnLevel": "-1",
|
||||
"List": "1",
|
||||
"OnMenu": "0"
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
### R2 — Spellcasting master feats
|
||||
|
||||
If class core defines:
|
||||
|
||||
- `"SpellCaster" = 1`
|
||||
|
||||
Then inject:
|
||||
|
||||
- `masterfeats:spellfocus`
|
||||
- `masterfeats:greaterspellfocus`
|
||||
|
||||
With properties:
|
||||
|
||||
```json
|
||||
{
|
||||
"GrantedOnLevel": "-1",
|
||||
"List": "1",
|
||||
"OnMenu": "0"
|
||||
}
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
### R3 — Literacy rule
|
||||
|
||||
Inject:
|
||||
|
||||
- `feat:literate`
|
||||
|
||||
**Only if**:
|
||||
|
||||
- `feat:illiterate` is NOT present
|
||||
|
||||
With properties:
|
||||
|
||||
```json
|
||||
{
|
||||
"GrantedOnLevel": "1",
|
||||
"List": "3",
|
||||
"OnMenu": "0"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### R4 — Default combat/menu feats
|
||||
|
||||
Always inject:
|
||||
|
||||
- `feat:offensivefighting`
|
||||
- `feat:defensivefighting`
|
||||
- `feat:horsemenu`
|
||||
|
||||
With properties:
|
||||
|
||||
```json
|
||||
{
|
||||
"GrantedOnLevel": "1",
|
||||
"List": "3",
|
||||
"OnMenu": "1"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### R5 — Conditional combat feats
|
||||
|
||||
Inject:
|
||||
|
||||
- `feat:powerattack`
|
||||
- `feat:combatexpertise`
|
||||
|
||||
With properties:
|
||||
|
||||
```json
|
||||
{
|
||||
"GrantedOnLevel": "-1",
|
||||
"List": "0",
|
||||
"OnMenu": "1"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### R6 — Override precedence
|
||||
|
||||
- Overrides MUST be applied after injection.
|
||||
- Overrides MUST take precedence over injected defaults.
|
||||
- Injection MUST NOT block or replace explicit override data.
|
||||
|
||||
---
|
||||
|
||||
## Behavioral Rules
|
||||
|
||||
### B1 — Output equivalence
|
||||
|
||||
- The resulting feat set MUST match legacy output **in substance**.
|
||||
- Exact row ordering and numeric IDs are NOT significant.
|
||||
|
||||
### B2 — Deterministic inclusion
|
||||
|
||||
- All injections MUST occur consistently for identical inputs.
|
||||
- No randomness or order-dependent behavior is allowed.
|
||||
|
||||
### B3 — Conditional correctness
|
||||
|
||||
- `feat:literate` MUST NOT be injected if `feat:illiterate` exists.
|
||||
- Spell focus feats MUST ONLY be injected when `"SpellCaster" = 1`.
|
||||
|
||||
### B4 — Integration with pipeline
|
||||
|
||||
- Injected feats MUST flow through the same processing stages as authored feats.
|
||||
- They MUST be subject to:
|
||||
- overrides
|
||||
- deduplication
|
||||
- final emission rules
|
||||
|
||||
---
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
An implementation is considered correct if:
|
||||
|
||||
1. **Parity**
|
||||
- For any given class input, native output produces the same effective feats as legacy.
|
||||
|
||||
2. **Injection coverage**
|
||||
- All required feats (R1–R5) appear when conditions are met.
|
||||
|
||||
3. **Exclusion correctness**
|
||||
- No invalid injections occur (e.g., literacy conflict).
|
||||
|
||||
4. **Override dominance**
|
||||
- Any override affecting injected feats is correctly applied.
|
||||
|
||||
5. **Stability**
|
||||
- Repeated runs with identical input produce identical output.
|
||||
|
||||
---
|
||||
|
||||
## Non-Negotiables
|
||||
|
||||
- This is **parity-critical**, not a best-effort feature.
|
||||
- Native pipeline MUST be capable of fully replacing legacy output.
|
||||
- There MUST be **zero dependency** on legacy systems at runtime.
|
||||
- Any deviation from legacy-equivalent output is a **defect**.
|
||||
Reference in New Issue
Block a user