jouleclaw-diagnose: a cross-model panel, so a verdict can rest on concurring models, or say they did not concur #277

Merged
dcharlot merged 1 commit from feat/diagnose-panel-entailer into main 2026-10-16 09:41:50 -04:00

2026-10-16

Transaction Science
jouleclaw-diagnose: a cross-model panel, so a verdict can rest on concurring models, or say they did not concur
All checks were successful
jouleclaw public surface must stay documented / Public-surface audit (jouleclaw-rs) (pull_request) Successful in 59s
repository checks / lockfiles, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Successful in 34s
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 5s
standards workspaces build + test / mesh-rs (mesh/mesh-rs, -p mesh-engine-gguf -p mesh-openai --features mesh-engine-gguf/gguf,mesh-openai/server, mesh-rs, linux-arm64) (pull_request) Successful in 1m7s
standards workspaces build + test / jouleclaw-rs (-nodebug, jouleclaw/jouleclaw-rs, -p jouleclaw-energy --features rapl,nvml, jouleclaw-rs, linux-arm64, -C target-feature=+fp16) (pull_request) Successful in 3m9s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 5m11s
standards workspaces build + test / jouledesk-rs (jouledesk/jouledesk-rs, jouledesk-rs, macos) (pull_request) Successful in 54s
`Backing::Concurring` and `Backing::Contested` were in the schema, and
`require_substantive_grounding` already accepted them. But nothing produced
either: diagnose only ever declared one entailer's fixed backing. A verdict
could never say "two independent models agreed", nor record that they did
not.

- `PanelEntailer`: at least two members, each a different model. Each
  consulted (claim, item) pair is put to every member, and the report
  carries every member's result under its own model id, so
  `require_substantive_grounding`'s check that the claim matches the
  evidence holds.
- Its backing is read from the results (`Entailer::backing_of`):
  `Concurring` when every member gave the same label on every pair, and
  `Contested` when any two differed. A panel is only as substantive as its
  members. A fixture member makes the whole panel a fixture, and an
  unstated member leaves it unstated, so a stand-in's labels never become
  corroboration.
- Grounding is unanimous per item: an item grounds a claim only when every
  result for that pair entails it. One model's "entails" no longer outvotes
  another's "neutral", and a claim some model entailed, without every
  model's agreement on an item, says `models_disagree: true`. A pair one
  member entails and another contradicts is the existing consistency
  conflict.
- Single-model behaviour is unchanged. Each pair has one result, so
  "every result entails" is "it entails". The new detail key appears only
  where a panel split, so a single model's report keeps its bytes. The
  trait's two new methods are provided, so existing entailers are
  untouched.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-16 04:57:13 -04:00