{
  "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": "fe99d92c-2de0-4682-9610-1db9b5856a75",
      "key": "LIVE",
      "title": "A collaborative incident room with a reliable timeline",
      "field": "Real-time systems",
      "summary": "Build a bounded live coordination room with ordered events, reconnect recovery, and clear authority.",
      "context": "The fictional Harbor operations team coordinates synthetic incidents in a shared room. Engineers post status notes and claim response tasks while connections come and go. Scope is one application gateway, a durable room event store, and fixture clients; alert paging and external chat delivery are excluded.",
      "stack": [
        "TypeScript",
        "Node.js",
        "WebSocket",
        "PostgreSQL",
        "Redis"
      ],
      "prerequisites": [
        "Room membership and command contracts",
        "Synthetic incident events and a controllable transport harness"
      ],
      "developerValue": "Practice event identity, ordering, replay, authorization, and bounded backpressure in one understandable system.",
      "companyValue": "Inspect how an engineer keeps collaborative state trustworthy during failures without relying on optimistic success messages.",
      "delivery": "Deliver one issue or a phase at a time against synthetic rooms. Keep load fixtures bounded and avoid real incident channels.",
      "phases": [
        {
          "id": "protocol",
          "title": "Establish the room contract",
          "goal": "Make connection state and event boundaries explicit."
        },
        {
          "id": "timeline",
          "title": "Recover a coherent timeline",
          "goal": "Order, deduplicate, and replay confirmed events."
        },
        {
          "id": "collaboration",
          "title": "Coordinate work safely",
          "goal": "Protect commands, presence, and changing access."
        },
        {
          "id": "readiness",
          "title": "Handle operational pressure",
          "goal": "Bound resource use and rehearse recovery."
        }
      ],
      "tickets": [
        {
          "id": "da389677-cab9-49d8-9c9e-82fdfaf8592c",
          "key": "LIVE-101",
          "title": "Show the difference between connected and caught up",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 75,
          "phaseId": "protocol",
          "dependsOn": [],
          "scenario": "The room shows Connected immediately after a socket opens, even while the last five minutes of events are still missing. Give connection and synchronization separate states.",
          "acceptanceCriteria": [
            "The UI distinguishes connecting, recovering, current, disconnected, and unavailable.",
            "Current appears only after the server-defined replay boundary has been applied.",
            "The latest confirmed timeline remains readable during reconnect with a visible freshness notice."
          ],
          "implementationNotes": [
            "Use a deterministic transport fixture; socket open alone is not proof of complete room state."
          ],
          "verification": [
            "Open a connection and delay replay completion; the room stays recovering until the boundary arrives.",
            "Disconnect after a confirmed note and fail reconnect; the note remains readable but is not labeled current."
          ],
          "deliverables": [
            "Room connection/sync state model and delayed-replay UI test"
          ],
          "rollout": "Enable state labels in the pilot room; force read-only mode if synchronization cannot be established.",
          "skills": [
            "State modeling",
            "Real-time UX",
            "Recovery"
          ],
          "fieldMix": [
            {
              "field": "Real-time systems",
              "percentage": 60
            },
            {
              "field": "Frontend",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "32a585ae-15f3-48cf-bc1f-acc4ed4dc598",
          "key": "LIVE-102",
          "title": "Reject malformed room events before they reach the reducer",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 90,
          "phaseId": "protocol",
          "dependsOn": [],
          "scenario": "A gateway change sends a string sequence number and crashes every open room tab. Define a versioned event envelope with deliberate unknown-version behavior.",
          "acceptanceCriteria": [
            "The boundary validates version, room ID, event ID, sequence, type, and bounded payload.",
            "Malformed or unsupported events never enter the state reducer.",
            "Protocol errors expose a safe category and recovery action without echoing raw note content."
          ],
          "implementationNotes": [
            "Treat transport input as untrusted and impose a documented frame-size limit."
          ],
          "verification": [
            "Accept a valid status-note envelope and verify its typed reducer input.",
            "Send an oversized frame, invalid sequence, and unknown version; reject each without crashing or leaking raw payloads."
          ],
          "deliverables": [
            "Versioned event parser and invalid-envelope fixture suite"
          ],
          "rollout": "Deploy readers that understand the new version before changing writers; pause the stream on unsupported contracts.",
          "skills": [
            "Schema validation",
            "Protocol design",
            "Untrusted input"
          ],
          "fieldMix": [
            {
              "field": "Real-time systems",
              "percentage": 50
            },
            {
              "field": "API design",
              "percentage": 30
            },
            {
              "field": "Security",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "2b229d62-6587-49a6-9e48-03033b817a63",
          "key": "LIVE-103",
          "title": "Authorize room subscription before replaying its history",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 120,
          "phaseId": "protocol",
          "dependsOn": [
            "LIVE-102"
          ],
          "scenario": "A client changes the room ID in its subscribe message and receives a few private timeline entries before the gateway rejects membership. Move authority checks ahead of all history and live delivery.",
          "acceptanceCriteria": [
            "Subscription derives tenant and user from the authenticated session.",
            "Current room membership is checked before replay queries and live listener registration.",
            "Denied subscriptions leave no active listener or partially delivered room data."
          ],
          "implementationNotes": [
            "Enforce room scope in repository methods as well as at the transport boundary."
          ],
          "verification": [
            "Subscribe as an authorized synthetic member and inspect permitted replay.",
            "Request a room in another organization and revoke membership before listener installation; deliver zero room events in both cases."
          ],
          "deliverables": [
            "Authorized subscription boundary and cross-room denial tests"
          ],
          "rollout": "Require this before private-room pilots; disable subscriptions if membership authority is unavailable.",
          "skills": [
            "Authorization",
            "Tenant isolation",
            "WebSocket security"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 60
            },
            {
              "field": "Real-time systems",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "baa437bf-f8b9-4890-895a-fef2f480fc44",
          "key": "LIVE-104",
          "title": "Stop duplicate and out-of-order notes confusing the timeline",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 150,
          "phaseId": "timeline",
          "dependsOn": [
            "LIVE-101",
            "LIVE-102",
            "LIVE-103"
          ],
          "scenario": "A reconnect overlaps live delivery with replay. The same mitigation note appears twice, and a late earlier event moves a resolved task back to active.",
          "acceptanceCriteria": [
            "Event identity deduplicates replay and live delivery for the same room.",
            "Only a contiguous server sequence advances the applied cursor.",
            "Out-of-order gaps are buffered within a configured bound and trigger recovery rather than arbitrary state application."
          ],
          "implementationNotes": [
            "A wall-clock timestamp is presentation metadata, not the authoritative event order."
          ],
          "verification": [
            "Deliver a duplicate event through replay and live paths; the timeline shows it once.",
            "Deliver sequences 12, 14, 13 and then an oversized gap; apply contiguous state correctly and enter recovery at the bound."
          ],
          "deliverables": [
            "Ordered room reducer and duplicate/gap test vectors"
          ],
          "rollout": "Shadow the reducer against fixed logs before use; reset from a validated snapshot if gap recovery fails.",
          "skills": [
            "Event ordering",
            "Deduplication",
            "State consistency"
          ],
          "fieldMix": [
            {
              "field": "Real-time systems",
              "percentage": 60
            },
            {
              "field": "Distributed systems",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "3508017f-157e-4300-9aeb-4b972f05ae84",
          "key": "LIVE-105",
          "title": "Recover when a reconnect cursor is older than retained history",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 165,
          "phaseId": "timeline",
          "dependsOn": [
            "LIVE-104"
          ],
          "scenario": "A laptop wakes after the room’s replay window has expired. The gateway returns recent events after the old cursor, leaving an invisible gap in the task state.",
          "acceptanceCriteria": [
            "An expired cursor receives an explicit resync-required response.",
            "The client replaces state from a room-scoped snapshot and resumes after its exact sequence boundary.",
            "Snapshot and post-snapshot events cannot combine data from different rooms or snapshot revisions."
          ],
          "implementationNotes": [
            "Keep the prior timeline visibly stale until the replacement state is validated."
          ],
          "verification": [
            "Resume a retained cursor and confirm ordinary incremental replay.",
            "Use an expired cursor and deliver a live event during snapshot loading; apply it once after the snapshot boundary, or reject mismatched room data."
          ],
          "deliverables": [
            "Snapshot/replay recovery protocol and expired-cursor tests"
          ],
          "rollout": "Pilot with a short synthetic retention window; disable writes during unresolved resync and retain safe read-only context.",
          "skills": [
            "Replay protocols",
            "Snapshot consistency",
            "Recovery"
          ],
          "fieldMix": [
            {
              "field": "Real-time systems",
              "percentage": 60
            },
            {
              "field": "Distributed systems",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "e2df0af1-b45f-448f-a4c5-c02c52f23ae1",
          "key": "LIVE-106",
          "title": "Reconcile a task claim when its acknowledgement is lost",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 150,
          "phaseId": "collaboration",
          "dependsOn": [
            "LIVE-105"
          ],
          "scenario": "A responder claims Investigate cache saturation, loses the acknowledgement, and retries. The room appends duplicate claims and briefly shows two owners.",
          "acceptanceCriteria": [
            "A claim command has a stable operation key and expected task revision.",
            "The durable event and operation result commit together or neither becomes authoritative.",
            "Retry returns the existing result; a competing confirmed claim produces a conflict instead of a second owner."
          ],
          "implementationNotes": [
            "Use the application transaction boundary and an outbox if broadcasting crosses processes."
          ],
          "verification": [
            "Accept a claim, drop the acknowledgement, and retry with the same key; one logical claim exists.",
            "Race two responders at the same revision and fail broadcast after commit; one owner remains and replay recovers the event."
          ],
          "deliverables": [
            "Idempotent claim command and lost-acknowledgement/concurrent-claim tests"
          ],
          "rollout": "Enable claims after replay recovery; disable new claims if transaction/result consistency fails while keeping confirmed assignments readable.",
          "skills": [
            "Idempotency",
            "Transactions",
            "Optimistic concurrency"
          ],
          "fieldMix": [
            {
              "field": "Real-time systems",
              "percentage": 40
            },
            {
              "field": "Backend",
              "percentage": 30
            },
            {
              "field": "Database engineering",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "7267732f-7464-4ee6-a935-540c2190f2ed",
          "key": "LIVE-107",
          "title": "Expire disconnected presence without rewriting incident history",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 105,
          "phaseId": "collaboration",
          "dependsOn": [
            "LIVE-103"
          ],
          "scenario": "Closing a laptop leaves its user shown as In room for hours. Presence currently uses the same durable event path as incident notes, making heartbeat traffic dominate replay.",
          "acceptanceCriteria": [
            "Presence expires from a bounded lease using server-observed heartbeats.",
            "Multiple tabs collapse to one visible member while preserving presence if one tab remains connected.",
            "Presence expiration never removes authored notes or changes task ownership."
          ],
          "implementationNotes": [
            "Presence is advisory activity state, not proof that someone read or understood an incident."
          ],
          "verification": [
            "Open two tabs, close one, and verify the member remains until the final lease expires.",
            "Delay heartbeats and restart the presence store; stale members expire without changing durable timeline or ownership."
          ],
          "deliverables": [
            "Ephemeral presence lease model and multi-tab expiry tests"
          ],
          "rollout": "Release advisory presence independently; hide it when its store is unavailable rather than retaining indefinite online claims.",
          "skills": [
            "Leases",
            "Ephemeral state",
            "Resource cleanup"
          ],
          "fieldMix": [
            {
              "field": "Real-time systems",
              "percentage": 70
            },
            {
              "field": "Distributed systems",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "0f574924-0761-4ad7-9bb4-10ddbb80a0a8",
          "key": "LIVE-108",
          "title": "Cut off room delivery when membership is revoked mid-replay",
          "type": "BUG",
          "priority": "URGENT",
          "difficulty": "EXPERT",
          "estimateMinutes": 210,
          "phaseId": "collaboration",
          "dependsOn": [
            "LIVE-105",
            "LIVE-106",
            "LIVE-107"
          ],
          "scenario": "A temporary responder is removed while a long history replay is streaming. The established socket keeps receiving new private notes until reconnect.",
          "acceptanceCriteria": [
            "Membership changes invalidate active subscriptions and pending replay batches for that session and room.",
            "Commands recheck current authority before committing, even when the socket was previously authorized.",
            "After the defined revocation barrier, no queued private frames are delivered and listener resources are released."
          ],
          "implementationNotes": [
            "Specify the barrier and in-flight message limits; do not promise retroactive removal of data already delivered."
          ],
          "verification": [
            "Revoke a member between replay batches and assert no subsequent private frames cross the barrier.",
            "Race revocation with task claim and a queued live note; reject unauthorized commit and remove all room listeners."
          ],
          "deliverables": [
            "Revocation-aware subscription lifecycle and race harness"
          ],
          "rollout": "Require the race harness before temporary-member use; close affected room sockets if revocation propagation is uncertain.",
          "skills": [
            "Authorization races",
            "Subscription lifecycle",
            "Security boundaries"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 60
            },
            {
              "field": "Real-time systems",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "c7a193df-6ec2-4a57-90bd-59cf0d0c4129",
          "key": "LIVE-109",
          "title": "Keep one slow room client from exhausting gateway memory",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 210,
          "phaseId": "readiness",
          "dependsOn": [
            "LIVE-105",
            "LIVE-108"
          ],
          "scenario": "A paused browser cannot consume events, but its send buffer grows throughout a synthetic incident drill. Add bounded per-connection delivery and a recoverable overload path.",
          "acceptanceCriteria": [
            "Each connection has explicit queued-byte and queued-event limits.",
            "Overloaded clients receive a safe resync/close outcome when possible; durable events are never silently skipped while claiming currency.",
            "Healthy clients continue receiving events and per-connection resources are reclaimed after closure."
          ],
          "implementationNotes": [
            "Keep a bounded load fixture; distinguish disposable presence updates from durable timeline events."
          ],
          "verification": [
            "Pause one consumer while a second reads normally; measure bounded memory and uninterrupted healthy delivery.",
            "Exceed limits, reconnect the slow client, and recover by cursor/snapshot with no silently missing timeline events."
          ],
          "deliverables": [
            "Backpressure policy and bounded slow-consumer load report"
          ],
          "rollout": "Canary conservative queue limits with disconnect metrics; reduce admission or disable live updates if memory bounds fail.",
          "skills": [
            "Backpressure",
            "Resource limits",
            "Load testing"
          ],
          "fieldMix": [
            {
              "field": "Performance engineering",
              "percentage": 50
            },
            {
              "field": "Real-time systems",
              "percentage": 50
            }
          ],
          "patterns": []
        },
        {
          "id": "313981f1-6814-4a56-be72-ec4882a2b05c",
          "key": "LIVE-110",
          "title": "Rehearse gateway restart during incident coordination",
          "type": "CHORE",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 150,
          "phaseId": "readiness",
          "dependsOn": [
            "LIVE-106",
            "LIVE-108",
            "LIVE-109"
          ],
          "scenario": "The team has not tested what room users see during a gateway restart. Create a repeatable drill with one pending claim, a disconnected reader, and a recently revoked member.",
          "acceptanceCriteria": [
            "The drill records final durable event IDs, sequence, task owner, and subscription count.",
            "Restart recovery neither duplicates the claim nor grants the revoked member replay access.",
            "The runbook defines safe metrics and a rollback action without logging private note bodies."
          ],
          "implementationNotes": [
            "Restart only disposable practice processes and use synthetic room content."
          ],
          "verification": [
            "Run the restart drill twice from the same fixture and compare final authoritative room state.",
            "Make the event store unavailable during reconnect; clients remain explicitly stale/read-only and no command is falsely confirmed."
          ],
          "deliverables": [
            "Gateway restart drill and incident-room operator runbook"
          ],
          "rollout": "Require the drill before pilot expansion; keep room writes disabled if durable replay or authorization recovery is unavailable.",
          "skills": [
            "Failure testing",
            "Operational readiness",
            "Observability"
          ],
          "fieldMix": [
            {
              "field": "Real-time systems",
              "percentage": 40
            },
            {
              "field": "Site reliability",
              "percentage": 30
            },
            {
              "field": "Quality engineering",
              "percentage": 30
            }
          ],
          "patterns": []
        }
      ]
    }
  ]
}
