ENFORCEMENT-LEDGER Design + plan agent-harness motor-fakta verifierad mot källor

Enforcement capability ledger: paritet mellan motorer, inte en Claude-hook-spegel

När du jobbar i Codex eller Gemini beter sig agenten annorlunda och mindre säkert. Inte för att reglerna saknas, utan för att den inte vet vilka skydd Claude får mekaniskt. Fixen är en kanonisk ledger nycklad på risk-intent: per skydd, vad varje motor faktiskt kan upprätthålla, och var den failar open.

Mål och klart-kriterium

En kanonisk enforcement-ledger som ger varje motor paritet via medvetenhet, inte via samma mekanik. Den är klar när:

Avgränsning

I scope: ledger-strukturen, nyckling på risk-intent, per-motor-grader för de hårdaste skydden, fail-läge-dimensionen, gotcha-konvergensen, render-modellen, adapter-rättningen.

Uttryckligt uppskjutet: full population av alla 16 policyer gånger 3 motorer med källverifierad grad per rad (görs fas för fas), och faktisk auto-installation av genererade hooks (gated, senare beslut).

Kärnan: premissen "bara Claude har hooks" är fel

Codex bias-checken rev upp antagandet, verifierat mot primärkällor: både Codex CLI (developers.openai.com/codex/hooks) och Gemini CLI (geminicli.com/docs/hooks) har hook-system. Men de är olika starka, och båda failar open. Codex PreToolUse är uttryckligen "a guardrail rather than a complete enforcement boundary" (fångar inte alla shell-vägar, ej-stödda fält gör att tool-call fortsätter). Gemini defaultar till "Allow" om hookens stdout inte är ren JSON. Gemini har äkta hard block på BeforeTool; Codex har en native approval gate (PermissionRequest) som Gemini saknar. Slutsats: paritet byggs inte genom att spegla Claudes 32 hooks, utan genom en ledger som per skydd säger vad varje motor faktiskt klarar, och var den brister.

Samma policy, tre olika enforcement-tak per motor En policy-nod hogst upp (exempel: filradering) med pilar ner till tre motor-boxar. Claude: hard block via Bash-gate. Codex: soft guardrail som failar open och inte fangar alla shell-vagar. Gemini: hard block via BeforeTool men failar open vid trasig JSON. Policy: filradering nyckel: risk-intent (inte hook-namn) Claude hard block PreToolUse Bash 32-hook-lagret, etablerat fail: stängt Codex soft guardrail PreToolUse ej alla shell-vägar, approval gate finns fail: open Gemini hard block BeforeTool deny deterministiskt, ingen kringgång-cit. fail: open (JSON)
hard block soft guardrail failar open
Ledger-formen: exempelrader (5 av 16 policyer)
Policy (risk-intent)ClaudeCodexGeminiFail-läge andra motorer
Secret exposure (master-lösen ut)hardguardrail + gatehardopen vid scriptfel
Filradering (rm, destruktivt)hardguardrailhardCodex: ej alla shell-vägar
Em-dash i kund-texthardguardrailhardopen vid trasig JSON
Publikt GitHub-repogateguardrailhardCodex: ekvivalent väg
Subagent-modellvalhardsaknastextCodex: SubagentStart kan ej stoppa start

Grader: hard = deterministisk blockering. guardrail = soft, kan kringgås eller failar open. gate = approval allow/deny. text = bara medvetenhet. saknas = ingen mekanism. Fullständig population av alla 16 policyer sker fas för fas med källkoll per rad.

Svåra-att-ångra beslut
Primärnyckel är risk-intent, inte hook-namn och inte symptom. Codex poäng: enforcement byggs runt invarianter (secret exposure, destructive shell), inte runt Claudes hook-katalog. Annars blir Claude norm.
Symptom är sekundärindex. Det är det reaktiva uppslaget du bad om: du klagar i symptom, agenten slår upp policyn och läser sin motors kolumn.
Handkurerad ledger som kanon (väg B, inte generera ur Claudes hooks). Codex valde B över min ursprungliga A: en generator ur Claude-hooks centrerar Claude och ärver Claude-specifika begrepp. Position bytt, källan var den verifierade kapabilitets-bilden.
Gotcha-loggen och ledgern är två vyer av samma kanon. Incidentloggen (reaktiv, upkeep/gotchas.md) matar ledgern (proaktiv). Vid 2+ incidenter formaliseras en rad eller, helst, ett hook (solve, don't punt).
Självbygge är gated. En agent får föreslå hooks och config-diffar ur ledgern, men installation kräver review. En hook som skriver hooks är en bootstrap-risk som kan cementera fel.
Rekommenderad ansats

A. Bygg ledger-filen (kanon)

kärnanny fil
policies/enforcement-ledger.md · MAP.md (trigger-rad samma commit)

B. Rätta adaptrarna + render per-motor-vyer

troligedit
AGENTS.md, GEMINI.md

C. Koppla gotcha-loggen + reaktivt uppslag

troligny fil
upkeep/gotchas.md (Motor / symptom / remedy / status)
Fil-karta: en ledger-rad
# policies/enforcement-ledger.md, en rad per risk-intent
| risk-intent | claude | codex | gemini | fail | test | symptom |
| filradering | hard (PreToolUse Bash) | guardrail* | hard (BeforeTool) | open | probe-rm | "den raderade en fil" |
# *guardrail: Codex fangar bara enkla shell-anrop, ej unified_exec/ekvivalent vag
# sekundarindex: symptom -> rad. gotcha-logg matar nya rader vid 2+.

Marginalnot: graderna kommer ur den verifierade kapabilitets-workflowen (Codex-doc + Gemini-doc, adversariellt granskad). Tre grader flaggades osäkra och källverifieras vid population.

Implementationsordning
  1. Bygg ledger-skelettet + MAP-trigger (fas A)
  2. Populera de hårdaste skydden först (secret, radering, em-dash, publikt repo) med källverifierad grad per rad
  3. Rätta adaptrarna (fas B)
  4. Koppla gotcha-loggen, seed HG-001 och HG-002 (fas C)
  5. Kör validation/probes per policy per motor som gate
  6. Först när bevisad: render per-motor-vyer, och senare (gated) self-bootstrap
Risker
Fail-open på andra motorer (blockerande). Codex och Gemini failar open vid scriptfel eller ej-stödda fält. En "hard"-grad i ledgern får aldrig läsas som vattentät på Codex/Gemini. Därför är fail-läge en egen kolumn, inte en fotnot.
Tre osäkra grader. Verifieraren flaggade Codex PreCompact/PostCompact hard-block och Gemini samlad hard-block som vilande på fält utan ordagrant citat. Källverifiera vid population innan graden låses.
Drift. En handkurerad ledger kan glida från HOOKS.md. Möts av en upkeep-check som diffar ledger-rader mot hook-indexet.
Per-motor-nyckling är en Viva-utvidgning. Anthropics modell-axel är Haiku/Sonnet/Opus inom Claude, inte tvärs leverantörer. Märk i ledgern att detta är vår generalisering, inte Anthropic-doktrin.
Verifiering (e2e-smoke)

Inte bara att ledgern finns: en riktig Codex-session ges ett symptom (t.ex. "den var på väg att radera en fil"), slår upp policyn, läser sin grad och självupprätthåller med bevis. Plus validation/probes som kör ett testfall per policy per motor och rapporterar grad-utfallet mot ledgern, så drift och overclaim syns mekaniskt.

Öppna frågor
1. Ledger-format: en bred markdown-tabell eller en rad-per-fil? rekommenderat: en tabell-fil, läsbar och diffbar
2. Gotcha-logg och ledger i samma fil eller separat? rekommenderat: separat, loggen i upkeep/ matar ledgern i policies/
3. Fail-läge som egen kolumn eller fotnot? rekommenderat: egen kolumn, för viktigt för att gömma
4. Verifiera de tre osäkra graderna nu eller vid population? rekommenderat: vid population, källkoll per rad
5. Koppla in skill-pipeline-spänningarna (gerund-namn, old-patterns) här? rekommenderat: nej, separat beslut