Skip to content

BUILD-REPORT-FLT133: autonomy contract package (types + wire schema)

Epic FLT-112 (fleet autonomy substrate). Council 2026-07-18: freeze one contract before building the safety substrate (FLT-113/114/119) or the auto-spawn engine (FLT-115), so nothing guards the wrong chokepoint and everything implements against the same fixed shape.

Scope discipline honored: this is types + schema + docs only. No breaker logic, no freeze enforcement, no spawn engine, no callable production code path. Nothing is wired into the running governor. Auto-spawn (FLT-115) is not built and not callable from anything added here.

Worked in an isolated worktree: wt/WT-6022/FLT-133, checked out at /c/Users/fives/source/repos/ug-FLT133 off origin/master (usage-governor). Not merged.

What was built

C# contract types

src/UsageGovernor.Core/Contracts/Autonomy/ (8 files, namespace UsageGovernor.Core.Contracts.Autonomy), matching the existing repo conventions: sealed records/classes with [JsonPropertyName], [JsonConverter(typeof(JsonStringEnumConverter<T>))] on every enum (precedent: QuotaObservation.QuotaGrade), a ContractVersion const mirroring AgyStatusReport.SchemaVersion, and rationale-carrying XML doc comments in the house style.

File Contents
AutonomyContract.cs ContractVersion = "autonomy-contract/v1"
ConcurrencySemaphore.cs ConcurrencySemaphore (key + CapByTier: GREEN 12 / YELLOW 6 / RED 2 / BLACKOUT 0), AcquireRequest, AcquireOutcome, AcquireResult, ReleaseRequest
FreezeState.cs FreezeStage (Running/FreezeSpawn/FreezeAll), FreezeCommand (incl. Kill), FreezeState
SpendWindow.cs SpendWindowKind ($/min, token/min), SpendWindowDefinition, SpendSample, BreakerTripThreshold, TelemetryHeartbeat, BreakerHaltReason (ThresholdTrip / TelemetryLossHalt)
TaintLevel.cs TaintLevel (Clean/Suspect/Tainted/Contaminated), TaintDemotionRule (+ frozen .Table), TaintClearingRule
AutonomyAuditEvent.cs AutonomyEventKind (7 kinds), AutonomyAuditEvent (ordered/immutable, chained via SequenceNumber/PriorEventId)
ExecutorFloor.cs FloorCategory (7 floored categories), ExecutorCapability, SecretsHandlingRule
IAutonomyGatedAction.cs Marker interface for the single-gate-wire invariant (no members)

Wire-schema doc

docs/autonomy-contract.md -- the cross-language source of truth. Documents all 7 contract areas with JSON examples matching the exact C# serialization, the frozen tables (tier caps, taint demotion matrix), the fail-closed/skip-and-retry/PAUSE-not-drain/cleared-only-by-re-mint rules as prose (not just types), and a "what FLT-113/114/119/132 build against this" section per ticket.

Tests

tests/UsageGovernor.Tests/Contracts/Autonomy/AutonomyContractTests.cs -- 50 tests:

  • Contract version pin
  • CapByTier matches the frozen 12/6/2/0 spec
  • JSON round-trips for every record through GovernorJson.ReadOptions/WriteOptionsCompact (the same options the rest of the repo uses)
  • Every enum serializes as a string, not an ordinal int (spot-checked per value)
  • AcquireResult.Deferred payload contains no "queue"/"position" substring (positive assertion that skip-and-retry has no queue shape to drift into)
  • TaintDemotionRule.Table asserted row-by-row against the spec matrix (Clean/Suspect/ Tainted/Contaminated x clampToSafe/spawnBlocked/cannotCrossFloor/transitivePropagation)
  • AutonomyAuditEvent round-trip with every optional field populated, plus a check that a first-event's priorEventId serializes as explicit null (not omitted)
  • ExecutorCapability.IsFree derivation (floored vs free)
  • IAutonomyGatedAction reflection check: interface, zero members

Build/test results

dotnet build UsageGovernor.sln -warnaserror   -> Build succeeded, 0 Warning(s), 0 Error(s)
dotnet test  UsageGovernor.sln                -> Passed: 514, Failed: 0, Skipped: 0

(514 = full existing suite + the 50 new contract tests; nothing else in the repo was touched.)

What FLT-113/114/119/132 implement against this

  • FLT-113 (breaker): ConcurrencySemaphore acquire/release/defer against CapByTier; §3 spend-window evaluation; fail-closed halt on TelemetryHeartbeat loss; is the first real implementer of IAutonomyGatedAction.
  • FLT-114 (freeze): FreezeCommand/FreezeStage state machine (PAUSE not drain); enforces TaintDemotionRule.Table; enforces the FloorCategory floored/free boundary including the secrets inject-at-exec rule.
  • FLT-119 (observability): renders AutonomyAuditEvent streams and FreezeState; must never surface a secret through AutonomyAuditEvent.Details.
  • FLT-115 (auto-spawn engine): the first sanctioned automatic producer of AcquireRequests -- explicitly not built here, not callable until FLT-113 exists to gate it.
  • FLT-132 (Python fleet-harness): implements a Python mirror of every JSON shape in docs/autonomy-contract.md, including string enums and contractVersion on every payload; that document, not this repo's C# names, is the shared source of truth where the two disagree.

Not done (by design, per the CONTRACT-FREEZE scope)

  • No breaker/semaphore enforcement logic
  • No freeze/kill enforcement
  • No spawn engine, no auto-spawn callable path
  • No wiring into GovernorState, ScanService, the CLI, or any running process
  • No Python-side implementation (FLT-132's job, against docs/autonomy-contract.md)