This commit is contained in:
parent
1cd75ca4b2
commit
6d11abc660
8 changed files with 228 additions and 62 deletions
|
|
@ -24,6 +24,7 @@
|
|||
{"_type":"issue","id":"islandflow-ayo","title":"Drop stale backlog events from live fanout","description":"Follow-up to live freshness rollout: /ws/live was still fanning out stale backlog events for freshness-gated channels, which kept tape panes in Live feed behind despite active synthetic ingest. Gate fanout and cache ingest by freshness for options/nbbo/equities/flow.","status":"closed","priority":1,"issue_type":"bug","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-04-28T21:26:39Z","created_by":"dirtydishes","updated_at":"2026-04-28T21:26:44Z","started_at":"2026-04-28T21:26:44Z","closed_at":"2026-04-28T21:26:44Z","close_reason":"Completed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"islandflow-0v6","title":"Fix tape freshness, NBBO coverage, pause controls, and filter popup","description":"Implement the tape fixes requested for synthetic options notional sizing, strict live freshness, live-mode pause/resume behavior, stronger NBBO snapshot coverage, and moving flow filters behind a popup. Includes server-side live cache changes, web terminal state/UI changes, and tests for synthetic pricing, live snapshot freshness/NBBO retention, and live pause/filter interactions.","status":"closed","priority":1,"issue_type":"task","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-04-28T21:02:52Z","created_by":"dirtydishes","updated_at":"2026-04-28T21:13:38Z","started_at":"2026-04-28T21:02:57Z","closed_at":"2026-04-28T21:13:38Z","close_reason":"Completed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"islandflow-e4r","title":"Implement smart-money flow filtering and synthetic firehose modes","description":"Implement the approved multi-surface plan for named synthetic market profiles, options raw-vs-signal filtering, live/API filter contracts, Tape page client-side flow filters, firehose-readiness improvements, tests, and README updates.","status":"closed","priority":1,"issue_type":"feature","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-04-28T20:10:49Z","created_by":"dirtydishes","updated_at":"2026-04-28T20:29:29Z","started_at":"2026-04-28T20:10:53Z","closed_at":"2026-04-28T20:29:29Z","close_reason":"Implemented synthetic market profiles, options signal-path filtering, signal-aware API/replay contracts, Tape page filters, tests, and README updates. Follow-up tracked in islandflow-biq.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"islandflow-dk5","title":"Remove frontend cooker route","description":"Remove the experimental /frontend-cooker page and update repository references that still list it as an available public route.","status":"closed","priority":2,"issue_type":"task","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-29T13:50:38Z","created_by":"dirtydishes","updated_at":"2026-05-29T13:53:05Z","started_at":"2026-05-29T13:50:48Z","closed_at":"2026-05-29T13:53:05Z","close_reason":"Removed the /frontend-cooker Next.js route, cleaned route/scanner references, documented the work, and validated the web build.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"islandflow-ep2","title":"Configure Impeccable live mode","description":"Initialize the repository's Impeccable live-mode configuration so future design iteration can start without first-time setup.","status":"closed","priority":2,"issue_type":"task","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-29T08:03:47Z","created_by":"dirtydishes","updated_at":"2026-05-29T08:05:01Z","started_at":"2026-05-29T08:03:52Z","closed_at":"2026-05-29T08:05:01Z","close_reason":"Configured Impeccable live mode and documented validation.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"islandflow-9en","title":"Install Impeccable skill for Codex","description":"Install the Impeccable skill in the Codex-compatible project locations after the upstream installer selected unused harness folders.","status":"closed","priority":2,"issue_type":"task","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-29T07:59:10Z","created_by":"dirtydishes","updated_at":"2026-05-29T07:59:22Z","started_at":"2026-05-29T07:59:18Z","closed_at":"2026-05-29T07:59:22Z","close_reason":"Installed Impeccable into .agents and mirrored it into .codex/skills for Codex use.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"islandflow-444","title":"Add typecheck to Forgejo CI","description":"Forgejo CI already validates PRs and pushes to main, but it does not run the new repository-wide typecheck gate. Add bun run typecheck before tests so type drift fails early in CI.","status":"closed","priority":2,"issue_type":"task","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-29T06:27:47Z","created_by":"dirtydishes","updated_at":"2026-05-29T06:29:33Z","started_at":"2026-05-29T06:27:49Z","closed_at":"2026-05-29T06:29:33Z","close_reason":"Added repository typecheck to the Forgejo PR/main CI workflow.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
.cookerShell{min-height:100vh;display:grid;grid-template-columns:280px 1fr;background:#080806;color:#f4efe3}.chrome{position:sticky;top:0;height:100vh;padding:18px;display:flex;flex-direction:column;gap:22px;background:#111;border-right:1px solid #333;z-index:5}.chrome p{margin:0 0 8px;color:#d6a84f;text-transform:uppercase;letter-spacing:.18em;font-size:12px}.chrome h2{margin:0 0 8px;font-family:Georgia,serif;font-size:28px;line-height:1}.chrome small,.chrome footer{color:#aaa;line-height:1.45}.chrome footer{margin-top:auto;font-size:12px}.switcher{display:grid;gap:9px}.switcher button{display:grid;grid-template-columns:28px 1fr;gap:10px;align-items:center;text-align:left;padding:10px;border:1px solid #333;border-radius:14px;background:#191919;color:#ddd;cursor:pointer;transition:.18s}.switcher button:hover,.switcher .active{transform:translateX(3px);border-color:#d6a84f;background:#272111}.switcher b{display:grid;place-items:center;width:24px;height:24px;border-radius:50%;background:#333;color:#fff}.mock{min-height:100vh;padding:28px;font-family:var(--body,serif);transition:background .25s,color .25s}.productNav{display:flex;align-items:center;gap:18px;margin-bottom:28px}.productNav strong{margin-right:auto;letter-spacing:.16em}.productNav span{opacity:.75}.productNav button,.panelHead button{border:0;border-radius:999px;padding:10px 14px;cursor:pointer;background:var(--accent);color:var(--accentText)}.hero{display:grid;grid-template-columns:minmax(0,1.25fr)360px;gap:24px;align-items:stretch}.kicker{margin:0 0 10px;color:var(--accent);letter-spacing:.18em;text-transform:uppercase;font-size:12px}.hero h1{margin:0;font-family:var(--display,Georgia,serif);font-size:clamp(42px,6vw,92px);line-height:.9;letter-spacing:-.05em;text-transform:none}.copy{max-width:680px;font-size:18px;line-height:1.5;opacity:.78}.statusCard,.metrics article,.primaryPanel,.sidePanel,.tableWrap{border:1px solid var(--line);background:var(--panel);box-shadow:var(--shadow);border-radius:var(--radius)}.statusCard{padding:24px;font-size:15px}.statusCard b{display:block;margin:28px 0 4px;font-size:48px;font-family:var(--display)}.liveDot{display:inline-block;width:10px;height:10px;border-radius:50%;background:#28d77f;box-shadow:0 0 18px #28d77f;margin-right:8px}.metrics{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin:20px 0}.metrics article{padding:18px;font-weight:700}.workspace{display:grid;grid-template-columns:1.45fr .75fr;gap:18px}.primaryPanel,.sidePanel{padding:18px}.panelHead{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px}.panelHead h2,.sidePanel h2{margin:0;font-family:var(--display);font-size:24px}.chart{height:330px;position:relative;display:flex;align-items:flex-end;gap:1.8%;padding:24px;overflow:hidden;background:var(--chart);border-radius:calc(var(--radius) - 6px)}.chart i{flex:1;background:var(--bar);border-radius:99px 99px 0 0;animation:rise .7s both}.chart b{position:absolute;left:5%;right:5%;top:45%;height:3px;background:var(--accent);transform:rotate(-8deg);box-shadow:0 0 24px var(--accent)}.alert,.empty,.loading,.error{padding:14px;margin-top:12px;border-radius:14px;border:1px solid var(--line);background:rgba(255,255,255,.06)}.loading{background:repeating-linear-gradient(90deg,rgba(255,255,255,.08),rgba(255,255,255,.08) 12px,transparent 12px,transparent 24px)}.error{color:#ffb1a8}.tableWrap{margin-top:18px;overflow:auto}.tableWrap table{width:100%;border-collapse:collapse}.tableWrap th,.tableWrap td{padding:14px 16px;border-bottom:1px solid var(--line);text-align:left}.tableWrap tr:hover td{background:rgba(255,255,255,.08)}@keyframes rise{from{transform:scaleY(.25);opacity:.2}to{transform:scaleY(1);opacity:1}}
|
||||
.pit{--display:Impact,Haettenschweiler,'Arial Narrow Bold',sans-serif;--body:'Trebuchet MS',sans-serif;--accent:#ffb000;--accentText:#1a0c00;--line:#3e321b;--panel:#16120b;--chart:#080602;--bar:linear-gradient(#ffcf52,#b35b00);--radius:4px;--shadow:inset 0 0 0 1px #000,0 18px 0 rgba(0,0,0,.25);background:radial-gradient(circle at 70% -10%,#5d2500,transparent 35%),#0b0905;color:#fff0c9}.pit .productNav{border-bottom:6px solid #ffb000;padding-bottom:12px}.atlas{--display:'Didot','Bodoni 72',serif;--body:'Avenir Next',Verdana,sans-serif;--accent:#00b894;--accentText:#001b15;--line:rgba(16,80,70,.28);--panel:rgba(235,255,250,.68);--chart:linear-gradient(135deg,#dff9ef,#b8d6e5);--bar:#0b8874;--radius:28px;--shadow:0 30px 80px rgba(30,90,90,.16);background:linear-gradient(120deg,#eef8f3,#cbdde1);color:#17322f}.ledger{--display:'Iowan Old Style',Georgia,serif;--body:Georgia,serif;--accent:#8b3f1f;--accentText:#fff8ee;--line:#d8c7a9;--panel:#fffaf0;--chart:#f7ecd8;--bar:#1f3f35;--radius:0;--shadow:8px 8px 0 #d8c7a9;background:#f4ead8;color:#24190f}.ledger.mock,.ledger .tableWrap table{font-size:17px}.neon{--display:'Courier New',monospace;--body:'Courier New',monospace;--accent:#39ff14;--accentText:#001400;--line:#263cff;--panel:rgba(4,8,28,.82);--chart:#03040f;--bar:linear-gradient(#ff2bd6,#263cff);--radius:18px;--shadow:0 0 32px rgba(57,255,20,.2),inset 0 0 24px rgba(38,60,255,.18);background:linear-gradient(180deg,#050718,#110014);color:#d6fff4}.neon .hero h1{text-shadow:0 0 20px #ff2bd6}.paper{--display:'Franklin Gothic Medium','Arial Narrow',sans-serif;--body:'Times New Roman',serif;--accent:#c5281c;--accentText:#fff;--line:#111;--panel:#f8f1df;--chart:repeating-linear-gradient(0deg,#efe4cc,#efe4cc 14px,#e2d3b8 15px);--bar:#111;--radius:0;--shadow:none;background:#eee2c8;color:#111}.paper .productNav,.paper .hero,.paper .metrics{border-bottom:3px double #111;padding-bottom:14px}@media(max-width:900px){.cookerShell{grid-template-columns:1fr}.chrome{height:auto;position:relative}.switcher{grid-template-columns:repeat(2,1fr)}.hero,.workspace,.metrics{grid-template-columns:1fr}.productNav{flex-wrap:wrap}.mock{padding:18px}}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
"use client";
|
||||
|
||||
import { useMemo, useState } from "react";
|
||||
import styles from "./frontend-cooker.module.css";
|
||||
|
||||
const variations = [
|
||||
{ id: "pit", name: "Open-Outcry Pit", rationale: "A loud exchange-floor command center optimized for immediate threat recognition and dense scan paths." },
|
||||
{ id: "atlas", name: "Glass Atlas", rationale: "A calm geospatial intelligence room that makes flow feel mapped, layered, and explorable." },
|
||||
{ id: "ledger", name: "Ivory Ledger", rationale: "A refined analyst notebook with editorial hierarchy for slower, higher-confidence review." },
|
||||
{ id: "neon", name: "Neon Underpass", rationale: "A kinetic cyberpunk tape for traders who want momentum, heat, and speed above all." },
|
||||
{ id: "paper", name: "Signal Gazette", rationale: "A newspaper-like briefing that turns raw options activity into a morning intelligence digest." }
|
||||
];
|
||||
|
||||
const flowRows = [
|
||||
["NVDA", "910C", "05-17", "$4.8M", "AA", "+92%", "Sweep"],
|
||||
["TSLA", "175P", "05-10", "$2.1M", "BB", "−68%", "ISO"],
|
||||
["AAPL", "205C", "06-21", "$1.4M", "A", "+41%", "Block"],
|
||||
["SPY", "520P", "05-03", "$8.7M", "B", "−53%", "Split"],
|
||||
["AMD", "162C", "05-24", "$910K", "AA", "+77%", "Sweep"]
|
||||
];
|
||||
|
||||
function MiniChart({ variant }: { variant: string }) {
|
||||
return <div className={`${styles.chart} ${styles[`chart_${variant}`]}`} aria-label="Mock price and flow chart">
|
||||
{Array.from({ length: 22 }).map((_, i) => <i key={i} style={{ height: `${24 + ((i * 17) % 58)}%`, animationDelay: `${i * 35}ms` }} />)}
|
||||
<b />
|
||||
</div>;
|
||||
}
|
||||
|
||||
function AppMock({ id }: { id: string }) {
|
||||
return <main className={`${styles.mock} ${styles[id]}`}>
|
||||
<nav className={styles.productNav}>
|
||||
<strong>ISLANDFLOW</strong><span>Overview</span><span>Live Tape</span><span>Signals</span><span>Replay</span><button>Filter Flow</button>
|
||||
</nav>
|
||||
<section className={styles.hero}>
|
||||
<div><p className={styles.kicker}>Live Options Intelligence</p><h1>Unusual flow surfaced before the crowd.</h1><p className={styles.copy}>Representative redesign of the IslandFlow terminal: live status, option sweeps, inferred dark activity, classifier hits, and replay controls.</p></div>
|
||||
<div className={styles.statusCard}><span className={styles.liveDot}/>Connected · 1,284 msgs/min<br/><b>$42.6M</b><small> premium tracked in active window</small></div>
|
||||
</section>
|
||||
<section className={styles.metrics}>{["Alert score 87", "Bullish 62%", "Dark pool 14", "Stale feeds 0"].map(x => <article key={x}>{x}</article>)}</section>
|
||||
<section className={styles.workspace}>
|
||||
<div className={styles.primaryPanel}><div className={styles.panelHead}><h2>Flow Radar</h2><button>Pause Tape</button></div><MiniChart variant={id}/></div>
|
||||
<div className={styles.sidePanel}><h2>Classifier Hits</h2><div className={styles.alert}>High conviction: NVDA call sweep above ask with confirming equity print.</div><div className={styles.empty}>Empty state: no stale NBBO quotes in the last 15s.</div><div className={styles.loading}>Loading replay baseline…</div><div className={styles.error}>Error state: dark inference source delayed.</div></div>
|
||||
</section>
|
||||
<section className={styles.tableWrap}><table><thead><tr>{["Ticker", "Contract", "Expiry", "Notional", "Side", "Delta", "Condition"].map(h => <th key={h}>{h}</th>)}</tr></thead><tbody>{flowRows.map((r) => <tr key={r.join("")}>{r.map((c, i) => <td key={i}>{c}</td>)}</tr>)}</tbody></table></section>
|
||||
</main>;
|
||||
}
|
||||
|
||||
export default function FrontendCooker() {
|
||||
const [active, setActive] = useState(0);
|
||||
const current = variations[active];
|
||||
const nav = useMemo(() => variations.slice(0, 5), []);
|
||||
return <div className={styles.cookerShell}>
|
||||
<aside className={styles.chrome}><div><p>Frontend Cooker</p><h2>{current.name}</h2><small>{current.rationale}</small></div><div className={styles.switcher}>{nav.map((v, i) => <button key={v.id} className={i === active ? styles.active : ""} onClick={() => setActive(i)}><b>{i + 1}</b><span>{v.name}</span></button>)}</div><footer>Target: IslandFlow trading terminal overview</footer></aside>
|
||||
<AppMock id={current.id}/>
|
||||
</div>;
|
||||
}
|
||||
225
docs/turns/2026-05-29-remove-frontend-cooker.html
Normal file
225
docs/turns/2026-05-29-remove-frontend-cooker.html
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Remove frontend cooker route</title>
|
||||
<style>
|
||||
:root {
|
||||
color-scheme: dark;
|
||||
--bg: #06080b;
|
||||
--panel: #111820;
|
||||
--panel-2: #0d141b;
|
||||
--border: rgba(255, 255, 255, 0.13);
|
||||
--text: #e6edf4;
|
||||
--muted: #90a0b2;
|
||||
--faint: #6e7b8c;
|
||||
--accent: #f5a623;
|
||||
--accent-soft: rgba(245, 166, 35, 0.12);
|
||||
--red-soft: rgba(255, 107, 95, 0.13);
|
||||
--green-soft: rgba(37, 193, 122, 0.12);
|
||||
font-family: "IBM Plex Sans", Inter, system-ui, sans-serif;
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background: linear-gradient(180deg, #0b1016 0%, var(--bg) 100%);
|
||||
color: var(--text);
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
main {
|
||||
width: min(1040px, calc(100vw - 32px));
|
||||
margin: 0 auto;
|
||||
padding: 48px 0 72px;
|
||||
}
|
||||
|
||||
header {
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 14px;
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.04), rgba(255, 255, 255, 0.018));
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
h1, h2, h3, code, pre {
|
||||
font-family: "IBM Plex Mono", "SFMono-Regular", Consolas, monospace;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0 0 12px;
|
||||
font-size: 1.9rem;
|
||||
letter-spacing: 0;
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 34px 0 12px;
|
||||
font-size: 1rem;
|
||||
color: var(--accent);
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
p { margin: 0 0 14px; color: var(--muted); }
|
||||
|
||||
ul { margin: 0; padding-left: 1.2rem; color: var(--muted); }
|
||||
|
||||
li + li { margin-top: 7px; }
|
||||
|
||||
.meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.chip {
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.035);
|
||||
padding: 4px 9px;
|
||||
color: var(--text);
|
||||
font-family: "IBM Plex Mono", monospace;
|
||||
font-size: 0.78rem;
|
||||
}
|
||||
|
||||
section {
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
||||
padding-bottom: 22px;
|
||||
}
|
||||
|
||||
section:last-child { border-bottom: 0; }
|
||||
|
||||
pre {
|
||||
margin: 12px 0 0;
|
||||
overflow: auto;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 10px;
|
||||
background: #080c11;
|
||||
padding: 14px;
|
||||
color: #d9e6f2;
|
||||
font-size: 0.83rem;
|
||||
line-height: 1.45;
|
||||
}
|
||||
|
||||
code {
|
||||
color: #f5d392;
|
||||
font-size: 0.93em;
|
||||
}
|
||||
|
||||
.note {
|
||||
border: 1px solid rgba(245, 166, 35, 0.24);
|
||||
border-radius: 10px;
|
||||
background: var(--accent-soft);
|
||||
padding: 12px 14px;
|
||||
color: #f6d69c;
|
||||
}
|
||||
|
||||
.ok {
|
||||
border-color: rgba(37, 193, 122, 0.22);
|
||||
background: var(--green-soft);
|
||||
color: #a9e8c9;
|
||||
}
|
||||
|
||||
.risk {
|
||||
border-color: rgba(255, 107, 95, 0.24);
|
||||
background: var(--red-soft);
|
||||
color: #ffc1bb;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<header>
|
||||
<h1>Remove frontend cooker route</h1>
|
||||
<p>Removed the experimental <code>/frontend-cooker</code> page from the Next.js app and cleaned up repository references that still listed it as a public route or scanner candidate.</p>
|
||||
<div class="meta">
|
||||
<span class="chip">2026-05-29 09:51 EDT</span>
|
||||
<span class="chip">Beads: islandflow-dk5</span>
|
||||
<span class="chip">Scope: web route removal</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section>
|
||||
<h2>Summary</h2>
|
||||
<p>The frontend cooker prototype is no longer routable in the web app. Its page component and CSS module were deleted, and the attack-surface documentation now reflects the remaining public pages.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Changes Made</h2>
|
||||
<ul>
|
||||
<li>Deleted <code>apps/web/app/frontend-cooker/page.tsx</code>.</li>
|
||||
<li>Deleted <code>apps/web/app/frontend-cooker/frontend-cooker.module.css</code>.</li>
|
||||
<li>Removed <code>/frontend-cooker</code> from the architecture entrypoint inventory.</li>
|
||||
<li>Removed <code>/frontend-cooker</code> from the public routes authorization matrix.</li>
|
||||
<li>Removed stale scanner candidate entries for the deleted page from <code>piolium/attack-surface/candidates-summary.md</code> and <code>piolium/attack-surface/candidates.jsonl</code>.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Context</h2>
|
||||
<p>The removed page was an experimental visual exploration route with several mock terminal variations. It was still exposed by file-system routing and listed in security inventory artifacts even though it was not part of the core Islandflow terminal workflow.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Important Implementation Details</h2>
|
||||
<p>Next.js removes the route when the corresponding folder no longer contains a page file. No redirects or replacement route were added, so requests to <code>/frontend-cooker</code> will now fall through to the app's not-found behavior.</p>
|
||||
<p>The existing local modification to <code>apps/web/next-env.d.ts</code> was left untouched because it predated this task.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Relevant Diff Snippets</h2>
|
||||
<p class="note">The repo asks for <code>@pierre/diffs</code> output by default. Attempting <code>bunx @pierre/diffs --help</code> failed because the package does not expose a runnable CLI executable, so this document includes a labeled plain unified diff fallback.</p>
|
||||
<pre><code>diff --git a/apps/web/app/frontend-cooker/page.tsx b/apps/web/app/frontend-cooker/page.tsx
|
||||
deleted file mode 100644
|
||||
--- a/apps/web/app/frontend-cooker/page.tsx
|
||||
+++ /dev/null
|
||||
@@ -1,55 +0,0 @@
|
||||
-"use client";
|
||||
-
|
||||
-import { useMemo, useState } from "react";
|
||||
-import styles from "./frontend-cooker.module.css";
|
||||
-...
|
||||
-export default function FrontendCooker() {
|
||||
- const [active, setActive] = useState(0);
|
||||
- const current = variations[active];
|
||||
- const nav = useMemo(() => variations.slice(0, 5), []);
|
||||
- return <div className={styles.cookerShell}>...</div>;
|
||||
-}</code></pre>
|
||||
<pre><code>diff --git a/piolium/attack-surface/architecture-entrypoints.md b/piolium/attack-surface/architecture-entrypoints.md
|
||||
@@ -12,7 +12,7 @@
|
||||
### Web app (`apps/web/app`, Next.js on port 3000)
|
||||
-- Pages: `/`, `/tape`, `/signals`, `/charts`, `/news`, `/options`, `/replay`, `/frontend-cooker`.
|
||||
+- Pages: `/`, `/tape`, `/signals`, `/charts`, `/news`, `/options`, `/replay`.</code></pre>
|
||||
<pre><code>diff --git a/piolium/attack-surface/public-routes-authz-matrix.md b/piolium/attack-surface/public-routes-authz-matrix.md
|
||||
@@ -29,7 +29,7 @@
|
||||
-| 17 | Next public pages `/`, `/tape`, `/signals`, `/charts`, `/news`, `/options`, `/replay`, `/frontend-cooker` | ...
|
||||
+| 17 | Next public pages `/`, `/tape`, `/signals`, `/charts`, `/news`, `/options`, `/replay` | ...</code></pre>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Expected Impact for End-Users</h2>
|
||||
<p>Users will no longer be able to open the experimental frontend cooker page. The production terminal routes remain unchanged: <code>/</code>, <code>/tape</code>, <code>/signals</code>, <code>/charts</code>, <code>/news</code>, <code>/options</code>, and <code>/replay</code>.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Validation</h2>
|
||||
<p class="ok">Passed: <code>bun --cwd=apps/web run build</code>. The resulting Next.js route list did not include <code>/frontend-cooker</code>.</p>
|
||||
<p>Also checked the repository with <code>rg -n "frontend-cooker|Frontend Cooker|/frontend-cooker" -S .</code>; no remaining references were found after the cleanup.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Issues, Limitations, and Mitigations</h2>
|
||||
<p class="risk">No runtime redirect was added. That is intentional for a removal request, but any external bookmark to <code>/frontend-cooker</code> will now receive the app's not-found response.</p>
|
||||
<p>The <code>@pierre/diffs</code> CLI was not available through <code>bunx</code>, so the diff section uses a plain unified diff fallback.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Follow-up Work</h2>
|
||||
<p>No follow-up issue was filed because the requested route and known references were removed, and validation passed.</p>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
- WebSockets: `GET /ws/options`, `/ws/options-nbbo`, `/ws/equities`, `/ws/equity-candles`, `/ws/equity-quotes`, `/ws/equity-joins`, `/ws/inferred-dark`, `/ws/flow`, `/ws/classifier-hits`, `/ws/smart-money`, `/ws/alerts`, `/ws/live`.
|
||||
|
||||
### Web app (`apps/web/app`, Next.js on port 3000)
|
||||
- Pages: `/`, `/tape`, `/signals`, `/charts`, `/news`, `/options`, `/replay`, `/frontend-cooker`.
|
||||
- Pages: `/`, `/tape`, `/signals`, `/charts`, `/news`, `/options`, `/replay`.
|
||||
- Next API admin proxy: `GET /api/admin/synthetic/status`, `GET|PUT /api/admin/synthetic/control`.
|
||||
|
||||
### Desktop (`apps/desktop`)
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@ Generated by piolium at 2026-05-27T05:18:10.316Z
|
|||
- `apps/web/app/replay/page.tsx`: score 65, 1 match(es)
|
||||
- `apps/web/app/signals/page.tsx`: score 65, 1 match(es)
|
||||
- `apps/web/app/tape/page.tsx`: score 65, 1 match(es)
|
||||
- `apps/web/app/frontend-cooker/page.tsx`: score 55, 1 match(es)
|
||||
|
||||
## Highest-Ranked Matches
|
||||
|
||||
|
|
@ -143,7 +142,6 @@ Generated by piolium at 2026-05-27T05:18:10.316Z
|
|||
- hidden-control-channel (normal, score 55) at `apps/desktop/src/security.ts:6` - new URL(DESKTOP_LOCAL_DEV_URL).origin,
|
||||
- hidden-control-channel (normal, score 55) at `apps/desktop/src/security.ts:26` - return TRUSTED_ORIGINS.has(url.origin);
|
||||
- hidden-control-channel (normal, score 55) at `apps/desktop/src/security.ts:35` - return !TRUSTED_ORIGINS.has(url.origin);
|
||||
- path-traversal-file-access (normal, score 55) at `apps/web/app/frontend-cooker/page.tsx:43` - <section className={styles.tableWrap}><table><thead><tr>{["Ticker", "Contract", "Expiry", "Notional", "Side", "Delta", "Condition"].map(h => <th key={h}>{h}</th>)}</tr></thead><tbody>{flowRows.map((r) => <tr key={r.join(
|
||||
- hidden-control-channel (normal, score 55) at `apps/web/app/terminal.tsx:516` - const contentType = response.headers.get("content-type")?.toLowerCase() ?? "";
|
||||
- hidden-control-channel (normal, score 55) at `apps/web/app/terminal.tsx:1024` - const host = isLocal ? `${hostname}:4000` : window.location.host;
|
||||
- hidden-control-channel (normal, score 55) at `apps/web/app/terminal.tsx:1024` - const host = isLocal ? `${hostname}:4000` : window.location.host;
|
||||
|
|
|
|||
|
|
@ -74,7 +74,6 @@
|
|||
{"slug":"hidden-control-channel","description":"Request header or framework/proxy context read that may influence auth, routing, tenant, runtime, debug, or middleware behavior.","noise":"normal","filePath":"apps/desktop/src/security.ts","line":6,"snippet":"new URL(DESKTOP_LOCAL_DEV_URL).origin,","matchedPattern":"proxy or original request header","score":55,"source":"builtin"}
|
||||
{"slug":"hidden-control-channel","description":"Request header or framework/proxy context read that may influence auth, routing, tenant, runtime, debug, or middleware behavior.","noise":"normal","filePath":"apps/desktop/src/security.ts","line":26,"snippet":"return TRUSTED_ORIGINS.has(url.origin);","matchedPattern":"proxy or original request header","score":55,"source":"builtin"}
|
||||
{"slug":"hidden-control-channel","description":"Request header or framework/proxy context read that may influence auth, routing, tenant, runtime, debug, or middleware behavior.","noise":"normal","filePath":"apps/desktop/src/security.ts","line":35,"snippet":"return !TRUSTED_ORIGINS.has(url.origin);","matchedPattern":"proxy or original request header","score":55,"source":"builtin"}
|
||||
{"slug":"path-traversal-file-access","description":"Filesystem access using path joins or user-controllable paths.","noise":"normal","filePath":"apps/web/app/frontend-cooker/page.tsx","line":43,"snippet":"<section className={styles.tableWrap}><table><thead><tr>{[\"Ticker\", \"Contract\", \"Expiry\", \"Notional\", \"Side\", \"Delta\", \"Condition\"].map(h => <th key={h}>{h}</th>)}</tr></thead><tbody>{flowRows.map((r) => <tr key={r.join(","matchedPattern":"path join","score":55,"source":"builtin"}
|
||||
{"slug":"hidden-control-channel","description":"Request header or framework/proxy context read that may influence auth, routing, tenant, runtime, debug, or middleware behavior.","noise":"normal","filePath":"apps/web/app/terminal.tsx","line":516,"snippet":"const contentType = response.headers.get(\"content-type\")?.toLowerCase() ?? \"\";","matchedPattern":"request header read","score":55,"source":"builtin"}
|
||||
{"slug":"hidden-control-channel","description":"Request header or framework/proxy context read that may influence auth, routing, tenant, runtime, debug, or middleware behavior.","noise":"normal","filePath":"apps/web/app/terminal.tsx","line":1024,"snippet":"const host = isLocal ? `${hostname}:4000` : window.location.host;","matchedPattern":"proxy or original request header","score":55,"source":"builtin"}
|
||||
{"slug":"hidden-control-channel","description":"Request header or framework/proxy context read that may influence auth, routing, tenant, runtime, debug, or middleware behavior.","noise":"normal","filePath":"apps/web/app/terminal.tsx","line":1024,"snippet":"const host = isLocal ? `${hostname}:4000` : window.location.host;","matchedPattern":"proxy or original request header","score":55,"source":"builtin"}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ Scope: Stage 05 public-route authorization/access-control review. Sources: `piol
|
|||
| 14 | Replay reads: `/replay/options`, `/replay/nbbo`, `/replay/equities`, `/replay/equity-quotes`, `/replay/equity-candles`, `/replay/equity-joins`, `/replay/inferred-dark`, `/replay/flow`, `/replay/smart-money`, `/replay/classifier-hits`, `/replay/alerts` | `services/api/src/index.ts:1720-1838` | Public per current architecture, bounded cursors/limits | anon/auth/admin/internal: allowed; zod parsing/limits only | none | bind/proxy | review target: bulk replay extraction if proprietary |
|
||||
| 15 | Legacy WebSockets: `/ws/options`, `/ws/options-nbbo`, `/ws/equities`, `/ws/equity-candles`, `/ws/equity-quotes`, `/ws/equity-joins`, `/ws/inferred-dark`, `/ws/flow`, `/ws/classifier-hits`, `/ws/smart-money`, `/ws/alerts` | `services/api/src/index.ts:1846-1926`, `:1958-1978` | Public live market streams or edge auth/rate/origin guard if proprietary | anon/auth/admin/internal: upgrade allowed by path; no Origin/auth check | none | bind/proxy, WebSocket origin not checked | review target: unauth streaming/resource exposure |
|
||||
| 16 | Live WebSocket subscription API: `GET /ws/live` + subscribe/unsubscribe/ping messages | `services/api/src/index.ts:1934`, `:1982-2008` | Public live API with schema limits; auth/rate/origin if proprietary | anon/auth/admin/internal: upgrade allowed; messages schema-validated but no auth | subscription data from client message | bind/proxy, WebSocket origin not checked | review target: unauth streaming/resource exposure |
|
||||
| 17 | Next public pages `/`, `/tape`, `/signals`, `/charts`, `/news`, `/options`, `/replay`, `/frontend-cooker` | `apps/web/app/**` | Public UI | anon/auth/admin/internal: allowed by file routing | browser calls API configured by env | `NEXT_PUBLIC_API_URL` exposed to client | none filed |
|
||||
| 17 | Next public pages `/`, `/tape`, `/signals`, `/charts`, `/news`, `/options`, `/replay` | `apps/web/app/**` | Public UI | anon/auth/admin/internal: allowed by file routing | browser calls API configured by env | `NEXT_PUBLIC_API_URL` exposed to client | none filed |
|
||||
|
||||
## Anomalies promoted to drafts
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue