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.
Recommended repository layout
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:setupdownloads 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 |
|---|---|
|
On, locked. The condition always applies; a developer may add stricter conditions but cannot strike it. |
|
Off, locked. The condition never applies and a developer cannot enable it. |
|
On by default; a developer may strike it, and the strike is recorded. |
|
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:
-
Download the organization’s
policy.yamlto.akka/governance/policy.yaml, when agovernance-policy-urlis configured (see Applying the policy in every project). -
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).
-
Materialize the result: the MCP configuration and the resolved conditions with their lock state, on/off, and provenance, ready for
status,conform, andship.
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) |
|
macOS / Linux / Windows |
|
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:setupdownloads the policy to.akka/governance/policy.yamland refreshes it when it changes centrally; -
every conformance check —
akka specify status,conform, andship, plus theakka_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--policythat 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 |
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.