Commit Graph

922 Commits

Author SHA1 Message Date
CarterPerez-dev 92d8a1aabf feat(monitor/frontend): bottom ticker (world events marquee, 60s loop)
32px strip in the bottomticker grid-area that renders the ticker Zustand
store as a horizontally scrolling marquee — one of the few places motion
is allowed because new entries pushing older ones along IS data changing.
Source label uppercase + letter-spaced --fg-3, headline body --fg-2,
relative timestamp mono tabular --fg-3.

Empty state is a bare strip (no "no events" message, no illustration) —
operator UI doesn't onboard. The track only renders when items.length > 0
so the marquee animation isn't running over an empty list.

formatRel uses module-scope SECONDS_PER_MINUTE / SECONDS_PER_HOUR /
MS_PER_SECOND constants (no inline magic numbers). Animation uses kebab
keyframe name (stylelint keyframes-name-pattern).
2026-05-03 07:00:27 -04:00
CarterPerez-dev 0ba29226a2 feat(monitor/frontend): alert banner (one-amber-fill overlay, 30s auto-dismiss)
The only surface in the dashboard that uses amber as a fill color — the
one-alarm-color rule reserves this paint for "look here." 48px strip in
the alertbanner grid-area, dark text (--amber-fg #1a1a1a) on the amber
fill for cross-room legibility, ellipsis on long messages, dismiss button
at right. Returns null when the ui store has no currentAlert so the row
collapses to zero and the center grid sits flush with the top strip.

Auto-dismiss after 30s via setTimeout in useEffect; cleanup on unmount
or alert change. role="alert" for screen readers. focus-visible outline
1px --amber-fg.

Adds --amber-fg to ethos tokens — pairs explicitly with --amber so any
future amber-fill surface uses the same dark text. Also cleans up an
empty `//` line in the ethos comment block (stylelint scss/comment-no-empty).
2026-05-03 06:58:37 -04:00
CarterPerez-dev 5e33a4db22 feat(monitor/frontend): top strip (title + UTC clock + about/user icons)
Thin 36px strip in the topstrip grid-area: left = MONITORING THE SITUATION
label + about-trigger icon, center = HH:MM:SS UTC mono clock with tabular-nums
ticking once per second, right = settings gear (auth) or user (anonymous)
that navigates via ROUTES.{SETTINGS,LOGIN}. About icon dispatches openAbout
on the ui store; the modal itself is Task 23.

Pure monochrome — title --fg-2 letter-spaced uppercase --type-label, clock
--fg-2 mono, icons --fg-3 with --fg-1 hover color shift (no transition,
no scale, no rounded surface). Reads tmux-status-line, not SaaS app header.
focus-visible outline 1px --fg-2 for keyboard a11y. Dashboard.tsx renders
<TopStrip /> as a direct child of .root so it auto-places into the
topstrip named area.

Plan 5 Task 8 Design QA: strip height, label tier, mono tabular clock,
zero rounding, tmux feel — all verified.
2026-05-03 06:56:03 -04:00
CarterPerez-dev c7a0dd33a2 feat(monitor/frontend): dashboard 3-col grid layout (320 / 1fr / 320, no body scroll)
Replaces the demolition scaffold with the structural grid that Tasks 8-21
fill in. Root is a 4-row grid (topstrip / alertbanner / main / bottomticker)
with named grid-areas; the main row contains a 3-col sub-grid (left aside /
center section / right aside) at fixed 320px / 1fr / 320px. 100dvh, no body
scroll, ethos custom properties only — no template SCSS variables touched.

Adds --col-panel-width: 320px to the ethos token block (no magic number in
the layout module). index.tsx becomes a one-line re-export of Dashboard so
the lazy-route contract in routers.tsx stays unchanged.

No placeholder components. The empty <aside>/<section> elements are the
column containers themselves; subsequent tasks add real children inside
them rather than swap stub components.

Verified in browser at 1920x1080: rgb(10,10,10) bg, 320/1247/320 col rects,
1px var(--fg-4) rules between columns, body has no scroll. All 5 Plan 5
Task 7 Design QA boxes checked.
2026-05-03 06:49:16 -04:00
CarterPerez-dev 50b0e96735 chore(monitor/frontend): demolish template shell + landing for clean dashboard canvas
Cleared:
- core/app/shell.tsx + shell.module.scss (sidebar+header layout)
- core/app/toast.module.scss (replaced by inline ethos toaster styling)
- core/lib/shell.ui.store.ts (sidebar collapsed state, no longer needed)
- pages/landing/ (template marketing copy)
- pages/dashboard/ template placeholder (replaced with minimal scaffold)
- components/index.tsx (empty stub)

Kept:
- All auth infrastructure (apiClient, auth.store, ProtectedRoute)
- Auth pages (login/register/settings/admin) — they keep the template's
  visual style for now; not on the operator's hot path
- All my Phase 5 work (ethos tokens, snapshot/ws/stores)

Routes now: / -> dashboard scaffold (no Shell), /login + /register
standalone, /settings + /admin auth-gated standalone (no Shell wrapper).
2026-05-03 02:04:26 -04:00
CarterPerez-dev 7a97aac091 feat(monitor/frontend): zustand stores (globe / ticker / prices / ui / audio + ticker tests) 2026-05-02 05:36:18 -04:00
CarterPerez-dev f7f276df39 feat(monitor/frontend): dashboard WS client with reconnect + init handshake (TDD, 6 tests) 2026-05-02 05:35:18 -04:00
CarterPerez-dev 6aa3efacd6 feat(monitor/frontend): useSnapshot hook (single bootstrap, no refetch) 2026-05-02 05:33:53 -04:00
CarterPerez-dev 4216de3435 feat(monitor/frontend): ethos-aligned base styles (zero rounding, density, tabular nums) 2026-05-02 05:33:12 -04:00
CarterPerez-dev a34a175f14 feat(monitor/frontend): ethos design tokens (colors, type, density) 2026-05-02 05:32:26 -04:00
CarterPerez-dev 94d7e6035e docs(monitor/frontend): mirror ethos hard rules into SCSS comment block 2026-05-02 05:31:32 -04:00
CarterPerez-dev 2ac91da809 docs(monitor): add four world-collector rows to data source matrix 2026-05-02 04:43:03 -04:00
CarterPerez-dev 2f0c019f20 fix(monitor/collectors/gdelt): GDELT 'value' field is float64 not int (caught in live verify) 2026-05-02 04:42:39 -04:00
CarterPerez-dev d662a8c81a fix(monitor/collectors/wikipedia): move revid out of state: namespace (was leaking into snapshot) 2026-05-02 04:41:34 -04:00
CarterPerez-dev 994b510fa4 feat(monitor/main): wire usgs/swpc/wikipedia/gdelt/iss collectors under errgroup 2026-05-02 04:40:46 -04:00
CarterPerez-dev a7f0d5b097 feat(monitor/config): usgs/swpc/wikipedia/gdelt/iss config blocks 2026-05-02 04:39:51 -04:00
CarterPerez-dev ae01113086 feat(monitor/collectors/iss): 10s position poll + daily TLE refresh + propagator-ready collector 2026-05-02 04:39:07 -04:00
CarterPerez-dev 928db0befc feat(monitor/collectors/iss): SGP4 propagator wrapper (Position + LookAngles via go-satellite) 2026-05-02 04:37:25 -04:00
CarterPerez-dev 317fadeeef feat(monitor/collectors/gdelt): 15m collector with per-theme rolling z-score spike emit 2026-05-02 04:35:15 -04:00
CarterPerez-dev 066e2debc2 feat(monitor/collectors/gdelt): per-theme rolling z-score baseline detector 2026-05-02 04:31:10 -04:00
CarterPerez-dev e1d021a99a feat(monitor/collectors/wikipedia): 5m ITN collector with revid-based dedup and per-entry id hash 2026-05-02 04:30:14 -04:00
CarterPerez-dev 85626a0e11 feat(monitor/collectors/wikipedia): goquery-backed ITN parser (revid + entries with article slugs) 2026-05-02 04:28:28 -04:00
CarterPerez-dev 05ca2f529f feat(monitor/collectors/swpc): collector with 1m + 3h cadences and ring-buffered persistence 2026-05-02 04:27:13 -04:00
CarterPerez-dev 608a7937e7 feat(monitor/collectors/swpc): five-endpoint NOAA SWPC client (plasma/mag/kp/xray/alerts) 2026-05-02 04:25:17 -04:00
CarterPerez-dev fc3cfb523b feat(monitor/redisring): sorted-set ring buffer with score-based retention 2026-05-02 04:23:37 -04:00
CarterPerez-dev 2368ed8f18 feat(monitor/collectors/usgs): 1m collector with id-diff and earthquake emit 2026-05-02 04:22:37 -04:00
CarterPerez-dev 1d414ff341 feat(monitor/collectors/usgs): GeoJSON feed client (2.5_day, ms-since-epoch decoder) 2026-05-02 04:21:38 -04:00
CarterPerez-dev 11a68de2b7 feat(monitor/collectors/usgs): earthquakes repository (upsert, known-ids, recent-by-mag) 2026-05-02 04:20:49 -04:00
CarterPerez-dev d4995c1258 fix(monitor/collectors/coinbase): connection-global sequencer; gap is non-fatal log
Two related issues caught in live verification:

1. Coinbase's sequence_num is connection-global (not per-product). Previous
   per-product tracking flagged every cross-product frame as a gap.

2. Even after switching to global tracking, gaps still occur regularly under
   normal operation (Coinbase's exact sequencing pattern across channels is
   not strictly seq+1 frame-to-frame). Treating gaps as fatal kills the
   ReadLoop in seconds, never giving the minute aggregator a chance to cross
   a boundary, so btc_eth_minute stays empty.

Resolution: rewrite Sequencer for a single global counter and downgrade
gap-detection to a non-fatal Warn. ReadLoop continues; (symbol, ts) PK on
btc_eth_ticks is the safety net for any duplicate replay. Includes a
diagnostic log on loop exit (handleConn) for ops visibility.
2026-05-02 04:03:09 -04:00
CarterPerez-dev 989e53c958 fix(monitor/collectors/coinbase): parse Coinbase's Go-style time format in heartbeat current_time
Coinbase Advanced Trade WS leaks Go's time.Time.String() format in
heartbeat events (e.g. "2026-05-02 07:55:50.784... +0000 UTC m=+102632...")
which is not RFC 3339 — UnmarshalJSON into time.Time fails and the entire
envelope errors. Decode current_time as a string and parse it with a
fallback that handles both RFC 3339 and the Go-string variant (with the
m=+monotonic suffix stripped).
2026-05-02 04:02:49 -04:00
CarterPerez-dev 2ccc379255 fix(monitor/collectors/coinbase): exhaustive switches, %w double-wrap, require.ErrorIs (lint) 2026-05-02 03:42:59 -04:00
CarterPerez-dev d352a6bce6 chore(monitor): gofmt const-block alignment in phase-2 collectors 2026-05-02 03:39:51 -04:00
CarterPerez-dev 0027de6c72 docs(monitor): add coinbase row to cyber data source matrix 2026-05-02 03:37:56 -04:00
CarterPerez-dev 99f6e41845 feat(monitor/main): wire coinbase BTC/ETH collector under errgroup 2026-05-02 03:36:26 -04:00
CarterPerez-dev 9c35e14ae8 fix(monitor/collectors/coinbase): use envelope timestamp (per-ticker time field is not in real Coinbase frames) 2026-05-02 03:36:26 -04:00
CarterPerez-dev 0a6f4f1e09 feat(monitor/config): coinbase config block (enabled, url, product_ids, throttle) 2026-05-02 03:32:53 -04:00
CarterPerez-dev 89f1c10249 feat(monitor/collectors/coinbase): collector Run loop ties dial+readloop+aggregator+repo+throttled-emit 2026-05-02 03:32:16 -04:00
CarterPerez-dev f6192e9c04 feat(monitor/collectors/coinbase): per-product minute aggregator with rollover-emit 2026-05-02 03:30:24 -04:00
CarterPerez-dev 23a4e2ded4 feat(monitor/collectors/coinbase): gap-aware ReadLoop (snapshot resets sequencer; gap → ErrSequenceGap) 2026-05-02 03:29:43 -04:00
CarterPerez-dev 3be4c9d815 feat(monitor/collectors/coinbase): reconnect-with-backoff helper (1s init, 60s max, ctx-aware) 2026-05-02 03:28:24 -04:00
CarterPerez-dev 3e398da3fb feat(monitor/collectors/coinbase): per-product sequence-gap detector 2026-05-02 03:27:32 -04:00
CarterPerez-dev 10862314f0 feat(monitor/collectors/coinbase): WS dialer + frame decoder for ticker/heartbeats/snapshot 2026-05-02 03:26:58 -04:00
CarterPerez-dev ae5a83c2f8 feat(monitor/collectors/coinbase): ticks + minute OHLC repo with 1h history reads
Adds shopspring/decimal as a require (folded with the first consuming task per
Plan 2 convention). cenkalti/backoff/v4 is also now consumed transitively;
remains indirect until Task 5 (reconnect) imports it.
2026-05-02 03:24:55 -04:00
CarterPerez-dev 687e13389e chore(monitor): tidy headers, drop unused StateDown, gofmt config defaults 2026-05-02 03:01:48 -04:00
CarterPerez-dev b9c5fa1e13 docs(monitor): add cyber data source matrix to README 2026-05-01 22:53:58 -04:00
CarterPerez-dev c64141bc0b feat(monitor/main): wire dshield/cfradar/cve/kev/ransomware collectors under errgroup 2026-05-01 22:51:50 -04:00
CarterPerez-dev cb8cd902f6 feat(monitor/config): collectors config (toggles, intervals, API key bindings) 2026-05-01 22:50:55 -04:00
CarterPerez-dev 6cc3e681de feat(monitor/enrich/greynoise): on-demand IP lookup with 404→ErrUnknownIP via httpx.StatusError 2026-05-01 22:49:48 -04:00
CarterPerez-dev 894ecc8fe5 feat(monitor/collectors/ransomware): 15m collector with hash-diff and victim emit 2026-05-01 22:48:09 -04:00
CarterPerez-dev 3d71fd8c84 feat(monitor/collectors/ransomware): ransomware.live client with stable triple-hash ID
Hand-crafted fixture matches spec §8.5 schema. Live API endpoint may move; client
takes BaseURL config for swap-in once api.ransomware.live publishes a stable JSON
endpoint (current free tier returns HTML landing page on /recentvictims).
2026-05-01 22:47:19 -04:00