Policies

Organizations govern spec-driven development with policy as code — a version-controlled definition of the mandatory controls every project inherits: which exit conditions are required, which mode is allowed, what "ship" does, and the toolchain to use. Developers can make these controls stricter, never weaker.

The governance policy

The policy is a single file, policy.yaml, that your organization authors, owns, and controls. Version-control it — most teams keep it in a dedicated git repository (for example github.com/manulife/akka-specify-governance), governed by your normal access controls: private repository, SSO, RBAC, and branch protection. Akka does not host it.

The CLI does not require any particular host, provider, or repository name. It fetches the policy.yaml at the URL your organization configures (see Applying the policy in every project), so the policy can live in a git repository, an internal mirror, or any location the CLI can read over HTTPS. A git repository is recommended simply because it gives you version history and a place to run CI that enforces the policy — see Drift and enforcement.

When you keep the policy in a git repository, a typical layout holds one required file and one recommended one:

akka-specify-governance/       # name it whatever you like
├── policy.yaml                # required — the organization policy (schema below)
└── .github/workflows/         # recommended — CI that enforces the policy
    └── conformance.yml
policy.yaml

The single source of truth for the policy. /akka:setup downloads it from the URL you configure; its schema is described below.

CI workflow

A pipeline that runs the Akka conformance check against policy.yaml. Because a developer can bypass local checks, the organization’s own CI is the enforcement backstop — the gate a change must pass to merge or ship. Use the .github/workflows/ directory on GitHub, or the equivalent for your provider.

Governance levels

Each condition in the policy is assigned a governance level — a clean 2×2 of default state (on or off) and developer configurability (locked or configurable):

Level Meaning

always-apply

On, locked. The condition always applies; a developer may add stricter conditions but cannot strike it.

never-apply

Off, locked. The condition never applies and a developer cannot enable it.

on-but-dev-configurable

On by default; a developer may strike it, and the strike is recorded.

off-but-dev-configurable

Off by default; a developer may opt in.

Only the two locked levels always win. Where the policy is silent, the platform-intrinsic conditions and the recommended-default library fill in. The policy sets a minimum, not a maximum: it constrains only in the stricter direction.

What a policy defines

Alongside conditions and their levels, a policy sets:

  • the allowed conformance mode(s) and whether the mode is locked (see /akka:mode);

  • the ship definition — the organization-authored terminal action(s) and the conditions that must be green before ship fires (see Shipping and receipts);

  • waiver rules — whether waivers are allowed, and whether they require approval;

  • the toolchain pin — the approved Akka CLI, plugin, and SDK versions.

Exit conditions in a policy

Each entry under exit_conditions is one of two things:

Adopt a library condition — reference an existing condition from the default library by its id and set its governance level (and any parameters). The id is how Akka Specify knows the entry is an exit condition: it resolves the id back to the library, which defines the condition’s type, invariant, and pass predicate, and applies it to every project the policy governs. The covering auditor is one of the three auditor kinds — a built-in or authored introspective check, a provisioned harness asset, or a delegated attestation — resolved for each ecosystem the project uses.

- ref: PROJ-SCAN-SAST-CLEAN        # an id from the default library
  level: ALWAYS-APPLY
- ref: PROJ-TEST-COVERAGE
  level: ON-BUT-DEV-CONFIGURABLE
  params: { min_line_coverage: 0.80 }

Define a corporate condition — to require something the library does not cover, declare a new condition inline with its own id and the fields the tooling needs to check it: the dod_type it belongs to, the invariant in business terms, the binary pass predicate, an inline introspective auditor (its run command and applies_to), and its autonomy (for example human-signoff). This is how a new organization-specific exit condition is created and added to projects.

- id: CORP-DATA-RESIDENCY-EU       # a new corporate condition
  level: ALWAYS-APPLY
  tier: product
  dod_type: security-compliance
  invariant: "customer PII is stored only in EU-region datastores"
  pass: "count(pii_entities where region not startswith 'eu-') == 0"
  auditor:
    run: ["./scripts/check-pii-region.sh"]
    applies_to:
      requirement: node
      module: .
  autonomy: human-signoff

See the exit condition schema for the full field set, and the default library for the adoptable ids.

Example policy.yaml

A representative policy. Adopt library conditions by ref, set each one’s governance level, and define corporate conditions inline within a type:

apiVersion: akka-specify/v1
kind: OrgPolicy
org: manulife
version: 3                     # bump on every policy change

mode:
  default: enforced            # enforced | a-la-carte
  allowed: [enforced]
  locked: true                 # developers cannot drop out of Enforced

ship:                          # org-authored terminal action(s)
  steps:
    - name: push-to-governed-repo
      action: "git push origin release"
  in_scope_auditor_tiers: [product-local, project, process]
  emit_receipt: true

toolchain:
  akka_cli: "3.0.65"           # approved version; drift triggers /akka:setup
  locked: true

exit_conditions:
  # The two locked process-integrity gates: always on, cannot be struck
  - ref: PROC-AUDITOR-COVERAGE
    level: ALWAYS-APPLY
  - ref: PROC-ADEQUACY-REVIEWED
    level: ALWAYS-APPLY
  # Adopt and lock library conditions by id
  - ref: PROJ-SCAN-SAST-CLEAN
    level: ALWAYS-APPLY
  - ref: SEC-SECRETS-NOT-COMMITTED
    level: ALWAYS-APPLY
  - ref: PROJ-TEST-COVERAGE
    level: ON-BUT-DEV-CONFIGURABLE
    params: { min_line_coverage: 0.80 }
  # A corporate condition, defined inline within a type
  - id: CORP-DATA-RESIDENCY-EU
    level: ALWAYS-APPLY
    tier: product
    dod_type: security-compliance
    invariant: "customer PII is stored only in EU-region datastores"
    pass: "count(pii_entities where region not startswith 'eu-') == 0"
    auditor:
      run: ["./scripts/check-pii-region.sh"]
      applies_to:
        requirement: node
        module: .
    autonomy: human-signoff

completion_policy:
  default_preset: all-must-pass          # confidence-pass | percent-threshold | all-must-pass
  human_review_required_for: [security-compliance, data-integrity]

waivers:
  allowed: true
  require_approval_for: [ALWAYS-APPLY]   # locked-condition waivers need approval
  default_expiry_days: 30
  approvers: ["@manulife/platform-governance"]

rollout:
  mode: warn-then-enforce                # newly-locked conditions don't turn projects red overnight
  enforce_after: "2026-09-01"

required_surfaces:                       # harness surfaces the coverage gate expects
  - vault                                # each must be activated or attested per project
  - siem
documentable:                            # ids the coverage gate accepts as satisfied by a docs file
  - CORP-DATA-RESIDENCY-EU

How a project sources the policy

/akka:setup resolves the policy for a project:

  1. Download the organization’s policy.yaml to .akka/governance/policy.yaml, when a governance-policy-url is configured (see Applying the policy in every project).

  2. Merge the layers — the default library, then the organization policy, then developer additions — applying locks (tighten-only: a developer may add conditions but never loosen a locked one).

  3. Materialize the result: the MCP configuration and the resolved conditions with their lock state, on/off, and provenance, ready for status, conform, and ship.

Because the policy is fetched fresh rather than vendored into the project, re-running /akka:setup always picks up the organization’s current policy, never a stale template.

Applying the policy in every project

A policy is a set of standards an organization defines once, centrally, and enforces everywhere. The governance repository holds that central definition; for it to take effect, each developer’s CLI has to know where the policy lives and that it is mandatory. That is a one-time setting owned by IT — not a per-project choice — deployed through the Akka CLI’s managed system configuration, the same read-only channel enterprises already use to push other defaults.

Platform Managed configuration file

macOS (MDM)

/Library/Managed Preferences/io.akka.cli.plist — deploy via Jamf, Intune, or another MDM

macOS / Linux / Windows

config.yml under the platform’s system configuration directory

Set the governance-policy-url key to the raw URL of the repository’s policy.yaml:

governance-policy-url: https://raw.githubusercontent.com/manulife/akka-specify-governance/main/policy.yaml

With this configured:

  • /akka:setup downloads the policy to .akka/governance/policy.yaml and refreshes it when it changes centrally;

  • every conformance check — akka specify status, conform, and ship, plus the akka_ec_* MCP tools — applies the policy by default, with no flag to pass;

  • the central policy always wins: a developer can add stricter conditions with --policy, but can never weaken the organization’s policy, and any --policy that tries is ignored.

Because the setting lives in a file that IT controls and the developer cannot edit, the policy cannot be skipped by leaving off a flag. The --policy flag is for local experimentation only, and is superseded whenever a central policy is in place. This is the same managed-configuration channel that already controls other CLI defaults (such as project templates and the AI context bundle); for the full key list, file locations, and an MDM profile example, see System Configuration.

The CLI fetches policy.yaml over plain HTTPS, so the URL must work without an interactive login. If the governance repository is private, publish policy.yaml somewhere the CLI can read it non-interactively — for example a URL that carries an access token, an internal mirror, or a copy your IT team syncs onto each machine — rather than a link that would prompt the developer to sign in.

Drift and enforcement

When the organization changes the policy, a developer picks up the new version by running /akka:setup again, which re-downloads the current policy.yaml.

The enforcement backstop is the organization’s own CI, which reads the same policy and fails the build if the policy is not met. The local CLI is advisory and guided; CI is the gate — the same way enterprises already enforce standards. You can bypass checks locally, but you cannot merge or ship past CI.