Skip to content

MagicAST restructure: Phase 1 — Data-driven structural-keyword table #2

Description

@Spelkington

Parent

Part of the MagicAST restructure milestone — a pre-TDD architectural refactor to eliminate merge-conflict hotspots so ~10 parallel agent worktrees can each add a new MTG ability/effect/keyword as a self-contained new file with zero edits to existing shared files.

This is Phase 1 of 5. The overall pattern across phases is attribute-driven registration discovered via reflection at startup. This phase is the smallest and exists partly to build the project's attribute-discovery muscle before tackling harder phases.

What to build

Today, the tokenizer maintains a hard-coded literal table of structural keywords (the _structuralKeywords field inside OracleTokenizer.cs, currently around lines 17–44). Adding a structural keyword is an edit to that shared file — a merge-conflict hotspot when multiple agents work in parallel.

Replace the inline table with self-contained registrations, one per structural keyword. The tokenizer discovers them at startup. Two acceptable implementation paths; pick (i) unless you find a concrete reason to prefer (ii):

  • (i, preferred) Attribute on a per-keyword class. Example shape: [StructuralKeyword("when")] public static class WhenKeyword {}. The tokenizer scans the assembly for [StructuralKeyword]-decorated types at startup and builds the dispatch table once.
  • (ii) Embedded JSON resource shipped with the assembly. The tokenizer loads it on first use.

Path (i) is preferred because it gives compile-time safety on keyword names and matches the attribute-driven pattern used by later phases.

Each keyword lives in its own file under (suggested) libs/magic-ast/Parsing/Tokens/Keywords/ or similar — exact directory layout is implementer's choice as long as the goal is met.

Acceptance criteria

  • OracleTokenizer.cs no longer contains a literal list of structural keyword strings.
  • Each structural keyword currently in the inline table has a corresponding self-contained registration file.
  • An agent can add a new structural keyword by creating one new file — zero edits to OracleTokenizer.cs or any other existing file.
  • The reflection-based registry scans the assembly once (cached for the process lifetime); subsequent tokenizer constructions do not re-scan.
  • Full ratchet test suite (tools/test/magic-ast/) remains green or improves — no regressions in test-baseline.json.
  • If adopting path (ii) instead of (i), document the reason in the PR description.

Blocked by

None — can start immediately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentFully specified, ready for an AFK agentscope:magic-astAffects libs/magic-ast/type:refactorRefactor — no behavior change expected

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions