{
  "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": "d50423a2-7db9-42a2-aae5-55e8c83682ad",
      "key": "CTYPE",
      "title": "A small expression type checker with explainable errors",
      "field": "Compiler and language tooling",
      "summary": "Type-check a bounded expression language without evaluating submitted expressions.",
      "context": "Fictional rules editor Willow supports numbers, strings, booleans, records and functions in a deliberately small language. Define syntax and type rules locally; no arbitrary code execution is needed.",
      "stack": [
        "TypeScript",
        "Vitest",
        "Typed AST fixtures"
      ],
      "prerequisites": [
        "Create synthetic AST fixtures and a written type-rule table.",
        "Define source spans and structured diagnostic output."
      ],
      "developerValue": "Practice type environments, unification and explainable rejection.",
      "companyValue": "Inspect whether developer tooling catches mistakes without hiding uncertainty.",
      "delivery": "Limit scope to the declared type system; general language compatibility is not claimed.",
      "phases": [
        {
          "id": "rules",
          "title": "Establish type rules",
          "goal": "Handle literals and lexical scope."
        },
        {
          "id": "inference",
          "title": "Resolve expression types",
          "goal": "Explain composition failures."
        },
        {
          "id": "stability",
          "title": "Keep checking predictable",
          "goal": "Bound work and stabilize diagnostics."
        }
      ],
      "tickets": [
        {
          "id": "1ed460c9-579f-466a-9a61-0fedf63492c6",
          "key": "CTYPE-101",
          "title": "Assign explicit types to rules-editor literals",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 60,
          "phaseId": "rules",
          "dependsOn": [],
          "scenario": "The prototype infers booleans from string truthiness. Type literals from AST node kinds only.",
          "acceptanceCriteria": [
            "Number string and boolean types differ",
            "Empty string stays string",
            "Unknown literal kind fails explicitly"
          ],
          "implementationNotes": [
            "Do not evaluate literal source text."
          ],
          "verification": [
            "Check each supported literal",
            "Reject unsupported node kind"
          ],
          "deliverables": [
            "Literal checker and cases"
          ],
          "rollout": "Reject unknown nodes while supported literals remain available.",
          "skills": [
            "Type systems",
            "AST"
          ],
          "fieldMix": [
            {
              "field": "Compiler and language tooling",
              "percentage": 100
            }
          ],
          "patterns": []
        },
        {
          "id": "f8e9ba70-b675-448b-a83b-3abc1c0b564f",
          "key": "CTYPE-102",
          "title": "Resolve expression identifiers through lexical scope",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 120,
          "phaseId": "rules",
          "dependsOn": [
            "CTYPE-101"
          ],
          "scenario": "Inner bindings overwrite the global environment and leak into sibling expressions. Use scoped environments.",
          "acceptanceCriteria": [
            "Inner shadowing is local",
            "Sibling scope remains unchanged",
            "Unbound names include source location"
          ],
          "implementationNotes": [
            "Environments must not mutate parent bindings accidentally."
          ],
          "verification": [
            "Check nested shadowing",
            "Use name outside its scope"
          ],
          "deliverables": [
            "Scope resolver and cases"
          ],
          "rollout": "Disable nested bindings if scope isolation fails.",
          "skills": [
            "Scoping",
            "Type checking"
          ],
          "fieldMix": [
            {
              "field": "Compiler and language tooling",
              "percentage": 100
            }
          ],
          "patterns": []
        },
        {
          "id": "34ce6bc2-e2b9-4efe-bb3c-ca839ad4c016",
          "key": "CTYPE-103",
          "title": "Explain rules-editor operator operand mismatches",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 90,
          "phaseId": "rules",
          "dependsOn": [
            "CTYPE-101",
            "CTYPE-102"
          ],
          "scenario": "Invalid addition reports Type error without naming either operand type. Add structured expected and actual types.",
          "acceptanceCriteria": [
            "Valid operands infer result",
            "Mismatch identifies operator span",
            "Diagnostic includes both operand types"
          ],
          "implementationNotes": [
            "Keep wording independent from internal object serialization."
          ],
          "verification": [
            "Add two numeric literals",
            "Add number to unsupported record"
          ],
          "deliverables": [
            "Operator rules and diagnostic cases"
          ],
          "rollout": "Reject ambiguous operators with explicit unsupported message.",
          "skills": [
            "Diagnostics",
            "Type rules"
          ],
          "fieldMix": [
            {
              "field": "Compiler and language tooling",
              "percentage": 100
            }
          ],
          "patterns": []
        },
        {
          "id": "8da7966d-9134-47d4-a6b1-5fdc5251e93c",
          "key": "CTYPE-104",
          "title": "Check function calls for arity before argument inference",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 135,
          "phaseId": "inference",
          "dependsOn": [
            "CTYPE-102",
            "CTYPE-103"
          ],
          "scenario": "Calling a two-argument function with one argument crashes inference. Validate arity and check only supplied expressions safely.",
          "acceptanceCriteria": [
            "Correct arity checks all arguments",
            "Wrong arity reports counts",
            "Nested argument errors remain inspectable"
          ],
          "implementationNotes": [
            "Avoid fabricating missing AST nodes."
          ],
          "verification": [
            "Check valid call",
            "Call with too few and too many arguments"
          ],
          "deliverables": [
            "Call checker and arity cases"
          ],
          "rollout": "Disable call inference for malformed ASTs.",
          "skills": [
            "Type checking",
            "Validation"
          ],
          "fieldMix": [
            {
              "field": "Compiler and language tooling",
              "percentage": 100
            }
          ],
          "patterns": []
        },
        {
          "id": "b35388eb-5588-4bf1-93fb-147dda14fd63",
          "key": "CTYPE-105",
          "title": "Unify rules-editor type variables with an occurs check",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 240,
          "phaseId": "inference",
          "dependsOn": [
            "CTYPE-104"
          ],
          "scenario": "A recursive synthetic constraint produces an infinite inferred type. Reject self-containing substitutions.",
          "acceptanceCriteria": [
            "Acyclic constraints unify",
            "Recursive substitution fails with reason",
            "Failure does not corrupt remaining environment"
          ],
          "implementationNotes": [
            "Bound this ticket to monomorphic variable unification."
          ],
          "verification": [
            "Unify variable with number",
            "Attempt variable equal to function containing itself"
          ],
          "deliverables": [
            "Unifier and occurs-check cases"
          ],
          "rollout": "Disable variable inference if substitution integrity fails.",
          "skills": [
            "Unification",
            "Algorithms"
          ],
          "fieldMix": [
            {
              "field": "Compiler and language tooling",
              "percentage": 100
            }
          ],
          "patterns": []
        },
        {
          "id": "6f28bdd8-7ead-43d7-8d19-98e7d9fb1159",
          "key": "CTYPE-106",
          "title": "Report missing rules-editor record fields without losing known fields",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "inference",
          "dependsOn": [
            "CTYPE-103",
            "CTYPE-105"
          ],
          "scenario": "Reading an absent field turns the whole record into unknown and suppresses later valid diagnostics. Preserve field-level information.",
          "acceptanceCriteria": [
            "Existing field returns declared type",
            "Missing field names available keys within a cap",
            "Later checks retain known types"
          ],
          "implementationNotes": [
            "Do not expose arbitrary source values in diagnostics."
          ],
          "verification": [
            "Access known field",
            "Access absent field then known field"
          ],
          "deliverables": [
            "Record-access rule and recovery cases"
          ],
          "rollout": "Reject absent-field expression only while preserving surrounding scope.",
          "skills": [
            "Type systems",
            "Error recovery"
          ],
          "fieldMix": [
            {
              "field": "Compiler and language tooling",
              "percentage": 100
            }
          ],
          "patterns": []
        },
        {
          "id": "10f9529a-4608-474e-ae6f-ebbc05d16e19",
          "key": "CTYPE-107",
          "title": "Merge rules-editor branch types through explicit compatibility rules",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "inference",
          "dependsOn": [
            "CTYPE-105",
            "CTYPE-106"
          ],
          "scenario": "Conditional branches return incompatible values but the checker chooses the first branch type. Define their common result rule.",
          "acceptanceCriteria": [
            "Compatible branches infer documented type",
            "Incompatible branches report both spans",
            "Condition must be boolean"
          ],
          "implementationNotes": [
            "Do not introduce implicit coercion without a declared rule."
          ],
          "verification": [
            "Check matching branches",
            "Check number versus record branches"
          ],
          "deliverables": [
            "Conditional rule and compatibility cases"
          ],
          "rollout": "Reject mixed branches until the rule is stable.",
          "skills": [
            "Type inference",
            "Control flow"
          ],
          "fieldMix": [
            {
              "field": "Compiler and language tooling",
              "percentage": 100
            }
          ],
          "patterns": []
        },
        {
          "id": "b91ba8bf-6445-452f-a499-c24ae8a3a001",
          "key": "CTYPE-108",
          "title": "Make rules-editor diagnostics deterministic across map insertion order",
          "type": "BUG",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 120,
          "phaseId": "stability",
          "dependsOn": [
            "CTYPE-106",
            "CTYPE-107"
          ],
          "scenario": "Equivalent AST construction order changes diagnostic output and noisy snapshots. Sort by source and stable category.",
          "acceptanceCriteria": [
            "Equivalent inputs yield same order",
            "Related locations stay attached",
            "Equal-span tie-breaking is documented"
          ],
          "implementationNotes": [
            "Determinism must not remove distinct failures."
          ],
          "verification": [
            "Reorder environment construction",
            "Create two same-span categories"
          ],
          "deliverables": [
            "Diagnostic ordering and cases"
          ],
          "rollout": "Preserve stable source traversal if sorting loses relationships.",
          "skills": [
            "Determinism",
            "Diagnostics"
          ],
          "fieldMix": [
            {
              "field": "Compiler and language tooling",
              "percentage": 100
            }
          ],
          "patterns": []
        },
        {
          "id": "8963cb6c-1945-444e-a308-210ef64c9faa",
          "key": "CTYPE-109",
          "title": "Cancel obsolete rules-editor checks without publishing stale results",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "stability",
          "dependsOn": [
            "CTYPE-107",
            "CTYPE-108"
          ],
          "scenario": "Editor edits finish out of order and older type errors replace current diagnostics. Scope checking to document version.",
          "acceptanceCriteria": [
            "Only current version publishes",
            "Cancellation releases resources",
            "Late completion cannot overwrite"
          ],
          "implementationNotes": [
            "Include document identity as well as version."
          ],
          "verification": [
            "Complete current check",
            "Resolve old check after replacement"
          ],
          "deliverables": [
            "Versioned checking coordinator"
          ],
          "rollout": "Run serial checks if publication ownership fails.",
          "skills": [
            "Concurrency",
            "Language tooling"
          ],
          "fieldMix": [
            {
              "field": "Compiler and language tooling",
              "percentage": 80
            },
            {
              "field": "Performance engineering",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "85101b60-aeb7-447d-a468-5b67acf76cd7",
          "key": "CTYPE-110",
          "title": "Bound rules-editor inference work with explicit incomplete status",
          "type": "CHORE",
          "priority": "MEDIUM",
          "difficulty": "EXPERT",
          "estimateMinutes": 210,
          "phaseId": "stability",
          "dependsOn": [
            "CTYPE-105",
            "CTYPE-109"
          ],
          "scenario": "Adversarial nested constraints consume excessive work. Add operation and depth budgets with honest termination status.",
          "acceptanceCriteria": [
            "Supported fixtures complete",
            "Budget exhaustion is explicit",
            "Incomplete checks cannot claim type safety"
          ],
          "implementationNotes": [
            "Use deterministic counters rather than wall time alone."
          ],
          "verification": [
            "Check normal corpus",
            "Exceed constraint budget"
          ],
          "deliverables": [
            "Inference budget and stress cases"
          ],
          "rollout": "Lower limits and mark affected files incomplete until improved.",
          "skills": [
            "Resource limits",
            "Static analysis"
          ],
          "fieldMix": [
            {
              "field": "Compiler and language tooling",
              "percentage": 60
            },
            {
              "field": "Performance engineering",
              "percentage": 40
            }
          ],
          "patterns": []
        }
      ]
    }
  ]
}
