Skip to content

Governance Model

The bijux-iac governance model separates declaration, planning, application, and audit. Each stage answers a different question and holds different write authority.

Control-Plane Stages

Stage Question State access Result
inventory validation Is the declared family complete and structurally valid? committed source only validated inventory or explicit rejection
deterministic rendering Do committed Terraform inputs equal the inventory projection? committed source only reviewable target set
plan What would change relative to imported live rulesets? read live state; no governance write Terraform plan and validation evidence
apply Can the accepted declaration be made active without racing another writer? repository-administration write updated settings and rulesets
audit Does live GitHub state now equal the declaration? read live state equality evidence or drift failure

Plan Before Write

sequenceDiagram
    participant Author
    participant PullRequest as Pull request checks
    participant GitHub as Live GitHub
    participant Terraform

    Author->>PullRequest: change inventory
    PullRequest->>PullRequest: validate and render
    PullRequest->>GitHub: read and import rulesets
    PullRequest->>Terraform: calculate plan
    Terraform-->>PullRequest: proposed changes
    PullRequest-->>Author: reviewable plan, no write

Planning against imported live resources matters because an empty local state would otherwise describe existing rulesets as new. Import failure is a hard stop, not permission to create around unknown state.

Serialized Apply

sequenceDiagram
    participant Main as Accepted main revision
    participant Apply as Serialized apply workflow
    participant Settings as GitHub settings API
    participant Terraform
    participant Audit

    Main->>Apply: trigger accepted declaration
    Apply->>Settings: patch repository settings
    Apply->>Terraform: import and apply rulesets
    Terraform-->>Apply: apply result
    Apply->>Audit: compare declared and live state
    Audit-->>Apply: match or failure

The workflow concurrency group permits one governance apply at a time. This is an ownership control: two accepted revisions cannot concurrently rewrite the same family settings and leave an ambiguous final state.

Admission And Application Are Different

Repository-local policy workflows protect changes entering each repository. bijux-iac applies the external settings that require those workflows. The two surfaces reinforce each other but should not be confused:

  • repository workflows expose named, reviewable check contexts;
  • branch rulesets require those contexts before merge;
  • the control plane audits that the requirements remain active;
  • product checks remain owned by the product repository.

Approval Is A Required Check

The default-branch ruleset requires pull requests but sets the native approving review count to zero. Approval policy is enforced through the required policy / pr approval workflow:

  • an owner-authored pull request must carry owner-self-signoff;
  • a non-owner pull request must have the owner's latest review state recorded as approved;
  • labeling, new commits, review dismissal, and draft transitions rerun the policy check.

This separates merge mechanics from approval authority while retaining a single required context that the control plane can audit across repositories.

Failure Policy

The governance path rejects rather than silently normalizes:

  • a missing or duplicate family member;
  • an obsolete or unexpected repository identity;
  • an unsupported delivery state;
  • generated Terraform inputs that do not match inventory;
  • a missing required status context;
  • a failed live-resource import;
  • a difference between declared and active settings after apply.

The correct response is to reconcile source or live state. Weakening the validator would destroy the evidence that the control plane exists to provide.

Partial Apply Recovery

Repository settings and Terraform-managed rulesets cross separate APIs. A serialized workflow prevents competing writers, but it cannot turn those APIs into one transaction. Recovery begins by observing the effective state rather than assuming that every earlier step rolled back when a later step failed.

flowchart TD
    failure["Apply or audit failure"] --> freeze["Keep governance writes serialized"]
    freeze --> inspect["Identify accepted revision,<br/>completed writes, and live state"]
    inspect --> declared{"Is the accepted declaration still correct?"}
    declared -->|yes| forward["Correct cause and reapply declaration"]
    declared -->|no| revert["Accept a reviewed declaration<br/>for the intended prior posture"]
    forward --> audit["Run full live audit"]
    revert --> audit
    audit --> equal{"All modeled fields equal?"}
    equal -->|no| inspect
    equal -->|yes| close["Close with revision-bound equality evidence"]

The choice is between two governed declarations, not between “forward” and an unrecorded administrator edit. Forward correction is appropriate when the accepted policy remains the intended policy. Restoring a prior posture first requires that posture to be represented by a reviewed source revision. A manual intervention may be necessary to recover access, but it creates drift until the declaration and full audit agree again.

Failure point State that may already have changed Recovery evidence
before import or plan none from this execution corrected import or validation result
during settings writes a subset of repository settings live settings comparison across the declared family
during Terraform apply settings and a subset of rulesets imported rulesets plus full settings and ruleset audit
during post-apply audit writes may be complete; equality is unknown successful rerun of the complete live audit

Retrying without classifying the failure can conceal a mixed state. A retry is safe only after the operator knows which declaration remains authoritative, why the previous execution failed, and whether prerequisites such as required status contexts are actually available.

Resolve Indeterminate Remote Outcomes Before Retrying

A timeout or interrupted runner does not prove that GitHub rejected a write. The request may have failed before admission, completed without delivering its response, or applied only part of a sequence. Blind retry can therefore turn an observation failure into additional mutation.

Observed outcome Safe next evidence
explicit validation or authorization rejection correct the declared input or authority; no state change should be inferred
explicit rate limit or service-unavailable response preserve retry guidance, wait within policy, then re-observe live state before planning
connection loss before response classify the write as indeterminate and read the affected control
runner cancellation during a write sequence inventory every operation that could have started and audit the complete affected family
acknowledged write followed by audit mismatch retain the request and response, stop further mutation, and reconcile declared versus effective state

Backoff protects the remote service but is not a correctness strategy. A retry is justified only after effective state shows that repeating the operation is still required and the accepted declaration remains authoritative. Logs must identify the operation without retaining administration credentials or sensitive response material.

Drift And Reconciliation

stateDiagram-v2
    [*] --> Declared
    Declared --> Planned: import live state and calculate change
    Planned --> Applied: accepted revision writes settings and rulesets
    Applied --> Verified: live audit matches inventory
    Applied --> Drifted: audit finds a mismatch
    Verified --> Drifted: later manual or external change
    Drifted --> Planned: reconcile declaration or live state

Drift is not automatically classified as malicious or accidental. The audit establishes a mismatch; maintainers must decide whether the accepted inventory or the live system is wrong, then reconcile through the governed path.

Repository settings and Terraform-managed rulesets are written through two different APIs. The apply workflow serializes writers and audits afterward, but it does not claim one cross-API transaction or automatic rollback. If a later write fails after earlier settings changed, the failed workflow and live audit boundary require explicit reconciliation.

Reconciliation Closure

A governance incident is not closed when the corrective workflow merely finishes. Closure requires a complete live audit against an identified accepted revision and an explanation of the original mismatch. If recovery changed the intended policy, the replacement declaration and its review are part of the evidence chain.

The audit observation is time-bounded. A later administrator action can create new drift, so the closure statement should say when the state was observed and which modeled surfaces were compared. Unmodeled organization controls, secret access, product check behavior, and historical continuity remain outside that claim.

Credential Boundary

Local tests and contract validation are network-free. Planning needs read access to current governance state. Apply and live audit need administration access across the governed repositories.

The administration token is a high-impact credential. Its safety depends on:

  • protected secret storage;
  • use only inside the controlled workflow path;
  • absence from committed files and generated reports;
  • serialized mutation;
  • an immediate post-write audit;
  • fail-closed behavior when state ownership cannot be established.

Recover Through Explicit Emergency Authority

An ordinary apply path can become unavailable because a required check cannot report, the workflow environment is inaccessible, a permission was removed, or the ruleset itself blocks the correction. Emergency administration may be necessary, but it is a distinct authority state—not an invisible shortcut inside normal operations.

stateDiagram-v2
    [*] --> Governed
    Governed --> EmergencyDeclared: ordinary correction path unavailable
    EmergencyDeclared --> Contained: scope, operator, approval, and expiry recorded
    Contained --> AccessRestored: minimum live intervention
    AccessRestored --> Reconciled: reviewed declaration and full audit agree
    Reconciled --> Governed: emergency authority revoked
    AccessRestored --> Drifted: declaration and live state differ
    Drifted --> Reconciled: governed correction completes

The emergency record should identify:

  • the blocked ordinary path and consumer consequence;
  • the exact repositories, settings, or rulesets in scope;
  • who authorized and performed the intervention;
  • the live state before and after the intervention;
  • the expiry or revocation of elevated authority; and
  • the accepted declaration and complete audit that closed the drift.

Emergency access should restore the governed path, not become a parallel governance channel. A successful manual edit is containment evidence. Only a reviewed declaration plus a matching full audit returns the affected controls to ordinary governed state.

Treat Audit Freshness As Dependency Freshness

An audit is an observation over a named target and field population. Its result can become stale when the declaration, audit implementation, repository membership, GitHub behavior, or live administration state changes.

Change after audit What must be reconsidered
inventory or rendered target changes target population and expected field values
audit implementation changes which fields and comparison semantics the prior result actually covered
repository transfer, rename, or archival owner, target identity, residual rulesets, and credential reach
manual or external administration equality for the affected repositories and fields
required workflow context changes whether the protected path can still produce the required result

Calendar recency alone is insufficient. A recent audit performed before a material change cannot support the post-change state, while an older audit can remain the latest valid observation only if no dependency that affects its claim has changed.

What Audit Proves

The live audit proves equality for the settings and ruleset fields represented by the inventory and audit implementation at the observed revision. It does not prove:

  • historical uptime of repository controls;
  • product correctness behind a required check;
  • organization settings outside the modeled scope;
  • that a future manual administrator action cannot introduce new drift.

Continuous trust comes from repeating the audit after governed changes and treating drift as an actionable failure.

Continue with Repository Coverage for the governed family or Bijux Standards for the separate shared-content authority.