{
  "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": "03ef30c2-e774-4aef-8e97-712ad3d6f1af",
      "key": "REPLAY",
      "title": "A webhook replay lab for incident recovery",
      "field": "Quality engineering",
      "summary": "Create a local webhook laboratory that reproduces duplicates, disorder, signature failures, and interrupted delivery.",
      "context": "An integration team closes incidents with screenshots of provider dashboards, then struggles to reproduce the same delivery sequence. Build a synthetic event corpus and replay runner against an allowlisted local receiver.",
      "stack": [
        "TypeScript",
        "HTTP",
        "HMAC",
        "SQLite"
      ],
      "prerequisites": [
        "Create a local receiver fixture with an inspectable event store.",
        "Use generated test signing keys and synthetic payloads only."
      ],
      "developerValue": "Practice protocol verification, controlled fault injection, and reproducible incident investigation.",
      "companyValue": "Review concrete evidence that webhook consumers tolerate real delivery failure patterns.",
      "delivery": "A synthetic event corpus, safe local replay runner, and repeatable incident scenarios.",
      "phases": [
        {
          "id": "corpus",
          "title": "Build inspectable event fixtures",
          "goal": "Represent exact request bytes and expected receiver effects."
        },
        {
          "id": "scenarios",
          "title": "Reproduce delivery failures",
          "goal": "Control signing, ordering, duplicates, and lost responses."
        },
        {
          "id": "report",
          "title": "Make incidents repeatable",
          "goal": "Bound replay authority and preserve useful run reports."
        }
      ],
      "tickets": [
        {
          "id": "2ff8c554-3464-4466-913a-0bd6bfe2b7c1",
          "key": "REPLAY-101",
          "title": "Define a portable synthetic webhook fixture",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 60,
          "phaseId": "corpus",
          "dependsOn": [],
          "scenario": "A copied JSON payload loses its original whitespace and cannot reproduce a signature mismatch. Store exact request bytes with safe headers and an expected event identity.",
          "acceptanceCriteria": [
            "The fixture preserves body bytes, content type, event ID, and schema version.",
            "Loading rejects unknown fields that could supply credentials or arbitrary destination URLs.",
            "The fixture includes a content digest and validates it before replay."
          ],
          "implementationNotes": [
            "Generate synthetic examples; do not import production customer payloads."
          ],
          "verification": [
            "Round-trip a body with whitespace and non-ASCII text byte-for-byte.",
            "Change one payload byte and verify digest validation fails before a request is sent."
          ],
          "deliverables": [
            "Fixture schema and three synthetic event examples"
          ],
          "rollout": "Version the fixture format; retain older samples read-only until a validated converter exists.",
          "skills": [
            "Serialization",
            "Byte integrity",
            "Test fixtures"
          ],
          "fieldMix": [
            {
              "field": "Quality engineering",
              "percentage": 60
            },
            {
              "field": "Integrations",
              "percentage": 20
            },
            {
              "field": "Security",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "ddc46767-593f-44d1-99cc-e7cfd8c30cd5",
          "key": "REPLAY-102",
          "title": "Generate signatures from raw bytes and an injected clock",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 90,
          "phaseId": "corpus",
          "dependsOn": [
            "REPLAY-101"
          ],
          "scenario": "The receiver accepts fresh signatures but rejects replay fixtures because timestamp generation depends on the wall clock. Add a deterministic signer for the lab contract.",
          "acceptanceCriteria": [
            "Signing covers the timestamp and exact raw body according to the documented lab protocol.",
            "The clock and generated test key are supplied explicitly.",
            "Signature values and secret keys are not printed in ordinary run logs."
          ],
          "implementationNotes": [
            "Use an established HMAC implementation and document byte encoding."
          ],
          "verification": [
            "Check a fixed key/time/body vector against an independently calculated digest.",
            "Change only whitespace or timestamp and confirm the signature changes."
          ],
          "deliverables": [
            "Test signer and fixed signature vectors"
          ],
          "rollout": "Restrict signing to the local lab adapter; rotate fixture keys by changing the versioned test configuration.",
          "skills": [
            "HMAC",
            "Protocol testing",
            "Clock control"
          ],
          "fieldMix": [
            {
              "field": "Quality engineering",
              "percentage": 50
            },
            {
              "field": "Security",
              "percentage": 30
            },
            {
              "field": "Integrations",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "046583aa-dac1-4235-a888-08df1fc84e4c",
          "key": "REPLAY-103",
          "title": "Assert duplicate delivery produces one business effect",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 105,
          "phaseId": "scenarios",
          "dependsOn": [
            "REPLAY-102"
          ],
          "scenario": "A subscription-created event is delivered three times with separate request IDs. The replay should test event-level deduplication rather than merely identical HTTP responses.",
          "acceptanceCriteria": [
            "A scenario sends one event identity with three distinct delivery identities.",
            "The receiver records delivery attempts but creates one subscription effect.",
            "Changing the event ID while preserving business data follows an explicitly documented business-key policy."
          ],
          "implementationNotes": [
            "Observe effects through the local receiver inspection API."
          ],
          "verification": [
            "Replay three duplicates and assert delivery and effect counts separately.",
            "Disable receiver deduplication in a fixture variant and confirm the scenario detects extra effects."
          ],
          "deliverables": [
            "Duplicate-delivery scenario and effect assertions"
          ],
          "rollout": "Add as the first consumer acceptance scenario; use the same fixture revision when comparing receiver changes.",
          "skills": [
            "Idempotency",
            "Integration testing",
            "Business invariants"
          ],
          "fieldMix": [
            {
              "field": "Quality engineering",
              "percentage": 50
            },
            {
              "field": "Integrations",
              "percentage": 30
            },
            {
              "field": "Distributed systems",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "bc7dbd70-f729-4bff-821e-7c590b8e95c1",
          "key": "REPLAY-104",
          "title": "Deliver update-before-create with a reproducible schedule",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 150,
          "phaseId": "scenarios",
          "dependsOn": [
            "REPLAY-102"
          ],
          "scenario": "A subscription update arrived before its create event during an outage. Add a schedule format that can hold, reorder, and release specific events without relying on elapsed sleeps.",
          "acceptanceCriteria": [
            "The scenario declares event order and release barriers separately from payload data.",
            "The receiver converges to the latest declared resource revision when all events arrive.",
            "Stale events cannot overwrite a newer stored revision."
          ],
          "implementationNotes": [
            "Define revision ordering in the lab contract instead of inferring it from arrival time."
          ],
          "verification": [
            "Run create-update and update-create schedules and compare final state.",
            "Append a stale update after convergence and verify the state remains at the newest revision."
          ],
          "deliverables": [
            "Barrier-based schedule runner and out-of-order scenarios"
          ],
          "rollout": "Keep scheduling deterministic by default; random ordering is optional and must record a replayable seed.",
          "skills": [
            "Event ordering",
            "Deterministic tests",
            "Version checks"
          ],
          "fieldMix": [
            {
              "field": "Quality engineering",
              "percentage": 50
            },
            {
              "field": "Real-time systems",
              "percentage": 30
            },
            {
              "field": "Integrations",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "31da06a8-e3c2-4cd6-b44e-7d84ce098b91",
          "key": "REPLAY-105",
          "title": "Exercise signature rotation without accepting expired requests",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 135,
          "phaseId": "scenarios",
          "dependsOn": [
            "REPLAY-102"
          ],
          "scenario": "During key rotation the receiver must accept old and new keys briefly, while still rejecting requests outside the timestamp tolerance. Add a table of rotation boundaries.",
          "acceptanceCriteria": [
            "Cases cover current key, overlap key, unknown key, and retired key.",
            "Freshness boundaries are tested immediately inside and outside the documented tolerance.",
            "Invalid signatures and stale timestamps produce no persisted business effect."
          ],
          "implementationNotes": [
            "Use an injected clock and generated lab keys.",
            "Verify signature checks occur before trusted event fields are consumed."
          ],
          "verification": [
            "Accept both keys inside the overlap window and reject the retired key afterward.",
            "Send a validly signed but stale event and a fresh tampered event; both must have zero effects."
          ],
          "deliverables": [
            "Rotation boundary matrix and receiver assertions"
          ],
          "rollout": "Run rotation cases before changing receiver key policy; keep retired test keys only in synthetic fixtures.",
          "skills": [
            "Security testing",
            "Key rotation",
            "Boundary cases"
          ],
          "fieldMix": [
            {
              "field": "Quality engineering",
              "percentage": 60
            },
            {
              "field": "Security",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "4e7656d9-8a7b-4d0e-bb60-aecc8d9f28d2",
          "key": "REPLAY-106",
          "title": "Reproduce a receiver commit followed by a dropped response",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 210,
          "phaseId": "scenarios",
          "dependsOn": [
            "REPLAY-103",
            "REPLAY-104"
          ],
          "scenario": "The receiver committed the event, then the connection closed before the sender received 200. Model this boundary and verify sender retries and receiver effects independently.",
          "acceptanceCriteria": [
            "A controlled fault drops the response only after the receiver commits its effect.",
            "The sender retries the original event identity under a bounded policy.",
            "Final reporting distinguishes transport uncertainty from receiver business success and proves one effect."
          ],
          "implementationNotes": [
            "Implement the fault in a local transport or receiver double.",
            "Do not treat a missing response as proof the receiver did nothing."
          ],
          "verification": [
            "Drop after commit and observe a retry with exactly one effect.",
            "Drop before commit and verify a later retry creates the missing effect once."
          ],
          "deliverables": [
            "Before/after-commit fault scenarios and uncertainty report"
          ],
          "rollout": "Keep fault controls unavailable outside the local lab; preserve failed-run reports when rerunning the scenario.",
          "skills": [
            "Distributed failure",
            "Fault injection",
            "Retry semantics",
            "Observability"
          ],
          "fieldMix": [
            {
              "field": "Quality engineering",
              "percentage": 50
            },
            {
              "field": "Distributed systems",
              "percentage": 30
            },
            {
              "field": "Integrations",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "fcb220a4-d346-4885-aef0-e2a04b932aa5",
          "key": "REPLAY-107",
          "title": "Block replay targets outside the approved local receiver",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 150,
          "phaseId": "report",
          "dependsOn": [
            "REPLAY-101"
          ],
          "scenario": "A fixture author added a destination that points at a metadata endpoint. Move destination control out of fixture data and enforce a fixed local target policy.",
          "acceptanceCriteria": [
            "Only configured loopback receiver hosts and ports can be selected.",
            "Redirects are rejected and userinfo, ambiguous IP syntax, and non-HTTP schemes are denied.",
            "The resolved address is validated at connection time; rejected destinations send zero payload bytes, and redirect responses trigger no follow-up request."
          ],
          "implementationNotes": [
            "Keep replay configuration separate from imported fixture content.",
            "Bound request body size and connection timeout."
          ],
          "verification": [
            "Replay to the configured local receiver successfully.",
            "Reject an external host, unapproved port, and alternate IP notation before any receiver request; for a redirect, allow one request to the approved receiver and assert zero requests to its redirect target."
          ],
          "deliverables": [
            "Destination policy and SSRF regression cases"
          ],
          "rollout": "Make the target policy mandatory before exposing fixture import; disable replay on target-validation uncertainty.",
          "skills": [
            "SSRF prevention",
            "Network boundaries",
            "Input validation"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 60
            },
            {
              "field": "Quality engineering",
              "percentage": 20
            },
            {
              "field": "Networking",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "b487fc3f-8ed8-4541-bf75-d758f7edcbda",
          "key": "REPLAY-108",
          "title": "Summarize deliveries and effects in separate report sections",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 75,
          "phaseId": "report",
          "dependsOn": [
            "REPLAY-103"
          ],
          "scenario": "The current report says three successes even though three deliveries produced one intended change. Report transport attempts and business effects as separate facts.",
          "acceptanceCriteria": [
            "The report lists delivery ID, event ID, response category, and receiver effect reference separately.",
            "A timeout remains unknown at the transport level even if later reconciliation finds an effect.",
            "Output is stably ordered and includes scenario and fixture revisions."
          ],
          "implementationNotes": [
            "Use synthetic receiver record IDs; these are not noCV Evidence IDs."
          ],
          "verification": [
            "Report a three-delivery duplicate scenario with three attempts and one effect.",
            "Report a timeout followed by reconciliation without rewriting the timeout as an HTTP success."
          ],
          "deliverables": [
            "JSON report contract and readable summary renderer"
          ],
          "rollout": "Version the new report format; preserve original attempt records when generating summaries.",
          "skills": [
            "Reporting",
            "Data modeling",
            "Traceability"
          ],
          "fieldMix": [
            {
              "field": "Quality engineering",
              "percentage": 80
            },
            {
              "field": "Developer tooling",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "9a7ec03a-0a5e-4dce-89d9-edeba1118537",
          "key": "REPLAY-109",
          "title": "Honor Retry-After without creating an unbounded replay",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 105,
          "phaseId": "report",
          "dependsOn": [
            "REPLAY-106",
            "REPLAY-107"
          ],
          "scenario": "The local receiver responds 429 with Retry-After, but the runner retries immediately. Add bounded backoff with a fake clock and explicit terminal reasons.",
          "acceptanceCriteria": [
            "Supported Retry-After forms are parsed and capped by the run time budget.",
            "Malformed or negative values fall back to documented bounded backoff.",
            "Maximum attempts and overall deadline stop retries with a terminal reason in the report."
          ],
          "implementationNotes": [
            "Seed jitter or disable it for deterministic fixtures."
          ],
          "verification": [
            "Advance a fake clock through 429, 503, and success and assert scheduled retry times.",
            "Return an excessive delay and confirm the deadline ends the run without waiting in real time."
          ],
          "deliverables": [
            "Retry policy and fake-clock timing cases"
          ],
          "rollout": "Apply bounded retry policy to all replay scenarios; allow zero retries for transport debugging.",
          "skills": [
            "Retry policies",
            "Rate limits",
            "Time-based testing"
          ],
          "fieldMix": [
            {
              "field": "Quality engineering",
              "percentage": 50
            },
            {
              "field": "Integrations",
              "percentage": 30
            },
            {
              "field": "Networking",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "c9a3e3c2-46a5-4d5d-b886-861bba575df2",
          "key": "REPLAY-110",
          "title": "Export an incident recipe another engineer can rerun",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 120,
          "phaseId": "report",
          "dependsOn": [
            "REPLAY-105",
            "REPLAY-108",
            "REPLAY-109"
          ],
          "scenario": "An engineer reproduced the incident but left only terminal history. Export the scenario, fixture digests, scheduler seed, and safe configuration as a portable recipe.",
          "acceptanceCriteria": [
            "The recipe resolves every fixture by immutable content digest and records the runner version.",
            "It excludes signing keys, credentials, destination overrides, and captured production payloads.",
            "A fresh local receiver can reproduce the expected effect and failure categories from the recipe."
          ],
          "implementationNotes": [
            "Require generated replacement keys on import.",
            "Keep original run reports separate from rerun reports."
          ],
          "verification": [
            "Export and rerun an out-of-order lost-response recipe in a clean temporary directory.",
            "Remove one referenced fixture and confirm import fails before sending requests."
          ],
          "deliverables": [
            "Incident-recipe export/import and a worked recovery exercise"
          ],
          "rollout": "Use recipes for internal synthetic exercises first; reject unsupported runner or fixture versions with migration guidance.",
          "skills": [
            "Reproducibility",
            "Incident tooling",
            "Safe export"
          ],
          "fieldMix": [
            {
              "field": "Quality engineering",
              "percentage": 60
            },
            {
              "field": "Developer tooling",
              "percentage": 40
            }
          ],
          "patterns": []
        }
      ]
    }
  ]
}
