# ADR-0131.G.1 — Capability axis: state-introducing verb classes **Status:** Accepted **Date:** 2026-05-23 **Author:** CORE agents **Parent:** [ADR-0131.G](./ADR-0131.G-gsm8k-coverage-probe.md) --- ## Context ADR-0131.G introduced the GSM8K coverage probe to measure the capability of the bounded grammar layers while maintaining the safety rail (`wrong == 0`). This decision record details the first capability-axis iteration on top of the coverage probe (G.1), which extends the grammar parser to support a closed set of acquisition / action verbs that introduce quantity. ## Decision We recognize that sentences of the form ` ` can introduce a quantity without an explicit "has/have" possession verb. The verbs fall into two classes: ### Class A — Pure-possession anchors (initial-possession slot) Kept in `_INITIAL_HAS_RE`. These verbs have no semantic overlap with operation verbs and produce no candidate ambiguity: - `had` (past possession) - `started` / `started with` (opening state) ### Class B — Acquisition/action verbs (operation slot, add-kind) Handled exclusively as `add` operations in `ADD_VERBS` / `SUBTRACT_VERBS`. The solver defaults the actor's pre-operation state to **0** when no initial possession exists, so a single-statement sentence like `"Sam buys 5 apples."` resolves correctly as `0 + 5 = 5`. These verbs were *not* added to `_INITIAL_HAS_RE` because they also appear in the operation verb registry (`math_roundtrip.KIND_TO_VERBS`). Adding them to both registries causes **branch-disagreement refusals**: when a canonical "has" initial for entity E is followed by an acquisition sentence for the same E, the candidate-graph emitter produces two branches—one treating the acquisition as a second initial (wrong answer) and one treating it as an add operation (correct answer)—and the decision rule refuses on disagreement. | Verb | Operation kind | Already in verb registry | |------|---------------|--------------------------| | `buys` / `bought` | `add` | `ADD_VERBS` | | `collected` | `add` | `ADD_VERBS` | | `saved` / `saved up` | `add` | `ADD_VERBS` | | `makes` / `made` | `add` | `ADD_VERBS` | | `sells` / `sold` | `subtract` | `SUBTRACT_VERBS` | ### Code Changes 1. **`_INITIAL_HAS_RE` narrowed** to pure possession anchors only: `(?Phas|have|had|started)(?:\s+(?:up|with))?` 2. **`CandidateInitial.__post_init__`** validation updated to match the narrower set. 3. **Optional verb particle** added to `_op_pattern` between verb and value: `(?:\s+(?:up|down|out|back|off|in|away))?` This allows the operation regex to match `"saved up N"`, `"picked up N"`, etc. without listing particle-bearing forms as initial anchors. 4. **`ADD_VERBS` / `SUBTRACT_VERBS`** in `math_roundtrip.py` already include all Class B verbs—no changes required there. ## Out of Scope The following capabilities are explicitly deferred to sibling axes: - **Rate-introducing verbs:** Multipliers and rates (e.g. "makes $18 an hour") continue to refuse on this axis. - **Comparatives:** Multiplicative/additive comparison structures (e.g., "twice as many", "3 more than"). - **Acquisition-with-cost:** Transactional semantics (buying items at a given price). - **Multi-statement coreference.** ## Invariants - **`wrong == 0`**: Every evaluation run over both the G1 curated axis and the GSM8K probe must yield zero wrong answers. - **Closed Set**: No synonymous expansion or paraphrase tolerance beyond the enumerated verbs. - **Determinism**: Evaluator outputs must be byte-equal across consecutive runs. - **No initial/operation overlap**: Verbs that appear in `ADD_VERBS` or `SUBTRACT_VERBS` must not also appear in `_INITIAL_HAS_RE`.