{
"schemaVersion": 1,
"visibility": "internal-engineering-metadata",
"artifact": "opy-rs OverPy feature inventory and support matrix",
"reference": {
"name": "overpy",
"version": "9.7.10",
"contentCommit": "889d9749d1def17f146548cbddb94ea1ab015847",
"integrity": "sha512-oX17nauJcPTaKIrRFY/rD0Rl8atqFUVv9Hg2TKH+A68/fC8+ZO344Mkd1A/Y0oOVp1hr5tktMBjzMEDDnMEYUw=="
},
"snapshot": {
"date": "2026-08-29",
"note": "Readiness baseline through the bounded #37 compiler slice. Settings, catalog-declared locale emission, and post-compile hooks have explicit OPY -> HIR -> WIR -> validated Workshop emission evidence. Optimizer controls remain non-blocking presentation differences; semantic replacement directives remain explicit gaps and fail at the compiler boundary until canonical lowering exists. Canonical Workshop catalog data, settings tables, locale spellings, WIR, validation, and emission remain owned by workshop-rs.",
"asOfCommit": "9f7c62b1958a3804780a2de7d1bd55e2fb298533"
},
"states": {
"planned": "Declared surface, not yet implemented in opy-rs; evidence/provenance recorded for the implementing issue.",
"source-supported": "Source implementation behavior (lex/parse/preprocess/macro expansion) implemented in opy-rs and corpus-evidenced.",
"semantic-supported": "Semantic resolution implemented in opy-rs (names, members, enums, call semantics covered by the semantic model).",
"lowering-dependent": "Completion requires canonical Workshop semantics/catalog/emission owned by workshop-rs; inventory-only until the integration stage.",
"end-to-end-supported": "A declared feature or bounded integration slice has explicit OPY -> HIR -> WIR -> validated Workshop emission evidence for that scope; this state does not imply full-language OPY-to-Workshop parity."
},
"categories": [
"syntax",
"semantics",
"preprocessing",
"macros",
"directives",
"translations",
"optimization",
"runtime",
"compilation",
"decompilation"
],
"features": [
{
"id": "syntax/lexing",
"name": "Lexer: identifiers, literals, strings, comments, #! directives, operators",
"category": "syntax",
"state": "source-supported",
"evidence": [
"fixtures:synthetic/basic-rule",
"fixtures:synthetic/control-flow",
"fixtures:synthetic/expressions-values",
"fixtures:synthetic/diagnostics",
"fixtures:real-world/overpy-cake",
"upstream:src/tests/comments.opy",
"upstream:src/tests/operators.opy",
"upstream:src/tests/strings.opy",
"upstream:src/tests/arrays.opy"
],
"notes": "Corpus-evidenced: differential suite runs 40 fixtures; upstream tokenizer surface probed."
},
{
"id": "syntax/expressions",
"name": "Expression/postfix/member/call grammar, precedence, indexing",
"category": "syntax",
"state": "source-supported",
"evidence": [
"fixtures:synthetic/expressions-values",
"fixtures:synthetic/receiver-calls",
"fixtures:real-world/overpy-cake",
"upstream:src/tests/operators.opy",
"upstream:src/tests/arrays.opy",
"upstream:src/tests/strings_args.opy"
],
"notes": "Corpus-evidenced: expression fixtures + receiver-calls fixture resolve through the semantic model."
},
{
"id": "syntax/declarations",
"name": "Declarations: globalvar/playervar (index + initializer), subroutine, def, enum, macro constants",
"category": "syntax",
"state": "source-supported",
"evidence": [
"fixtures:synthetic/declarations-rules",
"fixtures:synthetic/declarations-numbers",
"fixtures:synthetic/preprocessing",
"fixtures:real-world/overpy-cake",
"upstream:src/tests/variables.opy",
"upstream:src/tests/subroutines.opy",
"upstream:src/tests/enums.opy"
],
"notes": "Corpus-evidenced: declarations fixtures + overpy-cake resolve; diagnostics for malformed declarations."
},
{
"id": "syntax/assignments-control-flow",
"name": "Assignments and control flow: =, +=, -=, *=, /=, %=, **=, if/elif/else, for-in-range, while, pass",
"category": "syntax",
"state": "source-supported",
"evidence": [
"fixtures:synthetic/control-flow",
"fixtures:synthetic/for-range-agentlab",
"fixtures:synthetic/chase-condition-agentlab",
"upstream:src/tests/loops.opy",
"upstream:src/tests/conditions.opy"
],
"notes": "Corpus-evidenced: the supported augmented assignment subset is +=, -=, *=, /=, %=, and **=; control-flow fixtures resolve; parser rejects out-of-surface forms structurally. min=/max= and ++/-- remain explicit follow-ups (#59, wrightkit/workshop-rs#95)."
},
{
"id": "syntax/switch",
"name": "switch/case/default",
"category": "syntax",
"state": "source-supported",
"evidence": ["fixtures:synthetic/issue-28-syntax", "fixtures:synthetic/issue-33-switch-break", "upstream:src/tests/switches.opy"],
"notes": "Issue #28/#33: switch/case/default preserve source-order arms and fall through into subsequent arms; explicit break exits the innermost switch or loop. Workshop lowering remains out of scope."
},
{
"id": "syntax/break",
"name": "break statements in switch and loops",
"category": "syntax",
"state": "source-supported",
"evidence": ["fixtures:synthetic/issue-33-switch-break", "upstream:src/tests/switches.opy", "upstream:src/tests/loops.opy"],
"notes": "Issue #33: break is a real HIR statement, validates its enclosing switch/loop context, and is retained without implicit arm exits."
},
{
"id": "syntax/do-while",
"name": "do … while",
"category": "syntax",
"state": "source-supported",
"evidence": ["fixtures:synthetic/issue-28-syntax", "fixtures:real-world/overpy-santa/regressions/do-while.opy", "upstream:src/tests/loops.opy"],
"notes": "Issue #28: the body executes before the condition and the condition is retained as an OPY HIR expression; malformed/truncated conditions remain structured parse errors."
},
{
"id": "syntax/hex-literals",
"name": "Hexadecimal numeric literals (0x/0X)",
"category": "syntax",
"state": "source-supported",
"evidence": ["fixtures:synthetic/issue-28-syntax", "upstream:src/tests/operators.opy"],
"notes": "Issue #28: hexadecimal source spelling is preserved in the numeric HIR text while the numeric value is decoded independently."
},
{
"id": "syntax/membership",
"name": "Expression-level in/not in membership",
"category": "syntax",
"state": "source-supported",
"evidence": ["fixtures:synthetic/issue-28-syntax", "upstream:src/tests/operators.opy"],
"notes": "Issue #28: in/not in are represented as source-semantic binary operators; no Workshop Array Contains catalog or lowering is copied here."
},
{
"id": "syntax/string-modifiers",
"name": "String modifiers (f/w/l/b/c/t)",
"category": "syntax",
"state": "source-supported",
"evidence": ["fixtures:synthetic/issue-28-string-modifiers", "fixtures:synthetic/issue-28-syntax", "fixtures:synthetic/issue-33-f-string", "upstream:src/tests/strings.opy"],
"notes": "Issue #28/#33: f-string interpolation lowers to a semantic format node with source-spanned arguments; w/b/c remain semantic string modifiers and l/t remain syntax-carried without duplicating translation data."
},
{
"id": "syntax/dicts",
"name": "Dictionary literals and keyed access",
"category": "syntax",
"state": "source-supported",
"evidence": ["fixtures:synthetic/issue-28-syntax", "upstream:src/tests/dicts.opy"],
"notes": "Issue #28: dictionary entries and keyed access are represented in OPY HIR; bare dictionaries and malformed entries produce structured diagnostics."
},
{
"id": "syntax/comprehensions",
"name": "List comprehensions (mapping/filtering, element and index binders)",
"category": "syntax",
"state": "source-supported",
"evidence": ["fixtures:synthetic/issue-28-syntax", "upstream:src/tests/dicts.opy"],
"notes": "Issue #28: one-for-clause comprehensions with an optional filter and optional element/index binders preserve local scope in HIR."
},
{
"id": "syntax/lambda",
"name": "Lambda expressions for array operations",
"category": "syntax",
"state": "source-supported",
"evidence": ["fixtures:synthetic/issue-28-syntax", "fixtures:synthetic/issue-33-f-string", "fixtures:synthetic/issue-33-lambda-negative", "upstream:src/tests/dicts.opy"],
"notes": "Issue #28/#33: lambda x: expr is accepted only in signature-approved positions (sorted index 1/key and array map/filter/all/any index 0); standalone and other argument positions produce a structured diagnostic."
},
{
"id": "syntax/settings-blocks",
"name": "settings { ... } custom-game-settings blocks: JSONC parse into the typed HIR payload",
"category": "syntax",
"state": "source-supported",
"evidence": [
"fixtures:synthetic/settings",
"fixtures:real-world/overpy-meipocalypse/settings.opy",
"fixtures:real-world/6v6-adjustments/lobby/lobby.opy",
"upstream:src/tests/customGameSettings.opy",
"upstream:src/tests/workshopSettings.opy"
],
"notes": "Corpus-evidenced: settings fixtures parse into the typed HIR payload. Validation is structural only (group shape, span validity, non-empty key names); key-existence and leaf-kind settings validation was removed from the core and is lowering-dependent (#8). Emission lowering-dependent."
},
{
"id": "semantics/declaration-resolution",
"name": "Name resolution: undeclared identifiers, subroutine and constant references, enum types",
"category": "semantics",
"state": "semantic-supported",
"evidence": [
"fixtures:synthetic/declarations-rules",
"fixtures:synthetic/expressions-values",
"upstream:src/tests/functions.opy",
"upstream:src/tests/subroutines.opy"
],
"notes": "Resolved in Opy HIR with structured unknown-identifier/unsupported-member diagnostics; fixtures + tooling tests."
},
{
"id": "semantics/for-binder",
"name": "for-loop binder: declared globalvar or implicit default variables A-Z … DA-DX",
"category": "semantics",
"state": "semantic-supported",
"evidence": [
"fixtures:synthetic/for-range-agentlab",
"upstream:src/tests/loops.opy"
],
"notes": "for-loop binders resolve to declared globals or implicit default variables (A-Z .. DA-DX); fixture for-range-agentlab."
},
{
"id": "semantics/builtin-actions-values",
"name": "OPY builtin actions and values: manifest identities, signatures, aliases, and call semantics",
"category": "semantics",
"state": "semantic-supported",
"evidence": [
"probes:generic-builtins",
"probes:chase-over-time",
"probes:is-game-in-progress",
"probes:get-players-in-radius",
"probes:catalog-only-names",
"probes:unknown-function",
"probes:unknown-value",
"probes:action-in-value-position",
"probes:value-in-action-position",
"fixtures:synthetic/basic-rule",
"fixtures:synthetic/chase-condition-agentlab"
],
"notes": "Issue #30. The manifest-declared OPY overlay is semantic-supported: source identities, action/value position, signatures, keyword binding, aliases, and canonical catalogId links are probe-validated against the pinned oracle. Canonical Workshop existence/content/emission breadth is tracked separately as lowering-dependent."
},
{
"id": "semantics/workshop-builtin-catalog",
"name": "Canonical Workshop builtin action/value catalog existence, content, and emission",
"category": "semantics",
"state": "lowering-dependent",
"evidence": [
"probes:catalog-only-names",
"fixtures:synthetic/receiver-calls",
"fixtures:synthetic/chase-condition-agentlab",
"upstream:src/data/opy/functions.ts"
],
"notes": "Issue #42 closes a bounded catalog-backed slice: manifest catalogId links lower to canonical action/value ids and representative receiver/chase cases emit through workshop-rs with WIR and canonical-id validation. Full Workshop catalog breadth, content domains, localized spellings, and emission remain lowering-dependent; opy-rs does not copy the catalog or claim full 225/267 coverage."
},
{
"id": "semantics/receiver-members",
"name": "OPY receiver/member semantics: receiver categories and explicit-argument signatures",
"category": "semantics",
"state": "semantic-supported",
"evidence": [
"probes:receiver-calls",
"probes:enum-gated-members",
"probes:invalid-arity-member",
"probes:generic-member-only-action",
"probes:member-value-in-action-position",
"probes:invalid-receiver-append",
"probes:invalid-receiver-format",
"fixtures:synthetic/receiver-calls",
"upstream:src/data/opy/memberFunctions.ts"
],
"notes": "Issue #30. The manifest-declared OPY member overlay is semantic-supported: receiver syntax/category semantics, explicit-argument signatures, variable receiver rules, aliases, and catalogId links are probe-validated. Canonical member existence/content and Workshop emission remain lowering-dependent."
},
{
"id": "semantics/workshop-receiver-catalog",
"name": "Canonical Workshop receiver/member catalog existence, content, and emission",
"category": "semantics",
"state": "lowering-dependent",
"evidence": [
"probes:receiver-calls",
"fixtures:synthetic/receiver-calls",
"upstream:src/data/opy/memberFunctions.ts"
],
"notes": "Issue #42 closes the evidenced receiver slice: member action/value catalogIds are lowered with the receiver as the canonical leading operand, and catalog-gap members remain explicit integration diagnostics. The OPY receiver/member source-language surface (names, aliases, receiver categories, and signatures) belongs to opy-rs; workshop-rs owns canonical Workshop target identities and semantics, content domains, localization, validation, and emission."
},
{
"id": "semantics/receiver-playervar",
"name": "Bare playervar receiver member access (`A = B.C`)",
"category": "semantics",
"state": "semantic-supported",
"evidence": [
"fixtures:synthetic/receiver-playervar",
"upstream:src/tests/variables.opy",
"upstream:src/data/opy/memberFunctions.ts"
],
"notes": "Issue #30 repair. The pinned oracle accepts this OPY-owned receiver form and the source implementation preserves its variable receiver and member identity in HIR with source provenance. Canonical member existence and emission remain Workshop-owned and lowering-dependent; #8 must not be used to claim the OPY expression incomplete."
},
{
"id": "semantics/enum-domains",
"name": "OPY enum/domain semantics: declared domain identities and contextual dispatch",
"category": "semantics",
"state": "semantic-supported",
"evidence": [
"probes:unknown-enum",
"fixtures:synthetic/chase-enums",
"fixtures:synthetic/chase-keywords",
"upstream:src/tests/builtinenums.opy",
"upstream:src/data/opy/constants.ts"
],
"notes": "Issue #30. Manifest parameter domains and contextual dispatch are semantic-supported OPY identity links with oracle/corpus evidence. Domain member lists, member existence, domain membership, localized spellings, and emission remain Workshop-owned and are never approximated in opy-rs."
},
{
"id": "semantics/workshop-enum-domains",
"name": "Canonical Workshop enum/domain member lists, membership, and emission",
"category": "semantics",
"state": "lowering-dependent",
"evidence": [
"probes:unknown-enum",
"fixtures:synthetic/chase-enums",
"fixtures:synthetic/chase-condition-agentlab",
"upstream:src/data/opy/constants.ts"
],
"notes": "Issue #42 closes catalog validation for the representative declared and contextual enum slice: canonical domains/members are checked through workshop-rs and contextual chase dispatch reaches canonical action ids. Full Hero, Map, Gamemode, Team, and settings/content domain breadth remains Workshop-owned and lowering-dependent."
},
{
"id": "semantics/aliases",
"name": "Source aliases: non-contextual (stopChasingVariable, getCurrentHero, hasStatusEffect) and the ChaseReeval contextual alias",
"category": "semantics",
"state": "semantic-supported",
"evidence": [
"probes:aliases",
"probes:member-aliases",
"probes:chase-reeval-context",
"probes:chase-reeval-outside"
],
"notes": "Issue #4. Declared alias surface (3 non-contextual + ChaseReeval contextual) resolves; probes pass (chase-reeval-outside stays: it documents the contextual-domain identity rule). Wrong-domain member rejection is lowering-dependent (#8). Remaining alias surface legacy-quirk/demand-driven."
},
{
"id": "semantics/modules",
"name": "Modules: random.{randint,uniform,choice,shuffle}",
"category": "semantics",
"state": "semantic-supported",
"evidence": [
"fixtures:real-world/overpy-cake",
"fixtures:real-world/overpy-zencopter/heli.opy",
"fixtures:real-world/overpy-meipocalypse/meipocalypse.opy",
"upstream:src/data/opy/modules.ts"
],
"notes": "random.{uniform,choice} calls resolve; corpus-evidenced (overpy-cake, zencopter, meipocalypse)."
},
{
"id": "semantics/keyword-arguments",
"name": "Named/keyword arguments: generic name=expr binding and the chase/ChaseReeval special form",
"category": "semantics",
"state": "semantic-supported",
"evidence": [
"probes:chase-keywords",
"probes:chase-keyword-binding",
"probes:chase-arg3-keyword-required",
"probes:chase-duplicate-keyword",
"probes:chase-missing-argument",
"probes:chase-positional-after-keyword",
"probes:chase-unknown-keyword",
"probes:wait-keyword-names",
"probes:keyword-arguments-unsupported",
"fixtures:synthetic/chase-keywords"
],
"notes": "Generic keyword binding + chase/ChaseReeval special form; probe-evidenced (chase-keywords set)."
},
{
"id": "semantics/diagnostics",
"name": "Source identity and diagnostics: structured, source-located source implementation errors, wright-result/v1 envelope",
"category": "semantics",
"state": "source-supported",
"evidence": [
"fixtures:synthetic/diagnostics",
"fixtures:synthetic/declarations-rules",
"upstream:runTests.mjs"
],
"notes": "Structured stable-code diagnostics with 1-based spans; the stable-code contract is documented in docs/opy/tooling-api.md and tested in opy-rs tooling tests."
},
{
"id": "semantics/settings-emission",
"name": "Workshop settings-section emission: key table, enum values, map/hero list elements",
"category": "semantics",
"state": "end-to-end-supported",
"evidence": [
"fixtures:synthetic/settings",
"fixtures:real-world/6v6-adjustments/lobby/lobby.opy",
"upstream:src/tests/customGameSettings.opy"
],
"notes": "Settings lower directly into the neutral workshop-rs carrier; workshop-rs owns key/value validation, locale spellings, and emission. Emitted settings are deliberately not reparseable (round-trip boundary)."
},
{
"id": "preprocessing/include",
"name": "#!include: root-relative resolution, cycle detection, missing-file diagnostics, file registry",
"category": "preprocessing",
"state": "source-supported",
"evidence": [
"fixtures:synthetic/preprocessing",
"fixtures:real-world/ow1-emulator",
"fixtures:real-world/6v6-adjustments",
"upstream:src/tests/include.opy",
"upstream:src/tests/include3.opy",
"upstream:src/tests/include5.opy"
],
"notes": "Root-relative include resolution, cycle detection, missing-file diagnostics, file registry; deterministic multi-file tests."
},
{
"id": "preprocessing/define-undef",
"name": "#!define (object- and function-like), #!undef, recursive expansion, recursion guard",
"category": "preprocessing",
"state": "source-supported",
"evidence": [
"fixtures:synthetic/preprocessing",
"fixtures:real-world/overpy-cake",
"upstream:src/tests/macros.opy",
"upstream:src/tests/builtinmacros.opy"
],
"notes": "Object- and function-like #!define, #!undef, recursive expansion with recursion guard; preprocessing fixtures."
},
{
"id": "preprocessing/advanced-directives",
"name": "#!mainFile, #!allowMacroRedeclaration, #!optimize*/#!replace0By* family, #!rulePrefix*",
"category": "preprocessing",
"state": "semantic-supported",
"evidence": [
"fixtures:synthetic/issue-29-directives",
"fixtures:synthetic/issue-29-main-file",
"upstream:src/tests/rulePrefix.opy",
"upstream:src/tests/compression.opy",
"upstream:src/data/opy/preprocessing.ts"
],
"notes": "Issue #29: source implementation records directive state, macro-redeclaration policy, main-file provenance, and rule-prefix application. Optimizer and generated Workshop effects remain separate."
},
{
"id": "preprocessing/directive-effects",
"name": "Preprocessing directive effects on Workshop emission and optimization",
"category": "preprocessing",
"state": "lowering-dependent",
"evidence": [
"fixtures:synthetic/issue-29-directives",
"upstream:src/data/opy/preprocessing.ts"
],
"notes": "Rule-prefix metadata is already reflected in HIR rule names. Optimizer controls remain non-blocking presentation differences. The compiler rejects replacement directives at their source anchor until a canonical lowering and corpus evidence exist; it does not silently drop or approximate semantic rewrites."
},
{
"id": "macros/definitions",
"name": "macro name(params): statement bodies with MacroParam references, macro constants",
"category": "macros",
"state": "source-supported",
"evidence": [
"fixtures:synthetic/preprocessing",
"fixtures:real-world/overpy-cake",
"fixtures:real-world/overpy-meipocalypse",
"fixtures:real-world/ow1-emulator/common/macro_functions.opy",
"upstream:src/tests/macros.opy",
"upstream:src/tests/astMacros.opy",
"upstream:src/tests/builtinmacros.opy"
],
"notes": "macro name(params): statement bodies with MacroParam references expand; corpus-evidenced (cake, meipocalypse, ow1-emulator)."
},
{
"id": "macros/javascript",
"name": "__script__ JavaScript macros (QuickJS runtime); #!postCompileHook parsed and recorded",
"category": "macros",
"state": "source-supported",
"evidence": [
"upstream:runTests.mjs",
"upstream:src/tests/postCompileHook.opy",
"upstream:src/tests/quickjs-modern.js",
"upstream:src/tests/quickjs-invalid-return.js",
"upstream:src/tests/quickjs-runaway.js",
"upstream:src/quickjs.ts",
"test:opy-rs-macro-integration",
"test-fixture:crates/opy-rs/tests/fixtures/macros",
"test:opy-rs-differential",
"fixtures:real-world/overpy-meipocalypse"
],
"notes": "Issue #6 + #7 part B. `#!define name(args) __script__(\"path.js\")` parsed (root-relative script resolution, script-not-found at the define site like the reference's ENOENT), expanded through opy_macro_js::MacroRuntime with the reference's var-injection ABI, indentation rule, and string-only completion contract — compile-time expansion executes and is source-supported. `#!postCompileHook` is parsed, validated, and recorded (duplicate rejection); compiler execution against final Workshop text is tracked by hooks/post-compile-workshop. Structured script-* diagnostics carry script provenance. Catalog constants remain lowering-dependent; `#!require` does not exist in the pinned reference."
},
{
"id": "hooks/post-compile-workshop",
"name": "Post-compile hook execution against the final Workshop text",
"category": "macros",
"state": "end-to-end-supported",
"evidence": [
"upstream:src/tests/postCompileHook.opy",
"upstream:src/quickjs.ts",
"test:opy-macro-js-hooks",
"test:opy-rs-macro-integration",
"test:opy-compiler"
],
"notes": "The compiler runs the bounded opy-macro-js hook only after successful workshop-rs emission, passes the exact emitted Workshop text, and exposes the string completion as final output; hook failures retain both the directive anchor and structured script provenance."
},
{
"id": "directives/rule-annotations",
"name": "Rule annotations: @Event, @Condition, bare @Team/@Slot",
"category": "directives",
"state": "source-supported",
"evidence": [
"fixtures:synthetic/basic-rule",
"fixtures:synthetic/declarations-rules",
"fixtures:synthetic/control-flow",
"upstream:src/tests/rules.opy",
"upstream:README.md"
],
"notes": "Core rule annotations and event/condition structure are source implementation-owned."
},
{
"id": "directives/advanced-rule-annotations",
"name": "Rule annotations: @Team/@Slot args, @Name, @Hero, @Disabled, @Delimiter, @NewPage, @SuppressWarnings",
"category": "directives",
"state": "semantic-supported",
"evidence": [
"fixtures:synthetic/issue-29-directives",
"fixtures:synthetic/issue-29-invalid",
"upstream:src/data/opy/annotations.ts"
],
"notes": "Issue #29: annotation arguments, rule metadata, and source diagnostics are retained in OPY HIR; hero/team/slot domain validation and Workshop UI effects remain lowering-dependent."
},
{
"id": "directives/rule-model",
"name": "Rule model: rule \"name\": with events (global, eachPlayer), conditions list, statements",
"category": "directives",
"state": "source-supported",
"evidence": [
"fixtures:synthetic/basic-rule",
"fixtures:synthetic/chase-condition-agentlab",
"fixtures:synthetic/control-flow",
"upstream:src/tests/rules.opy",
"upstream:src/tests/eventVars.opy"
],
"notes": "rule \"name\": with global/eachPlayer events, conditions, statements; differential fixtures."
},
{
"id": "translations/directive",
"name": "#!translations directive recognition and .po generation surface",
"category": "translations",
"state": "semantic-supported",
"evidence": [
"fixtures:synthetic/issue-29-directives",
"upstream:src/tests/translations.opy",
"upstream:src/tests/translations2.opy",
"upstream:src/tests/translations.es.po",
"upstream:src/tests/translations2.fr.po",
"upstream:src/compiler/translations.ts"
],
"notes": "Issue #29: language-tag syntax, uniqueness/conflict validation, provenance, and translation state are source implementation-owned; locale availability, .po content, and generated Workshop helpers remain lowering-dependent."
},
{
"id": "translations/locale-emission",
"name": "Localized Workshop output (--language flag, localizedStrings data)",
"category": "translations",
"state": "end-to-end-supported",
"evidence": [
"upstream:src/data/localizedStrings.ts",
"oracle:CLI --language en-US invocation recorded in compatibility/run_oracle.py",
"test:opy-compiler"
],
"notes": "Compiler locale selection delegates to workshop-rs catalog coverage and rejects undeclared locales explicitly; missing per-identity mappings remain fail-explicit."
},
{
"id": "optimization/controls",
"name": "#!optimize*/#!replace0By* family and compression controls",
"category": "optimization",
"state": "semantic-supported",
"evidence": [
"fixtures:synthetic/issue-29-directives",
"upstream:src/tests/compression.opy",
"upstream:src/data/opy/preprocessing.ts"
],
"notes": "Issue #29: optimizer/replacement controls are parsed, validated, ordered, and exposed as source implementation state; transformation execution is not part of opy-rs."
},
{
"id": "optimization/backend-effects",
"name": "Optimizer transformations and replacement rewrites",
"category": "optimization",
"state": "lowering-dependent",
"evidence": [
"fixtures:synthetic/issue-29-directives",
"upstream:src/data/opy/preprocessing.ts"
],
"notes": "Optimizer transformations and replacement rewrites remain lowering-dependent. Optimizer controls remain non-blocking; replacement directives fail explicitly rather than silently changing Workshop output."
},
{
"id": "optimization/emission-form",
"name": "Workshop text emission form (variable naming, enum spellings, formatting)",
"category": "optimization",
"state": "lowering-dependent",
"evidence": [
"fixtures:synthetic/basic-rule/oracle.json",
"fixtures:real-world/overpy-cake/oracle.json"
],
"notes": "Output-text identity is explicitly not the compatibility contract; exact-vs-normalized differences are presentation differences. Emission form is workshop-rs-owned."
},
{
"id": "runtime/js-hooks",
"name": "QuickJS runtime for __script__ macro and hook execution (synthetic-content hook ABI)",
"category": "runtime",
"state": "source-supported",
"evidence": [
"upstream:runTests.mjs",
"upstream:src/quickjs.ts",
"oracle:quickjs-ng.wasm shipped in the pinned npm package",
"test:opy-macro-js-abi",
"test:opy-macro-js-hooks",
"test:opy-macro-js-limits",
"test:opy-rs-macro-integration"
],
"notes": "Issue #6 + #7 part B. Bounded runtime surface wired into the source implementation: macro execution with argument injection, `vect` helper, empty constant objects, console capture, reference-compatible accept/reject and result semantics, resource limits defaulting to the pinned reference constants (1000 ms macro / 2000 ms hook budgets, 64 MiB memory, 512 KiB stack). The hook ABI runs against synthetic content in opy-macro-js; hook execution against the Workshop output is lowering-dependent (see hooks/post-compile-workshop, issue #8). Browser/WASM execution remains unsupported (native embedding only), matching the declared boundary."
},
{
"id": "compilation/source implementation-pipeline",
"name": "Source implementation pipeline: lexer -> preprocess -> CST/parser -> semantic resolution -> Opy HIR v2",
"category": "compilation",
"state": "source-supported",
"evidence": [
"fixtures:synthetic",
"fixtures:real-world",
"docs:docs/hir/opy-hir-v2.md",
"test:opy-rs-differential"
],
"notes": "Issues #3-#7, #25, and the #28/#29/#30/#33 readiness tracks. Fully Workshop-independent; the pinned differential corpus is the acceptance corpus. Differential harness runs every fixture through the native pipeline in cargo test with structural self-checks (HIR validation, wire round-trip, deterministic dump), status/rule-name parity against recorded oracle.json snapshots, explicit native evidence expectations, and a machine-readable report (target/opy-differential-report.json). The generated report records per-fixture matches and known gaps; no unexpected divergence or inconclusive result is a support claim."
},
{
"id": "compilation/opy-integration-vertical-slice",
"name": "Minimal OPY -> canonical WIR -> Workshop emission vertical slice",
"category": "compilation",
"state": "end-to-end-supported",
"evidence": [
"fixtures:synthetic/issue-35-integration",
"test:opy-compiler-vertical-slice",
"contract:workshop-rs-v0.1.11"
],
"notes": "Issue #35. The dedicated opy-compiler crate consumes resolved OPY HIR, preserves source files/spans in workshop-rs WIR, cross-checks manifest catalogId/domain links against Catalog, validates canonical WIR, and emits deterministic en-US Workshop through the published workshop-rs v0.1.11 contract. This is a bounded first slice; broader OPY lowering remains lowering-dependent and is not reclassified by this fixture."
},
{
"id": "compilation/opy-structural-lowering",
"name": "OPY structural HIR -> canonical WIR lowering: declarations, subroutines, rules, events, and provenance",
"category": "compilation",
"state": "end-to-end-supported",
"evidence": [
"fixtures:synthetic/issue-35-integration",
"fixtures:synthetic/issue-40-structural",
"test:opy-compiler-structural-lowering",
"contract:workshop-rs-v0.1.11"
],
"notes": "Issue #40. Global/player variables and subroutines use deterministic canonical indices with source/name spans; subroutine definitions and calls, rule disabled state, conditions, supported event/filter identities, and source-file provenance lower directly into workshop-rs WIR. Unsupported settings, declarations, annotations, events, filters, and statement forms remain explicit source-attributed integration diagnostics. This does not claim full statement/expression, catalog/member/enum, settings, locale, optimizer, hook, or decompilation coverage."
},
{
"id": "compilation/opy-assignment-lowering",
"name": "OPY assignment and modification HIR -> canonical WIR lowering",
"category": "compilation",
"state": "end-to-end-supported",
"evidence": [
"fixtures:synthetic/issue-46-primitives",
"test:opy-compiler-primitive-lowering",
"test:opy-compiler-issue-46-oracle-equivalence",
"contract:workshop-rs-v0.1.11"
],
"notes": "Issue #46. Global/player assignments and augmented assignments (+=, -=, *=, /=, %=, **=), single-level indexed variable assignments and modifications (setGlobalVariableAtIndex, modifyGlobalVariableAtIndex, setPlayerVariableAtIndex, modifyPlayerVariableAtIndex), and pass no-op statements lower into canonical workshop-rs WIR. Declaration initializer evidence covers non-null initializers; OverPy null-default initializer semantics remain tracked by #58. Deeper indexed writes remain tracked by #60. Direct global/player assignments and modifications carry full statement and target-variable span provenance; the single-level indexed forms lower to canonical Call actions, which carry only the statement-level source span (the canonical WIR Call shape has no separate target-span field)."
},
{
"id": "compilation/opy-implicit-default-variables",
"name": "OverPy implicit default global and player variables (A-DX) at fixed Workshop slots",
"category": "compilation",
"state": "end-to-end-supported",
"evidence": [
"fixtures:synthetic/issue-46-primitives",
"test:opy-compiler-implicit-default-variables",
"contract:workshop-rs-v0.1.11"
],
"notes": "Issue #46. Undeclared A-Z, AA-AZ, ..., DA-DX global references and eventPlayer.<name> player references resolve through the source implementation default_var_index contract and lower to separate Workshop variable namespaces at their fixed reference slots (A=0 ... DX=127); used implicit slots are reserved independently for declared global/player allocation, an explicit declared index colliding with a used implicit slot fails with the stable source-attributed index-collision diagnostic, and a declared name wins in its own namespace. The pinned oracle snapshot for the issue-46 fixture constrains global and player slots through structural equivalence."
},
{
"id": "compilation/opy-primitive-lowering-limits",
"name": "Negative primitive-lowering diagnostics for forms outside canonical WIR",
"category": "compilation",
"state": "end-to-end-supported",
"evidence": [
"fixtures:synthetic/issue-46-unsupported",
"test:opy-compiler-primitive-lowering-limits"
],
"notes": "Issue #46 negative contract. A non-control-flow primitive the canonical WIR surface cannot represent (the fixture uses a dict-indexed assignment, which the pinned oracle compiles by constant folding) is rejected with the stable unsupported-integration-surface diagnostic attributed to the source statement; no unsupported HIR node is silently discarded or guessed."
},
{
"id": "compilation/opy-expression-lowering",
"name": "OPY non-control-flow value expression HIR -> canonical WIR lowering",
"category": "compilation",
"state": "end-to-end-supported",
"evidence": [
"fixtures:synthetic/issue-46-primitives",
"test:opy-compiler-primitive-lowering",
"contract:workshop-rs-v0.1.11"
],
"notes": "Issue #46. Literals (numbers, strings, booleans, null), arrays, vectors (vect), enum constants, global/player/eventPlayer variable references, array indexing (valueInArray; a literal zero index lowers to firstOf, matching the pinned oracle), string formatting (customString), arithmetic/comparison/logical binary operations, unary operations (not, -; not on a comparison lowers to the negated comparison, matching the pinned oracle), and power operations lower into canonical workshop-rs WIR. Value-position power uses the canonical raiseToPower Value contract; direct and indexed power modifications use the canonical Workshop Operation contract."
},
{
"id": "compilation/opy-control-flow-lowering",
"name": "OPY control-flow HIR -> canonical WIR lowering",
"category": "compilation",
"state": "end-to-end-supported",
"evidence": [
"fixtures:synthetic/issue-47-control-flow",
"fixtures:synthetic/issue-47-unsupported",
"fixtures:synthetic/issue-47-switch-order",
"fixtures:synthetic/issue-47-switch-structured-target",
"fixtures:synthetic/issue-47-switch-multiple-break",
"fixtures:synthetic/issue-47-do-while-shapes",
"fixtures:synthetic/issue-47-do-while-invalid-placement",
"fixtures:synthetic/issue-33-switch-break",
"test:opy-compiler-issue-47-oracle-equivalence",
"contract:workshop-rs-v0.1.11"
],
"notes": "Issue #47. If/elif/else, while, global-binder range-for, do-while expansion, source-ordered switch fallthrough/default, and direct loop/switch/do-while break lower into canonical workshop-rs WIR. Switch offsets and do-while distances use workshop-rs v0.1.11 canonical emitted action widths; direct, conditional, nested, and structured-tail do-while shapes plus structured switch targets are pinned and oracle-equivalent. A nested conditional switch break and a multi-break switch with later reachable actions remain stable source-attributed unsupported-integration-surface diagnostics because workshop-rs v0.1.11 has no lossless multi-target switch carrier."
},
{
"id": "compilation/workshop-lowering",
"name": "HIR -> Workshop lowering and emission through workshop-rs",
"category": "compilation",
"state": "lowering-dependent",
"evidence": [
"fixtures:synthetic",
"fixtures:real-world"
],
"notes": "Issue #8 remains the broader lowering track. The released workshop-rs v0.1.11 public contract now supports the bounded #35 adapter, the #40 structural skeleton, and the separately evidenced #47 control-flow slice; full OPY statement/expression lowering, catalog/member/enum breadth, settings/content, locales, optimizer effects, and hooks remain lowering-dependent follow-up work. Oracle snapshots (fixtures/**/oracle.json) remain preserved reference evidence; no temporary Workshop IR is introduced here."
},
{
"id": "compilation/end-to-end",
"name": "End-to-end OPY -> Workshop compile parity",
"category": "compilation",
"state": "lowering-dependent",
"evidence": [
"fixtures:synthetic",
"fixtures:real-world",
"fixtures:census/workshop-feature-census"
],
"notes": "Full OPY-to-Workshop parity remains lowering-dependent after the bounded #35 first slice; the OPY-side feature census records opaque workshop-rs#10 identities without duplicating catalog definitions. Differential harness contract is ready (compatibility/diff.py, issue #25)."
},
{
"id": "decompilation/workshop-to-opy",
"name": "Workshop -> OPY decompilation",
"category": "decompilation",
"state": "lowering-dependent",
"evidence": [
"upstream:src/tests/decompiler",
"upstream:src/decompiler"
],
"notes": "Deferred until the canonical Workshop semantic representation exists (workshop-rs integration); a non-goal before it. Upstream decompiler corpus (17 inputs) is the future reference."
},
{
"id": "decompilation/roundtrip-boundary",
"name": "Round-trip boundary: emitted settings reparsing, .ws round-trip",
"category": "decompilation",
"state": "lowering-dependent",
"evidence": [
"docs:docs/opy/support-matrix.md"
],
"notes": "Documented boundary: emitted settings sections are deliberately not reparseable; a .ws decompiler is a non-goal. Reconstruction of arbitrary Workshop text is out of scope."
}
],
"summary": {
"byState": {
"planned": 0,
"source-supported": 23,
"semantic-supported": 13,
"lowering-dependent": 10,
"end-to-end-supported": 10
},
"byCategory": {
"syntax": 14,
"semantics": 14,
"preprocessing": 4,
"macros": 3,
"directives": 3,
"translations": 2,
"optimization": 3,
"runtime": 1,
"compilation": 10,
"decompilation": 2
}
}
}