The 15-invariant contract

Every invariant has four properties: mechanism (where it's enforced), strength (how unbypassable it is), bypass (how to override on purpose), and event (what's logged when it fires).

Strength key

strong — mechanically blocked unless an explicit, named, logged bypass is in effect. medium — default-on, with a config opt-out. weak — advisory event, no block. deterministic — verified by xCoder TypeScript code (autopilot path), not the LLM.

I-1 to I-2 — The hook layer

#InvariantMechanismStrengthBypassEvent
I-1No Edit/Write/MultiEdit/NotebookEdit on integration branchno-edit-on-integration policystrongXCODER_ALLOW_INTEGRATION_EDIT=1 · workflow.commitDirectly: trueflow.guard.{allow,block,bypass}
I-2No git commit/push on integration branchno-edit-on-integration policystrong(same as I-1)(same as I-1)

I-3 to I-5, I-7 — The engine acceptance layer

#InvariantMechanismStrengthBypassEvent
I-3Tracking issue exists before BRANCH transitiontrackingIssueExistsstrongxc flow override I-3 --reason "..."flow.acceptance.{passed,failed}
I-4Branch matches branchPrefixbranchMatchesPrefixstrong(same as I-3)(same as I-3)
I-5Spec file exists if specsRequiredspecFileExistsIfRequiredmediumworkflow.specsRequired: false(same as I-3)
I-7Conventional-commit format on subjectconventionalCommitFormatstrongxc flow override I-7 --reason "..."flow.commit.format.violation

I-6, I-8 — Commit-time hooks

#InvariantMechanismStrengthBypassEvent
I-6Build / types pass before COMMITtypecheck-must-pass-before-commit policystrongXCODER_SKIP_QA_GATE=1 · --no-verify · --amendflow.guard.{allow,block}
I-8Commit message references tracking issuecommit-must-reference-issue policymediumXCODER_SKIP_ISSUE_REF=1 · --no-verify(same as I-6)

I-9, I-10 — PR & merge

#InvariantMechanismStrengthBypassEvent
I-9PR opened before "done" claimprOpenedBeforeIdle + session-end-pr-backstop policystrongxc flow override I-9 --reason "..."flow.acceptance.{passed,failed}
I-10Removals match stated intentmerge-gate analyzer (intent classification)strong (kernel)n/a — verified, not bypassablegate.intent.classified

I-11 to I-13 — Structural / observability

#InvariantMechanismStrengthBypassEvent
I-11Autopilot phase transitions go through FlowEngineautopilot adapter (observability v1; hard-gate v2)deterministicn/a (architectural)flow.transition
I-12Every state-mutating tool call is observablePreToolUse track-tool-calls + flow.tool.invokedstrongn/aflow.tool.invoked
I-13Every bypass is loggedAll bypass paths emit flow.bypass with reasonstrong (structural)n/aflow.bypass

I-14, I-15 — Supervisor protocol (post-v1)

#InvariantMechanismStrengthBypassEvent
I-14Autopilot questions never block the queuesupervisor protocol — task marked waiting-for-reply, queue continuesdeterministicn/a (architectural)supervisor.question.sent
I-15Resource caps are honoredPre-phase + mid-phase budget checks; halt on exceedstrongxc autopilot continue --over-budgetsupervisor.budget.{warning,halt}

Post-v1 invariants

I-14 and I-15 are scoped to the supervisor protocol — Part 2 of the specs/flow-adherence.md design. The protocol covers non-blocking question/reply, performance profiling, scope-down behavior, and resource caps. Tracked separately from the core engine.

What we explicitly do NOT guarantee

Worth being honest about the limits of mechanism-time enforcement:

Claim we don't makeWhy
LLM-side propertiesLLMs explore. The engine catches what it can, but inside a phase the agent can do anything its toolbox permits.
Cryptographic non-bypassA motivated user can chmod -x .claude/hooks/.... xCoder protects against drift, not adversaries.
Cross-repo guaranteesEach repo is its own FlowEngine instance. The engine doesn't track state across repos.
Code-quality enforcementThe contract is about flow-following, not code review. The merge-gate handles intent verification; static review is out of scope here.

Next