v2.10.0
v2.10.0 - 2026-07-13
Argument engine — AGD scan/audit agreement benchmark (R3B §4 Phase-2 scoring)
R3B §4 of the argument re-grounding roadmap — the offline, deterministic scoring half of the AGD producer/consumer behavioral benchmark. Phase 1 (acquisition) is committed as 20 run-manifests under evals/benchmark/agd-scan/manifests/ (5 R3A fixtures × {fable, codex} × rep{1,2}); the new evals/benchmark/agd-scan/score.py (stdlib-only) replays each one offline through the consumer channel and scores scan↔audit agreement.
Replay. Each manifest is replayed through the same shim an audit runs — ai_prose_agd_move_scan.py --judge manifest --judge-manifest <manifest> --expect-fingerprint <the manifest's own fingerprint> --json (SETEC_VOICEPRINT_DIR → the producer worktree; taken from the environment, a scoring run errors loudly if unset) — taking results.observations from the envelope. A non-available envelope or a fingerprint-drift refusal is a scoring ERROR for that cell, loudly reported and never silently skipped (and it fails the hard gate if it hits a gate cell).
Coordinate + match rule (mechanical §1b). An M-record's coordinate is its resolved Source anchor: the anchor's verbatim quote is resolved in the source under argument_agd's normalization (whitespace folded, quote/dash chars normalized, case-sensitive), the source is split into the producer's blank-line paragraphs, and the one normalized paragraph containing the normalized anchor is the record's derived paragraph (zero or >1 = a loud error, never a guess). A scan observation matches iff same derived paragraph AND same family AND normalized-span interval overlap (each span at its first occurrence; adjacent-but-disjoint spans do not overlap). Per-M-record outcome (§4 taxonomy): CORRECT = ≥1 same-family overlapping observation; INCORRECT = ≥1 overlapping observation, all a different family; SOFT = no overlapping observation. The prose locus label is never a comparison operand. The §10.9 parsing and Source-anchor normalization are imported from scripts/argument_agd.py (extract_section, parse_block, _norm, anchor_resolves), not forked.
Reporting + ownership. Per cell the harness enumerates misses (records with no same-family overlapping observation) and extras (observations overlapping no M-record coordinate — calibration data for the audit's decline path, never an error). The one hard gate (§4 wedge claim): fixture cue-free-structural-discounting, M1 (family DISCOUNTING) reaches ≥1 CORRECT rep per vendor and 0 INCORRECT reps across all reps — score.py exits 1 if it fails. --self-test covers the matcher/taxonomy/gate on synthetic in-memory arms (no file IO); --report / --write-report emit the §M-AGD section into docs/argument-benchmark-calibration-round.md, generated by running the scorer (result cells are never hand-written). The scorer measures agreement only (R4A ADR D5: the producer observes, the consumer alone adjudicates) — no code, no verdict, no observation-count-as-quality, no aggregate beyond the agreement bookkeeping. A purely additive harness: manifests, fixtures, argument_agd.py, and validate.sh are untouched.
Sources: Sinnott-Armstrong & Fogelin, Understanding Arguments 9e, ch. 3 (assuring / guarding / discounting); R3A AGD Move Audit lineage (argument-agd-audit.md); R4A ADR D5 (producer observes, consumer adjudicates); the R1 convergence-record convention (docs/argument-benchmark-calibration-round.md).
Argument engine — R4B AIF export + ADR review folds (non-blocking)
Folds five non-blocking review findings from the R4B pass. ADR hygiene: restores the
accepted docs/adr/0001-argument-layer-boundary.md Consequences sentence ("those unmapped
rows are the visible R4B/R2/R3 work-list") that the R4B PR had silently rewritten, and moves
the reinterpretation ("R4B reviewed those rationales into present-tense conclusions rather than
treating them as a quota for speculative mappings") into the dated R4B implementation note,
so the amendment history is explicit rather than overwriting the accepted decision.
Exporter (scripts/argument_aif.py). The _populated placeholder heuristic no longer
treats any underscore-led line as an empty stub: only the reserved machine-seeded shapes
(_seeded…_, _pending…_, or a bracketed […] stub) count as unpopulated, so authored italic
content smuggled into an out-of-profile section (e.g. a §7 body of _smuggled real out-of-profile content_) now discloses its OUT-OF-PROFILE-SECTION loss instead of being dropped silently,
while genuinely-seeded stubs still disclose nothing. Under --source, check now binds the
export's recorded source.artifact basename to the supplied source filename, so a tampered
basename can no longer ride through a source-closure check. Sourceless check now enforces the
canonical key order (it re-emits the parsed object in the exporter's emission order and
compares bytes), so a key-reordered-but-otherwise-canonical artifact fails without a source;
docs/argument-aif-export.md states that loss-set completeness still genuinely requires
--source. The self-test banner now derives its arm count from a counter (17 arms) instead of a
stale literal, adds a dedicated final-support-enum-invalid build-failure arm, and asserts both
the out-of-profile disclosure and the reserved-placeholder non-disclosure. The committed goldens
(evals/fixtures/argument-aif/final-audit/export.json and the reference example) are unchanged
and regenerate byte-identically; the scripts/ ↔ plugins/apodictic/scripts/ mirror stays
byte-identical.
Argument engine — R4B vocabulary migration + optional AIF-Core export
Renames Step 9's third decision test from Warrant-recoverability to
Bridge-recoverability without changing its question, ordering, verdicts,
codes, or scoring; Dialectical Clarity advances to v2.1 while Argument_State
stays v0.2.0. The taxonomy crosswalk advances to v0.2.0 with a separately
drift-bound eight-row concept layer for R2 relations and R3 AGD moves; the closed
82-code layer remains unchanged and all 48 unmapped rationales are now stable
present-tense conclusions.
Adds the optional apodictic.aif-core-export.v1 one-way adapter: deterministic,
atomic JSON with source-owned claim/support IDs, verbatim warrant scheme_text,
typed I/RA/CA incidence, explicit loss accounting, final-vs-pre-draft precedence,
and byte-level --source closure. It never invents claim-ladder, PA, alternative-
conflict, or AGD topology and never feeds external graphs back into diagnosis.
Mechanical gates certify shape and closure only; mappings remain reviewed
scholarly assertions. Source: ARG-tech, The AIF Specification, Definition 1.1
(AIF graph); Toulmin, The Uses of Argument (1958); Sinnott-Armstrong & Fogelin,
Understanding Arguments, 9th ed.
ClaimLicense ↔ Toulmin crosswalk (R5)
Documents the fleet's warrant/license resemblance as a cross-level analogy rather than an identity. A new field-by-field crosswalk distinguishes Toulmin's object-level argument roles from SETEC Voiceprint's meta-level ClaimLicense, fixes the current whole-object→warrant mapping as unmapped, and supplies hostile anti-equivalence cases plus a promotion test for any future explicit entitlement_basis / inference_rule. The snapshot is grounded in setec-voiceprint v1.124.0 and its schema_version: 1.0 producer envelopes; this is documentation and ADR clarification only, with no SETEC edit, vend, dependency-floor change, schema, validator, or runtime behavior change.