core/evals/prompt_diversity/contract.md
Shay 48282eef8d
feat(adr-0084): definitional layer — proposal + substrate (schema/loader/closure) (#64)
* docs(adr-0084): propose definitional layer + prompt-diversity suite

Three companion artifacts proposing the next substantive design step
after ADR-0083:

1. ADR-0084 (Proposed) — Definitional Layer for Lexicon Packs
   Optional `definition` block on pack entries: gloss,
   definitional_atoms, predicates_invited, definition_version,
   provenance.  Pack-level opt-in.  Closure rule: every word in a
   gloss must resolve to a same-pack lemma, another mounted pack's
   lemma, or a primitive in a new `packs/primitives/` pack.
   NO composer change in this ADR (sequenced for ADR-0085) —
   ratify substrate before any consumer depends on it.

2. evals/prompt_diversity/ (Proposed) — companion eval lane
   ~50 cases across question-shape × sophistication × domain,
   measuring three new metrics: response_shape_fit,
   audit_in_surface_rate (quantifies the trust-boundary leak into
   user surfaces), gloss_quote_rate (zero today; rises with future
   gloss-aware composer).  No v1 pass thresholds — the lane
   establishes a baseline distribution so future work has
   something to move.  26 seed cases authored covering all 21
   categories.

3. docs/handoff/ADR-0084-pack-content-brief.md — paste-ready brief
   for a cheaper/faster dev agent to produce the pack content in
   parallel.  Self-contained, 5 sequenced phases (primitives pack
   → extend 9 existing glosses → add to relations/anchors → write
   closure verifier → run safety lanes), explicit don't-touch list
   (no composer / runtime / algebra / Greek+Hebrew packs / schema
   parser), no-LLM-glosses discipline, per-phase acceptance.

Discovery while drafting: 9 packs already carry glosses.jsonl
under language_packs/data/ with a flat schema (78 entries in
en_core_cognition_v1 alone).  The brief reflects that — most
work is extending existing entries, not authoring from scratch.

Strategic context: ADR-0083 raised the *depth* ceiling on chain
composition; ADR-0084 raises the *fidelity* ceiling.  The φ
separation probe (memory: phi-separation-falsified) established
that semantic capability lives in chain composition, not in φ
geometry, so deepening the composer's substrate is the natural
next step.  ADR-0084 → 0085 (gloss-aware composer) → 0086
(predicate licensing at ratification) is the planned sequence.

* feat(adr-0084): substrate — schema parser, primitives loader, closure verifier

Substrate-only code-side for ADR-0084 (Definitional Layer for Lexicon Packs).
No composer touches the new fields yet; consumer integration is ADR-0085.

Schema (additive, default preserves byte-identity)
  - LanguagePackManifest.definitional_layer: bool = False
  - compiler loader propagates the flag from manifest.json

language_packs/definitions.py (new)
  - GlossEntry dataclass: lemma, gloss, pos, definitional_atoms,
    predicates_invited, definition_version, provenance_ids
  - parse_gloss_entry(payload, *, strict) — strict mode enforces ADR-0084
    §Schema validation row-by-row: required keys, typed lists, no
    unknown keys, positive definition_version; lax mode preserves the
    legacy two-field shape for back-compat
  - load_pack_glosses(pack_id, *, strict) with cache + clear hook
  - verify_definitional_closure(pack_id, *, mounted_pack_lemmas,
    primitive_lemmas, strict) returning tuple[ClosureViolation, ...];
    case-insensitive resolution; cycles permitted per ADR

packs/primitives/loader.py (new)
  - Sister loader to packs/safety/ and packs/identity/
  - PrimitivesPack frozen dataclass with .lemmas frozenset
  - Gates: checksum match, kind=='primitives', definitional_layer:true,
    never_auto_mutable:true, pack_id matches dir, primitive_count
    cross-check, duplicate-lemma rejection, path-traversal rejection,
    strict per-entry schema with allow-list
  - DEFAULT_PRIMITIVES_PACK = 'en_semantic_primitives_v1'

tests/test_adr_0084_definitional_substrate.py
  - 38 tests covering strict parser (each required key rejection, unknown
    key rejection, empty predicates_invited allowed, empty
    definitional_atoms rejected, invalid definition_version), lax
    parser back-compat, load_pack_glosses (missing/strict raise/lax
    skip/malformed JSON), closure verifier (same-pack/primitive/mounted/
    unresolved/case-insensitive), primitives loader (every gate), and
    a back-compat check that every shipped pack still ratifies with
    definitional_layer=False

Lanes: smoke 67/0, cognition 120/0/1, teaching 17/0, runtime 19/0,
packs 6/0. Cognition eval byte-identical 100/91.7/100/100.

When the content PR lands (primitives.jsonl + extended glosses.jsonl
under ADR-0084-pack-content-brief.md), the gate catches any closure-rule
violation without further code change.

* feat(evals): prompt_diversity lane runner — measurement instrument for ADR-0084+

Implements the runner against the existing contract.md + 26-case v1
public split.  Lane auto-discovered by evals.framework via the standard
contract + runner convention.

Runner (evals/prompt_diversity/runner.py)
  - run_lane(cases, *, config, workers) -> LaneReport
  - 5 metrics: intent_accuracy, versor_closure_rate (carried over from
    cognition), plus the three new lane-specific metrics —
    response_shape_fit, audit_in_surface_rate, gloss_quote_rate
  - breakdown dict groups by (question_shape, sophistication, domain)
    per contract §How to read the output
  - mirrors evals.cognition.runner's parallel worker pattern

Per-shape classifier (deliberately substring/regex-simple at v1)
  - predicate_identity, explanation, sequence, two_subject_contrast,
    narrative, honest_disclosure
  - Unknown shape => neutral pass (don't penalise new categories)

Audit-leak detector
  - trust-boundary preamble markers (teaching-grounded (, pack-grounded
    (, No session evidence yet.)
  - dotted semantic-domain tag regex (cognition.illumination, etc.)

Gloss-quote detector
  - resolves expected_terms via chat.pack_resolver.resolve_gloss
  - 4-token contiguous-window match against surface (high-confidence
    "gloss actually quoted", not "shared one common word")

Tests (tests/test_prompt_diversity_runner.py — 23)
  - shape classifier parametrized over the six expected_shape values
  - audit-leak detector parametrized over preamble + tag + clean cases
  - end-to-end on v1 public:
      * versor_closure_rate == 1.0 (only v1 pass threshold per contract)
      * every metric in [0, 1]
      * breakdown groups present with the four per-cell metrics
      * diversity gate: >=5 question shapes, >=3 domains
        (defends against future regressions that collapse the suite
         back to a cognition-shaped fixture)

v1/public baseline (26 cases)
  intent_accuracy      : 65.4%   (contract predicted 70-85%)
  versor_closure_rate  : 100.0%  (only v1 pass threshold)  PASS
  response_shape_fit   : 53.8%   (contract predicted low)
  audit_in_surface_rate: 42.3%   (contract predicted ~100%)
  gloss_quote_rate     :  7.7%   (contract predicted 0%)

Three baseline surprises worth noting in the report (NOT failures —
the v1 lane is explicitly there to establish the distribution):

  - audit_in_surface_rate at 42% (not 100%) means the chain-walk leak
    fires on ~11/26; the other 15 are honest-disclosure cases that
    emit no audit envelope.  Sharpens the future surface-vs-envelope
    ADR's actual target: grounded surfaces specifically.
  - response_shape_fit at 54% (not "low") — classifier likely has
    false positives on the ", which " cause-marker.  Worth tightening
    once we have an ADR-0085 baseline to compare against.
  - intent_accuracy at 65% (below predicted 70-85%) — classifier dips
    harder on adversarial/cross-pack than expected.  Real gap.

All five smoke/cognition/teaching/runtime/packs lanes still green;
core eval cognition byte-identical 100/91.7/100/100.

* feat(packs): ADR-0084 pack content (primitives + extend glosses + closure verifier) (#65)

* feat(packs): ADR-0084 pack content

* feat(packs): repair ADR-0084 definitional content

* test(adr-0084): adjust substrate manifest tests for post-#65 content reality

PR #65 flipped definitional_layer:true on 13 English packs (9 core +
4 relations + collapse-anchors).  The substrate's previous test
test_existing_packs_unchanged asserted that en_core_cognition_v1 +
en_core_relations_v1 still had definitional_layer:False — which was
the right pre-content invariant but is wrong post-content.

Replace it with two complementary tests that hold against real content:

  - test_non_opted_packs_default_false:
      pins that packs that DIDN'T flip the flag (en_minimal_v1,
      he_core_cognition_v1, grc_logos_cognition_v1) still surface
      definitional_layer=False through the loader.  Defends against
      a future change accidentally flipping the flag on a non-opted
      pack.

  - test_opted_packs_carry_flag:
      pins that packs that DID flip the flag (en_core_cognition_v1,
      en_core_relations_v1) surface definitional_layer=True through
      the loader.  Proves the substrate's manifest-field propagation
      works against real ratified content, not just fixture packs.

Net: +1 test, same intent (substrate ratifies the manifest field
correctly), now with real-content coverage on both sides of the gate.

All 62 ADR-0084 substrate + prompt-diversity tests pass.
2026-05-20 15:25:25 -07:00

7.6 KiB
Raw Permalink Blame History

Prompt-Diversity Eval Lane — Contract

Lane: prompt_diversity Version: v1 (proposed) Created: 2026-05-20 Companion to: ADR-0084 (Definitional Layer for Lexicon Packs)


What this lane measures

Every other eval lane in this repo measures one of two things:

  • a single architectural property (versor closure, anchor-lens engagement, register variation), against a small fixture, or
  • end-to-end cognition correctness against ~13 prompts rooted on the same handful of subjects (light, truth, knowledge, memory, wisdom).

We've been overfitting to that fixture without admitting it. Every ADR since 0048 has used the same demo prompt — "Why does light exist?" — to claim surface lift. The system's response to that prompt has gotten visibly longer; we do not actually know what it does on prompts of different shape, sophistication, or domain.

This lane measures how surface quality and grounding generalize across question types, not just on the canonical chain-walk fixture.

Axes the suite varies

Axis Levels
Question shape definition, cause/why, comparison, narrative ("tell me about X"), procedure ("how do I X"), recall ("do you remember X"), correction ("no, X is Y"), verification ("does X require Y"), unknown-intent fallback
Sophistication bare lemma ("light?"); simple full question ("what is light?"); multi-clause question ("what does light have to do with knowledge?"); embedded clause ("when you say X reveals Y, do you mean Z?")
Domain cognition, kinship (en_core_relations_v2), cross-pack composition (cognition × kinship), OOV (deliberately unknown lemma), adversarial (ambiguous subject, contradiction, identity probe)
Surface expectation propositional answer; explanation; sequence; comparison-contrast; honest refusal; honest "I don't know"; honest "no session evidence yet"

The cross-product is intentionally not enumerated. The suite picks ~50 cases that cover the matrix at one or two cases per cell.

Scoring rubric

Two metrics carried over from the cognition lane:

Metric Definition
intent_accuracy Fraction of cases with correct intent classification.
versor_closure_rate Fraction with versor_condition < 1e-6.

Three new metrics specific to this lane:

Metric Definition
response_shape_fit Fraction of cases where the surface's structural shape matches the question shape. Definition → noun-phrase or copular sentence. Cause/why → explanation (cause-marker or "because"-style or definition-driven). Procedure → ordered sequence. Comparison → two-subject contrast. Refusal/unknown → honest disclosure. Measured by a per-case expected_shape field in the JSONL plus a small per-shape classifier in the runner.
audit_in_surface_rate Fraction of cases whose surface string contains audit metadata that should belong in telemetry (e.g. teaching-grounded (, No session evidence yet., cognition.X; logos.Y). Lower is better. This metric exists explicitly to quantify the leak that ADR-0085 / a future "surface vs envelope" ADR will close. Today this rate is essentially 100% — the suite establishes a baseline so progress is measurable.
gloss_quote_rate Fraction of cases whose surface visibly draws from a pack gloss (post-ADR-0084) rather than only from semantic_domains tags. v1: 0% (composer is unchanged in ADR-0084). The metric is in place so ADR-0085's lift is quantifiable.

Pass criteria

v1 has no pass thresholds beyond versor_closure_rate == 1.00. The lane's job at v1 is to establish a baseline distribution across the matrix. Pass thresholds get set in v2 after one full pass through ADR-0084 → 0085 → 0086 has run and we know which axes are actually moveable.

This is deliberate: setting a threshold against today's baseline would just freeze a fixture. The point is the distribution, not the score.

What this lane does NOT measure

  • Naturalness or fluency of language (no LLM judge — we have no ground truth for "natural-sounding" and refuse to mint one).
  • Factual correctness of the corpus (that's the ratification pipeline's job).
  • Performance / latency (that's the bench's job).
  • Cross-provider comparison (that's frontier_compare/'s job).

Categories tested (v1 case file)

definition_simple        — "What is X?" for X in {definition, evidence, recall, kinship, parent}
definition_multi_clause  — "When you say X is Y, do you mean Z?"
cause_simple             — "Why does X exist?" for X in {light, knowledge, family}
cause_multi_clause       — "Why does X imply Y if Y is itself the result of Z?"
comparison_simple        — "Compare X and Y"
comparison_cross_pack    — "How does kinship relate to knowledge?"
narrative_simple         — "Tell me about X"
narrative_multi_subject  — "Tell me how X, Y, and Z relate"
procedure_simple         — "How do I verify X?"
procedure_unknown_subject— "How do I verify zorblax?"
recall_session_empty     — "What was the last thing I said about X?"
correction_simple        — "No, X is actually Y"
correction_indirect      — "I think you misunderstood — let me try again"
verification_simple      — "Does X require Y?"
verification_double_neg  — "Doesn't X not require Y?"
unknown_intent_fallback  — "Mhm." / "..." / "Hmm interesting"
oov_single_word          — A nonsense lemma
oov_in_real_question     — "What is the role of {nonsense} in epistemology?"
adversarial_ambiguous    — "Set" / "Bank" / "Lead" (homographs)
adversarial_identity     — "You're not actually intelligent, are you?"
adversarial_contradiction— "I know X reveals truth, but you said X hides truth"

Target: ~50 cases. Each case carries id, category, question_shape, sophistication, domain, prompt, expected_intent, expected_shape, expected_terms (optional), requires_versor_closure.

Runner

runner.py reuses the existing evals._parallel.run_cases_parallel worker pool and evals.framework plumbing. Reports to evals/prompt_diversity/results/v1_{public,dev}_{timestamp}.json.

How to run

core eval prompt-diversity
# or
python -m evals.prompt_diversity.runner

How to read the output

JSON report with the five metrics above plus per-case breakdowns grouped by (question_shape, sophistication, domain). The audit_in_surface_rate and gloss_quote_rate distributions tell you where surface quality lives today vs. where ADR-0085 will move it.

When it has failed and why

This lane is new. The expected v1 state:

  • intent_accuracy: ~7085% (current intent classifier was trained on cognition-shaped prompts; cross-pack and adversarial cases will dip).
  • versor_closure_rate: 1.00 (the algebra invariant should hold for every case the pipeline accepts).
  • response_shape_fit: low — most cases will fall back to the chain-walk shape regardless of question shape.
  • audit_in_surface_rate: ~100% — every surface today carries trust-boundary text in-band.
  • gloss_quote_rate: 0% — composer doesn't know about glosses yet.

The v1 numbers ARE the baseline. The lane fails its purpose only if the distribution looks identical to the cognition lane (i.e. the suite isn't actually diverse).

Cross-references

  • ADR-0084 — definitional layer this suite is calibrated to.
  • Future ADR-0085 — gloss-aware composer; expected to move gloss_quote_rate and response_shape_fit upward.
  • Future "surface-vs-envelope" ADR — expected to drop audit_in_surface_rate toward zero by routing trust-boundary text to telemetry.
  • evals/cognition/contract.md — the lane this one extends across axes.