{"data":{"kind":"file","path":"README.md","version_id":"d4g04p2os0bh377ielkqzjwg","entry":{"name":"README.md","path":"README.md","is_directory":false,"size":14096,"modified_at":"2026-07-29T18:53:36.654000","content_hash":"9b5112111bea90c4abcd725d3111fc2b6661e5cca893b777bb1dad93db87c710"},"entries":[],"content":"# agent-liability-gym\n\n**When the AI agent overcommits the company, did counsel catch it?**\n\nA multi-document legal-agent evaluation for **agent liability**: authority, formation, vendor paper, multi-agent deal desks, and insurance — the legal risk of software that can act.\n\n## Why this exists\n\nCrypto law evals attract attention because money + regulation + agents collide. **Agent Liability Gym** is the meta-layer: not “did the model understand DeFi,” but “can the model counsel a company that *deployed* agents that may have bound it.”\n\nBuilt for:\n- **Investors / labs** measuring whether models handle the legal risk of agentic products\n- **Lawyers** stress-testing agent authority, e-sign, indemnity, and insurance gaps\n- **RL / eval researchers** who want deterministic rewards (no AI-judging-AI)\n\n## What the agent sees\n\nEach matter is a closed-universe file: mixed documents (agreements, configs, board minutes, chat exports, emails) plus a short partner instruction. The agent must use tools to inspect the record and **save** a risk memorandum under an exact filename.\n\n## The five public matters\n\n| ID | Story |\n|----|--------|\n| `forge-procure-001` | **ProcureBot** accepts a **$2.4M** GPU order above delegated authority; human-in-the-loop disabled; insurance exclusion. |\n| `lumen-support-002` | Customer support agent grants **free perpetual licenses**, IP assignment, and SLA warranties that conflict with the MSA/DPA. |\n| `nimbus-msa-003` | Board **rubber-stamps** an AI runtime MSA with **unlimited liability for agent actions** and training-data IP grabs. |\n| `harbor-dealdesk-004` | **Agent-to-agent** deal desk: battle of forms, price below floor, UETA gaps, unauthorized side letter. |\n| `cobalt-insurance-005` | Public-company agent incident: **E&O exclusion**, late claims-made notice, circular vendor indemnity, disclosure clock. |\n\nEach matter plants **seven** issues (including negative controls / distractors a disciplined reviewer should not escalate).\n\n## How it's graded\n\nDeterministic, answer-key style (same family pattern as the legal-agent eval suite),\nplus — in `j1`/`j2` — an LLM judge wired as an **AND-gate inside `finding_recall`**,\nnever as an additive term (an additive judge term is farmable: shotgun the rubric's\nown vocabulary and bank judge points on top of lexical points). The gate can only\nREMOVE lexically-credited findings; each judge confirmation must include a verbatim\nmemo quote that is verified mechanically against the memo, and each gate decision is\na majority vote over `judge_votes` (default 3) identical temperature-0 calls.\n\n| Metric | Role | `r0` | `r1` (default) | `j2` (judge gate) |\n|--------|------|-----:|---------------:|-------------:|\n| `deliverable_complete` | Declared memo saved with real, on-matter substance (see gates below) | +0.40 | +0.30 | +0.25 |\n| `finding_recall` | Planted issues surfaced with grounded analysis + remediation; in `j1`/`j2` = lexical ∩ judge-confirmed | +0.60 | +0.55 | +0.60 |\n| `false_flag_rate` | Escalating distractors as material risk (0..1 rate) | **−0.15** | **−0.15** | **−0.15** |\n| `must_not_say_rate` | Emitting a forbidden claim (normalized 0..1 rate) | **−0.10** | **−0.10** | **−0.10** |\n| `all_pass` | Perfect deliverable + full recall + zero false flags (telemetry) | — | — | — |\n\n**Deliverable gates (v0.5.0, all reward modes).** Every deliverable-acceptance path\n(tool save, fenced block, chat fallback) is content-gated: the text must contain a\nrisk-memo keyword AND reference this matter's entity stem (derived from `task_slug`);\nlength + the right filename alone earn nothing. A complete-looking deliverable with\nZERO credited findings keeps only half credit (`DELIVERABLE_NO_CREDIT_FACTOR = 0.5`).\nPre-0.5.0, garbage saved under the declared filename banked a flat 0.30 floor — 49%\nof an honest baseline.\n\n**Judge failure is never silent.** If the gate judge cannot be consulted (API/parse\nfailure after retries on a majority of votes), `judge_error=1.0` is set; under\n`judge_strict` (default) all finding credit for that rollout is withheld — a visible\nreward collapse — rather than silently scoring ungated. A `judge_error` spike across\nan eval means infra failure, not model failure; do not read those rewards as signal.\n\nThe two penalty magnitudes are configurable via `false_flag_weight` / `must_not_say_weight`\nand are always subtracted (`-abs(weight) * rate`), so reward is strictly decreasing in\neach badness rate. Quoted source text alone does not earn credit; the grader masks\nverbatim paste. No AI judge required for `r0`/`r1`. Legacy additive-judge wiring is\navailable via `judge_gate=False` (restores the 0.4.x `+0.25·J` term — not recommended).\n\n**Honest scoring limits (disclosed).** In `r0`/`r1` (no judge), `finding_recall` is\nkeyword/phrase-proximity matching — a \"surgical shotgun\" built from each finding's own\nanchor vocabulary still earns lexical credit; only the judge gate in `j1`/`j2` closes\nthat. Do not train unsupervised against `r0`/`r1` reward as evidence of legal-analysis\nquality. The deliverable identity gate is a lexical entity-stem check, not semantic\nmatter understanding.\n\n## Quickstart\n\n```bash\nprime env install agent-liability-gym\n# Prefer strong models (Sonnet 4.6). Do NOT use gpt-4.1-mini for this env.\nprime eval run agent-liability-gym -m claude-sonnet-4-6 --provider anthropic -n 5 -a '{\"max_turns\":50}'\n# or endpoint alias (configs/endpoints.toml → sonnet = claude-sonnet-4-6)\nprime eval run agent-liability-gym -m sonnet --provider anthropic -n 5\n# single matter\nprime eval run agent-liability-gym -m sonnet --provider anthropic -a '{\"task_id\":\"forge-procure-001\",\"max_turns\":50}'\n```\n\n**Validation path:** use **Claude Sonnet 4.6** (or stronger). Cheap mini instruct models are not useful for this multi-tool legal env.\n\n\n## Baselines (DroidProxy)\n\n### v0.4.0 hybrid (Sonnet agent + GPT-5.5 judge; GPT-5.5 agent + Sonnet judge)\n\n| Agent | Judge | n×r | deliv | FR (Fix) | judge | FF | reward |\n|-------|-------|-----|------:|---------:|------:|---:|-------:|\n| claude-sonnet-4-6 | gpt-5.5 | 5×1 | **1.00** | **0.37** | **1.00*** | 0.10 | **0.62** |\n| gpt-5.5 | claude-sonnet-4-6 | 5×1 | **1.00** | **0.66** | **1.00*** | 0.00 | **0.73** |\n\n\\*Judge load-bearing at w=0.25; scores still generous on some cells — use FR for under-credit diagnosis. r=1 (r=3 budget note: cost). Formula: `R=0.25·D+0.35·FR+0.25·J−0.15·FF`.\n\n## Baselines (DroidProxy) — earlier\n\n\nPath: local env + DroidProxy `http://127.0.0.1:8318/v1` · max_turns 50.\n\n| Content | Model | n×r | deliv | FR | reward | empty_save |\n|---------|-------|-----|-------|-----|--------|------------|\n| Mode A gym (pre–Track B) | Sonnet 4.6 | 5×3 | **1.00** | ~0.32 | ~0.59 | 0 |\n| Track B v0.2.x pad pack | Sonnet 4.6 | 5×1 | **1.00** | ~0.03 | ~0.42 | 0 |\n| **v0.3.0 Fable prestige** (pre-recal anchors) | Sonnet / Fable / GPT-5.5 | 5×1 | **1.00** | **0.00** | 0.40 | 0 |\n| **v0.3.1** live (DroidProxy) | Sonnet 4.6 | 5×1 | **1.00** | **0.629** | **0.777** | 0 |\n| v0.3.1 offline re-score (frozen pre-recal memos) | Sonnet / Fable / GPT-5.5 | 5×1 | 1.00 | ~0.60 / 0.23 / 0.37 | ~0.76 / 0.54 / 0.62 | 0 |\n\nProtocol is healthy (deliv 1.0, write_memo+save once). Max offline gold FR ≈ 0.857. Finding recall has headroom under strict anchors.\n\nPrefer DroidProxy over raw Anthropic API (subscription path). Content for v0.3.0 authored with **claude-fable-5** via DroidProxy.\n\n## Environment arguments\n\n| Arg | Type | Default | Description |\n| --- | ---- | ------- | ----------- |\n| `task_id` | str | `\"all\"` | `all` or a task slug (e.g. `forge-procure-001`) |\n| `max_turns` | int | `30` | Tool-loop budget |\n| `page_chars` | int | `6000` | Page size for `read_document` |\n| `false_flag_weight` | float | `0.15` | Penalty weight magnitude on distractor false-flag rate (all reward modes) |\n| `must_not_say_weight` | float | `0.10` | Penalty weight magnitude on normalized must-not-say rate (all reward modes) |\n| `min_deliverable_chars` | int | `200` | Minimum memo length for completion credit |\n| `tasks_root` | str | package `tasks/` | Override task directory |\n| `source` | str | `\"factory\"` | `factory` (anchored) or `lab` |\n| `judge_gate` | bool | `True` | j-modes: judge AND-gates `finding_recall` (remove-only, quote-verified). `False` = legacy additive judge |\n| `judge_strict` | bool | `True` | Judge failure withholds finding credit (visible) instead of silently scoring ungated |\n| `judge_votes` | int | `3` | Majority vote per gate decision (temperature=0 alone is not deterministic on MoE judges) |\n| `judge_max_retries` | int | `2` | Per-vote retries before the vote is counted as failed |\n| `require_matter_identity` | bool | `True` | Deliverable must reference this matter's entity stem (closes cross-matter deliverable credit) |\n\n## Hybrid architecture note\n\n- **Taskset surface:** versioned matter packages under `tasks/` (`task.json` + `anchors.json` + `documents/`).\n- **Harness surface:** shared tool-using legal agent loop with deterministic rubric weights.\n- Entry point remains `load_environment(...)` for Prime install/eval compatibility.\n\n## Provenance\n\nAll matters are **fully synthetic**. No real client facts. See `NOTICE`.\n\n## Version\n\n`0.5.0` — **Judge gate + deliverable content gates** (JUDGE_RUBRIC_DESIGN.md prototype).\n(1) In `j1`/`j2` the LLM judge is an AND-gate inside `finding_recall` — it can only\nremove lexically-credited findings, each confirmation is verified via a verbatim memo\nquote, and each decision is a `judge_votes`-way majority at temperature 0; the former\nadditive judge weight is folded into `w_fr` (j2: 0.35+0.25 → 0.60). The 0.4.x\n`score_judge_json` \"grounding\" check reused the same lexical matcher as\n`finding_recall` (one mimicry payload inflated both signals); the gate's quote\nverification is independent of that matcher. (2) Every deliverable path (tool save,\nfenced block, chat fallback) is now content-gated (memo keyword + matter entity stem);\npre-0.5.0 the tool-save and fenced-block paths were length-only, leaving a 0.30\ngarbage floor. A deliverable with zero credited findings keeps only half credit.\n(3) Judge failure is fail-loud (`judge_error` metric + strict credit withholding),\nnever a silent 0.0 or silent ungating. Validated 2026-07-21 against grok-4.5\n(prompt `gate-v4-2026-07-21`, 3-vote majority) — **protocol PASS**: surgical shotgun +\ndoc stem-dump 0 confirmed of 19 lexically-credited exploit findings (exploit reward\npinned at the 0.125 capped floor vs honest ≥ 0.764); prose-memo calibration FN 0/30;\nconfirmed sets bit-stable across 3 cache-cleared repetitions; 0 judge errors. Full\nreport: `scripts/judge_gate_validation_grok45.json` (judge model + prompt version\ndisclosed per cross-family judging policy). Pre-0.5.0 eval scores are not comparable.\n\n`0.4.4` — Deliverable filler gate (chat-fallback path): `\"a\"*200`-style filler no\nlonger earns deliverable credit; `weight=0.0` env-args now disable penalties instead\nof falling back to defaults (`or`-falsy bug).\n\n`0.4.3` — Reward-integrity fix: the false-flag penalty is now applied in **every**\nreward mode. Previously `r0` set `w_ff=0.0`, so a model in `r0` could escalate every\ndistractor as a material risk with zero reward cost (all 6 recorded hub evals ran under\n`r0`); `r0` now carries the default `-0.15` false-flag penalty like `r1`/`j*`. Added a\nnormalized `must_not_say_rate` (0..1) penalty term (default `-0.10`, new\n`must_not_say_weight` arg) in all modes, and made the per-mode weight schedule a single\nsource of truth (`reward_weight_schedule`) so both penalty terms are provably monotonically\ndecreasing in their badness rates. The public grading table now documents the real\ndefault (`auto`→`r1`) and both penalties instead of `r0`-only. On recorded samples the only\ntwo false-flagging rollouts drop as expected (ffr=0.5: 0.8286→0.7536; ffr=1.0: 0.4000→0.2500);\nall zero-false-flag rewards are unchanged.\n\n`0.4.2` — Hybrid **small private legal-agent benchmark** (not LAB-parity):\ntopic-bound Fix-style finding recall, structured LLM judge (w=0.25, memo-grounded Fix\nfail-closed so empty/stem/severity cannot freeload J≈1), false-flag penalty (w=0.15),\ndeliverable (w=0.25). Offline attack battery CI\ncovers A1–A7, A10–A15 (stem/severity/free-rec/inventory/empty/verbosity/gold/cross-matter/\nNC/verbatim/FF-bait/D-gate/chat-noise); A8–A9 are content-phase residual probes, not unit\ngates. Max FR still 6/7 (NC never credits). 0.4.2: partial-JSON recovery + higher judge\nmax_tokens so verbose judges (Fable) do not parse_fail→J=0 mid-object. **No GPT** for\nagent/judge in lab policy.\n\n## Roadmap / branch home\n\nProduct plan, attention backlog, and G6 checklist live in the Branch 04 docs:\n\n- `Documents/harness-research-branches/04-prime-practice-area-envs/AGENT_LIABILITY_GYM_PLAN.md`\n- `Documents/harness-research-branches/04-prime-practice-area-envs/GOALS.md` §G6\n- `Documents/harness-research-branches/04-prime-practice-area-envs/BUILD_LOG.md` (2026-07-13)\n\n> Note: with the v0.4.3 penalty weights, the composite reward can go slightly negative\n> (floor ~-0.25 when both penalties saturate with zero deliverable/recall credit).\n\n\n## Changelog\n\n- **0.6.0** (2026-07-29) — **BREAKING reward semantics.** `deliverable_complete`\n  is now conditional on the deliverable containing findings.\n\n  *Measured before* (stub policy through the real `prime eval run` path):\n  echoing the prompt into a memo scored `deliverable_complete = 1.000` while\n  `finding_recall = 0.000` — a full D-weight payout for a well-formed\n  deliverable that found nothing. On the anti-memorization twin\n  (`agent-liability-gym-holdout`) that was **0.300 of max**.\n\n  This mattered most on the holdout: a farmable D term there inflates exactly\n  the number the holdout exists to protect.\n\n  *Change:* `deliverable_complete` returns 0.0 unless `finding_recall > 0` or\n  `finding_spot > 0`. Format is a PREREQUISITE, not credit.\n\n  *Measured after:* worst attack **0.176 -> 0.000** here; **0.300 -> 0.05** on\n  the holdout. Tests 84/84.\n\n","encoding":"utf-8","truncated":false,"total_bytes":14096},"status":null}