{
  "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": "d92afafe-688f-483d-9328-4dc2e8e31425",
      "key": "CAL",
      "title": "A booking connector that respects calendar reality",
      "field": "Integrations",
      "summary": "Build a calendar booking workflow with time-zone rules, conflict handling, idempotent provider calls, and safe reconnect behavior.",
      "context": "A fictional consultancy books appointments across time zones. The first connector duplicates events after timeouts and offers slots during stale calendar sync. Use a local calendar-provider double and synthetic calendars.",
      "stack": [
        "TypeScript",
        "PostgreSQL",
        "HTTP",
        "IANA time zones"
      ],
      "prerequisites": [
        "Create a local provider double for free/busy, event creation, updates, cancellation, and expiring tokens.",
        "Use synthetic calendars and an injected clock; no calendar account or outgoing invitation is required."
      ],
      "developerValue": "Practice time modeling, conflict-safe booking, external state reconciliation, and credential lifecycle boundaries.",
      "companyValue": "Review whether integration work protects appointment correctness and offers clear recovery when a provider is uncertain.",
      "delivery": "A local booking connector with deterministic provider scenarios and an operations guide.",
      "phases": [
        {
          "id": "availability",
          "title": "Represent time and availability",
          "goal": "Offer only valid, explainable slots from fresh calendar data."
        },
        {
          "id": "booking",
          "title": "Create and change bookings safely",
          "goal": "Handle concurrency, retries, and external side effects explicitly."
        },
        {
          "id": "lifecycle",
          "title": "Recover provider and account changes",
          "goal": "Manage updates, cancellation, expiry, and reconnect without duplicates."
        }
      ],
      "tickets": [
        {
          "id": "51105617-d295-4435-879d-157b94ee750e",
          "key": "CAL-101",
          "title": "Reject local times that do not identify one instant",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 105,
          "phaseId": "availability",
          "dependsOn": [],
          "scenario": "A booking form submits 01:30 on a daylight-saving fallback day without an offset. Store an instant plus display zone and explicitly handle ambiguous or nonexistent local times.",
          "acceptanceCriteria": [
            "Bookings store UTC start/end instants and an IANA display-zone identifier.",
            "Nonexistent local times are rejected with a selectable valid alternative.",
            "Ambiguous local times require an explicit offset or occurrence choice and preserve that choice."
          ],
          "implementationNotes": [
            "Use established time-zone APIs or libraries; do not hard-code seasonal offsets."
          ],
          "verification": [
            "Test a normal date and both sides of a known spring gap and autumn overlap in a fixture zone.",
            "Submit an unknown zone and an end before start and verify validation errors without provider calls."
          ],
          "deliverables": [
            "Booking time contract and daylight-saving boundary cases"
          ],
          "rollout": "Validate time inputs before availability or event creation; keep existing stored instants unchanged during migration.",
          "skills": [
            "Time zones",
            "Input validation",
            "Temporal modeling"
          ],
          "fieldMix": [
            {
              "field": "Integrations",
              "percentage": 60
            },
            {
              "field": "Backend",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "06d28b5f-665f-4b3e-bd0b-30f0d77f781a",
          "key": "CAL-102",
          "title": "Merge overlapping busy intervals before offering slots",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 75,
          "phaseId": "availability",
          "dependsOn": [
            "CAL-101"
          ],
          "scenario": "Two overlapping provider events produce a false free gap between them. Normalize busy intervals and apply the agreed booking duration and buffer.",
          "acceptanceCriteria": [
            "Overlapping and adjacent intervals merge according to documented half-open boundaries.",
            "Offered slots fit completely within working hours after pre/post buffers are applied.",
            "Zero-length or reversed provider intervals are rejected as malformed input."
          ],
          "implementationNotes": [
            "Keep interval calculations in UTC; convert working-hour boundaries from the declared zone."
          ],
          "verification": [
            "Merge 09:00-10:00 and 09:30-10:30 and confirm no slot appears at 10:00.",
            "Test a slot ending exactly at closing time with and without a post-booking buffer."
          ],
          "deliverables": [
            "Interval normalizer and slot boundary examples"
          ],
          "rollout": "Compare new slot output with fixture expectations in preview mode before exposing booking actions.",
          "skills": [
            "Interval arithmetic",
            "Boundary tests",
            "Scheduling"
          ],
          "fieldMix": [
            {
              "field": "Backend",
              "percentage": 60
            },
            {
              "field": "Integrations",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "a207da19-28c1-445e-8427-06825344382f",
          "key": "CAL-103",
          "title": "Label unavailable or stale free/busy data instead of showing open slots",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 90,
          "phaseId": "availability",
          "dependsOn": [
            "CAL-102"
          ],
          "scenario": "A free/busy request times out and the connector treats an empty response as an empty calendar. Distinguish confirmed free time from unknown availability.",
          "acceptanceCriteria": [
            "Availability responses include fetched-at time, freshness state, and provider outcome.",
            "A timeout, malformed response, or expired cache produces unknown availability and no bookable slots.",
            "Fresh empty busy data can produce slots and remains distinguishable from failure."
          ],
          "implementationNotes": [
            "Use a configurable freshness limit and injected clock."
          ],
          "verification": [
            "Return fresh empty data and verify valid working-hour slots.",
            "Return timeout and separately age cached data beyond the limit; neither may expose bookable slots."
          ],
          "deliverables": [
            "Availability state model and stale-data tests"
          ],
          "rollout": "Enable fail-closed availability before adding booking creation; users receive a retry state while provider data is unknown.",
          "skills": [
            "Failure semantics",
            "Caching",
            "User feedback"
          ],
          "fieldMix": [
            {
              "field": "Integrations",
              "percentage": 80
            },
            {
              "field": "API design",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "a5d8e108-7556-4437-b870-145a587a734e",
          "key": "CAL-104",
          "title": "Reserve a slot atomically when two customers choose it",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 240,
          "phaseId": "booking",
          "dependsOn": [
            "CAL-103"
          ],
          "scenario": "Two clients load the same available slot and submit together. Add an internal reservation transaction and a final provider availability check before creating an event.",
          "acceptanceCriteria": [
            "Overlapping active reservations for one resource are prevented by a database-backed invariant.",
            "Only the winning reservation can enqueue event creation through a transactional outbox.",
            "The product distinguishes internal reservation guarantees from provider-side races when the provider lacks atomic hold support."
          ],
          "implementationNotes": [
            "Use a barrier-controlled race with two synthetic customers.",
            "If the provider cannot guarantee exclusive booking, record the residual conflict state and provide reconciliation."
          ],
          "verification": [
            "Submit two overlapping reservations concurrently and assert one winner and one outbox event.",
            "Introduce an external busy event after the first check and verify the booking is rejected or explicitly reconciled under the declared provider contract."
          ],
          "deliverables": [
            "Reservation constraint, outbox flow, and provider-race analysis"
          ],
          "rollout": "Activate one resource at a time with explicit provider guarantees; pause creation if unresolved conflicts accumulate.",
          "skills": [
            "Database concurrency",
            "Outbox",
            "Distributed consistency",
            "Risk communication"
          ],
          "fieldMix": [
            {
              "field": "Database engineering",
              "percentage": 40
            },
            {
              "field": "Integrations",
              "percentage": 30
            },
            {
              "field": "Distributed systems",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "4bc7b889-1d17-4a9f-826e-7c2767626f98",
          "key": "CAL-105",
          "title": "Reconcile a create-event timeout before trying again",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "booking",
          "dependsOn": [
            "CAL-104"
          ],
          "scenario": "The calendar provider creates the appointment but drops its response. Retrying with a new request identifier currently creates a second event. Preserve creation identity and reconcile uncertainty.",
          "acceptanceCriteria": [
            "Each booking has a stable provider request identity persisted before the first call.",
            "A lost response triggers lookup by that identity or an explicit uncertain state when lookup is unsupported.",
            "A matching existing event is linked once; conflicting details block automatic completion."
          ],
          "implementationNotes": [
            "Use the local double to model accepted-then-timeout.",
            "Do not claim exactly-once provider behavior without the required idempotency contract."
          ],
          "verification": [
            "Lose the first create response and assert one provider event after reconciliation.",
            "Return an event with the same identity but different times and confirm the booking enters conflict without another create."
          ],
          "deliverables": [
            "Idempotent creation adapter and uncertain-outcome tests"
          ],
          "rollout": "Require reconciliation support before enabling retries; unsupported providers remain in manual resolution on ambiguous outcomes.",
          "skills": [
            "Idempotency",
            "External state reconciliation",
            "Failure handling"
          ],
          "fieldMix": [
            {
              "field": "Integrations",
              "percentage": 60
            },
            {
              "field": "Distributed systems",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "2d068496-a34e-41a9-b729-99358338871d",
          "key": "CAL-106",
          "title": "Move a booking only if its current revision still matches",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 165,
          "phaseId": "booking",
          "dependsOn": [
            "CAL-105"
          ],
          "scenario": "An agent reschedules a booking from an old browser tab after a colleague already moved it. Add revision-aware rescheduling and retain the original slot until the new operation is settled.",
          "acceptanceCriteria": [
            "Reschedule requests include the expected booking revision and are rejected when stale.",
            "The proposed new slot passes reservation and availability checks before the provider update.",
            "Provider failure or uncertainty leaves a documented pending/conflict state and does not silently mark both slots free."
          ],
          "implementationNotes": [
            "Use provider conditional updates when the adapter supports them.",
            "Record before and proposed intervals in an append-only operation record."
          ],
          "verification": [
            "Reschedule an unchanged booking and verify one final interval and incremented revision.",
            "Race two reschedules and simulate a provider timeout; verify explicit conflicts and no duplicate successful move."
          ],
          "deliverables": [
            "Rescheduling state transitions and race/failure cases"
          ],
          "rollout": "Enable rescheduling after create reconciliation is stable; fall back to operator resolution for uncertain provider updates.",
          "skills": [
            "Optimistic locking",
            "State machines",
            "Compensation"
          ],
          "fieldMix": [
            {
              "field": "Integrations",
              "percentage": 50
            },
            {
              "field": "Backend",
              "percentage": 30
            },
            {
              "field": "Distributed systems",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "b576e4d6-2fba-4b46-b0e2-e64acf4a9d72",
          "key": "CAL-107",
          "title": "Make repeated cancellation safe and tenant scoped",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 105,
          "phaseId": "lifecycle",
          "dependsOn": [
            "CAL-105"
          ],
          "scenario": "A client double-clicks Cancel while a support agent cancels from another screen. The connector must converge on one cancellation without allowing another tenant to cancel by event ID.",
          "acceptanceCriteria": [
            "Cancellation resolves the booking through tenant and actor authorization before accessing provider IDs.",
            "Repeated authorized cancellation converges on the same terminal result.",
            "Provider not-found is accepted only after verifying the expected booking/provider mapping, and other provider errors remain visible."
          ],
          "implementationNotes": [
            "Keep provider event IDs out of caller-controlled authority decisions."
          ],
          "verification": [
            "Send concurrent cancellation requests and assert one logical cancellation history.",
            "Attempt cancellation from another tenant and verify no provider request is made."
          ],
          "deliverables": [
            "Scoped cancellation service and idempotency/access tests"
          ],
          "rollout": "Expose cancellation with retry-safe state transitions; retain pending cancellation during provider outages rather than claiming success.",
          "skills": [
            "Authorization",
            "Idempotency",
            "Lifecycle design"
          ],
          "fieldMix": [
            {
              "field": "Integrations",
              "percentage": 50
            },
            {
              "field": "Security",
              "percentage": 30
            },
            {
              "field": "Backend",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "0394e732-e212-481f-8004-a401bd7b0050",
          "key": "CAL-108",
          "title": "Refresh expired connector credentials once per account",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 210,
          "phaseId": "lifecycle",
          "dependsOn": [
            "CAL-105"
          ],
          "scenario": "Ten jobs receive token-expired at once, all refresh, and a rotated token is overwritten by an older response. Serialize refresh by connector identity and persist credential revisions safely.",
          "acceptanceCriteria": [
            "Concurrent expiry responses share one refresh operation per connector account.",
            "Credential writes use version checks so an older refresh cannot overwrite a newer rotation.",
            "A revoked grant stops new provider mutations, records reconnect-required, and never logs credential values."
          ],
          "implementationNotes": [
            "Use synthetic opaque tokens and a local token endpoint double.",
            "Store credentials through a secret-store interface; do not hard-code a production key."
          ],
          "verification": [
            "Expire a token under ten concurrent calls and assert one refresh with successful versioned reuse.",
            "Return refresh responses out of order and a revoked grant; verify no stale overwrite and no further mutations."
          ],
          "deliverables": [
            "Credential lifecycle port and refresh-race tests"
          ],
          "rollout": "Canary the new refresh path on a synthetic connector; force reconnect when credential authority is ambiguous.",
          "skills": [
            "Credential lifecycle",
            "Concurrency",
            "Secret handling",
            "Provider integration"
          ],
          "fieldMix": [
            {
              "field": "Integrations",
              "percentage": 40
            },
            {
              "field": "Security",
              "percentage": 30
            },
            {
              "field": "Distributed systems",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "0a9053c1-3d7c-4a88-8ae1-5eb66b1f2184",
          "key": "CAL-109",
          "title": "Ignore duplicate calendar notifications and detect missed updates",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 150,
          "phaseId": "lifecycle",
          "dependsOn": [
            "CAL-106",
            "CAL-107",
            "CAL-108"
          ],
          "scenario": "Provider notifications arrive twice, then a subscription expires and updates stop. Treat notifications as sync hints and maintain a separate reconciliation cursor and subscription deadline.",
          "acceptanceCriteria": [
            "Authenticated duplicate notifications schedule at most one active sync for the connector.",
            "Sync advances its provider cursor only with committed local changes.",
            "Expired subscriptions or invalid cursors trigger an explicit refresh/reconnect path and mark availability stale."
          ],
          "implementationNotes": [
            "Validate the local notification authentication contract before trusting connector metadata.",
            "Do not use notification arrival order as event revision order."
          ],
          "verification": [
            "Send duplicate and invalid-auth notifications and count scheduled jobs.",
            "Expire a subscription and invalidate a cursor; confirm availability becomes unbookable until a successful resync."
          ],
          "deliverables": [
            "Notification ingestion, sync checkpointing, and expiry scenarios"
          ],
          "rollout": "Enable notification ingestion alongside periodic reconciliation; pause booking when either path cannot establish fresh availability.",
          "skills": [
            "Webhook security",
            "Cursor sync",
            "Freshness",
            "Idempotent jobs"
          ],
          "fieldMix": [
            {
              "field": "Integrations",
              "percentage": 40
            },
            {
              "field": "Distributed systems",
              "percentage": 30
            },
            {
              "field": "Security",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "940dd137-58cf-4f28-8de4-f4ff5bff6a19",
          "key": "CAL-110",
          "title": "Show operators which bookings need recovery after reconnect",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 90,
          "phaseId": "lifecycle",
          "dependsOn": [
            "CAL-109"
          ],
          "scenario": "After reconnecting an account, operations cannot tell which bookings were created, moved, or cancelled during the outage. Build a scoped recovery list with safe identifiers and next actions.",
          "acceptanceCriteria": [
            "The list separates pending creation, uncertain update, pending cancellation, and resolved operations.",
            "Each row includes safe booking reference, last attempt time, failure category, and permitted recovery action.",
            "Reading the list never sends invitations, creates events, or retries an operation implicitly."
          ],
          "implementationNotes": [
            "Omit attendee contact details from generic diagnostics.",
            "Actions invoke the existing authorized lifecycle methods."
          ],
          "verification": [
            "Populate one operation in each state and verify labels and action availability.",
            "Open the list as an unauthorized tenant and confirm denial with zero provider activity."
          ],
          "deliverables": [
            "Recovery list projection and reconnect operator guide"
          ],
          "rollout": "Release read-only recovery visibility first; activate explicit retry actions only through the already verified state transitions.",
          "skills": [
            "Operations UX",
            "Authorization",
            "Recovery workflows"
          ],
          "fieldMix": [
            {
              "field": "Integrations",
              "percentage": 50
            },
            {
              "field": "Backend",
              "percentage": 30
            },
            {
              "field": "Security",
              "percentage": 20
            }
          ],
          "patterns": []
        }
      ]
    }
  ]
}
