core/docs/decisions/ADR-0131.G.1-verb-classes-initial-state.md
Shay d66e8ad625 feat(G1): verb-classes capability axis (ADR-0131.G.1)
Cognitive capability: extend bounded grammar to admit acquisition/action
verbs (buys, bought, collected, saved, saved-up, makes, sells) as
operation-kind entries, and pure-possession verbs (had, started, started-with)
as initial-possession anchors.

What invariant proves correctness:
- wrong == 0 across all G1 curated cases (20/20) and GSM8K probe (0 wrong/50).
- versor_condition and field invariants untouched — no algebra-path changes.
- Round-trip filter (math_roundtrip.roundtrip_admissible) unchanged.

Which CLI suite / eval proves the lane:
  pytest tests/test_adr_0131_G1_verb_classes.py — 15/15 pass
  pytest tests/test_adr_0126_runner_wiring.py — 9/9 pass (3 regressions fixed)
  pytest tests/test_adr_0131_{1,3}_*lane.py — 17/17 pass
  pytest tests/test_adr_0131_G_gsm8k_coverage_probe.py — 8/8 pass
  pytest tests/test_gsm8k_math_runner.py — 11/11 pass

Key architectural change:
  Acquisition verbs that also appear in ADD_VERBS/SUBTRACT_VERBS were
  previously listed in _INITIAL_HAS_RE, causing branch-disagreement refusals
  when a canonical 'has' initial preceded an acquisition sentence for the
  same entity.  Fix: narrow _INITIAL_HAS_RE to pure-possession anchors only
  (has/have/had/started); acquisition verbs remain exclusively in KIND_TO_VERBS.
  The solver's default-from-zero means 'Sam buys 5 apples. How many does
  Sam have?' resolves as 0+5=5 without any initial-possession candidate.
  Optional verb particle (up/down/out/...) added to _op_pattern to handle
  'saved up N', 'picked up N' etc.

No changes to binding graph, solver, verifier, or versor/CGA algebra.
No stochastic generation, approximate recall, or hidden normalization.
Trust boundaries unaffected — no new dynamic imports or user-input paths.
2026-05-23 15:39:14 -07:00

3.6 KiB

ADR-0131.G.1 — Capability axis: state-introducing verb classes

Status: Accepted Date: 2026-05-23 Author: CORE agents Parent: ADR-0131.G


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 <Entity> <verb> <N> <unit> 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: (?P<anchor>has|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.