{
  "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": "aeceae5d-eb1e-42b5-a19f-ba251320a8ba",
      "key": "BDNS",
      "title": "Service DNS migration lab",
      "field": "Networking",
      "summary": "Move a service endpoint while accounting for caches, negative answers, and resolver behavior.",
      "context": "A fictional internal API is moving to a new endpoint. The team assumes DNS changes are immediate and has no rehearsal for stale clients.",
      "stack": [
        "TypeScript",
        "DNS fixtures",
        "HTTP"
      ],
      "prerequisites": [
        "Create a local resolver simulator and two loopback service endpoints with synthetic DNS records; query no external infrastructure."
      ],
      "developerValue": "Practice DNS semantics, migration timing, and network diagnosis.",
      "companyValue": "Produce a migration plan that makes cache delay and endpoint compatibility explicit.",
      "delivery": "Deliver local DNS simulations and a cutover report; modify no real DNS records.",
      "phases": [
        {
          "id": "records",
          "title": "Model DNS responses",
          "goal": "Define record and cache semantics."
        },
        {
          "id": "migrate",
          "title": "Rehearse endpoint changes",
          "goal": "Handle stale clients and lookup failures."
        },
        {
          "id": "assess",
          "title": "Review cutover",
          "goal": "Choose timing and recovery controls."
        }
      ],
      "tickets": [
        {
          "id": "249e22a3-59c1-4588-a50e-8f5e583464b8",
          "key": "BDNS-101",
          "title": "Inventory service records and their consumers",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 60,
          "phaseId": "records",
          "dependsOn": [],
          "scenario": "The team knows the main hostname but not aliases used by background jobs.",
          "acceptanceCriteria": [
            "List record types, aliases, and modeled consumers.",
            "Identify ownership and current TTL.",
            "Mark unknown client caching behavior."
          ],
          "implementationNotes": [
            "Use reserved local test names only."
          ],
          "verification": [
            "Resolve the declared alias chain.",
            "Report an unknown consumer cache policy explicitly."
          ],
          "deliverables": [
            "DNS dependency inventory."
          ],
          "rollout": "Review inventory before scheduling a cutover.",
          "skills": [
            "DNS fundamentals"
          ],
          "fieldMix": [
            {
              "field": "Networking",
              "percentage": 100
            }
          ],
          "patterns": []
        },
        {
          "id": "bf6086e3-8102-4a40-bffe-a1e7b83b1e80",
          "key": "BDNS-102",
          "title": "Implement TTL-aware positive caching in the resolver fixture",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 120,
          "phaseId": "records",
          "dependsOn": [
            "BDNS-101"
          ],
          "scenario": "The simulator caches every answer forever and cannot represent migration delays.",
          "acceptanceCriteria": [
            "Expire answers using an injected clock.",
            "Honor the declared TTL without extending it on reads.",
            "Key cache entries by name and record type."
          ],
          "implementationNotes": [
            "Do not use wall-clock sleeps in tests."
          ],
          "verification": [
            "Serve a cached answer before expiry.",
            "Advance time and retrieve the changed authoritative answer."
          ],
          "deliverables": [
            "Positive-cache simulator."
          ],
          "rollout": "Validate the simulator against its documented semantics before using results.",
          "skills": [
            "Caching",
            "DNS"
          ],
          "fieldMix": [
            {
              "field": "Networking",
              "percentage": 60
            },
            {
              "field": "Performance engineering",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "cf50600f-9307-4e82-885d-1bd7185bdc21",
          "key": "BDNS-103",
          "title": "Model negative caching separately from empty address records",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "records",
          "dependsOn": [
            "BDNS-102"
          ],
          "scenario": "A temporary missing hostname remains unavailable after its record is created.",
          "acceptanceCriteria": [
            "Distinguish nonexistent name from no record of requested type.",
            "Apply declared negative-cache lifetime.",
            "Preserve the reason for cached negative answers."
          ],
          "implementationNotes": [
            "Use explicit fixture policy rather than claiming universal resolver behavior."
          ],
          "verification": [
            "Create a record after a negative lookup.",
            "Show recovery only after the modeled negative cache expires."
          ],
          "deliverables": [
            "Negative-cache scenarios."
          ],
          "rollout": "Avoid deleting names during cutover unless negative-cache effects are accepted.",
          "skills": [
            "DNS",
            "Failure analysis"
          ],
          "fieldMix": [
            {
              "field": "Networking",
              "percentage": 80
            },
            {
              "field": "Site reliability",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "39da833a-46b5-45ef-a09f-5f7627bd6a4c",
          "key": "BDNS-104",
          "title": "Reject alias loops and excessively deep resolution chains",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 120,
          "phaseId": "migrate",
          "dependsOn": [
            "BDNS-102"
          ],
          "scenario": "A mistaken alias points back to the original hostname and exhausts lookup work.",
          "acceptanceCriteria": [
            "Track visited aliases.",
            "Bound chain depth and response size.",
            "Return a clear resolution failure without partial success."
          ],
          "implementationNotes": [
            "The resolver fixture remains local and read-only."
          ],
          "verification": [
            "Resolve a valid multi-hop chain.",
            "Reject a loop and an over-depth chain."
          ],
          "deliverables": [
            "Alias validation."
          ],
          "rollout": "Validate proposed record sets before applying the synthetic change.",
          "skills": [
            "Graph traversal",
            "Resource bounds"
          ],
          "fieldMix": [
            {
              "field": "Networking",
              "percentage": 70
            },
            {
              "field": "Backend",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "7c85c9cf-6719-4a49-af03-da492dd31022",
          "key": "BDNS-105",
          "title": "Rehearse lowering TTL before endpoint cutover",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "migrate",
          "dependsOn": [
            "BDNS-102",
            "BDNS-103"
          ],
          "scenario": "Lowering TTL at the same moment as the address change does not shorten existing cached lifetimes.",
          "acceptanceCriteria": [
            "Model caches populated before and after TTL reduction.",
            "Calculate the required wait under declared assumptions.",
            "Track old and new endpoint usage during overlap."
          ],
          "implementationNotes": [
            "Do not promise that every real client respects TTL."
          ],
          "verification": [
            "Simulate an appropriately staged cutover.",
            "Show a stale pre-change cache after an immediate cutover."
          ],
          "deliverables": [
            "TTL staging rehearsal."
          ],
          "rollout": "Keep the old endpoint available through the documented overlap.",
          "skills": [
            "Migration planning"
          ],
          "fieldMix": [
            {
              "field": "Networking",
              "percentage": 60
            },
            {
              "field": "Site reliability",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "1208381a-6a1e-48d8-8aba-6d74458d6151",
          "key": "BDNS-106",
          "title": "Preserve application compatibility across old and new addresses",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "migrate",
          "dependsOn": [
            "BDNS-105"
          ],
          "scenario": "DNS propagation sends different clients to different service versions.",
          "acceptanceCriteria": [
            "Exercise the same public contract on both endpoints.",
            "Preserve shared operation identity across retries.",
            "Reject incompatible old/new behavior before cutover."
          ],
          "implementationNotes": [
            "Use synthetic requests and loopback endpoints."
          ],
          "verification": [
            "Complete retries across both endpoints.",
            "Detect a response-contract mismatch during overlap."
          ],
          "deliverables": [
            "Endpoint overlap checks."
          ],
          "rollout": "Deploy compatible service behavior before changing DNS.",
          "skills": [
            "Compatibility",
            "Networking"
          ],
          "fieldMix": [
            {
              "field": "Networking",
              "percentage": 40
            },
            {
              "field": "API design",
              "percentage": 40
            },
            {
              "field": "Quality engineering",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "adbe8e8c-7b08-44dc-9a68-ff7614f15e89",
          "key": "BDNS-107",
          "title": "Distinguish resolver failure from application connection failure",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 150,
          "phaseId": "migrate",
          "dependsOn": [
            "BDNS-104",
            "BDNS-106"
          ],
          "scenario": "Operators see one generic network error for lookup failures and refused connections.",
          "acceptanceCriteria": [
            "Classify lookup, address selection, connection, and HTTP failures.",
            "Record bounded timing per stage.",
            "Keep hostnames and request data within the declared safe diagnostic policy."
          ],
          "implementationNotes": [
            "No packet payloads or credentials in generic logs."
          ],
          "verification": [
            "Diagnose a local nonexistent name.",
            "Resolve an address then distinguish refused connection."
          ],
          "deliverables": [
            "Network-stage diagnostics."
          ],
          "rollout": "Add classification before changing retry behavior.",
          "skills": [
            "Network diagnostics"
          ],
          "fieldMix": [
            {
              "field": "Networking",
              "percentage": 70
            },
            {
              "field": "Site reliability",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "5cdf40a3-177e-417d-acf2-102fd280ff4f",
          "key": "BDNS-108",
          "title": "Evaluate rollback when both old and new answers remain cached",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 300,
          "phaseId": "assess",
          "dependsOn": [
            "BDNS-105",
            "BDNS-106",
            "BDNS-107"
          ],
          "scenario": "Reverting the DNS record does not immediately send every client back to the old endpoint.",
          "acceptanceCriteria": [
            "Model multiple cache ages during rollback.",
            "Define service compatibility and overlap requirements.",
            "Compare DNS rollback with routing-level containment under declared constraints."
          ],
          "implementationNotes": [
            "Keep conclusions scoped to the simulated client population."
          ],
          "verification": [
            "Roll back with mixed cached answers.",
            "Expose clients that continue using the new endpoint until expiry."
          ],
          "deliverables": [
            "DNS recovery decision record."
          ],
          "rollout": "Retain both compatible endpoints until the modeled overlap and operational checks complete.",
          "skills": [
            "Distributed systems",
            "Recovery"
          ],
          "fieldMix": [
            {
              "field": "Networking",
              "percentage": 40
            },
            {
              "field": "Distributed systems",
              "percentage": 30
            },
            {
              "field": "Site reliability",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "24913884-11e1-4b8c-83f1-44fb1e8843a5",
          "key": "BDNS-109",
          "title": "Check IPv4 and IPv6 record migration independently",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "assess",
          "dependsOn": [
            "BDNS-108"
          ],
          "scenario": "Only the IPv4 record is updated while dual-stack clients continue using the old IPv6 endpoint.",
          "acceptanceCriteria": [
            "Track A and AAAA records separately.",
            "Rehearse differing cache ages by family.",
            "Verify contract compatibility on both local address families."
          ],
          "implementationNotes": [
            "If IPv6 is unavailable locally, label that execution unverified and use deterministic fixtures."
          ],
          "verification": [
            "Simulate synchronized family updates.",
            "Detect a stale AAAA record after A changes."
          ],
          "deliverables": [
            "Dual-stack DNS cutover checks."
          ],
          "rollout": "Require family-specific review before final endpoint retirement.",
          "skills": [
            "IPv6",
            "DNS"
          ],
          "fieldMix": [
            {
              "field": "Networking",
              "percentage": 80
            },
            {
              "field": "Quality engineering",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "21b490b7-5c22-4a1b-82d5-5cc59efb1674",
          "key": "BDNS-110",
          "title": "Write a DNS change record with cache assumptions",
          "type": "CHORE",
          "priority": "LOW",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 60,
          "phaseId": "assess",
          "dependsOn": [
            "BDNS-109"
          ],
          "scenario": "The handoff omits when TTL was lowered and when old endpoints can be removed.",
          "acceptanceCriteria": [
            "Record old/new values and effective times.",
            "List modeled cache and compatibility assumptions.",
            "Define endpoint retirement criteria."
          ],
          "implementationNotes": [
            "Use UTC timestamps and synthetic record identities."
          ],
          "verification": [
            "Follow the staged change from the record.",
            "Keep retirement blocked when a required client assumption is unknown."
          ],
          "deliverables": [
            "DNS cutover runbook."
          ],
          "rollout": "Preserve the change record after rollback or completion.",
          "skills": [
            "Runbooks"
          ],
          "fieldMix": [
            {
              "field": "Networking",
              "percentage": 70
            },
            {
              "field": "Site reliability",
              "percentage": 30
            }
          ],
          "patterns": []
        }
      ]
    }
  ]
}
