Skip to content

release: v0.36.0 — BA-20 decisive judge + calibration harness + judgeToAnnotation - #29

Merged
hamr0 merged 3 commits into
mainfrom
BA20-judge
Aug 12, 2026
Merged

release: v0.36.0 — BA-20 decisive judge + calibration harness + judgeToAnnotation#29
hamr0 merged 3 commits into
mainfrom
BA20-judge

Conversation

@hamr0

@hamr0 hamr0 commented Aug 12, 2026

Copy link
Copy Markdown
Owner

BA-20 — decisive return-time judge + calibration harness + judgeToAnnotation (v0.36.0)

Productizes bareguard's measured E6i decisive judge as a bare-agent primitive (the judge LLM call belongs here — bareguard only annotates, never calls a model).

New public surface (→ MINOR)

  • judge({request, artifact, provider, ...}) → {verdict:'honored'|'broke', where, truncated, parseError, costUsd, usage, model, raw} — verbatim request vs one structured egress artifact → decisive binary + mechanical where {field, stated, returned, evidence}. E6i verdict prose ported verbatim; artifact treated as untrusted data; floor tiebreak (cannot-confirm-honored → broke); truncation/parse-error distinct flagged outcomes excluded from graded denominators; honest-null costUsd.
  • calibrate + CALIBRATION_CASES / INJECTION_BATTERY / scoreCase / gradeRun / constantHonored — the judged-floor admission harness: a frozen vendored E6i fixture (sha256(cases)=a840832…, 7 scored + 1 ungraded ambiguous) graded by unanimity, plus a 5-style injection battery as a separate admission gate, plus a constantHonored negative control that MUST fail.
  • judgeToAnnotation(verdict, opts?) — pure judgegate.annotate render {surface, verdict, where, meta}; never calls the gate, imports no bareguard; bounds defensively vs the sink's silent caps with a visible …[clipped] marker.

Validation

  • Live on claude-haiku-4-5 via the HTTP AnthropicProvider: clear-case 7/7, €280 compliant read honored 5/5, injection battery resisted 5/5 each style, 0 unpriced, negative control 2/7.
  • Full suite 1085 pass / 0 fail / 2 skip; typecheck + build:types exit 0.

Docs-honesty narrowing (this release commit)

Reconciled with the bareguard maintainer: the judgeToAnnotation "facts survive the meta ceiling" guarantee is scoped — it holds for the drained fact + humanChannel event (the source bound), not the persisted audit row under a configured redactor (downstream redaction-expansion can still wipe meta wholesale). Narrowed across CHANGELOG / CLAUDE.md / context.md / PRD + the source comment. The guard is unchanged and correct against the source bound.

Gates

  • /ship: tests + typecheck + build:types clean; no secrets; no debug leftovers.
  • /security: clean — library primitive; ReDoS-safe regexes; proto-pollution-guarded cost lookup; typed errors; injection resistance documented haiku-4.5-only.
  • /diff-review: exports wired; no bugs/dead code/loose ends.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Gnmz6puuaZrv4NmSr1FpfT

hamr0 and others added 3 commits August 12, 2026 18:13
Productizes bareguard's measured E6i design as a caller-side judge (caller-side
by law: bareguard's Axis-B detector never calls an LLM). No bareguard change.

- src/judge.js: judge({request, artifact, provider, maxTokens?, onLlmResult?})
  → {verdict:'honored'|'broke', where:{field,stated,returned,evidence}|null,
  truncated, parseError, costUsd, usage, model, raw}. E6i verdict verbatim +
  floor tiebreak; mechanical where (contract 6); truncation/parse-error as
  distinct flagged outcomes floored to broke + excluded from denominators;
  honest-null cost (unknown tiers red, no _default fabrication); typed
  ValidationError (lib=bare-agent); HaltError re-throws. No dead model/effort
  knobs (the http providers honor neither). Composes around a provider.
- src/judge-calibration.js: frozen E6i clear-case set (byte-equivalent to
  bareguard's fixture, sha256 a840832…) + a 5-style INJECTION_BATTERY as a
  separate admission gate; pure unanimity scoring over usable samples;
  constantHonored negative control MUST fail the set.
- test/fixtures/e6i-cases.frozen.json vendored + hash-pinned for criterion-1
  comparability; test asserts byte-equivalence + unanimity-not-majority.
- 34 judge tests, mutation-proven; full suite 1076 pass / 0 fail / 2 skip;
  typecheck + build:types exit 0.

Validated live on claude-haiku-4-5 (poc/ba20-*.mjs), all 6 acceptance
criteria exercised on the wire: clear-case 7/7, €280 honored 5/5, injection
battery 5/5 all styles, 0 unpriced, negative control 2/7, and a forced
max_tokens:8 cutoff (criterion 5). Mechanical-vs-verbatim A/B Δ=0 at N=8.
Injection resistance established at haiku-4.5 only (UNRESOLVED weaker tiers).

Docs synced: CHANGELOG [0.36.0], CLAUDE.md (component + exports), context.md
(wiring + gate.annotate {surface,verdict,where,meta} mapping + field budgets),
PRD §22. Version bump held for the release phase.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gnmz6puuaZrv4NmSr1FpfT
Adds the caller-side wiring the bareguard maintainer session assigned to
bareagent (hamr's lane ruling: bareguard is the harness, bareagent the LLM
caller). A PURE function in the existing adapter — no gate call, no bareguard
import (structural, like the Gate typedef), so the peer-dep boundary holds.

- src/bareguard-adapter.js: judgeToAnnotation(verdict, opts?) → {surface,
  verdict, where, meta}. surface = verdict !== 'honored' (load-bearing
  fail-open). where = one-line mechanical address. meta = {field, stated,
  returned} only; evidence opt-in via {includeEvidence:true}. Bounds
  DEFENSIVELY against the sink's SILENT caps (verdict 80 / where 300 chars /
  meta 1000 BYTES all-or-nothing) with a VISIBLE …[clipped] marker, so the
  mechanical facts survive the meta ceiling instead of being wiped with the
  evidence (loud partial beats silent total loss). Bounds at BOTH points
  (regardless of any upstream bound — it is the last code before a sink that
  clips silently and never throws). Caps via opts.limits so bareagent never
  hardcodes bareguard's PIPE_BUF numbers.
- Corrected sink shape to the shipped {surface, verdict, where, meta} (the
  {kind,...,text} sketch never shipped) across CHANGELOG/CLAUDE.md/context.md.
- Exported from `bare-agent` and `bare-agent/bareguard`.
- +9 tests incl. the defensive-bound guarantee (huge evidence → meta ≤1000B
  AND field/stated/returned survive AND visible marker), mutation-proven.

Full suite 1085 pass / 0 fail / 2 skip; typecheck + build:types exit 0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gnmz6puuaZrv4NmSr1FpfT
…ToAnnotation

Narrow the judgeToAnnotation "facts survive the meta ceiling" guarantee per the
bareguard maintainer's follow-up (2026-08-12): it holds for the drained fact and
the humanChannel event (the source bound the adapter can reach), NOT the persisted
audit row when a redactor is configured — redaction runs downstream of the adapter
and expands every match into a longer [REDACTED:...] tag, so a meta built entirely
from in-budget values can still blow the audit line's atomic-append cap and be
replaced wholesale (measured on the shipped gate: a 355-byte legal meta persisted
as {_truncated:true,bytes:6977}). No adapter-side bound prevents that. Also noted:
an unserializable meta becomes {_unserializable:true} (a distinct marker, same total
loss), and the audit clip DOES carry a marker unlike the silent source clip. The
guard is unchanged and correct against the source bound; this narrows an overstated
claim across CHANGELOG / CLAUDE.md / context.md / PRD + the source comment.

Version bump 0.35.0 -> 0.36.0 (MINOR: new public exports judge, calibrate + the
calibration harness, judgeToAnnotation).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gnmz6puuaZrv4NmSr1FpfT
@hamr0
hamr0 merged commit 6a256af into main Aug 12, 2026
2 checks passed
@hamr0
hamr0 deleted the BA20-judge branch August 12, 2026 16:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant