---
id: OBPI-0.0.37-24-advisor-panel-info-retention-qc-loop
parent: ADR-0.0.37-constitutional-invariant-composition
item: 24
lane: Heavy
status: Draft
# req_atomic: each REQ is a single indivisible labor unit — one behavior/support
# surface apiece (record-advisory, explanation-before-verdict, skill-wielded,
# event, skill, docs); none decomposes into parallel seq=02+ sub-tasks (ADR-0.0.64).
req_atomic:
  - REQ-0.0.37-24-01
  - REQ-0.0.37-24-02
  - REQ-0.0.37-24-03
  - REQ-0.0.37-24-04
  - REQ-0.0.37-24-05
  - REQ-0.0.37-24-06
---

# OBPI-0.0.37-24-advisor-panel-info-retention-qc-loop: Advisor-Panel Info-Retention QC Loop

## ADR Item

- **Source ADR:** `docs/design/adr/foundation/ADR-0.0.37-constitutional-invariant-composition/ADR-0.0.37-constitutional-invariant-composition.md`
- **Checklist Item:** #24 - "OBPI-0.0.37-24 — Advisor-panel info-retention QC loop (per ADR-0.0.39 llm-as-judge: advisory never gating, receipt-emitting; scores information-retained-per-byte of a candidate rendition; verdict cited in operator attestation; tool(s) wielded by an advisor-QC skill)"

**Status:** Draft

## Objective

Deliver the **advisor-QC** stage between compress (OBPI-21) and commit (OBPI-22): an advisor that scores the **information-retained-per-byte** of a candidate rendition and records its verdict as a **receipt** the operator cites at Gate 5 — strictly **advisory, never gating** (parent ADR § Decision Re-Alignment point 3; ADR-0.0.39 doctrine). The judgment (an LLM-as-judge read of the candidate vs. the source corpus) is performed by the **agent wielding the `gz-advisor-qc` skill**; the **tool is deterministic** — it ingests the agent's verdict + explanation, validates receipt shape (explanation-before-verdict), writes an ARB receipt, and emits a ledger event. The tool **never blocks** on the verdict value: a low retention score is evidence for the operator, not a fail-closed gate (ADR-0.0.39: judge output is Evidentiary, not pass/fail).

## Lane

**Heavy** - This OBPI changes a command/API/schema/runtime contract surface.

> Heavy is reserved for command/API/schema/runtime-contract changes. Process,
> documentation, and template-only work stays Lite unless it changes one of
> those external surfaces.

A new advisor-QC subcommand + a new ledger event + a new skill are runtime-contract additions → Heavy. Gate 5 human attestation is mandatory (foundation/heavy; no self-close).

## Cross-ADR Dependency (surfaced, not assumed)

**ADR-0.0.39 (llm-as-judge doctrine) is `Proposed`/`Pending`; all its OBPIs are `Draft`; `src/gzkit/governance/judge_invocation.py` and `src/gzkit/schemas/judge_invocation.json` do NOT exist on disk.** This OBPI therefore binds to ADR-0.0.39's **doctrine** (advisory-never-gating, receipt-emitting, explanation-before-verdict) and the **existing** ARB receipt infrastructure (`src/gzkit/arb/`, whose `arb-step-judge-*` receipt-id form already validates under `attestation_receipts.py`). It does NOT depend on the un-landed `judge_invocation` schema. Schema conformance is an Open Implementation Decision (below).

## Allowed Paths

- `src/gzkit/commands/content/advise_rendition.py` **CREATE** — the advisor-QC record tool handler (`content_advise_rendition_cmd(*, ...)`; sibling to `remember.py`/`compose.py`; deterministic, NO in-code LLM)
- `src/gzkit/commands/content/__init__.py` — EDIT: register `_register_advise_rendition` in `register_content_parsers`
- `src/gzkit/content/advisor_qc.py` **CREATE** — the deterministic verdict-record engine: validate receipt shape (explanation-before-verdict), compute the bytes denominator for info-retained-per-byte, assemble the ARB receipt payload; reuses `gzkit.arb` for emission, NO LLM
- `src/gzkit/events.py` — EDIT: add the typed `RenditionAdvisorVerdictEvent` read-path model + register it in `TypedLedgerEvent`
- `src/gzkit/ledger_events.py` — EDIT: add the `rendition_advisor_verdict_event(...)` write-path factory
- `src/gzkit/schemas/ledger.json` — EDIT: register the `rendition_advisor_verdict` event type with its required-fields schema (the REAL registry `gz validate --ledger` reads)
- `src/gzkit/governance/trust_audits/events.py` — EDIT: `_NO_GRAPH_IMPACT` waiver for `rendition_advisor_verdict` (Layer-2 advisory witness, no artifact-graph edge)
- `.gzkit/skills/gz-advisor-qc/SKILL.md` **CREATE** — the advisor-QC skill (the LLM-as-judge surface; wields the tool)
- `tests/commands/test_content_advise_rendition.py` **CREATE** — command-level BEHAVIOR tests (`@covers`)
- `tests/content/test_advisor_qc.py` **CREATE** — engine-level BEHAVIOR tests (`@covers`)
- `tests/test_schemas.py` — EDIT: add the `rendition_advisor_verdict` entry to `_EVENT_MODELS`
- `tests/content/test_tui_affordances.py` — EDIT: admit `advise-rendition` in the content-subcommand fence
- `config/doc-coverage.json` — EDIT: declare `content advise-rendition`
- `docs/user/manpages/content.md` — EDIT: add a `### advise-rendition` subsection with a real EXAMPLES block
- `docs/user/runbook.md` — EDIT: operator runbook entry for the advisor-QC step
- `docs/user/skills/gz-advisor-qc.md` **CREATE** — skill manpage
- `docs/user/skills/index.md` — EDIT: link the new skill manpage
- `.gzkit/skills/gz-context/SKILL.md` — EDIT: route `gz-advisor-qc` under the gz-context router (version bump per skill-surface-sync)
- `data/distribution_baseline_manifest.json` — EDIT: regenerate to include the new canonical skill (ADR-0.0.31)
- `data/behave_coverage_waivers.json` — EDIT: OBPI-level behave-coverage waiver for any SUPPORT REQ with no Gherkin-observable behavior
- `features/content_advise_rendition.feature` **CREATE** — Heavy-lane BDD scenarios tagged `@REQ-0.0.37-24-*`
- `docs/design/adr/foundation/ADR-0.0.37-constitutional-invariant-composition/obpis/OBPI-0.0.37-24-advisor-panel-info-retention-qc-loop.md` — active brief and evidence record
- `docs/design/adr/foundation/ADR-0.0.37-constitutional-invariant-composition/ADR-0.0.37-constitutional-invariant-composition.md` — parent ADR (read-only, for intent and the 1:1 checklist sync)

**Sync-generated mirrors (written by `gz agent sync control-surfaces`, not hand-edited):** `src/gzkit/skills/gz-advisor-qc/SKILL.md`, `.claude/skills/gz-advisor-qc/SKILL.md`, `.github/skills/gz-advisor-qc/SKILL.md`, `.agents/skills/gz-advisor-qc/SKILL.md`.

## Denied Paths

- Paths not listed in Allowed Paths
- Any in-code LLM/network call — the advisor judgment is the skill's (agent's); the tool only records/validates the verdict (stdlib-first; no dependency departure)
- **Any fail-closed gate on the verdict value** — the advisor is advisory; a low retention score never blocks compose/commit (ADR-0.0.39 Evidentiary invariant). The only fail-closed path is a structurally malformed receipt (missing explanation), never the verdict itself
- `src/gzkit/content/composer.py`, `src/gzkit/content/rendition_store.py` — compose (OBPI-21) and rendition store/playback (OBPI-22) are coordinated, not modified here
- `src/gzkit/governance/judge_invocation.py`, `src/gzkit/schemas/judge_invocation.json` — ADR-0.0.39's un-landed surfaces; not created or depended on here
- `.gzkit/ledger.jsonl` — never hand-edited
- New runtime dependencies; CI files; lockfiles

## Creates These Files

Net-new paths this OBPI creates (exempt from the brief-path existence gate per GHI #419):

- `src/gzkit/commands/content/advise_rendition.py`
- `src/gzkit/content/advisor_qc.py`
- `.gzkit/skills/gz-advisor-qc/SKILL.md`
- `tests/commands/test_content_advise_rendition.py`
- `tests/content/test_advisor_qc.py`
- `docs/user/skills/gz-advisor-qc.md`
- `features/content_advise_rendition.feature`

All other Allowed Paths reference existing files modified in place.

## Open Implementation Decision (operator confirmation at Gate 5)

**Receipt schema conformance.** Recommended: emit the advisor-QC verdict as an existing-form ARB receipt (`arb-step-judge-<hash>` via `gzkit.arb.step_reporter`), aligned to ADR-0.0.39's doctrine fields (explanation-before-verdict, candidate provenance, bias-mitigation roster) but NOT bound to the un-landed `judge_invocation.json` schema. If ADR-0.0.39's OBPI-02 lands before this OBPI, conform to its schema instead. Alternative: block this OBPI on ADR-0.0.39 landing (rejected — the compress→commit pipeline needs the QC loop, and the doctrine is stable even though the schema artifact is not). **Recommend the doctrine-aligned ARB receipt**; confirm at Gate 5.

## Requirements (FAIL-CLOSED)

1. REQUIREMENT [BEHAVIOR]: The advisor-QC tool (`content advise-rendition <surface> [--consumer <vendor>]`), given a candidate rendition and its source corpus, MUST record an information-retained-per-byte verdict as an ARB receipt and exit 0 — it is ADVISORY and MUST NOT gate (no non-zero exit) on the verdict value.
1. REQUIREMENT [BEHAVIOR]: The recorded receipt MUST carry the explanation BEFORE the verdict (ADR-0.0.39 explanation-before-verdict doctrine); the tool MUST fail closed (non-zero exit, no receipt) when the supplied verdict has an empty/absent explanation — fail-closed on malformed receipt shape, never on the verdict value.
1. REQUIREMENT [BEHAVIOR]: The advisor judgment MUST be supplied by the wielding skill (the agent); the tool itself MUST perform NO in-code LLM/network call — given the same verdict input it records the same receipt deterministically.
1. REQUIREMENT [SUPPORT]: A successful record MUST emit a `rendition_advisor_verdict` ledger event carrying at least `surface`, `consumer`, `receipt_id`, and the retention score — proven by `uv run gz validate --ledger` plus the emitted `rendition_advisor_verdict` event.
1. REQUIREMENT [SUPPORT]: The advisor-QC skill MUST exist at `.gzkit/skills/gz-advisor-qc/SKILL.md` and propagate byte-equal to its mirrors — proven by `uv run gz validate --surfaces` plus the `artifact_edited` event for the skill.
1. REQUIREMENT [SUPPORT]: The `advise-rendition` verb MUST be documented in `docs/user/manpages/content.md` and `docs/user/runbook.md`, and the reference MUST resolve — proven by `uv run gz validate --documents` plus the `artifact_edited` event for the doc surfaces.
1. NEVER: gate (fail closed) on the verdict value, add an in-code LLM call, depend on the un-landed `judge_invocation` schema, or hand-edit the ledger.
1. ALWAYS: reconcile the brief with the parent ADR (`uv run gz validate --brief-reconcile`) before implementation begins.

> STOP-on-BLOCKERS: if prerequisites are missing, print a BLOCKERS list and halt.

## Discovery Checklist

**Parent ADR (read first; order pinned — GHI #321):**

- [ ] **Parent ADR § Decision item — quote the line this OBPI implements** verbatim into the brief's Implementation Summary. The contract: "Advisor-panel info-retention QC loop (per ADR-0.0.39 llm-as-judge: advisory never gating, receipt-emitting; scores information-retained-per-byte of a candidate rendition; verdict cited in operator attestation; tool(s) wielded by an advisor-QC skill)" (Checklist item #24; § Decision Re-Alignment 2026-06-03, point 3 — "advisor panel (LLM-as-judge — advisory, never gating, per ADR-0.0.39)").
- [ ] Parent ADR § Decision Re-Alignment point 3 — the compose→advisor-QC→operator-attest→commit sequence.
- [ ] Parent ADR file: `docs/design/adr/foundation/ADR-0.0.37-constitutional-invariant-composition/ADR-0.0.37-constitutional-invariant-composition.md`

> **STOP:** If you cannot quote the parent ADR § Decision item that this OBPI implements, STOP and re-read. Do not proceed until the Decision quote is in hand.

**Governance (read once, cache):**

- [ ] `docs/design/adr/foundation/ADR-0.0.39-llm-as-judge-doctrine/ADR-0.0.39-llm-as-judge-doctrine.md` — the advisory-never-gating / receipt-emitting / explanation-before-verdict doctrine this OBPI binds to (NOTE: Proposed/Pending — see § Cross-ADR Dependency)
- [ ] `docs/governance/arb-middleware.md` + `src/gzkit/arb/` — the existing ARB receipt infrastructure reused for emission
- [ ] `AGENTS.md` § STDLIB-FIRST — why the LLM stays out of tool code

**Context:**

- [ ] OBPI-0.0.37-21 (composer) — produces the candidate rendition this OBPI scores
- [ ] OBPI-0.0.37-22 (commit/playback) — the commit stage that follows operator attestation citing this verdict
- [ ] `.gzkit/skills/gz-complexity-advisor/SKILL.md` + `.gzkit/skills/gz-adr-evaluate/SKILL.md` — existing LLM-as-judge skill patterns (advisory, receipt-bearing)

**Prerequisites (check existence, STOP if missing):**

- [ ] `src/gzkit/arb/` exists with `advisor.py`, `paths.py`, `step_reporter.py` (receipt emission infrastructure)
- [ ] `src/gzkit/governance/trust_audits/attestation_receipts.py` exists (the `arb-step-*` receipt-id validator the verdict receipt must satisfy)
- [ ] `src/gzkit/commands/content/__init__.py` exists with `register_content_parsers`
- [ ] `src/gzkit/events.py` + `src/gzkit/ledger_events.py` + `src/gzkit/schemas/ledger.json` exist (event registration surfaces)

**Existing Code (understand current state):**

- [ ] `src/gzkit/commands/content/remember.py` — the sibling command pattern (arg parsing, exit codes, fail-closed-before-write, ledger emission)
- [ ] `src/gzkit/arb/step_reporter.py` + `src/gzkit/arb/paths.py` — how an `arb-step-<name>-<hash>` receipt is assembled and where it is written (`.gzkit/arb/receipts/`)
- [ ] `src/gzkit/governance/trust_audits/attestation_receipts.py` — the receipt-id regex (`arb-(?:ruff|step-[a-z][a-z0-9]*)-[a-f0-9]{32}`) the verdict receipt must match
- [ ] `src/gzkit/events.py` `CompositionRenderedEvent` — the `_EventBase` + `Literal[...]` pattern for `RenditionAdvisorVerdictEvent`
- [ ] `.gzkit/skills/gz-content-remember/SKILL.md` — the tool+skill split the advisor-QC skill follows

## Quality Gates

### Gate 1: ADR

- [ ] Intent and scope recorded in this OBPI brief
- [ ] Parent ADR checklist item quoted

### Gate 2: TDD (Red-Green-Refactor)

- [ ] Tests derived from brief acceptance criteria, not from implementation
- [ ] Red-Green-Refactor cycle followed per behavior increment
- [ ] Tests pass: `uv run gz test`
- [ ] Validation commands recorded in evidence with real outputs

### Code Quality

- [ ] Lint clean: `uv run gz lint`
- [ ] Type check clean: `uv run gz typecheck`

### Gate 3: Docs (Heavy only)

- [ ] Docs build: `uv run mkdocs build --strict`
- [ ] `docs/user/manpages/content.md` + `docs/user/runbook.md` updated; `gz validate --cli-alignment` resolves the verb

### Gate 4: BDD (Heavy only)

- [ ] Acceptance scenarios pass: `uv run -m behave --tags=@REQ-0.0.37-24-01,@REQ-0.0.37-24-02,@REQ-0.0.37-24-03 features/`

### Gate 5: Human (Heavy only)

- [ ] Human attestation recorded (mandatory; foundation/heavy; no self-close)
- [ ] § Open Implementation Decision (receipt schema conformance) confirmed or redirected by operator

## Verification

```bash
uv run gz validate --brief-reconcile
uv run gz validate --documents
uv run gz validate --ledger
uv run gz validate --surfaces
uv run gz validate --cli-alignment
uv run gz lint
uv run gz typecheck
uv run gz test
uv run mkdocs build --strict
uv run -m behave features/content_advise_rendition.feature

# Specific verification for this OBPI
test -f src/gzkit/commands/content/advise_rendition.py
test -f src/gzkit/content/advisor_qc.py
test -f .gzkit/skills/gz-advisor-qc/SKILL.md
uv run -m unittest tests.commands.test_content_advise_rendition -v
uv run -m unittest tests.content.test_advisor_qc -v
```

## Demo

<!-- gz-validate-skip: command-shape -->
```bash
# After composing a candidate (OBPI-21), the agent (via gz-advisor-qc skill) judges
# info-retained-per-byte and records the verdict — advisory, never gating
uv run gz content advise-rendition AGENTS.md --consumer codex \
  --score 0.94 --explanation "All Mechanical bullets retained; two Promotable bullets combined without information loss."

# The verdict is recorded as an ARB receipt and witnessed in the ledger (exit 0 regardless of score)
uv run gz ledger tail --event rendition_advisor_verdict
```

## Acceptance Criteria

- [ ] REQ-0.0.37-24-01 [BEHAVIOR]: Given a candidate rendition and its source corpus, when the `advise-rendition` subcommand records a verdict, then an info-retained-per-byte verdict is written as an ARB receipt and the tool exits 0 regardless of the score (advisory, never gating). Proof: `@covers`-decorated test in `tests/commands/test_content_advise_rendition.py`.
- [ ] REQ-0.0.37-24-02 [BEHAVIOR]: Given a verdict whose explanation is empty/absent, when `advise-rendition` runs, then it fails closed (non-zero exit, no receipt) — malformed receipt shape is rejected, the verdict value never is. Proof: `@covers`-decorated test.
- [ ] REQ-0.0.37-24-03 [BEHAVIOR]: Given an identical verdict input, when the advisor-QC engine records it twice, then the receipt payload is deterministic and no in-code LLM/network call is made (judgment is the skill's). Proof: `@covers`-decorated test in `tests/content/test_advisor_qc.py`.
- [ ] REQ-0.0.37-24-04 [SUPPORT]: Given the ledger schema, when the OBPI is complete, then `rendition_advisor_verdict` is registered in `src/gzkit/schemas/ledger.json` and emitted on a successful record — proven by `uv run gz validate --ledger` plus the `rendition_advisor_verdict` event.
- [ ] REQ-0.0.37-24-05 [SUPPORT]: Given the skill surface, when the OBPI is complete, then `.gzkit/skills/gz-advisor-qc/SKILL.md` exists and mirrors are byte-equal — proven by `uv run gz validate --surfaces` plus the `artifact_edited` event for the skill.
- [ ] REQ-0.0.37-24-06 [SUPPORT]: Given the operator docs, when the OBPI is complete, then `docs/user/manpages/content.md` and `docs/user/runbook.md` document the verb and the reference resolves — proven by `uv run gz validate --documents` plus the `artifact_edited` event for the docs.

## Completion Checklist

- [ ] **Gate 1 (ADR):** Intent recorded in brief
- [ ] **Gate 2 (TDD):** RGR cycle followed, tests derived from brief, coverage maintained
- [ ] **Code Quality:** Lint, format, type checks clean
- [ ] **Value Narrative:** Problem-before vs capability-now is documented
- [ ] **Key Proof:** One concrete usage example is included
- [ ] **OBPI Acceptance:** Evidence recorded below

> For ceremony steps and lane-inheritance attestation rules, see `AGENTS.md` section `OBPI Acceptance Protocol`.

## Evidence

### Gate 1 (ADR)

- [ ] Intent and scope recorded

### Gate 2 (TDD — Red-Green-Refactor)

```text
# Paste test output here
```

### Code Quality

```text
# Paste lint/format/type check output here
```

### Gate 3 (Docs)

```text
# Paste docs-build output here when Gate 3 applies
```

### Gate 4 (BDD)

```text
# Paste behave output here when Gate 4 applies
```

### Gate 5 (Human)

```text
# Record attestation text here when required by parent lane
```

### Value Narrative

<!-- What problem existed before this OBPI, and what capability exists now? -->

### Key Proof

### Implementation Summary

- Files created/modified:
- Tests added:
- Date completed:
- Attestation status:
- Defects noted:

## Tracked Defects

**ADR-0.0.39 dependency (cross-ADR, surfaced).** ADR-0.0.39's judge-invocation schema/code is not landed (see § Cross-ADR Dependency). This OBPI binds to the stable doctrine + existing ARB receipts and surfaces schema conformance as an Open Implementation Decision rather than blocking. If ADR-0.0.39 lands first, conform to its schema at brief-reconcile.

_No further defects tracked._

## Human Attestation

- Attestor: `<name>` when required, otherwise `n/a`
- Attestation: substantive attestation text or `n/a`
- Date: YYYY-MM-DD or `n/a`

---

**Date Completed:** -

**Evidence Hash:** -
