Record the implementation commit that pauses Header market-index polling while the tab is hidden.
Refs: docs/AUDIT_REDESIGN.md item C5.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Guard Header market-index refreshes with document.visibilityState and resume on visibilitychange so hidden tabs stop polling the backend while preserving stale index data.
Refs: docs/AUDIT_REDESIGN.md item C5.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Record the implementation commit that validates /api/news symbol filters before proxying.
Refs: docs/AUDIT_REDESIGN.md item C4.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Normalize and limit /api/news symbols before proxying to Alpaca so only bounded, expected symbol characters reach the upstream news endpoint.
Refs: docs/AUDIT_REDESIGN.md item C4.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Reject unsupported /api/screener sector values before building the FMP query so only known sector labels reach the upstream stock screener.
Refs: docs/AUDIT_REDESIGN.md item C3.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Record the implementation commit that adds mobile-width web dashboard breakpoints.
Refs: docs/AUDIT_REDESIGN.md item D5.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Move fixed shell dimensions into responsive classes so sub-1024px layouts hide the right panel, turn the sidebar into a bottom nav, and keep dashboard content usable with adaptive grids and horizontal screener scrolling.
Refs: docs/AUDIT_REDESIGN.md item D5.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Record the implementation commit that replaces dashboard loading copy with skeleton layouts.
Refs: docs/AUDIT_REDESIGN.md item D1.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Replace plain loading text in news, research cards, and screener results with stable skeleton layouts so the dashboard holds its shape while market data requests resolve.
Refs: docs/AUDIT_REDESIGN.md item D1.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Record the implementation commit that persists CodeStrategyEditor saves through the canonical profile API.
Refs: docs/AUDIT_REDESIGN.md item B6.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Route CodeStrategyEditor saves through the canonical profile API instead of browser localStorage, carrying the active symbol plus ResearchView capital and risk defaults into an inactive saved code strategy profile.
Refs: docs/AUDIT_REDESIGN.md item B6.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Record the implementation commit that refuses unsafe code strategy backtests before execution.
Refs: docs/AUDIT_REDESIGN.md item C1.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Reject inline JavaScript strategy payloads before backtest execution, both at the API boundary and inside runBacktest, so saved profiles and direct internal calls cannot route unsandboxed code into replay handling.
Refs: docs/AUDIT_REDESIGN.md item C1.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Record the implementation commit that adds backend contract coverage for the new market data and research proxy endpoints.
Refs: docs/AUDIT_REDESIGN.md item F6.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Add static contract coverage for the dashboard market data and research proxy routes so auth, upstream URL construction, response normalization, and FMP cache usage stay guarded by the backend test gate.
Refs: docs/AUDIT_REDESIGN.md item F6.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Centralize the HomeView research profile fetch so the ticker header and research cards share one FMP profile request, preserving the B3 company-name behavior without doubling profile traffic. Wire the FMP cache regression into the backend test script and fix the stale API-contract shared import so backend tests can run through the new cache check.
Refs: docs/AUDIT_REDESIGN.md items B2, B3, and C2.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Record the ticker header implementation commit in the redesign audit table.
Refs: docs/AUDIT_REDESIGN.md items B2 and B3.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Route the ticker header watchlist and alert controls to their existing screens and replace the symbol placeholder with the research profile company name while preserving a symbol fallback.
Refs: docs/AUDIT_REDESIGN.md items B2 and B3.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Add a 30-minute in-memory cache keyed by the complete Financial Modeling Prep upstream URL so repeated profile, metrics, earnings, and screener requests do not burn the free-tier quota. The cache keeps non-OK responses out of storage so transient rate-limit or provider errors can recover on the next request.
Refs: docs/AUDIT_REDESIGN.md item C2.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Add explicit sync, collision, reporting, multi-row, and newly-discovered-work rules so independent agents can safely make incremental commits, update audit rows with implementation hashes, and push without trampling parallel streams.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Tighten the completion checklist so future agents can follow a deterministic start procedure, implementation/doc-tick commit loop, and safe parallelization model. Include one-line prompts for up to three parallel streams with explicit ownership, gates, push, and audit-update requirements.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Add an execution-focused checklist that translates the redesign and platform audit ledgers into phases, acceptance criteria, gates, and final quality bars. This gives future work a single playbook while keeping AUDIT_REDESIGN.md and AUDIT_PLATFORM.md as the status sources of truth.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Record the B1 chart indicator implementation commit in the redesign audit table now that RSI, MACD, and Bollinger toggles are wired in StockChart.
Refs: docs/AUDIT_REDESIGN.md item B1.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Compute RSI, MACD, and Bollinger Bands from the OHLCV bars already loaded by StockChart so the redesigned dashboard can expose the planned technical indicators without adding backend calls. Bollinger Bands overlay the price chart while RSI and MACD render in separate panels to preserve scale readability.
Refs: docs/AUDIT_REDESIGN.md item B1.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Record the F7/F8 test fix commit in the redesign audit table now that the tab flag cache and EntryForm alert specs are green.
Refs: docs/AUDIT_REDESIGN.md items F7 and F8.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Reset the tab feature flag cache between DOM tests so one authenticated response cannot leak into fallback cases, and make the trade execution failure spec submit a valid executable order before asserting the backend error alert. This closes the documented pre-existing web test failures and restores the full Vitest suite to green.
Refs: docs/AUDIT_REDESIGN.md items F7 and F8.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Record the final E2 lockfile commit in the audit table so the redesign backlog accurately reflects the closed CI lockfile item.
Refs: docs/AUDIT_REDESIGN.md item E2.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Regenerate the root pnpm lockfile from the web workspace so CI can resolve the redesigned dashboard dependencies without relying on stray subpackage locks. The full recursive install path is still blocked locally by the mobile private-registry tarball route, so this keeps the E2 scope focused on the web importer entries and their package snapshots.
Refs: docs/AUDIT_REDESIGN.md item E2.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Self-contained brief that any coding agent (Codex, Claude, Gemini, etc.)
running on this machine can paste in to resume the redesign+audit work.
Covers, in order:
- Required reads (the 4 source-of-truth docs in both repos)
- Environment setup (source ~/.zshrc for GITEA_NPM_TOKEN)
- Verification gates per repo (must run before AND after every change)
- 12-item priority queue with effort estimates, top to bottom
- Commit conventions (subject `<type>(<id>):`, audit-doc tick, model
Co-Authored-By line)
- Six explicit "do not" rules (don't commit incidental lockfile
regens, don't touch nomgap WIP, don't skip gates, don't bulk-fix
platform lint, don't push --force, etc.)
- When-to-stop-and-ask criteria so the agent doesn't guess on
ambiguous specs or break public API surfaces
Bottom of the file has a short copy-paste prompt that points back at
this doc, so the human just pastes 7 lines into Codex and the agent
self-bootstraps from the full brief.
Refs: docs/HANDOVER.md, docs/AUDIT_REDESIGN.md.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Self-contained hand-off note covering:
- Current health snapshot (build/typecheck/test status, with the
4 known pre-existing test failures called out so they aren't
misread as regressions)
- Critical lockfile situation (web deps in package.json but not
in root pnpm-lock.yaml — needs `pnpm install -r` from a machine
with GITEA_NPM_TOKEN; tracked as audit item E2)
- Audit doc reference (docs/AUDIT_REDESIGN.md, 52 items, the 5
cleared so far + 47 still open)
- Suggested priority order: E2 lockfile → B1 chart indicators →
B2/B3 ticker header → C1 strategy code sandboxing → C2 FMP cache
→ F6 backend tests → G mobile parity
- Backup-branch reference for emergency rollback
- Note on vendored @bytelyst/* packages and the Vite alias resolver
Companion HANDOVER.md exists in the sibling learning_ai_common_plat
repo for the platform-side audit pushed in that repo's commit 8f541c9.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Partial fix for the lockfile drift caught in the audit. The previous
session ran `npm install` inside web/ as a workaround for a Vite vendor-
resolution issue, which left three lockfiles in the wrong places:
- web/package-lock.json (npm artifact in a pnpm monorepo)
- web/pnpm-lock.yaml (per-package pnpm lockfile, also wrong)
- backend/pnpm-lock.yaml (same issue)
This commit:
- Deletes those three files from the working tree.
- Adds .gitignore entries so they can't be re-committed by accident.
- Also gitignores .claude/ (Claude Code session metadata).
What's still missing: the root pnpm-lock.yaml needs `react-router-dom`,
`@monaco-editor/react`, `@dnd-kit/{core,sortable,utilities}` added to
its resolution graph. That requires `pnpm install -r --no-frozen-lockfile`
from the repo root on a workstation with GITEA_NPM_TOKEN exported (the
mobile workspace pulls @bytelyst/* private packages from the org's
private registry; this session has no token so the install errors out
on the mobile resolve). It's a one-line follow-up — tracked in
AUDIT_REDESIGN.md item E2.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
A1+A2 — CodeStrategyEditor backtest call
Was: POST /api/backtest with { symbol, strategyCode, mode: 'code' }
Now: POST /api/backtest/run with { symbols: [s], strategyConfig: {
type: 'code', language: 'javascript', code } }
The backend route is /api/backtest/run (not /api/backtest), and
/api/backtest/run validates `symbols[]` and `strategyConfig`, not the
ad-hoc fields we were sending. Also unwraps the { success, results }
envelope the engine returns and surfaces success:false errors.
A3 — VisualRuleBuilder save shape
Was: hand-rolled fetch to /api/profiles with { name, symbol, strategyType,
visualRules, description } — backend's saveTradeProfileForUser ignored
all of that and either 400'd or persisted a half-empty row.
Now: uses the canonical createTradeProfile() helper from lib/profileApi
with the documented TradeProfilePayload shape. Visual rules go inside
strategy_config.{type:'visual', version:1, rules:[...]} so the engine
can fan out to a visual interpreter without conflicting with the
existing rule-based engine. Allocated capital + risk pct pulled from
botState.settings so the profile inherits the user's current sizing.
is_active defaults false so the user activates explicitly.
A4+A5 — RightPanel.NewsFeed auth + runtime
Was: raw fetch() to import.meta.env.VITE_TRADING_API_URL with no
Authorization header → 401 on every render in any environment that
requires auth, and prod-broken where the runtime resolver is the
only source of truth for the API base URL.
Now: uses fetchNews() from lib/marketApi which already carries the
platform Bearer token and routes through tradingRuntime.tradingApiUrl.
Adds an error state in the UI for visibility instead of silently
leaving the panel blank.
Verified: web/ tsc --noEmit passes. No behavioural change to non-affected
code paths (RightPanel portfolio summary, ResearchView other tabs, etc.).
Refs: docs/AUDIT_REDESIGN.md items A1–A5.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Catalogues every gap, bug, and miss found in the web redesign work:
- A: critical broken integrations (wrong endpoint, wrong payload, missing auth)
- B: functional gaps from the original plan (chart indicators, watchlist
buttons, company name placeholder, etc.)
- C: security & correctness (sandboxing, FMP cache, query-param leakage)
- D: UX/UI polish (skeletons, dark-tab contrast, responsive breakpoints)
- E: build/infra (1 MB bundle, lockfile drift, Monaco workers, README)
- F: test coverage (zero tests for marketApi, builders, screener, endpoints)
- G: mobile parity (none of the new features exist on mobile)
Each row has a severity tag, status box, and a slot for the fix-commit hash.
Subsequent commits will reference items by ID (e.g. fix(A1): ...).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wires the new dashboard to real market data and adds the strategy
builder & screener UIs that were stubbed in the previous commit.
Frontend (web/src/):
- lib/marketApi.ts: authenticated fetch helpers for chart bars,
market indices, news, and FMP research endpoints
- views/HomeView.tsx: StockChart now fetches live OHLCV via
fetchChartBars on symbol/period change with loading/error states;
ResearchCards replaces the static placeholder with live FMP
profile/metrics/earnings (next-earnings + last 3 historical)
- components/layout/Header.tsx: live SPY/DIA/QQQ price + change%
via fetchMarketIndices, refreshing every 60s; removed unused
static sparkline placeholder
- components/strategy/VisualRuleBuilder.tsx: drag-and-drop IF/THEN
rule composer using @dnd-kit (RSI/MACD/EMA/Price/Volume,
above/below/crosses, BUY/SELL with shares or % of capital);
saves via POST /api/profiles
- components/strategy/CodeStrategyEditor.tsx: Monaco editor with
JS strategy template; "Run Backtest" posts to /api/backtest and
renders return/win-rate/Sharpe/drawdown plus trade log
- views/ResearchView.tsx: adds "Visual Builder" and "Code Editor"
sub-tabs alongside Strategies / Signals / Backtesting
- views/ScreenerView.tsx: live FMP screener with market-cap and
sector filters, sortable columns, click-to-load-symbol routing
- index.css: light theme background; @keyframes spin for loaders
- App.dom.test.tsx: rewritten for router-based AppShell (was
asserting on the removed tab UI; fixes 5 prior failures)
Backend (backend/src/services/apiServer.ts):
- /api/chart/bars: detects crypto symbols (contains "/") and
routes to Alpaca v1beta3/crypto/us/bars; equities use
v2/stocks/{symbol}/bars with iex feed
- (existing) /api/news, /api/market/indices, /api/research/{
profile,metrics,earnings}, /api/screener proxy endpoints
Build/config:
- web/vite.config.ts: dedupe react / react/jsx-runtime /
react-router-dom so the vendored react-auth dist resolves the
same React instance (fixes "Cannot resolve react/jsx-runtime"
Rollup error)
- web/tsconfig.app.json: exclude shared/platform-clients.ts and
shared/platform-mobile.ts (mobile-only, missing RN SDK)
- web/package.json: add react-router-dom, @monaco-editor/react,
@dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities
Verification: `npm run build` in web/ → clean (✓ built in 3s);
backend tsc --noEmit → clean. Test suite: 151/155 pass; the 4
remaining failures are pre-existing (3 useTabFeatureFlags module
cache leaks, 1 EntryForm), not introduced here.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the 12-tab dashboard with a 3-column layout matching the
investing app mockup (sidebar nav, main chart area, right panel).
Web changes:
- New context/AppContext.tsx — shared botState/auth across all views
- New layout: Sidebar, Header (with market index sparklines), RightPanel
- New views: Home, Portfolio, Research, Markets, Screener, Watchlist, Alerts, Settings
- AppShell wires React Router routes to all views
- App.tsx refactored to use AppContext.Provider + BrowserRouter
Backend changes:
- 6 new proxy endpoints: /api/news, /api/market/indices,
/api/research/profile, /api/research/metrics,
/api/research/earnings, /api/screener
- config/index.ts: FMP_API_KEY env var added
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Web:
- runtime.ts: use import.meta.env (process.env is undefined in Vite browser bundle)
- tradingApiUrl local fallback: drop /api suffix (API libs already append /api/*)
- useWebSocket: deriveSocketParams() — correctly splits origin + socket path for
Caddy handle_path /invttrdg/* proxy (io(origin, {path}), not io(url-with-path))
- App.tsx: pass socket prop to AdminTab; pass connected prop to SignalsTab
- AdminTab: remove duplicate useWebSocket; accept socket as prop
- SignalsTab: connection-aware empty state message
- backtest/flags: default to disabled when VITE_BACKTEST_ENABLED unset
- EntryForm: NaN guard before live trade execution
- MarketplaceTab: null-safety on symbols.rules access
- Tests: pass socket prop to AdminTab; update empty state assertion
Mobile:
- TradingDataProvider: same deriveSocketParams fix — EXPO_PUBLIC_SOCKET_PATH
overrides auto-derived path from tradingApiUrl
- strategies: replace mock data with real GET /api/profiles + PATCH active toggle
- chat: wire to real POST /api/chat; remove hardcoded mock reply
- marketplace: fetch GET /api/marketplace-presets; USE STRATEGY calls POST /api/profiles
- settings: sign-out confirmation dialog; execution mode read-only hint;
version from expo-constants instead of hardcoded v2.3
- positions/history: empty state UI when no data
- CustomTabBar: always show tab labels (not only when focused)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add web/Dockerfile (node:20 builder + nginx:alpine, port 3085)
- Add web service to docker-compose.yml with VITE_ build args
- Create web/.env and mobile/.env pointing to api.bytelyst.com
- Backend port mapping: 4025:4018 (4018 reserved by actiontrail)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Upgrade Dockerfile base from node:18 to node:20 (fixes crypto global)
- Map host port 4025 → container 4018 (4018 taken by actiontrail)
- Join learning_ai_common_plat_default Docker network for platform service
- Switch all @bytelyst/* link: deps to registry versions
- Bump @bytelyst/llm to ^0.1.1 (adds createFallbackChain, GeminiProvider etc)
- Regenerate pnpm-lock.yaml against Gitea registry
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add bootstrap.ts as new entry point — resolves Key Vault secrets via
DefaultAzureCredential before config/index.ts is evaluated, so all
process.env reads pick up KV values (Azure CLI in dev, Managed Identity
in prod). Falls back to .env if AZURE_KEYVAULT_URL is not set.
- Define INVTTRDG_SECRETS mappings for Cosmos, Azure OpenAI, product-id
- Add AZURE_OPENAI_ENDPOINT / KEY / DEPLOYMENT to config
- aiClient: prefer AzureOpenAIProvider (AI Foundry) when Azure OpenAI
config is present; falls back to direct OpenAI if not configured
- Add @azure/identity, @azure/keyvault-secrets, @bytelyst/config deps
- Update dev/start scripts to use bootstrap.ts entry point
- Document AZURE_KEYVAULT_URL and Azure OpenAI vars in .env.example
Key Vault: https://kv-mywisprai.vault.azure.net/
Secrets prefix: invttrdg-*
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Records Cosmos DB setup (12 containers), Azure OpenAI deployments (gpt-4o,
gpt-4o-mini), Key Vault secrets, and pending work items.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Import PerplexityProvider, OpenAIProvider, GeminiProvider from @bytelyst/llm
- Use createFallbackChain() instead of manual axios fallback loop
- Remove axios and @types/axios — no longer needed
- Preserve AIClient class interface (generateAnalysis, getProviderHealth) —
no changes required in apiServer.ts or AIAnalysisRule.ts
- Fallback order still driven by config.AI.FALLBACK_LIST
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>