{
  "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": "57c9682e-7fce-4003-8c0b-0e09f8ee3bb3",
      "key": "BAPIAUTH",
      "title": "Delegated partner API access",
      "field": "API design",
      "summary": "Design scoped partner credentials with revocation, safe errors, and client lifecycle controls.",
      "context": "A fictional operations platform lets customers connect automation clients. Broad API keys and inconsistent tenant checks make delegated access difficult to review.",
      "stack": [
        "TypeScript",
        "OpenAPI",
        "PostgreSQL"
      ],
      "prerequisites": [
        "Create a local authorization service and synthetic partner clients for two organizations; generate disposable test credentials only."
      ],
      "developerValue": "Practice delegated authorization, resource scoping, and secure public API ergonomics.",
      "companyValue": "Provide usable partner access that remains least-privilege and revocable.",
      "delivery": "Deliver local credential and access contracts; connect no real partner account.",
      "phases": [
        {
          "id": "scope",
          "title": "Define delegated authority",
          "goal": "Separate actor, organization, client, and permission scope."
        },
        {
          "id": "access",
          "title": "Enforce access",
          "goal": "Validate resource authority and token lifecycle."
        },
        {
          "id": "operate",
          "title": "Support client operations",
          "goal": "Handle rotation, auditing, and migration."
        }
      ],
      "tickets": [
        {
          "id": "ce6b449b-4a6b-4470-b1c0-ec6e086d1290",
          "key": "BAPIAUTH-101",
          "title": "Define partner scopes from concrete API operations",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 60,
          "phaseId": "scope",
          "dependsOn": [],
          "scenario": "A single automation scope permits every operation in the organization.",
          "acceptanceCriteria": [
            "Map scopes to specific operation classes.",
            "Separate read, write, and administrative authority.",
            "Document unsupported scope combinations."
          ],
          "implementationNotes": [
            "Do not derive permissions from client-provided role names."
          ],
          "verification": [
            "Authorize a read-only synthetic client.",
            "Deny a write under the read-only scope."
          ],
          "deliverables": [
            "Partner scope matrix."
          ],
          "rollout": "Review least-privilege defaults before issuing credentials.",
          "skills": [
            "Authorization design"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 70
            },
            {
              "field": "API design",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "ccd9c24e-4f1e-424f-a050-2cf39315c248",
          "key": "BAPIAUTH-102",
          "title": "Bind delegated credentials to organization and client identity",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "scope",
          "dependsOn": [
            "BAPIAUTH-101"
          ],
          "scenario": "A valid credential can be paired with another organization ID in the URL.",
          "acceptanceCriteria": [
            "Store organization and client authority server-side.",
            "Require exact binding on each service call.",
            "Reject caller attempts to substitute actor identity."
          ],
          "implementationNotes": [
            "Opaque credentials are never interpreted as authorization claims without lookup or verification."
          ],
          "verification": [
            "Call an owned resource.",
            "Reuse the credential against another organization and deny safely."
          ],
          "deliverables": [
            "Credential authority model."
          ],
          "rollout": "Fail closed on missing client or membership authority.",
          "skills": [
            "Tenant isolation"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 80
            },
            {
              "field": "API design",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "f58521d3-f1aa-4fc0-91b9-0c91aacd3724",
          "key": "BAPIAUTH-103",
          "title": "Return non-enumerating errors for unauthorized partner resources",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 150,
          "phaseId": "access",
          "dependsOn": [
            "BAPIAUTH-102"
          ],
          "scenario": "Partners can distinguish nonexistent records from records belonging to another organization.",
          "acceptanceCriteria": [
            "Define stable safe denial semantics.",
            "Keep error bodies free of foreign identifiers.",
            "Preserve internal diagnostic categories separately."
          ],
          "implementationNotes": [
            "Use Problem Details-style public errors."
          ],
          "verification": [
            "Read an authorized record.",
            "Compare missing and foreign-record public responses."
          ],
          "deliverables": [
            "Partner error contract."
          ],
          "rollout": "Use the same safe projection across all resource endpoints.",
          "skills": [
            "Error design",
            "Privacy"
          ],
          "fieldMix": [
            {
              "field": "API design",
              "percentage": 40
            },
            {
              "field": "Security",
              "percentage": 40
            },
            {
              "field": "Privacy engineering",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "27057922-a6df-4324-9c92-328e2882be5e",
          "key": "BAPIAUTH-104",
          "title": "Enforce authorization in nested and batch partner operations",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "access",
          "dependsOn": [
            "BAPIAUTH-102",
            "BAPIAUTH-103"
          ],
          "scenario": "The parent resource is authorized, but nested record IDs bypass tenant checks.",
          "acceptanceCriteria": [
            "Reauthorize every nested resource at the service boundary.",
            "Define atomic or per-item denial behavior.",
            "Prevent unauthorized items from influencing result totals."
          ],
          "implementationNotes": [
            "Client-supplied parent-child relationships are untrusted."
          ],
          "verification": [
            "Process a valid nested update.",
            "Insert a foreign child ID and verify the declared denial behavior."
          ],
          "deliverables": [
            "Nested authorization regression."
          ],
          "rollout": "Gate batch rollout on cross-tenant and relationship checks.",
          "skills": [
            "Authorization",
            "API consistency"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 70
            },
            {
              "field": "API design",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "8f0920d4-7b6c-4da8-96f8-dc8b27d7fb00",
          "key": "BAPIAUTH-105",
          "title": "Rotate partner credentials without indefinite dual-key access",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 210,
          "phaseId": "access",
          "dependsOn": [
            "BAPIAUTH-102",
            "BAPIAUTH-104"
          ],
          "scenario": "Customers need rotation overlap, but old keys remain valid forever.",
          "acceptanceCriteria": [
            "Issue a distinct new credential generation.",
            "Set an explicit overlap expiry for the old generation.",
            "Show generation status without exposing credential values."
          ],
          "implementationNotes": [
            "Reveal a generated test credential only through the intended creation response."
          ],
          "verification": [
            "Use both generations during overlap.",
            "Reject the old generation after expiry."
          ],
          "deliverables": [
            "Credential rotation workflow."
          ],
          "rollout": "Keep overlap bounded and auditable; never restore retired credentials silently.",
          "skills": [
            "Credential lifecycle"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 80
            },
            {
              "field": "API design",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "489ea678-167f-4289-8fa5-a27bdff07fd7",
          "key": "BAPIAUTH-106",
          "title": "Revoke partner access across cached authorization decisions",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 180,
          "phaseId": "access",
          "dependsOn": [
            "BAPIAUTH-105"
          ],
          "scenario": "Revoked clients retain access until a long cache TTL expires.",
          "acceptanceCriteria": [
            "Bind caches to current authorization revision.",
            "Recheck or invalidate revoked authority within the declared bound.",
            "Deny new operations after revocation."
          ],
          "implementationNotes": [
            "Cached membership is not permanent authority."
          ],
          "verification": [
            "Serve a current authorized cache entry.",
            "Revoke the client and verify cached access stops within policy."
          ],
          "deliverables": [
            "Revocation-aware authorization cache."
          ],
          "rollout": "Prioritize denial when revision freshness is unavailable.",
          "skills": [
            "Caching",
            "Revocation"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 70
            },
            {
              "field": "Distributed systems",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "aa46adbb-a2af-4650-94d8-2db69aa9ba38",
          "key": "BAPIAUTH-107",
          "title": "Rate-limit by delegated client without losing tenant-wide protection",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 150,
          "phaseId": "operate",
          "dependsOn": [
            "BAPIAUTH-104",
            "BAPIAUTH-106"
          ],
          "scenario": "Creating many client keys bypasses a per-key request limit.",
          "acceptanceCriteria": [
            "Apply both client and organization budgets.",
            "Return documented retry guidance.",
            "Keep denied requests from consuming unrelated client authority."
          ],
          "implementationNotes": [
            "Use deterministic local counters and no customer profiling."
          ],
          "verification": [
            "Exercise separate clients within the organization ceiling.",
            "Create multiple clients and verify the shared cap holds."
          ],
          "deliverables": [
            "Delegated rate-limit contract."
          ],
          "rollout": "Start with published conservative limits and inspect false rejection cases.",
          "skills": [
            "API limits"
          ],
          "fieldMix": [
            {
              "field": "API design",
              "percentage": 50
            },
            {
              "field": "Site reliability",
              "percentage": 30
            },
            {
              "field": "Security",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "37721d78-a253-469f-b2db-dda6b3ec8cec",
          "key": "BAPIAUTH-108",
          "title": "Expose an audit trail of privileged partner-client changes",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 150,
          "phaseId": "operate",
          "dependsOn": [
            "BAPIAUTH-105",
            "BAPIAUTH-106"
          ],
          "scenario": "Organization owners cannot see who expanded a client scope.",
          "acceptanceCriteria": [
            "Append actor, client, changed scope, and UTC time.",
            "Exclude tokens and request payloads.",
            "Scope audit reads to current authorized organization members."
          ],
          "implementationNotes": [
            "Do not overwrite previous audit facts."
          ],
          "verification": [
            "Inspect a credential rotation and scope change.",
            "Deny a cross-organization audit read."
          ],
          "deliverables": [
            "Partner access audit projection."
          ],
          "rollout": "Enable audit recording before scope mutation endpoints.",
          "skills": [
            "Auditability"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 60
            },
            {
              "field": "Privacy engineering",
              "percentage": 20
            },
            {
              "field": "API design",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "ad7b4211-2bf6-453b-9d9b-db612015168f",
          "key": "BAPIAUTH-109",
          "title": "Design migration from broad keys to scoped delegated clients",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 300,
          "phaseId": "operate",
          "dependsOn": [
            "BAPIAUTH-107",
            "BAPIAUTH-108"
          ],
          "scenario": "Existing integrations depend on broad keys and cannot all migrate at once.",
          "acceptanceCriteria": [
            "Inventory actual required operations through safe synthetic usage records.",
            "Define staged scope reduction and client cutover.",
            "Compare compatibility burden with the risk of retained broad authority."
          ],
          "implementationNotes": [
            "No real partner usage is inferred from absence of traffic."
          ],
          "verification": [
            "Migrate two synthetic clients with different needs.",
            "Keep an unknown integration unresolved instead of silently revoking or broadening it."
          ],
          "deliverables": [
            "Delegated-access migration plan."
          ],
          "rollout": "Use explicit reviewed deadlines and retain a bounded recovery process.",
          "skills": [
            "API strategy",
            "Security tradeoffs"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 50
            },
            {
              "field": "System design",
              "percentage": 30
            },
            {
              "field": "API design",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "b0425786-d306-4067-906d-f3899996da55",
          "key": "BAPIAUTH-110",
          "title": "Write a partner credential handling example for rotation and denial",
          "type": "CHORE",
          "priority": "LOW",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 90,
          "phaseId": "operate",
          "dependsOn": [
            "BAPIAUTH-109"
          ],
          "scenario": "Documentation encourages hardcoding keys and retrying every unauthorized response.",
          "acceptanceCriteria": [
            "Read credentials from the intended runtime boundary.",
            "Handle expiry and revocation without infinite retries.",
            "Show safe rotation using local test credentials."
          ],
          "implementationNotes": [
            "Examples must not log authorization headers."
          ],
          "verification": [
            "Run the example through a valid rotation.",
            "Revoke access and verify a terminal actionable error."
          ],
          "deliverables": [
            "Executable partner access guide."
          ],
          "rollout": "Version examples with the credential contract and remove obsolete broad-key guidance.",
          "skills": [
            "SDK ergonomics",
            "Documentation"
          ],
          "fieldMix": [
            {
              "field": "Developer tooling",
              "percentage": 40
            },
            {
              "field": "Security",
              "percentage": 40
            },
            {
              "field": "API design",
              "percentage": 20
            }
          ],
          "patterns": []
        }
      ]
    }
  ]
}
