Decision memo · 2026-07-25

Hold broad readiness claims; harden the real proof and promotion paths

The current program is governed by uat-production-readiness-convergence. Its first slice removes a concrete false-green: the platform harness no longer accepts arbitrary 4xx responses or starts an unowned repo-native dev service. The next launch-relevant slice must connect the constructed site-memory scanner/object-store dependencies to a persisted, tenant-scoped promotion consumer with browser, dependency-chaos, and container evidence.

Current evidence

Typed readiness RED/GREEN tests and active-runner inventory are current. Governed-bundle and browser evidence are accepted only after their executable reports are attached to the active spec.

Claim cap

CONDITIONAL. Historical Cloud SQL, certificate-pending, revision, and June screenshot statements below are predecessor evidence. Production database authority is Crunchy Bridge. No task counter, RTM rollup, static graph, screenshot, or endpoint liveness may upgrade the verdict.

Source: .agents/specs/uat-production-readiness-convergence/{requirements,design,tasks,TESTS,review}.md. Scope mode: HOLD_SCOPE and harden. Next proofs: governed cross-service browser journey; site-memory promotion runtime/chaos/container slice.
Executive Review · updated 2026-06-28

Production is live on Cloud Run — with evidence boundaries still explicit.

This update folds in the 2026-06-27 production deployment: backend, CMS, and web are live on GCP Cloud Run run.app with Cloud SQL PG17, Upstash Valkey TLS, Secret Manager, and declarative Terraform IaC. The missed shared-table RLS step has also been completed on the live Cloud SQL database and wired into the backend. This is a production-runtime status addendum with no new screenshots; custom-domain browser proof, live public-domain /mcp cross-tenant proof, and UAT remain open.

3Cloud Run services live
41RLS tables FORCE-enabled
3domain certs provisioning
0new screenshots
What's New · 2026-07-15

Security-hardening loop — 4 injection/XSS-class fixes + a production-breaking bug closed, and the web fixes deployed live (no new screenshots)

An autonomous, collision-free hardening loop (running entirely clear of two other sessions' backend work) shipped six fixes to main (v0.11.76–v0.11.82) and deployed the accessible web fixes to production. Decision read: several genuine, previously-unnoticed defects — three stored-XSS sinks, a confirmed-exploitable admin eval-injection, a Next.js-16 production-breaking form bug, and a CI false-green — are now closed and (for the public web) live. This is a shipped code/security round (cited to PRs + tags), unit/component + curl-smoke tier; no operator screens changed, so the visuals on this page still stand.

Stored XSS · closed ×3

DB/tenant content can no longer break out of a script/HTML sink

Evidence Source: PRs #775 (JSON-LD serializeJsonLd), #779 (ContentDetail/EventDetail → DOMPurify SafeContent), #783 (cms ComputedField new Function eval → JSON.stringify, empirically proven exploitable + fails-on-revert regression guard).
Coverage Tier: unit/component (jsdom + DOMPurify).
Claim boundary: defensive output-escaping/sanitization; not a live-exploit incident on the trusted single tenant, and no browser/UAT proof.
Prod bug + deploy

Next.js-16 async-params fix, and the web fixes are live on Cloud Run

Evidence Source: PR #777 (public /forms/*+plugins/[id] read params/searchParams synchronously → undefined in Next 16.2 prod, 404'ing forms); deployed cms-web @ v0.11.80 → revision cms-web-00052-xrf, smoke PASS (health + platform/NAELT homepages + /about all 200).
Coverage Tier: unit/component + curl-smoke on the deployed web.
Claim boundary: web-only deploy (backend/admin not redeployed); rollback ref cms-web-00051-6rc; no custom-domain browser/UAT proof. The cms-admin deploy (carrying the eval-injection fix) remains owner/cross-session-coordinated.
What's New · 2026-07-11

Showcase, manual, and review generation rules are now explicit (no new screenshots)

This documentation-governance pass adds docs/SHOWCASE_GENERATION_GUIDE.md and updates the docs hub, manuals, review guide, README indexes, AGENTS.md, NEXT_STEPS.md, and RTM.md. Decision read: future refreshes now have one durable memo for keeping three audiences separate — prospect-facing showcase copy, operator-facing manual content, and evidence-facing executive review — instead of rediscovering that boundary in each regen.

Governance

New showcase generation guide

Evidence Source: docs/SHOWCASE_GENERATION_GUIDE.md plus existing manual/review generation guides.
Coverage Tier: documentation/static-host governance.
Claim boundary: the guide defines source-manifest order, copy rules, and refresh checklist for docs/index.html and the public showcase surface; it does not add runtime readiness or production proof.
Audience split

Marketing, manual, and review no longer share one voice

Evidence Source: updated docs hub/manual/review artifacts.
Coverage Tier: curated documentation.
Claim boundary: showcase stays benefit-led; manual stays operator/source-manifest oriented; review stays evidence and gap-analysis oriented. No new browser capture, runtime probe, deploy, hosted workflow, or UAT evidence was gathered.
What's New · 2026-06-30

Security & quality-hardening round — the release gate is now real and GREEN (no new screenshots)

A focused security/quality round landed on 2026-06-30 (PRs #162/#163/#164 to dev) that converts a previously partial / false-green security gate into a real, fail-closed release gate — and the now-functional scanners immediately surfaced and fixed two genuine production defects. These are shipped backend/security/tooling/governance changes (cited to PRs + governance evidence), local-gate tier; no operator screens changed, so the visuals on this page still stand. Decision read: the platform's claim to be "secure by gate" is now defensible — the gate actually runs all 5 scanners, blocks on real findings, and a secret can no longer be committed by accident — while hosted CI cost stays owner-gated by design.

GREEN · release gate

Local security gate passes end-to-end — nothing bypassed

Evidence Source: bash scripts/test-security-ci.sh (Failures 0 / Missing tools 0); ISSUE_LOG.md SECURITY-CI-RELEASE-GATE-001, PR #162.
Coverage Tier: local security-gate (all 5 scanners present & passing).
Claim boundary: all five scanners — gosec, govulncheck, gitleaks, npm audit, trivy — now run and pass with nothing skipped. This converts a previously partial / false-green gate (scanners silently absent or never executed) into a real fail-closed gate. The gate is LOCAL by design; hosted CI cost stays owner-gated.
PASS · real defects fixed

gosec (never actually run before) found two real bugs

Evidence Source: scripts/gosec-baseline.md + PR #162 fixes.
Coverage Tier: static analysis + targeted fix.
Claim boundary: with gosec finally executing, it caught (a) the OAuth-state cookie shipped without Secure in production — a predicate bug comparing config.Env=="production" instead of the canonical prd tier — and (b) a MIME-sniffing reflected-XSS in the messaging webhook challenge echo. Both fixed; the other 22 gosec findings were triaged as justified false positives in the baseline.
PASS · supply chain

npm advisories cleared & container scan clean

Evidence Source: npm audit across all 4 package dirs; trivy.yaml scoped scan, PR #163.
Coverage Tier: dependency + image/source scan with --exit-code 1.
Claim boundary: removed an unused lighthouse devDependency dragging a vulnerable transitive chain and bumped js-yaml 3.14.2→3.15.0 → all four package dirs report npm audit = 0 vulnerabilities (full, every severity); trivy scoped to source + gates returns 0 CRITICAL/HIGH.
PASS · secret-leak protection

Fail-closed gitleaks guard verified, history clean

Evidence Source: make setup pre-commit guard; .gitleaks.toml; ISSUE_LOG.md SECRET-SCAN-GUARD-001, PR #164.
Coverage Tier: pre-commit guard + full-history review.
Claim boundary: the fail-closed gitleaks pre-commit guard blocks committing secrets (proven against a local gitignored cms/.env AWS key); a full 3,529-commit history review found no real production secret; the .gitleaks.toml allowlist was tuned so the guard stays precise (no noise-driven bypass).
Hygiene

One-command bootstrap makes the protections opt-in-by-default

Evidence Source: make setup, CONTRIBUTING.md, steering #26.
Coverage Tier: developer/agent bootstrap + governance.
Claim boundary: make setup installs the dev/agent toolchain and the fail-closed guards in one command, documented in CONTRIBUTING.md and the new steering doc #26 — so the security protections are documented and on-by-default rather than tribal knowledge. Three pre-existing flaky/stale tests were also fixed deterministically.
Honesty

Claim cap

This round is local security-gate + governance tier — no new browser screenshots (the 2026-06-16 captures + the 2026-06-21 governed payment screenshot still stand), no fabricated metrics. The gate is LOCAL (hosted CI cost stays owner-gated); NO new browser / UAT / deploy / live-provider / multi-region proof is claimed. Authority: .agents/specs/ISSUE_LOG.md (SECURITY-CI-RELEASE-GATE-001, SECRET-SCAN-GUARD-001), scripts/gosec-baseline.md, trivy.yaml, CONTRIBUTING.md, PRs #162/#163/#164.

CEO / Founder Perspective

CEO / Founder Perspective — current product direction (2026-06-30)

An evidence-disciplined strategic read. Capability is strong and the platform is live; the binding constraint is external demand proof, not more features.

Founder Thesis

Wedge (chosen)

Narrow to the NAELT advocacy beachhead

Owner decision 2026-06-30 — narrow to the NAELT victim-rights / NGO advocacy platform as the near-term launch beachhead, with the AI-agent-native layer (MCP discovery, agent-friendly SEO, A2UI authoring, GraphRAG) as the differentiation that rides on top. (Previously the scope spanned a horizontal "anyone builds a site" platform + 3 verticals + AI-native, all at once — too broad.)

Why meaningfully better

Agent-native is the "why now", not the horizontal

An AI-agent-readable, self-manageable advocacy site that a small NGO team runs without engineers; the agent-native angle (MCP / agent-SEO) is genuinely "why now" and not me-too. The generic horizontal "build any site" framing is commodity (Webflow/Wix/Sanity/Strapi) and is NOT the wedge.

Demand behavior that would prove it

External pull, not just the anchor tenant

A real NGO (NAELT going live for real users) plus a second, non-affiliated NGO adopting; for the agent layer, an external AI agent discovering & operating a tenant via public /mcp.

Kill assumption

"Someone other than the anchor tenant adopts"

The repo shows essentially zero external demand signal today — this is the central open question (a market fact, not provable from code).

Strategic Bet Map

BetEvidenceConfidenceKill / Risk SignalNext Proof
Platform runs in prod (multi-tenant, live)GCP Cloud Run + Crunchy live; GraphRAG live; security gate greenHighalready boots— (established)
AI-agent-native is the differentiationMCP / .well-known, agent-config, A2UI, component-manifest, GraphRAGMediumno end-to-end "agent operates a real site" demo; public /mcp cross-tenant proof still opena recorded "external AI agent discovers & operates a tenant via public /mcp"
NAELT beachhead has real, launchable demandNAELT anchor tenant + advocacy content / seedsLow–Mediumonly one affiliated tenant; "live" today = boots, not "users using it"NAELT live for real users on its custom domain, browser-proven end-to-end
"Anyone self-serves a site" has demandShowcase demo + landing→/examples→signup funnel (shipped)Lowno external signup / retention data5–10 external users complete signup→publish and still active after 7 days
Production is ready FOR USERS (not just running)runtime live, BUT custom-domain browser / public-/mcp / UAT still openConditional"live" is "process boots", not "customer in use"one real external user, custom-domain, browser-proven end-to-end flow
Scope Mode: Narrow the wedge (→ NAELT beachhead) — Ambition is already (over-)sufficient; the constraint is external demand proof + closing the last-mile production proof. Adding surface area now has negative marginal return. Owner has chosen NAELT as the near-term launch focus.

10-Star Gap Analysis

Execution gaps

Proof-tier, not missing implementation

Custom-domain browser proof / public-/mcp cross-tenant proof / UAT sign-off still open; worker is a prod no-op; AGE & multi-region deferred; several specs are completed-local with hybrid / mock CMS-admin evidence. (These are PROOF-TIER, not missing implementation.)

Product gaps

Wedge dispersion & no signature loop

The wedge was too dispersed (now narrowing to NAELT); no single signature "signal → action" closed-loop workflow; horizontal build-a-site lacks differentiation; no onboarding-retention UX evidence.

Operating gaps

The healthiest area — a genuine strength

This is the HEALTHIEST area — security gate green, secret guard, observability IaC, one-command make setup, honest claim-capped docs. Engineering discipline is a genuine strength.

Strategic gaps

The biggest hole — weak demand proof

The BIGGEST hole — weak demand proof, no measurable adoption signal, distribution path unproven. The NAELT pivot is the move to convert this from an abstract platform into a provable beachhead.

Decision Memo

Recommended decision

Hold and harden + Narrow the wedge → ship NAELT

(Not Invest — no external demand proof yet to justify more surface area; not Pause — it's live, real, technically strong.)

Rationale: Technical thesis and engineering discipline are strong and the platform is live, so don't pause. But recent energy has been almost entirely inward (security gate, secret guard, dev-setup, docs, hardening) while the largest risk is outward: no evidence anyone beyond the anchor tenant wants it. Before adding features or more internal polish, narrow to the sharpest, nearest-to-launch wedge (NAELT) and prove it with real external users.

Top 3 next actions

  1. Take NAELT live for real users on its custom domain — close the one end-to-end browser-proven flow (signup / advocacy content / donation or volunteer) so "live" means "in use", not "boots".
  2. Land the agent-native differentiation visibly on NAELT — a public /mcp + agent-SEO proof that an external agent can discover & read the site (also closes SPTR-LIVE-WIRING-001's public-/mcp gap).
  3. Pursue ONE external adoption signal — a second NGO or a real volunteer / donor completing a flow — even a free pilot.
Evidence limits / open questions: readiness labels above come from existing AGENTS.md / review.md / ISSUE_LOG claim-caps (custom-domain browser, public-/mcp, UAT remain open) — not self-adjudicated. The single largest unknown — external demand — cannot be produced by engineering; it requires real users.
Claim boundary: Strategic read; not a readiness verdict. Readiness labels inherit existing claim-caps. Demand is unproven and can only be validated with real external users.
What's New · 2026-06-29

Production-readiness hardening — security fail-closed, reduced over-state, live AI search (no new screenshots)

Two batches landed on 2026-06-29 that materially strengthen the production-readiness posture of the live Cloud Run + Crunchy stack: a UAT de-stub / de-mock / wire-up pass and a set of platform-operations lanes (observability, live GraphRAG, asset scan-path, worker). These are shipped backend/security/operations changes (cited to PRs + spec evidence), not roadmap; no operator screens changed, so the visuals on this page still stand. Decision read: the platform is more honest and more defensible (a real production fail-open was closed, dead/over-stated surfaces were removed, AI search is live) — while monitoring-apply, worker-deploy, and the backup restore-drill remain explicit owner-gated next steps.

Security · fail-closed

Signup site-DB provisioning fails closed in production

Evidence Source: uat-readiness-destub-wireup review + PR #160.
Coverage Tier: backend/security wire-up + grep-verified audit.
Claim boundary: the privileged CREATE DATABASE signup path (ensureSiteDatabase) previously could fall back to default cms_user/cms_password and sslmode=disable; it now routes through the shared database.SiteDBCredentials() resolver, rejecting default creds + non-TLS in production. This closes a real residual fail-open on the tenant-onboarding path.
LIVE · AI search

GraphRAG hybrid vector search live on production data

Evidence Source: crunchy-bridge-db-migration REQ-CBM-006 + graphrag-threshold-default, PR #155.
Coverage Tier: live authenticated query against re-ingested production data.
Claim boundary: the embedding model was fixed (preview gemini-embedding-2-preview → GA gemini-embedding-001), showcase + naelt re-ingested with 3072-dim Vertex vectors, and live graphRAGSearch returns ranked results (showcase "content platform" → Atlas 0.70; naelt "被害人權益保護" → 0.76–0.83); default semanticThreshold lowered 0.6→0.4 for recall.
Owner-gated · monitoring

Cloud Run observability IaC ready to apply

Evidence Source: cloud-run-observability review + PR #158.
Coverage Tier: infrastructure-as-code, terraform validate PASS.
Claim boundary: an email notification channel + 3 HTTPS uptime checks (api /health, www /, admin /login) + 3 alert policies (uptime-down, backend 5xx, TLS-cert-expiry); plan is 7-add / 0-destroy. The apply is owner-gated — defined, not yet activated.
Reduced over-state

Dead / over-stated surfaces removed from the contract

Evidence Source: uat-readiness-destub-wireup review + PR #160; two grep-verified audits.
Coverage Tier: contract / dead-code removal.
Claim boundary: deleted the AWS video pipeline (uploadVideoToAWS/checkVideoProcessingStatus, always "not configured") from the GraphQL schema, plus dead-mock GroupManagement.tsx and the unrouted stub PluginConfigurationManager. Notably, the audits found the codebase already heavily hardened — most candidates were rejected as real, wired code.
Prerequisite + boundary

Asset scan-path decoupling & worker state documented

Evidence Source: asset-object-storage-cloudrun (PR #156) + worker-runtime-deploy (PR #151).
Coverage Tier: backend wire-up + documented runtime state.
Claim boundary: the file-scan path can now scan object-storage (GCS) assets (local unchanged) — a prerequisite for the deferred worker; and the asynq worker is documented as a no-op in prod today (scanning off) with inert Cloud Run worker IaC. Worker activation is an owner-gated deploy decision.
Honesty

Claim cap

This pass is backend / security / operations + terraform validate tier — no new browser screenshots (the 2026-06-16 captures + the 2026-06-21 governed payment screenshot still stand), no fabricated metrics. Monitoring apply, worker deploy, and the backup restore-drill stay owner-gated; custom-domain browser proof, public-domain /mcp cross-tenant proof, AGE/GraphRAG-as-runtime, multi-region, and UAT remain unclaimed. Authority: .agents/specs/{uat-readiness-destub-wireup,cloud-run-observability,crunchy-bridge-db-migration,asset-object-storage-cloudrun,worker-runtime-deploy}/review.md, .agents/specs/{SPECS.md,NEXT_STEPS.md}, PRs #151/#155/#156/#158/#160.

Addendum · 2026-06-29

Showcase & docs-site enhancement — a branded documentation hub (no new screenshots)

The stakeholder docs now have a proper front door. The docs static host previously redirected its root straight to the English manual; it now serves a branded Documentation Hub (docs/index.html) that frames the three core documents (Manual EN/繁中, this Executive Review), presents the showcase tenant as the canonical live exemplar, and maps the eight platform capabilities — all in the same provisional NAELT CIS palette so the docs read as one product. This is a presentation/documentation enhancement (committed + Dockerfile-served), not a runtime or readiness change.

Shipped · repo

Docs front door + showcase cross-presentation

Evidence Source: committed docs/index.html + infra/docs/Dockerfile change (stops clobbering the hub with the redirect stub) + spec artifacts.
Coverage Tier: documentation / static-host.
Claim boundary: the hub is domain-free (no hard-coded production host), links the manual/review repo-relatively, and names the live showcase + /examples gallery as env-driven destinations. It goes live on the docs domain only after a migration-free cms-docs rebuild + deploy (offered owner follow-up). No backend, schema, or DNS/TLS change.
Boundary

What this addendum does NOT claim

No new screenshots — the 2026-06-16 local captures + the 2026-06-21 governed payment screenshot still stand. No fresh browser-full-integration, no live external provider, no production-readiness upgrade. Deeper showcase seed work (e.g. wiring a real YouTube video-embed) stays owner-input-gated under ISSUE_LOG.md SHOWCASE-YOUTUBE-WIRE-001.
Authority: .agents/specs/showcase-docs-enhancement/review.md, building on platform-landing-funnel / frontend-cms-showcase-examples / tutoring-learning-showcase-demo.
Addendum · 2026-06-28

Tutoring streaming & responsible-AI consultant — shipped & browser-proven on production

The tutoring plugin's previously contract-only media + consultant interfaces are now implemented end-to-end and live on production (Crunchy Bridge + Cloud Run) at www.austinchanglab.net/site/showcase/tutoring. This is a shipped, browser-proven capability (cited to PR #133 + spec evidence + Playwright screenshots).

LIVE · gated streaming

“Sample teaching” plays real, access-gated video

Showcase tutoring Sample teaching: a public preview video playing inline, with paid lessons locked
Evidence Source: live requestTutoringPlayback + GET /api/tutoring/media/* on prod; Playwright capture against the deployed site.
Coverage Tier: browser-full-integration + live signed playback.
Claim boundary: a real local_asset driver mints 15-min HMAC-signed URLs and a range-capable origin serves the bytes; public previews play, paid items stay locked (no URL), tampered/expired signatures → 403. Cloud providers (Cloudflare Stream coded+unit-tested; mux/gcp/aws/azure) are credential-gated follow-ups in ISSUE_LOG.
LIVE · responsible AI

Consultant bot answers, then hands off to a human teacher

Tutoring consultant chat: bot answers an FAQ, then escalates a booking request to a human teacher with a notify-teacher confirmation
Evidence Source: live tutoringConsult mutation on prod; Playwright capture.
Coverage Tier: browser-full-integration.
Claim boundary: a deterministic curated_faq bot answers a prospective student's first questions and — as responsible AI — escalates to a human teacher (creating a notify-teacher inquiry) on booking/pricing/explicit-human intent or low confidence, rather than fabricating an answer. No live LLM is claimed.
PASS · prod bugs fixed

Two latent production bugs found & fixed

Evidence Source: PR #133 + regression tests + live preflight verification.
Coverage Tier: unit + live verification.
Claim boundary: the first real browser-side public mutations exposed (1) StrictCORS never reading CORS_ORIGINS (403'd every cross-origin public call from the prod web host — curl had masked it) and (2) a missing CSP media-src blocking the signed video. Both fixed, regression-tested, and redeployed.
Pending

What is still not proven

Pending: live cloud streaming providers (no Cloudflare/Mux/Azure account); tutoring_teacher_profiles/course_profiles not migrated to prod (teacher display uses page-section props); curated_faq is deterministic (no live LLM). Tracked in ISSUE_LOG.md (TUTORING-CLOUD-PROVIDERS-001, TUTORING-PROFILE-SCHEMA-PROD-001).
Addendum · 2026-06-27

GCP Cloud Run production deployment — live runtime, RLS wired (no new screenshots)

The owner-selected production topology is now the lower-ops managed path in ADR-DEPLOY-003: Cloud Run (backend + cms + web), Cloud SQL PG17 via Auth-Proxy unix socket, Upstash Valkey TLS, Google Secret Manager, and Cloud Run domain mappings for api/www/admin. This addendum updates executive readiness status; it does not claim fresh production visual approval.

LIVE · runtime

Backend, CMS, and web are up on Cloud Run

Evidence Source: production-deployment-topology review + ADR-DEPLOY-003 + Terraform env files.
Coverage Tier: Cloud Run runtime + IaC.
Claim boundary: backend boots in prd, GraphQL HTTP 200, Cloud SQL socket connected, Upstash TLS connected, and cms/web healthy on run.app. This is not custom-domain browser proof.
LIVE · tenant isolation

Live shared-table RLS provisioned after deploy

Evidence Source: GCP Cloud Run RLS follow-up memo in NEXT_STEPS.md and deployment docs.
Coverage Tier: live Cloud SQL database configuration + verification.
Claim boundary: cms_tenant_app non-superuser app role exists, 41 tables have ENABLE+FORCE RLS, verify-rls PASS, and backend env/secrets now route non-VIP D2 through that role.
IaC

Declarative production state

Evidence Source: infra/terraform/envs/gcp-cloudrun/.
Coverage Tier: declarative IaC + import/reconcile.
Claim boundary: live backend imported into Terraform and reconciled with 0-destroy; secrets referenced by Secret Manager name, not inlined.
Pending

What is still not proven

Pending: custom-domain end-to-end browser proof while Google-managed certs provision; live public-domain /mcp cross-tenant proof; worker runtime; AGE/GraphRAG; multi-region; UAT sign-off. Existing screenshots remain predecessor/local evidence except the payment slice's governed browser proof.
Authority: .agents/specs/production-deployment-topology/{review.md,adr/ADR-DEPLOY-003-gcp-cloudrun-cloudsql-cloudflare.md}, .agents/specs/{SPECS.md,NEXT_STEPS.md,RTM.md,ISSUE_LOG.md}, and infra/terraform/envs/gcp-cloudrun/. Presentation: provisional NAELT CIS palette applied.
Addendum · 2026-06-24

Resilience & fail-closed hardening — chaos axis fully closed (no new screenshots)

A run of backend/test-tier prod-readiness lanes shipped as PRs against dev (#107/#108/#110/#111/#112/#113), reducing the codebase's mock-heavy / false-green / stub character with executable chaos & fail-closed coverage — and fixing one real wire-up bug found en route. These are shipped fixes (cited to PRs + spec evidence); no operator screens changed, so the visuals on this page still stand.

PASS · governed-PG chaos

Inbound webhook-flood dedup under race (REQ-RCC-006)

Evidence Source: social_pipeline_dedup_race_governed_test.go on governed PG15 :5433 (skip-gated TENANT_TEST_DSN), PR #113.
Coverage Tier: runtime-backed concurrent-transaction chaos.
Claim boundary: 8 concurrent IngestMessage on one (channel, provider_message_id) → exactly 1 ingested / 1 log / 1 draft (no orphan); a real per-operation tx (mirroring prod D2) makes the loser's poisoned-tx orphan rollback observable. Teeth: disabling the per-call tx leaks 3 orphan drafts. Closes the last adjacent-dependency chaos gap — axis fully closed (RCC-004/005/006/007 done, 008 N/A).
PASS · real bug fix

AI-generation transaction/connection leak fixed

Evidence Source: ai_generation.go + ai_generation_txleak_test.go, PR #110.
Coverage Tier: unit (single-connection pool, deterministic).
Claim boundary: SaveGeneration's invalid-generation-type path returned without tx.Rollback() — unlike every sibling error path — leaking the transaction's pooled connection until GC (a real Postgres pool-exhaustion bug). Fixed + a regression guard that fails fast on the starved pool.
PASS · fail-closed coverage

Quota / GraphRAG / storage fail-closed paths locked

Evidence Source: PRs #104/#107/#108; specs resilience-chaos-coverage + TEST-FAILCLOSED-COVERAGE-001.
Coverage Tier: unit + self-contained chaos + hand-killed mutants.
Claim boundary: transaction-scoped quota enforcement (CheckQuotaWithTx/RecordUsageWithTx — previously only the mock was tested), GraphRAG embedding-provider-down degradation + bounded hung-runtime (REQ-RCC-005), and asset storage-down fail-closed + no-orphan (REQ-RCC-007).
PASS · decision-logic coverage

Recommendation ranking & MCP-pool LRU locked

Evidence Source: PRs #111/#112.
Coverage Tier: unit + hand-killed mutants.
Claim boundary: the ContentBased/Popularity recommendation Recommend methods (behavior-weight × time-decay ranking) and the MCP connection-pool LRU eviction ordering — both previously unguarded (only constructed / only capacity-checked).
Readiness State: local unit + self-contained chaos + governed-PG (REQ-RCC-006) only; NO governed-bundle browser, live external provider, multi-node/real-image, DNS/TLS/deploy/UAT/hosted-Postgres/production. Authority: .agents/specs/resilience-chaos-coverage/review.md, ISSUE_LOG.md (CHAOS-COVERAGE-EXT-001 Resolved; TEST-FAILCLOSED-COVERAGE-001 exhausted), backend/test/TESTS.md, PRs #104/#107/#108/#110/#111/#112/#113.
Addendum · 2026-06-21

Payments / Donations / E-commerce — shipped & browser-proven (PR #86)

A generic, site-scoped, decoupled payment / donation / e-commerce module shipped as PR #86 against dev (payment-plugin). Donation is one purpose preset of a generic Payment* core. This is a shipped, browser-proven capability (cited to PR + spec + Playwright evidence), with a new donor-form screenshot.

PASS · browser-full-integration

Public donor PaymentForm (DB-driven, real backend)

Public donor PaymentForm rendered from DB-driven page data against the real backend
Evidence Source: governed multi-tenant web env, real backend (MSW off), Playwright 2/2 on the seeded NAELT /site/naelt/support/donate page.
Coverage Tier: browser-full-integration.
Claim boundary: the generic PaymentForm (the donation-form manifest preset) renders the full DB → component-manifest → web-registry chain with live seeded presets; no secrets reach the browser (server resolves the site's BYOK provider).
Gap: no live external-provider settlement (Stripe/NewebPay charge).
PASS · cms-e2e 3/3

CMS Donation & Payment + Products & Services admin

Evidence Source: governed cms-e2e bundle, real /api/auth/login + real GraphQL (MSW off), Playwright 3/3 — live provider catalog (only the real paymentProviderCatalog resolver produces the NewebPay/Stripe tags), catalog tab load, and a viewer denied the manage affordances.
Coverage Tier: browser-full-integration.
Claim boundary: provider catalog + guided setup wizard + masked BYOK secret rotate + donation/order list + ezPay 電子發票 status; Products & Services catalog CRUD + SKU variations + Udemy-style digital-content authoring; site.payment.*/site.catalog.* RBAC.
Gap: admin-initiated refund (ISSUE_LOG.md PAY-REFUND-001); provider-initiated refunds already flow via webhook.
Generic by design

One module, many use-cases

Public createPaymentCheckout(purpose) + a provider-registry (add a driver = one blank import) + a single PAYMENT_MODULE_ENABLED mount switch (ADR rejecting a runtime .so). Per-site BYOK secrets (write-only, masked-on-read), per-site routed sessions (VIP DB / non-VIP D2 RLS), order/line-item + product/service/variation/category catalog, and digital entitlements auto-granted on paid.

Honesty

Claim boundary

Proof tier: unit / property (gopter + fast-check) / mutation / enttest + web vitest + cms mocked-GraphQL component + tsc + governed browser-full-integration (both tiers). Not live external provider/OAuth/settlement, real charge/invoice, DNS/TLS/deploy, UAT, or production. Authority: .agents/specs/payment-plugin/review.md, PR #86.

Addendum · 2026-06-18

Production-readiness hardening (no new screenshots)

A backend/config-tier hardening lane shipped as PR #71 against dev, promoted from a repo-wide mock/stub/false-green audit (prod-readiness-wireup-hardening). These are shipped fixes (cited to PR + spec evidence), not roadmap; no new screenshots were captured, so the visuals on this page still stand.

Security · fail-closed

Per-tenant DB connections fail closed in production

Tenant database connections could previously fall back to default credentials and non-TLS in production. They now reject default user/password and require TLS when ENV=production — closing a fail-open path that the central platform-DB validation did not cover. 6 unit tests + 2 hand-killed mutants.

Security · no browser secrets

AI provider keys are server-only

The CMS no longer sources provider keys from NEXT_PUBLIC_*_API_KEY (which would inline secrets into the browser bundle); generation routes through the backend BYOK path, and the admin endpoint fallback fails closed on Vercel-style production markers.

Chaos/resilience

Real Postgres-outage health proof

An empty placeholder test was replaced with a real-dependency chaos test: the production health checker against a downed Postgres returns HTTP 503 (unhealthy), bounded — the most central dependency now has executable fail-closed evidence instead of mock-only coverage.

Honesty

Docs reconciled to real maturity

Module guides that under-stated implemented OAuth (Google/Facebook/Microsoft/Cognito + SAML + LDAP), storage (S3/GCS/Azure/R2/local), and real GraphQL data-binding were corrected — so the genuine remaining gaps stand out instead of being hidden behind stale "TODO" notes.

Chaos/resilience tier

Platform proven to degrade gracefully (PRs #72–#74)

A new resilience cluster proves the platform stays bounded and never hangs under fault injection: connection-pool exhaustion stays within its limit and recovers; a transient tenant-DB outage isn't cached and routing self-heals; a hung AI provider fails with a bounded typed error. Runtime-backed on governed PostgreSQL + hand-killed mutants.

Defense-in-depth tests

Sanitizer + fail-closed guards locked (PRs #75–#77)

The user-input→tenant-ID/cms_<slug> database-name sanitizer and the production credential/TLS guards gained property-based (gopter/fast-check) + call-site-wiring tests, so a future refactor can't silently weaken the only sanitizer before a DB name or re-open an insecure connection path.

Governance hygiene

Registries streamlined, history preserved (PRs #78–#80)

The spec-governance artifacts were token-lean'd while keeping full traceability: ISSUE_LOG.md 270→65, NEXT_STEPS.md 5654→63, RTM.md 2789→382, SPECS.md chars −59% — the complete catalogs/indexes stay in the active files; full history moved verbatim to *_ARCHIVE.md. Open items reconciled to 4, all owner/infra/docs-gated.

Authority: .agents/specs/{prod-readiness-wireup-hardening,resilience-chaos-coverage}/review.md, RTM.md, SPECS.md, ISSUE_LOG.md (PRWH-CLUSTER-001, SLUGIFY-CONTRACT-001), PRs #71–#80. Claim cap: local unit/property/mutation + vitest/tsc + self-contained & governed-PG chaos; NO governed browser, live external provider/OAuth/AI, hosted-Postgres, multi-node/real-image HA, DNS/TLS/deploy/UAT/production.
Addendum · 2026-06-17

Shipped since this review (two backend lanes — no new screenshots)

After the 2026-06-16 capture below, two backend/API-tier lanes shipped as PRs against dev. Both are shipped capabilities (cited to PRs + spec evidence), not roadmap; no new screenshots were captured, so the visuals on this page still stand.

PR #68 · runtime-backed

Spawn now provisions the VIP database

A spawned VIP site is no longer a dangling control-plane record: SpawnSite now creates the physical cms_<slug> database and migrates the schema into it (the create-side gap that previously forced hand-creating cms_showcase). Non-VIP/D2 stays record-only by design; fail-closed with site-record rollback. Proven by unit + property + 8 hand-killed mutants + a governed-PostgreSQL integration test.

Coverage Tier: unit / property / mutation / runtime-backed governed-PG integration.
Claim boundary: backend behavior on a governed PG15; on-demand provisioning only; not hosted-Postgres / production. tenant-lifecycle-dr-admin REQ-016, PR #68.
PR #69 · backend tests green

Messaging & Social draft/template editing API

The two previously-stubbed GraphQL operations are now implemented: updatePostDraft (edit a draft pre-publish; a published post is immutable) and upsertSkillTemplate (create / version-bump), both gated on site.social.manage. Includes a gqlgen codegen-hygiene refactor so schema regen stays safe.

Coverage Tier: service enttest + resolver RBAC deny tests; full graph+service packages green.
Claim boundary: repo-local backend tier; the in-CMS editor UI + the governed-bundle backend-backed browser smoke remain a tracked residual. messaging-ingest-social-publishing REQ-MISP-012, PR #69.
Authority: .agents/specs/RTM.md (2026-06-17 lanes 1+2 rollup), the two specs' review.md/tasks.md, PRs #68/#69. Both PRs open against dev (not auto-merged). NO DNS/TLS/deploy/UAT/hosted-Postgres/production.

Executive Summary

CMS Platform is a multi-tenant, DB/config-driven CMS with a Go backend, Next.js CMS admin, public web, plugin architecture, AI/SEO surfaces, and governed spec/test evidence. The 2026-06-16 pass refreshed the stakeholder artifacts after the non-VIP tenancy model converged on D2 (shared-table RLS) per ADR-RLS-002, the deprecated schema-tier code was removed, and host-preflight/operator tooling shipped — with the full local stack up on real data/API and fresh evidence.

Value

One platform, two isolation tiers — both demoable

VIP ⇒ database-per-tenant; non-VIP ⇒ shared-table RLS (the "D2" model). Four seeded sites now make both tiers visible: three DATABASE/VIP sites plus tenant-demo on the SCHEMA/non-VIP tier, each rendering identically to the end user.

Evidence

D2 read path runtime-backed end-to-end

The non-VIP read path is proven on a governed PG15 from primitives → provider → real public MCP read tools → literal HTTP transport, as a genuine non-superuser role, plus a transaction-pool safety proof. A host-capability db-doctor + a one-command provisioning flow make host selection reproducible.

Boundary

Custom-domain and UAT remain bounded

Cloud Run runtime is live and Cloud SQL RLS is wired; custom-domain browser proof, public-domain /mcp proof, worker, AGE/GraphRAG, multi-region, and UAT are still not claimed.

What's New Since The Last Review (2026-06-16)

Since the 2026-06-15 PR #9 review. Items below are backed by spec-local review.md / tasks.md / ADR evidence cited in the Source Manifest.

Decision

D2 is the canonical non-VIP model (ADR-RLS-002)

Owner-approved: non-VIP tenancy is shared-table Row-Level Security keyed on the site, enforced by a non-superuser app role. The deprecated schema-per-tenant/search_path code (provider, router, middleware, per-schema rollout) was removed; one model, one rollout (rls-rollout-shared).

Visual gap resolved

Non-VIP SCHEMA tier now exercised by seed

A fourth seeded site tenant-demo (tenancyTier:schema) renders as a public site at /site/tenant-demo and appears in the DR admin "Sites & DR" table with the SCHEMA badge and a Set VIP action (vs Remove VIP for DATABASE sites) — closing the prior "seed only exercises VIP tier" gap.

Runtime-backed

Host-capability preflight — migrate db-doctor

A read-mostly probe for any candidate Postgres: can it create a non-superuser app role and have FORCE RLS actually confine it, and does it have pgvector + Apache AGE for runtime GraphRAG (advisory)? Turns host selection from a guess into a reproducible check; runtime-backed on a governed PG15.

Runtime-backed + render

Turnkey operator flow + pooling safety

A one-command idempotent provision→seed→rollout→verify script (with --dry-run + a documented env contract), a post-deploy /mcp cross-tenant UAT smoke, and a proof that D2 is safe behind a transaction-mode PgBouncer (SET LOCAL is tx-scoped) + default-OFF PgBouncer Helm values.

Core Features And Evidence

Each card shows Evidence Source, Coverage Tier, and claim boundary directly in the artifact.

New · non-VIP D2 site

tenant-demo — SCHEMA tier public site

tenant-demo non-VIP schema-tier public site screenshot
Evidence Source: live screenshot (/site/tenant-demo, HTTP 200).
Coverage Tier: live screenshot (route-level browser).
Claim boundary: The fourth seeded site, on the non-VIP SCHEMA tier — content lives in the shared tables, isolated by RLS keyed on the slug (D2). Renders identically to a VIP site.
Gap: Live request-time RLS routing of the public read path is host/deploy-gated (proven on a governed PG15, not against a hosted DB yet).
PASS for DR admin (backend-backed)

CMS DR admin — Sites & DR (now 4 sites)

CMS DR admin Sites and DR table with a SCHEMA-tier non-VIP site
Evidence Source: live CMS runtime (/platform/sites), auth-cookie bootstrap + live GraphQL.
Coverage Tier: hybrid (backend-backed).
Claim boundary: The table now shows 4 real seeded sites — three DATABASE/VIP and one SCHEMA/non-VIP (tenant-demo), with the tier badge and Set-VIP-vs-Remove-VIP distinction driven by real data.
Gap: All four set domain none, so pending-domain Verify is still unexercised; backup/spawn render disabled (unbuilt); hybrid auth, not full browser-login.
PASS for dashboard visual evidence

CMS dashboard

CMS dashboard screenshot
Evidence Source: live CMS runtime (:23000), CMS auth API cookie bootstrap + live GraphQL.
Coverage Tier: hybrid.
Claim boundary: Platform control-plane dashboard now reports 4 total sites.
Gap: Not full browser-login; a Next dev "1 Issue" overlay badge is visible.
PASS for styled homepage

Platform public homepage

Platform public homepage screenshot
Evidence Source: live screenshot (/site/platform, HTTP 200).
Coverage Tier: live screenshot.
Claim boundary: DB/seed-driven platform sections, fully styled (shadcn / Tailwind v4).
Gap: Local runtime evidence, not production DNS/TLS/CDN visual approval.
PASS for third-site rendering

Showcase site homepage

Showcase site homepage screenshot
Evidence Source: live screenshot (/site/showcase, HTTP 200).
Coverage Tier: live screenshot.
Claim boundary: A distinct DB-driven demo site, proving multi-site delivery from one codebase.
Gap: Local runtime evidence only; not production deploy/visual approval.
PASS for route/form rendering

NAELT volunteer flow

NAELT volunteer flow screenshot
Evidence Source: live screenshot (/site/naelt/volunteer/register, HTTP 200).
Coverage Tier: live screenshot.
Claim boundary: The seeded manifest-driven volunteer form with Traditional Chinese field groups and required fields.
Gap: Rendering proof, not final submit/readback breadth.
PASS for route rendering

Platform contact flow

Platform contact flow screenshot
Evidence Source: live screenshot (/site/platform/contact, HTTP 200).
Coverage Tier: live screenshot.
Claim boundary: Current public submission route availability.
Gap: Does not by itself prove production delivery, email, or external DNS/TLS.
PASS for manifest-driven builder

CMS page builder

CMS manifest-driven page builder screenshot
Evidence Source: live CMS runtime (/pages), auth-cookie bootstrap + live GraphQL.
Coverage Tier: hybrid.
Claim boundary: The manifest-driven page builder entry (per-page layout/status/search).
Gap: Hybrid auth; live page-save/publish and A2UI apply are separate proofs.
New · backend / CLI

Host preflight — migrate db-doctor

$ migrate db-doctor
✅ privileged-role-can-create-app-role
✅ app-role-is-non-superuser
✅ app-role-non-bypassrls
✅ force-rls-confines-app-role
⚠️  tls          NOT using TLS — set sslmode=require
⚠️  extension:age    NOT available — GraphRAG cannot run here
⚠️  extension:vector NOT available — GraphRAG cannot run here
✅ HOST OK for the D2 shared-table-RLS read path.
Evidence Source: real CLI transcript (docs/review/assets/host-doctor-cli-2026-06-16.txt) against the governed PG15.
Coverage Tier: backend-tool-cli / runtime-backed.
Claim boundary: The host is D2-capable; GraphRAG is advisory-unavailable on this DB (no pgvector/AGE) — exactly the host-selection signal the doctor exists to surface.
Gap: A host with pgvector/AGE installed is not captured this pass.

FAQ

Questions leadership and operators should ask before treating Cloud Run runtime as full launch approval.

Does this prove production readiness?

It proves Cloud Run runtime is live and Cloud SQL shared-table RLS is wired, but it does not prove custom-domain browser behavior, public-domain /mcp cross-tenant isolation, worker runtime, AGE/GraphRAG, multi-region, or UAT sign-off.

What business data is visible?

Backend GraphQL returned 4 seeded sites — platform, naelt, showcase (DATABASE/VIP) and tenant-demo (SCHEMA/non-VIP). The DR admin table renders all four backend-backed; the non-VIP site renders publicly at /site/tenant-demo.

What is the main visual risk?

The non-VIP tier is now exercised, but all four sites set domain none, so the pending-custom-domain Verify affordance and the per-tenant /settings/dr panel are still not seed-exercised; backup/spawn render disabled (unbuilt). CMS captures are hybrid auth with a Next dev "1 Issue" overlay badge.

Is the D2 read path actually wired?

Yes — runtime-backed end-to-end on a governed PG15: primitives → provider → real public MCP read tools → literal HTTP transport, as a non-superuser role, default-off via SCHEMA_TIER_APP_USER. What is NOT done is confirming /mcp over the public custom domain after certificates finish provisioning.

How is auth evidence bounded?

CMS captures used the real CMS runtime plus CMS auth API cookie bootstrap. That is hybrid evidence and must not be described as full browser-login.

What changed since the previous review?

The non-VIP model converged on D2 (ADR-RLS-002) and the deprecated schema-tier code was removed; a non-VIP seed site now exercises the SCHEMA tier visually; and a host-preflight db-doctor + turnkey operator flow + PgBouncer transaction-pool safety shipped.

Runtime Evidence & UX Flow (this pass)

Full local stack up on real data/API, capped to the evidence actually gathered (2026-06-16).

Seed 4 sites (platform, naelt, showcase = DATABASE/VIP; tenant-demo = SCHEMA/non-VIP)
  -> Stack up: backend GraphQL :28080 (HTTP 200, 4 seeded sites), CMS :23000,
     web :23001, postgres :5432, valkey :6379
  -> Public routes 200: /site/platform, /site/platform/contact, /site/naelt,
     /site/showcase, /site/tenant-demo, /site/naelt/volunteer/register
  -> DR admin /platform/sites renders backend-backed: 4 sites, 1 SCHEMA/non-VIP row
  -> Host preflight: `migrate db-doctor` PASS on governed PG15 (non-super + FORCE-RLS
     confined; pgvector/AGE advisory-absent); `provision_...py --dry-run` plan printed
  -> Fixed scripts/ops.py db seed (broken single-file go run after migrate pkg split)
  -> 9 fresh screenshots + 2 CLI transcripts captured under docs/{manual,review}/assets/
  -> Production final gate remains blocked until DNS/TLS + deploy + UAT + hosted DB exist

Gap Analysis

Resolved items are real improvements since the prior review; open gaps remain bounded and should not be marketed as complete.

Resolved this pass

  • Non-VIP / SCHEMA tier now visually exercised — seeded tenant-demo on the SCHEMA tier, so the DR admin SCHEMA badge + Set-VIP distinction render with real data and the non-VIP public site loads (closes the top visual gap from 2026-06-15; ISSUE_LOG DR-DEMO-SEED-COVERAGE-001, partial).
  • Live D2 read path moved from "SQL-only / pending" to runtime-backed end-to-end (provider → real read tools → HTTP transport, non-superuser role) and wired into /mcp (default-off).
  • Host-preflight + operator tooling shipped — db-doctor (incl. pgvector/AGE detection), --dry-run + env contract, post-deploy UAT smoke, PgBouncer transaction-pool safety + Helm.
  • Model simplified — D2 is the single canonical non-VIP model (ADR-RLS-002); deprecated schema-tier code removed.
  • Seed command fixed — scripts/ops.py db seed corrected to go run ./cmd/migrate (the single-file invocation broke after the migrate package split).

Amazon-style PR note

CMS Platform now demonstrates both tenancy tiers end-to-end: a VIP database-per-tenant site and a non-VIP shared-table-RLS site render identically, while a host-capability preflight and a one-command provisioning flow make standing the non-VIP path up on a new Postgres a reproducible, verifiable operation. The next milestone is not more local proof; it is production-domain closure — certificate-complete browser proof, public-domain /mcp cross-tenant proof, UAT, and later worker/AGE/GraphRAG/multi-region decisions.

Medium

Pending-domain & tenant DR panel

All four seeded sites set domain none, so the pending-custom-domain Verify affordance and the per-tenant /settings/dr panel are still not visually exercised; backup/spawn ops render disabled (unbuilt).

Medium

Hybrid CMS auth captures

CMS captures (dashboard, page builder, DR admin) use auth-cookie bootstrap — hybrid evidence, not full browser-login. A Next dev "1 Issue" overlay badge appears.

Medium

No DR admin browser e2e

No full backend-backed CMS browser e2e exists yet for the DR admin UI; the table is shown via backend-backed capture, not an automated browser suite.

High

Public-domain D2/MCP proof

The live Cloud SQL RLS layer is provisioned and wired, but the public custom-domain /mcp cross-tenant proof still waits for the API certificate and at least two non-VIP tenants.

High

Worker / AGE / GraphRAG / multi-region

The Cloud Run HTTP services are live; continuous worker runtime, AGE-backed runtime GraphRAG, and multi-region/HA expansion remain deferred decisions.

High

Custom-domain browser proof + UAT

Cloud Run runtime and DNS mappings exist, but Google-managed certificates were still provisioning during this pass; custom-domain browser proof and UAT are not claimed.

Roadmap / Next Steps

1. Custom-domain browser proof + public MCP

After certificates finish, verify www, admin, and api end-to-end, then run the /mcp cross-tenant UAT smoke against the public API URL.

2. Deferred runtime surfaces

Decide and implement worker runtime, AGE/GraphRAG, multi-region/HA, and any remaining production backup/restore drills.

3. UAT sign-off

Run the launch/UAT matrix against production values and keep proof-tier labels separate from local predecessor screenshots.

Source Manifest

Used sources are explicit through the 2026-07-11 documentation-governance pass. No docs/*FEATURE*.md exists in this repo, so the spec/report/IaC chain below is the fallback authority. RTM.md is rollup only, not readiness authority.

SourceHow it was used
.agents/specs/{SPECS,NEXT_STEPS,ISSUE_LOG,RTM}.md (through 2026-07-11)Spec registry, rolling queue, issue-first launch notes, and traceability rollup; the 2026-07-11 pass uses them only for doc-governance context, not new runtime proof.
docs/SHOWCASE_GENERATION_GUIDE.mdAudience split and source-manifest rules for the docs hub/showcase surface, plus manual/review quick-link maintenance.
.agents/specs/production-deployment-topology/{review.md,adr/ADR-DEPLOY-003-gcp-cloudrun-cloudsql-cloudflare.md} + infra/terraform/envs/gcp-cloudrun/Production deployment authority: Cloud Run runtime live on run.app, Cloud SQL/Upstash connectivity, Terraform IaC, and live shared-table RLS provisioning/wiring claim boundary.
.agents/specs/schema-per-tenant-routing-rls/{tasks.md (Slice 8), review.md, adr/ADR-RLS-002-NON-VIP-CANONICAL-D2.md}The D2 canonical model + host-preflight / dry-run / UAT-smoke / transaction-pool-safety deliverables and their claim caps
.agents/specs/tenant-lifecycle-dr-admin/{design-cms-ui.md,requirements.md,tasks.md}DR admin UI scope (no review.md in this spec dir; cites the design/requirements/tasks chain)
backend/seeds/{platform,naelt,showcase,tenant-demo}-*.jsonCanonical seed/demo/sample data for the 4 seeded sites (the new tenant-demo carries tenancyTier:schema)
Live runtime probes (2026-06-27 deployment pass)Backend GraphQL 200 in prd on Cloud Run with Cloud SQL socket + Upstash TLS connected; cms/web healthy on run.app; live Cloud SQL shared-table RLS provisioned and verified. Existing 2026-06-16 local route screenshots remain predecessor visual evidence.
docs/review/assets/*-review-2026-06-16.png + *-cli-2026-06-16.txt9 predecessor 2026-06-16 local screenshots + 2 CLI transcripts embedded in this artifact; no new screenshots in the 2026-07-11 documentation-governance addendum
docs/{REVIEW_GENERATION_GUIDE,PROJECT_REVIEW_GUIDE,REVIEW_AND_DOCS_GUIDELINES,MANUAL_GENERATION_GUIDE}.mdReview/manual workflow, capture rules, source-manifest rules, and project-specific review priorities.
docs/*FEATURE*.mdNo matching files exist in this repo; fell back to the spec/report chain above.
docs/*SPEC*.mdMatching docs-spec files are historical/secondary context; active spec artifacts and RTM remain the readiness authority.