{
  "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": "ceb5bcc9-8949-4987-a0cb-1ceeca794793",
      "key": "AMERGE",
      "title": "Synchronize offline equipment inspections without silent overwrites",
      "field": "Distributed systems",
      "summary": "Merge local inspection changes with explicit conflicts, tombstones and attachment identity.",
      "context": "A fictional field team inspects equipment with intermittent connectivity. Two tablets can edit the same checklist and an old upload may restore a deleted finding.",
      "stack": [
        "TypeScript",
        "PostgreSQL",
        "HTTP"
      ],
      "prerequisites": [
        "Create two local client-state simulators and a synthetic inspection API.",
        "Use fabricated notes and local attachment bytes."
      ],
      "developerValue": "Practice offline synchronization, causal revisions and conflict resolution.",
      "companyValue": "Review whether field work survives disconnection without hiding conflicting observations.",
      "delivery": "Ten scoped tickets across three phases. Build a synthetic local service or select a ticket after recreating its prerequisites; estimates exclude setup.",
      "phases": [
        {
          "id": "changes",
          "title": "Define change identities",
          "goal": "Represent offline edits and authority boundaries."
        },
        {
          "id": "merge",
          "title": "Synchronize and resolve",
          "goal": "Handle duplicates, conflicts and deletion safely."
        },
        {
          "id": "recovery",
          "title": "Recover interrupted synchronization",
          "goal": "Reconcile attachments and explain remaining conflicts."
        }
      ],
      "tickets": [
        {
          "id": "00b9f2de-8655-4909-813d-3e20e4d273fb",
          "key": "AMERGE-101",
          "title": "Define offline change envelopes with stable client operation IDs",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 90,
          "phaseId": "changes",
          "dependsOn": [],
          "scenario": "A tablet retries saved edits with new request IDs, so the server creates duplicate inspection findings.",
          "acceptanceCriteria": [
            "Include operation ID, inspection ID, base revision and change type.",
            "Keep device display name separate from identity.",
            "Reject unknown envelope versions before mutation."
          ],
          "implementationNotes": [
            "Use generated disposable client identities."
          ],
          "verification": [
            "Replay the same synthetic change envelope twice.",
            "Change content under the same operation ID and return conflict."
          ],
          "deliverables": [
            "Offline operation contract"
          ],
          "rollout": "Publish the envelope before enabling sync retries; keep incompatible operations in local pending state.",
          "skills": [
            "Protocol design",
            "Idempotency"
          ],
          "fieldMix": [
            {
              "field": "Distributed systems",
              "percentage": 50
            },
            {
              "field": "API design",
              "percentage": 30
            },
            {
              "field": "Mobile",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "23929c4e-f871-4818-ae90-a87331742194",
          "key": "AMERGE-102",
          "title": "Require current inspection access before applying a queued offline change",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 150,
          "phaseId": "changes",
          "dependsOn": [
            "AMERGE-101"
          ],
          "scenario": "A contractor loses project access while offline, then reconnects with a batch of previously authorized edits.",
          "acceptanceCriteria": [
            "Reauthorize each target at synchronization time.",
            "Reject revoked or cross-organization changes without partial hidden writes.",
            "Return safe per-operation outcomes under the declared batch policy."
          ],
          "implementationNotes": [
            "Offline possession of data is not continuing write authority."
          ],
          "verification": [
            "Apply a queued edit for a still-authorized actor.",
            "Revoke access before reconnect and verify no inspection mutation."
          ],
          "deliverables": [
            "Sync authorization boundary"
          ],
          "rollout": "Enable scope checks before bulk sync; retain rejected local operations for user review.",
          "skills": [
            "Authorization",
            "Offline systems"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 50
            },
            {
              "field": "Distributed systems",
              "percentage": 30
            },
            {
              "field": "Mobile",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "1690b2fe-46a4-4981-9edb-d3c3ff64be86",
          "key": "AMERGE-103",
          "title": "Distinguish independent checklist edits from conflicting edits",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 120,
          "phaseId": "changes",
          "dependsOn": [
            "AMERGE-101",
            "AMERGE-102"
          ],
          "scenario": "The sync service treats every concurrent change as either a blanket overwrite or a blanket conflict.",
          "acceptanceCriteria": [
            "Define fields that can merge independently.",
            "Require explicit conflict when the same protected value diverges.",
            "Document attachment and deletion conflict rules separately."
          ],
          "implementationNotes": [
            "Use a small fixed checklist; avoid a general-purpose merge language."
          ],
          "verification": [
            "Merge edits to two independent checklist items.",
            "Edit the same item differently and preserve both proposed values as a conflict."
          ],
          "deliverables": [
            "Merge policy table and worked examples"
          ],
          "rollout": "Review the policy before automatic merging; keep unresolved fields on manual resolution.",
          "skills": [
            "Conflict modeling",
            "Data semantics"
          ],
          "fieldMix": [
            {
              "field": "Distributed systems",
              "percentage": 60
            },
            {
              "field": "System design",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "7acc7ed6-1787-43b0-b380-ae52c52780d9",
          "key": "AMERGE-104",
          "title": "Apply offline operations with a durable deduplication record",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "ADVANCED",
          "estimateMinutes": 210,
          "phaseId": "merge",
          "dependsOn": [
            "AMERGE-101",
            "AMERGE-102",
            "AMERGE-103"
          ],
          "scenario": "The server applies a change, loses the response, then reapplies it after the tablet reconnects.",
          "acceptanceCriteria": [
            "Commit operation identity and inspection mutation atomically.",
            "Return the original safe outcome for identical retries.",
            "Keep rejected authorization separate from accepted-operation history."
          ],
          "implementationNotes": [
            "Scope deduplication to the authorized client and operation identity."
          ],
          "verification": [
            "Drop the response after commit and retry to one revision.",
            "Force transaction rollback and verify the operation remains retryable without a partial edit."
          ],
          "deliverables": [
            "Idempotent sync transaction"
          ],
          "rollout": "Canary one synthetic client; pause replay when canonical operation identity is inconsistent.",
          "skills": [
            "Transactions",
            "Idempotency"
          ],
          "fieldMix": [
            {
              "field": "Distributed systems",
              "percentage": 50
            },
            {
              "field": "Database engineering",
              "percentage": 50
            }
          ],
          "patterns": []
        },
        {
          "id": "06d5245b-f9ce-48fb-a4a4-4151d20ec15a",
          "key": "AMERGE-105",
          "title": "Preserve concurrent inspection findings as explicit conflicts",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "ADVANCED",
          "estimateMinutes": 240,
          "phaseId": "merge",
          "dependsOn": [
            "AMERGE-103",
            "AMERGE-104"
          ],
          "scenario": "Two inspectors change a safety finding from different base revisions and last-write-wins hides one observation.",
          "acceptanceCriteria": [
            "Detect divergence from the declared base revision.",
            "Persist both proposals and their operation identities.",
            "Block authoritative resolution until a permitted resolution command chooses or combines them."
          ],
          "implementationNotes": [
            "Do not infer which observer is correct from arrival time."
          ],
          "verification": [
            "Submit conflicting changes in both arrival orders and retain equivalent conflict facts.",
            "Attempt ordinary edit completion over an unresolved conflict and reject it."
          ],
          "deliverables": [
            "Conflict record model and order-invariance tests"
          ],
          "rollout": "Enable conflict capture before automatic reconciliation; leave existing ambiguous cases unresolved.",
          "skills": [
            "Conflict detection",
            "Causal revisions"
          ],
          "fieldMix": [
            {
              "field": "Distributed systems",
              "percentage": 70
            },
            {
              "field": "Backend",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "46f017a0-c3cc-4216-aa44-ec970be6a010",
          "key": "AMERGE-106",
          "title": "Resolve an inspection conflict against its current proposal set",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 180,
          "phaseId": "merge",
          "dependsOn": [
            "AMERGE-105"
          ],
          "scenario": "A reviewer resolves a conflict while a third offline proposal arrives, silently discarding the new observation.",
          "acceptanceCriteria": [
            "Bind resolution to the expected conflict revision and proposal identities.",
            "Record resolution as an append-only fact.",
            "Reject stale resolution without deleting proposals."
          ],
          "implementationNotes": [
            "Require the reviewer's current inspection permission."
          ],
          "verification": [
            "Resolve an unchanged two-proposal conflict.",
            "Add a third proposal before commit and verify stale resolution conflicts."
          ],
          "deliverables": [
            "Guarded conflict resolution command"
          ],
          "rollout": "Canary synthetic review; reopen by appending a new conflict fact rather than editing history.",
          "skills": [
            "Optimistic concurrency",
            "Auditability"
          ],
          "fieldMix": [
            {
              "field": "Distributed systems",
              "percentage": 50
            },
            {
              "field": "Database engineering",
              "percentage": 30
            },
            {
              "field": "Backend",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "21a45a88-e345-4d3d-b42f-67de25131602",
          "key": "AMERGE-107",
          "title": "Keep deleted findings deleted when an old tablet reconnects",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 300,
          "phaseId": "merge",
          "dependsOn": [
            "AMERGE-103",
            "AMERGE-104",
            "AMERGE-105"
          ],
          "scenario": "A tablet that missed a deletion resubmits its old finding and recreates content the team intentionally removed.",
          "acceptanceCriteria": [
            "Represent deletion with an ordered tombstone.",
            "Reject stale recreation under the declared merge policy.",
            "Define tombstone retention and resnapshot requirements."
          ],
          "implementationNotes": [
            "Avoid using wall-clock time alone to order deletion and recreation."
          ],
          "verification": [
            "Delete a finding and replay an older update.",
            "Expire supported replay history in the simulator and require resnapshot rather than guessing."
          ],
          "deliverables": [
            "Tombstone protocol and stale-client cases"
          ],
          "rollout": "Deploy tombstones before cleanup; halt tombstone removal until the resnapshot contract is available.",
          "skills": [
            "Deletion semantics",
            "Synchronization"
          ],
          "fieldMix": [
            {
              "field": "Distributed systems",
              "percentage": 60
            },
            {
              "field": "Data engineering",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "a336a380-c9ae-46ac-9a58-41afc858ed19",
          "key": "AMERGE-108",
          "title": "Finalize offline attachments by verified content identity",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "ADVANCED",
          "estimateMinutes": 210,
          "phaseId": "recovery",
          "dependsOn": [
            "AMERGE-104",
            "AMERGE-107"
          ],
          "scenario": "An inspection references a photo before its interrupted upload completes, producing broken evidence links in the field report.",
          "acceptanceCriteria": [
            "Stage attachment uploads separately from finding references.",
            "Finalize only exact verified object generation and content hash.",
            "Keep incomplete attachments visible as pending without public links."
          ],
          "implementationNotes": [
            "Use synthetic images or byte fixtures; no personal photographs are needed."
          ],
          "verification": [
            "Complete a valid synthetic attachment and resolve its stable identity.",
            "Interrupt upload or alter bytes and verify the finding cannot publish an invalid link."
          ],
          "deliverables": [
            "Attachment finalization contract"
          ],
          "rollout": "Canary local attachments; keep staged objects private and resume or discard only exact generations.",
          "skills": [
            "Storage integrity",
            "Offline workflows"
          ],
          "fieldMix": [
            {
              "field": "Storage systems",
              "percentage": 50
            },
            {
              "field": "Distributed systems",
              "percentage": 30
            },
            {
              "field": "Mobile",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "691ce9a1-3402-42a7-8594-82ca7b16de53",
          "key": "AMERGE-109",
          "title": "Resume inspection synchronization from a server-confirmed cursor",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "EXPERT",
          "estimateMinutes": 300,
          "phaseId": "recovery",
          "dependsOn": [
            "AMERGE-104",
            "AMERGE-106",
            "AMERGE-107",
            "AMERGE-108"
          ],
          "scenario": "The tablet stores a local cursor before receiving server confirmation and skips updates after a crash.",
          "acceptanceCriteria": [
            "Advance the local acknowledged cursor only after durable server outcome.",
            "Bind cursor to inspection scope and sync generation.",
            "Require resnapshot when the server cannot honor the retained history window."
          ],
          "implementationNotes": [
            "Use two client simulators with controlled interruption points."
          ],
          "verification": [
            "Crash during a sync page and resume without missing confirmed operations.",
            "Use an expired or cross-scope cursor and reject incremental sync safely."
          ],
          "deliverables": [
            "Cursor recovery protocol and crash harness"
          ],
          "rollout": "Enable incremental sync after the resnapshot path passes; retain local pending operations until acknowledged.",
          "skills": [
            "Checkpointing",
            "Recovery"
          ],
          "fieldMix": [
            {
              "field": "Distributed systems",
              "percentage": 60
            },
            {
              "field": "Mobile",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "aadba700-8c89-4e22-997d-d1a62e845b3d",
          "key": "AMERGE-110",
          "title": "Show sync completion separately from resolved inspection conflicts",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 90,
          "phaseId": "recovery",
          "dependsOn": [
            "AMERGE-106",
            "AMERGE-108",
            "AMERGE-109"
          ],
          "scenario": "A tablet says all synced even though uploaded changes contain unresolved conflicts and a pending attachment.",
          "acceptanceCriteria": [
            "Report transport acknowledgement, conflict state and attachment state separately.",
            "Keep rejected operations visible with safe reasons.",
            "Never equate uploaded data with an approved inspection."
          ],
          "implementationNotes": [
            "Use a local status projection with accessible plain-language labels."
          ],
          "verification": [
            "Display a fully acknowledged conflict-free synthetic inspection.",
            "Acknowledge a conflicting batch and retain unresolved status."
          ],
          "deliverables": [
            "Sync status contract and state examples"
          ],
          "rollout": "Publish precise status labels; restore prior layout without collapsing distinct states.",
          "skills": [
            "Distributed UX",
            "State semantics"
          ],
          "fieldMix": [
            {
              "field": "Mobile",
              "percentage": 50
            },
            {
              "field": "Distributed systems",
              "percentage": 50
            }
          ],
          "patterns": []
        }
      ]
    }
  ]
}
