{
  "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": "c9f3c302-8964-4275-ba34-361bc13c1d07",
      "key": "CDOWN",
      "title": "A dependable mobile course-download shelf",
      "field": "Mobile",
      "summary": "Manage resumable public-content downloads and safe local playback state.",
      "context": "Fictional learning app Birch offers synthetic text and small local media fixtures through a loopback adapter. No copyrighted course assets or network accounts are needed.",
      "stack": [
        "React Native",
        "TypeScript",
        "SQLite",
        "Emulator"
      ],
      "prerequisites": [
        "Create small local byte fixtures and a range-response stub.",
        "Simulate low storage, interruptions and stale manifests."
      ],
      "developerValue": "Practice mobile file lifecycles and background state recovery.",
      "companyValue": "Inspect predictable resource usage and truthful download status.",
      "delivery": "Use generated local fixtures; app-store publishing is outside scope.",
      "phases": [
        {
          "id": "shelf",
          "title": "Describe downloads",
          "goal": "Model local content and sizes."
        },
        {
          "id": "transfer",
          "title": "Handle transfer boundaries",
          "goal": "Verify and recover bytes."
        },
        {
          "id": "lifecycle",
          "title": "Maintain the shelf",
          "goal": "Clean up and explain resource failures."
        }
      ],
      "tickets": [
        {
          "id": "a5a79885-e03a-44a5-b0eb-3c45ce51e13d",
          "key": "CDOWN-101",
          "title": "Distinguish unknown course-download sizes from zero bytes",
          "type": "BUG",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 60,
          "phaseId": "shelf",
          "dependsOn": [],
          "scenario": "Unmeasured courses show 0 MB and users assume downloads are free of storage cost. Display size uncertainty.",
          "acceptanceCriteria": [
            "Unknown size is labeled",
            "Zero-byte fixtures remain valid",
            "Unit formatting has boundary tests"
          ],
          "implementationNotes": [
            "Do not invent estimates without metadata."
          ],
          "verification": [
            "Render zero and unknown",
            "Render malformed size"
          ],
          "deliverables": [
            "Size formatter and shelf states"
          ],
          "rollout": "Fall back to byte counts for known values.",
          "skills": [
            "Formatting",
            "UX"
          ],
          "fieldMix": [
            {
              "field": "Mobile",
              "percentage": 100
            }
          ],
          "patterns": []
        },
        {
          "id": "63240b04-034f-470e-8fec-b277528a15c3",
          "key": "CDOWN-102",
          "title": "Keep mobile download buttons consistent with durable state",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 105,
          "phaseId": "shelf",
          "dependsOn": [],
          "scenario": "Returning to the shelf shows Download while a transfer is active. Render controls from one persisted lifecycle.",
          "acceptanceCriteria": [
            "Active transfer shows pause",
            "Completed content shows open",
            "Invalid states do not expose start"
          ],
          "implementationNotes": [
            "Define explicit lifecycle transitions."
          ],
          "verification": [
            "Navigate away and return",
            "Load corrupt lifecycle value"
          ],
          "deliverables": [
            "Download-state projection"
          ],
          "rollout": "Disable new downloads if state cannot be read.",
          "skills": [
            "State machines",
            "Persistence"
          ],
          "fieldMix": [
            {
              "field": "Mobile",
              "percentage": 80
            },
            {
              "field": "Storage systems",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "69e55e83-3c66-4aa6-bf4a-e1a0c3399a46",
          "key": "CDOWN-103",
          "title": "Validate course manifest paths before creating files",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 120,
          "phaseId": "shelf",
          "dependsOn": [
            "CDOWN-101"
          ],
          "scenario": "A malformed manifest filename can escape its course directory. Restrict all destinations to a scoped cache root.",
          "acceptanceCriteria": [
            "Traversal is rejected",
            "Absolute paths are rejected",
            "Valid nested relative paths stay scoped"
          ],
          "implementationNotes": [
            "Resolve paths before opening files."
          ],
          "verification": [
            "Write a valid nested fixture",
            "Reject parent-directory and drive paths"
          ],
          "deliverables": [
            "Manifest path validator"
          ],
          "rollout": "Reject new manifests until path validation is restored.",
          "skills": [
            "Filesystem",
            "Input security"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 60
            },
            {
              "field": "Storage systems",
              "percentage": 20
            },
            {
              "field": "Mobile",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "a37b82a5-3097-47a8-b6f3-9fc4251423e1",
          "key": "CDOWN-104",
          "title": "Resume a mobile course transfer only with matching content identity",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "transfer",
          "dependsOn": [
            "CDOWN-102",
            "CDOWN-103"
          ],
          "scenario": "A paused transfer resumes after content changed and produces mixed bytes. Bind ranges to a manifest version.",
          "acceptanceCriteria": [
            "Resume checks content identity",
            "Mismatch discards incompatible partial bytes",
            "Restart remains explicit in UI"
          ],
          "implementationNotes": [
            "Treat ETags as opaque validators."
          ],
          "verification": [
            "Resume unchanged fixture",
            "Change validator during pause"
          ],
          "deliverables": [
            "Range-resume coordinator"
          ],
          "rollout": "Disable resume and restart from zero safely.",
          "skills": [
            "HTTP",
            "Integrity"
          ],
          "fieldMix": [
            {
              "field": "Storage systems",
              "percentage": 40
            },
            {
              "field": "Networking",
              "percentage": 30
            },
            {
              "field": "Mobile",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "2cba4bfc-9ce8-4f34-8471-f5265a4e39c7",
          "key": "CDOWN-105",
          "title": "Verify downloaded course bytes before exposing Open",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "transfer",
          "dependsOn": [
            "CDOWN-104"
          ],
          "scenario": "A truncated transfer is marked complete because the connection closed normally. Verify length and declared digest.",
          "acceptanceCriteria": [
            "Completed means both checks pass",
            "Mismatch stays unavailable",
            "Bad partial bytes can be removed"
          ],
          "implementationNotes": [
            "Digest metadata comes from the local trusted manifest."
          ],
          "verification": [
            "Download valid fixture",
            "Truncate or flip one byte"
          ],
          "deliverables": [
            "Completion verifier and corruption cases"
          ],
          "rollout": "Disable Open for unverified content.",
          "skills": [
            "Hashing",
            "Data integrity"
          ],
          "fieldMix": [
            {
              "field": "Storage systems",
              "percentage": 60
            },
            {
              "field": "Mobile",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "9da19238-5006-42ef-b966-b70da5aee1a7",
          "key": "CDOWN-106",
          "title": "Pause mobile transfers when storage reservation fails",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 135,
          "phaseId": "transfer",
          "dependsOn": [
            "CDOWN-102",
            "CDOWN-103"
          ],
          "scenario": "A nearly full emulator accepts several downloads and fails unpredictably. Reserve a bounded budget before writing.",
          "acceptanceCriteria": [
            "Admission accounts for active transfers",
            "Failure preserves existing content",
            "User sees required space"
          ],
          "implementationNotes": [
            "Reservation estimates must state uncertainty."
          ],
          "verification": [
            "Admit fitting transfer",
            "Start competing transfers exceeding budget"
          ],
          "deliverables": [
            "Storage admission policy"
          ],
          "rollout": "Stop new transfers while preserving installed courses.",
          "skills": [
            "Resource management",
            "Concurrency"
          ],
          "fieldMix": [
            {
              "field": "Storage systems",
              "percentage": 50
            },
            {
              "field": "Mobile",
              "percentage": 30
            },
            {
              "field": "Performance engineering",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "776a4e76-9081-4c57-b692-b4995ccff979",
          "key": "CDOWN-107",
          "title": "Recover a course-download rename interrupted by process death",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 240,
          "phaseId": "transfer",
          "dependsOn": [
            "CDOWN-105",
            "CDOWN-106"
          ],
          "scenario": "A crash between verification and final rename leaves duplicate shelf entries. Introduce a recoverable promotion record.",
          "acceptanceCriteria": [
            "Recovery identifies one installed version",
            "Unverified partials stay hidden",
            "Repeated recovery is idempotent"
          ],
          "implementationNotes": [
            "Keep metadata and file promotion reconciliation explicit."
          ],
          "verification": [
            "Kill at each promotion boundary",
            "Repeat recovery after missing temp file"
          ],
          "deliverables": [
            "Promotion journal and crash cases"
          ],
          "rollout": "Disable promotion and retain recoverable temporary files.",
          "skills": [
            "Crash consistency",
            "Transactions"
          ],
          "fieldMix": [
            {
              "field": "Storage systems",
              "percentage": 50
            },
            {
              "field": "Mobile",
              "percentage": 30
            },
            {
              "field": "Database engineering",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "9449c0b3-357d-4c5e-96a8-5cdaccbf927c",
          "key": "CDOWN-108",
          "title": "Remove one downloaded course without breaking shared assets",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "lifecycle",
          "dependsOn": [
            "CDOWN-107"
          ],
          "scenario": "Deleting a course removes an image another course references. Track local references before reclaiming shared blobs.",
          "acceptanceCriteria": [
            "Unreferenced blobs are reclaimed",
            "Referenced blobs remain",
            "Failed cleanup is retryable"
          ],
          "implementationNotes": [
            "Keep references scoped to verified manifests."
          ],
          "verification": [
            "Delete unique course",
            "Delete course with shared asset"
          ],
          "deliverables": [
            "Reference-aware cleanup"
          ],
          "rollout": "Disable physical reclamation while fixing reference accounting.",
          "skills": [
            "Reference counting",
            "Storage"
          ],
          "fieldMix": [
            {
              "field": "Storage systems",
              "percentage": 70
            },
            {
              "field": "Mobile",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "fc923325-e7c1-4576-b712-9a5456e6b24a",
          "key": "CDOWN-109",
          "title": "Show course-download progress without rendering every chunk",
          "type": "BUG",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 105,
          "phaseId": "lifecycle",
          "dependsOn": [
            "CDOWN-104"
          ],
          "scenario": "Small network chunks trigger excessive mobile renders. Coalesce progress updates while keeping completion immediate.",
          "acceptanceCriteria": [
            "Updates have bounded frequency",
            "Completion bypasses throttle",
            "Paused bytes remain accurate"
          ],
          "implementationNotes": [
            "Use an injected scheduler."
          ],
          "verification": [
            "Stream many chunks",
            "Pause between scheduled updates"
          ],
          "deliverables": [
            "Progress coalescer and render-count check"
          ],
          "rollout": "Reduce to coarse milestones if scheduling regresses.",
          "skills": [
            "Rendering",
            "Performance"
          ],
          "fieldMix": [
            {
              "field": "Performance engineering",
              "percentage": 60
            },
            {
              "field": "Mobile",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "df1317f2-dad1-4fd2-856b-69c2e4f0ceab",
          "key": "CDOWN-110",
          "title": "Provide a local download repair action with explicit scope",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 120,
          "phaseId": "lifecycle",
          "dependsOn": [
            "CDOWN-108",
            "CDOWN-109"
          ],
          "scenario": "Users cannot recover one corrupt course without clearing the entire app. Add repair for the selected course only.",
          "acceptanceCriteria": [
            "Repair revalidates selected files",
            "Other courses remain intact",
            "Offline repair explains deferred bytes"
          ],
          "implementationNotes": [
            "Never clear account or unrelated application storage."
          ],
          "verification": [
            "Repair corrupted fixture",
            "Run repair offline"
          ],
          "deliverables": [
            "Scoped repair flow and isolation checks"
          ],
          "rollout": "Hide repair if deletion scope cannot be established.",
          "skills": [
            "Recovery",
            "Isolation"
          ],
          "fieldMix": [
            {
              "field": "Mobile",
              "percentage": 50
            },
            {
              "field": "Storage systems",
              "percentage": 50
            }
          ],
          "patterns": []
        }
      ]
    }
  ]
}
