# Eou Audit

> Audit an EOU spec — classification, authority, validators, failure modes, trace, blast radius, responsibility. <example> Context: Auditing an EOU before promoting it to active. user: "$eou-audit eou-diagnose" assistant: "Loading spec + governance + maturity model; report goes to foundry/audits/eou-audits/." </example> <example> Context: Re-audit after applying an ECP. user: "$eou-audit foundry/eous/audit-foundry.yml" assistant: "Re-running. Rule 94 (executor != approver) is hard-checked first." </example>

- Skill: `xiaolai/eou-audit` (Agent Skill)
- Install (CLI): `npx skillmds@latest add xiaolai/eou-audit`
- Raw SKILL.md: https://api.skillmd.com/api/skills/xiaolai/eou-audit/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: xiaolai (https://skillmd.com/u/xiaolai)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/xiaolai/eou-audit

---


# EOU Audit

Audit an EOU spec at `$target`, or all specs in `foundry/eous/` and `foundry/meta-eous/` when no target is given.

## Inputs

- `$target` (optional) — EOU ID resolved to `foundry/eous/{id}.yml` or `foundry/meta-eous/{id}.yml`, or a direct file path. When omitted, audits all specs in both directories.
- `captured_workflow` (optional, ECP-0017 / Rule 96) — auto-discovered from `foundry/captured-workflows/cw-*.yml`. When present with all four `human_approval` gates populated AND the audited spec's `target_object` is not in `rule_96_exempt_target_objects`, the Value Operationalization Test runs.

## Required reading

1. `foundry/constitution.yml`
2. `foundry/governance.yml`
3. `foundry/failure-taxonomy.yml`
4. `schemas/eou.schema.yml`
5. Target EOU spec(s)

## Stop conditions

Stop and record a `critical` finding before proceeding if:
- `schemas/eou.schema.yml` does not exist — cannot validate spec completeness.
- `$target` is provided but does not resolve to any spec file in `foundry/eous/` or `foundry/meta-eous/`.

## Procedure

### Step 1 — Deterministic validation

```bash
python3 scripts/validate_foundry.py
```

Record any schema errors as `critical` findings before proceeding.

### Step 2 — Faceted classification (per EOU)

Verify all six classification facets are present and use schema-allowed values:

| Facet | Allowed values |
|-------|----------------|
| `function` | `generate \| specify \| validate \| diagnose \| promote \| refactor \| audit \| propose \| activate \| implement \| retire` |
| `automation_mode` | `deterministic \| LLM_assisted \| hybrid \| human_executed` |
| `authority_level` | `suggest_only \| draft_only \| write_candidate \| write_inactive \| mutate_active \| approve \| publish` |
| `risk_level` | `low \| medium \| high \| critical` |
| `lifecycle_stage` | `candidate \| draft \| simulated \| pilot \| active \| monitored \| stable \| deprecated \| retired` |

Finding: any missing or out-of-vocabulary value → severity `high`.

### Step 3 — Authority and blast-radius consistency

- `mutate_active` or higher requires `risk_level: high` or `critical`.
- `blast_radius.forbidden_scope` must be declared for `mutate_active` or higher.
- `authority_level` must not exceed what the EOU's `function` requires.

Finding: mismatched authority/risk → severity `high`.

### Step 4 — Required structural fields

Each EOU must declare: `purpose` (with `non_goals`), `inputs` (with `forbidden_assumptions`), `context_manifest`, `execution` (with `stop_conditions`), `outputs`, `success_criteria`, `failure_modes` (with `repair_actions`), `escalation`, `responsibility`, `versioning`, `blast_radius`.

Finding: any missing field → severity `medium`. Placeholder text (e.g. "Perform bounded operation", "target artifact") → severity `high`.

### Step 5 — Separation of concerns

- `deterministic` work (scripts, schema checks) must not be mixed with `LLM_assisted` judgment steps in a single EOU step.
- Self-approval: `responsibility.executor` must not equal `responsibility.approver`.

Finding: violation → severity `high`.

### Step 6 — Trace preservation

- `outputs` must include `trace: foundry/runs/{eou_id}/{run_id}.yml`.
- `execution.steps` must be specific enough to reconstruct what ran.

Finding: absent trace output → severity `medium`.

### Step 7 — Generating-EOU additional checks

For every EOU with `function: generate`:

- `generation_envelope.forbidden_outputs` must include `active_eou`, `approved_eou`, `constitution_change`.
- `generation_envelope.default_status` must be `candidate`.
- `generation_budget.max_candidates` must be declared.
- `minimality_test` and `operational_value_test` must be declared.
- `counter_generation.required` must be `true`.

Finding: any violation → severity `high`.

### Step 8 — Human-approval escalation

- Any EOU that affects publication, finance, health, legal, safety, or constitution must declare `escalation.require_human_when`.
- `responsibility.cannot_delegate` must list at least one item for EOUs with `authority_level: mutate_active` or higher.

Finding: absent escalation on high-stakes EOU → severity `high`.

### Step 9 — Value Operationalization Test (ECP-0017 / Rule 96)

**Skip if no captured_workflow exists with complete `human_approval`, OR if the spec's `target_object` is in `rule_96_exempt_target_objects` (declared in `engine/governance.yml`).**

Otherwise, verify that `success_criteria.must_pass` contains at least one entry whose text references at least one `domain_value.id` of priority ≤ 3 from the loaded captured_workflow.

Severity escalation by `lifecycle_stage`:
- `active`, `monitored`, `stable` → `blocking` finding (must repair before promotion)
- `pilot` → `high`
- `draft` or `candidate` → `medium`

Record the operationalized `domain_value.id` entries in the audit report under a new `operationalized_values` field so future audits can detect drift (a spec that operationalized `dv-001` at v1.0 but no longer does at v2.0 is suspect).

**Limit:** the test is string-match based. A spec could cite an id without actually operationalizing the value (citation theater). Reviewers SHOULD spot-check value invocations for decorative pattern. The counterfactual-swap defense lands in the deferred agentic-judgment ECP package (see `dev-docs/07-agentic-judgment-proposal.md`).

## Output

Write one file per audited EOU to `foundry/audits/eou-audits/{eou_id}.audit.yml`:

```yaml
audit_date:
eou_id:
eou_version:
checks:
  - check_name:        # faceted_classification | authority_blast_radius | structural_fields | separation_of_concerns | trace | generating_eou | escalation
    status:            # pass | fail | skip
    findings:
      - severity:      # critical | high | medium | low
        field:         # YAML field path where the violation occurs
        description:
        required_fix:
summary:
  total_findings:
  by_severity: {critical: 0, high: 0, medium: 0, low: 0}
  verdict:             # PASS | FAIL | CONDITIONAL_PASS
```

When auditing the whole `foundry/` directory, write one file per EOU. Do not merge findings across specs.

## Constraints

- Do not modify any EOU spec — produce the audit report only.
- Treat missing required fields as failures, not warnings.
- Run `validate_foundry.py` before manual checks — its output is authoritative for schema errors.

## Scope Note

**Upstream:** receives an EOU spec id or path. Typically invoked on EOUs at lifecycle_stage pilot or active, or on ECP packages awaiting approval.

**Downstream:** findings feed `$eou-diagnose` (when an audit failure needs root-cause diagnosis), `$eou-refactor` (when findings suggest structural change), and `$eou-promote` (audit pass is a gate for active promotion).

**Related:** `$eou-validate` (sibling — structural validation, deterministic); `$foundry-audit` (sibling — system-wide rather than per-EOU); `$audit-candidate-eou-set` (sibling — audits a set, not a spec).

**Pipeline:** `eou-specify → eou-audit → eou-promote (if pass) | eou-diagnose (if fail)`

