diff --git a/SESSION.md b/SESSION.md index e3e6a24..953f0d4 100644 --- a/SESSION.md +++ b/SESSION.md @@ -805,6 +805,7 @@ Automation execution-layer PXX remains closed and its known scope stays frozen. - Trader Mode unified shell closure passed on 2026-05-20: `/trader-mode` now resolves to the same left-menu/right-workspace `index.html` shell instead of the standalone page, with the Trader Mode section active from the route and the sidebar `Trader Mode` tree item selected. The embedded Trader Mode surface keeps the fast-read status, live readout, fast queue, freshness, focus, action buttons, after-close draft, R2 evidence, and read-only boundary controls, while the generic workbench filter bar is hidden only for this section. `trader_mode.js` is scoped so it can run inside the workbench without leaking globals into `app.js`; keyboard shortcuts and auto-refresh are active only while the Trader Mode section is visible. Remote validation passed deploy smoke over 11 endpoints, gstack browser checks on `http://192.168.3.90:8000/trader-mode` (`bodySection=trader-mode`, active nav=`Trader Mode`, sidebar present, generic controls hidden, loaded status=`Observe Only`), `run_readonly_live_analysis_smoke.py`, and `run_remote_ops_smoke.py`. Evidence screenshot saved at `output/playwright/trader-mode-unified-shell-1366x768-loaded.png`. No change was made to `execution_allowed`, `decision_support_ready`, `real_live_ready`, risk governor, trust bucket, or operator confirmation protocol. - Frontend Chinese/English i18n closure passed on 2026-05-20: added shared `/static/i18n.js`, default locale `zh-CN`, persistent `ai_ict_locale_v1`, topbar language switchers on the workbench, standalone Trader Mode fallback page, and training page. `app.js`, `trader_mode.js`, and `training.js` now route dynamic `setText` output through the same translation layer, so both static shell labels and live Trader Mode status/readout labels can switch between Chinese and English without changing backend payloads. Mutation handling was hardened to avoid self-triggered translation loops during language changes. Remote validation confirmed default Chinese with no stored locale (`lang=zh-CN`, heading `AI ICT 交易工作台`, status `仅观察`, readout `为什么不交易`) and English switching (`lang=en`, heading `AI ICT Trading Workbench`, status `Observe Only`), with no browser console errors. Evidence screenshots saved at `output/playwright/i18n-trader-mode-zh-default-1366x768.png` and `output/playwright/i18n-trader-mode-en-1366x768.png`. Local validation passed i18n/app/trader/training JS syntax checks, focused static/read-only/operator tests, script static checks, full unit discovery (`789` tests), deploy smoke over 11 endpoints, `run_remote_ops_smoke.py`, and `run_readonly_live_analysis_smoke.py`. No change was made to `execution_allowed`, `decision_support_ready`, `real_live_ready`, risk governor, trust bucket, or operator confirmation protocol. - Frontend i18n regression follow-up passed on 2026-05-20: fixed whitespace-preserving text-node translation so Chinese mode now translates top controls such as `Instrument ID`, `Timeframe`, `Limit`, `Auto Refresh`, `Execution Status`, `Session Focus`, `Trust Class`, and `Search` on `/trader-mode#overview`. The workbench active-section marker moved from `body[data-workbench-section]` to `body[data-active-workbench-section]` to avoid selector collisions with real content sections during browser automation and Trader Mode visibility checks. Added missing Chinese button labels for dynamic workbench actions including `Generate Active Plan`, `Run Watch`, `Risk Check`, `Cleanup Old Captures`, `Reconcile Real Trades`, `Cancel`, `Close`, `Sync`, note/review-packet buttons, and visual feedback buttons. Local validation passed `node --check src/web/app.js`, `node --check src/web/i18n.js`, 27 focused static/read-only/operator tests, secret static checks, script static checks, full unit discovery (`789` tests), and `git diff --check` with only LF/CRLF warnings. Live deploy completed with 11 deploy smoke endpoints; `run_remote_ops_smoke.py` and `run_readonly_live_analysis_smoke.py` passed, with `ready_for_readonly_live_analysis=true`, `must_not_trade=true`, and `submit_cancel_or_live_execution_called=false`. gstack browser automation cold-started `http://192.168.3.90:8000/trader-mode?verify=20260520b#overview`, confirmed `lang=zh-CN`, no old body selector collision, Chinese top controls, 17 left-menu pages navigable, no console errors, and clicked only safe `刷新` while skipping write/record/reconcile buttons to avoid polluting live state. Evidence screenshot saved at `output/playwright/i18n-overview-controls-zh-final-1366x768.png`. No change was made to `execution_allowed`, `decision_support_ready`, `real_live_ready`, risk governor, trust bucket, or operator confirmation protocol. +- Existing-UI i18n polish passed on 2026-05-20 without adding product features: hardened phrase replacement so short words like `no` no longer corrupt larger English words such as `not` / `enough`, then optimized Chinese labels for existing Trader Mode / duty / chart bridge / R2 evidence / runtime workbench surfaces. Remote browser audit on `/trader-mode?audit=20260520e#trader-mode` confirmed no `否t` / `e否ugh` corruption, no old English labels such as `Bridge Status`, `Exact Candle Source`, `Use Today`, `Paper Tickets`, or `Decision Support Ready`, and reduced visible English-remnant audit count from `3396` before the fix to `881` after the fix; the remaining items are mostly symbols/session names/ICT tokens/internal status keys. Validation passed `node --check src/web/i18n.js`, 27 focused static/read-only/operator tests, secret static checks, script static checks, full unit discovery (`789` tests), `git diff --check` with only LF/CRLF warnings, deploy smoke over 11 endpoints, `run_remote_ops_smoke.py`, `run_readonly_live_analysis_smoke.py`, and gstack browser console check with no errors. Evidence screenshot saved at `output/playwright/i18n-existing-ui-polish-zh-1366x768.png`. No change was made to `execution_allowed`, `decision_support_ready`, `real_live_ready`, risk governor, trust bucket, or operator confirmation protocol. - Current assisted-analysis next gate: keep R1/R2 focused on `decision_support_ready` trust/sample/quality evidence and shadow/paper/operator feedback collection. OKX trade-permission sandbox smoke is deferred until the project explicitly re-enters execution adapter or real-trading preparation. ## Exact Next Step diff --git a/TASKS.md b/TASKS.md index bc7a94f..28fee67 100644 --- a/TASKS.md +++ b/TASKS.md @@ -164,7 +164,7 @@ - [x] Live usefulness blocker recovery: root workbench split-navigation is usable, slow frontend requests time out instead of freezing the page, remote DB/compose/deploy/migration/proxy/runtime blockers were recovered, standard remote ops smoke including `unattended_harness` passed, and readonly live analysis smoke passed without enabling order submission - [x] Trader Mode unified workbench shell closure: `/trader-mode` now opens inside the same left-tree/right-workspace framework with the Trader Mode tree item active, hides the generic workbench filters only for this section, scopes Trader Mode JS to avoid app globals/hidden-section shortcuts, deploy smoke passed, remote gstack browser verification passed, readonly live analysis smoke passed, and remote ops smoke passed - [x] Frontend Chinese/English i18n closure: added shared `/static/i18n.js`, default Chinese locale, persistent language selector, dynamic `setText` translation in workbench / Trader Mode / training pages, remote browser evidence for Chinese default and English switch, full unit validation, deploy smoke, remote ops smoke, and readonly live analysis smoke -- [ ] Next trader-usefulness refinement: compress Trader Mode / watchlist language around why no trade, what to watch next, unique focus quality, stale data, and no-candidate states so the first screen answers live operator questions faster +- [x] Next trader-usefulness refinement: compress Trader Mode / watchlist language around why no trade, what to watch next, unique focus quality, stale data, and no-candidate states so the first screen answers live operator questions faster - [ ] R2 next collection action after readonly launch: wait for or surface a real executable candidate, then build shadow paper ticket / confirm paper execution / record operator feedback / add weekly review evidence without changing execution/live gates - [x] R3 OKX sandbox preflight starter implemented and deployed: signed dry-run request previews, idempotency key preview, error normalization catalog, `/trading/okx-sandbox-preflight`, live-readiness summary, cockpit surface, deploy smoke, remote ops smoke, and remote field/UI smoke - [x] R3 OKX sandbox isolated smoke tooling implemented and deployed: explicit `OKX_SANDBOX_SMOKE_EXECUTE` gate, submit/query/cancel/query/fills script, JSON artifact, proxy reuse, permission-error normalization, focused tests, full unit, deploy smoke, and remote ops smoke @@ -922,6 +922,7 @@ - [x] Trader Mode usefulness compression: first screen and watchlist now answer why not to trade, what to watch next, why the unique focus matters, whether data is stale, and what to wait for when there is no candidate; remote deploy, ops smoke, read-only live analysis smoke, and 390/1366 gstack screenshots passed - [x] First real Trader Mode R2 usage loop: recorded UI `No Trade` for blocked Candidate #4610, increased operator feedback from 1 to 2, saved after-close draft note, and verified paper ticket/execution/weekly journal counts were not fabricated - [x] Frontend i18n regression follow-up: Chinese mode now translates whitespace-padded top controls on `/trader-mode#overview`, dynamic workbench buttons such as `Run Watch` / `Risk Check` / `Reconcile Real Trades`, and active-section automation no longer collides with body attributes; deploy smoke, remote ops smoke, read-only live smoke, and 17-page gstack browser click audit passed +- [x] Existing UI i18n polish: phrase replacement no longer corrupts `not` / `enough`, existing Trader Mode/duty/chart/R2/runtime labels are more readable in Chinese, browser audit dropped visible English remnants from 3396 to 881, and deploy smoke / remote ops / readonly live smoke / gstack console check passed - [ ] R2 paper-ticket sample gate is waiting on a real executable candidate; do not fabricate paper tickets from blocked candidates - [ ] R2 operator feedback sample gate still needs at least 3 more real feedback samples (`operator_feedback_count=2/5`) - [ ] R2 weekly review visible gate still needs a real execution-derived journal/weekly review entry (`weekly_review_entry_count=0`) diff --git a/output/playwright/i18n-existing-ui-polish-zh-1366x768.png b/output/playwright/i18n-existing-ui-polish-zh-1366x768.png new file mode 100644 index 0000000..baa9d25 Binary files /dev/null and b/output/playwright/i18n-existing-ui-polish-zh-1366x768.png differ diff --git a/src/web/i18n.js b/src/web/i18n.js index 39c554b..f9dbaee 100644 --- a/src/web/i18n.js +++ b/src/web/i18n.js @@ -73,6 +73,10 @@ 'Loading workspace...': '正在加载工作台...', 'Loading Trader Mode...': '正在加载交易员模式...', 'Read-only live brief for fast intraday review.': '只读盘中速读简报,用于快速复核。', + 'Data and runtime are fresh enough for read-only analysis.': '数据和运行状态足够新鲜,可用于只读分析。', + 'Do not use Trader Mode as the primary intraday screen until the listed blockers clear.': '阻塞项清除前,不要把交易员模式作为盘中主屏。', + 'Decision assistant summary unavailable.': '决策助手摘要不可用。', + 'current_focus_matches_profile': '当前焦点匹配模板', 'Status': '状态', 'Decision Now': '当前判断', 'Next Action': '下一步', @@ -95,8 +99,22 @@ 'Runtime Online': '运行状态在线', 'Stale Seconds': '过期秒数', 'Chart Bridge': '图表桥接', + 'Bridge Status': '桥接状态', + 'Exact Candle Source': '精确K线来源', + 'External Bridge': '外部桥接', + 'Chart Providers': '图表来源', 'Duty Panel': '值班面板', + 'Use Today': '今日可用', + 'Runtime Smoke': '运行冒烟', + 'Maintenance': '维护状态', + 'Recent Errors': '最近错误', 'Focus': '焦点', + 'Focus Candidate': '焦点候选', + 'Session / Model': '时段 / 模型', + 'State': '状态', + 'Why This Focus': '为什么看它', + 'Trade Action': '交易动作', + 'Continue Review': '继续复核', 'Three Reasons': '三条原因', 'Recovery': '恢复动作', 'Record Action': '记录盘中动作', @@ -108,8 +126,18 @@ 'No action recorded in this browser session.': '当前浏览器会话尚未记录动作。', 'Optional quick note for this live brief.': '可选:为当前速读简报记录快速备注。', 'After-Close Draft': '盘后草稿', + 'Draft Status': '草稿状态', + 'Intraday Actions': '盘中动作', + 'Agreement Mix': '反馈分布', + 'Weekly Carry Forward': '周复盘延续项', 'Save Draft Note': '保存草稿备注', 'R2 Evidence Window': 'R2 证据窗口', + 'Paper Tickets': '纸面票据', + 'Paper Executions': '纸面执行', + 'Operator Feedback': '操作员反馈', + 'Weekly Review Entries': '周复盘条目', + 'Decision Support Ready': '辅助决策就绪', + 'Missing Evidence': '缺失证据', 'Boundary': '边界', 'Review Now': '立即复核', 'Observe Only': '仅观察', @@ -123,6 +151,47 @@ 'No order submission': '不提交订单', 'Not a buy/sell instruction': '不是买卖指令', 'Execution disabled': '执行已禁用', + 'Executable Candidates': '可执行候选', + 'Confirmed Tickets': '已确认票据', + 'Open Positions': '持仓加载', + 'Framework Rate': '框架执行率', + 'Out-of-Model Rate': '模型外比例', + 'Risk Violations': '风险违规', + 'symbol': '品种', + 'session': '时段', + 'data freshness': '数据新鲜度', + 'news state': '新闻状态', + 'broker state': '经纪商状态', + 'broker equity': '账户权益', + 'broker available balance': '可用余额', + 'broker open positions': '经纪商持仓', + 'broker pending orders': '经纪商挂单', + 'broker alerts': '经纪商提醒', + 'account risk state': '账户风险状态', + 'open position': '持仓', + 'kill switch': '熔断开关', + 'scheduler state': '调度状态', + 'supervisor state': '监督状态', + 'stalled tasks': '卡住任务', + 'watchdog checked': '看门狗检查时间', + 'incident journal': '事件日志', + 'incident severity': '事件级别', + 'last incident': '最近事件', + 'recommended actions': '建议动作', + 'automatic actions': '自动动作', + 'operator actions': '操作员动作', + 'p23 assertions': 'P23 断言', + 'last success': '最近成功', + 'next run': '下次运行', + 'run count': '运行次数', + 'success / failure': '成功 / 失败', + 'last error': '最近错误', + 'ready to ticket': '可建票', + 'human confirmed': '人工已确认', + 'live management load': '实盘管理负载', + 'weekly execution discipline': '周度执行纪律', + 'model drift': '模型漂移', + 'weekly count': '周度计数', 'Training': '训练', 'AI ICT Training Console': 'AI ICT 训练控制台', 'Public training cases, attempts, annotations, and progress.': '公开训练案例、尝试、标注与进度。', @@ -186,6 +255,43 @@ ['runtime ok', '运行正常'], [' ok', ' 正常'], ['market ok', '行情正常'], + ['Read-only review only', '只读复核,不执行'], + ['internal candles + external refs', '内部K线 + 外部参考'], + ['internal candles', '内部K线'], + ['internal bridge', '内部桥接'], + ['not connected', '未连接'], + ['connect real-time chart bridge when available', '可用时连接实时图表桥'], + ['compare external chart state', '对比外部图表状态'], + ['unattended harness', '无人值守巡检'], + ['read-only duty status', '只读值班状态'], + ['not checked', '未检查'], + ['draft ready', '草稿就绪'], + ['weekly entries', '周复盘条目'], + ['Trader Mode observation(s)', '交易员模式观察'], + ['operator feedback sample(s)', '操作员反馈样本'], + ['collect more executed samples', '继续收集真实执行样本'], + ['review weekly trade selection', '复核周度交易选择'], + ['review risk process', '复核风险流程'], + ['paper ticket count', '纸面票据数量'], + ['paper execution count', '纸面执行数量'], + ['weekly review entry count', '周复盘条目数量'], + ['gaps', '项缺口'], + ['Off', '关闭'], + ['freeze', '冻结'], + ['blockers', '阻塞项'], + ['degraded', '降级'], + ['enabled', '已启用'], + ['symbols', '品种'], + ['idle', '空闲'], + ['persisted', '已持久化'], + ['sources', '来源'], + ['latest', '最新'], + ['warnings', '警告'], + ['stalled', '已卡住'], + ['details', '详情'], + ['sweep into MSS into FVG retrace', '扫流动性后形成 MSS 与 FVG 回撤'], + ['wait fvg retrace confirmed', '等待 FVG 回撤确认'], + ['fvg retrace confirmed', 'FVG 回撤确认'], ['drill down only if needed', '仅在需要时下钻'], ['read-only', '只读'], ['review packet', '复核包'], @@ -249,10 +355,24 @@ let currentLocale = storedLocale(); + function escapeRegExp(value) { + return String(value).replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + } + + function replacePhrase(source, from, to) { + const phrase = String(from || ''); + if (!phrase) return source; + const escaped = escapeRegExp(phrase); + const shouldBound = /^[A-Za-z0-9]/.test(phrase) || /[A-Za-z0-9]$/.test(phrase); + if (!shouldBound) return source.replace(new RegExp(escaped, 'g'), to); + const pattern = new RegExp(`(^|[^A-Za-z0-9_])(${escaped})(?=$|[^A-Za-z0-9_])`, 'g'); + return source.replace(pattern, (_match, prefix) => `${prefix}${to}`); + } + function applyPhraseTranslations(source) { let translated = source; for (const [from, to] of zhPhrases) { - translated = translated.replaceAll(from, to); + translated = replacePhrase(translated, from, to); } return translated; } diff --git a/tests/unit/test_api_static_server.py b/tests/unit/test_api_static_server.py index e0d9927..bbfee58 100644 --- a/tests/unit/test_api_static_server.py +++ b/tests/unit/test_api_static_server.py @@ -196,6 +196,10 @@ class ApiStaticServerTests(unittest.TestCase): "Cleanup Old Captures", "'Cancel':", "'Sync':", + "Bridge Status", + "Paper Tickets", + "replacePhrase", + "[^A-Za-z0-9_]", "ai_ict_locale_v1", "ai-ict-locale-change", "const core = source.slice(leading.length",