Skip to content

feat: load category prefix mappings from .toneforge/config.yaml with lazy loading and fallback#246

Draft
Copilot wants to merge 3 commits intomainfrom
copilot/refactor-category-classifier-config
Draft

feat: load category prefix mappings from .toneforge/config.yaml with lazy loading and fallback#246
Copilot wants to merge 3 commits intomainfrom
copilot/refactor-category-classifier-config

Conversation

Copy link
Contributor

Copilot AI commented Mar 13, 2026

Hard-coded RECIPE_NAME_CATEGORY_MAP in category.ts made adding categories require TypeScript changes. This refactor externalizes that map to a committed YAML config, with lazy loading and safe fallback behavior.

Changes

  • .toneforge/config.yaml — New file containing the canonical prefixToCategory map (all existing mappings preserved). Maintainers extend categories here, no TS edits needed.

  • src/classify/dimensions/category.tsCategoryClassifier now:

    • Accepts an optional configPath constructor arg (defaults to process.cwd()/.toneforge/config.yaml, resolved at first classify call)
    • Lazy-loads and caches mappings on first name-based lookup via loadMappings()
    • Missing config → console.warn + falls back to in-memory defaults
    • Malformed config → throws immediately (fail-fast for CI)
    • context.category path unchanged — still bypasses config entirely
  • src/classify/__tests__/category.test.ts — 8 new tests covering: valid config load, override of built-in defaults, missing-file fallback + warning, single-warn caching, and three malformed-config error cases (array root, missing prefixToCategory key, non-string value).

  • package.json — Added js-yaml@4.1.1 (runtime) and @types/js-yaml (dev).

Example: adding a new category

# .toneforge/config.yaml
prefixToCategory:
  card: card-game
  explosion: explosion   # ← new, no TypeScript change needed
Original prompt

This section details on the original issue you should resolve

<issue_title>Category System Config Refactoring</issue_title>
<issue_description>

Problem statement

Refactor the category classifier to load prefix-to-category mappings from a repository-stored YAML config (.toneforge/config.yaml if present) instead of requiring hard-coded mappings in src/classify/dimensions/category.ts. This will make adding and maintaining categories easier without TypeScript code changes while preserving current fallback heuristics and tests.

Users

  • ToneForge maintainers and contributors who add or update recipe categories (example: add card-game without changing TypeScript).
  • CI systems and integration tests that rely on deterministic classification behavior.

User stories

  • As a maintainer, I want to add or rename category prefixes via a YAML config so I can extend categories without editing code.
  • As a CI pipeline, I want classifier behavior to be reproducible and testable with a committed default config.

Success criteria

  • The classifier loads prefix-to-category mappings from a YAML file located at .toneforge/config.yaml (or extends an existing .toneforge config if present) and uses it when available.
  • If no config exists, the classifier falls back to in-memory defaults and emits a clear warning; it does not write files to the repository automatically.
  • The change is lazy-loaded on first classification call to avoid startup costs.
  • Unit tests covering config loading, fallback-to-hardcoded behavior, and existing category tests pass; npm test and npx tsc --noEmit succeed.
  • No observable change in classification outputs for existing categories unless mappings are intentionally changed.

Constraints

  • Use a YAML-based minimal schema: a map of prefix -> category (string->string). No extra fields required for initial implementation.
  • The implementation will add a small YAML parser dependency (js-yaml) to parse .toneforge/config.yaml.
  • Implementation must be conservative: preserve metric-based fallback heuristics and existing vocabulary.
  • Config file path preference: if an existing .toneforge config is present, extend/merge with it; otherwise look for .toneforge/config.yaml in the repo root. The classifier will not create or write this file automatically.

Existing state

  • Current implementation hard-codes RECIPE_NAME_CATEGORY_MAP in src/classify/dimensions/category.ts with mappings such as weapon, footstep, ui, ambient, character, creature, vehicle, impact (plus aliases like slam -> impact, card -> card-game).
  • There is an existing PRD: docs/prd/CLASSIFY_PRD.md describing classification goals and vocabulary.
  • Related work items include: TF-0MM65RIDV0EJH50O (Card Game Sound Effects Recipe Library) and TF-0MM79DNLZ0J2RP2P (Add card-game Classifier Category).

Desired change

  • Extract the hard-coded RECIPE_NAME_CATEGORY_MAP to a YAML config with a minimal schema (prefix-to-category map).
  • Implement a lazy loader that reads and parses .toneforge/config.yaml on the first call to CategoryClassifier.classify() and caches mappings in memory.
  • If the file is missing, fall back to in-memory defaults and emit a clear warning; do not write files from library code. If the file exists but is invalid/malformed, throw an error to fail fast so CI/tests surface the issue.
  • Add unit tests for config parsing, lazy loading, fallback behavior, and error-on-malformed-config.
  • Update src/classify/dimensions/category.ts to prefer config mappings, falling back to the in-file defaults when necessary.

Related work

  • docs/prd/CLASSIFY_PRD.md — Product-level requirements and vocabulary reference for classification.
  • src/classify/dimensions/category.ts — Current implementation with RECIPE_NAME_CATEGORY_MAP (will be updated).
  • TF-0MM65RIDV0EJH50O — Card Game Sound Effects Recipe Library (discovered-from parent epic).
  • TF-0MM79DNLZ0J2RP2P — Add card-game Classifier Category (completed; category must be present).

Notes

  • Implementation should avoid changing metric-based heuristics in inferCategoryFromMetrics. The config only affects recipe-name prefix mapping and optional explicit context.category normalization.
  • Be explicit in tests about file presence. Library code will not create config files; tests should create temp config files when exercising config-loading behavior. In CI or read-only worktrees the classifier should fall back to in-memory defaults and emit a warning.

Files to change (suggested)

  • src/classify/dimensions/category.ts
  • Suggested config file: .toneforge/config.yaml (maintainers should add/commit this file to change mappings)
  • tests for category classifier: src/classify/tests/category.test.ts (extend to cover config loading and fallback)

Recommended next question for implementer

  • Is adding a small YAML parser dependency (e.g. js-yaml) acceptable, or should the implementation ins...

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits March 13, 2026 10:41
Co-authored-by: SorraTheOrc <250240+SorraTheOrc@users.noreply.github.com>
…with js-yaml

Co-authored-by: SorraTheOrc <250240+SorraTheOrc@users.noreply.github.com>
Copilot AI changed the title [WIP] Refactor category classifier to use YAML config feat: load category prefix mappings from .toneforge/config.yaml with lazy loading and fallback Mar 13, 2026
Copilot AI requested a review from SorraTheOrc March 13, 2026 10:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Category System Config Refactoring

2 participants