{
  "schema_version": "0.5",
  "generated_at": "2026-08-02T19:45:00+08:00",
  "stats": {
    "public_cases": 6,
    "validated_units": 5,
    "patterns": 3,
    "classification_revisions": 3,
    "withheld": 2
  },
  "by_state": {
    "validated": 4,
    "unresolved": 1,
    "regressed": 1
  },
  "by_lens": {
    "dependency": 3,
    "developer": 3,
    "test": 3,
    "user": 2,
    "architecture": 2,
    "ai-generation": 1,
    "operations": 1,
    "framework": 1
  },
  "by_facet": {
    "what": 4,
    "why": 4,
    "where": 1,
    "under": 3,
    "state": 2,
    "when": 2
  },
  "cases": [
    {
      "id": "BC-0001",
      "app": "todo-app",
      "title": "Optimistic mutation does not roll back on failure",
      "state": "validated",
      "summary": "An item added optimistically stays on screen after the remote write returns HTTP 500. The list and the server disagree, and nothing tells the user.",
      "origin": "ai_generated",
      "ai": {
        "provider": "anthropic",
        "model": "claude-opus-5",
        "agent": "claude-code"
      },
      "created_at": "2026-08-01T12:00:00+08:00",
      "updated_at": "2026-08-01T12:35:00+08:00",
      "classifications": [
        {
          "facet": "what",
          "lens": "user",
          "value": "stale-ui",
          "confidence": 0.99,
          "valid_from": "2026-08-01T12:02:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": "human",
          "evidence_refs": [
            "EV-0001"
          ],
          "notes": null
        },
        {
          "facet": "why",
          "lens": "runtime",
          "value": "race-condition",
          "confidence": 0.42,
          "valid_from": "2026-08-01T12:05:00+08:00",
          "valid_to": "2026-08-01T12:22:00+08:00",
          "current": false,
          "superseded_by": null,
          "classifier": "ai",
          "evidence_refs": [
            "EV-0001"
          ],
          "notes": "First reading: two writes assumed to interleave."
        },
        {
          "facet": "why",
          "lens": "ai-generation",
          "value": "omitted-failure-path",
          "confidence": 0.92,
          "valid_from": "2026-08-01T12:22:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": "ai",
          "evidence_refs": [
            "EV-0002",
            "EV-0003"
          ],
          "notes": "Replaces CL-0001. The generated code models the success path only; there is no interleaving to race."
        },
        {
          "facet": "where",
          "lens": "architecture",
          "value": "transaction-boundary",
          "confidence": 0.84,
          "valid_from": "2026-08-01T12:24:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": "ai",
          "evidence_refs": [
            "EV-0002"
          ],
          "notes": null
        },
        {
          "facet": "under",
          "lens": "dependency",
          "value": "any-async-transport",
          "confidence": 0.71,
          "valid_from": "2026-08-01T12:30:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": "ai",
          "evidence_refs": [
            "EV-0003"
          ],
          "notes": null
        }
      ],
      "revisions": 1,
      "lenses": [
        "ai-generation",
        "architecture",
        "dependency",
        "runtime",
        "user"
      ],
      "perspectives": [
        {
          "lens": "user",
          "description": "The item is on the list. Reload and it is gone. Nothing said the save failed.",
          "confidence": 0.99
        },
        {
          "lens": "runtime",
          "description": "The mutation promise rejects. The rejection is caught and logged, and the local store is never touched again.",
          "confidence": 0.95
        },
        {
          "lens": "architecture",
          "description": "Local state was written before the remote write was known to succeed, and no compensating action exists for the failure branch.",
          "confidence": 0.88
        },
        {
          "lens": "ai-generation",
          "description": "The generated handler covers the success path in full and the failure path only as a log line — the shape you get when the prompt describes what should happen and not what happens when it does not.",
          "confidence": 0.9
        }
      ],
      "hypotheses": [
        {
          "hypothesis_id": "HY-0001",
          "statement": "Two concurrent writes interleave and the later one wins.",
          "status": "refuted",
          "refuted_by": [
            "EV-0002"
          ],
          "notes": "Reproduced with a single write. The failure needs no concurrency at all."
        },
        {
          "hypothesis_id": "HY-0002",
          "statement": "The error handler never restores the pre-mutation state.",
          "status": "supported",
          "supported_by": [
            "EV-0002",
            "EV-0003"
          ]
        }
      ],
      "evidence": [
        {
          "evidence_id": "EV-0001",
          "kind": "reproduction",
          "description": "Forced POST /todos to return HTTP 500. The optimistic row stayed visible; a reload removed it.",
          "captured_at": "2026-08-01T12:02:00+08:00"
        },
        {
          "evidence_id": "EV-0002",
          "kind": "execution",
          "description": "Single sequential write, no concurrency. Same outcome — refutes the race hypothesis.",
          "captured_at": "2026-08-01T12:20:00+08:00",
          "contradicts": [
            "HY-0001"
          ]
        },
        {
          "evidence_id": "EV-0003",
          "kind": "test_result",
          "description": "Regression test fails against pre and passes against post.",
          "captured_at": "2026-08-01T12:33:00+08:00"
        }
      ],
      "patches": [
        {
          "patch_id": "PA-0001",
          "status": "rejected",
          "summary": "Disable the optimistic update entirely.",
          "notes": "Rejected: removes the behaviour instead of completing it, and the latency it hid is real."
        },
        {
          "patch_id": "PA-0002",
          "status": "accepted",
          "summary": "Restore the captured previous state inside the async error handler."
        }
      ],
      "timeline": [
        {
          "at": "2026-08-01T12:00:00+08:00",
          "state": "captured",
          "text": "HTTP 500 reproduced with the optimistic item still on screen."
        },
        {
          "at": "2026-08-01T12:05:00+08:00",
          "state": "investigating",
          "text": "First reading: a race between two writes."
        },
        {
          "at": "2026-08-01T12:20:00+08:00",
          "state": "reproduced",
          "text": "Single-write reproduction refutes the race."
        },
        {
          "at": "2026-08-01T12:22:00+08:00",
          "state": "localized",
          "text": "The failure branch never restores state. Classification revised."
        },
        {
          "at": "2026-08-01T12:28:00+08:00",
          "state": "patched",
          "text": "First patch rejected; second attaches a rollback."
        },
        {
          "at": "2026-08-01T12:33:00+08:00",
          "state": "validation-pending",
          "text": "Regression test attached."
        },
        {
          "at": "2026-08-01T12:35:00+08:00",
          "state": "validated",
          "text": "pre failed, post passed."
        }
      ],
      "relations": [
        {
          "predicate": "manifested_as",
          "object": {
            "type": "BugEvent",
            "id": "BE-0001"
          }
        },
        {
          "predicate": "same_root_as",
          "object": {
            "type": "BugUnit",
            "id": "BU-0003"
          }
        }
      ],
      "unit_id": "BU-0001"
    },
    {
      "id": "BC-0002",
      "app": "notes-sync",
      "title": "Retry storm on a dependency that is already down",
      "state": "unresolved",
      "summary": "A bounded-looking retry has no budget across callers, so a single upstream outage multiplies into a self-inflicted load spike.",
      "origin": "human_ai_coproduced",
      "ai": {
        "provider": "anthropic",
        "model": "claude-opus-5",
        "agent": "claude-code"
      },
      "created_at": "2026-08-01T15:10:00+08:00",
      "updated_at": "2026-08-02T08:40:00+08:00",
      "classifications": [
        {
          "facet": "what",
          "lens": "operations",
          "value": "load-amplification",
          "confidence": 0.88,
          "valid_from": "2026-08-01T15:20:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": "human",
          "evidence_refs": [
            "EV-0010"
          ],
          "notes": null
        },
        {
          "facet": "why",
          "lens": "architecture",
          "value": "retry-without-budget",
          "confidence": 0.79,
          "valid_from": "2026-08-01T15:40:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": "ai",
          "evidence_refs": [
            "EV-0011"
          ],
          "notes": null
        },
        {
          "facet": "state",
          "lens": "developer",
          "value": "unresolved-by-design",
          "confidence": 0.6,
          "valid_from": "2026-08-02T08:40:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": "human",
          "evidence_refs": [],
          "notes": "Kept open on purpose. A fix that only adds backoff here would move the amplification one layer out."
        }
      ],
      "revisions": 0,
      "lenses": [
        "architecture",
        "developer",
        "operations"
      ],
      "perspectives": [
        {
          "lens": "operations",
          "description": "Request volume to the failing dependency rises during the outage rather than falling.",
          "confidence": 0.93
        },
        {
          "lens": "architecture",
          "description": "Each caller retries correctly in isolation. There is no shared budget, so correctness at each layer composes into failure.",
          "confidence": 0.8
        }
      ],
      "hypotheses": [
        {
          "hypothesis_id": "HY-0010",
          "statement": "Adding jittered backoff at the client resolves it.",
          "status": "open",
          "notes": "Suspected insufficient: it slows the storm without bounding total attempts."
        }
      ],
      "evidence": [
        {
          "evidence_id": "EV-0010",
          "kind": "metric",
          "description": "Upstream request rate rose 6.2x during a 90-second dependency outage.",
          "captured_at": "2026-08-01T15:18:00+08:00"
        },
        {
          "evidence_id": "EV-0011",
          "kind": "observation",
          "description": "Three independent call sites each retry three times; none is aware of the others.",
          "captured_at": "2026-08-01T15:38:00+08:00"
        }
      ],
      "patches": [],
      "timeline": [
        {
          "at": "2026-08-01T15:10:00+08:00",
          "state": "captured",
          "text": "Outage produced more traffic, not less."
        },
        {
          "at": "2026-08-01T15:20:00+08:00",
          "state": "triaged",
          "text": "Classified as load amplification."
        },
        {
          "at": "2026-08-01T15:40:00+08:00",
          "state": "investigating",
          "text": "Three retry sites found, no shared budget."
        },
        {
          "at": "2026-08-02T08:40:00+08:00",
          "state": "unresolved",
          "text": "Left open deliberately — a local fix would relocate the problem."
        }
      ],
      "relations": [
        {
          "predicate": "co_occurs_with",
          "object": {
            "type": "BugCase",
            "id": "BC-0001"
          }
        }
      ],
      "unit_id": null
    },
    {
      "id": "BC-0003",
      "app": "doc-pipeline",
      "title": "Previously-correct parser broke on a dependency minor release",
      "state": "validated",
      "summary": "No code changed. A transitive dependency tightened its date parsing in a minor release and a previously-passing path began rejecting valid input.",
      "origin": "environment_drift",
      "ai": null,
      "created_at": "2026-07-30T09:00:00+08:00",
      "updated_at": "2026-07-30T11:20:00+08:00",
      "classifications": [
        {
          "facet": "why",
          "lens": "developer",
          "value": "our-code-regressed",
          "confidence": 0.55,
          "valid_from": "2026-07-30T09:10:00+08:00",
          "valid_to": "2026-07-30T09:40:00+08:00",
          "current": false,
          "superseded_by": null,
          "classifier": "human",
          "evidence_refs": [],
          "notes": "The first assumption whenever something that worked stops working."
        },
        {
          "facet": "when",
          "lens": "dependency",
          "value": "introduced-by-upstream-minor",
          "confidence": 0.95,
          "valid_from": "2026-07-30T09:40:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": "tool",
          "evidence_refs": [
            "EV-0020"
          ],
          "notes": null
        },
        {
          "facet": "under",
          "lens": "dependency",
          "value": "context-dependent-defect",
          "confidence": 0.91,
          "valid_from": "2026-07-30T09:40:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": "ai",
          "evidence_refs": [
            "EV-0020",
            "EV-0021"
          ],
          "notes": "The same source is correct under the old resolution and incorrect under the new one."
        }
      ],
      "revisions": 1,
      "lenses": [
        "dependency",
        "developer"
      ],
      "perspectives": [
        {
          "lens": "developer",
          "description": "git blame points at code that has not changed in eight months.",
          "confidence": 0.99
        },
        {
          "lens": "dependency",
          "description": "The behaviour lives in the resolved version, not in the declared range. The range never changed; what it resolves to did.",
          "confidence": 0.94
        }
      ],
      "hypotheses": [
        {
          "hypothesis_id": "HY-0020",
          "statement": "A recent commit introduced it.",
          "status": "refuted",
          "refuted_by": [
            "EV-0020"
          ]
        }
      ],
      "evidence": [
        {
          "evidence_id": "EV-0020",
          "kind": "diff",
          "description": "Lockfile diff: the only change in the failing window is a transitive minor bump.",
          "captured_at": "2026-07-30T09:35:00+08:00",
          "contradicts": [
            "HY-0020"
          ]
        },
        {
          "evidence_id": "EV-0021",
          "kind": "execution",
          "description": "Pinning the previous resolved version makes the same source pass unchanged.",
          "captured_at": "2026-07-30T10:05:00+08:00"
        }
      ],
      "patches": [
        {
          "patch_id": "PA-0020",
          "status": "accepted",
          "summary": "Normalise the input format at the boundary rather than pinning the dependency."
        }
      ],
      "timeline": [
        {
          "at": "2026-07-30T09:00:00+08:00",
          "state": "captured",
          "text": "A path that passed yesterday now rejects valid input."
        },
        {
          "at": "2026-07-30T09:10:00+08:00",
          "state": "investigating",
          "text": "Assumed to be our regression."
        },
        {
          "at": "2026-07-30T09:40:00+08:00",
          "state": "localized",
          "text": "Lockfile diff refutes it. Classification revised to environment drift."
        },
        {
          "at": "2026-07-30T11:20:00+08:00",
          "state": "validated",
          "text": "Boundary normalisation: pre failed, post passed."
        }
      ],
      "relations": [
        {
          "predicate": "introduced_by",
          "object": {
            "type": "Dependency",
            "id": "upstream-date-parser@2.4.0"
          }
        }
      ],
      "unit_id": "BU-0002"
    },
    {
      "id": "BC-0005",
      "app": "todo-app",
      "title": "Validated fix regressed after a framework upgrade",
      "state": "regressed",
      "summary": "BU-0001's rollback stopped firing after a framework upgrade changed when error boundaries run. Validated is not permanent.",
      "origin": "environment_drift",
      "ai": null,
      "created_at": "2026-08-02T08:00:00+08:00",
      "updated_at": "2026-08-02T08:55:00+08:00",
      "classifications": [
        {
          "facet": "state",
          "lens": "test",
          "value": "regressed-after-upgrade",
          "confidence": 0.97,
          "valid_from": "2026-08-02T08:20:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": "ci",
          "evidence_refs": [
            "EV-0040"
          ],
          "notes": null
        },
        {
          "facet": "under",
          "lens": "framework",
          "value": "error-boundary-timing-change",
          "confidence": 0.82,
          "valid_from": "2026-08-02T08:50:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": "ai",
          "evidence_refs": [
            "EV-0041"
          ],
          "notes": null
        }
      ],
      "revisions": 0,
      "lenses": [
        "framework",
        "test"
      ],
      "perspectives": [
        {
          "lens": "test",
          "description": "The regression test that gated BU-0001 fails again on current main.",
          "confidence": 0.99
        },
        {
          "lens": "framework",
          "description": "The upgrade moved error handling relative to the state commit, so the rollback now runs against state that has already been replaced.",
          "confidence": 0.8
        }
      ],
      "hypotheses": [
        {
          "hypothesis_id": "HY-0040",
          "statement": "The rollback is correct but now runs too late.",
          "status": "supported",
          "supported_by": [
            "EV-0041"
          ]
        }
      ],
      "evidence": [
        {
          "evidence_id": "EV-0040",
          "kind": "test_result",
          "description": "The BU-0001 regression test fails on current main.",
          "captured_at": "2026-08-02T08:20:00+08:00"
        },
        {
          "evidence_id": "EV-0041",
          "kind": "execution",
          "description": "Instrumented ordering shows the error handler running after the state commit, inverted from the validated build.",
          "captured_at": "2026-08-02T08:50:00+08:00"
        }
      ],
      "patches": [],
      "timeline": [
        {
          "at": "2026-08-02T08:00:00+08:00",
          "state": "captured",
          "text": "Regression suite went red on a case marked validated."
        },
        {
          "at": "2026-08-02T08:20:00+08:00",
          "state": "triaged",
          "text": "Confirmed against BU-0001's own gate test."
        },
        {
          "at": "2026-08-02T08:55:00+08:00",
          "state": "investigating",
          "text": "Ordering change located in the upgrade."
        }
      ],
      "relations": [
        {
          "predicate": "regressed_from",
          "object": {
            "type": "BugUnit",
            "id": "BU-0001"
          }
        }
      ],
      "unit_id": null
    },
    {
      "id": "BC-0006",
      "app": "thisoneisneok-mssp",
      "title": "The build counted and published bytecode as example source",
      "state": "validated",
      "summary": "Two build scripts walked every file under an example. The first Python example brought __pycache__ with it, so 176 lines of bytecode were counted as source and .pyc files were published to readers as part of the structure.",
      "origin": "ai_generated",
      "ai": {
        "provider": "anthropic",
        "model": "claude-opus-5",
        "agent": "claude-code"
      },
      "created_at": "2026-08-02T18:40:00+08:00",
      "updated_at": "2026-08-02T19:05:00+08:00",
      "classifications": [
        {
          "facet": "what",
          "lens": "developer",
          "value": "build-artifact-published-as-source",
          "confidence": 0.99,
          "valid_from": "2026-08-02T18:45:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": "human",
          "evidence_refs": [
            "EV-0060"
          ],
          "notes": null
        },
        {
          "facet": "why",
          "lens": "developer",
          "value": "language-specific-artifact-in-a-language-agnostic-walk",
          "confidence": 0.94,
          "valid_from": "2026-08-02T18:50:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": "ai",
          "evidence_refs": [
            "EV-0061"
          ],
          "notes": "The walk had no reason to exclude anything while every example was JavaScript."
        },
        {
          "facet": "when",
          "lens": "test",
          "value": "guaranteed-by-the-check-itself",
          "confidence": 0.97,
          "valid_from": "2026-08-02T18:52:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": "ai",
          "evidence_refs": [
            "EV-0061"
          ],
          "notes": "The build runs the example to verify it is runnable, which is what creates __pycache__. The defect could not be intermittent."
        }
      ],
      "revisions": 0,
      "lenses": [
        "developer",
        "test"
      ],
      "perspectives": [
        {
          "lens": "user",
          "description": "The published page listed .pyc files as part of the example's structure, next to the code a reader is meant to study.",
          "confidence": 0.95
        },
        {
          "lens": "developer",
          "description": "walk() collected every file it found. That was correct for four JavaScript examples and silently wrong for the first Python one.",
          "confidence": 0.98
        },
        {
          "lens": "test",
          "description": "The runnable check executes the example, so the artifact is produced by the same pass that then counts it.",
          "confidence": 0.96
        }
      ],
      "hypotheses": [
        {
          "hypothesis_id": "HY-0060",
          "statement": "A stale directory left over from an earlier manual run.",
          "status": "refuted",
          "refuted_by": [
            "EV-0061"
          ],
          "notes": "Deleting it and rebuilding reproduced it immediately — the build makes it."
        }
      ],
      "evidence": [
        {
          "evidence_id": "EV-0060",
          "kind": "tool_output",
          "description": "Reported 963 lines across 20 files; the actual source is 730 across 12. Seven .pyc files, 176 lines of bytecode counted as code.",
          "captured_at": "2026-08-02T18:42:00+08:00"
        },
        {
          "evidence_id": "EV-0061",
          "kind": "execution",
          "description": "Removed __pycache__, rebuilt: 730/12. Ran the example once, rebuilt: 963/20 again.",
          "captured_at": "2026-08-02T18:50:00+08:00",
          "contradicts": [
            "HY-0060"
          ]
        },
        {
          "evidence_id": "EV-0062",
          "kind": "test_result",
          "description": "After the fix, with six .pyc files present on disk, the count stays 730/12.",
          "captured_at": "2026-08-02T19:04:00+08:00"
        }
      ],
      "patches": [
        {
          "patch_id": "PA-0060",
          "status": "rejected",
          "summary": "Delete __pycache__ before each build.",
          "notes": "Rejected: treats the symptom on a schedule. The next artifact-producing language reintroduces it."
        },
        {
          "patch_id": "PA-0061",
          "status": "accepted",
          "summary": "Exclude build-artifact directories and compiled extensions in both walks."
        }
      ],
      "timeline": [
        {
          "at": "2026-08-02T18:40:00+08:00",
          "state": "captured",
          "text": "Example line count looked implausible against the files actually written."
        },
        {
          "at": "2026-08-02T18:45:00+08:00",
          "state": "reproduced",
          "text": "Seven .pyc files were being counted and published."
        },
        {
          "at": "2026-08-02T18:50:00+08:00",
          "state": "localized",
          "text": "The runnable check produces them, so they are guaranteed rather than incidental."
        },
        {
          "at": "2026-08-02T19:05:00+08:00",
          "state": "validated",
          "text": "Count unchanged with bytecode present."
        }
      ],
      "relations": [
        {
          "predicate": "co_occurs_with",
          "object": {
            "type": "BugCase",
            "id": "BC-0007"
          }
        }
      ],
      "unit_id": "BU-0005"
    },
    {
      "id": "BC-0007",
      "app": "thisoneisneok-mssp",
      "title": "Broken links in prose, invisible to a gate that checks a list",
      "state": "validated",
      "summary": "Three hand-written internal links across two days pointed at URLs the site does not publish. Each was guessed from where the source file lives rather than read from where its build script puts it. Ten deploy checks were green throughout.",
      "origin": "ai_generated",
      "ai": {
        "provider": "anthropic",
        "model": "claude-opus-5",
        "agent": "claude-code"
      },
      "created_at": "2026-08-02T19:10:00+08:00",
      "updated_at": "2026-08-02T19:35:00+08:00",
      "classifications": [
        {
          "facet": "what",
          "lens": "user",
          "value": "dead-internal-link",
          "confidence": 0.99,
          "valid_from": "2026-08-02T19:12:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": "human",
          "evidence_refs": [
            "EV-0070"
          ],
          "notes": null
        },
        {
          "facet": "why",
          "lens": "developer",
          "value": "url-inferred-from-source-path",
          "confidence": 0.7,
          "valid_from": "2026-08-02T19:14:00+08:00",
          "valid_to": "2026-08-02T19:22:00+08:00",
          "current": false,
          "superseded_by": null,
          "classifier": "ai",
          "evidence_refs": [
            "EV-0070"
          ],
          "notes": "First reading: a careless guess. True, and it does not explain why nothing caught it."
        },
        {
          "facet": "why",
          "lens": "test",
          "value": "the-gate-checks-a-list-and-a-prose-link-is-on-no-list",
          "confidence": 0.93,
          "valid_from": "2026-08-02T19:22:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": "ai",
          "evidence_refs": [
            "EV-0071"
          ],
          "notes": "Replaces CL-0071. Two of the three survived a full day and ten green deploy checks. The guess is the cause of one link; the absent axis is the cause of all three."
        }
      ],
      "revisions": 1,
      "lenses": [
        "developer",
        "test",
        "user"
      ],
      "perspectives": [
        {
          "lens": "user",
          "description": "A link in the development log went to a 404. Nothing on the page suggested it would.",
          "confidence": 0.99
        },
        {
          "lens": "test",
          "description": "The deploy gate verifies a list of URLs it is handed. A link written inside a page's prose never joins that list, so no amount of green says anything about it.",
          "confidence": 0.95
        },
        {
          "lens": "architecture",
          "description": "The URL a page publishes to is decided by its build script. Prose that names a URL is a second, hand-maintained copy of that decision.",
          "confidence": 0.9
        }
      ],
      "hypotheses": [
        {
          "hypothesis_id": "HY-0070",
          "statement": "One careless link, caught on the day.",
          "status": "refuted",
          "refuted_by": [
            "EV-0071"
          ],
          "notes": "Two of the three were written the previous day and had been live since."
        }
      ],
      "evidence": [
        {
          "evidence_id": "EV-0070",
          "kind": "observation",
          "description": "Three of 28 hand-written internal links returned 404 against the live site.",
          "captured_at": "2026-08-02T19:12:00+08:00"
        },
        {
          "evidence_id": "EV-0071",
          "kind": "observation",
          "description": "Two of the three shipped the previous day and survived ten green deploy checks.",
          "captured_at": "2026-08-02T19:20:00+08:00",
          "contradicts": [
            "HY-0070"
          ]
        },
        {
          "evidence_id": "EV-0072",
          "kind": "test_result",
          "description": "New check fails on a reinstated bad link and passes once removed; 28 links across 11 files resolve.",
          "captured_at": "2026-08-02T19:34:00+08:00"
        }
      ],
      "patches": [
        {
          "patch_id": "PA-0070",
          "status": "rejected",
          "summary": "Add the pages to the deploy gate's URL list.",
          "notes": "Rejected: extends the list, which is the thing that cannot see a link nobody added to it."
        },
        {
          "patch_id": "PA-0071",
          "status": "accepted",
          "summary": "Resolve every hand-written link against the built output, offline, before deploy."
        }
      ],
      "timeline": [
        {
          "at": "2026-08-02T19:10:00+08:00",
          "state": "captured",
          "text": "A link written minutes earlier returned 404."
        },
        {
          "at": "2026-08-02T19:14:00+08:00",
          "state": "investigating",
          "text": "Read as a one-off careless guess."
        },
        {
          "at": "2026-08-02T19:22:00+08:00",
          "state": "localized",
          "text": "Two more found, both a day old. The cause is a missing axis, not a slip."
        },
        {
          "at": "2026-08-02T19:35:00+08:00",
          "state": "validated",
          "text": "Check fails on a bad link, passes when fixed."
        }
      ],
      "relations": [
        {
          "predicate": "same_root_as",
          "object": {
            "type": "BugPattern",
            "id": "BP-0003"
          }
        }
      ],
      "unit_id": "BU-0006"
    }
  ],
  "units": [
    {
      "id": "BU-0001",
      "case_id": "BC-0001",
      "title": "Optimistic rollback omission",
      "status": "validated",
      "origin": "ai_generated",
      "canonical_description": "State written optimistically before a remote mutation is confirmed is not restored when the mutation fails, so the interface keeps showing a value the server never accepted.",
      "root_cause": "The failure branch of the async handler logs and returns without restoring the captured previous state.",
      "repair": "Capture the previous state before the optimistic write; restore it in the error branch.",
      "gate": {
        "status": "pass",
        "pre_fails": true,
        "post_passes": true,
        "validated_at": "2026-08-01T12:35:00+08:00",
        "validator": "ci"
      },
      "classifications": [
        {
          "facet": "what",
          "lens": "user",
          "value": "stale-ui",
          "confidence": 0.99,
          "valid_from": "2026-08-01T12:02:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": null,
          "evidence_refs": [],
          "notes": null
        },
        {
          "facet": "why",
          "lens": "ai-generation",
          "value": "omitted-failure-path",
          "confidence": 0.92,
          "valid_from": "2026-08-01T12:22:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": null,
          "evidence_refs": [],
          "notes": null
        }
      ],
      "patterns": [
        "BP-0001"
      ],
      "contested": "Currently contested by BC-0005: the gate test fails after a framework upgrade."
    },
    {
      "id": "BU-0002",
      "case_id": "BC-0003",
      "title": "Correct source, changed resolution",
      "status": "validated",
      "origin": "environment_drift",
      "canonical_description": "A defect can be introduced with no change to the project's own source, when a declared version range resolves to a different implementation than it did before.",
      "root_cause": "Input format assumptions lived in a transitive dependency rather than at the project's own boundary.",
      "repair": "Normalise at the boundary so the assumption is stated where it is owned.",
      "gate": {
        "status": "pass",
        "pre_fails": true,
        "post_passes": true,
        "validated_at": "2026-07-30T11:20:00+08:00",
        "validator": "ci"
      },
      "classifications": [
        {
          "facet": "when",
          "lens": "dependency",
          "value": "introduced-by-upstream-minor",
          "confidence": 0.95,
          "valid_from": "2026-07-30T09:40:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": null,
          "evidence_refs": [],
          "notes": null
        },
        {
          "facet": "under",
          "lens": "dependency",
          "value": "context-dependent-defect",
          "confidence": 0.91,
          "valid_from": "2026-07-30T09:40:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": null,
          "evidence_refs": [],
          "notes": null
        }
      ],
      "patterns": [
        "BP-0002"
      ],
      "contested": null
    },
    {
      "id": "BU-0003",
      "case_id": "BC-0001",
      "title": "Compensating action missing from a generated failure branch",
      "status": "validated",
      "origin": "ai_generated",
      "canonical_description": "Generated code that models a success path and treats the failure path as a log statement leaves the system without the compensating action the success path assumed.",
      "root_cause": "The specification given to the generator described the intended outcome and not the failure behaviour.",
      "repair": "State the compensating action in the specification, and test the failure branch as a first-class path.",
      "gate": {
        "status": "pass",
        "pre_fails": true,
        "post_passes": true,
        "validated_at": "2026-08-01T13:10:00+08:00",
        "validator": "hybrid"
      },
      "classifications": [
        {
          "facet": "why",
          "lens": "ai-generation",
          "value": "omitted-failure-path",
          "confidence": 0.9,
          "valid_from": "2026-08-01T13:10:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": null,
          "evidence_refs": [],
          "notes": null
        }
      ],
      "patterns": [
        "BP-0001"
      ],
      "contested": null
    },
    {
      "id": "BU-0005",
      "case_id": "BC-0006",
      "title": "A verification step that produces the artifact it then measures",
      "status": "validated",
      "origin": "ai_generated",
      "canonical_description": "When a check runs the thing it is checking, any artifact that run produces becomes part of what gets measured — reliably, not intermittently.",
      "root_cause": "A language-agnostic file walk in a pipeline whose verification step executes the code it walks.",
      "repair": "Exclude build-artifact directories and compiled extensions at the walk, not on a cleanup schedule.",
      "gate": {
        "status": "pass",
        "pre_fails": true,
        "post_passes": true,
        "validated_at": "2026-08-02T19:05:00+08:00",
        "validator": "human"
      },
      "classifications": [
        {
          "facet": "what",
          "lens": "developer",
          "value": "build-artifact-published-as-source",
          "confidence": 0.99,
          "valid_from": "2026-08-02T18:45:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": null,
          "evidence_refs": [],
          "notes": null
        }
      ],
      "patterns": [],
      "contested": null
    },
    {
      "id": "BU-0006",
      "case_id": "BC-0007",
      "title": "A gate over an enumeration cannot see what is not enumerated",
      "status": "validated",
      "origin": "ai_generated",
      "canonical_description": "A check that verifies a supplied list is silent about anything absent from the list, and its silence is indistinguishable from a pass.",
      "root_cause": "Correctness was asserted over an enumeration rather than derived from the artefact, so an item nobody enumerated was never a candidate for checking.",
      "repair": "Derive the set to be checked from the source of truth — here, every link in the prose against every path in the built output.",
      "gate": {
        "status": "pass",
        "pre_fails": true,
        "post_passes": true,
        "validated_at": "2026-08-02T19:35:00+08:00",
        "validator": "human"
      },
      "classifications": [
        {
          "facet": "why",
          "lens": "test",
          "value": "the-gate-checks-a-list-and-a-prose-link-is-on-no-list",
          "confidence": 0.93,
          "valid_from": "2026-08-02T19:22:00+08:00",
          "valid_to": null,
          "current": true,
          "superseded_by": null,
          "classifier": null,
          "evidence_refs": [],
          "notes": null
        }
      ],
      "patterns": [
        "BP-0003"
      ],
      "contested": null
    }
  ],
  "patterns": [
    {
      "id": "BP-0001",
      "name": "Incomplete async failure path",
      "status": "emerging",
      "description": "The success path is modelled in full; the asynchronous failure path omits the compensating action the success path made necessary.",
      "common_context": [
        "AI-assisted generation",
        "optimistic or local-first state",
        "remote mutation"
      ],
      "common_structure": [
        "state written before confirmation",
        "failure branch present but inert",
        "no test exercising the failure branch"
      ],
      "repair_family": [
        "capture-then-restore",
        "confirm-before-commit",
        "explicit compensating action"
      ],
      "known_exceptions": [
        "Fire-and-forget writes where divergence is acceptable and stated."
      ],
      "support": [
        "BU-0001",
        "BU-0003"
      ],
      "proposed_by": "ai"
    },
    {
      "id": "BP-0002",
      "name": "Defect introduced without a code change",
      "status": "candidate",
      "description": "The project's own source is unchanged and correct under its previous environment; what changed is what the environment resolves to.",
      "common_context": [
        "transitive dependency",
        "version range rather than pin",
        "long-lived path with no recent commits"
      ],
      "common_structure": [
        "git blame points at old, unchanged code",
        "lockfile or image digest is the only diff",
        "reverting the resolution restores the behaviour"
      ],
      "repair_family": [
        "normalise at the owned boundary",
        "pin with an explicit review date",
        "assert the assumption in a test"
      ],
      "known_exceptions": [
        "Genuine latent defects that the upgrade merely exposed — these need the older resolution to fail too."
      ],
      "support": [
        "BU-0002"
      ],
      "proposed_by": "human"
    },
    {
      "id": "BP-0003",
      "name": "An enumeration standing in for a rule",
      "status": "candidate",
      "description": "Correctness is asserted over a hand-maintained list instead of derived from the thing itself. Everything on the list is verified, so the checks are green; anything nobody added is unverified and indistinguishable from verified.",
      "common_context": [
        "a check written to cover known cases",
        "a list that has to be updated by whoever adds the next case",
        "green output that reports on the list rather than on the domain"
      ],
      "common_structure": [
        "the set under test is supplied, not derived",
        "adding a case requires remembering a second place",
        "a miss produces no signal at all, rather than a weaker one"
      ],
      "repair_family": [
        "derive the set from the artefact",
        "fail when the derived set is empty",
        "report what was covered, not only what passed"
      ],
      "known_exceptions": [
        "A genuinely closed set — a protocol's fixed verbs, an enum in a spec — where the list is the domain and cannot silently grow."
      ],
      "support": [
        "BU-0006"
      ],
      "proposed_by": "ai"
    }
  ]
}
