{
  "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": "558c0723-d030-4cd2-8b38-a2485f2edfa4",
      "key": "CUPDATE",
      "title": "A recoverable edge software-update simulator",
      "field": "Embedded and edge",
      "summary": "Stage, validate and switch synthetic software images in an A/B slot emulator.",
      "context": "Fictional information kiosks receive small generated image blobs through a local update adapter. Simulate slots and boot outcomes in software; do not flash hardware or execute image contents.",
      "stack": [
        "TypeScript",
        "Slot emulator",
        "Filesystem adapter",
        "Vitest"
      ],
      "prerequisites": [
        "Generate inert byte images with manifests and development-only signing fixtures.",
        "Implement simulated boot success failure and power-cut points."
      ],
      "developerValue": "Practice update state machines and recoverable activation.",
      "companyValue": "Inspect whether an engineer can prevent partial rollout from stranding devices under declared conditions.",
      "delivery": "Use local emulator evidence only; signing fixtures never authorize production devices.",
      "phases": [
        {
          "id": "images",
          "title": "Validate update candidates",
          "goal": "Define version and image integrity."
        },
        {
          "id": "slots",
          "title": "Stage and activate",
          "goal": "Keep a recoverable known-good slot."
        },
        {
          "id": "fleet",
          "title": "Handle local rollout outcomes",
          "goal": "Bound retries and explain simulator status."
        }
      ],
      "tickets": [
        {
          "id": "359fe059-9a6c-465c-959e-f3708510044d",
          "key": "CUPDATE-101",
          "title": "Parse edge-update manifests with explicit supported versions",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 75,
          "phaseId": "images",
          "dependsOn": [],
          "scenario": "Unknown manifest fields are treated as executable update instructions. Replace loose parsing with a bounded schema.",
          "acceptanceCriteria": [
            "Known schema parses",
            "Unsupported version rejects",
            "Oversized fields reject before allocation"
          ],
          "implementationNotes": [
            "Manifests are data and never scripts."
          ],
          "verification": [
            "Parse valid inert image manifest",
            "Reject unsupported version"
          ],
          "deliverables": [
            "Manifest parser and cases"
          ],
          "rollout": "Reject new updates when schema identity is uncertain.",
          "skills": [
            "Validation",
            "Update systems"
          ],
          "fieldMix": [
            {
              "field": "Embedded and edge",
              "percentage": 60
            },
            {
              "field": "Security",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "66424d07-03b4-4a60-a91e-8f37959ecb60",
          "key": "CUPDATE-102",
          "title": "Verify edge-update image size and digest before staging",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 90,
          "phaseId": "images",
          "dependsOn": [
            "CUPDATE-101"
          ],
          "scenario": "A truncated synthetic image is marked downloaded. Gate staging on complete integrity verification.",
          "acceptanceCriteria": [
            "Size and digest both match",
            "Mismatch blocks staging",
            "Current active slot stays untouched"
          ],
          "implementationNotes": [
            "Stream verification under an explicit memory bound."
          ],
          "verification": [
            "Verify generated image",
            "Truncate or flip a byte"
          ],
          "deliverables": [
            "Image verifier and corruption cases"
          ],
          "rollout": "Keep failed images quarantined from slot activation.",
          "skills": [
            "Hashing",
            "Integrity"
          ],
          "fieldMix": [
            {
              "field": "Storage systems",
              "percentage": 50
            },
            {
              "field": "Embedded and edge",
              "percentage": 50
            }
          ],
          "patterns": []
        },
        {
          "id": "e5875246-81b1-4ab5-8797-fe8532060fda",
          "key": "CUPDATE-103",
          "title": "Validate edge-update manifests using local trust fixtures",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 150,
          "phaseId": "images",
          "dependsOn": [
            "CUPDATE-101",
            "CUPDATE-102"
          ],
          "scenario": "The simulator accepts any manifest signature. Add a trust adapter using ephemeral development keys.",
          "acceptanceCriteria": [
            "Trusted fixture signature passes",
            "Unknown signer fails",
            "Tampered manifest fails"
          ],
          "implementationNotes": [
            "No private keys enter source control or production configuration."
          ],
          "verification": [
            "Verify local signed fixture",
            "Change signed manifest field"
          ],
          "deliverables": [
            "Trust adapter and negative cases"
          ],
          "rollout": "Disable update acceptance if trusted verification is unavailable.",
          "skills": [
            "Cryptography",
            "Provider interfaces"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 70
            },
            {
              "field": "Embedded and edge",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "5a14f69e-5424-42e9-8366-c2295100fd31",
          "key": "CUPDATE-104",
          "title": "Write edge-update images only into the inactive simulated slot",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "slots",
          "dependsOn": [
            "CUPDATE-102",
            "CUPDATE-103"
          ],
          "scenario": "Update copying overwrites the currently selected image before validation finishes. Restrict staging to the inactive slot.",
          "acceptanceCriteria": [
            "Active slot remains byte-identical",
            "Inactive slot gets candidate bytes",
            "Failed write leaves active selection unchanged"
          ],
          "implementationNotes": [
            "Slot paths must stay inside the fixture root."
          ],
          "verification": [
            "Stage valid image",
            "Fail copy midway"
          ],
          "deliverables": [
            "Slot writer and isolation cases"
          ],
          "rollout": "Abandon inactive candidate and retain active slot.",
          "skills": [
            "Isolation",
            "Filesystem"
          ],
          "fieldMix": [
            {
              "field": "Embedded and edge",
              "percentage": 50
            },
            {
              "field": "Storage systems",
              "percentage": 50
            }
          ],
          "patterns": []
        },
        {
          "id": "b610907f-ad7e-41ea-abc1-7cd489aa6466",
          "key": "CUPDATE-105",
          "title": "Record edge-update activation intent before changing the boot selector",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 240,
          "phaseId": "slots",
          "dependsOn": [
            "CUPDATE-104"
          ],
          "scenario": "A power cut during selector change leaves no recoverable activation decision. Journal intent and candidate identity.",
          "acceptanceCriteria": [
            "Intent is durable before selector change",
            "Recovery identifies pending activation",
            "Repeated recovery is deterministic"
          ],
          "implementationNotes": [
            "Do not execute image bytes; use boot-result stubs."
          ],
          "verification": [
            "Cut before selector update",
            "Cut after selector update"
          ],
          "deliverables": [
            "Activation journal and cut-point matrix"
          ],
          "rollout": "Restore prior validated selector when activation state is ambiguous.",
          "skills": [
            "Crash consistency",
            "State machines"
          ],
          "fieldMix": [
            {
              "field": "Storage systems",
              "percentage": 50
            },
            {
              "field": "Embedded and edge",
              "percentage": 50
            }
          ],
          "patterns": []
        },
        {
          "id": "a5a8a264-c9bf-42ef-bc94-21876d1f90fc",
          "key": "CUPDATE-106",
          "title": "Mark an edge-update candidate healthy only after simulated boot confirmation",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 135,
          "phaseId": "slots",
          "dependsOn": [
            "CUPDATE-105"
          ],
          "scenario": "Merely selecting a slot labels the update successful. Require an explicit boot acknowledgement from the emulator.",
          "acceptanceCriteria": [
            "Selection yields pending health",
            "Confirmation marks success",
            "Missing confirmation reaches bounded failure state"
          ],
          "implementationNotes": [
            "Health means only the declared simulator check."
          ],
          "verification": [
            "Confirm successful boot",
            "Omit confirmation past deadline"
          ],
          "deliverables": [
            "Health transition and timer cases"
          ],
          "rollout": "Keep prior slot available until health acknowledgement commits.",
          "skills": [
            "State transitions",
            "Time"
          ],
          "fieldMix": [
            {
              "field": "Embedded and edge",
              "percentage": 70
            },
            {
              "field": "Site reliability",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "245c05eb-20e8-4eee-945c-bccdc1b7bbbd",
          "key": "CUPDATE-107",
          "title": "Roll back failed edge-update boots without retry loops",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "slots",
          "dependsOn": [
            "CUPDATE-105",
            "CUPDATE-106"
          ],
          "scenario": "A failing candidate is selected repeatedly on each restart. Persist failed-candidate disposition and restore the known-good slot.",
          "acceptanceCriteria": [
            "Failed candidate does not auto-reactivate",
            "Prior slot is selected",
            "No valid fallback produces explicit recovery-required state"
          ],
          "implementationNotes": [
            "Do not label fallback existence without validating its metadata."
          ],
          "verification": [
            "Fail candidate boot",
            "Invalidate both slot manifests"
          ],
          "deliverables": [
            "Rollback coordinator and failure cases"
          ],
          "rollout": "Stop automatic activation when no validated fallback exists.",
          "skills": [
            "Recovery",
            "Failure handling"
          ],
          "fieldMix": [
            {
              "field": "Embedded and edge",
              "percentage": 60
            },
            {
              "field": "Site reliability",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "a215a6f6-d181-4fda-83a5-e7b9ef984e5e",
          "key": "CUPDATE-108",
          "title": "Reject unintended edge-update downgrades under an explicit version policy",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 165,
          "phaseId": "fleet",
          "dependsOn": [
            "CUPDATE-103",
            "CUPDATE-107"
          ],
          "scenario": "Replaying an older signed image silently reverts a device. Add a declared minimum-version policy with a separate recovery mode.",
          "acceptanceCriteria": [
            "Normal mode rejects lower versions",
            "Equal-version replay is idempotent",
            "Recovery override is explicit and audited locally"
          ],
          "implementationNotes": [
            "Version order must be defined, not string-compared casually."
          ],
          "verification": [
            "Accept newer fixture",
            "Replay older signed fixture"
          ],
          "deliverables": [
            "Version policy and override cases"
          ],
          "rollout": "Disable updates if version comparison is ambiguous.",
          "skills": [
            "Versioning",
            "Security"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 60
            },
            {
              "field": "Embedded and edge",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "7fac0b9c-2b33-46fa-9919-fb58e6f101bd",
          "key": "CUPDATE-109",
          "title": "Limit concurrent downloads in the simulated kiosk update cohort",
          "type": "CHORE",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 120,
          "phaseId": "fleet",
          "dependsOn": [
            "CUPDATE-104",
            "CUPDATE-108"
          ],
          "scenario": "A local cohort starts every download at once and overwhelms the provider stub. Bound concurrency and retain per-device outcome.",
          "acceptanceCriteria": [
            "Active transfers stay within limit",
            "Failures release slots",
            "One device retry cannot starve all others"
          ],
          "implementationNotes": [
            "Cohort fixtures contain synthetic device IDs only."
          ],
          "verification": [
            "Update small cohort",
            "Fail one transfer repeatedly"
          ],
          "deliverables": [
            "Download scheduler and fairness cases"
          ],
          "rollout": "Reduce concurrency to one while queue behavior is repaired.",
          "skills": [
            "Scheduling",
            "Resource management"
          ],
          "fieldMix": [
            {
              "field": "Performance engineering",
              "percentage": 40
            },
            {
              "field": "Embedded and edge",
              "percentage": 40
            },
            {
              "field": "Networking",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "fbe52a33-002e-4e60-89eb-8fd0d29ffd45",
          "key": "CUPDATE-110",
          "title": "Report edge-update stages without overstating fleet success",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 120,
          "phaseId": "fleet",
          "dependsOn": [
            "CUPDATE-107",
            "CUPDATE-109"
          ],
          "scenario": "Dashboard counts downloaded images as updated kiosks. Project download, staged, boot-pending, healthy and rolled-back separately.",
          "acceptanceCriteria": [
            "Healthy requires committed boot confirmation",
            "Rollback remains visible",
            "Unknown outcomes are not counted successful"
          ],
          "implementationNotes": [
            "Reports describe simulator outcomes, not real-device certification."
          ],
          "verification": [
            "Complete one simulated update",
            "Interrupt another before boot confirmation"
          ],
          "deliverables": [
            "Update status report and consistency checks"
          ],
          "rollout": "Hide aggregate success if per-device authority is unresolved.",
          "skills": [
            "Reporting",
            "State projection"
          ],
          "fieldMix": [
            {
              "field": "Frontend",
              "percentage": 50
            },
            {
              "field": "Embedded and edge",
              "percentage": 30
            },
            {
              "field": "Site reliability",
              "percentage": 20
            }
          ],
          "patterns": []
        }
      ]
    }
  ]
}
