{
  "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": "257f157a-6e2f-4f0a-9322-abc658a6c403",
      "key": "COBJS",
      "title": "Resumable object uploads with verified completion",
      "field": "Storage systems",
      "summary": "Build a local multipart-upload coordinator with scoped identities and integrity checks.",
      "context": "Fictional document archive Fern stores synthetic byte objects. Use a local S3-compatible adapter or deterministic in-memory provider; no cloud credentials are needed.",
      "stack": [
        "TypeScript",
        "S3-compatible adapter",
        "PostgreSQL adapter",
        "Vitest"
      ],
      "prerequisites": [
        "Generate small deterministic byte fixtures.",
        "Implement local multipart provider responses including timeout and missing parts."
      ],
      "developerValue": "Practice object lifecycle, retry semantics and integrity verification.",
      "companyValue": "Inspect whether uploads avoid corruption, orphan cost and tenant crossover.",
      "delivery": "Submit bounded coordinator changes; external cloud rollout is separate.",
      "phases": [
        {
          "id": "contract",
          "title": "Define upload ownership",
          "goal": "Specify keys, parts and quotas."
        },
        {
          "id": "completion",
          "title": "Complete reliably",
          "goal": "Handle retries and integrity boundaries."
        },
        {
          "id": "recovery",
          "title": "Recover abandoned work",
          "goal": "Reclaim resources and inspect outcomes."
        }
      ],
      "tickets": [
        {
          "id": "de4d8c12-7077-4a6f-9fa2-9f5b81d695c1",
          "key": "COBJS-101",
          "title": "Normalize object names without treating them as filesystem paths",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 75,
          "phaseId": "contract",
          "dependsOn": [],
          "scenario": "The upload API accepts ambiguous separators and empty names. Define an opaque object-name contract.",
          "acceptanceCriteria": [
            "Valid names retain documented characters",
            "Empty and oversized names fail",
            "Normalization collisions are rejected"
          ],
          "implementationNotes": [
            "Object keys are not local file paths."
          ],
          "verification": [
            "Store valid unicode name",
            "Reject colliding normalized names"
          ],
          "deliverables": [
            "Name validator and examples"
          ],
          "rollout": "Reject new ambiguous names while keeping existing reads.",
          "skills": [
            "Object storage",
            "Validation"
          ],
          "fieldMix": [
            {
              "field": "API design",
              "percentage": 60
            },
            {
              "field": "Storage systems",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "be4f0c13-1bc6-491e-97c7-c8bad60c351c",
          "key": "COBJS-102",
          "title": "Bind multipart upload sessions to organization and object identity",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 120,
          "phaseId": "contract",
          "dependsOn": [
            "COBJS-101"
          ],
          "scenario": "A session ID can currently be reused against a different object. Require its original scope on every part operation.",
          "acceptanceCriteria": [
            "Matching owner uploads",
            "Foreign organization is denied",
            "Changed object identity is rejected"
          ],
          "implementationNotes": [
            "Enforce scope in the repository/provider boundary."
          ],
          "verification": [
            "Upload own part",
            "Reuse session against foreign object"
          ],
          "deliverables": [
            "Scoped session adapter and denial cases"
          ],
          "rollout": "Pause multipart writes if scope is uncertain.",
          "skills": [
            "Authorization",
            "Identity"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 60
            },
            {
              "field": "Storage systems",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "5b6d955f-de17-4a76-9958-2e9b81376658",
          "key": "COBJS-103",
          "title": "Reject multipart uploads exceeding declared size limits",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 75,
          "phaseId": "contract",
          "dependsOn": [
            "COBJS-102"
          ],
          "scenario": "The coordinator accepts an unlimited part list. Bound declared object size and per-session part count.",
          "acceptanceCriteria": [
            "Valid declared sizes pass",
            "Part count has explicit maximum",
            "Rejected admission creates no provider session"
          ],
          "implementationNotes": [
            "Limits must be checked before remote allocation."
          ],
          "verification": [
            "Admit small fixture",
            "Reject oversized declaration"
          ],
          "deliverables": [
            "Admission policy and allocation checks"
          ],
          "rollout": "Lower admission to a documented safe cap if accounting fails.",
          "skills": [
            "Resource limits",
            "Contracts"
          ],
          "fieldMix": [
            {
              "field": "Storage systems",
              "percentage": 50
            },
            {
              "field": "API design",
              "percentage": 30
            },
            {
              "field": "Performance engineering",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "949898d9-c35e-46b5-ba0b-c8f45af7ef6b",
          "key": "COBJS-104",
          "title": "Retry the same multipart part without creating contradictory receipts",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "completion",
          "dependsOn": [
            "COBJS-102",
            "COBJS-103"
          ],
          "scenario": "A timeout after part acceptance leads to duplicate receipts with different checksums. Bind retries to part number and digest.",
          "acceptanceCriteria": [
            "Same bytes return stable receipt",
            "Different bytes require explicit replacement",
            "Uncertain responses reconcile with provider state"
          ],
          "implementationNotes": [
            "Provider ETag is opaque unless contract says otherwise."
          ],
          "verification": [
            "Retry identical part",
            "Retry changed bytes under same operation"
          ],
          "deliverables": [
            "Part-retry coordinator and cases"
          ],
          "rollout": "Stop retries and expose reconciliation status.",
          "skills": [
            "Idempotency",
            "Integrity"
          ],
          "fieldMix": [
            {
              "field": "Storage systems",
              "percentage": 50
            },
            {
              "field": "Distributed systems",
              "percentage": 50
            }
          ],
          "patterns": []
        },
        {
          "id": "9f0fd846-0b72-4401-847f-d49c31c3e0fd",
          "key": "COBJS-105",
          "title": "Validate ordered multipart completion against acknowledged parts",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "completion",
          "dependsOn": [
            "COBJS-104"
          ],
          "scenario": "Completion silently omits a middle part and produces a shorter object. Check the requested manifest before finalization.",
          "acceptanceCriteria": [
            "Required part numbers are contiguous",
            "Receipts match acknowledged digests",
            "Missing parts prevent completion"
          ],
          "implementationNotes": [
            "Define final-part size exception explicitly."
          ],
          "verification": [
            "Complete ordered fixture",
            "Omit or duplicate middle part"
          ],
          "deliverables": [
            "Completion validator and negative cases"
          ],
          "rollout": "Disable completion until manifest validation recovers.",
          "skills": [
            "Validation",
            "Object storage"
          ],
          "fieldMix": [
            {
              "field": "Storage systems",
              "percentage": 80
            },
            {
              "field": "API design",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "610745e9-e43b-4e21-956c-56fe2845c5ce",
          "key": "COBJS-106",
          "title": "Verify completed object content before marking it available",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "completion",
          "dependsOn": [
            "COBJS-105"
          ],
          "scenario": "Provider completion succeeds but the assembled bytes differ from the expected digest. Introduce a verification state.",
          "acceptanceCriteria": [
            "Available requires digest agreement",
            "Mismatch quarantines the object",
            "Verification retries do not republish"
          ],
          "implementationNotes": [
            "Use bounded streaming hashing, not full-memory buffering."
          ],
          "verification": [
            "Verify matching bytes",
            "Flip one completed byte"
          ],
          "deliverables": [
            "Post-completion verifier and corruption cases"
          ],
          "rollout": "Keep newly completed objects unavailable if verification fails.",
          "skills": [
            "Streaming",
            "Hashing"
          ],
          "fieldMix": [
            {
              "field": "Storage systems",
              "percentage": 80
            },
            {
              "field": "Backend",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "d8a8754d-2132-4652-b5ef-7342492cda13",
          "key": "COBJS-107",
          "title": "Recover a timeout between multipart finalization and metadata commit",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 240,
          "phaseId": "completion",
          "dependsOn": [
            "COBJS-105",
            "COBJS-106"
          ],
          "scenario": "A crash after provider completion leaves the session looking incomplete. Reconcile provider outcome without creating another object.",
          "acceptanceCriteria": [
            "Recovery locates the finalized identity",
            "Metadata transition repeats safely",
            "Ambiguous provider state stays unresolved"
          ],
          "implementationNotes": [
            "Persist the completion operation before dispatch."
          ],
          "verification": [
            "Crash after finalization",
            "Return inconclusive provider lookup"
          ],
          "deliverables": [
            "Completion journal and crash schedule"
          ],
          "rollout": "Pause automatic completion recovery and retain session metadata.",
          "skills": [
            "Crash consistency",
            "Reconciliation"
          ],
          "fieldMix": [
            {
              "field": "Storage systems",
              "percentage": 50
            },
            {
              "field": "Distributed systems",
              "percentage": 30
            },
            {
              "field": "Database engineering",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "70e6f4ca-b857-490e-a52b-9e37f08ba518",
          "key": "COBJS-108",
          "title": "Abort expired multipart sessions without touching completed objects",
          "type": "CHORE",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 135,
          "phaseId": "recovery",
          "dependsOn": [
            "COBJS-107"
          ],
          "scenario": "Abandoned sessions retain billable parts. Add expiry cleanup with a guarded session transition.",
          "acceptanceCriteria": [
            "Only expired open sessions abort",
            "Completed objects remain readable",
            "Repeated abort is harmless"
          ],
          "implementationNotes": [
            "Compare session state immediately before provider action."
          ],
          "verification": [
            "Clean abandoned fixture",
            "Race cleanup with completion"
          ],
          "deliverables": [
            "Session cleanup and race case"
          ],
          "rollout": "Disable cleanup if finalization state is uncertain.",
          "skills": [
            "Lifecycle",
            "Resource management"
          ],
          "fieldMix": [
            {
              "field": "Storage systems",
              "percentage": 70
            },
            {
              "field": "Site reliability",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "97462569-e274-4c56-a2ad-e878f93cdbab",
          "key": "COBJS-109",
          "title": "Expose multipart upload progress from acknowledged bytes",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 105,
          "phaseId": "recovery",
          "dependsOn": [
            "COBJS-104",
            "COBJS-108"
          ],
          "scenario": "Progress reaches 100 percent before the provider accepts the final part. Count acknowledged bytes separately from verification state.",
          "acceptanceCriteria": [
            "Progress uses accepted parts",
            "Completion remains pending verification",
            "Retransmission does not double-count"
          ],
          "implementationNotes": [
            "Do not treat socket bytes sent as durable storage."
          ],
          "verification": [
            "Upload three parts",
            "Timeout accepted part and reconcile"
          ],
          "deliverables": [
            "Progress projection and cases"
          ],
          "rollout": "Display state-only progress if byte accounting diverges.",
          "skills": [
            "State projection",
            "UX"
          ],
          "fieldMix": [
            {
              "field": "Frontend",
              "percentage": 50
            },
            {
              "field": "Storage systems",
              "percentage": 30
            },
            {
              "field": "API design",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "36cd1ef9-3d4c-49e6-9cc2-5f9a57457811",
          "key": "COBJS-110",
          "title": "Export multipart failure diagnostics without signed URLs",
          "type": "CHORE",
          "priority": "LOW",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 90,
          "phaseId": "recovery",
          "dependsOn": [
            "COBJS-109"
          ],
          "scenario": "Support dumps provider receipts containing temporary access URLs. Add an allowlisted diagnostic projection.",
          "acceptanceCriteria": [
            "Includes operation and part counts",
            "Omits signatures and object content",
            "Errors use bounded categories"
          ],
          "implementationNotes": [
            "Signed URLs are bearer capabilities."
          ],
          "verification": [
            "Export failed session",
            "Inject signed URL in provider error"
          ],
          "deliverables": [
            "Diagnostic schema and redaction checks"
          ],
          "rollout": "Disable exports if bearer data appears.",
          "skills": [
            "Logging",
            "Security"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 50
            },
            {
              "field": "Site reliability",
              "percentage": 30
            },
            {
              "field": "Storage systems",
              "percentage": 20
            }
          ],
          "patterns": []
        }
      ]
    }
  ]
}
