{
  "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": "fb653e08-0b12-40cb-8892-f314d1aad0cf",
      "key": "BUILD",
      "title": "Make the monorepo feedback loop trustworthy",
      "field": "Developer tooling",
      "summary": "Shorten a local monorepo check loop while retaining correctness when inputs, dependencies, or tools change.",
      "context": "A product team waits for every package to rebuild after small changes. An experimental cache is faster but occasionally returns success after a shared type changed. Build a small, auditable task runner around fixture packages.",
      "stack": [
        "TypeScript",
        "Node.js",
        "pnpm",
        "JSON"
      ],
      "prerequisites": [
        "Prepare four fixture packages with one shared library and two applications.",
        "Use only trusted fixture commands in local tests."
      ],
      "developerValue": "Practice incremental computation, dependency scheduling, cache correctness, and cancellation.",
      "companyValue": "Inspect whether faster checks preserve the guarantees reviewers depend on.",
      "delivery": "A dependency-aware check runner with a local cache and reproducible benchmark report.",
      "phases": [
        {
          "id": "model",
          "title": "Model checks and dependencies",
          "goal": "Make task selection and scheduling predictable."
        },
        {
          "id": "cache",
          "title": "Cache only valid results",
          "goal": "Prove when outputs may safely be reused."
        },
        {
          "id": "operate",
          "title": "Make the runner usable in CI",
          "goal": "Control resources and report failures without hiding them."
        }
      ],
      "tickets": [
        {
          "id": "fcf138a0-1fe8-41d4-91d6-baa8cc69a4dc",
          "key": "BUILD-101",
          "title": "Reject invalid task configuration before starting a command",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 60,
          "phaseId": "model",
          "dependsOn": [],
          "scenario": "A misspelled dependsOn entry silently removed a typecheck prerequisite. Introduce a validated task configuration with clear locations for configuration errors.",
          "acceptanceCriteria": [
            "Every task has a unique ID, command argument list, working directory, and declared dependencies.",
            "Unknown dependencies and paths outside the workspace fail validation.",
            "Validation reports all independent configuration errors without starting commands."
          ],
          "implementationNotes": [
            "Commands are trusted fixture configuration; no shell interpolation.",
            "Keep configuration parsing independent of execution."
          ],
          "verification": [
            "Validate a four-task graph successfully.",
            "Submit a missing dependency and escaping working directory together and confirm both errors and zero process starts."
          ],
          "deliverables": [
            "Configuration schema and validation diagnostics"
          ],
          "rollout": "Use validation in a read-only plan command first; refuse execution for older unsupported config versions.",
          "skills": [
            "Schema validation",
            "CLI design",
            "Path safety"
          ],
          "fieldMix": [
            {
              "field": "Developer tooling",
              "percentage": 80
            },
            {
              "field": "Security",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "ec674da0-4a15-456d-83f2-0d98aaac7a62",
          "key": "BUILD-102",
          "title": "Show why a task is selected after a file change",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 105,
          "phaseId": "model",
          "dependsOn": [
            "BUILD-101"
          ],
          "scenario": "Changing packages/shared/types.ts reruns one app but not its sibling. Build a changed-file planner that includes affected dependents and prints the reason for each selected task.",
          "acceptanceCriteria": [
            "Changes under a shared package select all configured downstream checks.",
            "A root configuration change selects the documented full validation set.",
            "Deleted files and renamed files are handled using both old and new affected paths."
          ],
          "implementationNotes": [
            "Sort explanation paths for reproducible output."
          ],
          "verification": [
            "Change shared types and inspect both application check reasons.",
            "Delete a file from one leaf package and confirm unrelated leaf tasks remain unselected."
          ],
          "deliverables": [
            "Affected-task planner and explanation output"
          ],
          "rollout": "Compare selection with full checks in report-only mode before using it to skip work.",
          "skills": [
            "Dependency analysis",
            "Incremental builds",
            "Git changes"
          ],
          "fieldMix": [
            {
              "field": "Developer tooling",
              "percentage": 100
            }
          ],
          "patterns": []
        },
        {
          "id": "a4ff10d4-f051-48b3-97ec-22757398237c",
          "key": "BUILD-103",
          "title": "Schedule independent checks without exceeding the worker limit",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 150,
          "phaseId": "model",
          "dependsOn": [
            "BUILD-101"
          ],
          "scenario": "Two independent application tests could run together, but shared compilation must finish first. Add bounded scheduling and explicit blocked states for dependent tasks.",
          "acceptanceCriteria": [
            "A task starts only after every prerequisite succeeds.",
            "Active process count never exceeds the configured positive concurrency limit.",
            "A failed prerequisite marks descendants blocked while unrelated tasks may finish."
          ],
          "implementationNotes": [
            "Detect cycles before execution and return the cycle path.",
            "Store task transitions through one scheduler boundary."
          ],
          "verification": [
            "Run a diamond graph with barrier-controlled fixture tasks and assert start order and concurrency.",
            "Fail the shared task and verify descendants never start while an independent task completes."
          ],
          "deliverables": [
            "Bounded scheduler and graph execution trace"
          ],
          "rollout": "Default concurrency to one; increase only after the scheduling trace demonstrates the limit.",
          "skills": [
            "Scheduling",
            "Concurrency",
            "State machines"
          ],
          "fieldMix": [
            {
              "field": "Developer tooling",
              "percentage": 100
            }
          ],
          "patterns": []
        },
        {
          "id": "d4e1c413-bd3f-4ce0-85e1-43a5a1a8ce85",
          "key": "BUILD-104",
          "title": "Include tool versions and declared environment in the cache key",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 150,
          "phaseId": "cache",
          "dependsOn": [
            "BUILD-102"
          ],
          "scenario": "The cache reused a successful check after the TypeScript version changed. Define a canonical cache key that captures the command, inputs, dependency results, and supported environment.",
          "acceptanceCriteria": [
            "Changing input bytes, lockfile, command arguments, tool version, or a declared environment value changes the key.",
            "File enumeration order and path separators do not change an otherwise equivalent key.",
            "Undeclared environment dependence is documented as unsupported and such tasks can disable caching."
          ],
          "implementationNotes": [
            "Hash values rather than logging environment contents.",
            "Use content hashes, not modification times, as input identity."
          ],
          "verification": [
            "Reorder file enumeration and assert the key is unchanged.",
            "Change each declared input dimension independently and assert a cache miss."
          ],
          "deliverables": [
            "Cache-key specification and canonicalization tests"
          ],
          "rollout": "Version the cache namespace and discard entries produced by the old key algorithm.",
          "skills": [
            "Content hashing",
            "Build reproducibility",
            "Cache invalidation"
          ],
          "fieldMix": [
            {
              "field": "Developer tooling",
              "percentage": 80
            },
            {
              "field": "Storage systems",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "efdbdf80-95bf-43f5-8d3c-a49c92ea268e",
          "key": "BUILD-105",
          "title": "Restore cached outputs without touching unrelated files",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 240,
          "phaseId": "cache",
          "dependsOn": [
            "BUILD-104"
          ],
          "scenario": "A cached archive restored ../config.json during a local corruption test. Replace blind extraction with a validated manifest and staged restoration inside declared output roots.",
          "acceptanceCriteria": [
            "Every restored file has a normalized in-root path and verified content digest.",
            "Absolute paths, traversal paths, symlink escapes, and unexpected output entries are rejected.",
            "A rejected or interrupted restoration preserves the prior output set and reports a cache miss."
          ],
          "implementationNotes": [
            "Treat cache entries as untrusted even when the cache is local.",
            "Separate verification from replacement and avoid executing archive hooks."
          ],
          "verification": [
            "Restore a valid two-directory output manifest and compare every digest.",
            "Use traversal, digest mismatch, and interrupted replacement fixtures and verify unrelated files are unchanged."
          ],
          "deliverables": [
            "Validated cache restorer and corruption fixtures"
          ],
          "rollout": "Enable restoration behind an opt-in flag; on any integrity error rebuild from source and quarantine that cache entry.",
          "skills": [
            "Filesystem safety",
            "Artifact integrity",
            "Transactional writes",
            "Threat modeling"
          ],
          "fieldMix": [
            {
              "field": "Security",
              "percentage": 50
            },
            {
              "field": "Developer tooling",
              "percentage": 30
            },
            {
              "field": "Storage systems",
              "percentage": 20
            }
          ],
          "patterns": []
        },
        {
          "id": "658219af-1ed0-4d64-a09c-38382ce14a01",
          "key": "BUILD-106",
          "title": "Never cache failed or incompletely written task outputs",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 105,
          "phaseId": "cache",
          "dependsOn": [
            "BUILD-103",
            "BUILD-104"
          ],
          "scenario": "A killed build left an output directory that the next run accepted as a hit. Publish a cache entry only after successful exit and complete output hashing.",
          "acceptanceCriteria": [
            "Nonzero exit, cancellation, and missing declared outputs never create reusable entries.",
            "Entries become visible through one final commit marker after all files and metadata are written.",
            "Concurrent identical writers either publish equivalent complete entries or report an integrity conflict."
          ],
          "implementationNotes": [
            "Use a unique staging directory per attempt."
          ],
          "verification": [
            "Kill a fixture build after it creates one output and assert the next run executes it again.",
            "Race two successful writes for one key and verify readers observe only complete entries."
          ],
          "deliverables": [
            "Atomic cache publisher and partial-output test"
          ],
          "rollout": "Invalidate legacy entries without a completion marker; keep cache misses safe by running the original task.",
          "skills": [
            "Atomicity",
            "Cache design",
            "Failure injection"
          ],
          "fieldMix": [
            {
              "field": "Developer tooling",
              "percentage": 60
            },
            {
              "field": "Storage systems",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "e789713c-7624-47ef-9ba7-dd7ab2c205e0",
          "key": "BUILD-107",
          "title": "Cancel running checks and report what did not run",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "ADVANCED",
          "estimateMinutes": 150,
          "phaseId": "operate",
          "dependsOn": [
            "BUILD-103"
          ],
          "scenario": "Pressing Ctrl+C stops the runner but leaves a test child consuming CPU. Add cancellation with a bounded grace period and explicit cancelled outcomes.",
          "acceptanceCriteria": [
            "Cancellation stops new starts immediately and requests termination of every owned process tree.",
            "After the configured grace period remaining owned processes are forcefully terminated using supported platform behavior.",
            "The summary distinguishes failed, cancelled, blocked, and completed tasks and returns a nonzero exit."
          ],
          "implementationNotes": [
            "Exercise only controlled fixture child processes.",
            "Do not terminate processes outside the operation ownership set."
          ],
          "verification": [
            "Cancel a parent fixture that owns a long-lived child and confirm both are gone.",
            "Cancel while one independent task has completed and verify its successful result remains in the summary."
          ],
          "deliverables": [
            "Cancellation handler and process-cleanup test"
          ],
          "rollout": "Enable cancellation together with process ownership tracking; retain the serial execution fallback if cleanup fails on a supported OS.",
          "skills": [
            "Process lifecycle",
            "Cross-platform tooling",
            "Cancellation"
          ],
          "fieldMix": [
            {
              "field": "Developer tooling",
              "percentage": 100
            }
          ],
          "patterns": []
        },
        {
          "id": "1294311f-2f28-412b-b0ba-95907f328ec0",
          "key": "BUILD-108",
          "title": "Keep parallel task output readable and bounded",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 75,
          "phaseId": "operate",
          "dependsOn": [
            "BUILD-103"
          ],
          "scenario": "Concurrent test logs interleave half-lines and a noisy task consumes hundreds of megabytes of memory. Prefix complete lines and cap retained output per task.",
          "acceptanceCriteria": [
            "Every rendered line carries its task ID without splitting UTF-8 characters.",
            "Retained output per task stays below a configured byte limit with a visible truncation notice.",
            "The final summary includes exit code, duration, and an indication that output was truncated."
          ],
          "implementationNotes": [
            "Handle a final line that has no newline.",
            "Keep stderr attribution separate from status."
          ],
          "verification": [
            "Emit split multibyte characters from two fixture processes and check rendered text.",
            "Write beyond the limit and verify bounded retention and a single clear truncation notice."
          ],
          "deliverables": [
            "Streaming output formatter and noisy-task fixture"
          ],
          "rollout": "Use bounded capture by default and document an explicit file-output option for deeper local debugging.",
          "skills": [
            "Streams",
            "Memory limits",
            "Developer experience"
          ],
          "fieldMix": [
            {
              "field": "Developer tooling",
              "percentage": 60
            },
            {
              "field": "Performance engineering",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "dd391771-5c5f-4173-97e2-07196be31368",
          "key": "BUILD-109",
          "title": "Explain a cache miss without exposing input contents",
          "type": "STORY",
          "priority": "LOW",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 90,
          "phaseId": "operate",
          "dependsOn": [
            "BUILD-104",
            "BUILD-106"
          ],
          "scenario": "The team cannot tell whether frequent misses come from the lockfile or an unstable generated file. Add an explain command comparing safe input metadata from two runs.",
          "acceptanceCriteria": [
            "Explanation identifies added, removed, or changed input paths and changed key categories.",
            "File contents and environment values are never printed.",
            "A missing prior run produces a useful first-run result instead of an error."
          ],
          "implementationNotes": [
            "Retain hashes and category names only for environment-sensitive inputs."
          ],
          "verification": [
            "Change a source file and a tool version and assert both reasons appear.",
            "Place a secret fixture value in a declared environment variable and confirm no output includes it."
          ],
          "deliverables": [
            "Cache-miss explanation command and safe metadata format"
          ],
          "rollout": "Make explanation read-only; deleting history must not alter cache correctness.",
          "skills": [
            "Observability",
            "Developer tooling",
            "Privacy"
          ],
          "fieldMix": [
            {
              "field": "Developer tooling",
              "percentage": 70
            },
            {
              "field": "Privacy engineering",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "664d3841-71e4-4f31-9733-7d34a24db553",
          "key": "BUILD-110",
          "title": "Measure the faster loop against a full-check baseline",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 120,
          "phaseId": "operate",
          "dependsOn": [
            "BUILD-105",
            "BUILD-106",
            "BUILD-107",
            "BUILD-108",
            "BUILD-109"
          ],
          "scenario": "A timing screenshot says the cache is faster but omits cases where it skipped a required check. Produce a reproducible comparison covering clean, warm, leaf-change, and shared-change runs.",
          "acceptanceCriteria": [
            "The report records machine context, fixture revision, task counts, cache hits, and wall-clock timings.",
            "Each incremental result is compared with the full-check result for the same input state.",
            "A deliberate shared-type error fails both workflows and is never reported as a valid cache hit."
          ],
          "implementationNotes": [
            "Present measured numbers with run count and variability.",
            "Avoid a hard speed claim based on one run."
          ],
          "verification": [
            "Run the documented matrix from an empty cache and reproduce task selection.",
            "Introduce a dependent type error and confirm the benchmark records failed correctness before reporting speed."
          ],
          "deliverables": [
            "Benchmark script and correctness-first comparison report"
          ],
          "rollout": "Adopt skipped-task execution only after parity is demonstrated; retain a scheduled full-check path as a diagnostic baseline.",
          "skills": [
            "Benchmarking",
            "Experimental design",
            "Build correctness"
          ],
          "fieldMix": [
            {
              "field": "Performance engineering",
              "percentage": 50
            },
            {
              "field": "Developer tooling",
              "percentage": 30
            },
            {
              "field": "Quality engineering",
              "percentage": 20
            }
          ],
          "patterns": []
        }
      ]
    }
  ]
}
