{
  "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": [
    {
      "key": "SFFI",
      "title": "Stabilize a native compression boundary before wider adoption",
      "field": "Systems programming",
      "summary": "Design a safe FFI contract with explicit ownership, error mapping and compatibility.",
      "context": "A fictional desktop backup tool calls a small Rust compression library from Node.js. The binding leaks buffers on exceptions and treats ABI mismatches as corrupted input. Build against generated byte arrays and a local native library; no production archive format or user files are supplied.",
      "stack": [
        "Rust",
        "C ABI",
        "Node-API",
        "Sanitizers"
      ],
      "prerequisites": [
        "FFI ownership",
        "Binary compatibility",
        "Error handling"
      ],
      "developerValue": "Practice language-boundary contracts, native resource safety and version negotiation.",
      "companyValue": "Review a binding that fails safely and can be rolled back before native code enters additional application paths.",
      "delivery": "Ten linked tickets across three phases. Use synthetic inputs and a local harness; provide source, focused tests, measurements where requested, and a recovery note.",
      "phases": [
        {
          "id": "model",
          "title": "Establish the machine contract",
          "goal": "Make representation, ownership and failure boundaries explicit."
        },
        {
          "id": "control",
          "title": "Control resources and concurrency",
          "goal": "Implement bounded behavior under realistic interleavings."
        },
        {
          "id": "operate",
          "title": "Prove recovery and handoff",
          "goal": "Measure, diagnose and safely replace the component."
        }
      ],
      "tickets": [
        {
          "id": "29836321-c28f-4edc-953d-d714bfc57ed7",
          "key": "SFFI-101",
          "title": "Write the buffer ownership table before exposing the binding",
          "type": "TASK",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 90,
          "phaseId": "model",
          "dependsOn": [],
          "scenario": "JavaScript and Rust both believe the other side frees an output buffer when conversion throws.",
          "acceptanceCriteria": [
            "Document owner for every input, output, error, and callback value",
            "Each transfer has one release operation and allowed thread",
            "Borrowed memory cannot outlive its originating call"
          ],
          "implementationNotes": [
            "Do not infer ownership from constness or language garbage collection."
          ],
          "verification": [
            "Trace success and error paths through the ownership table.",
            "Inject failure after native allocation and verify exactly one release."
          ],
          "deliverables": [
            "FFI ownership contract and allocation counter test"
          ],
          "rollout": "Keep the pure-language fallback until every path has an owner.",
          "skills": [
            "FFI",
            "Ownership",
            "Resource cleanup"
          ],
          "fieldMix": [
            {
              "field": "Systems programming",
              "percentage": 70
            },
            {
              "field": "Developer tooling",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "3a048c85-03f3-4afc-91d9-ee3132f6b96b",
          "key": "SFFI-102",
          "title": "Validate lengths before converting JavaScript buffers",
          "type": "BUG",
          "priority": "MEDIUM",
          "difficulty": "FOUNDATIONAL",
          "estimateMinutes": 90,
          "phaseId": "model",
          "dependsOn": [],
          "scenario": "A signed length crosses the C boundary and becomes a very large unsigned value.",
          "acceptanceCriteria": [
            "Binding rejects lengths outside the actual buffer and native type range",
            "Zero-length input follows a documented contract",
            "Conversion failure calls no compression function"
          ],
          "implementationNotes": [
            "Perform validation on the boundary side that has both pointer and buffer length."
          ],
          "verification": [
            "Compress empty, small, and maximum-fixture buffers.",
            "Pass negative-equivalent, oversized, and detached buffers and verify rejection."
          ],
          "deliverables": [
            "Length checks and boundary corpus"
          ],
          "rollout": "Reject unsupported buffers before enabling the native path.",
          "skills": [
            "Integer conversion",
            "Input validation"
          ],
          "fieldMix": [
            {
              "field": "Systems programming",
              "percentage": 70
            },
            {
              "field": "Security",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "5b585a37-bb44-45bd-88a3-319c45e55124",
          "key": "SFFI-103",
          "title": "Map native errors without losing machine-readable causes",
          "type": "STORY",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 150,
          "phaseId": "model",
          "dependsOn": [
            "SFFI-101",
            "SFFI-102"
          ],
          "scenario": "Every nonzero native status becomes 'compression failed', hiding whether the caller supplied bad input or the allocator exhausted its cap.",
          "acceptanceCriteria": [
            "Stable public codes distinguish input, capacity, version, cancellation, and internal faults",
            "Native diagnostic text is bounded and treated as untrusted",
            "Unknown statuses map to one safe internal category"
          ],
          "implementationNotes": [
            "Do not include raw input bytes or native addresses in errors."
          ],
          "verification": [
            "Trigger and map each declared native status.",
            "Return an unknown status with oversized text and verify bounded safe mapping."
          ],
          "deliverables": [
            "Versioned error map and contract tests"
          ],
          "rollout": "Callers must stop branching on old free-form messages before migration.",
          "skills": [
            "Error contracts",
            "Boundary validation"
          ],
          "fieldMix": [
            {
              "field": "Systems programming",
              "percentage": 70
            },
            {
              "field": "API design",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "4b7c64ca-603f-4dcc-a608-61d08e41aac1",
          "key": "SFFI-104",
          "title": "Release native output after JavaScript cancellation",
          "type": "CHORE",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 150,
          "phaseId": "control",
          "dependsOn": [
            "SFFI-101",
            "SFFI-103"
          ],
          "scenario": "The caller abandons a promise while native work finishes later; its output buffer has no remaining JavaScript consumer and is leaked.",
          "acceptanceCriteria": [
            "Operation state records whether a result still has a consumer",
            "Late output is released on the native allocation thread or declared safe path",
            "Cancellation and completion races release once"
          ],
          "implementationNotes": [
            "Cancellation is cooperative; do not unload code while a native call is running."
          ],
          "verification": [
            "Cancel before start and after successful delivery.",
            "Race cancellation with native completion across repeated deterministic schedules."
          ],
          "deliverables": [
            "Cancellation cleanup protocol and race tests"
          ],
          "rollout": "Keep native concurrency at one until release counts reconcile.",
          "skills": [
            "Cancellation",
            "FFI cleanup",
            "Concurrency"
          ],
          "fieldMix": [
            {
              "field": "Systems programming",
              "percentage": 70
            },
            {
              "field": "Real-time systems",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "eec7179e-19df-4467-9b41-1fad48d4e812",
          "key": "SFFI-105",
          "title": "Move blocking compression off the JavaScript event loop",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 240,
          "phaseId": "control",
          "dependsOn": [
            "SFFI-102",
            "SFFI-104"
          ],
          "scenario": "A 50 MB synthetic buffer blocks timers and health checks because the binding invokes native compression synchronously.",
          "acceptanceCriteria": [
            "Large work runs in a bounded worker pool",
            "Completion returns on the expected runtime thread",
            "Queue saturation rejects before copying the full input"
          ],
          "implementationNotes": [
            "Measure copy cost separately from compression time and cap fixture size."
          ],
          "verification": [
            "Compress concurrent small and large buffers while measuring timer delay.",
            "Saturate the pool and confirm bounded memory with a typed overload result."
          ],
          "deliverables": [
            "Asynchronous binding and event-loop latency report"
          ],
          "rollout": "Route buffers above a measured threshold first and retain synchronous fallback for small fixtures.",
          "skills": [
            "Async runtimes",
            "Performance",
            "Backpressure"
          ],
          "fieldMix": [
            {
              "field": "Systems programming",
              "percentage": 60
            },
            {
              "field": "Performance engineering",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "396819f7-5b29-4ebd-a397-fb9c5528458a",
          "key": "SFFI-106",
          "title": "Negotiate ABI capability before the first compression call",
          "type": "BUG",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 240,
          "phaseId": "control",
          "dependsOn": [
            "SFFI-103"
          ],
          "scenario": "A newer binding calls an option function missing from the loaded native library and the process terminates during symbol resolution.",
          "acceptanceCriteria": [
            "Initialization reads ABI version and explicit capability bits",
            "Unsupported required capabilities fail before accepting work",
            "Optional capabilities have documented fallback behavior"
          ],
          "implementationNotes": [
            "Do not infer ABI compatibility from package version or filename alone."
          ],
          "verification": [
            "Load current and compatible older fixture libraries.",
            "Load a library missing a required symbol and fail closed before dispatch."
          ],
          "deliverables": [
            "ABI handshake and compatibility matrix"
          ],
          "rollout": "Probe in startup readiness while the pure-language provider remains selectable.",
          "skills": [
            "ABI versioning",
            "Feature negotiation"
          ],
          "fieldMix": [
            {
              "field": "Systems programming",
              "percentage": 70
            },
            {
              "field": "Platform engineering",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "87030659-88f7-4949-b29d-d66a46121f58",
          "key": "SFFI-107",
          "title": "Contain a native panic without pretending the process is safe",
          "type": "STORY",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 360,
          "phaseId": "control",
          "dependsOn": [
            "SFFI-103",
            "SFFI-106"
          ],
          "scenario": "Malformed options trigger a Rust panic that crosses the C ABI and aborts the Node process.",
          "acceptanceCriteria": [
            "FFI entry points catch supported unwind cases before the ABI boundary",
            "Panic maps to an internal fault with operation identity",
            "Abort-configured builds are identified and isolated out of process"
          ],
          "implementationNotes": [
            "Do not claim catch_unwind protects memory after arbitrary native corruption."
          ],
          "verification": [
            "Trigger a controlled recoverable panic and map its result.",
            "Select an aborting fixture provider and require process-isolation policy instead of in-process execution."
          ],
          "deliverables": [
            "Panic-boundary policy and controlled failure fixtures"
          ],
          "rollout": "Keep risky codecs behind an external process provider until their failure mode is qualified.",
          "skills": [
            "Panic safety",
            "Isolation boundaries",
            "FFI"
          ],
          "fieldMix": [
            {
              "field": "Systems programming",
              "percentage": 60
            },
            {
              "field": "Security",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "42d20473-5374-4d91-8310-aa483334b13f",
          "key": "SFFI-108",
          "title": "Compare native output against the compatibility oracle",
          "type": "CHORE",
          "priority": "HIGH",
          "difficulty": "ADVANCED",
          "estimateMinutes": 240,
          "phaseId": "operate",
          "dependsOn": [
            "SFFI-105",
            "SFFI-106"
          ],
          "scenario": "The native path is faster but emits archives the existing decompressor accepts differently around empty blocks.",
          "acceptanceCriteria": [
            "Golden corpus defines byte compatibility or declared semantic compatibility",
            "Both providers round-trip every supported case",
            "Differences are classified before rollout"
          ],
          "implementationNotes": [
            "Use generated non-sensitive bytes and pin provider versions in the report."
          ],
          "verification": [
            "Compare providers across corpus sizes and option combinations.",
            "Inject a one-byte divergence and show the gate blocks promotion."
          ],
          "deliverables": [
            "Differential harness and compatibility report"
          ],
          "rollout": "Canary only corpus classes with reconciled outputs.",
          "skills": [
            "Differential testing",
            "Compatibility"
          ],
          "fieldMix": [
            {
              "field": "Systems programming",
              "percentage": 70
            },
            {
              "field": "Quality engineering",
              "percentage": 30
            }
          ],
          "patterns": []
        },
        {
          "id": "13e8f702-7568-48d6-a393-595f2461f97b",
          "key": "SFFI-109",
          "title": "Unload a retired native revision only after callbacks drain",
          "type": "TASK",
          "priority": "HIGH",
          "difficulty": "EXPERT",
          "estimateMinutes": 360,
          "phaseId": "operate",
          "dependsOn": [
            "SFFI-104",
            "SFFI-106"
          ],
          "scenario": "Hot replacement unloads the old library while an asynchronous completion callback still points into its code.",
          "acceptanceCriteria": [
            "Each operation pins one library revision through callback completion",
            "Retirement blocks new calls and observes active reference count",
            "Deadline reports unresolved references without forced unload"
          ],
          "implementationNotes": [
            "Prefer process restart for platforms that cannot guarantee safe dynamic unloading."
          ],
          "verification": [
            "Run old and new revisions concurrently, then retire the old after drain.",
            "Hold one completion callback and verify unload does not occur at the deadline."
          ],
          "deliverables": [
            "Revision lifetime protocol and delayed-callback test"
          ],
          "rollout": "Use process replacement as the default until in-process retirement is proven for the target platform.",
          "skills": [
            "Dynamic libraries",
            "Reference lifetimes",
            "Safe rollout"
          ],
          "fieldMix": [
            {
              "field": "Systems programming",
              "percentage": 60
            },
            {
              "field": "Platform engineering",
              "percentage": 40
            }
          ],
          "patterns": []
        },
        {
          "id": "4337ba99-6c9a-4940-bc4f-6ed2ea1218a4",
          "key": "SFFI-110",
          "title": "Package the native binding with a reversible compatibility gate",
          "type": "BUG",
          "priority": "MEDIUM",
          "difficulty": "INTERMEDIATE",
          "estimateMinutes": 150,
          "phaseId": "operate",
          "dependsOn": [
            "SFFI-107",
            "SFFI-108",
            "SFFI-109"
          ],
          "scenario": "A package publish selects the native binary by platform name but ignores CPU features and libc compatibility.",
          "acceptanceCriteria": [
            "Artifact metadata binds OS, architecture, ABI, runtime, and required CPU features",
            "Installer rejects an incompatible binary before load",
            "Pure-language fallback selection is explicit and observable"
          ],
          "implementationNotes": [
            "Do not download or execute binaries outside the generated local fixture set."
          ],
          "verification": [
            "Select each compatible fixture artifact and report its identity.",
            "Present wrong architecture, ABI, and feature metadata and verify safe fallback."
          ],
          "deliverables": [
            "Artifact selector, compatibility cases, and rollback note"
          ],
          "rollout": "Publish metadata and fallback behavior before enabling native-by-default selection.",
          "skills": [
            "Packaging",
            "Compatibility",
            "Release engineering"
          ],
          "fieldMix": [
            {
              "field": "Systems programming",
              "percentage": 70
            },
            {
              "field": "DevOps",
              "percentage": 30
            }
          ],
          "patterns": []
        }
      ],
      "id": "00ad18d5-9ac5-4716-888c-62e97c908b90"
    }
  ]
}
