{
  "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": "795f7fba-673b-44f3-9303-2bddca3f6ce8",
      "key": "ARULE",
      "title": "Ship a reviewable pricing-rule service",
      "field": "Backend",
      "summary": "Version promotional pricing rules and make every applied discount explainable.",
      "context": "A fictional parts supplier combines contract prices with promotions. Sales needs repeatable quotes when rules change during checkout.",
      "stack": [
        "TypeScript",
        "PostgreSQL",
        "JSON Schema"
      ],
      "prerequisites": [
        "Create synthetic products and integer minor-unit prices.",
        "Implement a small local quote API."
      ],
      "developerValue": "Practice deterministic rule evaluation, revision control and bounded execution.",
      "companyValue": "Review explainable commercial rules without trusting opaque price changes.",
      "delivery": "Ten scoped tickets across three phases. Build a synthetic local service or select a ticket after recreating its prerequisites; estimates exclude setup.",
      "phases": [
        {
          "id": "rules",
          "title": "Constrain rule input",
          "goal": "Define a safe, deterministic rule language."
        },
        {
          "id": "quotes",
          "title": "Apply frozen rules",
          "goal": "Make quote decisions consistent and auditable."
        },
        {
          "id": "release",
          "title": "Release rule versions",
          "goal": "Compare revisions and recover rejected releases."
        }
      ],
      "tickets": [
        {
          "id": "fdee872f-bdf8-4d6e-99bd-5c2f4c61aaf1",
          "key": "ARULE-101",
          "title": "Define the supported promotion predicates without executable expressions",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 90,
          "phaseId": "rules",
          "dependsOn": [],
          "scenario": "Sales requested a formula textbox; evaluating arbitrary expressions would make quote behavior difficult to bound and audit.",
          "acceptanceCriteria": [
            "Allow explicit product, quantity and date predicates.",
            "Reject unknown operators and excessive nesting.",
            "Publish a schema with accepted and rejected examples."
          ],
          "implementationNotes": [
            "Treat rule documents as data; never evaluate source strings."
          ],
          "verification": [
            "Parse a quantity-band promotion.",
            "Reject a function expression and a nesting-limit violation."
          ],
          "deliverables": [
            "Promotion schema and parser cases"
          ],
          "rollout": "Accept drafts only initially; disable new drafts if parser compatibility fails.",
          "skills": [
            "Schema design",
            "Input validation"
          ],
          "fieldMix": [
            {
              "field": "Backend",
              "percentage": 60
            },
            {
              "field": "API design",
              "percentage": 20
            },
            {
              "field": "Security",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "a5b0c45d-fef0-4c27-9c3a-b2c4e56e1027",
          "key": "ARULE-102",
          "title": "Resolve overlapping promotions with an explicit tie-break policy",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 150,
          "phaseId": "rules",
          "dependsOn": [
            "ARULE-101"
          ],
          "scenario": "Two promotions match the same part and the chosen discount depends on database return order.",
          "acceptanceCriteria": [
            "Define priority and stable-ID tie breaking.",
            "Return the winning rule and losing-match reasons.",
            "Evaluation is independent of input array order."
          ],
          "implementationNotes": [
            "Use integer arithmetic and a documented rounding boundary."
          ],
          "verification": [
            "Shuffle matching rules and retain the same price.",
            "Exercise equal priorities and invalid discount bounds."
          ],
          "deliverables": [
            "Deterministic resolver and ordering tests"
          ],
          "rollout": "Compare decisions on synthetic quotes; retain the previous resolver version for rollback.",
          "skills": [
            "Determinism",
            "Business rules"
          ],
          "fieldMix": [
            {
              "field": "Backend",
              "percentage": 100
            }
          ],
          "patterns": []
        },
        {
          "id": "98375e52-586d-4fb2-a40e-1203e142ee70",
          "key": "ARULE-103",
          "title": "Validate promotion date ranges before publishing drafts",
          "type": "BUG",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 60,
          "phaseId": "rules",
          "dependsOn": [
            "ARULE-101"
          ],
          "scenario": "A promotion with its end before its start passes draft review and can never apply.",
          "acceptanceCriteria": [
            "Require offset-bearing UTC-normalizable dates.",
            "Reject empty and reversed ranges at publication.",
            "Display validation paths without raw rule documents in logs."
          ],
          "implementationNotes": [
            "Use half-open intervals consistently."
          ],
          "verification": [
            "Publish an adjacent pair of valid promotions.",
            "Reject reversed, missing-offset and empty intervals."
          ],
          "deliverables": [
            "Publication date guard"
          ],
          "rollout": "Deploy guard for unpublished drafts; preserve existing published versions.",
          "skills": [
            "Validation",
            "Temporal rules"
          ],
          "fieldMix": [
            {
              "field": "Backend",
              "percentage": 100
            }
          ],
          "patterns": []
        },
        {
          "id": "980cd226-b289-4740-a46d-d629c580c54e",
          "key": "ARULE-104",
          "title": "Freeze product and rule versions when a quote is accepted",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 240,
          "phaseId": "quotes",
          "dependsOn": [
            "ARULE-102",
            "ARULE-103"
          ],
          "scenario": "A buyer accepts a quote after a promotion edit and receives a different total from the amount previously displayed.",
          "acceptanceCriteria": [
            "Accepted quotes retain product and rule version identities.",
            "Acceptance checks expiry and expected quote revision.",
            "Retries resolve one accepted quote with an unchanged total."
          ],
          "implementationNotes": [
            "Store a canonical calculation input hash with the quote."
          ],
          "verification": [
            "Accept a quote after changing current rules and retain its frozen total.",
            "Attempt acceptance after expiry and create no order."
          ],
          "deliverables": [
            "Quote acceptance command and frozen-input checks"
          ],
          "rollout": "Enable acceptance for synthetic accounts; suspend new acceptance while preserving accepted records.",
          "skills": [
            "Immutability",
            "Transactions"
          ],
          "fieldMix": [
            {
              "field": "Backend",
              "percentage": 60
            },
            {
              "field": "Database engineering",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "7da5202d-9e8d-4340-9c2e-51b4a409328f",
          "key": "ARULE-105",
          "title": "Bound pricing work for a cart with many matching rules",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "EXPERT",
          "estimateMinutes": 300,
          "phaseId": "quotes",
          "dependsOn": [
            "ARULE-102"
          ],
          "scenario": "An unusually broad rule set makes checkout evaluate thousands of predicates per item and blocks unrelated quotes.",
          "acceptanceCriteria": [
            "Set explicit cart, rule-count and predicate-work limits.",
            "Reject over-budget requests before partial quote publication.",
            "Return a bounded-work error distinct from invalid pricing."
          ],
          "implementationNotes": [
            "Choose limits from a repeatable local synthetic workload and document conditions."
          ],
          "verification": [
            "Measure work counters for 100 items and 200 rules.",
            "Exceed each limit and verify no accepted quote is created."
          ],
          "deliverables": [
            "Evaluation budget and reproducible workload"
          ],
          "rollout": "Canary limits in observation mode; lower admitted work or restore prior limits on regressions.",
          "skills": [
            "Resource budgets",
            "Complexity"
          ],
          "fieldMix": [
            {
              "field": "Performance engineering",
              "percentage": 50
            },
            {
              "field": "Backend",
              "percentage": 50
            }
          ],
          "patterns": []
        },
        {
          "id": "2c465eeb-5e2e-4fcf-b8f6-3b4bfe110afc",
          "key": "ARULE-106",
          "title": "Keep negotiated account prices outside shared quote caches",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 210,
          "phaseId": "quotes",
          "dependsOn": [
            "ARULE-104"
          ],
          "scenario": "A shared cache returns one customer's negotiated rate to another account requesting the same product list.",
          "acceptanceCriteria": [
            "Bind cache identity to organization, account and frozen price version.",
            "Authorize before cache lookup.",
            "Never cache an authorization failure as a valid quote."
          ],
          "implementationNotes": [
            "Include all price-affecting inputs in canonical cache keys."
          ],
          "verification": [
            "Quote identical carts for two negotiated-price accounts.",
            "Attempt cross-account access and inspect cache hits and response fields."
          ],
          "deliverables": [
            "Scoped cache key and isolation regression"
          ],
          "rollout": "Invalidate the affected namespace before enabling the new key format.",
          "skills": [
            "Caching",
            "Tenant isolation"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 50
            },
            {
              "field": "Backend",
              "percentage": 50
            }
          ],
          "patterns": []
        },
        {
          "id": "e2ec3343-d95f-4070-87c6-12d2be14835c",
          "key": "ARULE-107",
          "title": "Report why a cart missed a promotion without leaking contract terms",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 150,
          "phaseId": "quotes",
          "dependsOn": [
            "ARULE-102",
            "ARULE-106"
          ],
          "scenario": "Sales wants to explain an unmet minimum quantity, but the current debug endpoint exposes every account's price rules.",
          "acceptanceCriteria": [
            "Explain only rules visible to the requesting account.",
            "Show failed predicate names with permitted thresholds.",
            "Omit internal contract identifiers and unrelated rule matches."
          ],
          "implementationNotes": [
            "Build a dedicated explanation projection."
          ],
          "verification": [
            "Explain a visible minimum-quantity miss.",
            "Request explanation for an inaccessible contract and receive no rule details."
          ],
          "deliverables": [
            "Scoped pricing explanation endpoint"
          ],
          "rollout": "Enable the projection for one synthetic sales role; disable debug routes on disclosure failure.",
          "skills": [
            "Authorization",
            "Explainability"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 50
            },
            {
              "field": "Backend",
              "percentage": 30
            },
            {
              "field": "API design",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "3f224d0f-e9bb-496b-9882-6e58feeb71af",
          "key": "ARULE-108",
          "title": "Compare a draft pricing revision against a named quote corpus",
          "type": "CHORE",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 180,
          "phaseId": "release",
          "dependsOn": [
            "ARULE-104",
            "ARULE-107"
          ],
          "scenario": "A promotion revision fixes bulk orders but may unintentionally discount small carts.",
          "acceptanceCriteria": [
            "Create and version a synthetic quote corpus.",
            "Report old and new totals plus changed rule identities.",
            "Flag unexplained differences before publication."
          ],
          "implementationNotes": [
            "The corpus is authored for this exercise; do not claim production coverage."
          ],
          "verification": [
            "Include bulk, small-cart and no-match examples.",
            "Insert an invalid draft and report validation failure instead of a comparison."
          ],
          "deliverables": [
            "Revision comparison command and synthetic corpus"
          ],
          "rollout": "Require comparison review for draft publication; preserve earlier reports.",
          "skills": [
            "Regression analysis",
            "Tooling"
          ],
          "fieldMix": [
            {
              "field": "Quality engineering",
              "percentage": 50
            },
            {
              "field": "Backend",
              "percentage": 30
            },
            {
              "field": "Developer tooling",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "938e3bdc-4687-4825-b8da-8afe19d99f9b",
          "key": "ARULE-109",
          "title": "Publish a pricing revision with optimistic review protection",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 240,
          "phaseId": "release",
          "dependsOn": [
            "ARULE-103",
            "ARULE-108"
          ],
          "scenario": "A reviewer approves a draft while an editor changes its discount; publication currently activates content nobody reviewed.",
          "acceptanceCriteria": [
            "Approval binds the exact canonical draft hash.",
            "Publication rejects a changed draft or stale expected revision.",
            "Published rule content cannot be updated in place."
          ],
          "implementationNotes": [
            "Commit active-pointer selection and audit metadata together."
          ],
          "verification": [
            "Publish an unchanged approved draft.",
            "Edit between approval and publish and retain the previous active revision."
          ],
          "deliverables": [
            "Guarded publication command"
          ],
          "rollout": "Publish to synthetic accounts first; restore the prior active pointer without rewriting versions.",
          "skills": [
            "Optimistic concurrency",
            "Versioning"
          ],
          "fieldMix": [
            {
              "field": "Backend",
              "percentage": 60
            },
            {
              "field": "Database engineering",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "695efa2c-4a88-4623-8b0b-0d542ac45406",
          "key": "ARULE-110",
          "title": "Replay a pricing dispute from immutable quote inputs",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "EXPERT",
          "estimateMinutes": 300,
          "phaseId": "release",
          "dependsOn": [
            "ARULE-104",
            "ARULE-109"
          ],
          "scenario": "Support receives a disputed total after three rule releases and cannot reproduce which calculation the buyer accepted.",
          "acceptanceCriteria": [
            "Replay selects the recorded evaluator and input versions.",
            "Report missing versions as unreproducible rather than guessing.",
            "Compare computed total and hash with the accepted record."
          ],
          "implementationNotes": [
            "Keep replay read-only and use fabricated customer data."
          ],
          "verification": [
            "Replay an accepted synthetic quote across later releases.",
            "Remove an available version in the test double and assert explicit failure."
          ],
          "deliverables": [
            "Read-only dispute replay and failure cases"
          ],
          "rollout": "Expose replay to scoped support users; revoke access if provenance cannot be resolved.",
          "skills": [
            "Reproducibility",
            "Auditability"
          ],
          "fieldMix": [
            {
              "field": "Backend",
              "percentage": 70
            },
            {
              "field": "Developer tooling",
              "percentage": 30
            }
          ],
          "patterns": []
        }
      ]
    }
  ]
}
