Skip to content

[M11 settings] Typed custom-game-settings support in the native frontend (v1 corpus boundary) #86

Description

@Teakowa

Parent: #82
Depends on: #81

Goal

Accept the corpus-evidenced settings { ... } JSONC surface in the native .opy frontend, carry it through HIR, and emit the translated Workshop settings section (before variables) matching the pinned oracle's artifact — removing the dominant real-world first blocker (settings blocks at 9/14 programs) so every settings-bearing program parses past its block.

Contract corrected post-rebaseline (8b782ad). The rebaseline invalidated two planning assumptions: (1) the four committed settings fixtures are not required to exit 0 — only pixelart's body is clean; broken-weapons/client-to-server/santa carry later unsupported constructs, so "settings parses" and "full program compiles" are distinct acceptance levels; (2) real-world settings fixtures cannot be added to PARITY_CASES (their bodies contain unsupported syntax that invalidates HIR parity regardless of settings) — settings HIR parity is proven at a bounded settings-focused boundary instead. Parity rows are added only where they genuinely pass; no parity counts are forced.

PM decision 2026-08-14 (Track A investigation, 017b693): settings enter v1 as typed native support; this supersedes the "unsupported-settings diagnostic" candidate — no standalone rejection task. Direction 3 (opaque/lossless pass-through) is architecturally rejected: the pinned oracle translates settings into the artifact's Workshop settings section, so dropping is silent semantic loss and a pass-through blob is not valid Workshop settings syntax.

Scope (smallest correct set)

  1. Scoped settings lexing/parsing (frontend): recognize the top-of-file settings keyword + JSONC block (trailing commas, quoted keys, \n escapes) without introducing global {/} tokens — meipocalypse's dict-literal diagnostic must stay lex-error at meipocalypse.opy:223:37 (AC-7). Settings in included files or as multiple blocks have no corpus evidence: reject with a stable code + span.
  2. HIR node (v1-additive, not v2): optional top-level settings payload in wright/opy-hir v1 — ordered group tree (main/lobby/gamemodes.<mode>/gamemodes.general/heroes.<team>.<hero>), typed leaf values (int/float/bool/enum/list/object), source spans; inert for HIR→WIR (no analyzer/lowering interaction). Consumer (driver/HIR) update ships in the same batch per protocol §7.1.
  3. Emission (compat profile): translated settings section emitted before variables, matching oracle artifact shape (Respawn Time Scalar: 30%, Hero Limit: Off, disabled <Mode>, enabled maps { ... } incl. empty, localized names). en-US only (the sole pinned locale). The key→localized-name/scalar emission table is built as fixture-evidenced data from the 7 oracle-success snapshots (4 committed + parabola/crosshair/inputhud acquired in this batch), provenance recorded, Architect-reviewed per LICENSE-BOUNDARY (observed-behavior interoperability input, not copied OverPy code).
  4. Structured rejection for out-of-corpus surface: unknown keys/values/enums → stable source-located settings-* diagnostics (registry pattern), never silent drop; no OW2-gamemode-validation replication in v1 (lucioball's gamemode key stays a documented oracle D divergence).
  5. Adapter lockstep + bounded parity boundary: pinned adapter (overpy 9.7.10) maps its settings AST to the HIR settings node; adapter fixtures updated. Settings HIR parity is proven on a bounded settings-focused fixture: a small synthetic fixture whose whole program is a corpus-evidenced settings block plus only supported syntax (e.g., one rule with a trivial condition/action), committed under compatibility/fixtures/synthetic/ with oracle.json + adapter fixture — native-vs-adapter HIR parity is added to PARITY_CASES for this fixture only. Real-world settings-bearing fixtures are not added to PARITY_CASES (their bodies contain unsupported syntax — see Known next blockers).
  6. Acquisition: parabola, crosshair, inputhud committed as settings-bearing real-world fixtures via scripts/acquire-corpus.py (provenance: pinned eea67ad, GPL-3.0-only) — they supply the emission-table snapshots and per-program N-level evidence; none is a full-program candidate (see Known next blockers). skirmish_elim/lucioball are not acquired as parity candidates; recorded as documented S divergence (oracle rejects on #!obfuscate at 48:1 / OW2 gamemode validation at 39:34; native accepts settings where the oracle rejects the program).
  7. Evidence integration + docs: scripts/m11-inventory.py extended to the settings-bearing fixtures; per-program records show settings no longer the first failure and the next blocker (AC-4); support-matrix settings entry (deferred → supported, corpus-evidenced) and the in-operator wording correction (AC-9); opy-hir-v1.md §11 amendment; oracle pin unchanged (9.7.10; ADR-0007, 9e1408b) — existing oracle.json snapshots untouched; new snapshots only for the acquisitions and the bounded synthetic fixture.

Non-goals (hard)

  • No settings semantics (no OW2 gamemode validation).
  • No \, ++/--, dict, """, #!obfuscate implementation (deferred surface stands).
  • No expression-level membership operator (in/not in) implementationfor ... in headers remain the only supported in form; AC-9 corrects the support-matrix wording only.
  • No .ws-input settings section (decompiler is a non-goal — explicit rejection).
  • No settings in includes / multiple blocks.
  • No LSP/analyzer/WIR changes.
  • No v2 protocol; no oracle change; no v1-gates FIXTURES change (gate changes only after verification, with inventory evidence).
  • No M12+ design.

Acceptance criteria (QA-verifiable)

  • AC-1 (settings parse; no exit-0 requirement): for every corpus-evidenced settings-bearing program (9/14), the native frontend parses the settings block and settings is no longer the first failure — verified via per-program first-failure records; the four committed fixtures are explicitly not required to exit 0.
  • AC-2 (section-level emission): for every oracle-success settings-bearing program (the 4 committed fixtures; post-acquisition also parabola/crosshair/inputhud), the emitted Workshop settings section (section-level, v1 normalizer) equals the pinned oracle snapshot's section, ordered before variables.
  • AC-3 (pixelart primary full-program candidate): pixelart is the primary full-program N-level/parity candidate; a full-program row is added only after independent QA verification of full native compile + normalized-output equality with its oracle snapshot (and, for parity, adapter HIR equality).
  • AC-4 (advancement to next blocker): every other settings-bearing program advances to its recorded next blocker (Known next blockers table); the later blocker is recorded in the per-program evidence and is not a [M11 settings] Typed custom-game-settings support in the native frontend (v1 corpus boundary) #86 failure.
  • AC-5 (bounded settings-focused HIR parity): native-vs-adapter HIR parity holds on the bounded synthetic settings fixture (settings + supported syntax only) and is added to PARITY_CASES (+1 row); no real-world settings fixture is added to PARITY_CASES.
  • AC-6 (structured rejection): out-of-corpus settings surface (unknown key/value/enum, settings-in-include, multiple blocks) fails with stable source-located settings-* diagnostics; nothing is silently dropped (synthetic repro fixtures).
  • AC-7 (no global braces): meipocalypse's dict-literal diagnostic is unchanged (lex-error at meipocalypse.opy:223:37); a synthetic dict-literal regression confirms scoped lexing introduced no global {/} tokens; differential suite green.
  • AC-8 (parity integrity): full-program parity rows are added only where they genuinely pass after independent verification; no parity count is promised or forced; the expected baseline (pixelart primary; others contingent) is recorded, not committed to.
  • AC-9 (support-matrix in wording): support-matrix operator wording corrected — for ... in headers are supported; expression-level membership in/not in is not currently supported and is recorded as deferred with the observed failure evidence (broken-weapons :107); no membership operator is implemented.
  • Plus suites: run_oracle, adapter suite, differential, v1-gates 6/6 unchanged, all six CI jobs green at the batch commit.

Known next blockers (not #86 failures) — QA-verified at 096891f (8b782ad)

Program Next blocker after settings (native)
pixelart none tracked — primary full-program candidate (AC-3)
broken-weapons not in [Hero.HANZO, ...] at broken_weapons.opy:107 (parse-error expected ']')
client-to-server chained inline conditional at clientToServer.opy:55 (parse-error expected ')')
santa list comprehension + inline conditional inside #!define createChimneyEffect, first expansion at santa.opy:213; ++ at santa.opy:304 follows
inputhud comprehension at inputhud.opy:83 (body clean to :82)
parabola inline conditional + bytes literal at parabola.opy:46; ++ at :70 follows
crosshair bytes literal b" \n" at crosshair.opy:31 + adjacent-string juxtaposition at :34–41

Dependency ordering

(1) HIR v1-additive amendment + emission-table data capture from the 7 snapshots (Architect: provenance review) → (2) frontend scoped settings lexing/parse + HIR node → (3) structured settings-* rejection → (4) emission (en-US, before variables) → (5) adapter lockstep + bounded synthetic fixture parity (+1 PARITY_CASES row) → (6) acquisitions (parabola, crosshair, inputhud) + oracle snapshots → (7) evidence integration + docs (m11-inventory extension, next-blocker records, support-matrix settings entry + in wording, opy-hir-v1 §11) → (8) QA verification (AC-1..AC-9).

Out of scope (explicit)

Keys beyond the 7-snapshot union; locales beyond en-US; OW2 gamemode validation; global {/} tokens; settings-in-includes; .ws input; WIR/analyzer/LSP interaction; membership operators; the other deferred constructs; a structured-rejection family for non-settings deferred surface; oracle pin change; v1-gates changes; full-program parity for any program other than pixelart (contingent) and the bounded fixture.

Evidence references

QA rebaseline docs/opy/m11-inventory-rebaseline.md (8b782ad) — surface matrix (33 leaf keys + general; 4 enums; 7 named modes + general; 5 maps; 10 heroes; 2 teams; nesting ≤5), emission finding, per-program blockers, parity baseline ("today 6 rows; no row counts promised"). Track A docs/opy/m11-settings-boundary-investigation.md (017b693) — D4 adoption, D3 rejection, sub-decisions, blocked-question resolutions. ADR-0007 docs/adr/0007-reference-pinning-policy.md (9e1408b) + docs/opy/m11-oracle-version-investigation.md — strategy 1, 9.7.10 content pin 889d974. QA reassessment docs/opy/m11-inventory-reassessment.md (a609062) and candidates doc docs/opy/m11-settings-free-candidates.md (f5fe337) — prior evidence, superseded where the rebaseline differs.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions