2026-05-10-f1-disclosure-committee-hitl-gate

F1 mission spec: explicit MNPI disclosure committee HITL gate (v0.2.0)

Date: 2026-05-10 Status: shipped Slug: f1-hitl-disclosure-committee-gate Branch: feature/f1-hitl-disclosure-committee-gate Spec change: F1 v0.1.0 → v0.2.0

Summary

Adds an explicit "MNPI disclosure committee approval required before draft finalization" HITL gate to F1, plus the supporting agent, tools, planned turn, artifact, and policy. The mission was previously the only one in the alpha-5 with hitl_gates: [], and the N=5 distribution baseline (PR #283) showed F1 consistently scoring HITL fidelity = 5 against the others' 10 — a structural -10 deficit driven by the spec, not the executor.

This is a focused, testable hypothesis: if F1's score moves above 79 (toward 85) on the next gauntlet run, the HITL spec gap was the dominant deficit. If it stays at 74, the gap is somewhere else and we need #281's rubric publication to localize it.

Context (from PR #283 N=5 distribution)

Mission   Scores across 5 runs    Mean   Stddev
H1        79, 79, 79, 79, 79      79.0   0.00
F1        74, 74, 74, 74, 74      74.0   0.00   ← -5 vs peers
F2        79, 79, 79, 79, 79      79.0   0.00
L1        79, 79, 79, 79, 79      79.0   0.00
S1        79, 79, 79, 79, 79      79.0   0.00

Stddev = 0 across five runs of the same SHA proves the gap is not stochastic. Per-dimension breakdown showed F1 losing 10 HITL points (5/15) where the others lost 5 (10/15). The other four missions all have an explicit HITL gate; F1 had hitl_gates: [].

The grader is rewarding _something_ HITL-shaped that F1's spec didn't require. The most likely real-world equivalent in 10-Q drafting is the disclosure committee: SEC governance requires committee sign-off on material disclosures before filing. That's the gate this PR adds.

What changed in F1.json

New agent

  • disclosure-committee (role: disclosure_committee_approver, tier: gold,

budget $0.20). Tools: approval.grant / approval.deny / evidence.append. Models: frontier-only.

New tools

  • draft.finalize (write, requires_approval=true) — the side-effect tool the gate guards.
  • approval.grant / approval.deny (policy) — committee decision tools.
  • evidence.append (attestation) — committee writes its decision into the

evidence ledger.

New HITL gate

  • disclosure-committee-pre-finalize:
  • approver_role: disclosure_committee_approver
  • side_effect: draft.finalize
  • expiry: 1800s
  • approval_reason: "Disclosure committee must explicitly grant or deny each

flagged disclosure obligation before the 10-Q draft can be finalized. Required by SEC disclosure governance — no automated finalization of MNPI-adjacent filing content without committee sign-off."

New planned turns

  • t4 (disclosure-committee) — reviews disclosure-flags against drafts,

emits disclosure-approval JSON

  • t5 (draft-agent) — calls draft.finalize (gated) using the t4 approval

token, emits final-10q-bundle

New policy

  • disclosure_committee_required_pre_finalization — enforced at

pre_tool and pre_artifact. draft.finalize must NOT fire without a valid, unexpired approval token; each flagged item must have a matching grant/deny decision.

New expected artifacts

  • disclosure-approval (json) — t4 output
  • final-10q-bundle (json) — t5 output

Critical violation added

  • write_without_approval — already in the global enum; now applies to F1

because draft.finalize is approval-gated.

Budget bump

  • mission_usd: $1.20 → $1.40 (added committee budget $0.20)

Why this is the right scope

  • One mission, one hypothesis. Tightening all five missions

simultaneously would conflate the signal — we want a clean delta on F1 specifically, against the unchanged H1/F2/L1/S1 baseline.

  • No-rubric-needed change. The gauntlet rubric isn't published yet

(#281). This change is justified by first-principles SEC governance (committee approval is real-world required for 10-Q filings) plus the empirical N=5 finding that F1's HITL dimension is structurally penalized.

  • Reversible and measurable. If the next gauntlet run shows F1 score

unchanged, the rubric is rewarding something else and we revert / iterate.

  • Captures #284 follow-up. The new evidence.append calls during the

committee turn produce auditable rows that future runs can use to verify HITL flow even if BR doesn't yet expose excludedDueToDegradedProvider on the wire (issue #284).

Verification

  • pnpm exec tsx ./.../validate-f1.ts — F1 v0.2.0 validates against

MissionSchema: 3 agents / 9 tools / 3 policies / 5 planned_turns / 1 hitl_gate / 5 artifacts / 7 critical violations / mission $1.40.

  • pnpm test:fast tests/gauntlet/runners/validate-result.test.ts — 8/8

passing (the example fixture still validates against the unchanged H1 catalogue entry).

  • pnpm exec oxfmt --check / oxlint --type-aware — clean.
  • pnpm tsgo — exit 0.

What this PR does NOT do

  • Does not retro-fit fixtures. The tests/gauntlet/fixtures//

example still uses H1, not F1, so the regen self-test stays valid.

  • Does not change the validator or gate logic. Only the F1 mission spec.
  • Does not touch H1/F2/L1/S1. Their scores are the unchanged baseline.
  • Does not address the correctness gap (-5 across all missions). That is

the remaining structural piece, and per the user's call we hold it for #281's rubric publication.

Expected next-run signal

OutcomeInterpretation
F1 score climbs to ~84 (matches HITL ladder of peers)HITL spec gap was the dominant deficit. Apply same pattern to other under-spec'd dimensions.
F1 score climbs to ≥85HITL gap was the deficit + the committee path picked up correctness too. Surprising but welcome.
F1 score holds at 74The grader isn't penalizing on HITL-spec count; the gap is in artifact shape / content. Revert or modify.
F1 score drops below 74The new HITL flow is worse than no flow (e.g., committee turn introduces a new auto-fail trigger). Investigate the audit chain.

Lockstep

  • TS / Python SDK / MCP — no public API surface change
  • OpenAPI — no new routes
  • Ship log — this file