ui: staffing co-pilot UX fixes — new-tab reference nav + discoverable collapsibles

Reconciles month-old working-tree UX work (served per-request, live on the demo since
2026-05-30) into git. Implements UX_FIX_PLAN.md's 5 user complaints: reference pages
(Profiler/Architecture/Spec/Onboard/Alerts/Workspaces) open in new tabs; contract-card
collapsible shows a persistent chevron + expand/collapse label in both states; proof.html
gains a substrate-signals chapter. Not authored this session — captured as-is (working
state verified: pages serve 200).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claw 2026-06-30 22:55:33 -05:00
parent 7dddb98f4b
commit 7365a4c23e
7 changed files with 230 additions and 85 deletions

94
mcp-server/UX_FIX_PLAN.md Normal file
View File

@ -0,0 +1,94 @@
# Staffing Co-Pilot UX Fix Plan (devop.live/lakehouse)
**Target file:** `/home/profit/lakehouse/mcp-server/search.html` (239KB, ~4100 lines) — THIS is the
main dashboard served at `/` (route at `index.ts:1258`; name "search.html" is historical).
Sibling pages: `console.html` (Walkthrough), `proof.html` (Architecture), `spec.html`, `onboard.html`,
`profiler.html`, `contractor.html`, `workspaces.html`, `alerts.html`.
**Serving:** Bun `mcp-server/index.ts` on `:3700`, nginx `/lakehouse/``127.0.0.1:3700`.
Restart after edits: HTML is read per-request (`Bun.file`), so **no restart needed for .html edits**
just reload the browser. (Restart only if editing index.ts: it's pid 1254, `bun run mcp-server/index.ts`.)
**Constraints:** neo-brutalist, compact, distinct colors, NO fake timers. Surgical edits only.
Dashboard fires real SQL + /intelligence/* — don't break data wiring. Repo is FROZEN Rust legacy;
J explicitly authorized work on this surface.
**Base path quirk:** nav uses `var P = location.pathname.indexOf('/lakehouse')>=0?'/lakehouse':''`.
Relative hrefs (`href="console"`) resolve fine under `/lakehouse/`.
## User's 5 complaints → fixes (line numbers in search.html)
### 1+2. New tabs for reference pages (HIGH)
- **Top nav lines 594-599**: add `target="_blank" rel="noopener"` to Profiler, Architecture(proof),
Spec, Onboard, Alerts, Workspaces. LEAVE 592-593 (Dashboard `href="."`, Walkthrough `href="console"`) same-tab.
- **Footer line 781**: `<a href="proof">Architecture</a>` → add `target="_blank" rel="noopener"`. Keep Console same-tab.
- **Dynamic footer lines 1024-1026**: proof link needs `target=_blank rel=noopener` + `.ft` class styling (currently unstyled).
### 3. Collapsible "preview" not discoverable (HIGH)
Primary = **contract card expandable panel** (markup ~2620-2820, CSS grid-template-rows ~160-220).
Chevron rotates 180° but hint text "click for full curve…" only shows collapsed; vanishes on expand.
Fix: chevron always visible+larger(16px); persistent "Expand details"/"Collapse" label in BOTH states;
cursor:pointer on card header; hover border-left/bg shift; optional localStorage per-card.
Secondary collapsibles: ⓪ legacy-bridge narrative (~820-900) → default COLLAPSED for returning users
(localStorage 'seen_intro'); ② Staffer's Console preview (~1400-1500) → make collapsible, "Open full console →".
### 4. Clickable elements don't look clickable (HIGH)
Add global CSS: `[onclick]{cursor:pointer}` + reusable `.clickable` class with :hover (bg lift #161b22#1c2333
+ border accent), :active (translateY(1px)), :focus-visible (outline).
Apply to: insight cards (~1180-1280), alert rows (~1700-1780), worker result rows (~990-1030 — add hover '' chevron
for drilldown discoverability per feedback_test_drilldowns), collapsible section headers (~820-830, ~1400-1410),
action chips/buttons (~740-760, standardize .btn/.chip).
### 5. Layout clutter / flat hierarchy (HIGH)
8 sections at equal weight: ⓪ Not-a-CRM narrative, ① Live Market, Forecast, ② Staffer Console,
Market Intelligence, ③ Worker Search, ④ System Activity, ⑤ Substrate Signals.
3-tier fix: PRIMARY always-visible (Live Market, Worker Search, Staffer Console);
SECONDARY collapsible-open (Forecast, Market Intelligence); TERTIARY collapse-by-default or relocate
(⓪ narrative → collapsible banner; ⑤ Substrate Signals → move to proof.html/Architecture; ④ System Activity demote).
Also: Live Market vs Market Intelligence may overlap — differentiate headers or merge w/ sub-tabs.
Long card walls → add "show top 5 / show all" truncation.
### Cross-page nav consistency (MEDIUM)
Each of 8 pages has hardcoded nav with differing link sets/order/labels and unreliable .active.
Canonical set + order, each page sets .active on its own entry, brand/logo → `href="."`.
Long-term: extract nav to shared JS snippet served by index.ts to stop drift.
## ✅ SHIPPED 2026-05-30 (live-verified via curl against :3700; HTML served per-request → no restart)
- **#1+#2 New tabs** — search.html: 6 nav reference links (Profiler/Architecture/Spec/Onboard/Alerts/Workspaces)
+ footer Architecture + dynamic-footer Architecture now `target="_blank" rel="noopener"` with ↗ glyph.
Dashboard + Walkthrough stay same-tab (primary flow). VERIFIED: 7 static new-tab links served; nav listing clean.
- **#4 Clickability** — global affordance CSS inserted after `.ft a:hover{...}` (NOT `.ft a{margin}` — that anchor
was a hallucination): `[onclick]{cursor:pointer}`, `[role=button]`, `.iworker` cursor+hover-lift+active,
`details>summary` cursor+hover, global `:focus-visible`. VERIFIED served (affordance_css=1, iworker_cursor=1, summary_hover=1).
- **#3 partial** — every `<details>` collapsible now has visible hover affordance (cursor+bg). Contract-card toggle NOT yet (below).
- **Nav consistency** — added Profiler link to onboard/workspaces/alerts (verified profiler=1 each);
fixed contractor.html back-link `href="/"``href="."` (real bug: `/` = LLM-Team UI on :5000, ejected users out of lakehouse; verified root-bug=0, dot-fixed=1);
fixed profiler.html empty `href=""`→relative `.`/`console` (was JS-only/fragile; verified empty-href=0).
> CORRECTION LOG: first edit pass (earlier this session) FAILED silently — old_strings were guessed
> (`.ft a{margin:0 4px}`, a fake footer string, `ui-copilot/dashboard.html` path). Re-done with grep/Read-verified
> exact strings. The real dashboard file is `search.html` (route index.ts:1258), NOT `dashboard.html` (orphan) or `ui/`.
## (status note) — rounds 2 & 3 are recorded in the SHIPPED sections below; this block is superseded.
- #3 contract-card collapse → DONE round 2 (persistent `.card-top-toggle`).
- #5 declutter (⑤ relocate, ④ demote, ③ disclosure, Market Intelligence clarify, dead CSS) → DONE round 3.
- Still open: nav shared-component refactor (deferred, needs restart) + optional contract truncation (skipped on purpose). See "DELIBERATELY NOT DONE".
## Recommended execution order
1. New-tab attrs (lines 594-599, 781, 1024-1026) — trivial, high impact.
2. Global `.clickable` CSS helper + apply to onclick elements.
3. Collapsible affordance (chevron+label persistent, cursor, hover) on contract cards + section headers.
4. Default-collapse ⓪ narrative for returning users (localStorage).
5. Hierarchy/declutter (tiering, relocate ⑤ to proof, truncation).
6. Nav consistency pass across sibling files.
## VERIFY before claiming done (J's rules: test drilldowns, no greenwashing)
- `curl -s localhost:3700/ | grep target=_blank` confirms new-tab attrs present.
- Load https://devop.live/lakehouse/ in browser: click a contract card (expand+collapse visible),
hover a worker row (cursor+chevron), click reference nav (opens new tab), reload (intro stays collapsed).
- Don't restart the service for HTML-only edits.
## Audit provenance
5-dimension parallel Explore audit, run wf_c897f421-db1, full JSON at
`/tmp/claude-0/-home-profit/c6ca0218-678c-4a30-833c-1063e40e7f69/tasks/wm9x4y52d.output`.
NOTE: line numbers are audit estimates — `grep` to confirm exact lines before each Edit.

View File

@ -74,6 +74,7 @@ input:focus{border-color:#388bfd}
<nav>
<a href=".">Dashboard</a>
<a href="console">Walkthrough</a>
<a href="profiler">Profiler</a>
<a href="proof">Architecture</a>
<a href="spec">Spec</a>
<a href="onboard">Onboard</a>

View File

@ -54,7 +54,7 @@ body{font-family:'Inter',-apple-system,system-ui,sans-serif;background:#090c10;c
</head><body>
<div class="bar">
<h1>Staffing Co-Pilot · Contractor Profile</h1>
<a href="/">← Dashboard</a>
<a href=".">← Dashboard</a>
</div>
<div class="content">
<div class="search-box">

View File

@ -91,6 +91,7 @@ table.preview tr:hover td{background:#0d1117}
<nav>
<a href=".">Dashboard</a>
<a href="console">Walkthrough</a>
<a href="profiler">Profiler</a>
<a href="proof">Architecture</a>
<a href="spec">Spec</a>
<a href="onboard" class="active">Onboard</a>

View File

@ -478,6 +478,15 @@ bun test auditor/schemas/distillation/ tests/distillation/
</div>
</div>
<div class="chapter">
<div class="num">Chapter 11</div>
<h2>Substrate signals — live architecture health</h2>
<div class="lede">Four live probes of the architecture itself, not the staffing workload: instant-search latency, index shape, playbook-memory depth, and pathway-matrix compounding. These answer "is the substrate healthy right now?" — moved here from the operator dashboard (2026-05-30) where they competed with the day's work.</div>
<div class="grid" id="arch-signals" style="grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px">
<div class="loading" style="grid-column:1/-1">Probing substrate…</div>
</div>
</div>
</div>
<div class="footer">Lakehouse · Architecture page regenerates tests on every load · <a href="console">walkthrough</a> · <a href=".">dashboard</a></div>
@ -501,8 +510,40 @@ window.addEventListener('load',function(){
loadLiveSections();
loadPathwayLive();
loadSignalLive();
loadArchSignals();
});
// ⑤ Substrate Signals — moved from the operator dashboard (search.html)
// 2026-05-30 so the dashboard stays focused on staffing work and the
// architecture-health probes live with the rest of the architecture page.
// Uses apiPost (the /intelligence/arch_signals endpoint accepts GET or POST).
function loadArchSignals(){
var el=document.getElementById('arch-signals');
if(!el) return;
apiPost('/intelligence/arch_signals',{}).then(function(s){
el.textContent='';
function tile(label, big, sub, accent){
var t=document.createElement('div');
t.style.cssText='background:#0d1117;border:1px solid #171d27;border-radius:10px;padding:14px 16px;border-left:3px solid '+(accent||'#58a6ff');
var l=document.createElement('div');l.style.cssText='font-size:10px;text-transform:uppercase;letter-spacing:1px;color:#545d68;margin-bottom:6px';l.textContent=label;
var b=document.createElement('div');b.style.cssText='font-size:20px;font-weight:600;color:#e6edf3;line-height:1.1';b.textContent=big;
var u=document.createElement('div');u.style.cssText='font-size:10px;color:#8b949e;margin-top:6px;line-height:1.4';u.textContent=sub;
t.appendChild(l);t.appendChild(b);t.appendChild(u);
return t;
}
var idx=s.index||{};
var pbm=s.playbook_memory||{};
var pwm=s.pathway_memory||{};
var latencyColor=s.instant_search_probe_ms<100?'#2ea043':s.instant_search_probe_ms<500?'#d29922':'#f85149';
el.appendChild(tile('Instant Search',(s.instant_search_probe_ms||'?')+'ms','Live /vectors/hybrid probe · 500K-row index · '+(idx.chunk_count||0).toLocaleString()+' chunks',latencyColor));
el.appendChild(tile('Index',(idx.dimensions||768)+'d · '+(idx.model||'?'),(idx.source||'?')+' → '+(idx.name||'?')+' · '+(idx.backend||'parquet'),'#58a6ff'));
el.appendChild(tile('Playbook Memory',(pbm.entries||0).toLocaleString()+' entries',pbm.entries>0?'Meta-index active · boosts candidates from past fills':'Empty · POST /vectors/playbook_memory/rebuild to populate',pbm.entries>0?'#2ea043':'#d29922'));
el.appendChild(tile('Pathway Matrix',(pwm.total_pathways||0)+' traces',pwm.retired+' retired · '+pwm.total_replays+' replays · ADR-021 compounding','#58a6ff'));
}).catch(function(e){
el.textContent='substrate signals unavailable: '+e.message;
});
}
// Pathway memory live counters in Chapter 4 — small inline spans.
function loadPathwayLive(){
fetch(A+'/api/vectors/pathway/stats').then(function(r){return r.json()}).then(function(p){

View File

@ -135,6 +135,26 @@ body{font-family:'Inter',-apple-system,system-ui,'Segoe UI',sans-serif;backgroun
.ft{text-align:center;padding:24px;color:#3d444d;font-size:11px;border-top:1px solid #171d27;margin-top:32px}
.ft a{color:#545d68;text-decoration:none;transition:color 0.15s}
.ft a:hover{color:#e6edf3}
/* ── UX pass 2026-05-30: clearer interactive affordances ── */
[onclick]{cursor:pointer}
[role="button"]{cursor:pointer}
.iworker{cursor:pointer}
.iworker:hover{background:#1c2333;transform:translateY(-1px);box-shadow:0 2px 8px rgba(0,0,0,.3),0 0 0 1px #30363d;transition:background .15s,transform .15s,box-shadow .15s}
.iworker:active{transform:translateY(0);box-shadow:none}
details>summary{cursor:pointer}
details>summary:hover{color:#e6edf3;background:rgba(58,90,127,.15);border-radius:6px}
a:focus-visible,button:focus-visible,summary:focus-visible,[onclick]:focus-visible{outline:2px solid #388bfd;outline-offset:2px;border-radius:4px}
/* ③ example-search disclosure (2026-05-30) — collapsed by default, CSS-only hover/focus */
.samples-disclosure{font-size:11px}
.samples-summary{display:inline-flex;align-items:center;gap:6px;cursor:pointer;color:#8b949e;list-style:none;padding:4px 0;user-select:none}
.samples-summary::-webkit-details-marker{display:none}
.samples-summary::before{content:'▸';display:inline-block;font-size:10px;transition:transform .15s}
.samples-disclosure[open] .samples-summary::before{transform:rotate(90deg)}
.samples-summary:hover{color:#e6edf3}
.samples-row{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.search-chip{font-size:11px;padding:5px 10px;background:#161b22;border:1px solid #30363d;border-radius:14px;color:#8b949e;cursor:pointer;transition:border-color .15s,color .15s,background .15s}
.search-chip:hover{border-color:#58a6ff;color:#e6edf3;background:#1c2333}
.search-chip:focus-visible{outline:2px solid #388bfd;outline-offset:2px}
.ld{color:#3d444d;text-align:center;padding:40px;font-size:13px}
/* Reused pulse keyframe — shared by status dots in the market-pulse
@ -336,6 +356,18 @@ body{font-family:'Inter',-apple-system,system-ui,'Segoe UI',sans-serif;backgroun
line-height: 1;
}
.contract-card.expanded .card-toggle .chevron { transform: rotate(180deg) }
/* Persistent top-of-card expand affordance (2026-05-30 UX) — always
visible, button-styled so users immediately see the card expands. */
.contract-card .card-top-toggle {
display: inline-flex; align-items: center; gap: 6px;
padding: 4px 10px; margin-bottom: 10px;
font-size: 11px; font-weight: 600; color: #8b949e;
background: #161b22; border: 1px solid #30363d; border-radius: 7px;
cursor: pointer; user-select: none;
transition: background .15s, border-color .15s, color .15s;
}
.contract-card .card-top-toggle:hover { background: #1c2333; border-color: #58a6ff; color: #e6edf3 }
.contract-card .card-top-toggle .chevron { display:inline-block; font-size:12px; line-height:1 }
@media (prefers-reduced-motion: reduce) {
.contract-card { transition: none }
.contract-card:hover { transform: none }
@ -591,12 +623,12 @@ body{font-family:'Inter',-apple-system,system-ui,'Segoe UI',sans-serif;backgroun
<nav>
<a href="." class="active">Dashboard</a>
<a href="console">Walkthrough</a>
<a href="profiler">Profiler</a>
<a href="proof">Architecture</a>
<a href="spec">Spec</a>
<a href="onboard">Onboard</a>
<a href="alerts">Alerts</a>
<a href="workspaces">Workspaces</a>
<a href="profiler" target="_blank" rel="noopener">Profiler</a>
<a href="proof" target="_blank" rel="noopener">Architecture</a>
<a href="spec" target="_blank" rel="noopener">Spec</a>
<a href="onboard" target="_blank" rel="noopener">Onboard</a>
<a href="alerts" target="_blank" rel="noopener">Alerts</a>
<a href="workspaces" target="_blank" rel="noopener">Workspaces</a>
</nav>
<div class="rt" id="status">Loading...</div>
</div>
@ -711,10 +743,15 @@ body{font-family:'Inter',-apple-system,system-ui,'Segoe UI',sans-serif;backgroun
<div class="section" id="market-section">
<div class="section-header">
<span class="section-title">Market Intelligence</span>
<span class="section-meta">Public permit data · Updated live</span>
<span class="section-title">Market Intelligence — Chicago permit map</span>
<span class="section-meta">Where the construction money is · live from data.cityofchicago.org</span>
</div>
<div id="market"></div>
<p style="color:#8b949e;font-size:11px;margin:0 0 10px;line-height:1.5;max-width:680px">
The geographic companion to ① Live Market: every active building permit plotted
by location, sized by construction value. ① tells you <em>when</em> the shifts are;
this tells you <em>where</em> the work is.
</p>
<div id="market"><div style="color:#8b949e;font-size:11px;padding:8px 0">Loading Chicago permit map…</div></div>
</div>
<!-- ═══ ③ Worker Search — natural-language lookup over the 500K bench ═══ -->
@ -747,12 +784,18 @@ body{font-family:'Inter',-apple-system,system-ui,'Segoe UI',sans-serif;backgroun
</div>
<!-- ═══ ④ System Activity — what the substrate has learned to do ═══ -->
<div class="section" id="learning-section">
<div class="section-header">
<!-- 2026-05-30: demoted to a collapsed-by-default <details> (tier 3). It's
capability/reference info, not the day's staffing work, so it no longer
competes for attention on every load. Mirrors the ⓪ legacy-bridge pattern:
ontoggle flips the ▸/▾ hint. loadLearning() still populates #learning. -->
<details class="section" id="learning-section"
ontoggle="var s=this.querySelector('.lr-toggle-hint');if(s)s.textContent=this.open?'▾ click to collapse':'▸ click to expand'">
<summary style="list-style:none;cursor:pointer;display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;outline:none">
<span class="section-title" style="color:#e6edf3;font-size:13px">④ System Activity — what the substrate has learned to do</span>
<span class="section-meta">Live capabilities · pulled from each subsystem on load</span>
</div>
<p style="color:#8b949e;font-size:11px;margin:0 0 12px;line-height:1.5;max-width:780px">
<span class="lr-toggle-hint" style="margin-left:auto;font-size:10px;color:#545d68">▸ click to expand</span>
</summary>
<p style="color:#8b949e;font-size:11px;margin:10px 0 12px;line-height:1.5;max-width:780px">
Each tile is a capability the system has acquired and the live metric proving
it's running. Operational learning (fills, playbooks, hot-swaps) compounds
inside each capability; what changes here is the <em>set of things the
@ -760,25 +803,14 @@ body{font-family:'Inter',-apple-system,system-ui,'Segoe UI',sans-serif;backgroun
capability replicates by config, not code.
</p>
<div id="learning"></div>
</div>
</details>
<!-- ═══ ⑤ Substrate signals — compact architecture-health strip (bottom) ═══ -->
<div class="section" id="arch-signals-section">
<div class="section-header">
<span class="section-title" style="color:#e6edf3;font-size:13px">⑤ Substrate Signals — architecture health</span>
<span class="section-meta">Live probes of the index, memory, and pathway layers</span>
</div>
<p style="color:#8b949e;font-size:11px;margin:0 0 10px;line-height:1.5;max-width:680px">
These tiles measure the architecture itself, not the staffing workload.
Instant-search latency, index shape, playbook-memory depth, pathway-matrix
compounding — four probes that answer "is the substrate healthy right now?"
</p>
<div id="arch-signals" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px">
<div style="color:#8b949e;font-size:11px;grid-column:1/-1">Probing substrate…</div>
</div>
</div>
<!-- ⑤ Substrate Signals (architecture-health probes) moved to the Architecture
page (proof.html, Chapter 11) on 2026-05-30 — they measure the substrate,
not the staffing workload, so they belong with the architecture story and
keep this operator dashboard focused on the day's work. Link in the footer. -->
<div class="ft" id="footer">Staffing Co-Pilot · Hybrid SQL + Vector Search · loading scale… · <a href="console">Console</a> · <a href="proof">Architecture</a></div>
<div class="ft" id="footer">Staffing Co-Pilot · Hybrid SQL + Vector Search · loading scale… · <a href="console">Console</a> · <a href="proof" target="_blank" rel="noopener">Architecture ↗</a></div>
</div>
<!-- ═══ Mobile section-jump dock — visible < 768px only via CSS ═══ -->
@ -792,7 +824,7 @@ body{font-family:'Inter',-apple-system,system-ui,'Segoe UI',sans-serif;backgroun
<a href="#live-contracts-section" title="Open contracts + candidates"><span class="dock-label">Jobs</span></a>
<a href="#worker-search-section" title="Search 500K workers"><span class="dock-label">Search</span></a>
<a href="#learning-section" title="What the substrate has learned"><span class="dock-label">Learn</span></a>
<a href="#arch-signals-section" title="Live architecture health"><span class="dock-label">Stack</span></a>
<a href="proof" title="Architecture &amp; live substrate signals" target="_blank" rel="noopener"><span class="dock-label">Arch</span></a>
</nav>
<script>
var P=location.pathname.indexOf('/lakehouse')>=0?'/lakehouse':'';
@ -826,7 +858,7 @@ function styleSkelStages(){
}
window.addEventListener('load',function(){
styleSkelStages(); startSkelStages();
loadSystemSummary();loadLegacyBridge();loadDay();loadStaffingForecast();loadLiveContracts();loadMarket();loadLearning();loadWorkerSearchSamples();loadArchSignals();loadStaffers();
loadSystemSummary();loadLegacyBridge();loadDay();loadStaffingForecast();loadLiveContracts();loadMarket();loadLearning();loadWorkerSearchSamples();loadStaffers();
});
// Per-staffer hot-swap dropdown — runs independently of the simulation
@ -989,6 +1021,15 @@ function loadWorkerSearchSamples(){
{tag:'Specialist', q:'maintenance tech comfortable with Allen-Bradley PLCs'},
{tag:'High-volume', q:'warehouse associates available next week near Indianapolis'}
];
// 2026-05-30: wrap the 6 example chips in a collapsed disclosure so they
// don't consume vertical space on every load. The chip keeps its tag+query
// two-span layout and scroll-into-view click; the disclosure just gates them.
el.textContent='';
var det=document.createElement('details');det.className='samples-disclosure';
var sum=document.createElement('summary');sum.className='samples-summary';
sum.textContent='Example searches';
det.appendChild(sum);
var row=document.createElement('div');row.className='samples-row';
samples.forEach(function(s){
var chip=document.createElement('button');
chip.type='button';
@ -1002,8 +1043,10 @@ function loadWorkerSearchSamples(){
var input=document.getElementById('sq');
if(input){input.value=s.q;doSearch();input.scrollIntoView({behavior:'smooth',block:'center'});}
};
el.appendChild(chip);
row.appendChild(chip);
});
det.appendChild(row);
el.appendChild(det);
}
function loadSystemSummary(){
@ -1023,7 +1066,7 @@ function loadSystemSummary(){
foot.appendChild(document.createTextNode('Staffing Co-Pilot · Hybrid SQL + Vector Search · '+totalRows+' rows across '+ds+' datasets · '+chunks+' vector chunks · '));
var a1=document.createElement('a');a1.href='console';a1.textContent='Console';foot.appendChild(a1);
foot.appendChild(document.createTextNode(' · '));
var a2=document.createElement('a');a2.href='proof';a2.textContent='Architecture';foot.appendChild(a2);
var a2=document.createElement('a');a2.href='proof';a2.target='_blank';a2.rel='noopener';a2.textContent='Architecture';foot.appendChild(a2);
}
// Also update the collapsible search box label if not yet populated
var sum=document.querySelector('.sa summary');
@ -1033,56 +1076,9 @@ function loadSystemSummary(){
}).catch(function(){/* non-fatal */});
}
// ─── Substrate signals: render the 4 architecture-health tiles ───
function loadArchSignals(){
var el=document.getElementById('arch-signals');
api('/intelligence/arch_signals',{}).then(function(s){
el.textContent='';
function tile(label, big, sub, accent){
var t=document.createElement('div');
t.style.cssText='background:#0d1117;border:1px solid #171d27;border-radius:10px;padding:14px 16px;border-left:3px solid '+(accent||'#58a6ff');
var l=document.createElement('div');l.style.cssText='font-size:10px;text-transform:uppercase;letter-spacing:1px;color:#545d68;margin-bottom:6px';l.textContent=label;
var b=document.createElement('div');b.style.cssText='font-size:20px;font-weight:600;color:#e6edf3;line-height:1.1';b.textContent=big;
var u=document.createElement('div');u.style.cssText='font-size:10px;color:#8b949e;margin-top:6px;line-height:1.4';u.textContent=sub;
t.appendChild(l);t.appendChild(b);t.appendChild(u);
return t;
}
var idx=s.index||{};
var pbm=s.playbook_memory||{};
var pwm=s.pathway_memory||{};
// Tile 1 — instant search (the "we cleverly indexed at ingest" claim)
var latencyColor=s.instant_search_probe_ms<100?'#2ea043':s.instant_search_probe_ms<500?'#d29922':'#f85149';
el.appendChild(tile(
'Instant Search',
(s.instant_search_probe_ms||'?')+'ms',
'Live /vectors/hybrid probe · 500K-row index · '+(idx.chunk_count||0).toLocaleString()+' chunks',
latencyColor
));
// Tile 2 — index shape (hot-swap claim)
el.appendChild(tile(
'Index',
(idx.dimensions||768)+'d · '+(idx.model||'?'),
(idx.source||'?')+' → '+(idx.name||'?')+' · '+(idx.backend||'parquet'),
'#58a6ff'
));
// Tile 3 — self-regulating memory
el.appendChild(tile(
'Playbook Memory',
(pbm.entries||0).toLocaleString()+' entries',
pbm.entries>0?'Meta-index active · boosts candidates from past fills':'Empty · POST /vectors/playbook_memory/rebuild to populate',
pbm.entries>0?'#2ea043':'#d29922'
));
// Tile 4 — ADR-021 pathway compounding
el.appendChild(tile(
'Pathway Matrix',
(pwm.total_pathways||0)+' traces',
pwm.retired+' retired · '+pwm.total_replays+' replays · ADR-021 compounding',
'#58a6ff'
));
}).catch(function(e){
el.textContent='substrate signals unavailable: '+e.message;
});
}
// ⑤ loadArchSignals() was MOVED to proof.html (Architecture, Chapter 11)
// on 2026-05-30 — the architecture-health probes live with the rest of the
// architecture story now, so the dashboard stays focused on staffing work.
// ─── Live Market hero: 24/7 shift clock (left) + Chicago permit pulse (right) ──
// Combines two previously-separate tiles into one coherent "what's happening in
@ -2534,6 +2530,15 @@ function loadLiveContracts(){
right.appendChild(rate);
}
hdr.appendChild(left);hdr.appendChild(right);card.appendChild(hdr);
// Persistent expand affordance at the TOP of the card (2026-05-30
// UX). The whole card is already clickable; this makes the toggle
// obvious and shows expand state in BOTH collapsed and expanded
// form. Text + chevron are flipped by the card click handler below.
var topToggle=document.createElement('div');topToggle.className='card-top-toggle';
var topChev=document.createElement('span');topChev.className='chevron';topChev.textContent='▸';
var topLabel=document.createElement('span');topLabel.textContent='Show details';
topToggle.appendChild(topChev);topToggle.appendChild(topLabel);
card.appendChild(topToggle);
// Architecture pill row — instant-search latency + shift coverage
// + pool-size proof that the index actually fired on this call.
// This is the "our substrate is better" surface J asked for.
@ -2853,6 +2858,8 @@ function loadLiveContracts(){
toggleLabel.textContent=nowExpanded
? 'click to collapse'
: 'click for full curve, economics, candidates, project index';
topLabel.textContent=nowExpanded?'Hide details':'Show details';
topChev.textContent=nowExpanded?'▾':'▸';
// Auto-open the Project Index ONLY on user-driven expand. This
// avoids firing 20+ OSHA scrapes on page load — each open
// triggers /intelligence/permit_entities, which live-scrapes

View File

@ -102,6 +102,7 @@ h2{color:#e6edf3;font-size:22px;font-weight:700;letter-spacing:-0.3px;margin-bot
<nav>
<a href=".">Dashboard</a>
<a href="console">Walkthrough</a>
<a href="profiler">Profiler</a>
<a href="proof">Architecture</a>
<a href="spec">Spec</a>
<a href="onboard">Onboard</a>