{
  "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": "0dce159a-d7f5-41f9-8a92-a36a34e76367",
      "key": "PCACHE",
      "title": "Keep product availability caching correct during a traffic spike",
      "summary": "Measure cache value, prevent refill storms and bound staleness without hiding origin failures.",
      "context": "A fictional equipment-rental service caches availability summaries. A campaign sends repeated reads, while stock updates and shared expiry times create bursts against the origin. Build a local origin stub and cache-backed read API using synthetic depots and products.",
      "stack": [
        "TypeScript",
        "Redis",
        "HTTP",
        "k6"
      ],
      "prerequisites": [
        "Create a deterministic local availability origin and Redis-backed reader with synthetic tenant, depot and product data.",
        "Use a seeded hot-key distribution and controlled time; record cache capacity, TTLs, runtime and machine limits."
      ],
      "developerValue": "Learn to evaluate caching through avoided work, bounded staleness, concurrency and recovery rather than hit rate alone.",
      "companyValue": "Produce a reviewable cache policy and failure exercise for a read-heavy service with changing business data.",
      "delivery": "Ten tickets in three phases. Availability is informational; booking remains an authoritative origin operation. All load and failure experiments use owned local services.",
      "phases": [
        {
          "id": "model",
          "title": "Define cache meaning and baseline",
          "goal": "Specify keys, freshness and measurements before optimization."
        },
        {
          "id": "control",
          "title": "Bound cache work and staleness",
          "goal": "Handle simultaneous misses, updates and failure without serving another tenant or hiding stale data."
        },
        {
          "id": "recover",
          "title": "Validate degraded and release behavior",
          "goal": "Exercise cache loss, policy changes and measurable promotion gates."
        }
      ],
      "field": "Performance engineering",
      "tickets": [
        {
          "id": "02a941ba-09b0-4aad-b909-cd250c648ffb",
          "key": "PCACHE-101",
          "title": "Specify which availability responses may be reused",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 75,
          "phaseId": "model",
          "dependsOn": [],
          "scenario": "Two requests for the same product receive different answers because depot and tenant affect availability. The prototype cache key contains only the product ID.",
          "acceptanceCriteria": [
            "Include tenant, depot, product and response-schema version in an unambiguous cache-key contract.",
            "State the maximum informational freshness window and keep booking decisions on the authoritative origin.",
            "Define which errors and absence responses are cacheable, with a separate bounded lifetime where appropriate."
          ],
          "implementationNotes": [
            "Use opaque synthetic identifiers and avoid leaking sensitive request values through diagnostic key labels."
          ],
          "verification": [
            "Request the same product from two depots and tenants and verify no shared response.",
            "Construct delimiter-collision inputs and confirm distinct semantic keys remain distinct."
          ],
          "deliverables": [
            "Cache-key and freshness contract with boundary fixtures"
          ],
          "rollout": "Introduce a new key namespace for the contract; expiry cleans old derived entries without rewriting authoritative availability.",
          "skills": [
            "Cache semantics",
            "Tenant isolation"
          ],
          "fieldMix": [
            {
              "field": "API design",
              "percentage": 40
            },
            {
              "field": "Security",
              "percentage": 30
            },
            {
              "field": "Performance engineering",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "164eced6-74a0-4fcd-81e8-8a49d1d7979c",
          "key": "PCACHE-102",
          "title": "Measure saved origin work instead of celebrating the hit ratio",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 90,
          "phaseId": "model",
          "dependsOn": [
            "PCACHE-101"
          ],
          "scenario": "The cache reports a high hit ratio, but every hit still triggers a synchronous origin validation and costs almost as much as a miss.",
          "acceptanceCriteria": [
            "Record hits, misses, stale responses, origin calls, origin work duration and end-to-end request latency separately.",
            "Use bounded labels and report the same workload window and request counts for all rates.",
            "Define avoided origin calls against an uncached run of the identical seeded requests."
          ],
          "implementationNotes": [
            "Do not combine cache and origin error outcomes into successful hits; expose failures and retries explicitly."
          ],
          "verification": [
            "Replay a repeated-key fixture and reconcile request count with cache outcomes and actual stub calls.",
            "Enable synchronous validation deliberately and verify the report reveals that high hit rate did not remove origin work."
          ],
          "deliverables": [
            "Cache effectiveness report and aggregate counters"
          ],
          "rollout": "Run counters beside the existing local behavior before policy changes; preserve raw attempt counts for comparisons.",
          "skills": [
            "Cache measurement",
            "Latency analysis"
          ],
          "fieldMix": [
            {
              "field": "Performance engineering",
              "percentage": 100
            }
          ],
          "patterns": []
        },
        {
          "id": "1fe083b2-747b-435f-9201-fe47d7b33e6a",
          "key": "PCACHE-103",
          "title": "Create a hot-key workload that exposes synchronized expiry",
          "type": "CHORE",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 120,
          "phaseId": "model",
          "dependsOn": [
            "PCACHE-101",
            "PCACHE-102"
          ],
          "scenario": "Uniform random keys miss often but never reproduce the traffic surge that arrives when the most popular products expire together.",
          "acceptanceCriteria": [
            "Generate a seeded workload where 80% of reads target 20 hot product/depot keys and the remainder sample a larger declared set.",
            "Include a synchronized-expiry phase, a cold start and a quiet recovery period.",
            "Record scheduled and achieved arrivals, timeouts and origin concurrency so generator saturation is visible."
          ],
          "implementationNotes": [
            "Use a controllable clock for unit-level expiry cases and a documented arrival schedule for load runs."
          ],
          "verification": [
            "Repeat the seed and compare key frequencies and expiry schedule.",
            "Run the uncached and cached paths against the same origin-delay fixture and retain all outcome counts."
          ],
          "deliverables": [
            "Hot-key generator and baseline workload manifest"
          ],
          "rollout": "Version the workload independently of cache implementation; changing the distribution starts a new comparison baseline.",
          "skills": [
            "Workload design",
            "Load testing"
          ],
          "fieldMix": [
            {
              "field": "Performance engineering",
              "percentage": 80
            },
            {
              "field": "Quality engineering",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "6c00414d-61f7-41e8-ad01-4c1b8b9bdb73",
          "key": "PCACHE-104",
          "title": "Coalesce simultaneous availability misses for one key",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 210,
          "phaseId": "control",
          "dependsOn": [
            "PCACHE-101",
            "PCACHE-103"
          ],
          "scenario": "Hundreds of requests miss the same just-expired key and each starts an identical origin read.",
          "acceptanceCriteria": [
            "Share one bounded in-flight fill per semantic key within the declared process scope.",
            "Give each waiter its own deadline and release the in-flight entry on success, failure and cancellation.",
            "Keep different tenants and keys independent, and document that process-local coalescing does not coordinate multiple instances."
          ],
          "implementationNotes": [
            "Use a deterministic origin latch to prove fan-in; a fast origin can hide duplicate concurrent fills in a timing-only test."
          ],
          "verification": [
            "Release 100 simultaneous same-key reads and verify one origin fill with identical successful results.",
            "Cancel some waiters and fail the fill; verify remaining outcomes, cleanup and a successful subsequent retry."
          ],
          "deliverables": [
            "Single-flight implementation and concurrency/failure regressions"
          ],
          "rollout": "Gate coalescing locally; disabling it preserves the same freshness contract and drains existing waiters before removing entries.",
          "skills": [
            "Request coalescing",
            "Cancellation"
          ],
          "fieldMix": [
            {
              "field": "Performance engineering",
              "percentage": 60
            },
            {
              "field": "Backend",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "0413ca4f-f697-42fe-9f4c-25d5b60e9bc4",
          "key": "PCACHE-105",
          "title": "Spread cache refill times without extending the freshness ceiling",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 150,
          "phaseId": "control",
          "dependsOn": [
            "PCACHE-101",
            "PCACHE-103"
          ],
          "scenario": "A bulk warmup writes every popular key with the same lifetime. They expire in one wave and overload the origin.",
          "acceptanceCriteria": [
            "Apply bounded expiry variation that never exceeds the declared maximum freshness window.",
            "Make the randomness injectable for repeatable tests and preserve explicit short-lived negative-cache policy.",
            "Report refill concurrency before and after under the synchronized-expiry fixture."
          ],
          "implementationNotes": [
            "Define whether jitter shortens lifetime or schedules refresh earlier; do not silently extend a business freshness bound."
          ],
          "verification": [
            "Generate many lifetimes with a fixed seed and verify all are positive and within the contractual ceiling.",
            "Replay the warmup/expiry workload and compare peak origin concurrency while checking response ages."
          ],
          "deliverables": [
            "Expiry policy, deterministic boundary tests and refill comparison"
          ],
          "rollout": "Roll out the new expiry policy only for newly written entries; reverting changes future writes while existing entries remain within the original ceiling.",
          "skills": [
            "Expiry policies",
            "Traffic smoothing"
          ],
          "fieldMix": [
            {
              "field": "Performance engineering",
              "percentage": 80
            },
            {
              "field": "Backend",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "3023627c-74b0-44f3-832a-10c5f94d3626",
          "key": "PCACHE-106",
          "title": "Serve stale availability only within an explicit degraded-read policy",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 330,
          "phaseId": "control",
          "dependsOn": [
            "PCACHE-101",
            "PCACHE-102",
            "PCACHE-104"
          ],
          "scenario": "During a short origin outage the cache can show useful recent information, but the prototype serves old availability indefinitely and presents it as current.",
          "acceptanceCriteria": [
            "Define fresh, stale-but-allowed and expired states with explicit age limits and response metadata.",
            "Choose bounded background refresh behavior and retain authoritative booking checks.",
            "After the hard age limit, return an explicit unavailable outcome rather than an apparently current availability summary."
          ],
          "implementationNotes": [
            "The policy concerns informational reads only. Preserve origin-error visibility and do not cache authorization failures as product absence."
          ],
          "verification": [
            "Advance the clock across both boundaries during origin success and failure, checking age metadata and result state.",
            "Run concurrent stale reads with a blocked refresh and verify bounded origin work and transition to unavailable after the hard limit."
          ],
          "deliverables": [
            "Freshness state machine, degraded-read implementation and boundary matrix"
          ],
          "rollout": "Canary with response-age and stale-outcome counters; disable stale serving immediately if clients fail to present the declared state.",
          "skills": [
            "Freshness modeling",
            "Graceful degradation"
          ],
          "fieldMix": [
            {
              "field": "Site reliability",
              "percentage": 50
            },
            {
              "field": "API design",
              "percentage": 30
            },
            {
              "field": "Performance engineering",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "ba777e5b-971a-410d-854d-c0284ffea4c2",
          "key": "PCACHE-107",
          "title": "Prevent a delayed refill from restoring availability older than an update",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 330,
          "phaseId": "control",
          "dependsOn": [
            "PCACHE-101",
            "PCACHE-104",
            "PCACHE-106"
          ],
          "scenario": "An origin read starts before a stock update, then finishes after invalidation and writes the old value back into the cache.",
          "acceptanceCriteria": [
            "Associate fills and updates with an explicit revision or generation rule.",
            "Reject an obsolete fill after a newer invalidation or value is known within the chosen coordination scope.",
            "Document behavior when invalidation delivery is delayed and preserve the hard freshness ceiling as a backstop."
          ],
          "implementationNotes": [
            "Use atomic cache operations where a check-and-set race matters; explain limits across multiple readers rather than claiming perfect global freshness."
          ],
          "verification": [
            "Hold an old origin response, apply a newer update, then release it and verify the cached revision does not go backward.",
            "Repeat the sequence with duplicate invalidations and a cache reconnect; verify the declared recovery behavior and age bound."
          ],
          "deliverables": [
            "Revision protocol, race regression and coordination-limit note"
          ],
          "rollout": "Introduce the revisioned namespace gradually; on uncertainty discard derived cache state and use the bounded origin path.",
          "skills": [
            "Race conditions",
            "Cache invalidation"
          ],
          "fieldMix": [
            {
              "field": "Distributed systems",
              "percentage": 60
            },
            {
              "field": "Performance engineering",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "8a9a9049-ba50-4b07-a590-fab2e5742ce7",
          "key": "PCACHE-108",
          "title": "Keep origin traffic bounded when the cache becomes unavailable",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 240,
          "phaseId": "recover",
          "dependsOn": [
            "PCACHE-102",
            "PCACHE-104",
            "PCACHE-106"
          ],
          "scenario": "A cache outage redirects the full request rate to the origin. The supposed fallback turns a small infrastructure fault into a wider outage.",
          "acceptanceCriteria": [
            "Set cache-client timeouts and bound origin fallback concurrency and queue length.",
            "Return an explicit overload or unavailable response when the fallback budget is exhausted.",
            "Recover cache use without a synchronized refill storm or continuing to queue expired callers."
          ],
          "implementationNotes": [
            "Exercise cache disconnect, slow response and recovery separately; do not rely only on a clean process shutdown."
          ],
          "verification": [
            "Run the hot-key load while making cache operations hang and assert bounded connection and origin work counts.",
            "Restore the cache during overload and verify queue drainage, timeout accounting and correct tenant-specific responses."
          ],
          "deliverables": [
            "Degraded-cache policy, failure injection and recovery traces"
          ],
          "rollout": "Canary the bounded fallback configuration locally; retain a switch that fails informational reads explicitly if fallback threatens the origin budget.",
          "skills": [
            "Fault isolation",
            "Backpressure"
          ],
          "fieldMix": [
            {
              "field": "Site reliability",
              "percentage": 60
            },
            {
              "field": "Performance engineering",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "72d58451-28e2-4539-924c-aa4745397272",
          "key": "PCACHE-109",
          "title": "Version availability cache payloads without flushing every tenant at once",
          "type": "CHORE",
          "priority": "MEDIUM",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "recover",
          "dependsOn": [
            "PCACHE-101",
            "PCACHE-105",
            "PCACHE-107"
          ],
          "scenario": "A response-field change makes older cached payloads unreadable. Flushing all keys would force a simultaneous cold start across the service.",
          "acceptanceCriteria": [
            "Write a new payload/key version and reject incompatible old payloads safely.",
            "Define a bounded warming or lazy-fill strategy and retain per-tenant scope.",
            "Make rollback behavior explicit when older readers encounter values written during the new release."
          ],
          "implementationNotes": [
            "Treat cache payloads as derived data; do not migrate authoritative stock records as part of this change."
          ],
          "verification": [
            "Run old and new readers against mixed-version fixtures and verify the documented compatibility behavior.",
            "Switch versions under the hot-key workload and measure origin refill concurrency without a global flush."
          ],
          "deliverables": [
            "Payload-version contract, compatibility tests and rollout procedure"
          ],
          "rollout": "Canary a small synthetic tenant set, then expand; rollback restores the prior namespace and lets unused versioned entries expire.",
          "skills": [
            "Schema compatibility",
            "Cache rollout"
          ],
          "fieldMix": [
            {
              "field": "Platform engineering",
              "percentage": 40
            },
            {
              "field": "API design",
              "percentage": 30
            },
            {
              "field": "Performance engineering",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "8bc9bf49-f0a2-44ca-ac51-d5462e96f097",
          "key": "PCACHE-110",
          "title": "Choose the cache policy from freshness, origin load and tail latency together",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 300,
          "phaseId": "recover",
          "dependsOn": [
            "PCACHE-104",
            "PCACHE-105",
            "PCACHE-106",
            "PCACHE-107",
            "PCACHE-108",
            "PCACHE-109"
          ],
          "scenario": "One policy gives the highest hit rate by serving older data. Another is fresh but overloads the origin at expiry. The team needs a decision tied to the actual contract.",
          "acceptanceCriteria": [
            "Run three paired repetitions of cold, warm, synchronized-expiry and cache-outage phases on the declared workload.",
            "For the warm phase require at least 60% fewer origin calls than uncached reads, no cross-tenant result and no response beyond the hard freshness limit.",
            "Require bounded origin concurrency in every phase and publish p95/p99, rejection and stale-response rates; mark invalid or noisy runs inconclusive."
          ],
          "implementationNotes": [
            "The avoided-call threshold is an exercise budget for the seeded hot-key distribution. Do not infer a production hit rate or freshness guarantee from it."
          ],
          "verification": [
            "Reconcile all attempted reads with results, cache states and actual origin calls for baseline and candidate.",
            "Revert the chosen configuration and repeat the outage/recovery phase, checking correctness and bounded work after rollback."
          ],
          "deliverables": [
            "Cache-policy decision, raw measurements and recovery handoff"
          ],
          "rollout": "Promote only the policy satisfying correctness and degraded-mode gates; rollback uses the documented namespace and bounded origin policy.",
          "skills": [
            "Performance tradeoffs",
            "Resilience testing"
          ],
          "fieldMix": [
            {
              "field": "Performance engineering",
              "percentage": 50
            },
            {
              "field": "Site reliability",
              "percentage": 30
            },
            {
              "field": "Quality engineering",
              "percentage": 20
            }
          ],
          "patterns": []
        }
      ]
    }
  ]
}
