topdata: stop hardcoding the skills dataset location (#43)
test / test (push) Successful in 1m24s
build-binaries / build-binaries (push) Successful in 2m8s

sow-topdata moved skills into a tree (skills/core, skills/specs, skillcats, skillspecranks), which broke validate/build: the generated feat families hardcoded dataset "skills".

Resolution is now data-driven: the family spec's child_source names the dataset, child slugs come from the row key's own namespace, and the wiki loader accepts both the flat and tree layouts (topdata main still uses the flat one until the overhaul merges).

Verified against the skill-grouping-overhaul topdata branch: validate/build/wiki all clean with zero lock churn, focus feats stay on their adopted rows.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Reviewed-on: #43
Co-authored-by: vickydotbat <vickydotbat@tutamail.com>
Co-committed-by: vickydotbat <vickydotbat@tutamail.com>
This commit was merged in pull request #43.
This commit is contained in:
2026-07-19 07:33:19 +00:00
committed by archvillainette
parent 24e57457b0
commit bc8fa3a6fe
3 changed files with 35 additions and 13 deletions
+9 -4
View File
@@ -1867,8 +1867,10 @@ func validateGeneratedFeatFamilies(dataDir string, report *ValidationReport) {
}
required := []requiredFeatFamily{
{FamilyKey: "skillfocus", Dataset: "skills", Predicate: "accessible"},
{FamilyKey: "greaterskillfocus", Dataset: "skills", Predicate: "accessible"},
// skill families: the source dataset is data-driven (family spec), only
// the accessibility predicate is required
{FamilyKey: "skillfocus", Predicate: "accessible"},
{FamilyKey: "greaterskillfocus", Predicate: "accessible"},
{FamilyKey: "weaponfocus", Dataset: "baseitems", Column: "WeaponFocusFeat"},
{FamilyKey: "weaponspecialization", Dataset: "baseitems", Column: "WeaponSpecializationFeat"},
{FamilyKey: "improvedcritical", Dataset: "baseitems", Column: "WeaponImprovedCriticalFeat"},
@@ -1882,7 +1884,7 @@ func validateGeneratedFeatFamilies(dataDir string, report *ValidationReport) {
if !ok {
continue
}
if spec.ChildSource.Dataset != requirement.Dataset ||
if (requirement.Dataset != "" && spec.ChildSource.Dataset != requirement.Dataset) ||
spec.ChildSource.Column != requirement.Column ||
spec.ChildSource.Predicate != requirement.Predicate {
report.Diagnostics = append(report.Diagnostics, Diagnostic{
@@ -2081,7 +2083,10 @@ func validateGeneratedFeatFamilyCompleteness(path string, spec familyExpansionSp
}
if include {
if familyAllowlist {
slug := strings.TrimPrefix(sourceKey, spec.ChildSource.Dataset+":")
slug := sourceKey
if idx := strings.Index(slug, ":"); idx >= 0 {
slug = slug[idx+1:]
}
featKey, _, _, err := ctx.resolveGeneratedFeatIdentity(spec, slug, row)
if err != nil {
report.Diagnostics = append(report.Diagnostics, Diagnostic{