{
  "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": "5541d678-05d0-41ca-a883-491dc2a791b9",
      "key": "REXPORT",
      "title": "Deliver a personal data export with a narrow access boundary",
      "summary": "Build a scoped asynchronous export, redact unrelated records and expire its downloadable artifact.",
      "context": "A fictional learning workspace offers a member a portable copy of their own profile, notes and activity settings. Shared documents contain contributions from other people. The product export policy specifies included fields and shared-record handling; this is an engineering exercise, not a legal portability claim.",
      "stack": [
        "TypeScript",
        "PostgreSQL",
        "JSON",
        "Object storage adapter"
      ],
      "prerequisites": [
        "Create synthetic members, private notes and shared-document contributions in a local database.",
        "Provide fake queue and object-storage adapters with controllable expiry and failure."
      ],
      "developerValue": "Practice export scoping, consistency, streaming and expiring access without leaking other members’ data.",
      "companyValue": "Create a reviewable export contract and cross-subject regression suite for an approved product policy.",
      "delivery": "Ten tickets from field inventory to delivery and cleanup. Artifacts contain only synthetic data, and all download links resolve through local provider doubles.",
      "phases": [
        {
          "id": "scope",
          "title": "Specify the export boundary",
          "goal": "Define authorized subjects, included fields and shared-record rules."
        },
        {
          "id": "assemble",
          "title": "Build a consistent artifact",
          "goal": "Generate bounded exports with explicit version and failure behavior."
        },
        {
          "id": "deliver",
          "title": "Deliver and expire access",
          "goal": "Restrict retrieval and verify cleanup and disclosure behavior."
        }
      ],
      "field": "Privacy engineering",
      "tickets": [
        {
          "id": "077c4e9a-6377-474e-8da8-3a97a0a7819e",
          "key": "REXPORT-101",
          "title": "List exportable member fields before serializing database rows",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 60,
          "phaseId": "scope",
          "dependsOn": [],
          "scenario": "A prototype exports complete ORM objects, including internal moderation flags and provider tokens.",
          "acceptanceCriteria": [
            "Create an explicit allowlist for profile, private-note and settings fields.",
            "Exclude credentials, internal operational fields and unrelated-member data.",
            "Version the export schema and document omitted field categories."
          ],
          "implementationNotes": [
            "Build export DTOs independently of database model serialization."
          ],
          "verification": [
            "Export a synthetic row containing token-like and internal fields and verify they are absent.",
            "Add an unknown database column and confirm it does not enter the artifact automatically."
          ],
          "deliverables": [
            "Export field contract and allowlist tests"
          ],
          "rollout": "Review the field contract before enabling generation; new fields require an explicit schema change.",
          "skills": [
            "Data minimization",
            "Serialization"
          ],
          "fieldMix": [
            {
              "field": "Privacy engineering",
              "percentage": 80
            },
            {
              "field": "Backend",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "f44598d1-e7ca-4f2e-8fef-a56102688269",
          "key": "REXPORT-102",
          "title": "Define how shared document contributions appear in a personal export",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 120,
          "phaseId": "scope",
          "dependsOn": [
            "REXPORT-101"
          ],
          "scenario": "Exporting a whole shared document would include other members’ private comments and mentions.",
          "acceptanceCriteria": [
            "Specify which subject-owned contributions and necessary context are included.",
            "Define redaction or omission for unrelated-member fields and private comments.",
            "Represent omitted shared content honestly rather than implying the export is a complete document history."
          ],
          "implementationNotes": [
            "Use a mixed-author fixture; access to a workspace does not by itself settle the product export policy."
          ],
          "verification": [
            "Export a document with two authors, private comments and a deleted contribution.",
            "Verify exported context does not reveal an unrelated private field or silently change the subject’s contribution text."
          ],
          "deliverables": [
            "Shared-record export policy and mixed-author fixtures"
          ],
          "rollout": "Keep shared-content export disabled until its policy and regression examples are reviewed.",
          "skills": [
            "Privacy boundaries",
            "Content modeling"
          ],
          "fieldMix": [
            {
              "field": "Privacy engineering",
              "percentage": 100
            }
          ],
          "patterns": []
        },
        {
          "id": "55684b80-9d66-4f19-aa51-c8e37add4265",
          "key": "REXPORT-103",
          "title": "Bind export creation to the current authorized subject",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 135,
          "phaseId": "scope",
          "dependsOn": [
            "REXPORT-101",
            "REXPORT-102"
          ],
          "scenario": "The endpoint accepts any member ID and relies on the UI to submit the current user.",
          "acceptanceCriteria": [
            "Resolve export scope from the authenticated subject and approved workspace access.",
            "Reject substituted IDs and revoked sessions before queueing work.",
            "Record a safe operation reference without embedding personal fields in job identifiers."
          ],
          "implementationNotes": [
            "Authorization also belongs at the data-access boundary used by background assembly."
          ],
          "verification": [
            "Create an export as the matching synthetic member.",
            "Attempt another member’s ID and a revoked membership, checking that no job or artifact is created."
          ],
          "deliverables": [
            "Scoped export command and cross-subject denial tests"
          ],
          "rollout": "Deploy command and repository checks together before queue activation.",
          "skills": [
            "Authorization",
            "Repository boundaries"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 60
            },
            {
              "field": "Privacy engineering",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "f284d4db-3f78-41f4-b72e-fdfb7cecca73",
          "key": "REXPORT-104",
          "title": "Freeze the export selection without holding a long database transaction",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "ADVANCED",
          "estimateMinutes": 210,
          "phaseId": "assemble",
          "dependsOn": [
            "REXPORT-103"
          ],
          "scenario": "Notes added midway through an export appear inconsistently, and the worker holds a transaction open while uploading the archive.",
          "acceptanceCriteria": [
            "Declare the export consistency boundary and record a cutoff or snapshot reference.",
            "Keep database selection consistent with that boundary while assembling outside an unbounded transaction.",
            "Expose generation time and the selection boundary in the manifest."
          ],
          "implementationNotes": [
            "Choose a method supported by the local schema; do not promise a global snapshot across unrelated stores without a protocol."
          ],
          "verification": [
            "Edit and add notes during a paused assembly and verify the documented inclusion rule.",
            "Slow artifact upload and verify no long-lived database transaction is retained solely for transfer."
          ],
          "deliverables": [
            "Selection protocol and concurrent-edit export tests"
          ],
          "rollout": "Version the consistency contract; failed assembly may retry against the same frozen selection or start a clearly new operation.",
          "skills": [
            "Snapshot semantics",
            "Transactions"
          ],
          "fieldMix": [
            {
              "field": "Database engineering",
              "percentage": 50
            },
            {
              "field": "Privacy engineering",
              "percentage": 30
            },
            {
              "field": "System design",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "5dd961ce-6670-43d5-9497-f225c6960c61",
          "key": "REXPORT-105",
          "title": "Stream large note exports with bounded intermediate storage",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "ADVANCED",
          "estimateMinutes": 210,
          "phaseId": "assemble",
          "dependsOn": [
            "REXPORT-101",
            "REXPORT-104"
          ],
          "scenario": "A member with many notes causes the worker to build one large JSON string and exceed its resource budget.",
          "acceptanceCriteria": [
            "Stream the chosen format with bounded buffering and valid escaping.",
            "Keep ordering and manifest counts deterministic for the frozen selection.",
            "Remove incomplete temporary artifacts on controlled failure while preserving retry metadata."
          ],
          "implementationNotes": [
            "Use a synthetic large-note fixture and declared memory/disk limits; do not require real user content."
          ],
          "verification": [
            "Export the same selection through small and large chunk sizes and compare parsed records and digest.",
            "Interrupt output after a multibyte value and verify no incomplete artifact becomes downloadable."
          ],
          "deliverables": [
            "Streaming exporter, resource report and interrupted-write regression"
          ],
          "rollout": "Keep completed artifacts unpublished until final validation; retry writes to a new temporary object identity.",
          "skills": [
            "Streaming",
            "Artifact integrity"
          ],
          "fieldMix": [
            {
              "field": "Performance engineering",
              "percentage": 40
            },
            {
              "field": "Privacy engineering",
              "percentage": 30
            },
            {
              "field": "Storage systems",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "2487e66c-2aeb-40c1-9f4a-50d4e35e3838",
          "key": "REXPORT-106",
          "title": "Validate the export manifest before marking assembly complete",
          "type": "CHORE",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 150,
          "phaseId": "assemble",
          "dependsOn": [
            "REXPORT-102",
            "REXPORT-105"
          ],
          "scenario": "The archive download succeeds even when one source query failed and an entire section is missing.",
          "acceptanceCriteria": [
            "Record schema version, section counts, selection boundary and artifact digest.",
            "Distinguish intentionally omitted sections from failed required sections.",
            "Mark ready only after required sections and digest validation succeed."
          ],
          "implementationNotes": [
            "A digest establishes artifact consistency, not completeness beyond the declared export contract."
          ],
          "verification": [
            "Fail the required private-note query and verify the export remains non-ready and non-downloadable, with the required-section failure reported explicitly.",
            "Corrupt a completed temporary artifact and verify publication is blocked."
          ],
          "deliverables": [
            "Manifest validator and incomplete-section fixtures"
          ],
          "rollout": "Place manifest validation before the ready transition; keep failed artifacts inaccessible and eligible for cleanup.",
          "skills": [
            "Integrity checks",
            "State transitions"
          ],
          "fieldMix": [
            {
              "field": "Storage systems",
              "percentage": 50
            },
            {
              "field": "Privacy engineering",
              "percentage": 30
            },
            {
              "field": "Data engineering",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "72f7ca97-7e1e-4f8b-9c59-2f22591b5417",
          "key": "REXPORT-107",
          "title": "Issue a short-lived download capability only after subject authorization",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "ADVANCED",
          "estimateMinutes": 210,
          "phaseId": "deliver",
          "dependsOn": [
            "REXPORT-103",
            "REXPORT-106"
          ],
          "scenario": "A predictable artifact URL lets one member retrieve another member’s completed export.",
          "acceptanceCriteria": [
            "Authorize every capability request against the current subject and export operation.",
            "Scope the capability to one object and a declared short lifetime.",
            "Keep capabilities out of generic logs, analytics and unrelated API responses."
          ],
          "implementationNotes": [
            "Use a local storage adapter implementing the capability contract; an opaque URL alone is not authorization."
          ],
          "verification": [
            "Request and use a valid capability for the matching export.",
            "Attempt another subject’s operation, an expired capability and an altered object reference; all must fail without bytes."
          ],
          "deliverables": [
            "Download capability endpoint and scope/expiry tests"
          ],
          "rollout": "Enable downloads only after complete artifacts exist; disable capability issuance independently during an incident.",
          "skills": [
            "Capability security",
            "Access control"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 60
            },
            {
              "field": "Privacy engineering",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "0e96ad48-8f0c-4997-afea-e5d8d141e5f6",
          "key": "REXPORT-108",
          "title": "Revoke export access when the subject loses the required session",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 300,
          "phaseId": "deliver",
          "dependsOn": [
            "REXPORT-103",
            "REXPORT-107"
          ],
          "scenario": "A member signs out all sessions after an account concern, but a previously issued export link remains usable longer than the product policy allows.",
          "acceptanceCriteria": [
            "Define the revocation guarantee and the limits of direct object-store capabilities.",
            "Choose a bounded retrieval design that meets the stated exercise policy and document its latency/availability tradeoff.",
            "Prevent new access after revocation and state how an already-started transfer is handled."
          ],
          "implementationNotes": [
            "Do not promise immediate revocation of an independently valid signed URL without a mechanism that can enforce it."
          ],
          "verification": [
            "Issue access, revoke the session and attempt a new download under the chosen design.",
            "Revoke during a paused transfer and verify the documented in-flight behavior and resource cleanup."
          ],
          "deliverables": [
            "Revocation design decision and enforced retrieval tests"
          ],
          "rollout": "Roll out the chosen retrieval path under a new capability version; stop issuing the old form before claiming the new guarantee.",
          "skills": [
            "Revocation",
            "Security tradeoffs"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 40
            },
            {
              "field": "Privacy engineering",
              "percentage": 40
            },
            {
              "field": "System design",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "57283d9b-6214-4318-96d4-0509f54e68ac",
          "key": "REXPORT-109",
          "title": "Expire export artifacts and incomplete assembly objects separately",
          "type": "CHORE",
          "priority": "MEDIUM",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "deliver",
          "dependsOn": [
            "REXPORT-105",
            "REXPORT-106",
            "REXPORT-107"
          ],
          "scenario": "Completed exports expire after a day, but failed assembly objects remain indefinitely under a different prefix.",
          "acceptanceCriteria": [
            "Define bounded lifetimes for ready, failed and abandoned temporary artifacts.",
            "Recheck active assembly ownership before removing a temporary object.",
            "Confirm object removal separately from expired download access."
          ],
          "implementationNotes": [
            "Use an injected clock and per-operation object registry; prefix age alone cannot distinguish an active write."
          ],
          "verification": [
            "Advance time through each lifecycle and verify correct removal eligibility.",
            "Race cleanup with an active assembly lease and verify either safe retention or the declared cancellation path."
          ],
          "deliverables": [
            "Artifact cleanup policy and lifecycle race tests"
          ],
          "rollout": "Run a scoped preview before local cleanup; retain unresolved storage outcomes for reconciliation.",
          "skills": [
            "Retention",
            "Resource ownership"
          ],
          "fieldMix": [
            {
              "field": "Privacy engineering",
              "percentage": 50
            },
            {
              "field": "Storage systems",
              "percentage": 30
            },
            {
              "field": "Site reliability",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "308965e9-7221-4913-bcff-a24d6aba55f5",
          "key": "REXPORT-110",
          "title": "Review the export for cross-member disclosure and delivery failures",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "EXPERT",
          "estimateMinutes": 270,
          "phaseId": "deliver",
          "dependsOn": [
            "REXPORT-102",
            "REXPORT-106",
            "REXPORT-108",
            "REXPORT-109"
          ],
          "scenario": "The happy-path export looks correct, but nobody has reviewed shared records, access revocation and abandoned files together.",
          "acceptanceCriteria": [
            "Run a fixture matrix covering two members, two organizations, shared contributions and private notes.",
            "Reconcile manifest counts and allowed fields with the declared policy and actual artifact.",
            "Report tested boundaries, omitted content and unresolved provider limitations without a blanket privacy certification."
          ],
          "implementationNotes": [
            "The exercise review is a reproducible engineering check; it does not create noCV evidence or legal assurance by itself."
          ],
          "verification": [
            "Attempt creation, polling and download across subject/organization boundaries.",
            "Exercise interrupted assembly, expiry and session revocation, then inventory remaining local artifacts."
          ],
          "deliverables": [
            "Export review report and reproducible disclosure/failure matrix"
          ],
          "rollout": "Enable the complete local flow only when required cases pass; keep unsupported content categories explicitly out of the export contract.",
          "skills": [
            "Privacy testing",
            "Failure analysis"
          ],
          "fieldMix": [
            {
              "field": "Privacy engineering",
              "percentage": 50
            },
            {
              "field": "Quality engineering",
              "percentage": 30
            },
            {
              "field": "Security",
              "percentage": 20
            }
          ],
          "patterns": []
        }
      ]
    }
  ]
}
