{
  "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": "91f3550e-2cb8-44ae-ba8c-3f540083146b",
      "key": "ADRIFT",
      "title": "Make subscription entitlements survive plan changes",
      "field": "Backend",
      "summary": "Resolve effective entitlements across scheduled and immediate plan changes.",
      "context": "A fictional document service grants storage and collaboration rights from subscriptions. Support cannot explain why delayed events restore old limits.",
      "stack": [
        "TypeScript",
        "NestJS",
        "PostgreSQL"
      ],
      "prerequisites": [
        "Create a local subscription API with synthetic accounts.",
        "Understand transactions and UTC intervals."
      ],
      "developerValue": "Practice temporal rules, concurrency and explainable API decisions.",
      "companyValue": "Review whether entitlement changes preserve customer access and produce supportable decisions.",
      "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": "contract",
          "title": "Define effective rights",
          "goal": "Specify entitlement periods and failure responses."
        },
        {
          "id": "change",
          "title": "Apply changes safely",
          "goal": "Preserve ordering and concurrent update invariants."
        },
        {
          "id": "support",
          "title": "Explain and recover",
          "goal": "Expose effective decisions and recover delayed changes."
        }
      ],
      "tickets": [
        {
          "id": "df462ec4-a772-482b-a7bc-d6532cbfdb87",
          "key": "ADRIFT-101",
          "title": "Specify the entitlement response at an exact effective instant",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 90,
          "phaseId": "contract",
          "dependsOn": [],
          "scenario": "Support compares screenshots from two time zones and cannot tell which storage limit applied when an upload failed.",
          "acceptanceCriteria": [
            "Return limit, effective UTC instant and plan revision.",
            "Document inclusive start and exclusive end boundaries.",
            "Reject an invalid timestamp without resolving rights."
          ],
          "implementationNotes": [
            "Use synthetic plan names and integer byte limits."
          ],
          "verification": [
            "Resolve immediately before and at a plan boundary.",
            "Reject a timestamp without an offset and verify no write."
          ],
          "deliverables": [
            "Versioned response contract and boundary fixtures"
          ],
          "rollout": "Introduce the versioned read route; remove routing if consumers reject it.",
          "skills": [
            "API contracts",
            "Temporal modeling"
          ],
          "fieldMix": [
            {
              "field": "API design",
              "percentage": 60
            },
            {
              "field": "Backend",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "53584c31-a0d8-4bcd-86a6-94f46d8c6089",
          "key": "ADRIFT-102",
          "title": "Keep manual account restrictions separate from plan allowances",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 150,
          "phaseId": "contract",
          "dependsOn": [
            "ADRIFT-101"
          ],
          "scenario": "A support restriction disappears when an account upgrades because both settings currently share one mutable limit.",
          "acceptanceCriteria": [
            "Store restriction and plan allowance with separate provenance.",
            "Return the effective minimum with both reasons.",
            "Removing a restriction restores the current plan allowance."
          ],
          "implementationNotes": [
            "Restrict mutation to an authorized support role."
          ],
          "verification": [
            "Upgrade a restricted account and retain its lower limit.",
            "Attempt a restriction change as a normal member and deny it."
          ],
          "deliverables": [
            "Restriction command and permission tests"
          ],
          "rollout": "Enable for synthetic accounts; disable mutation while retaining restriction history.",
          "skills": [
            "Domain modeling",
            "Authorization"
          ],
          "fieldMix": [
            {
              "field": "Backend",
              "percentage": 70
            },
            {
              "field": "Security",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "189ad5cd-e676-4300-b9f1-dcf946e0da64",
          "key": "ADRIFT-103",
          "title": "Reject negative and fractional seat allowances consistently",
          "type": "BUG",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 60,
          "phaseId": "contract",
          "dependsOn": [
            "ADRIFT-101"
          ],
          "scenario": "An administrative import accepts 2.5 seats, while the runtime truncates the value differently from the billing preview.",
          "acceptanceCriteria": [
            "Accept only nonnegative safe integers for seat limits.",
            "Use one validation rule for import and API commands.",
            "Return the offending field without echoing the entire import."
          ],
          "implementationNotes": [
            "Represent unlimited explicitly rather than with negative sentinels."
          ],
          "verification": [
            "Create zero-seat and unlimited synthetic plans.",
            "Reject fractional, negative and unsafe integer limits."
          ],
          "deliverables": [
            "Shared seat schema and import regression"
          ],
          "rollout": "Deploy validation before new imports; quarantine rejected rows for correction.",
          "skills": [
            "Validation",
            "TypeScript"
          ],
          "fieldMix": [
            {
              "field": "Backend",
              "percentage": 80
            },
            {
              "field": "API design",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "8c452e1a-d494-44fe-8c0d-9db19ffb8daa",
          "key": "ADRIFT-104",
          "title": "Apply a scheduled downgrade only after its stored effective time",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 180,
          "phaseId": "change",
          "dependsOn": [
            "ADRIFT-101",
            "ADRIFT-103"
          ],
          "scenario": "A worker runs the next day's downgrade early when a retry executes against the server's local calendar date.",
          "acceptanceCriteria": [
            "Compare a persisted UTC instant with an injected clock.",
            "Early delivery leaves the schedule pending.",
            "Repeated eligible delivery creates one entitlement revision."
          ],
          "implementationNotes": [
            "Persist the revision and dispatch record in one transaction."
          ],
          "verification": [
            "Advance a fake clock through the exact effective instant.",
            "Deliver early and twice after the boundary; count one revision."
          ],
          "deliverables": [
            "Scheduled transition and deterministic-clock tests"
          ],
          "rollout": "Canary scheduled changes; pause the consumer and retain pending schedules on failure.",
          "skills": [
            "State transitions",
            "Idempotency"
          ],
          "fieldMix": [
            {
              "field": "Backend",
              "percentage": 80
            },
            {
              "field": "Distributed systems",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "f961e265-1e5a-4d00-a9ef-257b52638c9c",
          "key": "ADRIFT-105",
          "title": "Prevent a late upgrade event from undoing a newer cancellation",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 240,
          "phaseId": "change",
          "dependsOn": [
            "ADRIFT-104"
          ],
          "scenario": "Provider events arrive out of order and an old upgrade reopens collaboration after cancellation became effective.",
          "acceptanceCriteria": [
            "Compare provider sequence within each subscription.",
            "Older events remain recorded without changing effective rights.",
            "Equal sequence with different payload is surfaced as conflict."
          ],
          "implementationNotes": [
            "Do not order provider events by receipt timestamp."
          ],
          "verification": [
            "Replay cancellation followed by an older upgrade.",
            "Submit contradictory equal-sequence events and preserve current rights."
          ],
          "deliverables": [
            "Ordering guard and conflicting-event report"
          ],
          "rollout": "Run the guard in audit mode first; quarantine conflicts without deleting events.",
          "skills": [
            "Event ordering",
            "Conflict handling"
          ],
          "fieldMix": [
            {
              "field": "Backend",
              "percentage": 60
            },
            {
              "field": "Distributed systems",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "65e1fe79-ac52-4674-b60f-676c59c6fb32",
          "key": "ADRIFT-106",
          "title": "Make plan switching and seat allocation share one consistency boundary",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 360,
          "phaseId": "change",
          "dependsOn": [
            "ADRIFT-102",
            "ADRIFT-104"
          ],
          "scenario": "A downgrade races a seat invitation; both requests pass their reads and leave more active seats than permitted.",
          "acceptanceCriteria": [
            "Serialize competing allowance and allocation changes per account.",
            "One conflicting request returns a retryable conflict.",
            "A failed transaction leaves both seat count and rights unchanged."
          ],
          "implementationNotes": [
            "Document the invariant and chosen locking order."
          ],
          "verification": [
            "Run a two-client barrier test for downgrade versus invitation.",
            "Force transaction rollback and check both tables retain prior values."
          ],
          "deliverables": [
            "Transactional guard and concurrency reproduction"
          ],
          "rollout": "Introduce with lock-wait monitoring; revert command routing if contention exceeds the documented local budget.",
          "skills": [
            "Transactions",
            "Concurrency"
          ],
          "fieldMix": [
            {
              "field": "Database engineering",
              "percentage": 60
            },
            {
              "field": "Backend",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "3a9a138e-0fbb-48d5-b55a-b283418c58cb",
          "key": "ADRIFT-107",
          "title": "Preview entitlement changes without creating pending work",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 150,
          "phaseId": "change",
          "dependsOn": [
            "ADRIFT-104",
            "ADRIFT-105"
          ],
          "scenario": "Sales wants to preview next month's downgrade, but the current preview endpoint creates a schedule visible to the worker.",
          "acceptanceCriteria": [
            "Preview uses the same pure decision function as execution.",
            "Return affected features and effective-time assumptions.",
            "No schedule, outbox or audit mutation occurs on preview."
          ],
          "implementationNotes": [
            "Authorize account reads before computing the preview."
          ],
          "verification": [
            "Compare preview with a later applied synthetic change.",
            "Repeat preview and assert unchanged row counts; deny another account."
          ],
          "deliverables": [
            "Pure preview operation and nonmutation checks"
          ],
          "rollout": "Expose preview behind a route flag; remove the route without touching schedules.",
          "skills": [
            "Pure functions",
            "API design"
          ],
          "fieldMix": [
            {
              "field": "Backend",
              "percentage": 70
            },
            {
              "field": "API design",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "d1fcae8c-52cc-4e8d-bbd2-d8d789d846f5",
          "key": "ADRIFT-108",
          "title": "Explain a denied upload using the exact entitlement revision",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "support",
          "dependsOn": [
            "ADRIFT-105",
            "ADRIFT-106"
          ],
          "scenario": "An upload rejection says only limit exceeded, so support cannot connect it to the plan and restriction that were evaluated.",
          "acceptanceCriteria": [
            "Return a stable denial code and evaluated revision ID.",
            "Include byte limit and current usage without other accounts' data.",
            "Keep historical revisions immutable for later explanation."
          ],
          "implementationNotes": [
            "Avoid storing document contents in decision logs."
          ],
          "verification": [
            "Reproduce a denial and resolve the same historical decision after upgrade.",
            "Request another account's decision ID and return a nondisclosing denial."
          ],
          "deliverables": [
            "Decision projection and scoped history route"
          ],
          "rollout": "Enable explanation reads first; disable projection if privacy checks fail.",
          "skills": [
            "Provenance",
            "Tenant isolation"
          ],
          "fieldMix": [
            {
              "field": "Backend",
              "percentage": 70
            },
            {
              "field": "API design",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "a888e995-caa9-4c71-90fb-baf195e41534",
          "key": "ADRIFT-109",
          "title": "Rebuild an account entitlement projection from its ordered history",
          "type": "CHORE",
          "priority": "MEDIUM",
          "difficulty": "EXPERT",
          "estimateMinutes": 360,
          "phaseId": "support",
          "dependsOn": [
            "ADRIFT-105",
            "ADRIFT-108"
          ],
          "scenario": "A projection bug affected a synthetic account; operators need to repair derived rights without rewriting the source change history.",
          "acceptanceCriteria": [
            "Rebuild into a separate generation using deterministic ordering.",
            "Compare differences before atomically selecting the generation.",
            "Interrupted rebuild leaves the active projection usable."
          ],
          "implementationNotes": [
            "Require an account scope and dry-run mode."
          ],
          "verification": [
            "Compare a rebuilt generation with a clean reference history.",
            "Interrupt before activation and prove the old generation still resolves."
          ],
          "deliverables": [
            "Scoped rebuild command and difference report"
          ],
          "rollout": "Dry-run one synthetic account; restore the previous generation pointer on mismatch.",
          "skills": [
            "Recovery",
            "Projection design"
          ],
          "fieldMix": [
            {
              "field": "Data engineering",
              "percentage": 50
            },
            {
              "field": "Backend",
              "percentage": 30
            },
            {
              "field": "Database engineering",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "5cd2d519-47fa-42c3-80c5-d377c3c2fa82",
          "key": "ADRIFT-110",
          "title": "Document the handoff for disputed effective entitlements",
          "type": "TASK",
          "priority": "LOW",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 90,
          "phaseId": "support",
          "dependsOn": [
            "ADRIFT-108",
            "ADRIFT-109"
          ],
          "scenario": "Support needs a repeatable path to investigate a rights dispute without editing rows directly or promising the wrong allowance.",
          "acceptanceCriteria": [
            "Runbook starts from account, decision and revision identifiers.",
            "Separate delayed-provider, restriction and usage causes.",
            "Include escalation and projection rollback steps."
          ],
          "implementationNotes": [
            "Use fabricated examples and avoid raw customer identifiers."
          ],
          "verification": [
            "Follow the runbook for a scheduled downgrade dispute.",
            "Follow the missing-history branch and confirm it stops before mutation."
          ],
          "deliverables": [
            "Support runbook and two worked synthetic incidents"
          ],
          "rollout": "Review the runbook with a fresh local reproduction; version corrections alongside the projection.",
          "skills": [
            "Runbooks",
            "Incident analysis"
          ],
          "fieldMix": [
            {
              "field": "Backend",
              "percentage": 60
            },
            {
              "field": "Site reliability",
              "percentage": 40
            }
          ],
          "patterns": []
        }
      ]
    }
  ]
}
