Skip to content

fix(settings): preserve distinct catalog identities - #120

Merged
Teakowa merged 1 commit into
mainfrom
codex/issue-110-review-remediation
Aug 28, 2026
Merged

fix(settings): preserve distinct catalog identities#120
Teakowa merged 1 commit into
mainfrom
codex/issue-110-review-remediation

Conversation

@Teakowa

@Teakowa Teakowa commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #110 by making settings identity and projection validation fail closed.

  • Remove broad key-pattern canonicalization that collapsed distinct hero ability concepts.
  • Validate raw hand-written and generated projections before first-wins lookup deduplication.
  • Keep hand-written lookup precedence explicit and validate duplicate value shape.
  • Add a regression test for distinct hero modifier identities.

Independent QA evidence

This PR was checked against the exact pre-remediation merge head ea45518185c8d34b7186376b9e376e57480b9c85:

  • Baseline QA harness: failed as expected because ability1Kb% and ability1SelfKb% both resolved to setting.hero.ability.knockback.
  • Treatment QA harness at this branch: passed for distinct ability1Kb%/ability1SelfKb% identities and distinct damageDealt%/damageReceived% identities.
  • Disposable mutation: changing generated gamemodes.general.heroLimit from Enum to Bool caused workshop-catalog-gen check to fail with conflicting duplicate settings path.
  • The QA harness and mutation worktree were disposable and are not part of this PR.

Local verification

  • cargo fmt --all --check
  • cargo test --workspace --all-targets --locked
  • cargo run -p workshop-rs --bin workshop-catalog-gen -- check
  • cargo clippy --workspace --all-targets --locked -- -D warnings
  • git diff --check

@Teakowa

Teakowa commented Aug 28, 2026

Copy link
Copy Markdown
Contributor Author

Independent QA audit

Review target: the post-merge findings on #110, not only the implementation-authored tests.

Check Baseline ea45518 Remediation 62cd832 Verdict
Distinct ability1Kb% vs ability1SelfKb% identity failed: both setting.hero.ability.knockback passed fixed
Distinct damageDealt% vs damageReceived% identity covered by treatment contract passed fixed
Duplicate projection type conflict not observable through old effective table disposable mutation rejected by workshop-catalog-gen check fixed

The baseline/treatment harness and mutation were run outside the committed test surface and then removed. This is an agent-run independent verification pass, not a claim of a separate human approval.

@Teakowa
Teakowa merged commit a7fd6cc into main Aug 28, 2026
4 checks passed
@Teakowa
Teakowa deleted the codex/issue-110-review-remediation branch August 28, 2026 09:33

Teakowa commented Aug 28, 2026

Copy link
Copy Markdown
Contributor Author

Post-remediation QA audit

Blocker

  1. Duplicate enum-domain conflicts are still hidden by the validator, and this occurs in the current catalog.

validate_catalog() now compares raw duplicate paths before first-wins deduplication, which is the right direction. However, same_entry_shape() treats every Enum(_) / Enum(_) pair as equivalent and does not compare the enum domain identity.

Current data already contains a concrete mismatch for the same path:

  • hand-written gamemodes.general.heroLimitKeyKind::Enum("heroLimit")
  • generated gamemodes.general.heroLimitKeyKind::Enum("setting_gamemodes_general_heroLimit")

Because both are Enum(_), the raw duplicate check accepts them. entries() then keeps the hand-written entry, so the later SettingDefinition validation never sees the generated conflicting domain. workshop-catalog-gen check is therefore green while the two source projections disagree on the enum domain.

This directly misses #110's acceptance criteria around conflicting domains and stale/duplicate semantic tables. The duplicate comparison needs to compare the full semantic KeyKind (including the exact enum domain), not only the broad variant shape. A regression/mutation should specifically cover Enum("a") vs Enum("b"), not only Enum vs Bool.

Major

  1. Duplicate presentation conflicts remain invisible. TableEntry also carries workshop_name, but the raw duplicate reconciliation currently compares only path + broad value shape. Two projections can therefore disagree on the canonical en-US presentation for the same path while check still passes and first-wins lookup silently hides one side. Build the canonical typed Workshop settings catalog #110 explicitly requires stale/duplicate source conflicts and inconsistent presentation/locale facts to fail closed.

The identity-collision remediation itself is valid: the prior contains("Damage") / contains("Kb") style normalization is gone and the reproduced collisions are fixed. CI on 62cd832 is green, but the catalog reconciliation contract is not yet complete.

#110 should remain open until the duplicate projections are compared on the semantic facts that affect the effective catalog rather than only their broad Rust enum variant.

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.

Build the canonical typed Workshop settings catalog

1 participant