← back to Consulting Rentv Com
portal: add Sources & Methodology data-provenance section
be831941447a68d0974c5ee918fa5ea553cc43f0 · 2026-07-25 13:03:16 -0700 · Steve Abrams
Files touched
M build.mjsM public/portal.html
Diff
commit be831941447a68d0974c5ee918fa5ea553cc43f0
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Sat Jul 25 13:03:16 2026 -0700
portal: add Sources & Methodology data-provenance section
---
build.mjs | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
public/portal.html | 23 ++++++++++++++++++++-
2 files changed, 79 insertions(+), 3 deletions(-)
diff --git a/build.mjs b/build.mjs
index 2c8275a..6c746c7 100644
--- a/build.mjs
+++ b/build.mjs
@@ -257,7 +257,7 @@ const partners = [
];
const partnerRows = partners.map((p,i)=>`<div class="pcard rv"><div class="pnum">${String(i+1).padStart(2,'0')}</div><div><h4>${p[0]}</h4><p>${p[1]}</p></div></div>`).join('');
-const CATS = [['summary','Executive Summary'],['swot','SWOT Analysis'],['reputation','Reputation & Authority'],['empire','The Empire & Sublease.com'],['competitors','Competitors'],['advertising','Where to Advertise'],['timing','Timing & Cadence'],['audit','Website Audit'],['teardown','Page-by-Page Teardown'],['social','Social Media Audit'],['suggested','Suggested New Websites'],['partners','Unlikely Partners'],['revenue','Unlikely Revenue'],['videos','Video + Brand Films'],['dealdesk','Live Deal Desk (demo)'],['roadmap','90-Day Roadmap']];
+const CATS = [['summary','Executive Summary'],['swot','SWOT Analysis'],['reputation','Reputation & Authority'],['empire','The Empire & Sublease.com'],['competitors','Competitors'],['advertising','Where to Advertise'],['timing','Timing & Cadence'],['audit','Website Audit'],['teardown','Page-by-Page Teardown'],['social','Social Media Audit'],['suggested','Suggested New Websites'],['partners','Unlikely Partners'],['revenue','Unlikely Revenue'],['videos','Video + Brand Films'],['dealdesk','Live Deal Desk (demo)'],['roadmap','90-Day Roadmap'],['sources','Sources & Methodology']];
/* ---- Live Deal Desk (real CRCP data) --------------------------------------- */
const DESK_DEALS = (CRCP.deals || []).filter(d => d.score != null).slice(0, 24);
@@ -318,7 +318,41 @@ function swotAgent(input){
}
const swotGrid = swotAgent(SWOT_INPUT);
-const navLinks = CATS.map(c=>`<a href="#${c[0]}">${c[1]}</a>`).join('');
+/* ---- Sources & methodology (data provenance) ------------------------------
+ * Honest map of where every part of the brief comes from and how it's made, so
+ * the client can weigh each claim by its provenance. Tiers are colour-coded and
+ * estimates are flagged AS estimates — never dressed up as measured analytics.
+ * Add a row when a new data-backed section ships; keep the tier honest. */
+const SRC_TIER = {
+ verified: ['Client-verified', 'v'],
+ observed: ['Observed live', 'o'],
+ real: ['Real dataset', 'r'],
+ derived: ['Computed', 'd'],
+ analyst: ['Analyst view', 'a'],
+ estimate: ['Illustrative', 'e'],
+ illustrative: ['Decorative', 'a'],
+ generated: ['Generated', 'd'],
+};
+const SOURCES = [
+ ['Portfolio, owner, team & contact', "The client's own materials — the package supplied by Daniel Ginzburg (CFO, Dandeana Corp), Jul 2026", 'Transcribed into <code>data/client.json</code> and rendered verbatim', 'verified'],
+ ['Sublease.com market size & revenue', '"Sublease.com Business Plan & Market Strategy," April 2026 (confidential, client-supplied)', 'Figures ($650B market, ~$5.9M Year-2 mix) lifted straight from the plan and charted', 'verified'],
+ ['Website & page-by-page audit', 'Live rentv.com — every page loaded and screenshotted directly', 'Adversarial teardown; a grade + fixes authored per page. The dead analytics tag (UA-148799896-1) was read from the live page source', 'observed'],
+ ['Live Deal Desk — listings & map', 'Real LA-area CRE listings sampled from CRCP into <code>data/deals-sample.json</code>', 'Deal scores computed by a transparent weighted model (<code>deal-score.js</code>): rent yield, cap rate, DSCR, financing signals', 'real'],
+ ['Deal Desk — demographics chart', 'U.S. Census median gross rent & income, LA-area cities', 'Carried in the <code>demographics[]</code> block of deals-sample.json and charted live', 'real'],
+ ['SWOT snapshot', 'Derived from the reputation, revenue & competitive reads elsewhere in this brief', 'A small agent (<code>swotAgent()</code>) runs four lenses over one profile so the quadrant stays consistent with the rest', 'derived'],
+ ['Competitors · channels · timing · partners · revenue', 'Analyst strategy, benchmarked to the Bisnow / CoStar / Real Deal / Commercial Observer playbooks', 'Authored as consulting recommendations — industry-standard models, not scraped metrics', 'analyst'],
+ ['Charts (reach, ROI, readership, growth)', 'Illustrative CRE-shaped figures around one real anchor — the observed LinkedIn count (818)', 'Estimates for shape & direction only. The live site ran no analytics for ~3 years, so measured traffic does not exist to chart', 'estimate'],
+ ['Hero & section imagery', 'Unsplash editorial stock (desaturated skyline / CRE photography)', 'Hotlinked, decorative only — carries no data meaning', 'illustrative'],
+ ['Brand films', 'Generated presenter videos (HeyGen) over CRE footage', 'Rendered to <code>/portal/videos/heygen-*.mp4</code>; appear on the page as they finish', 'generated'],
+];
+const srcRows = SOURCES.map(s => {
+ const t = SRC_TIER[s[3]] || ['—', 'a'];
+ return `<tr><td><b>${s[0]}</b></td><td>${s[1]}</td><td>${s[2]}</td><td class="srccell"><span class="srcb ${t[1]}">${t[0]}</span></td></tr>`;
+}).join('');
+const srcLegend = [...new Set(SOURCES.map(s => s[3]))]
+ .map(k => { const t = SRC_TIER[k]; return `<span class="srcb ${t[1]}">${t[0]}</span>`; }).join('');
+
+const navLinks = CATS.map(c=>`<a href="#${c[0]}">${c[1].replace(/&/g,'&')}</a>`).join('');
const heroSlides = HERO_IMGS.map((u,i)=>`<div class="slide${i===0?' on':''}" style="background-image:url('${u}')"></div>`).join('');
const app = `<!doctype html><html lang="en"><head>
@@ -390,6 +424,20 @@ td.mo{font-family:'Cormorant Garamond',serif;color:var(--gold);font-size:18px;wi
.swotq.pos{border-top:2px solid #9fd6b0}.swotq.neg{border-top:2px solid #e8a0a0}
.swotq.pos h3{color:#9fd6b0}.swotq.neg h3{color:#e8a0a0}
.swotq ul{margin:0;padding-left:18px}.swotq li{color:var(--dim);font-size:15px;line-height:1.55;margin:6px 0}
+.srclegend{display:flex;flex-wrap:wrap;gap:10px;margin:26px 0 4px}
+.srcb{display:inline-block;font-size:10px;letter-spacing:.14em;text-transform:uppercase;padding:5px 11px;border-radius:3px;border:1px solid var(--line);white-space:nowrap}
+.srcb.v{color:#9fd6b0;border-color:rgba(159,214,176,.4)}
+.srcb.o{color:#78aaff;border-color:rgba(120,170,255,.4)}
+.srcb.r{color:var(--gold)}
+.srcb.d{color:#b78d3f}
+.srcb.a{color:var(--dim)}
+.srcb.e{color:#e8a0a0;border-color:rgba(232,160,160,.4)}
+td.srccell{white-space:nowrap;vertical-align:middle}
+.srcnote{margin-top:34px;display:flex;gap:22px;padding:28px 30px;border:1px solid var(--line);background:var(--panel)}
+.srcnote .i{font-size:26px;color:var(--gold);line-height:1}
+.srcnote h4{font-family:'Cormorant Garamond',serif;font-size:21px;color:var(--gold);margin-bottom:8px}
+.srcnote p{color:var(--dim);font-size:15px;line-height:1.6}
+.srcnote code,.accbody td code{font-family:ui-monospace,Menlo,monospace;font-size:12.5px;color:var(--ink);background:rgba(200,161,90,.12);padding:1px 6px;border-radius:3px}
.flagbox{display:flex;gap:22px;margin-top:34px;padding:30px 32px;border:1px solid var(--gold);background:rgba(200,161,90,.07)}
.flagbox .i{font-size:30px;color:var(--gold)}.flagbox h3{font-family:'Cormorant Garamond',serif;font-size:24px;color:var(--gold);margin-bottom:10px}.flagbox p{color:var(--ink);opacity:.92;font-size:16px;line-height:1.6}
.vgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:20px;margin-top:20px}
@@ -662,6 +710,13 @@ footer{padding:56px clamp(24px,7vw,120px);border-top:1px solid var(--line);color
</ul>
</div></section>
+<section id="sources"><div class="eyebrow">15 · Sources & Methodology</div><h2 class="disp">Where every number comes from — and how.</h2><div class="accbody">
+ <p class="lead2">A brief is only as trustworthy as its sourcing, so here is the whole provenance map. Each row states <b>where the data came from</b> and <b>how it was produced</b> — and anything that is an estimate is labelled an estimate, never dressed up as measured analytics.</p>
+ <div class="srclegend">${srcLegend}</div>
+ <table><thead><tr><th>Section of the brief</th><th>Where it comes from</th><th>How it’s produced</th><th>Provenance</th></tr></thead><tbody>${srcRows}</tbody></table>
+ <div class="srcnote"><div class="i">⚙</div><div><h4>How this document is built</h4><p>This portal is generated, not hand-typed. Client-supplied facts live in <code>data/*.json</code>; a build step (<code>build.mjs</code>) renders them into the page and redraws the charts & map on every deploy — so the brief updates when the underlying data does. Nothing is invented at page-load: the charts read fixed datasets, the Deal Desk reads a real listing sample, and projections appear only where the row above is labelled <b>Illustrative</b>.</p></div></div>
+</div></section>
+
<footer><span>RENTV.com · Growth Strategy Brief</span><span>Prepared for the ${new Date().getFullYear()} consulting review</span><span>Confidential — for discussion</span></footer>
<script>
diff --git a/public/portal.html b/public/portal.html
index 5ec5e41..b59b82c 100644
--- a/public/portal.html
+++ b/public/portal.html
@@ -67,6 +67,20 @@ td.mo{font-family:'Cormorant Garamond',serif;color:var(--gold);font-size:18px;wi
.swotq.pos{border-top:2px solid #9fd6b0}.swotq.neg{border-top:2px solid #e8a0a0}
.swotq.pos h3{color:#9fd6b0}.swotq.neg h3{color:#e8a0a0}
.swotq ul{margin:0;padding-left:18px}.swotq li{color:var(--dim);font-size:15px;line-height:1.55;margin:6px 0}
+.srclegend{display:flex;flex-wrap:wrap;gap:10px;margin:26px 0 4px}
+.srcb{display:inline-block;font-size:10px;letter-spacing:.14em;text-transform:uppercase;padding:5px 11px;border-radius:3px;border:1px solid var(--line);white-space:nowrap}
+.srcb.v{color:#9fd6b0;border-color:rgba(159,214,176,.4)}
+.srcb.o{color:#78aaff;border-color:rgba(120,170,255,.4)}
+.srcb.r{color:var(--gold)}
+.srcb.d{color:#b78d3f}
+.srcb.a{color:var(--dim)}
+.srcb.e{color:#e8a0a0;border-color:rgba(232,160,160,.4)}
+td.srccell{white-space:nowrap;vertical-align:middle}
+.srcnote{margin-top:34px;display:flex;gap:22px;padding:28px 30px;border:1px solid var(--line);background:var(--panel)}
+.srcnote .i{font-size:26px;color:var(--gold);line-height:1}
+.srcnote h4{font-family:'Cormorant Garamond',serif;font-size:21px;color:var(--gold);margin-bottom:8px}
+.srcnote p{color:var(--dim);font-size:15px;line-height:1.6}
+.srcnote code,.accbody td code{font-family:ui-monospace,Menlo,monospace;font-size:12.5px;color:var(--ink);background:rgba(200,161,90,.12);padding:1px 6px;border-radius:3px}
.flagbox{display:flex;gap:22px;margin-top:34px;padding:30px 32px;border:1px solid var(--gold);background:rgba(200,161,90,.07)}
.flagbox .i{font-size:30px;color:var(--gold)}.flagbox h3{font-family:'Cormorant Garamond',serif;font-size:24px;color:var(--gold);margin-bottom:10px}.flagbox p{color:var(--ink);opacity:.92;font-size:16px;line-height:1.6}
.vgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:20px;margin-top:20px}
@@ -130,7 +144,7 @@ footer{padding:56px clamp(24px,7vw,120px);border-top:1px solid var(--line);color
<div class="scrim" onclick="document.body.classList.remove('nav')"></div>
<nav class="menu" id="portalmenu" onclick="if(event.target.closest('a'))document.body.classList.remove('nav')">
<a class="mbrand" href="#summary">REN<span>TV</span>.com<small>Growth Strategy · 2026</small></a>
- <div class="mh">Contents</div><a href="#summary">Executive Summary</a><a href="#swot">SWOT Analysis</a><a href="#reputation">Reputation & Authority</a><a href="#empire">The Empire & Sublease.com</a><a href="#competitors">Competitors</a><a href="#advertising">Where to Advertise</a><a href="#timing">Timing & Cadence</a><a href="#audit">Website Audit</a><a href="#teardown">Page-by-Page Teardown</a><a href="#social">Social Media Audit</a><a href="#suggested">Suggested New Websites</a><a href="#partners">Unlikely Partners</a><a href="#revenue">Unlikely Revenue</a><a href="#videos">Video + Brand Films</a><a href="#dealdesk">Live Deal Desk (demo)</a><a href="#roadmap">90-Day Roadmap</a>
+ <div class="mh">Contents</div><a href="#summary">Executive Summary</a><a href="#swot">SWOT Analysis</a><a href="#reputation">Reputation & Authority</a><a href="#empire">The Empire & Sublease.com</a><a href="#competitors">Competitors</a><a href="#advertising">Where to Advertise</a><a href="#timing">Timing & Cadence</a><a href="#audit">Website Audit</a><a href="#teardown">Page-by-Page Teardown</a><a href="#social">Social Media Audit</a><a href="#suggested">Suggested New Websites</a><a href="#partners">Unlikely Partners</a><a href="#revenue">Unlikely Revenue</a><a href="#videos">Video + Brand Films</a><a href="#dealdesk">Live Deal Desk (demo)</a><a href="#roadmap">90-Day Roadmap</a><a href="#sources">Sources & Methodology</a>
<div class="minfo"><div class="mh">RENTV.com, Inc.</div><p>5757 W. Century Blvd., #700, Los Angeles, CA 90045</p><p>Steve Bloom — Owner / Producer · (310) 213-6409</p><p>Arnie Garfinkel — CRE Talk co-host · (818) 532-7660</p><p>Allen Wolfsheimer — News/Resources · (310) 836-8238</p><p>Daniel Ginzburg — CFO, Dandeana Corp · (424) 251-8405</p><p><span>rentv.com</span> · <a href="https://www.rentvreview.com" target="_blank" rel="noopener">The REview ↗</a> · <a href="https://www.linkedin.com/company/rentv.com-inc" target="_blank" rel="noopener">LinkedIn ↗</a></p></div>
</nav>
@@ -494,6 +508,13 @@ footer{padding:56px clamp(24px,7vw,120px);border-top:1px solid var(--line);color
</ul>
</div></section>
+<section id="sources"><div class="eyebrow">15 · Sources & Methodology</div><h2 class="disp">Where every number comes from — and how.</h2><div class="accbody">
+ <p class="lead2">A brief is only as trustworthy as its sourcing, so here is the whole provenance map. Each row states <b>where the data came from</b> and <b>how it was produced</b> — and anything that is an estimate is labelled an estimate, never dressed up as measured analytics.</p>
+ <div class="srclegend"><span class="srcb v">Client-verified</span><span class="srcb o">Observed live</span><span class="srcb r">Real dataset</span><span class="srcb d">Computed</span><span class="srcb a">Analyst view</span><span class="srcb e">Illustrative</span><span class="srcb a">Decorative</span><span class="srcb d">Generated</span></div>
+ <table><thead><tr><th>Section of the brief</th><th>Where it comes from</th><th>How it’s produced</th><th>Provenance</th></tr></thead><tbody><tr><td><b>Portfolio, owner, team & contact</b></td><td>The client's own materials — the package supplied by Daniel Ginzburg (CFO, Dandeana Corp), Jul 2026</td><td>Transcribed into <code>data/client.json</code> and rendered verbatim</td><td class="srccell"><span class="srcb v">Client-verified</span></td></tr><tr><td><b>Sublease.com market size & revenue</b></td><td>"Sublease.com Business Plan & Market Strategy," April 2026 (confidential, client-supplied)</td><td>Figures ($650B market, ~$5.9M Year-2 mix) lifted straight from the plan and charted</td><td class="srccell"><span class="srcb v">Client-verified</span></td></tr><tr><td><b>Website & page-by-page audit</b></td><td>Live rentv.com — every page loaded and screenshotted directly</td><td>Adversarial teardown; a grade + fixes authored per page. The dead analytics tag (UA-148799896-1) was read from the live page source</td><td class="srccell"><span class="srcb o">Observed live</span></td></tr><tr><td><b>Live Deal Desk — listings & map</b></td><td>Real LA-area CRE listings sampled from CRCP into <code>data/deals-sample.json</code></td><td>Deal scores computed by a transparent weighted model (<code>deal-score.js</code>): rent yield, cap rate, DSCR, financing signals</td><td class="srccell"><span class="srcb r">Real dataset</span></td></tr><tr><td><b>Deal Desk — demographics chart</b></td><td>U.S. Census median gross rent & income, LA-area cities</td><td>Carried in the <code>demographics[]</code> block of deals-sample.json and charted live</td><td class="srccell"><span class="srcb r">Real dataset</span></td></tr><tr><td><b>SWOT snapshot</b></td><td>Derived from the reputation, revenue & competitive reads elsewhere in this brief</td><td>A small agent (<code>swotAgent()</code>) runs four lenses over one profile so the quadrant stays consistent with the rest</td><td class="srccell"><span class="srcb d">Computed</span></td></tr><tr><td><b>Competitors · channels · timing · partners · revenue</b></td><td>Analyst strategy, benchmarked to the Bisnow / CoStar / Real Deal / Commercial Observer playbooks</td><td>Authored as consulting recommendations — industry-standard models, not scraped metrics</td><td class="srccell"><span class="srcb a">Analyst view</span></td></tr><tr><td><b>Charts (reach, ROI, readership, growth)</b></td><td>Illustrative CRE-shaped figures around one real anchor — the observed LinkedIn count (818)</td><td>Estimates for shape & direction only. The live site ran no analytics for ~3 years, so measured traffic does not exist to chart</td><td class="srccell"><span class="srcb e">Illustrative</span></td></tr><tr><td><b>Hero & section imagery</b></td><td>Unsplash editorial stock (desaturated skyline / CRE photography)</td><td>Hotlinked, decorative only — carries no data meaning</td><td class="srccell"><span class="srcb a">Decorative</span></td></tr><tr><td><b>Brand films</b></td><td>Generated presenter videos (HeyGen) over CRE footage</td><td>Rendered to <code>/portal/videos/heygen-*.mp4</code>; appear on the page as they finish</td><td class="srccell"><span class="srcb d">Generated</span></td></tr></tbody></table>
+ <div class="srcnote"><div class="i">⚙</div><div><h4>How this document is built</h4><p>This portal is generated, not hand-typed. Client-supplied facts live in <code>data/*.json</code>; a build step (<code>build.mjs</code>) renders them into the page and redraws the charts & map on every deploy — so the brief updates when the underlying data does. Nothing is invented at page-load: the charts read fixed datasets, the Deal Desk reads a real listing sample, and projections appear only where the row above is labelled <b>Illustrative</b>.</p></div></div>
+</div></section>
+
<footer><span>RENTV.com · Growth Strategy Brief</span><span>Prepared for the 2026 consulting review</span><span>Confidential — for discussion</span></footer>
<script>
← 713c574 auth: add Scott login
·
back to Consulting Rentv Com
·
portal: add News + Conference Rivals deep-dive (LA -> CA -> 0cc02df →