{
"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 #38 versioned compile API and CLI. Supported settings, catalog-declared locale emission, and post-compile hooks have explicit OPY -> HIR -> WIR -> validated Workshop emission evidence. Compiler and CLI failures remain structured and source-attributed; optimizer controls remain non-blocking presentation differences and semantic replacement directives remain explicit gaps. 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, conditional values",
"category": "syntax",
"state": "source-supported",
"evidence": [
"fixtures:synthetic/expressions-values",
"fixtures:synthetic/receiver-calls",
"fixtures:synthetic/issue-59-postfix-assignment",
"fixtures:synthetic/issue-59-postfix-negative",
"fixtures:synthetic/issue-59-embedded-postfix-negative",
"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; conditional values retain right-associative nesting and source spans. Postfix ++/-- are accepted only as statement-level assignments; prefix ++ and embedded postfix ++/-- remain stable parse diagnostics, while prefix --x remains valid consecutive unary-minus syntax."
},
{
"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",
"fixtures:synthetic/issue-59-postfix-assignment",
"upstream:src/tests/loops.opy",
"upstream:src/tests/conditions.opy"
],
"notes": "Corpus-evidenced: the supported augmented assignment subset is +=, -=, *=, /=, %=, and **=, plus statement-level postfix ++/--; control-flow fixtures resolve; parser rejects out-of-surface forms structurally. min=/max= remains an explicit follow-up (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", "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-rs::macro_js::tests::hooks",
"test:opy-rs-macro-integration",
"test:opy-rs::compiler"
],
"notes": "The compiler runs the bounded internal macro runtime 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-rs::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-rs::macro_js::tests::macro_abi",
"test:opy-rs::macro_js::tests::hooks",
"test:opy-rs::macro_js::tests::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 the internal macro runtime; 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-rs::compiler-vertical-slice",
"contract:workshop-rs-v0.1.16"
],
"notes": "Issue #35. The internal compiler module 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.16 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-rs::compiler-structural-lowering",
"contract:workshop-rs-v0.1.16"
],
"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",
"fixtures:synthetic/issue-59-postfix-assignment",
"test:opy-rs::compiler-primitive-lowering",
"test:opy-rs::compiler::integration_tests::issue_59_oracle::issue_59_postfix_assignments_match_the_pinned_oracle",
"test:opy-rs::compiler-issue-46-native-wir-gap",
"contract:workshop-rs-v0.1.16"
],
"notes": "Issue #46/#59. 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 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": "lowering-dependent",
"evidence": [
"fixtures:synthetic/issue-46-primitives",
"test:opy-rs::compiler-implicit-default-variables",
"contract:workshop-rs-v0.1.16"
],
"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-rs::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-rs::compiler-primitive-lowering",
"test:opy-rs::compiler::integration_tests::issue_100_conditional",
"contract:workshop-rs-v0.1.16"
],
"notes": "Issue #46/#100. 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), right-associative conditional values (ifThenElse), 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": "lowering-dependent",
"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-rs::compiler-issue-47-residual-native-wir-gaps",
"contract:workshop-rs-v0.1.16"
],
"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.16 canonical emitted action widths; direct, conditional, and nested do-while shapes are pinned and oracle-equivalent. Residual native-WIR differences in switch-break and switch-target shapes remain explicit compiler gaps, while nested conditional switch break and multi-break switch cases remain stable source-attributed unsupported-integration-surface diagnostics because OPY has no lossless lowering for those source shapes."
},
{
"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 #38 exposes the bounded compiler/library/CLI surface over the released workshop-rs v0.1.16 contract. Full OPY statement/expression lowering, catalog/member/enum breadth, optimizer effects, and remaining real-project gaps stay explicit in compiler-expectations.json and the native corpus report; 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 broader than the declared #38 baseline. compatibility/run_native.py compiles every fixture through the versioned CLI contract and compares it with the separate compiler-expectations.json baseline. Source/frontend expectations remain independent; entries are separately classified and no unverified case is counted as compiler parity."
},
{
"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": 12,
"end-to-end-supported": 8
},
"byCategory": {
"syntax": 14,
"semantics": 14,
"preprocessing": 4,
"macros": 3,
"directives": 3,
"translations": 2,
"optimization": 3,
"runtime": 1,
"compilation": 10,
"decompilation": 2
}
}
}