{
  "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": "b83998ec-d76e-456c-a667-6064568ba37e",
      "key": "ACACHE",
      "title": "Keep shared product caches consistent across writers",
      "field": "Distributed systems",
      "summary": "Invalidate and refresh tenant-scoped product views without resurrecting stale versions.",
      "context": "A fictional wholesale portal caches product availability descriptions across several API instances. Delayed invalidations and slow refreshes bring back old content after edits.",
      "stack": [
        "TypeScript",
        "PostgreSQL",
        "Redis"
      ],
      "prerequisites": [
        "Create two local cache clients and a synthetic authoritative product store.",
        "Use a fake clock and controllable read/write barriers."
      ],
      "developerValue": "Practice cache consistency, version guards and recoverable invalidation.",
      "companyValue": "Review fast derived reads without losing authoritative state or tenant isolation.",
      "delivery": "Ten scoped tickets across three phases. Build a synthetic local service or select a ticket after recreating its prerequisites; estimates exclude setup.",
      "phases": [
        {
          "id": "identity",
          "title": "Define cache meaning",
          "goal": "Bind keys, versions and freshness to authoritative data."
        },
        {
          "id": "refresh",
          "title": "Guard shared refreshes",
          "goal": "Order writes, invalidations and concurrent fills."
        },
        {
          "id": "failure",
          "title": "Recover cache uncertainty",
          "goal": "Handle outages, reconcile generations and expose staleness."
        }
      ],
      "tickets": [
        {
          "id": "56909d89-0541-4001-9245-44d7947d017e",
          "key": "ACACHE-101",
          "title": "Define cache keys from every product-view authority input",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 90,
          "phaseId": "identity",
          "dependsOn": [],
          "scenario": "Two customer organizations request the same SKU but have different visible product descriptions, and the shared cache returns the first result.",
          "acceptanceCriteria": [
            "Bind keys to organization, view policy and product identity.",
            "Authorize before cache lookup.",
            "Version the key namespace for incompatible projection changes."
          ],
          "implementationNotes": [
            "Do not include secrets or raw personal data in keys."
          ],
          "verification": [
            "Cache different permitted views of the same synthetic SKU.",
            "Request another organization's view and verify no cross-scope hit."
          ],
          "deliverables": [
            "Canonical cache-key contract"
          ],
          "rollout": "Introduce a fresh namespace and expire the affected old namespace.",
          "skills": [
            "Cache identity",
            "Tenant isolation"
          ],
          "fieldMix": [
            {
              "field": "Distributed systems",
              "percentage": 50
            },
            {
              "field": "Security",
              "percentage": 50
            }
          ],
          "patterns": []
        },
        {
          "id": "fa7bfc5d-b923-4fb9-896e-0d10ba1e5eb7",
          "key": "ACACHE-102",
          "title": "Specify what stale product data the portal may display",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 150,
          "phaseId": "identity",
          "dependsOn": [
            "ACACHE-101"
          ],
          "scenario": "The cache uses one TTL for descriptive text and order-critical availability, though they have different correctness needs.",
          "acceptanceCriteria": [
            "Classify fields by tolerated staleness.",
            "Keep authoritative order decisions outside stale display data.",
            "Define fresh, stale-allowed and unusable cache states."
          ],
          "implementationNotes": [
            "Use explicit hypothetical freshness bounds with product approval noted as pending."
          ],
          "verification": [
            "Serve stale descriptive text within the declared window.",
            "Reject using stale cached availability to authorize an order."
          ],
          "deliverables": [
            "Cache consistency matrix"
          ],
          "rollout": "Review the matrix before changing TTLs; leave unresolved critical reads authoritative.",
          "skills": [
            "Consistency policy",
            "Data semantics"
          ],
          "fieldMix": [
            {
              "field": "Distributed systems",
              "percentage": 60
            },
            {
              "field": "System design",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "ad1e051e-435c-441d-a2b2-04264d766757",
          "key": "ACACHE-103",
          "title": "Record authoritative product revision with each cached projection",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 90,
          "phaseId": "identity",
          "dependsOn": [
            "ACACHE-101",
            "ACACHE-102"
          ],
          "scenario": "An API instance receives two cached values but cannot tell which reflects the newer database update.",
          "acceptanceCriteria": [
            "Store source revision and projection version with the value.",
            "Reject malformed or unknown envelopes.",
            "Keep fetch time separate from source revision."
          ],
          "implementationNotes": [
            "Do not use cache write time as data ordering authority."
          ],
          "verification": [
            "Compare cached revisions 7 and 8.",
            "Read an envelope missing revision and treat it as unusable."
          ],
          "deliverables": [
            "Versioned cache envelope"
          ],
          "rollout": "Deploy readers that accept the envelope before enabling new writers; miss safely on legacy values.",
          "skills": [
            "Versioning",
            "Cache contracts"
          ],
          "fieldMix": [
            {
              "field": "Distributed systems",
              "percentage": 80
            },
            {
              "field": "API design",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "c1d285f5-80bd-4cf7-b543-c8155e8a9f87",
          "key": "ACACHE-104",
          "title": "Commit product changes with a durable invalidation fact",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 240,
          "phaseId": "refresh",
          "dependsOn": [
            "ACACHE-101",
            "ACACHE-103"
          ],
          "scenario": "The product write commits and then the process dies before deleting shared cache keys.",
          "acceptanceCriteria": [
            "Persist the product revision and invalidation outbox fact atomically.",
            "Bind invalidation identity to product scope and revision.",
            "Replay invalidation safely after a crash."
          ],
          "implementationNotes": [
            "Cache failure must not roll back an already committed product change."
          ],
          "verification": [
            "Crash after database commit and dispatch the retained invalidation.",
            "Replay the same invalidation and retain correct cache state."
          ],
          "deliverables": [
            "Product/outbox transaction and recovery test"
          ],
          "rollout": "Canary one synthetic product class; monitor pending invalidations and fall back to authoritative reads when stale bounds expire.",
          "skills": [
            "Transactional outbox",
            "Invalidation"
          ],
          "fieldMix": [
            {
              "field": "Distributed systems",
              "percentage": 60
            },
            {
              "field": "Database engineering",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "babc7479-8875-4c9e-b660-e9ba5aba6f69",
          "key": "ACACHE-105",
          "title": "Prevent a slow cache fill from overwriting a newer product revision",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 300,
          "phaseId": "refresh",
          "dependsOn": [
            "ACACHE-103",
            "ACACHE-104"
          ],
          "scenario": "A read for revision 7 starts before an edit, then finishes after revision 8 has already been cached and overwrites it.",
          "acceptanceCriteria": [
            "Use an atomic revision comparison when publishing a fill.",
            "Reject lower source revisions regardless of completion order.",
            "Keep projection-version incompatibility separate from source ordering."
          ],
          "implementationNotes": [
            "Implement with a bounded Redis script or provider-level compare-and-set."
          ],
          "verification": [
            "Pause an old fill, publish the new revision, then resume the old fill.",
            "Attempt a malformed revision and verify it cannot replace the current value."
          ],
          "deliverables": [
            "Version-guarded fill and race reproduction"
          ],
          "rollout": "Canary guarded fills; disable cache publication if the adapter lacks atomic comparison.",
          "skills": [
            "Compare-and-set",
            "Concurrency"
          ],
          "fieldMix": [
            {
              "field": "Distributed systems",
              "percentage": 80
            },
            {
              "field": "Database engineering",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "80a42db5-aa79-4ec3-bc6d-4df60ed83d48",
          "key": "ACACHE-106",
          "title": "Handle delayed invalidation without evicting a newer cache revision unnecessarily",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "ADVANCED",
          "estimateMinutes": 210,
          "phaseId": "refresh",
          "dependsOn": [
            "ACACHE-104",
            "ACACHE-105"
          ],
          "scenario": "An old invalidation arrives after a fresh fill and deletes valid data, triggering avoidable refresh work across instances.",
          "acceptanceCriteria": [
            "Compare invalidation revision with cached source revision.",
            "Evict or mark stale only entries covered by the event.",
            "Treat missing or incompatible envelopes as safe misses."
          ],
          "implementationNotes": [
            "Keep invalidation decisions atomic with cache state inspection."
          ],
          "verification": [
            "Deliver revision 7 invalidation against cached revision 8 and retain it.",
            "Deliver matching/newer invalidation and enforce the declared stale behavior."
          ],
          "deliverables": [
            "Revision-aware invalidation and ordering tests"
          ],
          "rollout": "Enable after envelope rollout; fall back to conservative eviction on unknown formats.",
          "skills": [
            "Event ordering",
            "Cache invalidation"
          ],
          "fieldMix": [
            {
              "field": "Distributed systems",
              "percentage": 100
            }
          ],
          "patterns": []
        },
        {
          "id": "34520256-4547-4b16-9903-83ae9f3eae70",
          "key": "ACACHE-107",
          "title": "Bound duplicate refresh work across API instances",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 180,
          "phaseId": "refresh",
          "dependsOn": [
            "ACACHE-102",
            "ACACHE-105",
            "ACACHE-106"
          ],
          "scenario": "A popular product expires and every API instance refreshes it simultaneously, increasing pressure on the source database.",
          "acceptanceCriteria": [
            "Use a bounded per-key refresh ownership mechanism.",
            "Waiters have a deadline and declared stale/miss fallback.",
            "Expired refresh ownership cannot publish an older revision."
          ],
          "implementationNotes": [
            "A refresh lock reduces duplicate work; revision fencing still protects correctness."
          ],
          "verification": [
            "Request one expired synthetic key from two clients and observe bounded refresh calls.",
            "Pause the owner past expiry and verify stale completion cannot overwrite newer data."
          ],
          "deliverables": [
            "Shared refresh coordinator and expired-owner test"
          ],
          "rollout": "Canary a small key cohort; disable coordination while retaining revision guards if locks stall.",
          "skills": [
            "Single-flight",
            "Lease limits"
          ],
          "fieldMix": [
            {
              "field": "Distributed systems",
              "percentage": 60
            },
            {
              "field": "Performance engineering",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "36edf2a6-ec3d-4b3a-b0d1-abef4fa23210",
          "key": "ACACHE-108",
          "title": "Fall back predictably when the shared cache is unavailable",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "ADVANCED",
          "estimateMinutes": 210,
          "phaseId": "failure",
          "dependsOn": [
            "ACACHE-102",
            "ACACHE-104",
            "ACACHE-107"
          ],
          "scenario": "A Redis outage makes every request retry repeatedly, overwhelming the authoritative database while users wait.",
          "acceptanceCriteria": [
            "Bound cache attempts and stop retry amplification.",
            "Apply an explicit source-read admission limit.",
            "Return the declared degraded or unavailable response when both paths lack capacity."
          ],
          "implementationNotes": [
            "Use local adapter failures and synthetic requests."
          ],
          "verification": [
            "Disconnect the cache and serve an admitted authoritative read.",
            "Exceed fallback admission and return a bounded failure without unbounded source calls."
          ],
          "deliverables": [
            "Cache-outage fallback and overload probe"
          ],
          "rollout": "Canary with conservative fallback limits; shed excess reads until cache recovery is verified.",
          "skills": [
            "Failure containment",
            "Admission control"
          ],
          "fieldMix": [
            {
              "field": "Distributed systems",
              "percentage": 40
            },
            {
              "field": "Site reliability",
              "percentage": 30
            },
            {
              "field": "Performance engineering",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "9d4fb00f-a9ab-4a0a-92a2-7a4b8b1b2da9",
          "key": "ACACHE-109",
          "title": "Reconcile cache generations after a projection-schema release",
          "type": "CHORE",
          "priority": "MEDIUM",
          "difficulty": "EXPERT",
          "estimateMinutes": 300,
          "phaseId": "failure",
          "dependsOn": [
            "ACACHE-103",
            "ACACHE-105",
            "ACACHE-108"
          ],
          "scenario": "A new release changes product projection shape while old and new API instances share cached envelopes.",
          "acceptanceCriteria": [
            "Use explicit projection namespaces and compatible-reader declarations.",
            "Warm a new namespace from authoritative revisions.",
            "Retire the old namespace only after old readers are gone."
          ],
          "implementationNotes": [
            "Do not rewrite old cache values into a guessed new schema."
          ],
          "verification": [
            "Run mixed-version clients against their declared namespaces.",
            "Send a new envelope to an incompatible reader and verify safe miss or rejection."
          ],
          "deliverables": [
            "Cache-generation rollout and compatibility drill"
          ],
          "rollout": "Switch one synthetic cohort first; restore its previous namespace while keeping authoritative data unchanged.",
          "skills": [
            "Schema compatibility",
            "Recovery"
          ],
          "fieldMix": [
            {
              "field": "Distributed systems",
              "percentage": 70
            },
            {
              "field": "Platform engineering",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "4bd4dbb6-77c3-4cf7-941f-4f2217e5289a",
          "key": "ACACHE-110",
          "title": "Expose cache freshness observations without claiming source correctness",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 90,
          "phaseId": "failure",
          "dependsOn": [
            "ACACHE-102",
            "ACACHE-108",
            "ACACHE-109"
          ],
          "scenario": "The dashboard shows a high hit rate as proof the product data is correct, though hit count says nothing about revision freshness.",
          "acceptanceCriteria": [
            "Report hit/miss, source revision and observed freshness separately.",
            "Mark unknown source comparison explicitly.",
            "Avoid exposing product payloads in generic telemetry."
          ],
          "implementationNotes": [
            "Metrics describe cache behavior, not business-data correctness."
          ],
          "verification": [
            "Observe a fresh hit with a known source revision.",
            "Hide source revision availability and report unknown freshness despite a cache hit."
          ],
          "deliverables": [
            "Cache health projection and semantics notes"
          ],
          "rollout": "Add freshness diagnostics before tuning hit-rate targets; retain unknown states during outages.",
          "skills": [
            "Observability",
            "Metric semantics"
          ],
          "fieldMix": [
            {
              "field": "Distributed systems",
              "percentage": 50
            },
            {
              "field": "Site reliability",
              "percentage": 50
            }
          ],
          "patterns": []
        }
      ]
    }
  ]
}
