meta living owner: Azwaan reviewed: 2026-07-06

Publication Validation

The gate that keeps the published portal evidence-first and render-safe. Every rule below is an automated acceptance test run at pipeline stage ⑥ (pipeline); a single failure blocks publish. Rules reference the Data Contract and Model.


1 · Rule set

A · No invented content (the cardinal rule)

  • A1 Every factual value (metric, artefact, relationship, maturity, sample) traces to source (graph/estate/ repo). Values without provenance are rejected or downgraded to awaiting.
  • A2 No feed contains an entity, edge, or number absent from portfolio-graph.json / health.json unless it is explicitly editorial copy (hero/story/flagship-experience prose) — and prose asserts no unsourced metric/fact.
  • A3 evidence-plates with status:"verified" must carry sourceRepo + sourcePath. Missing ⇒ fail (or auto-downgrade to awaiting).

B · Missing data handled correctly

  • B1 Absent data appears as an empty collection with a status, never as a missing key.
  • B2 Every awaiting/planned/missing item carries a reason and is listed in the feed’s missing[].
  • B3 No planned/in-progress/awaiting item is serialized with fields that imply completion.

C · Routes resolve

  • C1 Every route in every feed exists in routes.json.
  • C2 Every EntityRef.route and link target resolves; zero dead links.
  • C3 routes.json covers every entity referenced anywhere in publication/**.

D · Evidence has source

  • D1 Every Fact in story.json has an EvidenceRef.
  • D2 Every CaseStudy.artefacts[] resolves to an evidence-plate.
  • D3 Every intelligence-product.evidence[] resolves (or the product is awaiting).

E · Status & maturity labels valid

  • E1 Every status ∈ the closed enum; every maturity ∈ the closed enum; every realization ∈ its enum.
  • E2 A feed’s status is consistent with its data (a live feed cannot contain only awaiting items).
  • E3 Maturity/realization labels equal the source frontmatter/digest — no upgrades in transit.

F · Every destination has data

  • F1 Each of the 9 destinations has a feed present in manifest.json.
  • F2 Each destination feed is either non-empty or explicitly awaiting/future with a reason.
  • F3 No destination renders empty by omission (only by declared awaiting).

G · Schema conformance

  • G1 Every feed validates against its publication/schemas/<feed>.schema.json.
  • G2 The envelope (contract/version/status/source/data/missing) is present and typed on every feed.
  • G3 manifest.hash for each feed equals the sha256 of the feed bytes.

H · Lovable rendering safety

  • H1 No null where the schema requires a value; optional fields are absent or typed, never undefined.
  • H2 Text fields are plain strings (no unescaped HTML); diagram bodies are referenced, not inlined raw.
  • H3 Enumerated role/altitude/docType/artefactType values are within their closed sets (Lovable can switch on them safely).
  • H4 Arrays Lovable iterates (items, chapters, studies, exhibits, sections, products, plates) are always present (possibly empty), never absent.

I · Claude ownership boundary

  • I1 No feed contains presentation directives (CSS, component names, layout hints) — truth only.
  • I2 No published feed version is mutated in place (hash of a given version never changes).
  • I3 Determinism: regenerating from the same estateCommit+editorialCommit+graphHash yields identical data bytes (ignoring the generatedAt stamp).

J · Canonical models (single source)

  • J1 spine-single-source — exactly one stage list exists (in canonical/spine.json, 6 stages); arrival, story, architecture-gallery carry spineRef:"platform-spine" and no inline stage list.
  • J2 navigation-single-source — exactly one navigation.json; every route/feed it names resolves; no other feed defines site structure.
  • J3 search-single-source — exactly one search-index.json; every SearchDoc.route resolves; embeddingRef is unset unless semantic search exists.
  • J4 system-venture-distinct — no entity is typed both system and venture; the canonical spine stage 5 is venture (business), not system.

K · Feed & publication classes

  • K1 Every feed declares feedClass + publicationClass + shape, all within their closed enums.
  • K2 feedClass:"live" requires a ttl and lives under live/, not publication/; zero live feeds exist today (any live feed in publication/ fails).
  • K3 Approval routing matches class: reference/generated → auto-publishable; editorial/claim-bearing → human-approved; structural → human+ADR (the publish log records which gate ran).
  • K4 shape:"index" feeds reference detail feeds that all appear (with hashes) in the manifest; shape:"single" carries no shard/page fields.

L · Editorial boundary

  • L1 Editorial narrative originates in content/editorial/** (never extracted from Lovable/presentation).
  • L2 Any factual claim inside editorial-sourced fields carries an EvidenceRef; unsourced facts in prose fail (no-invented applies to editorial prose too).
  • L3 No feed sources authored copy from a presentation artefact (site/**, Lovable components).

2 · Acceptance-test matrix

Test Checks rule(s) Fails when
schema-valid G1–G2 any feed violates its schema
manifest-integrity A(manifest), G3 a feed hash mismatches or a feed is unlisted
routes-resolve C1–C3 any route/ref/link is unresolved
evidence-sourced A1,A3,D1–D3 a verified claim/fact/artefact lacks a resolvable source
no-invented A1–A2 a metric/entity/edge not in graph/health appears as fact
enums-valid E1,H3 a status/maturity/role/altitude is out of set
maturity-honest E3,B3 a label differs from source, or a planned item looks done
destination-coverage F1–F3 a destination lacks a feed or renders empty-by-omission
missing-explicit B1–B2 absent data is a missing key rather than empty+status
render-safe H1–H4 a required value is null, or an iterated array is absent
boundary-clean I1, L3 a feed carries presentation directives or sources copy from presentation
determinism I3 two builds of the same inputs differ
spine-single-source J1 more than one stage list exists, or a feed inlines the spine
navigation-single-source J2 missing/duplicate nav, or an unresolved nav route/feed
search-single-source J3 missing/duplicate search index, or an unresolved doc route
system-venture-distinct J4 an entity is both system and venture, or spine stage 5 ≠ venture
classes-valid K1–K4 a bad/missing feedClass/publicationClass/shape, or a live feed under publication/
editorial-boundary L1–L2 authored prose lacks an editorial source, or asserts an unsourced fact
stats-cross-check A1 arrival.scale/story.meta.stats ≠ graph/health values

Publish requires all green. The report lists, per feed: pass/fail, counts of awaiting/planned items, and any unresolved refs.

3 · Manual review checklist (gate ⑦, human)

Beyond the automated gate, the founder confirms:

  • [ ] The diff (what changed since the last version) is understood.
  • [ ] New/changed maturity labels match reality (no optimistic drift).
  • [ ] New flagship-experience / flagship claims are ones you’d defend to a customer.
  • [ ] awaiting/future items are correctly labelled (nothing planned reads as live).
  • [ ] Editorial copy invents no facts beyond the sourced data.
  • [ ] Any structural change (new feed, schema shape, tier promotion) has an ADR.

4 · Known validation gaps to design against

  • Cross-feed referential integrity (an EntityRef in one feed pointing at an id that another feed dropped) — the routes.json + graph id set is the canonical id registry; validate all refs against it.
  • Editorial-vs-fact separation is partly human-judged (D-rules cover machine facts; prose is checked at gate ⑦). Keep editorial copy in clearly-marked fields so no-invented can scope machine facts precisely.