# Audit outcomes — a six-flag vocabulary

> **Audience:** consumers (humans + AI agents) running a per-rule
> conformance audit against `docs/standards/`. The most common
> incarnation is a `docs/inprogress/MGF_STANDARDS_CONFORMANCE.md`
> ledger that walks every rule row by row and records the project's
> standing on each.

This is a **principle**, not a MUST. It names the vocabulary that
audit-time conformance work converges on, so two auditors looking at
the same project produce the same taxonomy rather than each inventing
ad-hoc flags.

Promoted to a standalone document by
[PAPER-31](../../../FEEDBACK.md) in v0.39.0 / v1.0 doc bundle. The
trigger was a real TelePlasma audit pass that initially flagged
nine rows as `🚫 declined-with-rationale`; review-pass split that
into six `N/A` + three actual declines — a 2:1 noise ratio in the
"declined" signal. Naming the distinction upstream lets every future
audit avoid the same conflation.

---

## The six flags

A per-rule audit row resolves into one of six outcomes:

| Flag | Meaning | Rationale doc required? |
|---|---|---|
| **✅ conformant** | Rule applies; project conforms today. | No — the code IS the rationale. |
| **❌ violation** | Rule applies; project does NOT conform today. | No — open a tracker item to fix. |
| **⚪ partial** | Rule applies; project conforms in some places, not in others. | Yes — partial-conformance note inside the audit row, naming what's done and what's pending. |
| **🚫 declined-with-rationale** | Rule **applies** but the project consciously declines to follow it. The deviation has a real reason. | **Yes** — full rationale per [`non-adoption-is-valid.md`](non-adoption-is-valid.md). |
| **N/A** | Rule's scope does **not** apply to this project. The project could never conform because the rule isn't theirs. | No — but the N/A reason ("backend service, no GUI") is a one-liner in the row. |
| **⏳ no-surface-yet** | Rule applies in principle but the feature it gates hasn't shipped in this project yet. | No — but the audit row should name the next milestone where the surface would appear. |

The ASCII-emoji vocabulary is a convention, not a requirement; an
audit doc that uses plain words ("conformant", "violation", "n/a")
is just as legitimate. The point is to name the **six categories**
distinctly, not to mandate the flag glyphs.

### Optional evidence/confidence enrichment (independent of the flag)

The six flags above record a row's **outcome**. They say nothing about how
well the auditor could *establish* that outcome — and a `❌ violation` or
`🚫 declined` row asserted on a hunch reads as urgent **action** when it may
need urgent **verification** first. A row MAY therefore *optionally* carry,
in its note (or an extra column), two enrichments **recorded independent of
the flag**:

- **`evidence_level`** — how the standing was established:
  `VERIFIED_BY_EXECUTION` / `CODE_READ` / `INFERRED` (or the fuller
  `VERIFIED_AGAINST_CODE` / `_AGAINST_DOCS` / `_BY_EXECUTION` / `INFERRED`
  the review recipes use).
- **`confidence`** — HIGH / MEDIUM / LOW.

This is **not** a seventh flag and **not** a severity dimension: a `❌` row
with LOW confidence is still a `❌` — it just signals "confirm before acting."
It is the **same grammar** the review recipes already mandate
([`architecture-review`](../../recipes/architecture-review.md),
[`doc-review`](../../recipes/doc-review.md),
[`ui-review`](../../recipes/ui-review.md): *record `confidence` independent of
severity — CRITICAL + LOW confidence needs urgent verification, not urgent
action*), surfaced here so a conformance audit can borrow it rather than
invent a parallel one. It stays **optional** — a high-signal audit row needs
only its flag and one-line note.

---

## Why the three non-✅ non-❌ flags are easy to conflate

The principle file [`non-adoption-is-valid.md`](non-adoption-is-valid.md)
is the only "I'm not following this rule and that's fine" framing
the standards corpus ships. A first-pass auditor encounters a row
where the project doesn't conform, reaches for the only sanctioned
"non-conformant but OK" flag, and writes `🚫 declined-with-rationale`
for all three categories:

1. The GUI-worker rule for a backend service ("EH-06 GUI workers? we
   have no GUI") — **really `N/A`**, not 🚫. The rule is out of
   scope.
2. The CLI `--config` flag rule under the web carve-out ("CF-09
   --config flag? we're a 12-factor web service, env-only") — **really
   🚫 declined-with-rationale**, with a real design choice behind it.
3. The deprecation-cycle rule with no deprecations to audit ("AP-04
   deprecation aliases? we have no deprecations") — **really `⏳
   no-surface-yet`**. The rule WILL apply the moment the project
   ships its first deprecation; today there's nothing to audit.

All three look the same to an auditor reaching for the only "not
conformant, not broken" framing they've been shown. The signal
collapses.

**The cost of conflation.** A reviewer reading a 🚫 row needs to ask
"is this a design choice I should know about, or is the rule just
not yours?" That question burns 30–60 seconds per row times 100+
rules per audit. Multiply by 4 consumers and the cost is real.

A clear taxonomy fixes that: the reviewer reads the flag and knows
which row to engage with. `🚫` rows get reviewer attention; `N/A`
and `⏳` rows get skimmed.

---

## Audit-flag decision tree

When an audit hits a non-✅ row, walk this tree:

```
Does the rule's scope apply to this project's shape?
├── No  → N/A
│         (write the one-liner reason: "backend service,
│          no GUI" / "library, no entry-point" / etc.)
│
└── Yes → Does the feature the rule gates exist in this
          project today?
          ├── No  → ⏳ no-surface-yet
          │         (write the milestone: "first
          │          deprecation pair lands when X
          │          ships")
          │
          └── Yes → Does the project conform?
                    ├── Fully  → ✅ conformant
                    ├── Partly → ⚪ partial
                    │            (write what's done +
                    │             what's pending)
                    └── No     → Is the non-conformance a
                                 conscious decision with a
                                 documented rationale?
                                 ├── Yes → 🚫 declined-with-rationale
                                 │         (cross-link to the
                                 │          rationale per
                                 │          non-adoption-is-valid.md)
                                 └── No  → ❌ violation
                                           (tracker item to fix)
```

The tree's load-bearing branch is the first one: **applies or not?**
That single question is what most first-pass audits skip, producing
the 🚫-overload pattern. If the rule doesn't apply, the audit row is
done in five seconds.

---

## Worked examples (TelePlasma's first-pass diagnosis)

These three examples are the canonical illustrations of each
non-✅ outcome. All three sit in
`TelePlasma/docs/inprogress/MGF_STANDARDS_CONFORMANCE.md` today.

### `N/A` — EH-06 (GUI worker rule for a backend service)

EH-06 mandates Qt-style worker patterns for GUI projects.
TelePlasma is a FastAPI multi-tenant SaaS — there is no GUI to
apply EH-06 to. The first-pass audit wrote 🚫 because the project
"didn't conform"; review-pass corrected to `N/A` because the rule's
shape doesn't fit the project shape.

**Audit row text:**

```
| EH-06 | Worker via QThread / asyncio.to_thread | N/A | FastAPI service; no GUI workers. |
```

### `🚫 declined-with-rationale` — AP-12 (CHANGELOG for PyPI consumer apps)

AP-12 mandates a CHANGELOG for PyPI-published libraries.
TelePlasma is a consumer application, not a library — it's
deployed as a service, not published to PyPI. The team consciously
declines the CHANGELOG discipline because consumers (operators) read
the deploy notes, not a changelog. The rationale is recorded.

**Audit row text:**

```
| AP-12 | CHANGELOG for PyPI releases | 🚫 declined | Consumer application, not a library. Deploy notes in
release/* live in the operator-facing channel; CHANGELOG would
duplicate without serving a different audience. Per
non-adoption-is-valid.md. |
```

### `⏳ no-surface-yet` — CF-11 (field-rename alias)

CF-11 mandates that renaming a config field MUST go through a
pydantic `Field(alias=...)` deprecation alias for two MINORs.
TelePlasma has never renamed a config field; there's no surface to
audit. The rule WILL apply the moment a field rename ships, but
today there's no code to point at.

**Audit row text:**

```
| CF-11 | Rename via alias + deprecation | ⏳ no-surface-yet | No field renames in PlasmaSettings to date. Will apply on first rename. |
```

---

## The holistic verdict — "reviewed; sound; no change needed"

The six flags above resolve a **per-rule row**. They do not give an
auditor a way to report the *whole review's* honest top-line conclusion
— and without one, "reviewed and found sound" reads as indistinguishable
from "didn't really look." That gap has a concrete cost: it pressures an
auditor to **pad** a review with marginal findings to look thorough,
which is exactly the noise this taxonomy exists to cut (recall the
30–60 s × 100+ rows × consumers conflation cost). So every conformance
review, design review, or audit SHOULD also carry a **holistic verdict**,
distinct from the per-row flags, drawn from:

| Holistic outcome | When |
|---|---|
| **✅ Reviewed; sound; no significant change needed** | The surface was genuinely examined and is in good shape. A first-class, valuable result — **not** a failure to find work. State *what was examined* so the verdict is auditable, not a rubber stamp. |
| **Findings recorded** | One or more rows are `❌` / `⚪` / `🚫`; the verdict points at them. |
| **🔍 Could not verify** | The surface was in scope but could not be confirmed (tool denied, no access, needs the maintainer). Name *what* could not be verified and *why* — honest uncertainty beats a padded guess or a suppressed concern. Pairs with the never-block protocol ([Agent Empowerment Charter §4](agent-empowerment-charter.md)). |
| **🗂 Considered and rejected** | Candidate findings examined and deliberately *not* raised (no concrete cost; principle-as-aesthetic). Recording these is where much of an honest review's value lives — it shows the surface was probed, not skipped. |

These three honest-output sections (already-sound / could-not-verify /
considered-and-rejected) are the audit-time form of the
[Agent Empowerment Charter §5](agent-empowerment-charter.md)
honest-output discipline — **no false balance, depth over breadth over
length.** The conformance-tracker template
([`mgf-standards-conformance-md-template.md`](../../recipes/mgf-standards-conformance-md-template.md))
carries matching sections.

---

## Cross-references

- [`agent-empowerment-charter.md`](agent-empowerment-charter.md) — the
  agent's license to *conclude* "no change needed" and to record
  could-not-verify / considered-and-rejected honestly.
- [`non-adoption-is-valid.md`](non-adoption-is-valid.md) — the
  adoption-time taxonomy (adopted / adopted-with-carve-out /
  declined) that this audit-time taxonomy complements. A `🚫` audit
  row's rationale documentation flows through that principle.
- [`../README.md`](../README.md) §"Conformance levels for projects" —
  L1 / L2 / L3 levels are independent of audit flags; a project at
  any level can have a mix of ✅, 🚫, N/A, and ⏳ rows.
- [`../../recipes/mgf-standards-conformance-md-template.md`](../../recipes/mgf-standards-conformance-md-template.md)
  — the canonical template for the audit ledger doc. The flag
  vocabulary here is what the template should use.
- [`../../../FEEDBACK.md`](../../../FEEDBACK.md) PAPER-31 — the
  consumer evidence that motivated this document. TelePlasma's
  first-pass-to-review-pass diff (9 🚫 → 6 N/A + 3 🚫) is the
  empirical case.
- **Future complement — PAPER-47** (post-v1.0): the
  `mgf-fed standards --kind=django` CLI filter will use the
  `Applies to` column on each rule to emit only the applicable rows
  for a given project kind. That filter implements the first branch
  of the decision tree above (applies / N/A) automatically; the
  remaining four flags stay manual.
