{
  "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": "870ca293-ba3d-4340-bd71-a2142fa7bef0",
      "key": "CAUCT",
      "title": "A realtime reservation window for workshop seats",
      "field": "Real-time systems",
      "summary": "Coordinate expiring seat holds and live availability in a local simulation.",
      "context": "Fictional craft studio Maple offers workshop seats. Implement synthetic reservations without payments or real booking services.",
      "stack": [
        "TypeScript",
        "PostgreSQL adapter",
        "WebSocket",
        "Vitest"
      ],
      "prerequisites": [
        "Create synthetic workshops with small capacities.",
        "Implement local transactional hold storage and injected clocks."
      ],
      "developerValue": "Practice contention, expiry and truthful realtime projections.",
      "companyValue": "Inspect whether concurrent clients avoid overselling and recover uncertain results.",
      "delivery": "Booking simulation only; payment and production capacity planning are excluded.",
      "phases": [
        {
          "id": "holds",
          "title": "Define hold rules",
          "goal": "Specify capacity and ownership."
        },
        {
          "id": "races",
          "title": "Resolve concurrent changes",
          "goal": "Handle expiry and confirmation atomically."
        },
        {
          "id": "clients",
          "title": "Synchronize the audience",
          "goal": "Keep availability and recovery bounded."
        }
      ],
      "tickets": [
        {
          "id": "b1149a73-eb98-44ba-a263-3ca1538e972b",
          "key": "CAUCT-101",
          "title": "Specify workshop seat counts without negative availability",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 75,
          "phaseId": "holds",
          "dependsOn": [],
          "scenario": "The prototype subtracts all historical holds and displays negative seats. Project availability from current authoritative states.",
          "acceptanceCriteria": [
            "Only active holds consume seats",
            "Confirmed reservations consume seats",
            "Expired holds do not consume seats"
          ],
          "implementationNotes": [
            "Define active using injected time."
          ],
          "verification": [
            "Project mixed states",
            "Use boundary expiry instant"
          ],
          "deliverables": [
            "Availability projection and cases"
          ],
          "rollout": "Hide counts if state cannot be reconciled.",
          "skills": [
            "State modeling",
            "Time"
          ],
          "fieldMix": [
            {
              "field": "Backend",
              "percentage": 60
            },
            {
              "field": "Database engineering",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "5c7cf0d8-af2c-4eaa-8915-225612f3ce5b",
          "key": "CAUCT-102",
          "title": "Validate workshop hold quantities before storage",
          "type": "BUG",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 60,
          "phaseId": "holds",
          "dependsOn": [
            "CAUCT-101"
          ],
          "scenario": "A zero-seat request creates a hold and a fractional request breaks counts. Enforce bounded integer quantities.",
          "acceptanceCriteria": [
            "Positive integers within limit pass",
            "Zero and fractions fail",
            "Invalid input creates no record"
          ],
          "implementationNotes": [
            "Keep limits explicit in the local contract."
          ],
          "verification": [
            "Hold two seats",
            "Reject zero and oversized quantities"
          ],
          "deliverables": [
            "Quantity validator and failure cases"
          ],
          "rollout": "Reject new holds if validation is unavailable.",
          "skills": [
            "Validation",
            "Contracts"
          ],
          "fieldMix": [
            {
              "field": "Backend",
              "percentage": 80
            },
            {
              "field": "API design",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "86d754d4-7ef2-4eea-a645-f914809b8b5d",
          "key": "CAUCT-103",
          "title": "Create workshop holds atomically under contention",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "holds",
          "dependsOn": [
            "CAUCT-101",
            "CAUCT-102"
          ],
          "scenario": "Two clients see one available seat and both reserve it. Serialize capacity consumption at storage.",
          "acceptanceCriteria": [
            "At most capacity is consumed",
            "Loser receives unavailable result",
            "No partial hold record remains"
          ],
          "implementationNotes": [
            "A browser availability check is advisory only."
          ],
          "verification": [
            "Create uncontested hold",
            "Race two requests for one seat"
          ],
          "deliverables": [
            "Transactional hold operation"
          ],
          "rollout": "Pause hold creation if capacity invariant fails.",
          "skills": [
            "Transactions",
            "Concurrency"
          ],
          "fieldMix": [
            {
              "field": "Database engineering",
              "percentage": 70
            },
            {
              "field": "Backend",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "04228c7d-6f7b-4246-8630-6979c6c1cd30",
          "key": "CAUCT-104",
          "title": "Scope workshop hold lookup and cancellation to its owner",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 135,
          "phaseId": "races",
          "dependsOn": [
            "CAUCT-103"
          ],
          "scenario": "Knowing a hold ID lets another user cancel it. Enforce owner scope in the repository boundary.",
          "acceptanceCriteria": [
            "Owner reads and cancels",
            "Foreign owner is denied",
            "Denied calls do not disclose hold details"
          ],
          "implementationNotes": [
            "Synthetic identities remain required in all adapter calls."
          ],
          "verification": [
            "Cancel own hold",
            "Cancel another account's hold"
          ],
          "deliverables": [
            "Scoped hold repository and denial tests"
          ],
          "rollout": "Disable cancellation if scope cannot be established.",
          "skills": [
            "Authorization",
            "Repository design"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 70
            },
            {
              "field": "Backend",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "be81a3d4-386e-445e-950b-0e26a2a2ee60",
          "key": "CAUCT-105",
          "title": "Confirm workshop holds only before the expiry boundary",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "races",
          "dependsOn": [
            "CAUCT-103",
            "CAUCT-104"
          ],
          "scenario": "Confirm and expiry cleanup race, creating reservations from expired holds. Add an atomic transition with one time rule.",
          "acceptanceCriteria": [
            "Eligible hold confirms once",
            "Expired hold cannot confirm",
            "Cleanup cannot remove confirmed reservation"
          ],
          "implementationNotes": [
            "Compare time inside the authoritative transition."
          ],
          "verification": [
            "Confirm before boundary",
            "Race confirm with expiry cleanup"
          ],
          "deliverables": [
            "Confirmation transition and boundary cases"
          ],
          "rollout": "Pause confirmation if atomicity fails.",
          "skills": [
            "State machines",
            "Concurrency"
          ],
          "fieldMix": [
            {
              "field": "Database engineering",
              "percentage": 60
            },
            {
              "field": "Backend",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "6fb50879-6487-4422-b12f-8ab0c1a538db",
          "key": "CAUCT-106",
          "title": "Replay workshop hold requests with the same idempotency key",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 135,
          "phaseId": "races",
          "dependsOn": [
            "CAUCT-103"
          ],
          "scenario": "Timeout retry creates two holds for one user's click. Bind the operation key to the normalized request.",
          "acceptanceCriteria": [
            "Same key and payload returns same hold",
            "Different payload conflicts",
            "Keys remain scoped to owner"
          ],
          "implementationNotes": [
            "Store idempotency result with the hold transaction."
          ],
          "verification": [
            "Replay accepted request",
            "Reuse key with different quantity"
          ],
          "deliverables": [
            "Idempotent create contract"
          ],
          "rollout": "Require status lookup while replay support is repaired.",
          "skills": [
            "Idempotency",
            "Transactions"
          ],
          "fieldMix": [
            {
              "field": "Backend",
              "percentage": 50
            },
            {
              "field": "Database engineering",
              "percentage": 30
            },
            {
              "field": "API design",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "d3454de1-e672-4eaa-8951-c006128c645f",
          "key": "CAUCT-107",
          "title": "Publish workshop availability changes only after commit",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 240,
          "phaseId": "races",
          "dependsOn": [
            "CAUCT-105",
            "CAUCT-106"
          ],
          "scenario": "Clients see seats disappear for a transaction that later rolls back. Publish committed availability through an outbox.",
          "acceptanceCriteria": [
            "Committed changes enqueue events",
            "Rollback emits no event",
            "Replay cannot double-apply availability"
          ],
          "implementationNotes": [
            "Event consumers receive versions, not count deltas alone."
          ],
          "verification": [
            "Commit hold and publish",
            "Roll back after preparing event"
          ],
          "deliverables": [
            "Outbox handoff and rollback cases"
          ],
          "rollout": "Stop live updates and serve authoritative snapshots.",
          "skills": [
            "Outbox",
            "Consistency"
          ],
          "fieldMix": [
            {
              "field": "Distributed systems",
              "percentage": 50
            },
            {
              "field": "Database engineering",
              "percentage": 30
            },
            {
              "field": "Real-time systems",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "4fa4cebe-37e4-45e1-b75c-80ffb9380777",
          "key": "CAUCT-108",
          "title": "Rebuild workshop availability after a missed realtime update",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 165,
          "phaseId": "clients",
          "dependsOn": [
            "CAUCT-107"
          ],
          "scenario": "Dropped socket messages leave the workshop full after holds expire. Detect version gaps and refresh a snapshot.",
          "acceptanceCriteria": [
            "Versions advance monotonically",
            "Gap triggers resync",
            "Stale events cannot reduce version"
          ],
          "implementationNotes": [
            "Snapshot and event versions share one scope."
          ],
          "verification": [
            "Apply contiguous updates",
            "Skip one version and reconnect"
          ],
          "deliverables": [
            "Versioned client projection"
          ],
          "rollout": "Poll snapshots if delta recovery fails.",
          "skills": [
            "Synchronization",
            "Recovery"
          ],
          "fieldMix": [
            {
              "field": "Real-time systems",
              "percentage": 50
            },
            {
              "field": "Distributed systems",
              "percentage": 50
            }
          ],
          "patterns": []
        },
        {
          "id": "82e6520e-b5f2-426e-b94c-6ca80d5a55d4",
          "key": "CAUCT-109",
          "title": "Display workshop hold countdown as advisory",
          "type": "BUG",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 105,
          "phaseId": "clients",
          "dependsOn": [
            "CAUCT-105",
            "CAUCT-108"
          ],
          "scenario": "A client clock skew shows time remaining after the server expired the hold. Label countdown and reconcile server refusal.",
          "acceptanceCriteria": [
            "Countdown uses server offset estimate",
            "Zero disables local confirmation",
            "Server expiry still wins"
          ],
          "implementationNotes": [
            "A visual timer cannot authorize a reservation."
          ],
          "verification": [
            "Use skewed client clock",
            "Confirm after authoritative expiry"
          ],
          "deliverables": [
            "Countdown presenter and skew cases"
          ],
          "rollout": "Replace countdown with expiry timestamp if offset is unreliable.",
          "skills": [
            "Time",
            "UX"
          ],
          "fieldMix": [
            {
              "field": "Frontend",
              "percentage": 70
            },
            {
              "field": "Real-time systems",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "9eae6e01-e892-4f2f-98c9-0e2e84ef97d4",
          "key": "CAUCT-110",
          "title": "Bound workshop hold cleanup batches and expose progress",
          "type": "CHORE",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 120,
          "phaseId": "clients",
          "dependsOn": [
            "CAUCT-107",
            "CAUCT-108"
          ],
          "scenario": "Cleanup scans every historical hold on each tick. Add bounded cursor batches with repeat-safe transitions.",
          "acceptanceCriteria": [
            "Each batch has fixed limit",
            "Concurrent confirms are preserved",
            "Restart resumes without skipping eligible rows"
          ],
          "implementationNotes": [
            "Use indexed expiry selection in the adapter design."
          ],
          "verification": [
            "Clean several batches",
            "Confirm a selected hold concurrently"
          ],
          "deliverables": [
            "Cleanup worker contract and restart cases"
          ],
          "rollout": "Pause cleanup and rely on read-time expiry until repaired.",
          "skills": [
            "Batch processing",
            "Recovery"
          ],
          "fieldMix": [
            {
              "field": "Database engineering",
              "percentage": 50
            },
            {
              "field": "Data engineering",
              "percentage": 30
            },
            {
              "field": "Performance engineering",
              "percentage": 20
            }
          ],
          "patterns": []
        }
      ]
    }
  ]
}
