Frontend audit — 2026-05-25
Summary
The frontend is largely coherent with the new vault structure. Parser, route generation, and content-collection IDs all work correctly for the current vault contents (PLTR full bundle + FCN first-read with shelve-with-trigger decision). Three issues to address:
- P1 —
Daily-Scans/folder is unmapped. The user spec says "AM scan output →Daily-Scans/YYYY-MM-DD-AM.md," but no collection has../AlphaSteve/Daily-Scansas a base. The dailies index page reads from theresearchcollection (13-Research/2026-MM/YYYY-MM-DD-{AM,PM}.md) instead. If the scheduled-task spec is now authoritative, dailies will silently stop appearing as soon as the scan writer moves toDaily-Scans/. Today'sDaily-Scans/2026-05-25.md(no AM/PM suffix) is invisible to the site. - P2 — Ticker-prefixed wiki-links unresolved.
wiki-links.ts:37matches[PLTR](/theses/PLTR),[PLTR-calibration](/theses/PLTR),[PLTR-dashboard](/theses/PLTR),[PLTR-model](/theses/PLTR)but NOT[PLTR-thesis](/theses/PLTR),[PLTR-shadow-matrix](/theses/PLTR), or[PLTR-consensus-gap](/theses/PLTR). The new filenames inside the dated bundle folder all carry these prefixes, so cross-links from PLTR.md and elsewhere fall through to/brain/pltr-thesis(404). - P2 — First-read wiki-links unresolved.
[first-read-2026-05-25](/brain/first-read-2026-05-25)falls through to/brain/first-read-2026-05-25rather than/theses/<TICKER>/first-read/2026-05-25. There's no way to know the ticker from the filename alone, so this needs either a[FCN/first-read-2026-05-25](/theses/FCN/first-read/2026-05-25)convention or an index lookup.
Everything else (parser, page logic, schema, build cleanliness) checks out.
Findings by category
Content config — src/content/config.ts
- All nine collections declared with
generateId: preserveId(lines 25–167). Verified that PLTR'sMAY2026folder, the ticker landingPLTR/PLTR.md, and the AM/PM filenames2026-05-25-AMare all preserved with original casing. - Theses schema (lines 47–96) declares thesis-bundle fields and uses
.passthrough(), so first-read fields (decision,decision_rationale,shelve_trigger,shelve_horizon,first_read_date) flow through untyped but accessible. Fine for read-only rendering. - Missing collection:
daily-scans. Vault now containsAlphaSteve/Daily-Scans/(e.g.,2026-05-25.md). No glob covers it. See P1. 12-Portfolio/Daily-Notes/2026-05-25.mdexists butportfolioCollectionusespattern: '*.md'(line 27), so subfolders are excluded — likely intentional (only Portfolio/Performance/Transactions are exposed). Worth confirming.researchglob is recursive (line 100). It picks up13-Research/2026-05/*-AM.md,13-Research/2026-05/*-PM.md,_house-view.md,_long-form-template.md, plusThemes/(currently empty) andREADME.md. The dailies and papers filters tolerate this —_house-view.mdandREADME.mdwill appear as research entries but are not surfaced by any page (no harm).
Parser — src/lib/thesis-bundle.ts
parseEntry(lines 21–81) handles all four required cases:- New layout
PLTR/PLTR - MAY2026/PLTR-thesis— splits cleanly, fileName='PLTR-thesis' whichbuildCoveragethen strips viastripTickerPrefix(line 177) to 'thesis'. Correct. - First-read
FCN/first-read-2026-05-25— handled inbuildCoverageat lines 132–148 (beforeparseEntryis even called). Captures date, decision, decisionRationale. Correct. - Landing
PLTR/PLTR— short-circuited inbuildCoveragelines 126–130 (idParts[0] === idParts[1]). Stored ontickerLandings. Correct (though nothing consumeslandingyet — see P3). - Revisions
PLTR/PLTR - MAY2026/revisions/2026-05-23-original-EPV-only— fileParts has 2 elements with first='revisions', captured as revisionName. Correct. - Legacy
<TICKER> - <MMMYYYY>/file— branch at lines 39–45 still supported,isLegacy=true. Correct.
- New layout
buildCoverage(lines 118–228) correctly emits coverage for both "has thesis" tickers (lines 202–213) and "first-read only" tickers (lines 216–225). Both branches attachtickerLandings.get(ticker).coverageState(lines 231–241) returns correct values for:covered(has thesis, no first-read),mixed(both),shelved(first-read only, latest decision = shelve-with-trigger),pipeline(anything else with first-reads). Matches spec.- Minor — landing file unused.
Coverage.landingis populated but no page renders it. PLTR.md contains a useful summary block; the ticker page currently shows the latest thesis bundle directly. Not a bug, just unrealized capability (P3).
Pages
index.astro(dashboard) — counters work:latestByTicker.length= covered count (1 for PLTR),pipelineCountfor continue/pass first-reads with no thesis,shelfCountfor shelve-with-trigger first-reads. Watchlist counter usesthesesByVerdict['pass-with-trigger'](PLTR = 1). Dailies derive from research collection (4 entries today). Papers filterlong-form/prefix (currently 0). All sound.theses/index.astro— splits into Published (has thesis) + Pipeline (first-read only). Today renders PLTR in Published, FCN in Pipeline withdecision='shelve-with-trigger'→ orange "shelve with trigger" badge. Correct.theses/[ticker].astro— three branches: hasThesis (PLTR), firstRead-only (FCN), neither. All present. Variant URL generation fortickerSlug.toLowerCase()and legacy slugified folder name (lines 21–30) is correct.theses/[ticker]/[instance].astro— only generates paths whereinst.thesis !== null(line 17), preventing 404s for first-read-only tickers. Correct.theses/[ticker]/first-read/[date].astro— iteratescov.firstReads, renders body and (for shelve-with-trigger) extractsshelve_trigger/shelve_horizonfrom frontmatter. Will render correctly for FCN today. Correct.theses/[ticker]/[instance]/revisions/[date].astro— iteratesinst.revisions, usesfileName(stripped of.md) asparams.date. Matches theThesisInstance.astrorevision link (line 170 of component). Correct.shelf.astro— filters tocov.firstReads[0].decision === 'shelve-with-trigger'AND!hasThesis. FCN renders. Correct.watchlist.astro— filters theses tod.verdict === 'pass-with-trigger'. PLTR renders. Correct.dailies/index.astroand[slug].astro— both filterresearchcollection by/\d{4}-\d{2}-\d{2}-(AM|PM)/. Works for13-Research/2026-05/2026-05-25-AM.md. Will silently break if writer moves toDaily-Scans/(P1).papers/index.astroand[slug].astro— filterresearchbylong-form/prefix. Empty today but no error.brain/index.astroand[slug].astro— list soul, frameworks, risk, optimization. All four collections currently populated. Slug uses.toLowerCase()(line 14 of [slug].astro) and matches the link generation in the index. Correct. Note:Optimization/Daily/andOptimization/Closed/subfolders get picked up by the recursive glob, so their IDs areDaily/2026-05-24and would render under/brain/daily/2026-05-24— fine but unsignposted.portfolio.astro— reads three flat files by id (Portfolio,Performance,Transactions). All present, casing preserved bypreserveId. Correct.calibration/[slug].astro— only individual calibration entries are routable (e.g.,/calibration/kit-debrief-001-PLTR). No index page. Used by wiki-links (kit-debrief-001-PLTR→/calibration/...). Note thatactive="brain"is set, so nav highlights Reference. Fine but inconsistent with not surfacing calibration from/brain(P3).
Layout — src/layouts/Layout.astro
- Nav (lines 12–21) includes all eight expected sections: Dashboard, Portfolio, Watchlist, Shelf, Theses, Dailies, Papers, Reference.
activeprop type (line 7) accepts exactly those eight keys. Every page passes a valid key. No TS error.
Wiki-link resolution — src/lib/wiki-links.ts
[PLTR](/theses/PLTR)→/theses/PLTRvia the/^[A-Z]{1,5}(-calibration|-dashboard|-model)?$/rule. Correct.[PLTR-calibration](/theses/PLTR),[PLTR-dashboard](/theses/PLTR),[PLTR-model](/theses/PLTR)→/theses/PLTR. Correct.[PLTR-thesis](/theses/PLTR),[PLTR-shadow-matrix](/theses/PLTR),[PLTR-consensus-gap](/theses/PLTR)— NOT handled. Falls to/brain/<lowercased>(404). See P2.[YYYY-MM-DD-AM](/brain/yyyy-mm-dd-am)→/dailies/YYYY-MM-DD-AM(line 43). Correct.[first-read-YYYY-MM-DD](/brain/first-read-yyyy-mm-dd)— falls to catchall/brain/first-read-YYYY-MM-DD(404). See P3 — also impossible to resolve without ticker context.[Watchlist](/watchlist),[Portfolio](/portfolio), soul files, frameworks, calibration entries — all mapped. Correct.
Build risks (static-build dry-read)
- No TypeScript errors observed in the page files.
getStaticPathsreturns objects with the right shape everywhere checked. - No null-access risk in the rendered cards: every
.thesis?.data/.firstRead?.entry?.dataaccess is optional-chained. - The
markedparse runs server-side at build time;renderMarkdownis wrapped in try/catch on every page that uses it. verdict_date/last_refresh/ etc. are coerced viadateOrStringthen re-formatted byformatDate. PLTR's2026-05-24round-trips cleanly.- Risk: if a future thesis omits
decision_rationaleand the first-read filename pattern shifts,fr.entry?.data?.decision_rationaleis already optional-chained — no crash.
Render cases (today's vault)
- PLTR (full thesis exists) —
/thesesshows it under Published;/theses/PLTRrenders the latest instance viaThesisInstance.astrowith all four tabs (thesis, matrix, consensus, calibration) plus revisions (2)./watchlisttable includes PLTR (verdict pass-with-trigger). Counters: theses=1, watchlist=1, shelf=0, pipeline=0. - FCN (first-read with decision=shelve-with-trigger) —
/thesesshows it under Pipeline./theses/FCNrenders first-read landing with the "Shelve" badge,shelve_triggerandshelve_horizoncards, full markdown body./shelfincludes FCN row with $115 trigger. Counters: shelf=1. - Hypothetical: new ticker with decision=continue (no thesis yet) — appears in
/thesesPipeline with green "Continue" badge./theses/<TICKER>shows first-read landing with "Continue" badge and a note "No full thesis yet." Not on watchlist/shelf. Counter: pipeline=+1. - Hypothetical: new ticker with decision=pass — same as case 3 with muted "Pass" badge. Counter: pipeline=+1.
- Hypothetical: new ticker with decision=shelve-with-trigger — identical to FCN behavior. Counter: shelf=+1.
- Hypothetical: ticker with first-read + later full thesis (mixed) — Published card displays first-read count in the metadata strip (line 147 of theses/index.astro). The
/theses/<TICKER>page shows the thesis (hasThesis branch wins); first-reads are reachable via direct URL/theses/<TICKER>/first-read/<date>but no in-page link from the thesis surfaces them. Minor UX gap (P3).
Recommended fixes (priority-ordered)
P1 — pick one and commit:
- If
Daily-Scans/is the new source of truth, add adailyScansCollectionrooted at../AlphaSteve/Daily-Scanswithpattern: '*.md'andgenerateId: preserveId; updatedailies/index.astroanddailies/[slug].astroto read from it; tighten the filename pattern to/^\d{4}-\d{2}-\d{2}-(AM|PM)$/so the in-flight2026-05-25.md(no suffix) is excluded until renamed. - Or keep dailies in
13-Research/YYYY-MM/and update the scheduled-task spec / writer accordingly.
P2 — extend wiki-link map (src/lib/wiki-links.ts:37):
- Add
-thesis,-shadow-matrix,-consensus-gapto the suffix capture group so[PLTR-thesis](/theses/PLTR)resolves to/theses/PLTR. Change regex to/^[A-Z]{1,5}(-calibration|-dashboard|-model|-thesis|-shadow-matrix|-consensus-gap)?$/.
P2 — first-read wiki-link convention:
- Decide on a stable form. Two options: (a) require
[FCN/first-read-2026-05-25](/theses/FCN/first-read/2026-05-25)and add a path-aware resolver branch; (b) build a build-time index offirst-read-*→ ticker and resolve by lookup. Option (a) is cheaper.
P3 — surface ticker landing (PLTR.md):
Coverage.landingis parsed but never rendered. Consider showing the landing's summary table above the thesis tabs on/theses/<TICKER>, or use it when no thesis exists yet but the landing was hand-created.
P3 — mixed-state cross-links:
- On a ticker page where a full thesis exists AND there are first-reads, surface the first-reads (e.g., a "Pipeline history" section above Coverage history). Currently the only signal is the small first-read count chip on
/thesesindex.
P3 — calibration discoverability:
/calibration/[slug]exists but nothing links to it from/brain. Either add a Calibration section to the brain index, or remove the route if calibration is meant to be private.
P3 — Optimization/Daily entries:
- Recursive glob picks up
Optimization/Daily/*.md; they become routes/brain/daily/2026-05-24not listed anywhere. Either restrict to*.md(flat) or render the subfolder structure in the brain index.