Wave 5A: /u house-mode public profile (D2)

Reserved house handle (default 'vyndr', env HOUSE_HANDLE) resolves to the
PUBLIC model record — getModelAggregate() with no userId (user_id=NULL rows)
— WITHOUT a public_profiles row. It is the ONLY special case; every other
handle keeps the private-by-default, byte-identical-404 no-existence-leak
contract. The house profile is always public and never 404s (a fetch failure
degrades to an honest building state).

- src/routes/profiles.js: house short-circuit + sendHouseProfile (public
  aggregate + by_tier + public settled entries), reserved before the publish
  lookup so a user claim is shadowed.
- PublicProfile.tsx: house label 'VYNDR MODEL · PUBLIC RECORD' + hero/subtitle
  off data.house; keeps the CLV-VERIFIED record hero + TierRecord calibration
  + recent settled reads (misses included).
- opengraph-image.tsx (1200x630): house-branded eyebrow/heading.
- portrait/route.tsx: new 1080x1350 share crop (real aggregate or tagline
  fallback, never a fabricated number).
- Discoverability: 'VIEW AS PUBLIC PAGE ->' on the ledger MODEL header +
  'VIEW PUBLIC RECORD ->' under the landing ModelRecord, both to /u/vyndr.
- tests/unit/houseProfile.test.js: house resolves to user_id=NULL aggregate
  (no public_profiles row) + by_tier; unknown/unpublished user handles stay
  byte-identical 404; page renders house label + TierRecord + portrait crop.

3019 tests green (3012 -> 3019); next build EXIT=0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kev
2026-07-13 15:26:48 -04:00
parent da144ecb5e
commit 76c289d4c1
8 changed files with 399 additions and 8 deletions
+12
View File
@@ -1,6 +1,7 @@
'use client';
import { useCallback, useEffect, useState } from 'react';
import Link from 'next/link';
import { GradePill } from '@/components/GradeCard';
import { useAuth } from '@/contexts/AuthContext';
import { Skeleton, EmptyState, ArchetypeBadge, BookWordmark, TierRecord } from '@/components/vyndr';
@@ -284,6 +285,17 @@ function ModelHeader({ agg, minSample }: { agg: ModelAggregate; minSample: numbe
{/* Wave 3 (Addition 2) — the ONE shared record-by-grade-tier table,
identical here, on the dashboard, and on /u. */}
<TierRecord byTier={agg.by_tier} minSample={minSample} />
{/* Wave 5A (D2) — the shareable house/model profile. Same record, a
public page you can hand a partner. */}
<div style={{ marginTop: 14, textAlign: 'right' }}>
<Link
href="/u/vyndr"
className="mono"
style={{ fontSize: 11, fontWeight: 700, letterSpacing: '0.08em', color: 'var(--g-a, #00D4A0)', textDecoration: 'none' }}
>
VIEW AS PUBLIC PAGE
</Link>
</div>
</div>
);
}