{
  "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": "fe12ff15-5218-4692-b487-7326309121cc",
      "key": "BCRM",
      "title": "CRM contact synchronization repair",
      "field": "Integrations",
      "summary": "Keep customer records consistent across a local application and a simulated CRM.",
      "context": "A fictional account team sees overwritten edits, duplicate contacts, and stale opt-out preferences after synchronization retries.",
      "stack": [
        "TypeScript",
        "PostgreSQL",
        "HTTP"
      ],
      "prerequisites": [
        "Create a local CRM double and synthetic contact records for two organizations; no real personal data or CRM credentials."
      ],
      "developerValue": "Practice sync cursors, conflict policies, privacy boundaries, and replay.",
      "companyValue": "Provide predictable customer-data synchronization with inspectable conflicts.",
      "delivery": "Deliver a local bidirectional adapter and reconciliation report.",
      "phases": [
        {
          "id": "map",
          "title": "Map authority",
          "goal": "Define identities and field ownership."
        },
        {
          "id": "sync",
          "title": "Synchronize changes",
          "goal": "Handle pagination, retries, conflicts, and deletion."
        },
        {
          "id": "operate",
          "title": "Operate safely",
          "goal": "Reconcile drift and recover interrupted imports."
        }
      ],
      "tickets": [
        {
          "id": "2df0ac0d-8624-4029-8200-a133636749c0",
          "key": "BCRM-101",
          "title": "Define contact field ownership between the app and CRM",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 60,
          "phaseId": "map",
          "dependsOn": [],
          "scenario": "Both systems overwrite account names and communication preferences.",
          "acceptanceCriteria": [
            "Assign an authority rule per synchronized field.",
            "Separate display fields from consent fields.",
            "Define unresolved conflicts explicitly."
          ],
          "implementationNotes": [
            "Never infer marketing consent from unrelated activity."
          ],
          "verification": [
            "Resolve an app-owned field change.",
            "Keep conflicting consent records unresolved."
          ],
          "deliverables": [
            "Field ownership matrix."
          ],
          "rollout": "Review the matrix before enabling writes.",
          "skills": [
            "Data ownership"
          ],
          "fieldMix": [
            {
              "field": "Integrations",
              "percentage": 50
            },
            {
              "field": "System design",
              "percentage": 30
            },
            {
              "field": "Privacy engineering",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "30d0d38d-4f5d-4ca2-96ff-ceaf0c7ecb98",
          "key": "BCRM-102",
          "title": "Separate external contact identity from email addresses",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 120,
          "phaseId": "map",
          "dependsOn": [
            "BCRM-101"
          ],
          "scenario": "An email change creates a second contact instead of updating the original.",
          "acceptanceCriteria": [
            "Use provider and organization-scoped external identities.",
            "Allow email changes without identity replacement.",
            "Detect conflicting identity mappings."
          ],
          "implementationNotes": [
            "Email is mutable data, not a stable key."
          ],
          "verification": [
            "Update an existing contact's email.",
            "Reject an external identity mapped across organizations."
          ],
          "deliverables": [
            "Identity mapping model."
          ],
          "rollout": "Backfill synthetic mappings before synchronization.",
          "skills": [
            "Identity modeling"
          ],
          "fieldMix": [
            {
              "field": "Integrations",
              "percentage": 60
            },
            {
              "field": "Database engineering",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "ef10713b-2428-4a43-b570-128fa7c0a900",
          "key": "BCRM-103",
          "title": "Checkpoint CRM pagination only after local batch commit",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "sync",
          "dependsOn": [
            "BCRM-102"
          ],
          "scenario": "The cursor advances even when a page fails to persist.",
          "acceptanceCriteria": [
            "Commit page changes and cursor together.",
            "Resume from the last committed cursor.",
            "Bound page size and total import work."
          ],
          "implementationNotes": [
            "Do not use timestamps alone as a pagination tie-breaker."
          ],
          "verification": [
            "Interrupt after a committed page and resume.",
            "Fail persistence and verify the cursor remains unchanged."
          ],
          "deliverables": [
            "Transactional page importer."
          ],
          "rollout": "Start with small batches; retain checkpoints during recovery.",
          "skills": [
            "Transactions",
            "Pagination"
          ],
          "fieldMix": [
            {
              "field": "Data engineering",
              "percentage": 50
            },
            {
              "field": "Database engineering",
              "percentage": 30
            },
            {
              "field": "Integrations",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "bf12e9ad-3239-4f74-b3c9-754703db9a52",
          "key": "BCRM-104",
          "title": "Apply contact updates with explicit conflict detection",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 210,
          "phaseId": "sync",
          "dependsOn": [
            "BCRM-101",
            "BCRM-103"
          ],
          "scenario": "A delayed CRM event overwrites a newer local edit.",
          "acceptanceCriteria": [
            "Compare the declared version or revision.",
            "Apply field ownership rules on conflicts.",
            "Preserve unresolved values and provenance."
          ],
          "implementationNotes": [
            "Do not use arrival time as proof of freshness."
          ],
          "verification": [
            "Merge independent field edits.",
            "Detect conflicting edits to the same owned field."
          ],
          "deliverables": [
            "Conflict-aware update handler."
          ],
          "rollout": "Enable writes only after the conflict report is reviewable.",
          "skills": [
            "Concurrency",
            "Data synchronization"
          ],
          "fieldMix": [
            {
              "field": "Distributed systems",
              "percentage": 40
            },
            {
              "field": "Integrations",
              "percentage": 40
            },
            {
              "field": "Database engineering",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "537a0fc4-8f29-43b6-9ad5-d6d9adf98bd3",
          "key": "BCRM-105",
          "title": "Propagate communication opt-outs ahead of ordinary profile updates",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "sync",
          "dependsOn": [
            "BCRM-104"
          ],
          "scenario": "An opt-out remains queued behind thousands of cosmetic profile changes.",
          "acceptanceCriteria": [
            "Prioritize restrictive preference updates.",
            "Prevent older permissive values from restoring permission.",
            "Record propagation state without exposing contact details in logs."
          ],
          "implementationNotes": [
            "Use synthetic preferences; no messages are sent."
          ],
          "verification": [
            "Propagate a new opt-out.",
            "Replay an older opt-in and preserve the restrictive state."
          ],
          "deliverables": [
            "Preference propagation checks."
          ],
          "rollout": "Pause outbound communication integration when preference state is uncertain.",
          "skills": [
            "Privacy engineering",
            "Event ordering"
          ],
          "fieldMix": [
            {
              "field": "Privacy engineering",
              "percentage": 50
            },
            {
              "field": "Integrations",
              "percentage": 30
            },
            {
              "field": "Distributed systems",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "b893312e-905c-4229-88c2-b56bbc475dd7",
          "key": "BCRM-106",
          "title": "Handle provider rate limits without skipping contacts",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 150,
          "phaseId": "sync",
          "dependsOn": [
            "BCRM-103"
          ],
          "scenario": "The importer treats a rate-limited page as empty and advances.",
          "acceptanceCriteria": [
            "Respect bounded retry delays.",
            "Keep the current cursor until a successful page.",
            "Distinguish terminal authentication failure from throttling."
          ],
          "implementationNotes": [
            "Use a mock clock and fixed retry ceiling."
          ],
          "verification": [
            "Recover from one rate-limited response.",
            "Exhaust retries without advancing the cursor."
          ],
          "deliverables": [
            "Rate-limit handling."
          ],
          "rollout": "Pause the organization sync after exhaustion; resume from its saved cursor.",
          "skills": [
            "Retries",
            "HTTP"
          ],
          "fieldMix": [
            {
              "field": "Integrations",
              "percentage": 60
            },
            {
              "field": "Site reliability",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "fac441b1-6085-4319-b69b-2f8c19ed1439",
          "key": "BCRM-107",
          "title": "Represent deleted CRM records with tombstone semantics",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "sync",
          "dependsOn": [
            "BCRM-104",
            "BCRM-105"
          ],
          "scenario": "A deleted record reappears when an old update is replayed.",
          "acceptanceCriteria": [
            "Retain deletion identity and source revision.",
            "Prevent older updates from resurrecting the record.",
            "Apply the documented retention rule to local fields."
          ],
          "implementationNotes": [
            "Deletion policy must distinguish identity metadata from contact contents."
          ],
          "verification": [
            "Apply a deletion then replay an older update.",
            "Verify an authorized new identity follows an explicit recreation path."
          ],
          "deliverables": [
            "Deletion and replay rules."
          ],
          "rollout": "Introduce tombstones before importing deletion events.",
          "skills": [
            "Data lifecycle",
            "Idempotency"
          ],
          "fieldMix": [
            {
              "field": "Data engineering",
              "percentage": 40
            },
            {
              "field": "Integrations",
              "percentage": 30
            },
            {
              "field": "Privacy engineering",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "3759404a-694e-4e94-8e2d-04d6e296fc5e",
          "key": "BCRM-108",
          "title": "Reconcile contact drift using bounded hashes and counts",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 150,
          "phaseId": "operate",
          "dependsOn": [
            "BCRM-106",
            "BCRM-107"
          ],
          "scenario": "Support needs to find mismatches without exporting every contact's personal data.",
          "acceptanceCriteria": [
            "Compare scoped canonical synchronized-field digests.",
            "Report missing and changed identities separately.",
            "Limit detailed inspection to authorized records."
          ],
          "implementationNotes": [
            "Do not publish raw contact values in aggregate reports."
          ],
          "verification": [
            "Identify one missing and one changed contact.",
            "Deny reconciliation across organization boundaries."
          ],
          "deliverables": [
            "Drift report."
          ],
          "rollout": "Run read-only reconciliation before repair.",
          "skills": [
            "Reconciliation",
            "Privacy"
          ],
          "fieldMix": [
            {
              "field": "Integrations",
              "percentage": 50
            },
            {
              "field": "Privacy engineering",
              "percentage": 50
            }
          ],
          "patterns": []
        },
        {
          "id": "e5af60b7-68bf-42f1-ad86-aa92debe1c13",
          "key": "BCRM-109",
          "title": "Plan a full CRM resynchronization without erasing local edits",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 300,
          "phaseId": "operate",
          "dependsOn": [
            "BCRM-104",
            "BCRM-108"
          ],
          "scenario": "A corrupted cursor requires a new import while staff continue editing customer records.",
          "acceptanceCriteria": [
            "Freeze an import boundary and preserve concurrent local revisions.",
            "Compare merge strategies and conflict workload.",
            "Rehearse resumption and cancellation without bulk replacement."
          ],
          "implementationNotes": [
            "Keep the exercise bounded to the synthetic dataset."
          ],
          "verification": [
            "Resume an interrupted full import.",
            "Edit a contact mid-import and verify conflict preservation."
          ],
          "deliverables": [
            "Resynchronization decision record."
          ],
          "rollout": "Run read-only comparison first; apply reviewed differences in bounded batches.",
          "skills": [
            "Migration design",
            "Consistency"
          ],
          "fieldMix": [
            {
              "field": "System design",
              "percentage": 40
            },
            {
              "field": "Integrations",
              "percentage": 40
            },
            {
              "field": "Distributed systems",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "2853cc6a-076a-4900-a651-e6056a1e445c",
          "key": "BCRM-110",
          "title": "Create a sync support view with safe failure categories",
          "type": "STORY",
          "priority": "LOW",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 90,
          "phaseId": "operate",
          "dependsOn": [
            "BCRM-109"
          ],
          "scenario": "Support sees only 'sync failed' and repeatedly restarts imports.",
          "acceptanceCriteria": [
            "Show last committed cursor age and operation status.",
            "Distinguish throttling, authorization, conflict, and malformed data.",
            "Provide a scoped resume action using existing identity."
          ],
          "implementationNotes": [
            "Exclude tokens and contact contents from status output."
          ],
          "verification": [
            "Display a successful completed import.",
            "Show authorization failure without retrying indefinitely."
          ],
          "deliverables": [
            "Support status projection."
          ],
          "rollout": "Expose read-only status first; keep repairs separately authorized.",
          "skills": [
            "Operational UX"
          ],
          "fieldMix": [
            {
              "field": "Frontend",
              "percentage": 40
            },
            {
              "field": "Integrations",
              "percentage": 40
            },
            {
              "field": "Site reliability",
              "percentage": 20
            }
          ],
          "patterns": []
        }
      ]
    }
  ]
}
