{
  "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": "292bf637-b8f9-4ad3-adb8-dd5b496cbd03",
      "key": "FIELD",
      "title": "An offline workday for field technicians",
      "field": "Mobile",
      "summary": "Keep assigned maintenance work usable without reception and reconcile changes safely when connectivity returns.",
      "context": "The fictional Vale facilities team services equipment in basements with poor reception. Technicians receive assigned work orders, record checks, and attach synthetic equipment photos. The practice app uses an on-device database and a stub sync service; background location tracking is excluded.",
      "stack": [
        "React Native",
        "TypeScript",
        "SQLite",
        "Jest",
        "Android emulator"
      ],
      "prerequisites": [
        "Synthetic work orders and a revisioned sync contract",
        "An emulator with controllable connectivity and app lifecycle"
      ],
      "developerValue": "Practice durable local state, mobile lifecycle recovery, and conflict resolution in realistic offline workflows.",
      "companyValue": "Review whether an engineer can protect field work through crashes, interrupted uploads, and reassignment.",
      "delivery": "Deliver selected tickets against synthetic work orders. Full project phases are optional and do not require a live dispatch service.",
      "phases": [
        {
          "id": "local",
          "title": "Start the offline day",
          "goal": "Make downloaded work clear and durable."
        },
        {
          "id": "capture",
          "title": "Record the visit",
          "goal": "Capture work and attachments through interruptions."
        },
        {
          "id": "sync",
          "title": "Reconnect safely",
          "goal": "Resolve retries, reassignment, and conflicting edits."
        },
        {
          "id": "operations",
          "title": "Support the rollout",
          "goal": "Protect devices and give support safe diagnostics."
        }
      ],
      "tickets": [
        {
          "id": "93cd97b9-6099-42a7-828b-07b0c4013aae",
          "key": "FIELD-101",
          "title": "Tell technicians which work orders are available offline",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 75,
          "phaseId": "local",
          "dependsOn": [],
          "scenario": "The assignment list looks ready in the depot, but opening a work order downstairs produces an endless spinner. Distinguish listed work from fully downloaded details.",
          "acceptanceCriteria": [
            "Each order states whether required details are cached, downloading, or unavailable offline.",
            "Opening an uncached order offline shows a recoverable explanation.",
            "The app shows the last successful download time without presenting cached data as current."
          ],
          "implementationNotes": [
            "Use a connectivity adapter for fixtures; an online signal does not guarantee the API is reachable."
          ],
          "verification": [
            "Download an order, disable connectivity, and open its cached details.",
            "Open a listed but uncached order offline and simulate a reachable network with a failed API; neither path spins indefinitely."
          ],
          "deliverables": [
            "Offline-availability presentation and connectivity fixture cases"
          ],
          "rollout": "Pilot with a small depot dataset; retain read-only cached access if download status regresses.",
          "skills": [
            "Offline UX",
            "Mobile state",
            "Error handling"
          ],
          "fieldMix": [
            {
              "field": "Mobile",
              "percentage": 100
            }
          ],
          "patterns": []
        },
        {
          "id": "1120c719-5295-4a9c-accf-1100e20fc2dc",
          "key": "FIELD-102",
          "title": "Commit a completed checklist item before showing it saved",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 120,
          "phaseId": "local",
          "dependsOn": [],
          "scenario": "A technician checks Replace intake filter and force-closes the app. On reopening, the check is gone even though the screen showed Saved.",
          "acceptanceCriteria": [
            "Saved appears only after the local transaction commits.",
            "A committed answer survives process termination and reopening.",
            "Database write failure preserves the editable value and clearly marks it unsaved."
          ],
          "implementationNotes": [
            "Keep persistence behind a repository boundary; component state alone is not durable."
          ],
          "verification": [
            "Commit an answer, terminate the app, and verify the answer after restart.",
            "Inject a database-full error before commit; the UI must not claim success or discard the typed value."
          ],
          "deliverables": [
            "Transactional checklist persistence and restart regression test"
          ],
          "rollout": "Enable on pilot devices with synthetic work; stop editing if local persistence is unavailable rather than falsely confirming saves.",
          "skills": [
            "SQLite",
            "Transactions",
            "Lifecycle testing"
          ],
          "fieldMix": [
            {
              "field": "Mobile",
              "percentage": 60
            },
            {
              "field": "Database engineering",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "f914c1c0-09f7-40b4-a1ef-ad61e820cef9",
          "key": "FIELD-103",
          "title": "Make inspection inputs usable with large text",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 75,
          "phaseId": "local",
          "dependsOn": [
            "FIELD-101"
          ],
          "scenario": "A technician increases system text size. Pass/Fail controls overlap equipment names, and the last input disappears beneath the keyboard.",
          "acceptanceCriteria": [
            "The agreed largest supported text setting keeps labels and choices readable.",
            "Focused fields can scroll above the keyboard without hiding their error messages.",
            "Each checklist choice has an accessible name that includes its inspection item."
          ],
          "implementationNotes": [
            "Do not disable system text scaling to make the layout fit."
          ],
          "verification": [
            "Complete a six-item inspection at large text size with the on-screen keyboard.",
            "Use a long equipment name and an invalid reading; controls and errors remain reachable through assistive navigation."
          ],
          "deliverables": [
            "Adaptive inspection layout and emulator accessibility walkthrough"
          ],
          "rollout": "Review on the smallest supported test device; revert affected layout components if input becomes unreachable.",
          "skills": [
            "Mobile accessibility",
            "Responsive layout",
            "Forms"
          ],
          "fieldMix": [
            {
              "field": "Accessibility",
              "percentage": 60
            },
            {
              "field": "Mobile",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "7eadff40-7e44-4ee0-9ecb-d99312806e71",
          "key": "FIELD-104",
          "title": "Keep photo evidence attached after the app is suspended",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 165,
          "phaseId": "capture",
          "dependsOn": [
            "FIELD-102"
          ],
          "scenario": "A technician takes an equipment photo, answers a phone call, and returns to a blank attachment tile. The draft stored a temporary camera URI that no longer exists.",
          "acceptanceCriteria": [
            "Attachment metadata becomes saved only after the file is copied into app-owned storage.",
            "Restart restores pending attachments with a clear missing-file recovery action when necessary.",
            "Cancelled capture and failed copies leave neither dangling records nor orphaned temporary files."
          ],
          "implementationNotes": [
            "Use synthetic equipment images; permission to capture does not authorize unrelated gallery access."
          ],
          "verification": [
            "Capture, suspend, terminate, and reopen; the saved attachment remains available.",
            "Delete the source URI before copying and cancel another capture; no accepted attachment or orphaned pending row remains."
          ],
          "deliverables": [
            "Durable attachment staging and lifecycle failure cases"
          ],
          "rollout": "Pilot capture separately from uploads; disable new capture if staged-file recovery fails while preserving existing files.",
          "skills": [
            "Mobile filesystems",
            "Lifecycle recovery",
            "Data integrity"
          ],
          "fieldMix": [
            {
              "field": "Mobile",
              "percentage": 60
            },
            {
              "field": "Storage systems",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "5ea9cec4-2f80-4e05-afab-6cac466834cd",
          "key": "FIELD-105",
          "title": "Explain why a work order is not ready to finish",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 90,
          "phaseId": "capture",
          "dependsOn": [
            "FIELD-102",
            "FIELD-103",
            "FIELD-104"
          ],
          "scenario": "Finish visit is disabled with no explanation when a required reading or photo is missing. Technicians tap through every section to find the blocker.",
          "acceptanceCriteria": [
            "A completion summary lists missing required answers and attachments with navigation actions.",
            "Optional notes never block completion.",
            "Finishing offline creates a pending completion operation and labels it as awaiting sync rather than server-confirmed."
          ],
          "implementationNotes": [
            "Derive readiness from the current local revision and the downloaded checklist version."
          ],
          "verification": [
            "Fill the required inputs and finish offline; a pending operation is visible after restart.",
            "Remove a required photo and leave optional notes empty; only the photo blocks completion."
          ],
          "deliverables": [
            "Completion-readiness summary and offline finish cases"
          ],
          "rollout": "Enable the summary before completion changes; pause finishing if checklist versions cannot be resolved.",
          "skills": [
            "Workflow modeling",
            "Validation",
            "Offline UX"
          ],
          "fieldMix": [
            {
              "field": "Mobile",
              "percentage": 100
            }
          ],
          "patterns": []
        },
        {
          "id": "daa7f5fb-4523-423b-b6a5-d9768be143e5",
          "key": "FIELD-106",
          "title": "Drain the sync queue without duplicating completed visits",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "sync",
          "dependsOn": [
            "FIELD-105"
          ],
          "scenario": "Reception returns briefly and drops again during sync. The same completed visit is sent twice, while a later note disappears after a failed batch.",
          "acceptanceCriteria": [
            "Each queued operation has a stable identity and advances only after acknowledgement.",
            "Per-order dependencies preserve answer and completion ordering while unrelated orders can progress.",
            "Retry uses bounded backoff and keeps unacknowledged operations durable across restart."
          ],
          "implementationNotes": [
            "The fixture service deduplicates operation IDs; do not assume a timeout means the server rejected a write."
          ],
          "verification": [
            "Acknowledge a batch and verify only confirmed queue entries leave local storage.",
            "Drop a response after server acceptance and restart; retries keep the same IDs and produce one logical completion."
          ],
          "deliverables": [
            "Durable sync queue processor and interrupted-batch tests"
          ],
          "rollout": "Limit initial batch size and observe backlog age; pause queue draining on repeated protocol errors without deleting pending work.",
          "skills": [
            "Idempotency",
            "Queues",
            "Retry design"
          ],
          "fieldMix": [
            {
              "field": "Mobile",
              "percentage": 50
            },
            {
              "field": "Distributed systems",
              "percentage": 50
            }
          ],
          "patterns": []
        },
        {
          "id": "631b1950-c7c4-4aa2-8d56-f9d0cee3176f",
          "key": "FIELD-107",
          "title": "Keep reassigned work from being silently completed offline",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 210,
          "phaseId": "sync",
          "dependsOn": [
            "FIELD-106"
          ],
          "scenario": "Dispatch reassigns a job while the original technician is underground. That device later uploads completion against the old assignment. Preserve the technician’s work while honoring current server authority.",
          "acceptanceCriteria": [
            "Sync includes the assignment revision that authorized the offline visit.",
            "Reassignment rejection moves local work into an explicit review-required state without marking the job complete.",
            "The technician can inspect their unsynced notes and a redacted export while server-only actions remain blocked."
          ],
          "implementationNotes": [
            "Do not automatically apply old work to the new assignee; supervisor resolution is a documented stub contract."
          ],
          "verification": [
            "Sync a completion with the current assignment revision and confirm acceptance.",
            "Reassign before reconnecting and reject the old revision; retain local work and prevent repeated automatic completion retries."
          ],
          "deliverables": [
            "Reassignment conflict flow and preserved-work recovery fixture"
          ],
          "rollout": "Pilot with forced reassignment scenarios; disable offline finishing if authority conflicts cannot retain work safely.",
          "skills": [
            "Authorization",
            "Conflict resolution",
            "Distributed state"
          ],
          "fieldMix": [
            {
              "field": "Mobile",
              "percentage": 40
            },
            {
              "field": "Security",
              "percentage": 30
            },
            {
              "field": "Distributed systems",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "562e988f-9375-4d42-98ea-755bf996f35a",
          "key": "FIELD-108",
          "title": "Resume a large photo upload without restarting the whole queue",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "ADVANCED",
          "estimateMinutes": 150,
          "phaseId": "sync",
          "dependsOn": [
            "FIELD-104",
            "FIELD-106"
          ],
          "scenario": "One 12 MB equipment photo repeatedly fails halfway through and blocks all completed visits. Integrate the resumable-upload contract and isolate attachment progress from unrelated operations.",
          "acceptanceCriteria": [
            "Committed upload offsets are persisted and reconciled with the service after reconnect.",
            "An expired upload session starts a new session without losing the source file.",
            "Failure of one attachment does not block sync for another independent work order."
          ],
          "implementationNotes": [
            "Use small synthetic chunks in tests; server file integrity and scanning remain separate responsibilities."
          ],
          "verification": [
            "Interrupt after two acknowledged chunks and resume from the server-confirmed offset.",
            "Expire the session and simulate a missing local file; show repair guidance and allow another work order to sync."
          ],
          "deliverables": [
            "Resumable upload adapter and offset/session recovery cases"
          ],
          "rollout": "Enable for larger attachments first; pause uploads and keep staged files if offset reconciliation fails.",
          "skills": [
            "Resumable uploads",
            "Fault isolation",
            "Persistence"
          ],
          "fieldMix": [
            {
              "field": "Mobile",
              "percentage": 40
            },
            {
              "field": "Storage systems",
              "percentage": 40
            },
            {
              "field": "Networking",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "b14875a2-9ac4-4ccf-8e9c-6dc16a6870ce",
          "key": "FIELD-109",
          "title": "Clear a shared device without dropping pending work invisibly",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 150,
          "phaseId": "operations",
          "dependsOn": [
            "FIELD-107",
            "FIELD-108"
          ],
          "scenario": "Two technicians share a tablet between shifts. Sign-out currently leaves cached addresses for the next user, but blindly deleting storage would also erase unsynced repairs.",
          "acceptanceCriteria": [
            "Sign-out reports pending work before an explicit discard or sync choice.",
            "Confirmed sign-out removes account-scoped database rows, staged files, and credentials from the usable app context.",
            "Signing in as a different technician cannot render or sync the prior account’s data."
          ],
          "implementationNotes": [
            "Document the limits of app-level deletion; do not claim forensic erasure or export data automatically."
          ],
          "verification": [
            "Sync all work, sign out, and sign in as another user; no previous records appear.",
            "Fail sync with pending attachments and choose cancel; preserve the current session and work without exposing it to another account."
          ],
          "deliverables": [
            "Shared-device sign-out flow and account-boundary tests"
          ],
          "rollout": "Require this check before shared-device pilots; disable account switching if cleanup cannot be confirmed.",
          "skills": [
            "Privacy",
            "Account isolation",
            "Data lifecycle"
          ],
          "fieldMix": [
            {
              "field": "Privacy engineering",
              "percentage": 60
            },
            {
              "field": "Mobile",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "81110be7-0f2c-44ec-a850-a6b128d41707",
          "key": "FIELD-110",
          "title": "Expose sync health that depot support can act on",
          "type": "CHORE",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 90,
          "phaseId": "operations",
          "dependsOn": [
            "FIELD-106",
            "FIELD-109"
          ],
          "scenario": "Depot support cannot distinguish a device waiting for Wi-Fi from one stuck on an expired upload. Add an account-local sync health page and a safe support bundle.",
          "acceptanceCriteria": [
            "The page separates queued, retrying, blocked, and acknowledged counts with last successful sync time.",
            "The bundle includes app/schema versions and operation categories but excludes notes, photos, addresses, and tokens.",
            "A retry action obeys the same queue rules and cannot bypass blocked authority conflicts."
          ],
          "implementationNotes": [
            "Keep diagnostic storage bounded and document one recovery action per blocker category."
          ],
          "verification": [
            "Create a retryable upload and a reassignment blocker; verify distinct states and actions.",
            "Seed private fixture content and inspect the exported bundle; none of it is present and blocked work is not force-sent."
          ],
          "deliverables": [
            "Sync health screen and depot troubleshooting note"
          ],
          "rollout": "Enable for pilot support staff; remove bundle export if redaction fails while retaining local status labels.",
          "skills": [
            "Observability",
            "Support tooling",
            "Privacy"
          ],
          "fieldMix": [
            {
              "field": "Mobile",
              "percentage": 50
            },
            {
              "field": "Site reliability",
              "percentage": 30
            },
            {
              "field": "Privacy engineering",
              "percentage": 20
            }
          ],
          "patterns": []
        }
      ]
    }
  ]
}
