{
  "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": "df8e1208-e1cc-413d-9e0a-2dad2eb5bde9",
      "key": "RTELEMETRY",
      "title": "Measure a workflow without collecting its private content",
      "summary": "Build an allowlisted telemetry boundary, useful aggregates and controlled diagnostic access.",
      "context": "A fictional document workspace wants to measure upload completion and failure. Its prototype sends filenames, document titles and raw errors to general analytics. Replace that path with a minimal event contract using synthetic traffic.",
      "stack": [
        "TypeScript",
        "JSON Schema",
        "HTTP collector double",
        "SQL"
      ],
      "prerequisites": [
        "Create synthetic upload workflows and a local collector that captures received payloads.",
        "Define measurement questions and a separate restricted diagnostic store fixture."
      ],
      "developerValue": "Practice minimization, safe failure handling and correct aggregates.",
      "companyValue": "Produce useful operational measurements with a reviewable collection boundary and disclosure regression suite.",
      "delivery": "Ten tickets using synthetic data. No claim of anonymization, privacy certification or measured customer behavior is made.",
      "phases": [
        {
          "id": "contract",
          "title": "Specify minimal measurement",
          "goal": "Define useful questions and an allowlisted event schema."
        },
        {
          "id": "boundary",
          "title": "Enforce collection limits",
          "goal": "Reject accidental content, separate diagnostics and bound retention."
        },
        {
          "id": "aggregate",
          "title": "Verify useful reporting",
          "goal": "Reconcile aggregates and test disclosure under failures."
        }
      ],
      "field": "Privacy engineering",
      "tickets": [
        {
          "id": "d894ff32-ed06-4fc9-aa15-05ce68a0a240",
          "key": "RTELEMETRY-101",
          "title": "Translate upload questions into bounded telemetry events",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 60,
          "phaseId": "contract",
          "dependsOn": [],
          "scenario": "Product wants to understand upload failures, but the event captures the entire form submission.",
          "acceptanceCriteria": [
            "Define attempted, accepted, completed and failed events with bounded reason categories.",
            "Map every field to a stated measurement question.",
            "Exclude filenames, document text, form values and unrestricted URLs."
          ],
          "implementationNotes": [
            "Counts describe workflow outcomes, not ability, attention or authorship."
          ],
          "verification": [
            "Answer the stated questions from a synthetic sequence.",
            "Remove a field without a measurement purpose and verify the report remains possible."
          ],
          "deliverables": [
            "Question map and minimal event contract"
          ],
          "rollout": "Review the contract before changing collection; unknown fields remain disallowed.",
          "skills": [
            "Event modeling",
            "Data minimization"
          ],
          "fieldMix": [
            {
              "field": "Privacy engineering",
              "percentage": 80
            },
            {
              "field": "Data engineering",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "ca51ee9c-678e-4b6d-b704-5837c27ff255",
          "key": "RTELEMETRY-102",
          "title": "Reject unknown telemetry fields at the sending boundary",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 120,
          "phaseId": "contract",
          "dependsOn": [
            "RTELEMETRY-101"
          ],
          "scenario": "Spreading an error object into an event accidentally includes headers and document metadata.",
          "acceptanceCriteria": [
            "Build payloads through a runtime schema with unknown-field rejection.",
            "Expose a typed interface that does not accept arbitrary payload spreading.",
            "Report rejection without echoing the rejected payload."
          ],
          "implementationNotes": [
            "The runtime boundary must handle loosely typed callers as well as normal TypeScript code."
          ],
          "verification": [
            "Send a valid completion and inspect the collector payload.",
            "Add token-like headers, nested objects and unknown properties; no event may reach the collector."
          ],
          "deliverables": [
            "Telemetry boundary and rejection tests"
          ],
          "rollout": "Route events through the boundary before retiring the old sender.",
          "skills": [
            "Runtime validation",
            "Information boundaries"
          ],
          "fieldMix": [
            {
              "field": "Privacy engineering",
              "percentage": 60
            },
            {
              "field": "Security",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "4ae8c056-86ba-401d-b122-724f2aa886e4",
          "key": "RTELEMETRY-103",
          "title": "Use a short-lived workflow correlation ID with a defined scope",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 120,
          "phaseId": "contract",
          "dependsOn": [
            "RTELEMETRY-101",
            "RTELEMETRY-102"
          ],
          "scenario": "Analytics uses the account email as a permanent join key for all uploads.",
          "acceptanceCriteria": [
            "Use a random operation ID limited to one workflow and its bounded retry window.",
            "Exclude account, document and contact identifiers from the ID.",
            "Document linkability within the operation rather than calling the event anonymous."
          ],
          "implementationNotes": [
            "Keep subject mapping outside the generic sink; collect correlation only when required for the stated question."
          ],
          "verification": [
            "Retry one operation and verify intended correlation, then start another with a new ID.",
            "Inspect IDs and payloads for subject or document fields."
          ],
          "deliverables": [
            "Correlation lifecycle and identifier tests"
          ],
          "rollout": "Version the schema and stop emitting direct identifiers before comparing reports.",
          "skills": [
            "Pseudonymous identifiers",
            "Retention scope"
          ],
          "fieldMix": [
            {
              "field": "Privacy engineering",
              "percentage": 100
            }
          ],
          "patterns": []
        },
        {
          "id": "8620bd55-16c3-46ce-abf8-52420eccda58",
          "key": "RTELEMETRY-104",
          "title": "Map upload errors to safe categories before analytics dispatch",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "boundary",
          "dependsOn": [
            "RTELEMETRY-102"
          ],
          "scenario": "An unfamiliar storage exception contains a signed URL. The fallback serializes it into analytics.",
          "acceptanceCriteria": [
            "Map known failures to bounded categories and unknown failures to a generic category.",
            "Never send raw messages, stacks, headers or signed URLs through generic telemetry.",
            "Route justified detailed diagnostics through a separate restricted interface."
          ],
          "implementationNotes": [
            "Do not rely on a regular expression to find every possible secret in an arbitrary object."
          ],
          "verification": [
            "Classify known storage, validation and timeout errors.",
            "Inject an unfamiliar nested error with a token-like URL and verify only the generic category is emitted."
          ],
          "deliverables": [
            "Safe classifier and nested-error fixtures"
          ],
          "rollout": "Deploy the safe fallback before expanding error coverage.",
          "skills": [
            "Error handling",
            "Safe defaults"
          ],
          "fieldMix": [
            {
              "field": "Privacy engineering",
              "percentage": 70
            },
            {
              "field": "Site reliability",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "35f5de4a-47fc-414e-b58f-68953de9ddd0",
          "key": "RTELEMETRY-105",
          "title": "Keep restricted upload diagnostics out of the analytics transport",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "ADVANCED",
          "estimateMinutes": 210,
          "phaseId": "boundary",
          "dependsOn": [
            "RTELEMETRY-103",
            "RTELEMETRY-104"
          ],
          "scenario": "Support needs a detailed failure record, but the proposed implementation reuses analytics permissions and transport.",
          "acceptanceCriteria": [
            "Create a separate diagnostic store with tenant-scoped access.",
            "Collect only justified fields with a bounded retention period.",
            "Use safe references for an authorized diagnostic lookup rather than exposing details in counters."
          ],
          "implementationNotes": [
            "Use synthetic errors; omit credentials and private upload bytes even from this exercise diagnostic store."
          ],
          "verification": [
            "Read a diagnostic as an authorized scoped operator.",
            "Attempt cross-tenant access and inspect analytics requests to verify no diagnostic details pass through them."
          ],
          "deliverables": [
            "Restricted diagnostics and transport-separation tests"
          ],
          "rollout": "Enable diagnostics independently; analytics must work when diagnostics are disabled.",
          "skills": [
            "Access separation",
            "Operational privacy"
          ],
          "fieldMix": [
            {
              "field": "Privacy engineering",
              "percentage": 60
            },
            {
              "field": "Security",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "48670ee9-cd20-4a55-bbf4-cc6c36ec6a55",
          "key": "RTELEMETRY-106",
          "title": "Drop telemetry safely when validation or the collector fails",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "boundary",
          "dependsOn": [
            "RTELEMETRY-102",
            "RTELEMETRY-104"
          ],
          "scenario": "The validation failure handler prints the original event, leaking the content the guard rejected.",
          "acceptanceCriteria": [
            "Never log the rejected event payload.",
            "Keep optional analytics failure independent of upload completion with bounded buffers and retries.",
            "Count dropped events through safe categories so gaps remain visible."
          ],
          "implementationNotes": [
            "A collector outage must not block the workflow or grow an unlimited in-memory queue."
          ],
          "verification": [
            "Fail validation and inspect captured logs and requests for the rejected marker.",
            "Disconnect the collector under sustained synthetic events and verify bounded buffering and successful uploads."
          ],
          "deliverables": [
            "Safe fallback and outage regressions"
          ],
          "rollout": "Ship the fallback before stricter validation; drop optional events rather than exposing raw content.",
          "skills": [
            "Failure containment",
            "Data minimization"
          ],
          "fieldMix": [
            {
              "field": "Privacy engineering",
              "percentage": 60
            },
            {
              "field": "Site reliability",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "ff0198b3-696b-4f46-a50d-deb1fea7808e",
          "key": "RTELEMETRY-107",
          "title": "Expire raw workflow events while preserving only approved aggregates",
          "type": "CHORE",
          "priority": "MEDIUM",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "boundary",
          "dependsOn": [
            "RTELEMETRY-103",
            "RTELEMETRY-105",
            "RTELEMETRY-106"
          ],
          "scenario": "Correlation-bearing raw events remain forever although reporting needs only daily counts.",
          "acceptanceCriteria": [
            "Version fictional raw-event and aggregate retention rules.",
            "Remove expired raw events from the declared sink and replay buffers.",
            "Report unresolved copies and avoid assuming aggregates cannot identify people."
          ],
          "implementationNotes": [
            "Use injected time and local adapters; retention values are exercise inputs, not real-world policy advice."
          ],
          "verification": [
            "Advance beyond raw expiry and verify sink and replay cleanup while permitted counts remain.",
            "Fail one cleanup adapter and verify its unresolved location appears in the report."
          ],
          "deliverables": [
            "Telemetry retention job and copy-reconciliation cases"
          ],
          "rollout": "Preview eligibility before removal and version aggregate definitions when collection changes.",
          "skills": [
            "Retention engineering",
            "Aggregation"
          ],
          "fieldMix": [
            {
              "field": "Privacy engineering",
              "percentage": 60
            },
            {
              "field": "Data engineering",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "4fd76377-2c25-4355-8224-20e4b15853cc",
          "key": "RTELEMETRY-108",
          "title": "Suppress small-group reports under the exercise disclosure rule",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "EXPERT",
          "estimateMinutes": 270,
          "phaseId": "aggregate",
          "dependsOn": [
            "RTELEMETRY-101",
            "RTELEMETRY-103",
            "RTELEMETRY-107"
          ],
          "scenario": "Filtering a report to a tiny group reveals one person’s workflow even when source events omit email.",
          "acceptanceCriteria": [
            "Apply an exercise threshold of 10 distinct synthetic subjects through a separately restricted aggregation fixture.",
            "Prevent supported filter combinations and complementary totals from releasing a suppressed value.",
            "Document that thresholding addresses a specific disclosure path and does not prove anonymity or differential privacy."
          ],
          "implementationNotes": [
            "Do not add permanent subject IDs to the general event sink to support this exercise; define the separate aggregation boundary and tested query family."
          ],
          "verification": [
            "Query small, large and overlapping groups and inspect API plus report downloads.",
            "Attempt deduction from a total and complementary group; verify the declared release rule suppresses the relevant results."
          ],
          "deliverables": [
            "Report-release rule, disclosure fixtures and limitations"
          ],
          "rollout": "Keep fine-grained reports disabled until the rule and tested limits are reviewed.",
          "skills": [
            "Disclosure control",
            "Aggregation boundaries"
          ],
          "fieldMix": [
            {
              "field": "Privacy engineering",
              "percentage": 70
            },
            {
              "field": "Data engineering",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "fe1d176e-5aa8-4b9a-8ad3-faa7ad5256c4",
          "key": "RTELEMETRY-109",
          "title": "Reconcile upload outcome counts without hiding dropped telemetry",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 150,
          "phaseId": "aggregate",
          "dependsOn": [
            "RTELEMETRY-101",
            "RTELEMETRY-106",
            "RTELEMETRY-107"
          ],
          "scenario": "The success percentage rises during a collector outage because failed uploads lose terminal events.",
          "acceptanceCriteria": [
            "Define denominators and windows from the event contract.",
            "Expose incomplete operations and dropped events instead of treating missing completion as success.",
            "Mark comparisons incomplete when collection gaps prevent a supported result."
          ],
          "implementationNotes": [
            "Keep uncertainty visible; never invent missing user behavior with model guesses."
          ],
          "verification": [
            "Replay success, failure, duplicate and missing-terminal sequences and reconcile counts.",
            "Simulate asymmetric loss and verify the report is incomplete rather than improved."
          ],
          "deliverables": [
            "Outcome aggregation and collection-gap regressions"
          ],
          "rollout": "Compare the new calculation with the old one on synthetic traces before changing the report.",
          "skills": [
            "Metrics correctness",
            "Uncertainty"
          ],
          "fieldMix": [
            {
              "field": "Site reliability",
              "percentage": 50
            },
            {
              "field": "Data engineering",
              "percentage": 30
            },
            {
              "field": "Privacy engineering",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "5d610747-4591-44af-8cd4-c394bc8885db",
          "key": "RTELEMETRY-110",
          "title": "Test telemetry collection with planted private-content markers",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "EXPERT",
          "estimateMinutes": 270,
          "phaseId": "aggregate",
          "dependsOn": [
            "RTELEMETRY-102",
            "RTELEMETRY-104",
            "RTELEMETRY-105",
            "RTELEMETRY-106",
            "RTELEMETRY-107",
            "RTELEMETRY-108",
            "RTELEMETRY-109"
          ],
          "scenario": "The contract looks safe, but errors, retries and report downloads may bypass the sending boundary.",
          "acceptanceCriteria": [
            "Plant unique synthetic markers in filenames, titles, headers, errors and form values.",
            "Exercise success, retry, validation failure, collector outage and report download paths.",
            "Verify markers never reach generic telemetry or logs while required aggregate questions remain answerable."
          ],
          "implementationNotes": [
            "Passing supports only inspected conditions and boundaries, not a blanket no-leak guarantee."
          ],
          "verification": [
            "Search collector captures, fallback logs and downloaded reports for every marker.",
            "Add a deliberate bypass to the test sender and confirm the regression detects it; verify the guarded implementation passes."
          ],
          "deliverables": [
            "Disclosure regression matrix and boundary review"
          ],
          "rollout": "Run the matrix when schemas or sending paths change; block the exercise release on a prohibited disclosure.",
          "skills": [
            "Privacy testing",
            "Defense in depth"
          ],
          "fieldMix": [
            {
              "field": "Privacy engineering",
              "percentage": 50
            },
            {
              "field": "Quality engineering",
              "percentage": 50
            }
          ],
          "patterns": []
        }
      ]
    }
  ]
}
