{
  "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": "992e2b16-9300-45f2-bc00-b0b78f58aaa9",
      "key": "CJOUR",
      "title": "A power-loss-tolerant edge event journal",
      "field": "Embedded and edge",
      "summary": "Persist synthetic gateway events in a bounded software flash emulator.",
      "context": "Fictional edge display gateway stores noncritical synthetic readings while disconnected. Implement a byte-array flash emulator with explicit erase/write behavior and injected power cuts; no physical storage device is required.",
      "stack": [
        "TypeScript",
        "Flash-storage emulator",
        "Vitest"
      ],
      "prerequisites": [
        "Specify emulator page size write rules and erase behavior.",
        "Generate synthetic records and deterministic power-cut schedules."
      ],
      "developerValue": "Practice torn writes, wear-aware batching and acknowledged durability.",
      "companyValue": "Inspect whether offline device records remain recoverable within stated constraints.",
      "delivery": "Emulator guarantees are explicit; real flash endurance and device qualification remain separate.",
      "phases": [
        {
          "id": "records",
          "title": "Define durable records",
          "goal": "Encode and validate journal entries."
        },
        {
          "id": "power",
          "title": "Recover interrupted writes",
          "goal": "Handle commits and page boundaries."
        },
        {
          "id": "capacity",
          "title": "Manage finite storage",
          "goal": "Reclaim acknowledged records safely."
        }
      ],
      "tickets": [
        {
          "id": "62abe268-a5d9-4eec-a600-cfe72915d90e",
          "key": "CJOUR-101",
          "title": "Model edge-journal flash writes with explicit emulator constraints",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 90,
          "phaseId": "records",
          "dependsOn": [],
          "scenario": "The byte-array stub permits writes that real flash-like storage would reject. Declare and enforce the chosen emulator model.",
          "acceptanceCriteria": [
            "Page boundaries are explicit",
            "Forbidden bit transitions fail",
            "Erase resets one selected page"
          ],
          "implementationNotes": [
            "This models selected behavior and does not certify real hardware."
          ],
          "verification": [
            "Write allowed transition",
            "Attempt forbidden transition without erase"
          ],
          "deliverables": [
            "Flash emulator contract and cases"
          ],
          "rollout": "Stop journal writes when adapter behavior violates the declared model.",
          "skills": [
            "Emulation",
            "Storage"
          ],
          "fieldMix": [
            {
              "field": "Embedded and edge",
              "percentage": 60
            },
            {
              "field": "Storage systems",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "2c45d8f3-059d-459f-b5f5-a8ece8f02786",
          "key": "CJOUR-102",
          "title": "Encode edge-journal records with bounded length and checksum",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 90,
          "phaseId": "records",
          "dependsOn": [
            "CJOUR-101"
          ],
          "scenario": "Truncated synthetic records are indistinguishable from valid short payloads. Add explicit length and integrity fields.",
          "acceptanceCriteria": [
            "Payload bytes round-trip",
            "Length is bounded",
            "Checksum mismatch rejects record"
          ],
          "implementationNotes": [
            "Checksum is corruption detection, not authentication."
          ],
          "verification": [
            "Encode valid record",
            "Flip one stored byte"
          ],
          "deliverables": [
            "Record codec and corruption cases"
          ],
          "rollout": "Keep affected pages read-only for inspection.",
          "skills": [
            "Binary formats",
            "Integrity"
          ],
          "fieldMix": [
            {
              "field": "Embedded and edge",
              "percentage": 50
            },
            {
              "field": "Storage systems",
              "percentage": 50
            }
          ],
          "patterns": []
        },
        {
          "id": "4f788f4f-fe84-4a29-a5b9-04cd9f8a072f",
          "key": "CJOUR-103",
          "title": "Assign edge-journal event identities independently from delivery attempts",
          "type": "BUG",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 105,
          "phaseId": "records",
          "dependsOn": [
            "CJOUR-102"
          ],
          "scenario": "Retried uploads mint new event IDs and duplicate accepted readings. Persist identity with the original record.",
          "acceptanceCriteria": [
            "Retry preserves identity",
            "New records get distinct identity",
            "Restart retains stored identity"
          ],
          "implementationNotes": [
            "IDs must not encode raw reading values."
          ],
          "verification": [
            "Retry same record",
            "Restart and compare identities"
          ],
          "deliverables": [
            "Event identity contract and cases"
          ],
          "rollout": "Pause replay if stored identity cannot be recovered.",
          "skills": [
            "Idempotency",
            "Identity"
          ],
          "fieldMix": [
            {
              "field": "Embedded and edge",
              "percentage": 50
            },
            {
              "field": "Distributed systems",
              "percentage": 30
            },
            {
              "field": "Storage systems",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "30ca4175-6d9e-4ee7-8231-756f56fcff5b",
          "key": "CJOUR-104",
          "title": "Commit edge-journal records only after their marker is durable",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "power",
          "dependsOn": [
            "CJOUR-102",
            "CJOUR-103"
          ],
          "scenario": "A record appears readable before its body finishes writing. Introduce a commit-marker protocol compatible with the emulator.",
          "acceptanceCriteria": [
            "Uncommitted bodies stay invisible",
            "Acknowledgement follows durable marker",
            "Invalid marker cannot authorize partial body"
          ],
          "implementationNotes": [
            "Specify write and flush ordering explicitly."
          ],
          "verification": [
            "Write committed fixture",
            "Cut power before marker"
          ],
          "deliverables": [
            "Commit protocol and cut-point tests"
          ],
          "rollout": "Disable acknowledgement if the durability barrier fails.",
          "skills": [
            "Durability",
            "Atomicity"
          ],
          "fieldMix": [
            {
              "field": "Storage systems",
              "percentage": 60
            },
            {
              "field": "Embedded and edge",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "6d2fd934-9c5a-4143-ae27-d07ab71d41bc",
          "key": "CJOUR-105",
          "title": "Recover edge-journal scanning after a torn final record",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "power",
          "dependsOn": [
            "CJOUR-104"
          ],
          "scenario": "Startup stops at partial data and loses earlier committed events. Scan the valid committed prefix conservatively.",
          "acceptanceCriteria": [
            "Earlier committed records survive",
            "Incomplete tail is ignored with reason",
            "Middle corruption is not silently skipped"
          ],
          "implementationNotes": [
            "Preserve damaged bytes for explicit local diagnosis."
          ],
          "verification": [
            "Cut final body write",
            "Corrupt an earlier committed record"
          ],
          "deliverables": [
            "Recovery scanner and fault cases"
          ],
          "rollout": "Open journal read-only when corruption is not a tail interruption.",
          "skills": [
            "Recovery",
            "Integrity"
          ],
          "fieldMix": [
            {
              "field": "Storage systems",
              "percentage": 60
            },
            {
              "field": "Embedded and edge",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "12d922db-8d6c-46fc-977f-f6f300f4ec4f",
          "key": "CJOUR-106",
          "title": "Roll edge-journal writes onto a new page without overwriting unread events",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 135,
          "phaseId": "power",
          "dependsOn": [
            "CJOUR-101",
            "CJOUR-104",
            "CJOUR-105"
          ],
          "scenario": "Page wrap overwrites unacknowledged events. Separate writable capacity from reclaimable pages.",
          "acceptanceCriteria": [
            "Active unread pages remain protected",
            "Full journal returns explicit capacity result",
            "New page starts with validated header"
          ],
          "implementationNotes": [
            "Do not silently discard oldest readings."
          ],
          "verification": [
            "Fill to page boundary",
            "Fill entire journal without acknowledgements"
          ],
          "deliverables": [
            "Page allocator and full-capacity cases"
          ],
          "rollout": "Stop admission when no safe writable page exists.",
          "skills": [
            "Ring buffers",
            "Resource limits"
          ],
          "fieldMix": [
            {
              "field": "Embedded and edge",
              "percentage": 50
            },
            {
              "field": "Storage systems",
              "percentage": 50
            }
          ],
          "patterns": []
        },
        {
          "id": "db01f212-a266-4994-9d1a-e0796993da8e",
          "key": "CJOUR-107",
          "title": "Recover edge-journal page generation selection after power loss",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 240,
          "phaseId": "power",
          "dependsOn": [
            "CJOUR-105",
            "CJOUR-106"
          ],
          "scenario": "A cut during page-header activation leaves two pages claiming to be newest. Resolve generations through a declared ordering rule.",
          "acceptanceCriteria": [
            "Recovery chooses valid committed generation",
            "Incomplete header cannot supersede valid page",
            "Ambiguous generations fail visibly"
          ],
          "implementationNotes": [
            "Include wrap behavior in generation comparison."
          ],
          "verification": [
            "Cut header activation",
            "Exercise generation wrap fixture"
          ],
          "deliverables": [
            "Generation selection and boundary tests"
          ],
          "rollout": "Preserve both pages and stop writes on unresolved ambiguity.",
          "skills": [
            "Crash consistency",
            "Sequence arithmetic"
          ],
          "fieldMix": [
            {
              "field": "Storage systems",
              "percentage": 60
            },
            {
              "field": "Embedded and edge",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "e1024784-a659-4fc1-9426-f4426b8a7e8f",
          "key": "CJOUR-108",
          "title": "Reclaim edge-journal pages only after durable delivery acknowledgements",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "capacity",
          "dependsOn": [
            "CJOUR-103",
            "CJOUR-107"
          ],
          "scenario": "The gateway erases a page after sending bytes, before the receiver acknowledges them. Gate reclamation on durable acknowledgements.",
          "acceptanceCriteria": [
            "Sent-only records remain protected",
            "Acknowledged complete page may erase",
            "Crash before acknowledgement persistence keeps page"
          ],
          "implementationNotes": [
            "Receiver stub must support replay by stable event identity."
          ],
          "verification": [
            "Acknowledge all page records",
            "Timeout after receiver acceptance"
          ],
          "deliverables": [
            "Ack ledger and reclamation cases"
          ],
          "rollout": "Pause erasure if acknowledgement state is uncertain.",
          "skills": [
            "Delivery semantics",
            "Storage"
          ],
          "fieldMix": [
            {
              "field": "Storage systems",
              "percentage": 40
            },
            {
              "field": "Embedded and edge",
              "percentage": 30
            },
            {
              "field": "Distributed systems",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "7710346a-76da-4620-98bc-ec0ad87291d2",
          "key": "CJOUR-109",
          "title": "Batch edge-journal metadata updates within a declared loss window",
          "type": "CHORE",
          "priority": "MEDIUM",
          "difficulty": "ADVANCED",
          "estimateMinutes": 165,
          "phaseId": "capacity",
          "dependsOn": [
            "CJOUR-108"
          ],
          "scenario": "A metadata write for every status poll causes unnecessary emulated erase work. Batch only nonauthoritative counters.",
          "acceptanceCriteria": [
            "Event commits remain durable",
            "Batching does not weaken acknowledgement protection",
            "Counter loss window is documented"
          ],
          "implementationNotes": [
            "Do not batch safety-critical authority or claim real endurance improvement."
          ],
          "verification": [
            "Compare emulator operation counts",
            "Cut power before counter flush"
          ],
          "deliverables": [
            "Counter batching and measured local trace"
          ],
          "rollout": "Disable batching if authority depends on buffered counters.",
          "skills": [
            "Performance",
            "Durability"
          ],
          "fieldMix": [
            {
              "field": "Performance engineering",
              "percentage": 40
            },
            {
              "field": "Storage systems",
              "percentage": 30
            },
            {
              "field": "Embedded and edge",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "4d5d951a-fa4c-4fb3-a5d1-8d53858ad443",
          "key": "CJOUR-110",
          "title": "Inspect edge-journal pages without modifying recovery state",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 120,
          "phaseId": "capacity",
          "dependsOn": [
            "CJOUR-107",
            "CJOUR-109"
          ],
          "scenario": "Debugging currently boots the journal and may erase pages. Add a read-only page inspector.",
          "acceptanceCriteria": [
            "Reports generation and commit validity",
            "Does not erase or rewrite",
            "Payload display is opt-in"
          ],
          "implementationNotes": [
            "Restrict input to explicit synthetic image files."
          ],
          "verification": [
            "Inspect valid image",
            "Inspect torn and corrupt images"
          ],
          "deliverables": [
            "Inspector and no-write assertions"
          ],
          "rollout": "Keep diagnostic mode read-only if recovery suggestions are uncertain.",
          "skills": [
            "Diagnostics",
            "Emulation"
          ],
          "fieldMix": [
            {
              "field": "Developer tooling",
              "percentage": 40
            },
            {
              "field": "Embedded and edge",
              "percentage": 30
            },
            {
              "field": "Storage systems",
              "percentage": 30
            }
          ],
          "patterns": []
        }
      ]
    }
  ]
}
