{
  "policy": {
    "version": 5,
    "patterns": {
      "version": 1,
      "method": "CURATED_PRACTICE_TOPIC",
      "notice": "Pattern topics identify design choices to practice. Read the ticket's acceptance criteria and justify the simplest suitable approach. Tags are not capability or ownership evidence; an untagged ticket has no curated pattern topic assigned."
    },
    "fieldMix": {
      "version": 1,
      "method": "CURATED_ESTIMATE",
      "notice": "Field percentages are editorial estimates of the ticket's engineering focus. They total 100%; they are not measured time, proficiency scores, or ownership evidence."
    },
    "contentStatus": "PRACTICE_BRIEF",
    "assessmentStatus": "NOT_QUALIFIED",
    "evidenceUse": "NONE",
    "aiPolicy": "AI tools are welcome during implementation. Record assumptions, review the result, and verify its behavior.",
    "notice": "Fictional engineering practice briefs. Starter repositories, fixtures, automated grading, and verified ownership are not included.",
    "outcomeEvidence": "Tests, patches, and runbooks are requested deliverables. They become Outcome Evidence only through a qualified Mission and immutable Evidence IDs.",
    "ownershipEvidence": "Independent adaptation must be observed under a declared verification policy and cite immutable Evidence IDs. Completing a planning ticket establishes no Ownership Evidence."
  },
  "patternTopics": [
    {
      "id": "factory-method",
      "label": "Factory Method",
      "group": "Creational"
    },
    {
      "id": "abstract-factory",
      "label": "Abstract Factory",
      "group": "Creational"
    },
    {
      "id": "builder",
      "label": "Builder",
      "group": "Creational"
    },
    {
      "id": "prototype",
      "label": "Prototype",
      "group": "Creational"
    },
    {
      "id": "singleton",
      "label": "Singleton",
      "group": "Creational"
    },
    {
      "id": "adapter",
      "label": "Adapter",
      "group": "Structural"
    },
    {
      "id": "bridge",
      "label": "Bridge",
      "group": "Structural"
    },
    {
      "id": "composite",
      "label": "Composite",
      "group": "Structural"
    },
    {
      "id": "decorator",
      "label": "Decorator",
      "group": "Structural"
    },
    {
      "id": "facade",
      "label": "Facade",
      "group": "Structural"
    },
    {
      "id": "flyweight",
      "label": "Flyweight",
      "group": "Structural"
    },
    {
      "id": "proxy",
      "label": "Proxy",
      "group": "Structural"
    },
    {
      "id": "chain-of-responsibility",
      "label": "Chain of Responsibility",
      "group": "Behavioral"
    },
    {
      "id": "command",
      "label": "Command",
      "group": "Behavioral"
    },
    {
      "id": "interpreter",
      "label": "Interpreter",
      "group": "Behavioral"
    },
    {
      "id": "iterator",
      "label": "Iterator",
      "group": "Behavioral"
    },
    {
      "id": "mediator",
      "label": "Mediator",
      "group": "Behavioral"
    },
    {
      "id": "memento",
      "label": "Memento",
      "group": "Behavioral"
    },
    {
      "id": "observer",
      "label": "Observer",
      "group": "Behavioral"
    },
    {
      "id": "state",
      "label": "State",
      "group": "Behavioral"
    },
    {
      "id": "strategy",
      "label": "Strategy",
      "group": "Behavioral"
    },
    {
      "id": "template-method",
      "label": "Template Method",
      "group": "Behavioral"
    },
    {
      "id": "visitor",
      "label": "Visitor",
      "group": "Behavioral"
    },
    {
      "id": "ports-and-adapters",
      "label": "Ports and Adapters",
      "group": "Architectural"
    },
    {
      "id": "cqrs",
      "label": "CQRS",
      "group": "Architectural"
    },
    {
      "id": "strangler-fig",
      "label": "Strangler Fig",
      "group": "Architectural"
    },
    {
      "id": "saga",
      "label": "Saga",
      "group": "Distributed and reliability"
    },
    {
      "id": "transactional-outbox",
      "label": "Transactional Outbox",
      "group": "Distributed and reliability"
    },
    {
      "id": "circuit-breaker",
      "label": "Circuit Breaker",
      "group": "Distributed and reliability"
    },
    {
      "id": "bulkhead",
      "label": "Bulkhead",
      "group": "Distributed and reliability"
    }
  ],
  "projects": [
    {
      "id": "4ac38ae8-76d6-4511-bb71-557947944989",
      "key": "PDSL",
      "title": "Make fulfillment rules understandable without executing scripts",
      "field": "Compiler and language tooling",
      "summary": "Replace a growing set of warehouse eligibility switches with a small, bounded rule language that support can inspect and engineers can evolve.",
      "context": "A fictional fulfillment product routes parcels using destination zone, weight in grams, and service level. Its next release needs nested eligibility rules, but arbitrary customer scripts are out of scope. Create a local TypeScript baseline and synthetic parcel/rule fixtures; no starter repository or fixtures are supplied. Keep parsing and evaluation in a local practice application with no network, filesystem, or host-code expressions in the language.",
      "stack": [
        "TypeScript",
        "Node.js",
        "Vitest",
        "JSON"
      ],
      "prerequisites": [
        "Recursive data structures",
        "Parser error handling",
        "Discriminated unions"
      ],
      "developerValue": "Practice expression modeling, language compatibility, bounded evaluation, and deciding whether object-oriented patterns improve a small interpreter.",
      "companyValue": "Review concrete tradeoffs around rule changes, diagnostic quality, resource limits, and the cost of adding an operator without breaking saved rules.",
      "delivery": "Ten tickets across language definition, evaluation, and evolution. Author a minimal local baseline for individual tickets or build the complete synthetic rule engine and compatibility report.",
      "phases": [
        {
          "id": "define",
          "title": "Define the language boundary",
          "goal": "Give saved rules an explicit grammar, tree shape, and useful diagnostics."
        },
        {
          "id": "evaluate",
          "title": "Evaluate and inspect",
          "goal": "Make rule behavior deterministic and inspectable without mutable shared state."
        },
        {
          "id": "evolve",
          "title": "Evolve within limits",
          "goal": "Add syntax safely, bound adversarial inputs, and preserve old rule versions."
        }
      ],
      "tickets": [
        {
          "id": "511541ad-7588-43fb-9a03-a6de91595b07",
          "key": "PDSL-101",
          "title": "Settle literal and operator precedence before saving warehouse rules",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 90,
          "phaseId": "define",
          "dependsOn": [],
          "scenario": "Operations wrote zone == 'north' OR service == 'express' AND weightGrams < 500. Two engineers read it differently, and there is no grammar to decide which parcels qualify.",
          "acceptanceCriteria": [
            "Define parentheses, AND-before-OR precedence, quoted strings, and nonnegative integer gram literals with unambiguous examples.",
            "Reject unknown operators, decimal weights, and trailing tokens with a stable code and source range.",
            "A parse result carries a language version; invalid input cannot produce a saved rule object."
          ],
          "implementationNotes": [
            "Keep the grammar limited to the three documented parcel fields; do not translate input into JavaScript or expose general function calls."
          ],
          "verification": [
            "Parse the disputed expression and its parenthesized alternative into different expected trees.",
            "Reject an unterminated string and an extra closing parenthesis without a stack trace in the public diagnostic."
          ],
          "deliverables": [
            "Versioned grammar note, parser entry point, and synthetic parsing cases"
          ],
          "rollout": "Use the grammar for newly authored local rules first; retain the original text when reverting the parser version.",
          "skills": [
            "Grammar design",
            "Input validation",
            "Error contracts"
          ],
          "fieldMix": [
            {
              "field": "Compiler and language tooling",
              "percentage": 80
            },
            {
              "field": "API design",
              "percentage": 20
            }
          ],
          "patterns": [
            {
              "pattern": "interpreter",
              "activity": "APPLY",
              "focus": "Use an explicit expression grammar as the interpreter boundary so precedence and permitted operations are reviewable before execution."
            }
          ]
        },
        {
          "id": "60734a38-6f9a-4135-8791-b3d57a2a3b5d",
          "key": "PDSL-102",
          "title": "Represent nested all-of and any-of rules without special-case depth handling",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 150,
          "phaseId": "define",
          "dependsOn": [
            "PDSL-101"
          ],
          "scenario": "The current rule model has separate fields for one AND group and one OR group. A warehouse needs (north OR west) AND (express OR under-500g), which cannot be represented without duplicated conditions.",
          "acceptanceCriteria": [
            "Model comparisons and nested all-of/any-of groups through one expression contract while preserving child order.",
            "Reject empty groups and enforce a documented maximum of 16 levels and 1,000 nodes at construction.",
            "Serialize and parse a valid tree without changing its grouping, field types, or language version."
          ],
          "implementationNotes": [
            "Compare a discriminated-union tree with a class hierarchy; choose the smaller representation that supports the required operations."
          ],
          "verification": [
            "Round-trip a four-level mixed rule and compare every node and child position.",
            "Reject a seventeenth level and a reused mutable child that would change an already constructed rule."
          ],
          "deliverables": [
            "Expression model, boundary tests, and a short representation decision"
          ],
          "rollout": "Convert only synthetic flat rules first and compare their trees; retain flat input conversion until nested-rule behavior is checked.",
          "skills": [
            "Tree modeling",
            "Immutability",
            "Serialization"
          ],
          "fieldMix": [
            {
              "field": "Compiler and language tooling",
              "percentage": 75
            },
            {
              "field": "System design",
              "percentage": 25
            }
          ],
          "patterns": [
            {
              "pattern": "composite",
              "activity": "COMPARE",
              "focus": "Compare uniform leaf/group composition with the existing fixed-depth structure, retaining type safety without requiring a class per node."
            }
          ]
        },
        {
          "id": "4027bc4e-2695-41bf-9f7b-38e77e1820bf",
          "key": "PDSL-103",
          "title": "Point rule editors to invalid fields before evaluation starts",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 90,
          "phaseId": "define",
          "dependsOn": [
            "PDSL-102"
          ],
          "scenario": "A rule containing weightGrams == 'heavy' parses successfully, then fails when a parcel reaches the evaluator. Support needs all actionable type errors from the saved rule before attempting a run.",
          "acceptanceCriteria": [
            "Validate permitted field/operator/literal combinations in a pass that does not evaluate parcel data.",
            "Return diagnostics in source order with node path and source range, capped at 50 with an omitted count.",
            "Keep the rule tree unchanged and report an unknown node kind as an unsupported-language error."
          ],
          "implementationNotes": [
            "Compare a visitor with an exhaustive traversal function; document how adding a node forces the validator to handle it."
          ],
          "verification": [
            "Collect distinct string/number mismatch diagnostics from separate branches in stable order.",
            "Pass a synthetic unknown node and a 70-error tree; verify safe rejection and the diagnostic cap."
          ],
          "deliverables": [
            "Static rule validator and support-facing diagnostic examples"
          ],
          "rollout": "Run validation on synthetic saved rules in report-only mode before blocking new invalid saves.",
          "skills": [
            "Static analysis",
            "Tree traversal",
            "Diagnostics"
          ],
          "fieldMix": [
            {
              "field": "Compiler and language tooling",
              "percentage": 70
            },
            {
              "field": "Developer tooling",
              "percentage": 30
            }
          ],
          "patterns": [
            {
              "pattern": "visitor",
              "activity": "COMPARE",
              "focus": "Keep validation separate from evaluation and compare visitor dispatch with an exhaustive function for adding independent tree operations."
            }
          ]
        },
        {
          "id": "4bb83e06-e123-4769-96d2-971b9909db51",
          "key": "PDSL-104",
          "title": "Stop treating an absent parcel weight as a zero-weight match",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 210,
          "phaseId": "evaluate",
          "dependsOn": [
            "PDSL-103"
          ],
          "scenario": "A carrier feed omitted weightGrams and the evaluator coerced it to zero. The parcel passed a weight limit despite having no measurement; OR branches also mask inconsistent missing-value behavior.",
          "acceptanceCriteria": [
            "Define true, false, and unknown outcomes with explicit AND/OR truth tables and no implicit string/number coercion.",
            "Missing referenced inputs produce unknown with the relevant field path; only true authorizes the synthetic routing decision.",
            "Repeated evaluation of the same rule and parcel returns the same outcome and bounded explanation without mutating either input."
          ],
          "implementationNotes": [
            "Short-circuit only when the declared three-valued semantics permit it; retain enough information to explain the final outcome."
          ],
          "verification": [
            "Exercise every pair in both truth tables, including false AND unknown and true OR unknown.",
            "Evaluate missing, null, zero, and numeric-string weights and assert the distinct documented results."
          ],
          "deliverables": [
            "Typed evaluation result, truth-table regression cases, and explanation format"
          ],
          "rollout": "Compare decisions against a synthetic parcel corpus; keep unknown outcomes in a review queue and revert the evaluator by version.",
          "skills": [
            "Evaluation semantics",
            "Null handling",
            "Determinism"
          ],
          "fieldMix": [
            {
              "field": "Compiler and language tooling",
              "percentage": 70
            },
            {
              "field": "Backend",
              "percentage": 30
            }
          ],
          "patterns": [
            {
              "pattern": "interpreter",
              "activity": "REFACTOR",
              "focus": "Replace coercion spread across conditions with one explicit interpreter result model and consistent missing-value semantics."
            }
          ]
        },
        {
          "id": "022b09ca-1619-4447-9972-cfc10e6fb86a",
          "key": "PDSL-105",
          "title": "Keep draft rule builders from changing previously saved expressions",
          "type": "BUG",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 150,
          "phaseId": "evaluate",
          "dependsOn": [
            "PDSL-103"
          ],
          "scenario": "The rule editor reuses a builder to produce two templates. Adding a condition to the second template mutates the first because both saved objects reference the builder's child array.",
          "acceptanceCriteria": [
            "A build operation returns an immutable validated expression with no writable references to builder state.",
            "Incomplete drafts identify missing fields without emitting a partially valid saved rule.",
            "Building twice and then editing the draft cannot change either earlier result or its serialized bytes."
          ],
          "implementationNotes": [
            "Compare a builder with ordinary validated object construction; retain staged construction only where it improves the editor's incomplete-state handling."
          ],
          "verification": [
            "Build two rules from one draft and edit a nested child; verify both saved rule snapshots stay unchanged.",
            "Attempt to build a comparison without a literal and confirm no persisted rule identity is allocated."
          ],
          "deliverables": [
            "Draft-to-rule construction API and shared-reference regression reproduction"
          ],
          "rollout": "Switch local editor saves behind a construction flag; old saved rules stay readable if the editor construction path is reverted.",
          "skills": [
            "Object construction",
            "Immutability",
            "API ergonomics"
          ],
          "fieldMix": [
            {
              "field": "Compiler and language tooling",
              "percentage": 50
            },
            {
              "field": "Frontend",
              "percentage": 30
            },
            {
              "field": "API design",
              "percentage": 20
            }
          ],
          "patterns": [
            {
              "pattern": "builder",
              "activity": "COMPARE",
              "focus": "Assess whether staged rule construction earns its complexity and make the handoff from a mutable draft to an immutable expression explicit."
            }
          ]
        },
        {
          "id": "172a295f-b744-44b6-823e-9107379427a3",
          "key": "PDSL-106",
          "title": "Give the support inspector a stable walk through nested conditions",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 120,
          "phaseId": "evaluate",
          "dependsOn": [
            "PDSL-102"
          ],
          "scenario": "The support inspector duplicates recursive loops for a tree outline, field usage report, and copyable diagnostics. These loops disagree on child order and sometimes skip a nested condition.",
          "acceptanceCriteria": [
            "Expose a read-only depth-first iterator that yields each node once with a stable path and parent path.",
            "The outline and field usage report consume the same traversal contract while retaining their own presentation rules.",
            "Early termination releases traversal state, and malformed cycles are rejected instead of looping indefinitely."
          ],
          "implementationNotes": [
            "Do not expose the mutable traversal stack or allow consumers to rewrite children during iteration."
          ],
          "verification": [
            "Walk a mixed tree and compare the complete path order used by both consumers.",
            "Break after the first leaf, then start a fresh iteration; also supply a manually constructed cycle and assert a bounded error."
          ],
          "deliverables": [
            "Traversal API, two migrated consumers, and cycle/early-exit checks"
          ],
          "rollout": "Compare inspector output before replacing the duplicated traversals; restore the old read path if ordering changes unexpectedly.",
          "skills": [
            "Iteration",
            "Tree traversal",
            "Resource bounds"
          ],
          "fieldMix": [
            {
              "field": "Compiler and language tooling",
              "percentage": 60
            },
            {
              "field": "Developer tooling",
              "percentage": 40
            }
          ],
          "patterns": [
            {
              "pattern": "iterator",
              "activity": "APPLY",
              "focus": "Provide a shared traversal contract for independent tree consumers without exposing the representation or coupling their presentation logic."
            }
          ]
        },
        {
          "id": "d46bdac6-42cd-4b3b-ba42-bcfdab980e22",
          "key": "PDSL-107",
          "title": "Measure whether interning field symbols actually reduces rule-cache memory",
          "type": "TASK",
          "priority": "LOW",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "evaluate",
          "dependsOn": [
            "PDSL-104"
          ],
          "scenario": "A heap profile suggests thousands of cached rules repeat the same field and operator metadata. The proposed optimization shares entire nodes, including source locations and tenant rule identifiers.",
          "acceptanceCriteria": [
            "Benchmark an authored 10,000-rule synthetic corpus before and after sharing only immutable context-free symbols.",
            "Keep source spans, rule identities, and parcel evaluation state outside shared symbols, and bound or evict the intern pool.",
            "Report retained heap, parse time, and identical rule outcomes across repeated runs; retain the optimization only if the measured tradeoff justifies it."
          ],
          "implementationNotes": [
            "State runtime, corpus seed, warmup, and measurement variability; a decision to remove the pool is an acceptable result."
          ],
          "verification": [
            "Compare all evaluation outcomes and source-specific diagnostics with pooling enabled and disabled.",
            "Load many distinct invalid symbols and verify rejection cannot grow the intern pool without bound or reuse another rule's source range."
          ],
          "deliverables": [
            "Reproducible heap comparison and an evidence-backed keep-or-remove decision"
          ],
          "rollout": "Default pooling off until the local measurements pass review; disabling it must leave serialized rule content unchanged.",
          "skills": [
            "Memory profiling",
            "Caching",
            "Benchmark design"
          ],
          "fieldMix": [
            {
              "field": "Performance engineering",
              "percentage": 60
            },
            {
              "field": "Compiler and language tooling",
              "percentage": 40
            }
          ],
          "patterns": [
            {
              "pattern": "flyweight",
              "activity": "COMPARE",
              "focus": "Test whether sharing intrinsic symbol metadata saves enough memory while keeping source, tenant, and evaluation context out of shared objects."
            }
          ]
        },
        {
          "id": "492a894f-ccbe-4e15-962f-09fe7a0260a5",
          "key": "PDSL-108",
          "title": "Add membership expressions without leaving tree operations behind",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "EXPERT",
          "estimateMinutes": 300,
          "phaseId": "evolve",
          "dependsOn": [
            "PDSL-104",
            "PDSL-106"
          ],
          "scenario": "Warehouse rules repeat long chains such as zone == 'north' OR zone == 'west'. Adding IN to evaluation alone would leave validation, inspection, and serialization unaware of the new node.",
          "acceptanceCriteria": [
            "Add string-set membership with a 50-item limit, explicit duplicate handling, and no implicit type conversion.",
            "Update parsing, validation, evaluation, inspection, and serialization, with an exhaustive mechanism that exposes unhandled node kinds.",
            "Compare visitor-based operations with node-local methods for this change and explain which extension axis becomes easier or harder."
          ],
          "implementationNotes": [
            "New syntax uses a new language version; existing rules retain their old version and behavior, including missing-field outcomes."
          ],
          "verification": [
            "Compare membership and equivalent OR rules over present, absent, matching, and nonmatching zones.",
            "Run every tree operation on the new node; reject a 51-item set and an older parser receiving the new version."
          ],
          "deliverables": [
            "Membership implementation, operation coverage matrix, and extension tradeoff note"
          ],
          "rollout": "Enable authoring for the new version after all operations support it; turn off new authoring without rewriting saved older rules.",
          "skills": [
            "Language evolution",
            "Exhaustiveness",
            "Design tradeoffs"
          ],
          "fieldMix": [
            {
              "field": "Compiler and language tooling",
              "percentage": 70
            },
            {
              "field": "System design",
              "percentage": 30
            }
          ],
          "patterns": [
            {
              "pattern": "visitor",
              "activity": "COMPARE",
              "focus": "Use a real new-node change to compare operation-oriented visitors with node-local methods and make the extension cost visible in the patch."
            },
            {
              "pattern": "composite",
              "activity": "REFACTOR",
              "focus": "Integrate the membership leaf into the uniform expression tree without adding special group traversal paths or weakening node validation."
            }
          ]
        },
        {
          "id": "788ea190-f734-4160-b2c4-c1eb4e35308f",
          "key": "PDSL-109",
          "title": "Bound rule parsing and explanation work before expensive allocation",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 210,
          "phaseId": "evolve",
          "dependsOn": [
            "PDSL-104",
            "PDSL-108"
          ],
          "scenario": "The editor rejects a deeply nested rule only after parsing its entire text. A pasted megabyte of repeated parentheses stalls the local worker, and explanations allocate one message for every attempted comparison.",
          "acceptanceCriteria": [
            "Reject source text above 64 KiB before tokenization and enforce depth, node, and literal limits as input is consumed.",
            "Bound evaluation steps and explanation entries independently; return distinct stable limit codes without partial routing approval.",
            "After a rejected rule, the same process can evaluate a small valid rule with no retained traversal or explanation state."
          ],
          "implementationNotes": [
            "Use deterministic operation budgets rather than relying solely on wall-clock time; no regex features with unbounded backtracking are required by this language."
          ],
          "verification": [
            "Exercise just-below and just-above each declared bound with reproducible generated inputs.",
            "Alternate rejected and valid rules for 100 runs; confirm bounded diagnostics and unchanged valid outcomes."
          ],
          "deliverables": [
            "Limit enforcement changes, adversarial local cases, and resource-bound report"
          ],
          "rollout": "Publish the limit codes in the local editor before enforcing them; revert language authoring if needed while retaining safe evaluator limits.",
          "skills": [
            "Resource limits",
            "Parser robustness",
            "Failure recovery"
          ],
          "fieldMix": [
            {
              "field": "Compiler and language tooling",
              "percentage": 50
            },
            {
              "field": "Security",
              "percentage": 30
            },
            {
              "field": "Performance engineering",
              "percentage": 20
            }
          ],
          "patterns": [
            {
              "pattern": "interpreter",
              "activity": "REFACTOR",
              "focus": "Make resource accounting part of the interpreter contract so nested expressions cannot bypass limits through separate parsing or explanation paths."
            }
          ]
        },
        {
          "id": "7e46d0c0-1ec7-44ad-aacd-89d46e7b901d",
          "key": "PDSL-110",
          "title": "Ship a rule-language upgrade with a reversible authoring boundary",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 240,
          "phaseId": "evolve",
          "dependsOn": [
            "PDSL-105",
            "PDSL-108",
            "PDSL-109"
          ],
          "scenario": "The membership release introduces version 2 rules, but a rollback plan assumes every stored rule can still be opened by the version 1 editor. Saving an unrecognized node would silently discard a condition.",
          "acceptanceCriteria": [
            "Route evaluation by saved language version and fail closed for unknown versions without rewriting the original rule bytes.",
            "Keep unsupported rules read-only in an older editor and require an explicit conversion preview before creating a new version.",
            "Demonstrate a rollback sequence that stops version 2 authoring while preserving version 2 evaluation or explicitly pausing those rules."
          ],
          "implementationNotes": [
            "Record conversion warnings and original version lineage; a builder must not invent defaults for unsupported expression nodes."
          ],
          "verification": [
            "Run a mixed-version synthetic corpus before upgrade, after upgrade, and through the documented rollback sequence.",
            "Open a version 2 rule in the old editor and submit an unknown-version rule; verify neither path loses conditions or approves routing."
          ],
          "deliverables": [
            "Compatibility matrix, conversion preview, and rehearsed local rollback runbook"
          ],
          "rollout": "Stage evaluation support before new authoring, then enable one synthetic warehouse; retain versioned evaluators until all dependent rules are explicitly retired.",
          "skills": [
            "Compatibility",
            "Release planning",
            "Versioned data"
          ],
          "fieldMix": [
            {
              "field": "Compiler and language tooling",
              "percentage": 50
            },
            {
              "field": "System design",
              "percentage": 30
            },
            {
              "field": "Site reliability",
              "percentage": 20
            }
          ],
          "patterns": [
            {
              "pattern": "interpreter",
              "activity": "APPLY",
              "focus": "Keep interpreter semantics tied to stored language versions so deploying or reverting authoring code cannot silently change routing behavior."
            },
            {
              "pattern": "builder",
              "activity": "REFACTOR",
              "focus": "Make version conversion an explicit construction step with a preview instead of rebuilding unknown nodes with guessed defaults."
            }
          ]
        }
      ]
    }
  ]
}
