{
  "repo": "core",
  "version": "7.15.0",
  "from": "2835a37e2b956c9f08346117877f68025f68f2a8",
  "to": "v7.15.0",
  "added": [
    {
      "name": "ShellGateDoctrine",
      "kind": "type",
      "tier": "advanced",
      "at": [
        "src/core/task-spec.ts:47",
        "src/core/types.ts:22",
        "src/index.ts:3189"
      ],
      "criteriaCovered": false,
      "breaking": false
    },
    {
      "name": "bashReadBoundaryProbe",
      "kind": "function",
      "tier": "advanced",
      "at": [
        "src/index.ts:512",
        "src/tools/fs/fs-bash.ts:376"
      ],
      "criteriaCovered": false,
      "breaking": false
    }
  ],
  "removed": [],
  "changed": [],
  "narrowed": [
    {
      "id": "F1",
      "source": "behaviorFlips.summary",
      "text": "#696 (P1; ruling: follow CC 2.1.250, where the read boundary is a property of the path layer judged on every shell call and the shell doctrine only decides the residual risk) — a behaviour NARROWING on one lane: the read boundary is judged on every Bash/Monitor call under every `shellGate` doctrine: the shell seat installs `bashReadBoundaryProbe` (boundary-only; new export) under absent/\"off\" and `bashReversibilityProbe` (boundary ∘ shape classifier) under \"classify\"; Bash/Monitor carry the \"maybe\" tier and the seat provenance under every doctrine; `RiskDescriptor.shellGateDoctrine` widens to `\"off\" | \"classify\" | \"always\"`. Rules 3 → 2."
    },
    {
      "id": "F2",
      "source": "behaviorFlips.summary",
      "text": "#695 (ruling: match CC 2.1.250 unless a live measurement says otherwise; the measurement showed the engine's unconditional deferral of remote/`defer:true` tools costs +16–20% over inlining) — a NARROWING of a shape consumers could depend on (\"a remote tool is always a placeholder\"): deferred tool disclosure becomes two rules: the caller's literal lists (`deferTools` always deferred, `alwaysLoad` always inline, neither measured) and ONE threshold gate over the engine's own candidates (`ToolSpec.defer:true`, MCP/A2A protocol names, built-in self-declared defer) — open iff their combined inlined size ≥ 10% of the model's context (chars = floor(ctx×0.1)×3), all-or-nothing; `deferMode:\"auto\"` (value domain unchanged) only widens the candidate set to every caller spec under the same gate. MCP resource helpers are never deferred. Rules 8 → 2."
    }
  ],
  "closedSetMembers": [
    {
      "set": "ShellGateDoctrine",
      "at": [
        "src/core/task-spec.ts:47"
      ],
      "newSet": true,
      "added": [
        "always",
        "classify",
        "off"
      ],
      "removed": [],
      "breaking": false,
      "criteriaCovered": false
    }
  ],
  "typeKeys": [],
  "declarationMoves": [
    {
      "name": "classifyDeferred",
      "kind": null,
      "onSurface": false,
      "from": [
        "src/core/runner/tool-disclosure.ts"
      ],
      "to": [
        "src/core/runner/tool-defer-gate.ts"
      ]
    }
  ],
  "mintMoves": [],
  "criteriaObserves": [
    {
      "kind": "taskEventField",
      "name": "tool_end.gate",
      "assertions": [
        "G1.a",
        "G3.a",
        "G6.a",
        "G7.a",
        "G8.a",
        "G12.a"
      ]
    },
    {
      "kind": "taskEventField",
      "name": "tool_end.isError",
      "assertions": [
        "G2.a"
      ]
    },
    {
      "kind": "typeMember",
      "name": "AskRequest.ruleOffersAbsence",
      "assertions": [
        "G1.a",
        "G2.a",
        "G4.a",
        "G5.a",
        "G6.a"
      ]
    },
    {
      "kind": "typeMember",
      "name": "RiskDescriptor.shellGateDoctrine",
      "assertions": [
        "G10.a",
        "G11.a",
        "G21.a"
      ]
    },
    {
      "kind": "typeMember",
      "name": "RunnerDeps.deferMode",
      "assertions": [
        "G17.a",
        "G19.a",
        "G20.a"
      ]
    },
    {
      "kind": "typeMember",
      "name": "RunnerDeps.onError",
      "assertions": [
        "G9.a"
      ]
    },
    {
      "kind": "typeMember",
      "name": "TaskResult.terminal",
      "assertions": [
        "G17.a"
      ]
    },
    {
      "kind": "typeMember",
      "name": "TaskSpec.alwaysLoadTools",
      "assertions": [
        "G15.a"
      ]
    },
    {
      "kind": "typeMember",
      "name": "TaskSpec.deferTools",
      "assertions": [
        "G13.a",
        "G14.a",
        "G16.a",
        "G18.a"
      ]
    },
    {
      "kind": "typeMember",
      "name": "TaskSpec.shellGate",
      "assertions": [
        "G21.a"
      ]
    }
  ],
  "consumersHint": {
    "cli": [],
    "server": [],
    "sdk": [],
    "note": "scanned cli@27ec504d server@b603e2b2 sdk@557dfdf — a name listed is MENTIONED there today, which is evidence of consumption, not proof of it"
  },
  "breakingCount": 0,
  "breakingItems": [],
  "toResolvedAt": "f470a0190955815e8be90ac7640a5fa3e0a9a027"
}
