# AI Agent Contract: Auto-Include Existing Part Models in 2DA Generation

## Status Snapshot

Current state as of 2026-05-17:

- Superseded for current Shadows Over Westgate builds.
- The module no longer consumes a released parts manifest. Parts data is owned by
  `assets/`, generated as HAK-side 2DA assets from `assets/topdata/data/parts`
  plus a direct scan of `assets/content/part/**/*.mdl`, and packaged in
  `sow_part`.
- This file remains as historical context for the legacy manifest-backed
  consumer path.

## Objective

The native 2DA generation pipeline must automatically include existing part models already present in the **`sow-assets` repository** when building final parts tables.

This behavior is required for parity with the current asset set and must not depend on manually authored entries for models that already exist in repository assets.

---

## Source of Truth

The superseded manifest-backed native builder obtained existing model
information from a released artifact published by the **`sow-assets` repository**.

Resolution rules:

- if `topdata.assets` is configured to a local path, use that exact path
- otherwise derive the **`sow-assets` repository** from the module repo's Gitea origin
  and fetch only the configured released manifest

Normal builds must not clone or scan the `sow-assets` repo tree. They may cache the
downloaded manifest locally for reuse, but the source of truth remains the released
manifest on Gitea.

Manifest-backed discovery is derived from:

```text
sow-assets/assets/part/**/*.mdl
```

The manifest generator may also accept the repo's legacy `assets/parts/` layout when
resolving the physical paths, but the native builder itself must consume the manifest,
not the repo tree.

---

## Required Scope

Process existing `.mdl` files for these parts table categories only:

- `belt`
- `bicep`
- `chest`
- `foot`
- `forearm`
- `leg`
- `neck`
- `pelvis`
- `robe`
- `shin`
- `shoulder`

Dataset mapping rules:

- `parts/legs` maps to asset category `leg`
- `parts/hand` remains unsupported and is not auto-generated

The scan must recurse through subdirectories under each applicable category path.

---

## Required Behavior

### 1. Manifest-backed discovery

For each supported part category, read the released manifest and discover all existing
numeric model IDs listed for that category.

### 2. Trailing numeric suffix extraction

The released manifest must be generated using trailing-numeric-suffix extraction from
the source `.mdl` filenames. Native topdata consumes the resulting numeric IDs only.

### 3. Row generation

If a trailing numeric suffix is present:

- use that numeric suffix as the output row ID
- emit a row for that part model in the final generated 2DA

### 4. Default emitted values

For rows generated from discovered existing models, set:

- `COSTMODIFIER = 0`
- `ACBONUS = 0.00`

Rows without discovered existing models may be intentionally emitted as dense
2DA null rows when configured. In that mode, missing rows must have
`COSTMODIFIER = ****` and `ACBONUS = ****` in the final generated 2DA.

### 5. Override precedence

If file-based overrides exist, they must take precedence over discovered defaults.

That means:

- manifest discovery provides the baseline row presence and default values
- override data may replace or augment those values
- override data wins in any conflict

---

## Non-Negotiable Requirements

- The implementation must read model presence from the **released parts manifest**,
  not from assumption, hardcoded lists, or legacy output.
- Existing repository models with trailing numeric suffixes must be reflected in generated output even if they are not otherwise explicitly authored.
- Override application is mandatory and must win over auto-discovered defaults.
- This is replacement behavior for the native pipeline, not an optional enhancement.

---

## Acceptance Criteria

The superseded implementation was correct only if all of the following were true:

1. The builder fetches the configured released manifest artifact for part models.
2. Only the supported part categories are considered.
3. Manifest IDs derived from trailing numeric suffixes generate corresponding 2DA rows.
4. The numeric suffix is used as the row ID.
5. Auto-generated rows default to:
   - `COSTMODIFIER = 0`
   - `ACBONUS = 0.00`

6. Authored base rows remain exposed. Authored `ACBONUS = ****` rows remain
   null unless model discovery activates the row.
7. Dense gaps without authored rows or discovered models are emitted as null
   rows with `COSTMODIFIER = ****` and `ACBONUS = ****`.
8. File overrides are applied after discovery and take precedence.
9. The final output includes all eligible existing models present in the manifest.
10. Discovery does not require a sibling local `sow-assets` checkout or a Git clone.

---

## Implementation Directive

When generating native parts 2DAs, first scan the project-resolved assets repo for
supported part models, collect existing supported part models by category, extract
trailing numeric suffixes from filenames, emit rows using those suffixes as row IDs
with default `COSTMODIFIER = 0` and `ACBONUS = 0.00`, then apply overrides with
override values taking precedence.
