---
status: complete
phase: 02-client-engine-documentation
source:
  - 02-01-SUMMARY.md
  - 02-01b-SUMMARY.md
  - 02-02-SUMMARY.md
  - 02-03-SUMMARY.md
  - 02-04-SUMMARY.md
  - 02-05-SUMMARY.md
  - 02-06-SUMMARY.md
started: 2026-05-03T00:00:00Z
updated: 2026-05-03T04:02:00Z
executed_by: claude
---

## Current Test

[testing complete]

## Tests

### 1. Cold Start Smoke Test
expected: From clean shell at repo root, `cd tools/asset-catalog && pnpm install && pnpm test:full` → install exit 0, 160/160 tests pass.
result: pass
note: |
  Initially failed: 8/8 tests in tests/integration/cli.test.ts errored with `'tsx' is not recognized` because runCli spawned `pnpm exec tsx` from cwd=repoRoot — repo root has no node_modules / no tsx.
  Fix applied:
    - tests/integration/cli.test.ts:33-50 → runCli now uses cwd=toolDir, cliPath='cli.ts' (relative).
    - 3 test bodies → 'extracted/client-5-8' string replaced with realDataPath absolute.
    - src/emit.ts runVerify → 3rd resolution candidate `fileURLToPath(new URL('../../../extracted/client-5-8/', import.meta.url))` so verify works with tmp-dir docsDirs.
  After fix: `pnpm test:full` → 14 files / 160 tests passed (65s). `pnpm test` (default, integration excluded) → 10 files / 144 tests passed.

### 2. CLI Exit-Code Matrix
expected: From `tools/asset-catalog/`, `pnpm exec tsx cli.ts` → exit 2; `... help` → exit 0; `... --help` → exit 0; `... bogus` → exit 2.
result: pass
note: 2/0/0/2 confirmed.

### 3. Catalog Regeneration (D-15/D-16 Determinism)
expected: From repo root, `pnpm catalog:client` <30s; re-run produces zero git diff.
result: pass
note: 4.7s. Re-run after emit.ts edit → `git status --porcelain docs/extracted-engine/` clean.

### 4. Catalog Verify (Drift Guard)
expected: `pnpm catalog:verify` exit 0.
result: pass
note: "OK: autogen blocks match" exit 0.

### 5. Real-Data Catalog Counts
expected: 854/12/198/320/16 sprites/bg/scripts/objects/rooms.
result: pass
note: Asset counts confirmed exactly. Sounds/fonts/timelines arrays absent from index.json (no input data; functionally equivalent to length 0).

### 6. UNKNOWN-ACTIONS Drained
expected: extracted/{client-5-8,server-5-4}/UNKNOWN-ACTIONS.md absent; no `// UNKNOWN ACTION_ID=` strings in any Draw.gml.
result: pass

### 7. 11 Subsystem MDs Present (CDOC-01)
expected: docs/extracted-engine/ contains README + SUBSYSTEM-MAP.json + 11 subsystem MDs.
result: pass

### 8. AUTOGEN Round-Trip (lint-docs)
expected: lint-docs.mjs exit 0.
result: pass
note: "OK: all 12 subsystem MDs match regen-autogen output".

### 9. MATRIX.md + Engine ADR (CDOC-03/CDOC-04)
expected: MATRIX-rows.json (21 rows) + MATRIX.md + adr/0001-client-engine.md present.
result: pass

### 10. lint-matrix + lint-adr Pass
expected: both exit 0.
result: pass
note: |
  lint-matrix exit 0 ("MATRIX-rows.json (21 rows) + MATRIX.md totals validated").
  lint-adr exit 0 ("6 unique MX-* citations resolved").
  Cosmetic warning from lint-adr — "MATRIX-rows.json not found at docs/extracted-engine/MATRIX-rows.json; skipping rowId citation resolution check" — script's CWD-relative lookup is wrong, then re-resolves successfully via different path. Exit 0 holds. Worth follow-up cleanup but does not block.

### 11. No Plaintext Credential Leak in Catalog
expected: zero `Jarhead111` matches in index.json.
result: pass

## Summary

total: 11
passed: 11
issues: 0
pending: 0
skipped: 0

## Gaps

[none — initial issue resolved by inline fix]

## Inline Fixes Applied During UAT

1. `tools/asset-catalog/tests/integration/cli.test.ts` — runCli helper switched cwd to tools/asset-catalog; cliPath made relative; 3 test bodies updated to use absolute realDataPath for catalog input.
2. `tools/asset-catalog/src/emit.ts` — `runVerify` gained a 3rd source-dir resolution candidate (tool-relative via `import.meta.url`) so verify works against tmp-dir docsDirs created by integration tests.

Both fixes preserve byte-determinism (catalog re-emit + catalog:verify both clean) and pass all 160 tests.

## Follow-Up Notes (non-blocking)

- `lint-adr.mjs` first-pass MATRIX-rows.json lookup uses CWD-relative path that doesn't resolve when invoked from inside tools/asset-catalog; it then succeeds via a fallback. Cosmetic warning, exit 0. Worth a one-line cleanup.
- `index.json` omits `sounds`, `fonts`, `timelines` keys entirely instead of emitting empty arrays. SUMMARY claims describe these as "0/0/0" — input has none; output schema decision is to omit. Consistent with deriveCatalog impl. If downstream wants stable shape, add empty-array defaults.
