# Partner and Editorial Firewall

## Purpose and authority

This document is an internal governance and conformance map. It does not determine substance identity, regulatory status, evidence status, publication state, or commercial eligibility. Those decisions remain in the source-controlled packet and policy contracts:

- `schemas/record-packet.schema.json` and `data/records/*/{record,sources,timeline,review}.json` define packet inputs.
- `docs/data/compoundguide-source-registry-v1.json` owns source identity, category, and authority-tier metadata.
- `schemas/source-authority-policy.schema.json` and `data/source-authority-policy-v1.json` define the authority-policy sidecar and permitted source hosts and redirects.
- `config/agent-readiness-policy.json` records machine-interface and commercial-boundary decisions.
- `src/data/records.ts` is generated runtime data, not a hand-edited authority.

This document is not legal, medical, regulatory, or compliance advice. It creates no procurement route, partner approval, favorable-outcome promise, or public competitor/vendor product. A capability that is not implemented below remains unavailable and fails closed.

The public methodology surface `/methodology/` is implemented under `compoundguide-kva.4.4` and carries the public firewall summary; this document is its linked governance map, published verbatim at `/methodology/firewall`.

## Current baseline

Every current packet requires `commercial_policy` to equal `"none"` and `commercial_exit_disabled` to equal `true` in both `record.json` and `review.json.publication_gate`. These are required enum/const restrictions, not inferred defaults. Missing or different values fail packet validation.

No commercial action route, partner registry, sponsorship inventory, or referral exit exists. Payment cannot be allowed to alter facts, ordering, conflicts, or verified negative history. Where the repository does not yet encode that rule as executable enforcement, the table labels it as policy and identifies the implementation owner.

## Ten non-negotiable rules

| Rule | Current observed enforcement | Data or decision owner | Fail behavior | Exact missing follow-up |
| --- | --- | --- | --- | --- |
| **1. Payment never changes factual status.** | Packet identity, candidate status, claims, sources, conflicts, and review state are closed schema fields validated by `schemas/record-packet.schema.json` and `scripts/packet-validator.mjs`. Current packets cannot encode payment as factual evidence. The live generator separately reads `record.json` and `sources.json`; it does not consume the validator's `publicProjection`, so complete publication-state parity is **not implemented**. | Packet evidence and editorial review; commercial decisions remain separate. | A packet carrying unknown fields or invalid fixed commercial fields fails validation. No payment input exists in the factual packet path. | `compoundguide-kva.12.2: Define the shared enterprise record envelope and separate date semantics` owns generator-projection parity; the packet-side commercial block it formerly pointed at shipped in `compoundguide-kva.4.2` |
| **2. Payment never removes verified negative history.** | For a packet marked published, `scripts/packet-validator.mjs` rejects declared conflicts that remain unresolved/undated or applicable but unlinked. `timeline.json` is source-controlled dated-event provenance. The validator does not detect omitted sources or events and does not enforce append-only history across packet versions; complete anti-removal enforcement is **not implemented**. | Editorial evidence review and future correction history. | Declared unresolved or unlinked conflicts block packet publication. Undeclared omissions require review/correction controls and cannot be claimed as detected today. | `compoundguide-erw: Enforce append-only packet-version history and omitted-source detection` (the correction channel it feeds shipped in `compoundguide-kva.4.5`); `compoundguide-kva.4.5: Build correction/challenge intake and Access-protected correction queue` |
| **3. Sponsored placement is labeled beside the placement.** | **Not implemented.** No sponsorship inventory or sponsored placement exists; current records remain commercially disabled. | Commercial operations and editorial policy. | Render no sponsored placement until adjacent labeling and approval controls exist. | `compoundguide-kva.10.6: Launch labeled sponsorship inventory: sponsored data briefs and newsletter slots`; `compoundguide-kva.10.7: Sell and approve labeled sponsorship inventory` |
| **4. Organic evidence ordering uses public, noncommercial criteria.** | The schema constrains `authority_tier` to P0/P1/P2, and the validator checks each referenced registry category against the allowed coverage bucket; neither component orders evidence. `scripts/generate-records.mjs` currently emits records by slug and sources in fixed source-type order. Executable public ordering criteria and sponsor non-influence are **not implemented**. | Editorial methodology. | Until criteria are published and enforced, commercial inputs cannot modify record or source ordering. | `compoundguide-1xh: Enforce executable noncommercial evidence ordering in the generator`; must land before any sponsorship inventory (`compoundguide-kva.10.6`) |
| **5. Medical reviewers receive no click-, conversion-, or partner-revenue compensation.** | **Not implemented as executable enforcement.** The packet schema has no named reviewer, compensation, click, conversion, or partner-revenue fields. Absence of those fields is not a compensation control. | Owner and future reviewer policy. | No paid medical-review program or performance-linked reviewer compensation may launch before the policy and evidence model exist. | The compensation policy itself is intent only on `/methodology/`; its enforceable policy and evidence model is owned by `compoundguide-3iu: Define reviewer compensation policy and evidence model`. Disclosure population is separately owned by `compoundguide-rk1`. |
| **6. Reviewer and founder conflicts are public.** | The public disclosure POLICY is live on `/methodology/` (shipped `compoundguide-kva.4.4`); no populated named disclosures exist because no reviewers are appointed and no founder conflicts are recorded. Current source/claim conflicts are not reviewer/founder conflicts. | Owner and editorial governance. | Do not claim named medical review or complete conflict disclosure. Retain editorial-verification-only language. | `compoundguide-rk1: Populate named reviewer and founder conflict disclosures when they exist` |
| **7. Investigational, unresolved, stale, or conflicted records have no commercial exits.** | `commercial_policy="none"` and `commercial_exit_disabled=true` are required packet invariants in `schemas/record-packet.schema.json` and asserted by `scripts/packet-validator.mjs`. There is no commercial route. The schema's `https_policy` describes provenance-link policy; it is not a runtime commercial-link detector. | Packet commercial invariant; future action eligibility remains separate. | No commercial action is available for any record. Missing future eligibility evidence cannot enable one. | No follow-up is missing for current enforcement: both the packet invariant and the fail-closed request-time evaluator are implemented. If an outbound action route is ever approved, its eligibility consumption is owned by the kva.4.6 decision contract and the kva.12.5 partner registry. |
| **8. Every outbound commercial action rechecks current eligibility.** | The pure request-time evaluator exists: `src/lib/commercial-eligibility.ts` (fail-closed on every missing, malformed, stale, conflicted, or unresolved gate; 36h module-owned source freshness; trusted-window facility evidence; counsel and partner gates; opaque decision references) with 24 focused tests. **No route consumes it** — no outbound commercial action exists, so nothing calls it at request time yet, and no action boundary exists to deny. `DATASET_VERSION` remains a content digest/cache version, not an eligibility recheck. | Commercial eligibility engine (implemented) and future partner evidence registry (`compoundguide-kva.12.5`). | No action occurs. Any future route MUST rerun this evaluator at request time; missing, stale, conflicted, malformed, or timed-out checks deny rather than redirect or fall back. | `compoundguide-kva.12.5: Build partner evidence registry and attribution preflight with routing off`; `compoundguide-kva.12.7: Activate referrals only after counsel, evidence, privacy, attribution, and independence gates` |
| **9. Every partner relationship is disclosed beside the action.** | **Not implemented.** No partner relationship model, disclosure block, or referral action exists. | Commercial operations and public disclosure policy. | Do not render a partner action until its relationship and adjacent disclosure are represented and approved. | `compoundguide-kva.12.5: Build partner evidence registry and attribution preflight with routing off`; `compoundguide-kva.12.7: Activate referrals only after counsel, evidence, privacy, attribution, and independence gates` |
| **10. Commercial eligibility defaults false.** | Packet fields are required and restricted to `commercial_policy="none"` and `commercial_exit_disabled=true`; `scripts/packet-validator.mjs` rejects any other values. The versioned `commercial_eligibility` decision block (commercial-eligibility-v1) is implemented: absent blocks normalize to exact deny-only defaults, authored `commercial_eligible=true` is rejected in the current phase, and the deterministic gate evaluator denies all nine unresolved gates. The request-time evaluator (`compoundguide-kva.4.3`) is a different phase, not a mirror of this one: it computes eligibility from gates and CAN return `eligible=true` when every gate passes — it fails closed on any missing, malformed, stale, conflicted, or unresolved input, and no route invokes it until an owner-approved action exists. | Private, append-only action decision; never the editorial record. | Missing packet fields fail validation. Missing future eligibility inputs produce a deterministic denial, never an implicit pass. | The completed `compoundguide-kva.4.6` decision (closed 2026-08-02) already governs the terms of any ACTIONABLE, routed commercial path — a private append-only action decision per exact identity, controlled action, bounded scope and jurisdiction, with expiration. The packet field remains author-unassertable, and the evaluator's computational `eligible=true` confers no action by itself. The open follow-up is only the route and its activation gates (`compoundguide-kva.12.5`, `compoundguide-kva.12.7`). |

## Date semantics

These dates are independent and must not substitute for one another:

1. `sources[].published_date`: when the source publisher issued the source, when known.
2. `sources[].effective_date` and `timeline.events[].effective_date`: when the described action became effective, when applicable.
3. `sources[].retrieved_at` and `capture_attestation.retrieved_at`: when CompoundGuide captured the source.
4. `review.json.editorial_verification.verified_at`: the human editorial-verification timestamp.
5. `commercial_reviewed_at`: the commercial-action review timestamp defined in the packet contract's `commercial_eligibility` block (nullable, default null, owned by `compoundguide-kva.4.2`). No commercial review has occurred: absent blocks normalize to null at validation, and only the template carries the field explicitly, so every current packet resolves to null. It must never substitute for any other date.

The generated runtime `reviewedAt` is currently derived by `scripts/generate-records.mjs` from the latest source retrieval date, falling back to packet update/creation dates. It is a display/freshness date, **not proof of human editorial review**. Full runtime separation is open under `compoundguide-kva.12.2: Define the shared enterprise record envelope and separate date semantics`.

## Cross-surface derivation rule and current gap

The required invariant is that HTML, JSON-LD, REST API and bulk exports, Markdown, comparisons, and MCP consume one generated normalized record and do not independently recompute status or eligibility.

Current record surfaces largely consume the generated `PeptideRecord` in `src/data/records.ts`; JSON-LD is rendered in `src/lib/html.ts`, datasets in `src/lib/dataset.ts`, Markdown in `src/lib/markdown.ts`, routes in `src/index.ts`, comparisons in `src/lib/compare-html.ts`, and MCP in `src/mcp/server.ts`. Evidence/change views also consume D1 evidence, change, and claim rows. The public `/evidence/<id>` query admits only claims with `verification_status='source_verified'` and `curated=1`; `src/lib/evidence-html.ts` independently enforces both conditions before rendering the verified label. `test/routes.test.mjs` pins the query and rendering boundaries.

There is a second material current gap: `scripts/packet-validator.mjs` can compile a publication `publicProjection`, but `scripts/generate-records.mjs` does not consume it. The generator reads packet `record.json`, `sources.json`, and the cited captured snapshot files to derive runtime facts, without consuming `review.json`, `timeline.json`, or the validator projection. Therefore validator-to-generator publication parity is **not implemented** and this document does not claim otherwise. `compoundguide-kva.12.2: Define the shared enterprise record envelope and separate date semantics` owns the shared-envelope direction; any implementation must preserve the current packet commercial lock and must not add surface-specific eligibility math.

## Capabilities that remain unavailable

- Partner evidence registry: `compoundguide-kva.12.5: Build partner evidence registry and attribution preflight with routing off`.
- Outbound commercial action route and its deny-only boundary: `compoundguide-kva.4.3` shipped the fail-closed evaluator; the route itself remains unbuilt until an owner-approved commercial action exists.
- Sponsorship inventory: `compoundguide-kva.10.6: Launch labeled sponsorship inventory: sponsored data briefs and newsletter slots` and `compoundguide-kva.10.7: Sell and approve labeled sponsorship inventory`.
- Open correction intake: `compoundguide-kva.4.5` shipped the intake and Access-protected queue; the public form stays flag-closed until a correction owner and retention policy exist.
- Named reviewer/founder disclosure: `compoundguide-kva.4.4` shipped the disclosure policy; no named reviewers or founder-conflict entries exist to disclose yet.
- Referral counsel decision: `compoundguide-kva.12.6: Assemble the healthcare referral counsel packet and record a scoped gate decision`.
- Referral activation: `compoundguide-kva.12.7: Activate referrals only after counsel, evidence, privacy, attribution, and independence gates`.
