15 Commits
Author SHA1 Message Date
archvillainette 2f4685e470 fix(erf): align restype numbers with upstream neverwinter.nim (#69)
Closes #64.

Five entries in `internal/erf/erf.go`'s restype table disagreed with upstream neverwinter.nim (`neverwinter/restype.nim`). `HAKResourceTypeForExtension` packs arbitrary source files, so a `.jpg` packed into a HAK today is written as restype 2076, which the game reads as `tml`.

| ext | was | now |
|-----|-----|-----|
| gff | 2039 (upstream `bte`) | 2037 |
| ltr | 2067 (upstream `bak`) | 2036 |
| jpg | 2076 (upstream `tml`) | 2081 |
| dfa | 2045, name typo | `dft`, 2045 (number was already right) |
| mdb | 2070 (upstream `xbc`) | removed |

Upstream registers no restype for `mdb`, so there is no correct number to give it, and leaving it squatting on `xbc` silently mislabels the resource. It is dropped from `AssetExtensions` too, which turns a `.mdb` source into a loud "unsupported extension" build error instead of a corrupt HAK entry. **This is the one judgment call the issue left open** — if `mdb` should instead stay as a deliberate local addition like `lyt`/`vis`/`gr2`, say so and I will move it to a free number in the 0x0BB8+ local range.

No asset in the current corpus uses any of these paths, so nothing in shipped content changes.

The six local additions upstream does not have (`lyt` 3000, `vis` 3001, `mdx` 3008, `wlk` 3020, `xml` 3021, `gr2` 4003) are left alone and now carry a comment saying they are deliberate.

## Root cause

The `init()` consistency guard only panicked when a number was missing from the reverse map. Its `if canonicalExt == ext { continue }` branch did nothing when the two maps disagreed, so a mismatch was never caught. The guard now panics on disagreement and also checks the reverse direction.

## Tests

- `TestRestypeTableMatchesUpstream` pins every number shared with upstream, and asserts the four numbers upstream reserves for other extensions (2039 `bte`, 2067 `bak`, 2070 `xbc`, 2076 `tml`) stay unclaimed.
- `TestRestypeTablesAreMutualInverses` is the check `init()` is meant to enforce.

`make check` passes.Reviewed-on: #69

Co-authored-by: vickydotbat <vickydotbat@tutamail.com>
2026-07-28 22:18:03 +00:00
xtulandarchvillainette 895f63a81c support your local gifmaker (#33)
test / test (push) Successful in 1m25s
build-binaries / build-binaries (push) Successful in 2m10s
build-image / publish (push) Successful in 40s
Reviewed-on: #33
Reviewed-by: archvillainette <vickydotbat@tutamail.com>
Co-authored-by: Michał Piasecki <mpiasecki720@protonmail.com>
Co-committed-by: Michał Piasecki <mpiasecki720@protonmail.com>
2026-07-08 18:37:18 +00:00
archvillainette f1fd03ee83 pipeline: reject resref collisions when chunking; document erf post-write hashing (#8)
test-image / build-image (push) Successful in 47s
test / test (push) Successful in 1m27s
build-binaries / build-binaries (push) Successful in 2m14s
build-image / publish (push) Successful in 13s
## What

Two correctness fixes surfaced in review of the direct-depot HAK artifact work.

### Reject resref+type collisions in `chunksFromManifest`

A manifest can name two distinct source paths that collapse to the same
`resref+type` (e.g. `creature/foo.tga` and `placeable/foo.tga` — resref is the
lowercase basename minus extension). The ERF writer keys resources on
`Name:Type`, so the second silently shadowed the first: an asset would vanish
from the packed HAK with no error.

`chunksFromManifest` now runs `ensureUniqueChunkResources` per chunk and fails
the build on a duplicate. This guards **both** build paths — the legacy
`--source-manifest` flow and the direct content-addressed flow
(`chunksFromSourceManifest` → `chunksFromManifest`).

### Document erf post-write hash coupling

`writeResourceData` streams the source into the output while hashing, so
size/SHA mismatches are only detected *after* the bytes are written. A non-nil
return therefore means the writer holds partial, unverified output and the
caller must discard it. Added a comment making that contract explicit;
`writeHAKArchive` already honours it (writes to a temp file, removes on any
Write error, never renames a bad archive into place).

## Tests

- `TestChunksFromManifestRejectsResrefCollision`: collision → error, distinct
  resrefs → clean. Asserts only error presence/absence — silent asset loss is
  the contract, not any specific wording.
- `go vet ./internal/erf/ ./internal/pipeline/` clean.
- `go test ./internal/erf/ ./internal/pipeline/` green.

## Follow-up

A new crucible release must be cut after this merges so the guard ships in the
binary `sow-assets-manifest` pins.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Reviewed-on: #8
Co-authored-by: vickydotbat <vickydotbat@tutamail.com>
Co-committed-by: vickydotbat <vickydotbat@tutamail.com>
2026-06-20 07:53:04 +00:00
archvillainette cdbbba3181 add content-addressed hak source mode (#7)
test-image / build-image (push) Successful in 46s
test / test (push) Successful in 1m26s
build-binaries / build-binaries (push) Successful in 2m20s
build-image / publish (push) Successful in 31s
Reviewed-on: #7
Co-authored-by: vickydotbat <vickydotbat@tutamail.com>
Co-committed-by: vickydotbat <vickydotbat@tutamail.com>
2026-06-19 20:56:36 +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 1a33c4e102 fix: png now 2080 2026-06-08 19:39:27 +02:00
archvillainette b1b7a08848 Extraction of other resource mappings 2026-05-20 19:27:27 +02:00
archvillainette f6bb4fe3d7 Music Pipeline Implementation 2026-05-07 08:51:42 +02:00
archvillainette 543945f099 Fix type extensions 2 2026-04-10 08:43:06 +02:00
archvillainette 89e0ecd9e1 Fix type extensions 2026-04-10 08:28:06 +02:00
archvillainette 3a0d4eb990 Fix Windows Wrappers and Extensions 2026-04-10 08:13:09 +02:00
archvillainette 94ffcc5868 Fix validation steps for image files 2026-04-09 20:44:21 +02:00
archvillainette 65b9a3dff8 Fix VPS freeze 2026-04-02 18:28:37 +02:00
archvillainette b7f188779a Initial sow-tools import 2026-04-02 17:19:23 +02:00