arborist/bench/stock_v1.py
russell@unturf.com 1a7f8eb4ea
feat: STOCK V.1 two-mode config family + wire treatment arms to the pin
fox 2026-05-21: characterize substrate-ON under BOTH answer shapes, so
answer_mode is a swept axis, not a single pinned value.

stock_v1.py now exposes STOCK_V1_POLICIES{quote,claim_lattice} +
STOCK_V1_GOVERNANCE_HASHES (quote 5b6ca4c5..., claim_lattice 036a4c79...),
policy_for(mode), and assert_not_drifted(mode). Shared pins (crosslang
OFF, repair OFF, quantifier dry-run, metacognition label-only,
soft-preflight OFF, claim cap 12, v2-acronym-aware) are frozen
identically across modes.

Wire the treatment arms to the pin (the consumer-side step that makes
the freeze real):
  * control_ab    --answer-mode {quote,claim_lattice}
  * control_sweep --arborist-answer-mode {quote,claim_lattice}
Both default claim_lattice (prior behavior), call assert_not_drifted on
non-reasoning runs (halts the sweep if DEFAULT_QUERY_POLICY drifts), and
load the frozen policy_for(mode) instead of an inline
dict(DEFAULT_QUERY_POLICY, ...). Reasoning refs (phase 3) keep their
documented JSON overrides and skip the assert by design (different hash).

jaggedness is left standalone — it is a mode-agnostic retrieval
instrument, coupling it to the answer-policy freeze adds friction with no
correctness gain. Full suite 2528 passed.
2026-05-21 10:15:26 -04:00

161 lines
6.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""STOCK V.1 — the frozen substrate-ON configuration under test.
fox 2026-05-21: before the multi-day GPU campaign (hermes 3090/4090 →
qwen 3090/4090 → reasoning variants), pin the substrate-ON config so the
treatment arm cannot silently drift across the run. The control arms
(``bench/control_ab.py`` arm A = bare-model-solo,
``bench/control_sweep.py``) and the substrate-ON arm B (the full
``query()`` pipeline) must all measure the SAME substrate every cell, or
the substrate-OFF-vs-ON delta is meaningless.
Two answer modes (fox 2026-05-21)
---------------------------------
STOCK V.1 is a **two-cell config family**: the substrate is characterized
under BOTH answer shapes, each frozen with its own governance hash —
* ``quote`` — model writes prose with inline verbatim quotes;
bench leader on raw lexical grounding.
* ``claim_lattice`` — structured JSON claim-lattice (the merkle-agi-dag
four-rung ladder); what control_ab/control_sweep
already drive, and the only shape with phase-3
reasoning-variant support built.
``answer_mode`` is therefore a swept axis, not a single pinned value.
Everything else below is frozen identically across both modes.
What V.1 is (both modes)
------------------------
The full merkle-agi-dag reverse-RAG SQD / Prometheus-σ recursive-
falsification substrate, **non-reasoning** and **non-distributed**:
* cross-language guard / sandwich-MT / entity-mask = OFF (English-only)
* mechanical answer-repair = OFF (one-shot discipline)
* quantifier caps = reported, not applied (dry-run)
* metacognition preflight = label-only (no verdict gating)
* soft-preflight LLM sidecar = OFF (no extra round-trip)
* claim ceiling = 12
* verifier content-token rules = v2-acronym-aware
* reasoning (inference layer) = OFF -> reasoning variants are phase 3
* mesh / multi-witness = OFF -> distributed is the later fork
Phase 3 (reasoning) note
------------------------
Reasoning refs (qwen-think) layer documented overrides onto claim_lattice
inside ``control_sweep`` (cleared JSON stop sequences, 8192-token budget
for the reasoning trace, empty-output self-heal). Those overrides change
the policy, so a reasoning run has a DIFFERENT governance hash by
construction — that is correct (it is a different, phase-3 config). The
V.1 drift guard therefore covers only the non-reasoning frozen base;
reasoning runs skip the assert.
How the freeze is enforced
--------------------------
``STOCK_V1_POLICIES[mode]`` is a deep snapshot of the live
``arborist.qa.query.DEFAULT_QUERY_POLICY`` with the load-bearing knobs
re-asserted explicitly (they ARE the current defaults — a freeze, not a
change) plus the mode's ``answer_mode``. ``assert_not_drifted(mode)``
hashes the whole effective dict and fails LOUDLY if it no longer matches
the pin — a mid-campaign edit to ``DEFAULT_QUERY_POLICY`` stops the
harness rather than quietly changing what "substrate-ON" means. We do
not hand-copy the big prompt strings (they would rot against source); we
snapshot + pin the hash.
"""
from __future__ import annotations
import copy
from arborist.qa.keys import governance_policy_hash
from arborist.qa.query import DEFAULT_QUERY_POLICY
#: The knobs that DEFINE substrate-ON V.1, re-asserted explicitly so the
#: intent is readable. Every value equals the current
#: ``DEFAULT_QUERY_POLICY`` default — see the module docstring.
#: ``answer_mode`` is NOT here — it is the swept axis (see STOCK_V1_MODES).
STOCK_V1_PINS: dict = {
"crosslang_guard_enabled": False,
"crosslang_translate_enabled": False,
"crosslang_entity_mask": False,
"repair_enabled": False,
"soft_preflight_enabled": False,
"metacognition_block_on_contradiction": False,
"quantifier_guard_apply_caps": False,
"quantifier_reject_broad": False,
"claim_lattice_max_claims_per_answer": 12,
"content_token_rules": "v2-acronym-aware",
}
#: The two frozen answer shapes the campaign characterizes.
STOCK_V1_MODES: tuple[str, ...] = ("quote", "claim_lattice")
def policy_for(mode: str) -> dict:
"""Frozen substrate-ON policy for one answer mode: defaults + pins."""
if mode not in STOCK_V1_MODES:
raise ValueError(f"unknown STOCK V.1 mode {mode!r}; "
f"expected one of {STOCK_V1_MODES}")
return {
**copy.deepcopy(DEFAULT_QUERY_POLICY),
**STOCK_V1_PINS,
"answer_mode": mode,
}
#: Frozen policies, one per mode.
STOCK_V1_POLICIES: dict = {m: policy_for(m) for m in STOCK_V1_MODES}
#: Inference / harness axes — NOT policy fields (they don't fold into
#: governance_policy_hash). Phases 1-2 hold these; phase 3 flips reasoning.
STOCK_V1_REASONING = False # reasoning variants are campaign phase 3
STOCK_V1_DISTRIBUTED = False # mesh / multi-witness is the later fork
#: The hashes that identify the campaign — one per non-reasoning mode.
#: Pinned 2026-05-21 against DEFAULT_QUERY_POLICY at commit e227bbc.
#: Re-pin (with a fox go) only when a deliberate substrate change lands.
STOCK_V1_GOVERNANCE_HASHES: dict = {
"quote": "5b6ca4c5e754e96b7e2e8af16a8948dec8d8b2a80b9304df21b1f6d494aade4e",
"claim_lattice": "036a4c79fd9d381a9ebf54094091c5f4e892793ae3b6dc56f70b8d4921c47455",
}
def assert_not_drifted(mode: str | None = None) -> dict:
"""Fail loudly if DEFAULT_QUERY_POLICY drifted from the V.1 pin(s).
``mode=None`` checks every mode; pass a single mode to check one.
Returns ``{mode: live_hash}`` on success. Reasoning (phase-3) runs
intentionally diverge and should NOT call this. The campaign harness
calls this before any non-reasoning substrate-ON run.
"""
modes = STOCK_V1_MODES if mode is None else (mode,)
live = {}
for m in modes:
h = governance_policy_hash(STOCK_V1_POLICIES[m])
live[m] = h
pinned = STOCK_V1_GOVERNANCE_HASHES.get(m, "__PIN_ME__")
if pinned == "__PIN_ME__":
continue # un-pinned bootstrap: caller prints + bakes the value
if h != pinned:
raise SystemExit(
f"STOCK V.1 DRIFT ({m}): DEFAULT_QUERY_POLICY no longer "
"hashes to the\n pinned campaign substrate.\n"
f" pinned: {pinned}\n"
f" live: {h}\n"
" Either revert the policy change, or (with a fox go) "
"re-pin\n STOCK_V1_GOVERNANCE_HASHES and bump the "
"campaign to V.2."
)
return live
if __name__ == "__main__":
import json
print("STOCK V.1 substrate-ON config (two-mode family)")
print(f" reasoning : {STOCK_V1_REASONING}")
print(f" distributed : {STOCK_V1_DISTRIBUTED}")
for m in STOCK_V1_MODES:
print(f" governance_policy_hash[{m}] = "
f"{governance_policy_hash(STOCK_V1_POLICIES[m])}")
print(" shared pins:")
print(json.dumps(STOCK_V1_PINS, indent=4, sort_keys=True))