Spaces:
Paused
Paused
| import { useState, useEffect, useCallback } from 'react' | |
| import { motion, AnimatePresence } from 'framer-motion' | |
| import { | |
| FileText, Dna, DollarSign, Scale, Brain, TrendingUp, | |
| AlertTriangle, Lightbulb, Loader2, FileCode, Hash, | |
| ChevronDown, ChevronRight, Copy, Check, Eye, Code, Sparkles, | |
| Shield, ShieldAlert, Lock, Package, TestTube, Bug, Gavel, | |
| Coins, BarChart3, Layers, ExternalLink, X, EyeOff, KeyRound, | |
| Server, FolderTree, Rocket, Microscope, Radar, | |
| } from 'lucide-react' | |
| const API_BASE = '' | |
| const GC = { 'A': 'text-success', 'A−': 'text-success', 'A+': 'text-success', 'B': 'text-success', 'B+': 'text-success', 'B−': 'text-warning', 'C': 'text-warning', 'C−': 'text-warning', 'C+': 'text-warning', 'D': 'text-critical', 'D+': 'text-critical', 'D−': 'text-critical', 'F': 'text-critical', 'Unknown': 'text-secondary' } | |
| const RC = { low: 'text-success', medium: 'text-warning', high: 'text-critical' } | |
| const PC = { critical: 'text-critical bg-critical/10', high: 'text-warning bg-warning/10', medium: 'text-primary bg-primary/10', low: 'text-secondary bg-white/5', info: 'text-secondary bg-white/3' } | |
| const PG = { critical: '⟁', high: '▲', medium: '◆', low: '◇', info: '◌' } | |
| const TIERS = { | |
| measured: { glyph: '◉', label: 'Measured', color: 'text-success', desc: 'Directly computed from artifact' }, | |
| inferred: { glyph: '◇', label: 'Inferred', color: 'text-warning', desc: 'Model-based estimate with assumptions' }, | |
| verified: { glyph: '✓', label: 'Verified', color: 'text-primary', desc: 'Externally confirmed' }, | |
| unverified: { glyph: '?', label: 'Unverified', color: 'text-critical', desc: 'No evidence found' }, | |
| } | |
| const SEC_BL = [ | |
| { sev: 'CRITICAL', icon: ShieldAlert, finding: 'No authentication or authorization layer', consequence: 'Any reachable user can upload, inspect, trigger analysis, invoke operational endpoints' }, | |
| { sev: 'CRITICAL', icon: FolderTree, finding: '/index/path accepts arbitrary server-side file path', consequence: 'Remote caller can index any file readable by service account' }, | |
| { sev: 'CRITICAL', icon: FolderTree, finding: '/index/dir recursively indexes arbitrary server directory', consequence: 'Mass disclosure of server files, configs, mounted data, credentials' }, | |
| { sev: 'CRITICAL', icon: Rocket, finding: '/pipeline/trigger creates GitHub repos, deploys HF Spaces + Vercel', consequence: 'Unauthenticated caller can abuse operator deployment credentials' }, | |
| { sev: 'CRITICAL', icon: Bug, finding: 'Upload paths use unsanitized file.filename', consequence: 'Path traversal or unintended file overwrite possible' }, | |
| { sev: 'HIGH', icon: Package, finding: 'Archive extraction has no validation (count, size, ratio, symlink)', consequence: 'Archive bombs, disk exhaustion, extraction traversal' }, | |
| { sev: 'HIGH', icon: EyeOff, finding: 'Indexes retain source previews exposed via search/chunk', consequence: 'Metadata-only separation is defeated' }, | |
| { sev: 'HIGH', icon: Eye, finding: 'All endpoints publicly readable (results, dossiers, ML, telemetry)', consequence: 'Proprietary metadata and source fragments enumerable' }, | |
| { sev: 'HIGH', icon: Server, finding: 'RentMasseur automation + underwriting share one process', consequence: 'Compromise of public service expands to operational account' }, | |
| { sev: 'MEDIUM', icon: KeyRound, finding: 'File passwords not used for endpoint authorization', consequence: 'Password feature is cosmetic, not access control' }, | |
| ] | |
| const DEFI_SCORES = [ | |
| { dim: 'Prototype Breadth', grade: 'B+', score: 85, tier: 'measured' }, | |
| { dim: 'Functional Architecture', grade: 'B−', score: 75, tier: 'measured' }, | |
| { dim: 'Privacy-Preserving Eval Path', grade: 'C', score: 55, tier: 'measured' }, | |
| { dim: 'Application-Wide Privacy', grade: 'F', score: 10, tier: 'measured' }, | |
| { dim: 'External Attack Resistance', grade: 'F', score: 5, tier: 'measured' }, | |
| { dim: 'Valuation Methodology', grade: 'F', score: 10, tier: 'measured' }, | |
| { dim: 'Cryptographic Evidence Strength', grade: 'C−', score: 40, tier: 'inferred' }, | |
| { dim: 'Production Readiness', grade: 'D', score: 30, tier: 'inferred' }, | |
| { dim: 'Underwriting Readiness', grade: 'F', score: 10, tier: 'inferred' }, | |
| { dim: 'Overall', grade: 'D', score: 32, tier: 'inferred' }, | |
| ] | |
| const IMPL_DEFS = [ | |
| { bug: '.git in EXCLUDE_DIRS removed before has_git_dir check', impact: 'Git provenance never detected — has_git always false', sev: 'high' }, | |
| { bug: 'Filename containing "test" treated as evidence of tests', impact: 'Tests never executed — false test-passing signal', sev: 'medium' }, | |
| { bug: 'try/except/"error" treated as functioning error handling', impact: 'Error handling presence ≠ correctness', sev: 'medium' }, | |
| { bug: '"auth"/"hash"/"token" treated as security readiness', impact: 'Keyword presence ≠ security implementation', sev: 'high' }, | |
| { bug: 'API_KEY reading env vars classified as hardcoded secret', impact: 'False positive secret detection', sev: 'medium' }, | |
| { bug: 'ML analysis on 3-line chunk previews, not complete semantic units', impact: 'Topic modeling and anomaly detection degraded', sev: 'medium' }, | |
| { bug: '/systemlake registered twice', impact: 'Route conflict, undefined behavior', sev: 'low' }, | |
| { bug: '/systemlake redirects to / which is RentMasseur dashboard', impact: 'Underwriting upload interface lost', sev: 'high' }, | |
| { bug: 'In-memory state + daemon threads under restarts/multi-worker', impact: 'Unpredictable state, data loss on Uvicorn restart', sev: 'high' }, | |
| ] | |
| const CRYPTO_LIM = [ | |
| { issue: 'No canonical file sorting', impact: 'Different traversal order → different Merkle root for same package' }, | |
| { issue: 'File paths not committed into leaf', impact: 'Directory rename not detected' }, | |
| { issue: 'No permissions or package metadata in leaf', impact: 'Permission changes invisible' }, | |
| { issue: 'Denied files excluded entirely', impact: 'Missing files not represented as null leaves' }, | |
| { issue: 'Depends on filesystem traversal order', impact: 'Non-deterministic across OS/FS' }, | |
| { issue: 'Hashes hex hash strings again', impact: 'No versioned canonical leaf format defined' }, | |
| { issue: 'Receipt hashed but not signed', impact: 'Anyone can modify receipt and recompute hash — no issuer authenticity' }, | |
| { issue: 'No asymmetric signature / key ID / timestamp', impact: 'Not lender-grade — needs PKI signature, trusted timestamp, canonical JSON' }, | |
| ] | |
| const EVIDENCE_LAYERS = [ | |
| { key: 'technical', icon: TestTube, glyph: '⌁', label: 'Technical Evidence', items: ['Reproducible installation', 'Passing tests (executed, not filename-matched)', 'Runtime smoke test', 'Dependency lockfile', 'Supported OS environments', 'Benchmark results', 'Deterministic build receipt'] }, | |
| { key: 'security', icon: ShieldAlert, glyph: '⟁', label: 'Security Evidence (NIST SSDF)', items: ['Verified secret-scan results (full Git history)', 'Revoked + rotated credentials', 'Vulnerability scan (CVE)', 'Dependency audit', 'Threat model', 'Remediation record', 'Push protection enabled'] }, | |
| { key: 'supplychain', icon: Package, glyph: '◇', label: 'Supply-Chain Evidence (SBOM — CISA)', items: ['Component identities + versions', 'Component hashes', 'Licenses', 'Dependency relationships', 'SBOM generation tool + context', 'Generation timestamp'] }, | |
| { key: 'legal', icon: Gavel, glyph: '§', label: 'Legal Evidence', items: ['Authorship declaration', 'Chain of title', 'License manifest', 'Contributor assignments (CLAs)', 'Third-party code review', 'Litigation search', 'Prior-lien search (UCC-1)', 'Exact collateral description'] }, | |
| { key: 'economic', icon: Coins, glyph: '$', label: 'Economic Evidence (3 Approaches)', items: ['Cost: documented recreation cost', 'Market: actual comparable transactions', 'Income: forecast cash flow + discount rate', 'Useful life estimate', 'Probability adjustment', 'Attributable revenue/cost savings'] }, | |
| ] | |
| export default function FileDossier({ fileId, onClose }) { | |
| const [dossier, setDossier] = useState(null) | |
| const [loading, setLoading] = useState(true) | |
| const [error, setError] = useState(null) | |
| const [viewMode, setViewMode] = useState('visual') | |
| const [asciiDossier, setAsciiDossier] = useState('') | |
| const [expanded, setExpanded] = useState({}) | |
| const [copied, setCopied] = useState(false) | |
| const fetchDossier = useCallback(async () => { | |
| setLoading(true); setError(null) | |
| try { | |
| const res = await fetch(`${API_BASE}/resume/${fileId}`) | |
| const data = await res.json() | |
| if (data.error) setError(data.error); else setDossier(data.resume) | |
| } catch (e) { setError(e.message) } finally { setLoading(false) } | |
| }, [fileId]) | |
| const fetchAscii = useCallback(async () => { | |
| try { const res = await fetch(`${API_BASE}/resume/${fileId}?format=text`); setAsciiDossier(await res.text()) } catch { } | |
| }, [fileId]) | |
| useEffect(() => { fetchDossier() }, [fetchDossier]) | |
| useEffect(() => { if (viewMode === 'ascii' && !asciiDossier) fetchAscii() }, [viewMode, asciiDossier, fetchAscii]) | |
| const toggle = (k) => setExpanded(p => ({ ...p, [k]: !p[k] })) | |
| const copyDossier = () => { if (asciiDossier) { navigator.clipboard?.writeText(asciiDossier); setCopied(true); setTimeout(() => setCopied(false), 2000) } } | |
| if (loading) return ( | |
| <div className="flex items-center justify-center h-full p-8"> | |
| <div className="flex flex-col items-center gap-3"> | |
| <Loader2 className="w-6 h-6 text-primary animate-spin" /> | |
| <div className="text-sm text-secondary font-mono">Compiling audited underwriting dossier · security · privacy · valuation deconstruction · crypto · defects · evidence layers…</div> | |
| </div> | |
| </div> | |
| ) | |
| if (error) return ( | |
| <div className="flex items-center justify-center h-full p-8"> | |
| <div className="flex flex-col items-center gap-3"><AlertTriangle className="w-6 h-6 text-critical" /><div className="text-sm text-critical">{error}</div></div> | |
| </div> | |
| ) | |
| if (!dossier) return null | |
| const r = dossier, id = r.identity || {}, dna = r.structural_dna || {}, kpi = r.kpi_summary || {} | |
| const fin = r.financial_profile || {}, legal = r.legal_profile || {}, ml = r.ml_insights || {} | |
| const val = r.valuation_summary || {}, risk = r.risk_assessment || {}, recs = r.recommendations || [] | |
| const llmFacts = r.llm_facts || [], header = r.header || {} | |
| const hasSecret = (risk.signals || []).some(s => s.includes('secret') || s.includes('credential') || s.includes('hardcoded')) | |
| const hasLit = (risk.signals || []).some(s => s.includes('litigation') || s.includes('legal')) | |
| const buildCostLabor = val.time_to_rebuild_days ? Math.round(val.time_to_rebuild_days * 8 * 60) : 0 | |
| const totalKpi = (kpi.total || 0) + (ml.inferred_kpis?.length || 0) + (llmFacts.length || 0) | |
| return ( | |
| <div className="p-6 space-y-4 h-full overflow-y-auto thin-scrollbar"> | |
| {/* Header */} | |
| <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className="glass-strong rounded-2xl p-5"> | |
| <div className="flex items-center justify-between mb-3"> | |
| <div className="flex items-center gap-3"> | |
| <div className="w-8 h-8 rounded-lg bg-gradient-to-br from-primary to-accent flex items-center justify-center glow-orange"> | |
| <FileText className="w-4 h-4 text-bg" /> | |
| </div> | |
| <div> | |
| <div className="text-sm font-bold">{header.title || id.name || 'Unknown'}</div> | |
| <div className="text-[10px] text-secondary font-mono">{header.file_id || fileId} · v3.0 · UNDERWRITING DOSSIER — AUDITED</div> | |
| </div> | |
| </div> | |
| <div className="flex items-center gap-2"> | |
| <div className="flex items-center gap-1 p-1 rounded-lg bg-white/5"> | |
| <button onClick={() => setViewMode('visual')} className={`flex items-center gap-1 px-2 py-1 rounded text-[10px] font-mono transition-all ${viewMode === 'visual' ? 'glass-orange text-primary' : 'text-secondary hover:text-text'}`}><Eye className="w-3 h-3" /> VISUAL</button> | |
| <button onClick={() => setViewMode('ascii')} className={`flex items-center gap-1 px-2 py-1 rounded text-[10px] font-mono transition-all ${viewMode === 'ascii' ? 'glass-orange text-primary' : 'text-secondary hover:text-text'}`}><Code className="w-3 h-3" /> DOSSIER</button> | |
| </div> | |
| {onClose && <button onClick={onClose} className="text-[10px] text-secondary/60 hover:text-text px-2 py-1">✕</button>} | |
| </div> | |
| </div> | |
| <div className="flex items-center gap-4 text-[10px] font-mono text-secondary/60 flex-wrap"> | |
| <span className="flex items-center gap-1"><Hash className="w-3 h-3" />{header.merkle_root?.slice(0, 24) || id.merkle_prefix || '—'}…</span> | |
| <span>│</span><span>{id.primary_purpose || 'unknown'}</span> | |
| <span>│</span><span className="text-critical">⟁ NOT UNDERWRITABLE IN CURRENT FORM</span> | |
| <span>│</span><span className="text-warning">◇ POTENTIALLY UNDERWRITABLE AFTER REMEDIATION</span> | |
| </div> | |
| </motion.div> | |
| {/* Corrected Verdict */} | |
| <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className="glass rounded-2xl p-5 border border-critical/20"> | |
| <div className="flex items-center gap-2 mb-3"> | |
| <ShieldAlert className="w-5 h-5 text-critical" /> | |
| <span className="text-sm font-bold text-critical">Corrected Verdict — Not Underwritable in Present Deployed Form</span> | |
| </div> | |
| <div className="text-xs text-secondary leading-relaxed mb-3"> | |
| <span className="text-text font-semibold">Cryptographically identified software asset</span> with measurable structure, preliminary commercial utility, and <span className="text-critical font-semibold">unresolved security, privacy, and valuation risks</span>. Contains ~{id.lines || 6000} lines, ~159 functions, ~94 FastAPI routes. Exposes critical unauthenticated endpoints, sends source-derived content to external LLMs despite metadata-only claims, and uses keyword-heuristic valuation that does not constitute underwriting evidence. | |
| </div> | |
| <div className="glass rounded-xl p-3 border border-warning/20"> | |
| <div className="text-[10px] uppercase tracking-wider text-warning font-semibold mb-1">Corrected Bottom Line</div> | |
| <div className="text-xs text-secondary"> | |
| <span className="text-warning">Potentially underwritable after:</span> architectural separation of privacy gateway from content analysis · security remediation (auth, path sanitization, endpoint isolation) · independent execution verification · replacement of keyword valuation with evidence-linked appraisal · signed cryptographic receipts | |
| </div> | |
| </div> | |
| <a href={`${API_BASE}/meta/${fileId}`} target="_blank" rel="noopener noreferrer" | |
| className="mt-3 flex items-center gap-3 px-5 py-4 rounded-xl glass-orange text-primary text-base font-mono hover:scale-[1.01] transition-transform glow-orange"> | |
| <ExternalLink className="w-5 h-5" /> | |
| <span className="font-bold text-lg">QUERY FULL FILE →</span> | |
| <span className="text-[10px] text-secondary/60 ml-auto truncate">{API_BASE}/meta/{fileId}</span> | |
| </a> | |
| </motion.div> | |
| <AnimatePresence mode="wait"> | |
| {viewMode === 'ascii' ? ( | |
| <motion.div key="ascii" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} className="glass rounded-2xl p-5"> | |
| <div className="flex items-center justify-between mb-3"> | |
| <span className="text-sm font-semibold">Underwriting Intelligence Report — Audited</span> | |
| <button onClick={copyDossier} className="flex items-center gap-1 text-[10px] text-secondary hover:text-primary transition-colors"> | |
| {copied ? <Check className="w-3 h-3 text-success" /> : <Copy className="w-3 h-3" />}{copied ? 'Copied' : 'Copy'} | |
| </button> | |
| </div> | |
| <pre className="text-[10px] font-mono text-text/80 bg-bg/60 rounded-xl p-4 overflow-x-auto whitespace-pre leading-tight">{asciiDossier || 'Loading…'}</pre> | |
| </motion.div> | |
| ) : ( | |
| <motion.div key="visual" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} className="space-y-4"> | |
| {/* Evidence Tier Legend */} | |
| <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className="glass rounded-2xl p-3 flex items-center gap-4 flex-wrap"> | |
| <span className="text-[10px] uppercase tracking-wider text-secondary/50 font-semibold">Evidence Tiers:</span> | |
| {Object.entries(TIERS).map(([key, t]) => ( | |
| <div key={key} className="flex items-center gap-1.5"> | |
| <span className={`text-sm font-mono ${t.color}`}>{t.glyph}</span> | |
| <span className={`text-[10px] font-mono ${t.color}`}>{t.label}</span> | |
| <span className="text-[9px] text-secondary/40">{t.desc}</span> | |
| </div> | |
| ))} | |
| </motion.div> | |
| {/* Privacy Contradiction */} | |
| <Section icon={EyeOff} glyph="⟁" title="Privacy Contradiction — Metadata-Only Claim is False" tier="measured" | |
| expanded={expanded.privacy !== false} onToggle={() => toggle('privacy')}> | |
| <div className="space-y-3"> | |
| <div className="glass rounded-xl p-3 border border-critical/20"> | |
| <div className="text-xs text-critical font-semibold mb-2">"source_code_sent_to_llm: False" is only accurate for POST /upload evaluation path</div> | |
| {['First 2,000 chars of reconstructed file text for "30 facts"', 'First 1,500 chars for LLM extrapolation', 'File names, extracted KPIs, topics, source-derived previews', 'Fallback calls to Groq, OpenAI, or anonymous LLM7 endpoint'].map((item, i) => ( | |
| <div key={i} className="flex items-center gap-2 text-[11px] font-mono text-warning"><span className="text-critical">⟁</span><span>{item}</span></div> | |
| ))} | |
| </div> | |
| <div className="glass rounded-xl p-3 border border-warning/20"> | |
| <div className="text-[10px] uppercase tracking-wider text-warning font-semibold mb-1">Data Exfiltration Path</div> | |
| <div className="text-[11px] font-mono text-secondary leading-relaxed">unauthenticated /index/path → read local server file → store source previews in SQLite → retrieve via /search, /chunk, /ml, or dossier → transmit previews to external LLM</div> | |
| <div className="text-[10px] text-critical mt-2 font-semibold">RELEASE-BLOCKING</div> | |
| </div> | |
| </div> | |
| </Section> | |
| {/* Security Blockers */} | |
| <Section icon={ShieldAlert} glyph="⟁" title={`Security Blockers (${SEC_BL.length}) — Release Blocking`} tier="measured" | |
| expanded={expanded.security !== false} onToggle={() => toggle('security')}> | |
| <div className="space-y-2"> | |
| {SEC_BL.map((b, i) => { | |
| const Icon = b.icon | |
| const sc = b.sev === 'CRITICAL' ? 'text-critical border-critical/30' : b.sev === 'HIGH' ? 'text-warning border-warning/30' : 'text-primary border-primary/30' | |
| return ( | |
| <div key={i} className={`glass rounded-xl p-3 border ${sc}`}> | |
| <div className="flex items-start gap-3"> | |
| <Icon className={`w-4 h-4 flex-shrink-0 mt-0.5 ${sc}`} /> | |
| <div className="flex-1 min-w-0"> | |
| <div className="flex items-center gap-2 mb-1"> | |
| <span className={`text-[9px] font-mono font-bold px-1.5 py-0.5 rounded ${sc} border`}>{b.sev}</span> | |
| <span className="text-xs font-mono text-text">{b.finding}</span> | |
| </div> | |
| <div className="text-[10px] text-secondary/70 font-mono">→ {b.consequence}</div> | |
| </div> | |
| </div> | |
| </div> | |
| ) | |
| })} | |
| </div> | |
| </Section> | |
| {/* Identity + DNA */} | |
| <div className="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
| <Section icon={FileCode} glyph="◉" title="Artifact Identity" tier="measured" | |
| expanded={expanded.identity !== false} onToggle={() => toggle('identity')}> | |
| <div className="grid grid-cols-2 gap-3 text-xs"> | |
| <SR label="Species" value={id.species} mono tier="measured" /> | |
| <SR label="Size" value={id.size} mono tier="measured" /> | |
| <SR label="Lines" value={id.lines} mono tier="measured" /> | |
| <SR label="Words" value={id.words} mono tier="measured" /> | |
| <SR label="Chunks" value={id.chunks} mono tier="measured" /> | |
| <SR label="Symbols" value={id.symbols} mono tier="measured" /> | |
| <SR label="Vocabulary" value={id.vocabulary} mono tier="measured" /> | |
| <SR label="Functions" value="~159" mono tier="measured" /> | |
| <SR label="FastAPI Routes" value="~94" mono tier="measured" /> | |
| <SR label="Parse Status" value="Valid Python" mono tier="measured" /> | |
| </div> | |
| {id.all_purposes?.length > 0 && ( | |
| <div className="mt-3 pt-3 border-t border-white/5"> | |
| <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">Detected Purposes</div> | |
| <div className="flex flex-wrap gap-1.5"> | |
| {id.all_purposes.map((p, i) => <span key={i} className="text-[10px] px-2 py-1 rounded-lg glass-orange text-primary font-mono">{p}</span>)} | |
| </div> | |
| </div> | |
| )} | |
| </Section> | |
| <Section icon={Dna} glyph="◇" title="Structural DNA" tier="measured" | |
| expanded={expanded.dna !== false} onToggle={() => toggle('dna')}> | |
| <div className="space-y-3"> | |
| <div className="flex items-center justify-between"> | |
| <span className="text-xs text-secondary">Complexity</span> | |
| <div className="flex items-center gap-2"> | |
| <div className="w-24 h-1.5 rounded-full bg-white/5 overflow-hidden"> | |
| <div className="h-full bar-fill" style={{ width: `${Math.min(dna.complexity_score || 0, 100)}%` }} /> | |
| </div> | |
| <span className="text-xs font-mono text-primary">{(dna.complexity_score || 0).toFixed(1)}</span> | |
| </div> | |
| </div> | |
| <SR label="Interpretation" value={dna.interpretation} tier="measured" /> | |
| <SR label="Genome Size" value={`${dna.genome_size || 0} bytes`} mono tier="measured" /> | |
| <SR label="Hashing" value="SHA-256" mono tier="measured" /> | |
| <SR label="Chunking" value="Semantic boundary" mono tier="measured" /> | |
| {dna.genes && Object.keys(dna.genes).length > 0 && ( | |
| <div className="pt-2 border-t border-white/5"> | |
| <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">Genes ({Object.keys(dna.genes).length})</div> | |
| <div className="grid grid-cols-2 gap-1.5"> | |
| {Object.entries(dna.genes).slice(0, 16).map(([k, v]) => ( | |
| <span key={k} className="text-[10px] px-2 py-1 rounded-lg bg-white/5 text-secondary font-mono">{k}: {String(v).slice(0, 20)}</span> | |
| ))} | |
| </div> | |
| </div> | |
| )} | |
| </div> | |
| </Section> | |
| </div> | |
| {/* Crypto Limitations */} | |
| <Section icon={Lock} glyph="🔒" title="Cryptographic Evidence — Limitations Audit" tier="inferred" | |
| expanded={expanded.crypto !== false} onToggle={() => toggle('crypto')}> | |
| <div className="space-y-2"> | |
| <div className="glass rounded-xl p-3 border border-warning/20 mb-2"> | |
| <div className="text-[10px] uppercase tracking-wider text-warning font-semibold mb-1">Receipt is hashed, not signed</div> | |
| <div className="text-[11px] font-mono text-secondary">receipt_hash = SHA256(receipt) — anyone can modify and recompute. Not lender-grade.</div> | |
| </div> | |
| {CRYPTO_LIM.map((c, i) => ( | |
| <div key={i} className="flex items-start gap-3 py-2 px-3 rounded-lg bg-white/3"> | |
| <span className="text-warning text-sm font-mono flex-shrink-0">⚠</span> | |
| <div className="flex-1"> | |
| <div className="text-[11px] font-mono text-text">{c.issue}</div> | |
| <div className="text-[10px] text-secondary/60 font-mono mt-0.5">→ {c.impact}</div> | |
| </div> | |
| </div> | |
| ))} | |
| <div className="glass rounded-xl p-3 border border-primary/20 mt-2"> | |
| <div className="text-[10px] uppercase tracking-wider text-primary font-semibold mb-1">Required for Lender-Grade</div> | |
| <div className="text-[11px] font-mono text-secondary">Asymmetric signature (Ed25519/ECDSA) · Key identifier · Canonical JSON encoding · Trusted timestamp (RFC 3161) · Verification procedure</div> | |
| </div> | |
| </div> | |
| </Section> | |
| {/* Valuation Deconstruction */} | |
| <Section icon={DollarSign} glyph="$" title="Valuation — Heuristic Deconstruction & Corrected" tier="inferred" | |
| expanded={expanded.valuation !== false} onToggle={() => toggle('valuation')}> | |
| <div className="space-y-4"> | |
| <div className="glass rounded-xl p-4 border border-critical/20"> | |
| <div className="flex items-center gap-2 mb-2"> | |
| <AlertTriangle className="w-3.5 h-3.5 text-critical" /> | |
| <span className="text-[10px] uppercase tracking-wider text-critical font-semibold">Exposed: Keyword-Heuristic Valuation Formula</span> | |
| </div> | |
| <div className="space-y-2 text-[11px] font-mono"> | |
| <div className="text-secondary">Collateral: <span className="text-critical">min(signal_count × 3, 100)</span></div> | |
| <div className="text-secondary/60 text-[10px]">→ Document discussing "revenue", "collateral", "litigation" scores A. Terms ≠ ownership, enforceability, revenue, or liquidation value.</div> | |
| <div className="text-secondary mt-2">Liquidity: <span className="text-critical">score ≥ 60 → time_to_liquidate = "days"</span></div> | |
| <div className="text-secondary/60 text-[10px]">→ Semantically circular. File mentioning liquidity ≠ liquid.</div> | |
| <div className="text-secondary mt-2">Borrowing base: <span className="text-critical">low = score × $5 · mid = score × $15 · high = score × $25</span></div> | |
| <div className="text-secondary/60 text-[10px]">→ Price mapping, not appraisal. No comparable sales, advance rates, enforcement cost.</div> | |
| <div className="text-secondary mt-2">Insurance: <span className="text-critical">replacement + $5K security + $10K payment + $8K auth + $3K readiness≥60</span></div> | |
| <div className="text-secondary/60 text-[10px]">→ Fixed keyword bonuses, not insurance loss model.</div> | |
| </div> | |
| </div> | |
| <div className="grid grid-cols-2 md:grid-cols-4 gap-3"> | |
| <CVC label="Stated Build Cost" stated={`$${val.build_cost_usd || 0}`} corrected={`$${buildCostLabor}`} note="2.3d × 8h × $60/h labor" status="corrected" /> | |
| <CVC label="Stated Replacement" stated={`$${val.replacement_cost_usd || '—'}`} corrected="$4K–$12K" note="Engineering recreation of prototypes" status="corrected" /> | |
| <CVC label="Stated Insurance" stated={`$${val.insurance_value_usd?.toLocaleString() || '—'}`} corrected="Max Loss Exposure" note="Relabeled — not asset valuation" status="relabeled" /> | |
| <CVC label="Stated Liquidation" stated={`$${(val.replacement_cost_usd || 0) * 5}`} corrected="$0–$2,500" note="No buyers, revenue, contracts" status="corrected" /> | |
| </div> | |
| <div className="grid grid-cols-1 md:grid-cols-3 gap-3"> | |
| <VAC label="Cost Approach" glyph="⌁" icon={Coins} value={`$${buildCostLabor}–$12K`} confidence="LOW" tier="inferred" detail="WIPO cost method — engineering recreation" assumptions={[`Labor: $60/h × ${(val.time_to_rebuild_days || 0) * 8}h`, 'Compute + data + testing', 'Documentation burden']} /> | |
| <VAC label="Market Approach" glyph="◆" icon={BarChart3} value="No comparables" confidence="UNVERIFIED" tier="unverified" detail="No comparable code sales, licenses, or acquisitions" assumptions={['No identified transactions', 'No comparable licenses', 'No acquisition multiples']} /> | |
| <VAC label="Income Approach" glyph="▲" icon={TrendingUp} value="No cash flow" confidence="UNVERIFIED" tier="unverified" detail="IVS 210 — no attributable forecast cash flow" assumptions={['No revenue record', 'No cost savings', 'No discount rate']} /> | |
| </div> | |
| <div className="glass rounded-xl p-4 border border-primary/20"> | |
| <div className="flex items-center gap-2 mb-2"> | |
| <Coins className="w-3.5 h-3.5 text-primary" /> | |
| <span className="text-[10px] uppercase tracking-wider text-primary font-semibold">Defensible Economic Interpretation</span> | |
| </div> | |
| <div className="grid grid-cols-1 md:grid-cols-2 gap-3 text-xs"> | |
| <div><div className="text-[10px] text-secondary/50">As-is salvage/recreation</div><div className="font-mono text-warning">$4,000–$12,000</div></div> | |
| <div><div className="text-[10px] text-secondary/50">Cost to production-harden</div><div className="font-mono text-warning">$20,000–$60,000</div></div> | |
| <div><div className="text-[10px] text-secondary/50">Current liquidation/collateral</div><div className="font-mono text-critical">$0–$2,500</div></div> | |
| <div><div className="text-[10px] text-secondary/50">Potential post-remediation</div><div className="font-mono text-success">Substantially higher — dependent on real customers</div></div> | |
| </div> | |
| </div> | |
| </div> | |
| </Section> | |
| {/* Defensible Scoring */} | |
| <Section icon={BarChart3} glyph="◆" title="Defensible Scoring — Revised (Overall D / ~32)" tier="inferred" | |
| expanded={expanded.scoring !== false} onToggle={() => toggle('scoring')}> | |
| <div className="space-y-1"> | |
| {DEFI_SCORES.map((s, i) => ( | |
| <div key={i} className="flex items-center gap-3 py-2 px-3 rounded-lg bg-white/3 hover:bg-white/5 transition-all"> | |
| <span className={`text-sm font-mono ${TIERS[s.tier]?.color || 'text-secondary'}`}>{TIERS[s.tier]?.glyph || '?'}</span> | |
| <span className="text-xs text-text flex-1">{s.dim}</span> | |
| <div className="w-32 h-1.5 rounded-full bg-white/5 overflow-hidden"> | |
| <div className={`h-full ${s.score >= 70 ? 'bg-success' : s.score >= 40 ? 'bg-warning' : 'bg-critical'}`} style={{ width: `${s.score}%` }} /> | |
| </div> | |
| <span className={`text-xs font-bold ${GC[s.grade] || 'text-secondary'} w-8 text-center`}>{s.grade}</span> | |
| <span className="text-[10px] font-mono text-secondary w-10 text-right">{s.score}/100</span> | |
| </div> | |
| ))} | |
| </div> | |
| <div className="mt-3 pt-3 border-t border-white/5 text-[10px] font-mono text-secondary/40"> | |
| Eligibility ≠ Bankability: software may legally be pledged, borrower may own it, lender may perfect security interest — yet asset may have negligible liquidation value without buyers, revenue, documentation, or operating system. | |
| </div> | |
| </Section> | |
| {/* Five Evidence Layers */} | |
| <Section icon={Layers} glyph="◇" title="Five Evidence Layers — Underwriting Package Requirements" tier="unverified" | |
| expanded={expanded.evidence !== false} onToggle={() => toggle('evidence')}> | |
| <div className="space-y-3"> | |
| {EVIDENCE_LAYERS.map(layer => { | |
| const Icon = layer.icon | |
| return ( | |
| <div key={layer.key} className="glass rounded-xl p-3"> | |
| <div className="flex items-center gap-2 mb-2"> | |
| <span className="text-primary text-sm font-mono">{layer.glyph}</span> | |
| <Icon className="w-3.5 h-3.5 text-primary" /> | |
| <span className="text-xs font-semibold">{layer.label}</span> | |
| <span className="text-[9px] font-mono text-critical ml-auto">ALL UNVERIFIED</span> | |
| </div> | |
| <div className="grid grid-cols-1 md:grid-cols-2 gap-1"> | |
| {layer.items.map((item, i) => ( | |
| <div key={i} className="flex items-center gap-2 text-[10px] font-mono text-secondary/60"> | |
| <span className="text-critical">?</span><span>{item}</span> | |
| </div> | |
| ))} | |
| </div> | |
| </div> | |
| ) | |
| })} | |
| </div> | |
| </Section> | |
| {/* Implementation Defects */} | |
| <Section icon={Bug} glyph="⊗" title={`Implementation Defects (${IMPL_DEFS.length})`} tier="measured" | |
| expanded={expanded.defects !== false} onToggle={() => toggle('defects')}> | |
| <div className="space-y-2"> | |
| {IMPL_DEFS.map((d, i) => ( | |
| <div key={i} className={`flex items-start gap-3 py-2.5 px-3 rounded-xl ${d.sev === 'high' ? 'bg-critical/5' : d.sev === 'medium' ? 'bg-warning/5' : 'bg-white/3'}`}> | |
| <span className={`text-sm font-mono flex-shrink-0 ${d.sev === 'high' ? 'text-critical' : d.sev === 'medium' ? 'text-warning' : 'text-secondary'}`}>{d.sev === 'high' ? '⟁' : d.sev === 'medium' ? '▲' : '◇'}</span> | |
| <div className="flex-1"> | |
| <div className="text-[11px] font-mono text-text">{d.bug}</div> | |
| <div className="text-[10px] text-secondary/60 font-mono mt-0.5">→ {d.impact}</div> | |
| </div> | |
| <span className={`text-[9px] font-mono uppercase px-1.5 py-0.5 rounded ${d.sev === 'high' ? 'text-critical bg-critical/10' : d.sev === 'medium' ? 'text-warning bg-warning/10' : 'text-secondary bg-white/5'}`}>{d.sev}</span> | |
| </div> | |
| ))} | |
| </div> | |
| </Section> | |
| {/* Financial + Legal */} | |
| <div className="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
| <Section icon={TrendingUp} glyph="▲" title="Financial Profile — Corrected" tier="unverified" | |
| expanded={expanded.financial !== false} onToggle={() => toggle('financial')}> | |
| <div className="space-y-3"> | |
| <div className="glass rounded-xl p-3 border border-critical/20"> | |
| <div className="text-[10px] uppercase tracking-wider text-critical font-semibold mb-1">Collateral Grade: F (GATED)</div> | |
| <div className="text-[11px] font-mono text-secondary">Secret exposure gate triggered. Unconditional A grade is invalid when risk=90/100, secret_exposure, and litigation_risk exist.</div> | |
| </div> | |
| <div className="grid grid-cols-2 gap-3"> | |
| <GC2 label="Collateral (Corrected)" grade="F" score={0} /> | |
| <GC2 label="Liquidity (Corrected)" grade="D+" score={35} /> | |
| </div> | |
| <SR label="Time to Liquidate" value="UNPROVEN — no identified buyer/lender/channel" tier="unverified" /> | |
| <SR label="Monetary Refs" value={fin.monetary_references} mono tier="measured" /> | |
| {fin.has_financial_statements && <span className="text-[10px] px-2 py-1 rounded-lg bg-success/10 text-success font-mono">◆ Financial statements detected</span>} | |
| {fin.finance_metrics && Object.keys(fin.finance_metrics).length > 0 && ( | |
| <div className="pt-2 border-t border-white/5"> | |
| <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">Metrics Detected</div> | |
| <div className="flex flex-wrap gap-1.5"> | |
| {Object.entries(fin.finance_metrics).map(([k, v]) => <span key={k} className="text-[10px] px-2 py-1 rounded-lg bg-white/5 text-secondary font-mono">{k} ×{v}</span>)} | |
| </div> | |
| </div> | |
| )} | |
| </div> | |
| </Section> | |
| <Section icon={Scale} glyph="§" title="Legal Profile" tier="inferred" | |
| expanded={expanded.legal !== false} onToggle={() => toggle('legal')}> | |
| <div className="space-y-3"> | |
| <div className="glass rounded-xl p-3 border border-primary/20"> | |
| <div className="text-[10px] uppercase tracking-wider text-primary font-semibold mb-1">UCC Article 9 — General Intangible</div> | |
| <div className="text-[11px] font-mono text-secondary">Software may legally be pledged. Does NOT establish market value, lender acceptance, ownership, priority, or recoverability.</div> | |
| </div> | |
| {legal.has_contract_language && <span className="text-[10px] px-2 py-1 rounded-lg bg-warning/10 text-warning font-mono">⚠ Contract language detected</span>} | |
| {legal.regulatory?.length > 0 && ( | |
| <div><div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">Regulatory</div> | |
| <div className="flex flex-wrap gap-1.5">{legal.regulatory.map(r => <span key={r} className="text-[10px] px-2 py-1 rounded-lg bg-critical/10 text-critical font-mono">{r}</span>)}</div> | |
| </div> | |
| )} | |
| {legal.ip_references?.length > 0 && ( | |
| <div><div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">IP References</div> | |
| <div className="flex flex-wrap gap-1.5">{legal.ip_references.map(r => <span key={r} className="text-[10px] px-2 py-1 rounded-lg bg-white/5 text-secondary font-mono">{r}</span>)}</div> | |
| </div> | |
| )} | |
| </div> | |
| </Section> | |
| </div> | |
| {/* ML Insights */} | |
| <Section icon={Brain} glyph="⟡" title="ML Insights" tier="inferred" | |
| expanded={expanded.ml !== false} onToggle={() => toggle('ml')}> | |
| {ml.available ? ( | |
| <div className="space-y-3"> | |
| {ml.topics?.length > 0 && ( | |
| <div><div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">NMF Topics</div> | |
| <div className="space-y-2">{ml.topics.map((t, i) => ( | |
| <div key={i} className="flex items-center gap-3 py-2 px-3 rounded-lg bg-white/3"> | |
| <span className="text-[10px] font-mono text-primary flex-shrink-0">T{t.id}</span> | |
| <div className="flex-1 flex flex-wrap gap-1">{t.keywords?.map((kw, j) => <span key={j} className="text-[10px] px-1.5 py-0.5 rounded bg-white/5 text-secondary font-mono">{kw}</span>)}</div> | |
| <span className="text-[10px] font-mono text-secondary/40 flex-shrink-0">{t.chunk_count} chunks</span> | |
| </div> | |
| ))}</div> | |
| </div> | |
| )} | |
| {ml.tfidf_top?.length > 0 && ( | |
| <div><div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">TF-IDF Top Terms</div> | |
| <div className="flex flex-wrap gap-1.5">{ml.tfidf_top.map((t, i) => <span key={i} className="text-[10px] px-2 py-1 rounded-lg glass-orange text-primary font-mono">{typeof t === 'object' ? t.term || t : t}</span>)}</div> | |
| </div> | |
| )} | |
| <div className="grid grid-cols-2 md:grid-cols-4 gap-2 text-[10px] font-mono"> | |
| {ml.information_density && <div className="glass rounded-lg p-2"><div className="text-secondary/50">Info Density</div><div className="text-primary">{ml.information_density} bits/char</div></div>} | |
| {ml.zipf_slope && <div className="glass rounded-lg p-2"><div className="text-secondary/50">Zipf Slope</div><div className="text-primary">{ml.zipf_slope}</div></div>} | |
| {ml.vocabulary_concentration && <div className="glass rounded-lg p-2"><div className="text-secondary/50">Vocab Concentration</div><div className="text-primary">{ml.vocabulary_concentration}</div></div>} | |
| {ml.topic_coherence && <div className="glass rounded-lg p-2"><div className="text-secondary/50">Topic Coherence</div><div className="text-primary">{ml.topic_coherence}</div></div>} | |
| </div> | |
| {ml.anomaly_count > 0 && ( | |
| <div className="flex items-center gap-2 text-xs text-warning"><AlertTriangle className="w-3.5 h-3.5" />{ml.anomaly_count} anomalous chunks (Isolation Forest) — analysis on 3-line previews, degraded accuracy</div> | |
| )} | |
| {ml.llm_extrapolation && ( | |
| <div className="pt-2 border-t border-white/5"> | |
| <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">LLM Extrapolation (⚠ uses source-derived content)</div> | |
| <div className="space-y-2 text-xs"> | |
| {ml.llm_extrapolation.inferred_purpose && <div className="text-secondary"><span className="text-primary font-mono">Purpose:</span> {ml.llm_extrapolation.inferred_purpose}</div>} | |
| {ml.llm_extrapolation.hidden_value && <div className="text-secondary"><span className="text-primary font-mono">Hidden Value:</span> {ml.llm_extrapolation.hidden_value}</div>} | |
| {ml.llm_extrapolation.counterparty_risk && <div className="text-secondary"><span className="text-critical font-mono">Risk:</span> {ml.llm_extrapolation.counterparty_risk}</div>} | |
| {ml.llm_extrapolation.monetization_vector && <div className="text-secondary"><span className="text-success font-mono">Monetization:</span> {ml.llm_extrapolation.monetization_vector}</div>} | |
| </div> | |
| </div> | |
| )} | |
| </div> | |
| ) : <div className="text-xs text-secondary/50 py-4 text-center">ML features unavailable — {ml.error || 'scikit-learn not installed'}</div>} | |
| </Section> | |
| {/* KPI Summary — Expanded */} | |
| <Section icon={Hash} glyph="#" title={`KPI Summary (${totalKpi} total — expanded)`} tier="measured" | |
| expanded={expanded.kpi !== false} onToggle={() => toggle('kpi')}> | |
| <div className="space-y-3"> | |
| {kpi.by_category && Object.keys(kpi.by_category).length > 0 && ( | |
| <div className="flex flex-wrap gap-2"> | |
| {Object.entries(kpi.by_category).map(([cat, count]) => ( | |
| <span key={cat} className="text-[10px] px-2 py-1 rounded-lg bg-white/5 text-secondary font-mono">{cat}: {count}</span> | |
| ))} | |
| {ml.inferred_kpis?.length > 0 && <span className="text-[10px] px-2 py-1 rounded-lg bg-warning/10 text-warning font-mono">ml_inferred: {ml.inferred_kpis.length}</span>} | |
| {llmFacts.length > 0 && <span className="text-[10px] px-2 py-1 rounded-lg bg-primary/10 text-primary font-mono">llm_generated: {llmFacts.length}</span>} | |
| </div> | |
| )} | |
| {kpi.top_financial?.length > 0 && ( | |
| <div><div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">Top Financial KPIs</div> | |
| <div className="space-y-1">{kpi.top_financial.map((k, i) => ( | |
| <div key={i} className="flex items-center gap-2 text-[11px] font-mono py-1 px-2 rounded-lg bg-white/3"> | |
| <span className="text-success text-[9px]">◉</span> | |
| <span className="text-primary flex-shrink-0">{k.name}</span> | |
| <span className="text-text flex-1 truncate">{k.value}</span> | |
| <span className="text-secondary/40">L{k.line}</span> | |
| </div> | |
| ))}</div> | |
| </div> | |
| )} | |
| {kpi.top_technical?.length > 0 && ( | |
| <div><div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">Top Technical KPIs</div> | |
| <div className="space-y-1">{kpi.top_technical.map((k, i) => ( | |
| <div key={i} className="flex items-center gap-2 text-[11px] font-mono py-1 px-2 rounded-lg bg-white/3"> | |
| <span className="text-success text-[9px]">◉</span> | |
| <span className="text-primary flex-shrink-0">{k.name}</span> | |
| <span className="text-text flex-1 truncate">{k.value}</span> | |
| <span className="text-secondary/40">L{k.line}</span> | |
| </div> | |
| ))}</div> | |
| </div> | |
| )} | |
| {ml.inferred_kpis?.length > 0 && ( | |
| <div><div className="text-[10px] uppercase tracking-wider text-warning/50 mb-2">ML-Inferred KPIs (◇ inferred)</div> | |
| <div className="grid grid-cols-1 md:grid-cols-2 gap-2">{ml.inferred_kpis.map((k, i) => ( | |
| <div key={i} className="flex items-center gap-2 py-1.5 px-2 rounded-lg bg-warning/3"> | |
| <span className="text-warning text-[9px]">◇</span> | |
| <span className="text-[10px] font-mono text-primary flex-shrink-0">{k.name}</span> | |
| <span className="text-[10px] font-mono text-text flex-1 truncate">{k.value}</span> | |
| <span className="text-[9px] font-mono text-secondary/40">{k.method}</span> | |
| </div> | |
| ))}</div> | |
| </div> | |
| )} | |
| </div> | |
| </Section> | |
| {/* Risk Assessment */} | |
| <Section icon={AlertTriangle} glyph="⟁" title="Risk Assessment" tier="measured" | |
| expanded={expanded.risk !== false} onToggle={() => toggle('risk')}> | |
| <div className="space-y-3"> | |
| <div className="flex items-center gap-4"> | |
| <div className={`text-2xl font-bold ${RC[risk.level] || 'text-secondary'}`}>{risk.level?.toUpperCase()}</div> | |
| <div className="text-sm font-mono text-secondary">{risk.score}/100</div> | |
| <div className="flex-1" /> | |
| <div className="text-right"><div className="text-[10px] text-secondary/50">Origin</div><div className="text-xs font-mono text-primary">{risk.origin}</div></div> | |
| </div> | |
| {risk.signals?.length > 0 && ( | |
| <div className="flex flex-wrap gap-1.5">{risk.signals.map((s, i) => <span key={i} className="text-[10px] px-2 py-1 rounded-lg bg-critical/10 text-critical font-mono">⟁ {s}</span>)}</div> | |
| )} | |
| <div className="glass rounded-xl p-3 border border-critical/20"> | |
| <div className="text-[10px] uppercase tracking-wider text-critical font-semibold mb-1">Risk-Collateral Contradiction</div> | |
| <div className="text-[11px] font-mono text-secondary">Risk 90/100 + secret_exposure + litigation_risk → Collateral A (100/100) is invalid. Corrected: F (0/100) — gated.</div> | |
| </div> | |
| </div> | |
| </Section> | |
| {/* LLM Facts */} | |
| {llmFacts.length > 0 && ( | |
| <Section icon={Sparkles} glyph="⟡" title={`LLM Facts (${llmFacts.length}) — ⚠ Source-derived content sent to LLM`} tier="inferred" | |
| expanded={expanded.llmfacts !== false} onToggle={() => toggle('llmfacts')}> | |
| <div className="grid grid-cols-1 md:grid-cols-2 gap-2"> | |
| {llmFacts.map((fact, i) => ( | |
| <div key={fact.id || i} className="flex items-center gap-3 py-2 px-3 rounded-lg bg-white/3 hover:bg-white/5 transition-all"> | |
| <span className="text-[10px] font-mono text-primary/60 flex-shrink-0 w-6">{String(fact.id || i + 1).padStart(2, '0')}</span> | |
| <span className="text-[10px] font-mono text-primary flex-shrink-0 w-28 truncate">{fact.label}</span> | |
| <span className="text-[10px] font-mono text-text flex-1 truncate">{fact.value}</span> | |
| <span className="text-[9px] font-mono text-secondary/40 flex-shrink-0 uppercase">{fact.category}</span> | |
| <span className="text-[9px] font-mono text-secondary/30 flex-shrink-0">{((fact.confidence || 0) * 100).toFixed(0)}%</span> | |
| </div> | |
| ))} | |
| </div> | |
| <div className="mt-3 pt-3 border-t border-white/5 flex items-center gap-3 text-[10px] font-mono text-secondary/40"> | |
| <span>⟡ Groq LLM · llama-3.3-70b</span><span>│</span> | |
| <span className="text-warning">⚠ First 2,000 chars of file content sent to LLM</span> | |
| </div> | |
| </Section> | |
| )} | |
| {/* Recommendations */} | |
| <Section icon={Lightbulb} glyph="✦" title={`Recommendations (${recs.length})`} tier="inferred" | |
| expanded={expanded.recs !== false} onToggle={() => toggle('recs')}> | |
| <div className="space-y-2"> | |
| {recs.map((rec, i) => ( | |
| <div key={i} className={`flex items-center gap-3 py-2.5 px-3 rounded-xl ${PC[rec.priority] || ''}`}> | |
| <span className="text-sm font-mono flex-shrink-0">{PG[rec.priority] || '◌'}</span> | |
| <div className="flex-1 min-w-0"> | |
| <div className="flex items-center gap-2"> | |
| <span className="text-xs font-mono font-medium">{rec.action}</span> | |
| <span className="text-[9px] uppercase tracking-wider opacity-60">{rec.priority}</span> | |
| </div> | |
| <div className="text-[10px] opacity-70 mt-0.5">{rec.reason}</div> | |
| </div> | |
| </div> | |
| ))} | |
| </div> | |
| </Section> | |
| {/* Strongest Product */} | |
| <Section icon={Microscope} glyph="◆" title="Strongest Product — Hidden Inside" tier="inferred" | |
| expanded={expanded.product !== false} onToggle={() => toggle('product')}> | |
| <div className="glass rounded-xl p-4 border border-primary/20"> | |
| <div className="text-xs text-primary font-semibold mb-2">Privacy-scoped software evidence gateway</div> | |
| <div className="text-[11px] text-secondary leading-relaxed mb-3"> | |
| Creates reproducible structural manifests and signed evaluation packets without transferring source code to an evaluator. To make this statement true, the underwriting gateway must be physically separated from Jorki content analysis, deployment automation, audio processing, and RentMasseur operations. | |
| </div> | |
| <div className="grid grid-cols-1 md:grid-cols-2 gap-2 text-[10px] font-mono"> | |
| <div className="glass rounded-lg p-2"><div className="text-secondary/50">Separate from:</div><div className="text-critical">Content analysis · LLM calls · Deployment · Audio · RentMasseur</div></div> | |
| <div className="glass rounded-lg p-2"><div className="text-secondary/50">Keep in gateway:</div><div className="text-success">Hashing · Merkle · Metadata · KPI extraction · Signed receipts</div></div> | |
| </div> | |
| </div> | |
| </Section> | |
| </motion.div> | |
| )} | |
| </AnimatePresence> | |
| </div> | |
| ) | |
| } | |
| // ─── Sub-components ─── | |
| function Section({ icon: Icon, glyph, title, tier, expanded, onToggle, children }) { | |
| const t = TIERS[tier] || TIERS.unverified | |
| return ( | |
| <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className="glass rounded-2xl overflow-hidden"> | |
| <button onClick={onToggle} className="w-full flex items-center gap-3 px-5 py-3.5 hover:bg-white/3 transition-all"> | |
| <span className={`text-sm font-mono ${t.color}`}>{t.glyph}</span> | |
| <span className="text-primary text-sm font-mono">{glyph}</span> | |
| <Icon className="w-4 h-4 text-primary" /> | |
| <span className="text-sm font-semibold flex-1 text-left">{title}</span> | |
| {expanded !== false ? <ChevronDown className="w-4 h-4 text-secondary/50" /> : <ChevronRight className="w-4 h-4 text-secondary/50" />} | |
| </button> | |
| <AnimatePresence> | |
| {expanded !== false && ( | |
| <motion.div initial={{ height: 0, opacity: 0 }} animate={{ height: 'auto', opacity: 1 }} exit={{ height: 0, opacity: 0 }} transition={{ duration: 0.2 }} className="overflow-hidden"> | |
| <div className="px-5 pb-5">{children}</div> | |
| </motion.div> | |
| )} | |
| </AnimatePresence> | |
| </motion.div> | |
| ) | |
| } | |
| function SR({ label, value, mono, tier }) { | |
| const t = TIERS[tier] || TIERS.unverified | |
| return ( | |
| <div className="flex items-center justify-between py-1"> | |
| <span className="text-secondary/60 text-[10px] uppercase tracking-wider">{label}</span> | |
| <div className="flex items-center gap-1.5"> | |
| <span className={`text-[9px] ${t.color}`}>{t.glyph}</span> | |
| <span className={`text-text ${mono ? 'font-mono' : ''} text-xs truncate ml-1`}>{value ?? '—'}</span> | |
| </div> | |
| </div> | |
| ) | |
| } | |
| function CVC({ label, stated, corrected, note, status }) { | |
| return ( | |
| <div className="glass rounded-xl p-3 border border-warning/20"> | |
| <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-1">{label}</div> | |
| <div className="text-xs font-mono text-secondary/40 line-through">{stated}</div> | |
| <div className="text-sm font-bold font-mono text-warning">{corrected}</div> | |
| <div className="text-[9px] text-secondary/40 mt-0.5">{note}</div> | |
| <div className={`text-[9px] font-mono mt-1 ${status === 'corrected' ? 'text-warning' : 'text-primary'}`}>{status === 'corrected' ? '⚠ CORRECTED' : '↻ RELABELED'}</div> | |
| </div> | |
| ) | |
| } | |
| function VAC({ label, glyph, icon: Icon, value, confidence, tier, detail, assumptions }) { | |
| const t = TIERS[tier] || TIERS.unverified | |
| const confColor = confidence === 'LOW' ? 'text-warning' : 'text-critical' | |
| return ( | |
| <div className="glass rounded-xl p-3"> | |
| <div className="flex items-center gap-2 mb-2"> | |
| <span className={`text-sm font-mono ${t.color}`}>{t.glyph}</span> | |
| <Icon className="w-3.5 h-3.5 text-primary" /> | |
| <span className="text-xs font-semibold">{label}</span> | |
| </div> | |
| <div className="text-sm font-bold font-mono text-text mb-1">{value}</div> | |
| <div className={`text-[9px] font-mono ${confColor} mb-2`}>Confidence: {confidence}</div> | |
| <div className="text-[10px] text-secondary/60 mb-2">{detail}</div> | |
| <div className="space-y-0.5"> | |
| {assumptions.map((a, i) => <div key={i} className="text-[9px] font-mono text-secondary/40">• {a}</div>)} | |
| </div> | |
| </div> | |
| ) | |
| } | |
| function GC2({ label, grade, score }) { | |
| return ( | |
| <div className="glass rounded-xl p-3"> | |
| <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-1">{label}</div> | |
| <div className="flex items-center gap-2"> | |
| <span className={`text-lg font-bold ${GC[grade] || 'text-secondary'}`}>{grade}</span> | |
| <span className="text-xs font-mono text-secondary">{score}/100</span> | |
| </div> | |
| </div> | |
| ) | |
| } | |