Commit Graph
70 Commits
Author SHA1 Message Date
archvillainetteandClaude Fable 5 3ab770639c topdata: remove completed legacy-migration cluster
build-binaries / build-binaries (pull_request) Successful in 2m4s
test / test (pull_request) Successful in 1m18s
The one-time legacy normalize migration finished; NormalizeProject had no
production callers. Delete migrate.go, the 26 *_migrate.go files, the
importLegacyItempropsRegistry cluster, loadLegacyTLK, and the 48 test
blocks that only exercised them. mergeLegacyTLK moves to tlk_native.go
because the live TLK compiler still uses it for base_dialog.json.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 10:03:31 +02:00
archvillainette bc8fa3a6fe 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>
2026-07-19 07:33:19 +00:00
archvillainette 24e57457b0 topdata: legacy aliases for skill-grouping renames (#42)
test / test (push) Successful in 1m27s
build-binaries / build-binaries (push) Successful in 2m11s
Extends legacyFamilyChildAliases so skill focus / greater skill focus children adopt the stock feat rows of the skills they were renamed from: medicine<-heal, investigation<-search, diplomacy<-influence/persuade, security<-open lock, intimidate<-taunt.

Existing craft_*/influence/disabledevice aliases stay: sow-topdata main still carries those skills until the overhaul merges. Needs a Crucible release before sow-topdata CI picks this up.

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

Reviewed-on: #42
Reviewed-by: xtul <mpiasecki720@protonmail.com>
Co-authored-by: vickydotbat <vickydotbat@tutamail.com>
Co-committed-by: vickydotbat <vickydotbat@tutamail.com>
2026-07-19 00:20:04 +00:00
gitea-botandarchvillainette e9860c12c6 fix(topdata): encode spell radial feat IDs (#37)
test / test (push) Successful in 1m21s
build-binaries / build-binaries (push) Successful in 2m3s
build-image / publish (push) Successful in 13s
## Summary
- add explicit `{"spellradial": {"id": "feat:key"}}` authoring syntax for `spells.2da` `FeatID`
- resolve spell and feat rows dynamically and emit NWN:EE packed subradial values
- reject malformed or misplaced spell-radial references

## Verification
- `go test ./internal/topdata`

Co-authored-by: vickydotbat <vickydotbat@tutamail.com>
Reviewed-on: #37
Reviewed-by: archvillainette <vickydotbat@tutamail.com>
Reviewed-by: xtul <mpiasecki720@protonmail.com>
Co-authored-by: gitea-bot <gitea-bot@noreply.git.westgate.pw>
Co-committed-by: gitea-bot <gitea-bot@noreply.git.westgate.pw>
2026-07-11 15:10:10 +00:00
archvillainette 06e5893734 feat(topdata): parts autogen from CDN part.yml channel (Phase 2) (#25)
test / test (push) Successful in 1m26s
build-binaries / build-binaries (push) Successful in 2m12s
build-image / publish (push) Successful in 38s
Phase 2 of the parts-row autogen design — Crucible (sow-tools) side only.

Resolves parts 2DA rows from the immutable \`part.yml\` published with the asset HAK release, over the anonymous Bunny CDN channel, with the parts consumer **required** (no fail-open).

## Changes
- **Resolver (T3):** generalize \`resolveCDNChannelManifest\` — derive manifest basename + provenance label from config; drop hardcoded \`assets/vfxs.yml\` so \`part.yml\` resolves through the same path. VFX behavior unchanged.
- **Parts filter (T4):** \`filterCDNChannelEntries\` dispatches on consumer mode; new \`filterPartsCDNChannelEntries\` implements the inventory contract — \`restype: mdl\` under \`part/<supported-cat>/\`, row id from trailing digits, dedup l/r/race/gender variants by (category,rowID), sort by source, **zero accepted rows = hard fail**, reject row id 0 / non-numeric / malformed / no-assets.
- **Category (T5):** add \`hand\` + \`parts/hand\` mapping (12 datasets; \`leg→legs\` already present).
- **Pipeline (T6):** native build runs one explicit augment → normalize → override sequence under the configured \`parts_rows\` policy; overrides may update an existing/discovered row but **never synthesize** one (orphan override now errors).
- **Validation (T7):** reject more than one \`parts_rows\` consumer.

## Tests
9 new tests: parts filter contract, 12-dataset coverage, offline manifest-basename, orphan-override reject + discovered-row update, and a parity guard proving a bare CDN-only parts build needs no wrapper/token/NWN_ROOT/checkout.

Gate green: \`go test ./internal/topdata/... ./internal/project/...\` + full \`go build ./... && go test ./...\`.

## Scope / ordering
Phase 2 is inert until **Phase 1** (sow-assets-manifest publishes \`part.yml\`) ships and the operational **Gate** (release publish/promote) runs, then **Phase 3** enables the sow-topdata consumer. Do not enable the consumer against a channel whose current release predates \`part.yml\`.

Plan: \`sow-topdata/docs/superpowers/plans/2026-06-25-topdata-parts-autogen-channel.md\`

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

Reviewed-on: #25
Co-authored-by: vickydotbat <vickydotbat@tutamail.com>
Co-committed-by: vickydotbat <vickydotbat@tutamail.com>
2026-06-26 12:12:06 +00:00
archvillainette 332a24fd3e stricter topdata validation (#24)
test / test (push) Successful in 1m23s
build-binaries / build-binaries (push) Successful in 2m13s
build-image / publish (push) Successful in 39s
makes topdata json validation much stricter, currently still too permissive

Reviewed-on: #24
Reviewed-by: xtul <mpiasecki720@protonmail.com>
Co-authored-by: vickydotbat <vickydotbat@tutamail.com>
Co-committed-by: vickydotbat <vickydotbat@tutamail.com>
2026-06-25 21:49:03 +00:00
archvillainette 16d5586587 Crucible: Fix Formatting Churn (#5)
test-image / build-image (push) Successful in 43s
test / test (push) Successful in 1m21s
build-binaries / build-binaries (push) Successful in 2m2s
build-image / publish (push) Successful in 13s
RC#1 — build wrote 2-space instead of .editorconfig's 4-space
- editorconfig_format.go: the glob translator escaped {/} as literals, so [*.{json,jsonc}]→indent_size=4 never matched any file and formatting fell back to [*]→2. Implemented real editorconfig brace expansion — {a,b,c} alternation and {n..m} numeric ranges. Nothing is hardcoded; saveLockfile already read .editorconfig, it just got the wrong section.

RC#2 — validate wrote a lockfile (it must be read-only)
- The three registry collectors persisted lockfiles as a side effect of collection; ValidateProject calls collection outside its snapshot guard, so the write leaked. Threaded a persistLocks bool through collectGeneratedRegistryDatasets and the damagetypes/itemprops/racialtypes collectors. Only buildNativeUnchecked (the real build allocator) passes true; validate, discovery, packaging queries, and wiki discovery pass false.

Tests added: editorconfig_glob_test.go (brace match + 4-space via brace glob), registry_readonly_test.go (read-only writes nothing; persist writes allocations).

Reviewed-on: #5
Co-authored-by: vickydotbat <vickydotbat@tutamail.com>
Co-committed-by: vickydotbat <vickydotbat@tutamail.com>
2026-06-17 07:57:54 +00:00
archvillainette 56c67132f3 claude: fold in old sow-tools 2026-06-13 09:49:29 +02:00
archvillainette 97f8427c4b Phase 5: scaffold Crucible (sow-tools) — dispatcher + builder shims, container, PR-first CI, fail-closed (D11, D19). 2026-06-11 20:36:13 +02:00
archvillainette 55322dc7bf Respect editorconfig formatting 2026-06-06 16:21:38 +02:00
archvillainette dfdc47c2dc Global json adjustments 2026-06-05 16:35:14 +02:00
archvillainette c672a1ff33 Support for global.json files 2026-06-05 10:36:47 +02:00
archvillainette 67c03fa6bd Fix alignment/ids output 2026-05-31 08:17:41 +02:00
archvillainette c7dc81b80f Fixed plain datasets generating lock ids when not necessary 2026-05-27 23:51:49 +02:00
archvillainette 88be9e95d3 Automatic spellknown/spellgain null-filling (#12)
Implemented on branches `feature/topdata-row-extensions` in both `toolkit` and `module`.

**Scope Audited**
- Toolkit native topdata collection/build path.
- Project config/effective config validation.
- Module `nwn-tool.yaml` topdata config and topdata README.

**Changes Made**
- Added `topdata.row_extensions` config with `repeat_last` support.
- Added glob dataset matching and build-time row extension for plain native datasets in [native.go](/home/vicky/Projects/nwnee-shadowsoverwestgate/toolkit/internal/topdata/native.go:641).
- Extension copies emitted columns from the highest authored `Level`, increments `Level`, and assigns sequential `id`s through target level.
- Enabled rules for `classes/spellsgained/*` and `classes/spellsknown/*` to level 60 in [nwn-tool.yaml](/home/vicky/Projects/nwnee-shadowsoverwestgate/module/nwn-tool.yaml:90).
- Updated toolkit/module docs.

**Configuration / Compatibility**
- New public config type: `TopDataRowExtensionConfig` in [project.go](/home/vicky/Projects/nwnee-shadowsoverwestgate/toolkit/internal/project/project.go:233).
- Existing behavior is unchanged unless a repo opts into `topdata.row_extensions`.
- Source JSON and lockfiles are not updated for generated extension rows.

**Tests / Validation**
- Added project config tests for loading and validation.
- Added native topdata tests for extension behavior, glob application, preserving manually authored rows, unmatched datasets, and failure cases.
- Ran:
  - `go test ./internal/project ./internal/topdata`
  - `go test ./internal/topdata -run TestBuildNativeKeepsGeneratedIDsStableAcrossRepeatedBuilds`
  - `/tmp/sow-toolkit-rowext config validate` in `module`
  - `/tmp/sow-toolkit-rowext validate-topdata` in `module`
  - `/tmp/sow-toolkit-rowext build-topdata --force`, then inspected generated rows: `cls_spgn_acolyte.2da` now reaches row `59` / level `60`.

**Remaining Notes**
- `validate-topdata` still reports the pre-existing portrait lock warnings for `cotbl/cotbl_` and `lantern/lantern_`.
- `build-topdata --force` briefly rewrote three spellbook JSON files as a side effect; I reverted those, leaving only the intended YAML/docs changes in `module`.

Reviewed-on: https://gitea.westgate.pw/ShadowsOverWestgate/sow-tools/pulls/12
Co-authored-by: vickydotbat <vickydotbat@tutamail.com>
Co-committed-by: vickydotbat <vickydotbat@tutamail.com>
2026-05-26 19:54:48 +02:00
archvillainette 16ed4fe47d Spellbook lists 2026-05-26 18:25:58 +02:00
archvillainette c5a18df730 Sidecar generation 2026-05-26 16:11:45 +02:00
archvillainette 28d487565a Fix alignment/id encoding 2026-05-26 14:18:04 +02:00
archvillainette 22e3fabbbb ID List Support expansion
**Scope Audited**
- Topdata configured value encoders in [native.go](/home/vicky/Projects/nwnee-shadowsoverwestgate/toolkit/internal/topdata/native.go:3894)
- Config validation in [project.go](/home/vicky/Projects/nwnee-shadowsoverwestgate/toolkit/internal/project/project.go:799)
- Wiki alignment formatting
- Module topdata config/docs and authored `PreferredAlignments` / `ProficiencyFeats` files

**Changes Made**
- Added generic `id_hex_list` support. It works for any configured dataset/column and emits packed hex row IDs from `ids`.
- Updated alignment encoding to accept explicit `alignments`; legacy `list` still works.
- Kept numeric packed lists on `list` / `all_except`.
- Configured `baseitems.ProficiencyFeats` in [nwn-tool.yaml](/home/vicky/Projects/nwnee-shadowsoverwestgate/module/nwn-tool.yaml:73).
- Migrated module proficiency authoring to `ids` and racial alignment authoring to `alignments`.
- Updated docs in [module/topdata/README.md](/home/vicky/Projects/nwnee-shadowsoverwestgate/module/topdata/README.md:157).

**Configuration / Schema Impact**
- New `topdata.value_encodings[].mode`: `id_hex_list`.
- `id_hex_list` accepts:
  - `"feat:some_key"`
  - `{ "id": "feat:some_key" }`
  - numeric IDs, still range-checked by `min`, `max`, `hex_width`.

**Compatibility Impact**
- Existing numeric packed lists are unchanged.
- Existing alignment `{ "list": [...] }` remains accepted, but docs and module data now prefer `{ "alignments": [...] }`.
- ID-list behavior is config-driven, not hardcoded to proficiencies.

**Tests Added / Updated**
- Added build test for generic `id_hex_list`.
- Added validation test for unknown ID references.
- Updated alignment tests to use `alignments`.
- Updated wiki alignment tests for explicit `alignments` plus legacy `list`.

**Validation Performed**
- `go test ./internal/topdata` passed.
- `go test ./internal/project` passed.
- `go test ./...` passed.
- `SOW_TOOLS_DEV_BINARY=../toolkit/tools/sow-toolkit ./scripts/run-nwn-tool.sh config validate` passed in `module/`.

**Remaining Risk**
- `./validate-topdata.sh` in `module/` is currently blocked by existing staged module authored-content changes: generated feat/baseitems validation reports `dataset baseitems: override must specify id or key` from `topdata/data/feat/generated`. I did not try to repair that unrelated staged work.
2026-05-26 13:39:07 +02:00
archvillainette 37db91314b Minimum row 2026-05-25 14:50:01 +02:00
archvillainette 7714c068fe Unhardcode 2026-05-25 10:23:42 +02:00
archvillainette e6fffdf041 Fix tail rows in portrait generation 2026-05-25 10:06:40 +02:00
archvillainette 01ddcf8735 "first_null_row" configuration option 2026-05-25 09:47:36 +02:00
archvillainette 34692fa9b4 Skill focus identity resolution 2026-05-24 20:44:52 +02:00
archvillainette b2a58cb011 Class feat injections moved to yaml 2026-05-24 20:23:08 +02:00
archvillainette a0c3c89049 ECL, default scale, and preferred alignment entries 2026-05-24 17:58:33 +02:00
archvillainette 6707edfccf Reverse allowlist 2026-05-24 15:48:37 +02:00
archvillainette 0e1ebf552d List/range support 2026-05-24 14:11:15 +02:00
archvillainette f4d92a9766 Fix Wiki Generation Not Running 2026-05-22 09:38:46 +02:00
archvillainette 6790274d95 Title normalization hot fix 2026-05-21 21:14:25 +02:00
archvillainette 74c5ea34e1 Normalize feat names (#8)
Reviewed-on: https://gitea.westgate.pw/ShadowsOverWestgate/sow-tools/pulls/8
Co-authored-by: vickydotbat <vickydotbat@tutamail.com>
Co-committed-by: vickydotbat <vickydotbat@tutamail.com>
2026-05-21 21:03:23 +02:00
archvillainette 59994c8b29 Closing gaps and cleaning house 2026-05-14 21:08:38 +02:00
archvillainette e39d539585 Fix stale tag considerations 2026-05-14 19:49:42 +02:00
archvillainette 961a518d66 Wrapper fixes 2026-05-14 19:04:07 +02:00
archvillainette 0e1001657a Fix id flip 2026-05-14 18:50:10 +02:00
archvillainette 9384d905d1 Enable plain TTY logging mode + loose-data processing 2026-05-14 15:11:08 +02:00
archvillainette 2cef662e8e Validation hardening 2026-05-14 15:01:04 +02:00
archvillainette 651336d48e Key lock honoring? 2026-05-14 14:16:02 +02:00
archvillainette baa81f6cb7 Praying for deliberately deleted entries to STOP BEING PARSED AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 2026-05-14 13:45:16 +02:00
archvillainette c9e2b9fdc4 Fix deliberate deletion reuse 2026-05-14 12:54:09 +02:00
archvillainette 393e9a4e59 Lockfile priority normalization 2026-05-14 12:21:47 +02:00
archvillainette 4449fa4f0e Fix override precedence 2026-05-14 11:43:52 +02:00
archvillainette 8fcf0863cc Fix: replaced keys become stale 2026-05-14 11:25:13 +02:00
archvillainette d61ab33aa4 Class skill injection now points to authored entries 2026-05-14 09:29:55 +02:00
archvillainette 18066ee0dd Lock normalization 2026-05-14 08:34:50 +02:00
archvillainette c66b7dcb2b Fix Toolkit Overriding Semantics
- key: null and key: "****" now mean “remove this row's identity”
  - only "null": true blanks the whole row
  - explicit id remains authoritative on id + key overrides
  - when a row claims a key from another row, the key and lock entry can move with it if the old row
    loses that key
2026-05-14 00:15:58 +02:00
archvillainette 985bffa8fb Null key overrides add null rows 2 2026-05-13 22:22:20 +02:00
archvillainette 4b55628ac8 Explicit masterfeats/feats removal 2026-05-13 19:32:41 +02:00
archvillainette 53cb1e6996 Portrait reservation fix? 2026-05-12 17:36:19 +02:00
archvillainette b39bdf13e8 Configuration Hardening 2
What changed:

  - Added visible runtime override reporting with masking for sensitive values.
  - Expanded effective config for build cleanup, script compiler discovery/env, extract layout/cleanup/
    HAK discovery, wiki deploy defaults, autogen cache policy, and release-source env names.
  - Wired configured values into build, script compiler resolution, extract, autogen cache refresh/max
    age, parts manifest release source, wiki generation/deploy, and TLK output naming.
  - Added config sources override output and validation-rule hints in config explain.
  - Added CONFIGURATION_HARDENING_AUDIT.md.
  - Updated README.md with config commands, schema defaults, and JSON artifact boundaries.
  - Added regression tests for override visibility/masking, compiler/extract/wiki/autogen config,
    configured HAK discovery, and config sources output.
2026-05-07 14:22:47 +02:00