Governance problems in software organizations often share a root cause: rules defined in one place are enforced differently in another, not enforced at all in a third, and unknown to a fourth. A security policy lives in a Confluence page; the Git hook that supposedly enforces it was written two years ago and has not been updated since; the CI pipeline has a slightly different interpretation; the AI agent has never heard of any of it.

The policy bundle compiler in coding-ethos exists to eliminate this fragmentation. Its job is to take all the sources of policy truth – engineering principles, repository-specific rules, enforcement configuration – and compile them into a single versioned artifact that every enforcement surface reads from.

What the compiler does

The policy compiler is invoked as:

“`bash

coding-ethos policy compile –repo .

“`

It reads four input files:

  • `coding_ethos.yml`: the shared engineering principles – the organizational values that own the policies.
  • `repo_ethos.yml`: an optional repository-specific overlay that extends or adjusts the shared principles for a particular codebase.
  • `config.yaml`: the shared enforcement configuration – which evaluator types are enabled, what default severities apply, which linters are managed.
  • `repo_config.yaml`: repository-specific enforcement settings – which policies apply to this repo, any path-specific overrides, sandbox read/write path additions.

The compiler validates all inputs, merges overlays, normalizes principles, attaches principles to policies, compiles evaluators, builds dispatch indexes, and writes the output artifact.

The output: policy-bundle.json

The compiled artifact is a JSON file called `policy-bundle.json`. The design choice here is explicit: “The compiled bundle is data, not code.”

This distinction matters. “Data, not code” means:

  • The bundle does not execute anything itself. Runtime components implement evaluators; the bundle configures which policies are enabled and how they behave.
  • The bundle can be read by any language – Go, Python, Node.js, shell scripts – without requiring a specific runtime.
  • The bundle can be hashed, versioned, diffed, and audited like any other data file.
  • A stale bundle cannot masquerade as a current one – runtime components check the bundle’s metadata hash and fail if it does not match the source inputs.
See also  Would Ethosure have caught this? The OpenAI agents that spammed RubyGems in May

The bundle has a specific structure:

Principles section: normalized principle records, each with an ID, directive, summary, quick reference items, and agent hints. Hooks and linters can produce accurate, principle-grounded advice without loading the full rendered ethos document.

Policies section: policy rules with their IDs, categories, principle linkages, default severities, supported enforcement modes, messages, suggestions, defense layer settings, applicable file patterns, and evaluator references.

Dispatch section: optimized indexes for fast runtime lookup. The dispatch layer maps hook events to applicable policies, linter modes to applicable checks, and Git operations to applicable rules. This is what makes hooks fast – they do not need to traverse the full policy graph on every invocation; they look up the pre-compiled dispatch table for the current event type.

The semantic graph underneath

While the bundle is serialized as JSON for runtime consumption, it is logically structured as a semantic graph – a network of nodes (principles, policies, evaluators, dispatch entries) and typed relationships (a policy is “explained by” a principle; a policy is “evaluated by” an evaluator). This graph structure means every decision is explainable by traversal: why was this action blocked? → which policy applied? → which principle owns that policy? → what is the directive for that principle?

The graph also enables future export to RDF (Resource Description Framework), a format used by knowledge management and linked-data systems. The JSON schema is designed so that a full-fidelity RDF export is possible without information loss.

Compiler pipeline and validation

The compiler runs this pipeline:

  1. Load source files.
  2. Validate source schemas – fail fast for unknown policy IDs, invalid severities, missing evaluator implementations, or invalid path matchers.
  3. Merge repository overlays.
  4. Normalize principles.
  5. Normalize enforcement configuration.
  6. Attach principles to policies.
  7. Compile evaluators.
  8. Build dispatch indexes.
  9. Write `policy-bundle.json`, `policy-metadata.json`, and `policy-summary.md`.
  10. Write a bundle hash and source hashes.

The hash metadata is the stale-detection mechanism. Runtime components load the bundle hash at startup and verify it against the current source file hashes. If the sources have changed since the last compilation, the runtime can detect the discrepancy and refuse to operate on a stale policy – or trigger an automatic recompile.

See also  Would Ethosure have caught this? The OpenAI ExploitGym escape into Hugging Face

The practical governance benefit

For organizations deploying AI agents across multiple repositories, the policy bundle model has a significant practical advantage: policy governance scales through configuration, not code duplication.

A shared `coding_ethos.yml` defines the organization-wide principles. Each repository has a thin `repo_ethos.yml` overlay that customizes behavior for its specific context. The compiler produces a bundle per repository, but all bundles share the same principled foundation. When the organization updates a principle – for example, adding a new security policy – that update flows to every repository’s compiled bundle on the next compile, not by patching N separate hook scripts.

The CLI also supports inspection and debugging:

“`bash

coding-ethos policy validate –repo .

coding-ethos policy explain python.conditional_imports

coding-ethos policy dump –json

coding-ethos policy doctor –repo .

“`

`policy explain` shows which principle justifies a rule and what evaluator implements it. `policy doctor` checks for configuration inconsistencies before they become runtime surprises. These tools make the single source of truth interrogable – not just a black box that produces decisions.