style(obs): compact runtime health workbench copy
Some checks failed
CD Pipeline / deploy (push) Has been cancelled

This commit is contained in:
ogt
2026-07-02 20:44:38 +08:00
parent 820df1b5dd
commit 8c1c63db87
5 changed files with 59 additions and 3 deletions

View File

@@ -103,6 +103,7 @@
- 2026-07-02 起 `/observability/quality_trend` 必須採密集 AI 品質工作台:首屏使用 `data-density-guardrail="compact-quality-workbench"`,以「品質回饋、知識可靠、行動成效」短標籤承接 AI 建議可靠性hero 說明、KPI 小註與頁尾重複標題不得佔用第一層視覺,畫面先保留反饋總量、最低均分、蒸餾樣本、知識評分、使用情境反饋、根因建議與實際動作成效。
- 2026-07-02 起 `/observability/budget` 必須採密集 AI 成本工作台:首屏使用 `data-density-guardrail="compact-budget-workbench"`以「成本守門、節流狀態、知識策略」短標籤承接成本治理hero 說明、按鈕註解、KPI 小註與頁尾重複標題不得佔用第一層視覺,畫面先保留當月花費、預算使用率、預警、已節流、預算線、成本趨勢、成本集中與 AI 價格決策成效。
- 2026-07-02 起 `/observability/business_intel` 必須採密集 AI 商業工作台:首屏使用 `data-density-guardrail="compact-business-workbench"`,以「戰果追蹤、閉環成效、競品訊號」短標籤承接 AI 商業狀態hero 說明、決策節奏註解、KPI 小註、panel 說明與頁尾資料來源不得佔用第一層視覺,畫面先保留高信心未跟進、平均信心分、有效率、競品監測、外部促銷活動監控、策略族群、最近建議與閉環學習紀錄。
- 2026-07-02 起 `/observability/host_health` 必須採密集 AI runtime 工作台:首屏使用 `data-density-guardrail="compact-runtime-workbench"`,以「主機級聯、自癒閉環、成本節流」短標籤承接 AI runtime 狀態hero 說明、KPI 小註與頁尾重複標題不得佔用第一層視覺畫面先保留建議服務離線、AIOps 未解、自癒成功率、節流供應商、AI 建議服務主機、健康趨勢、自癒閉環、工具層與事件紀錄。
- 2026-07-02 起 `/ai_intelligence` 商品明細與單品作戰詳情的四格價格證據必須可測PChome 價格、MOMO 參考價、差距、可信度需以 `data-evidence` 固定,並以 `aria-label="價格證據"` 對應可掃描區塊;候選待確認或缺資料只能顯示「候選待確認 / 待補」,不得捏造價格或讓使用者打開 raw payload 才知道判斷依據。
- 2026-07-02 起 `/ai_intelligence` 必須是密集 AI 工作台不得退回大段文字說明頁首屏與明細可見內容只保留短狀態、數字、四格證據與下一步按鈕KPI note、benchmark detail、alert 副句、策略說明、decision copy、來源長句與單品 reason list 不得佔用第一層視覺。`tests/test_ai_intelligence_text_density_guardrails.py` 必須鎖住 `data-density-guardrail="compact-ai-workbench"`、短任務文案、detail meta 與 hidden explanatory copy。
- 2026-07-02 起 `/observability/overview` 也必須採密集 AI 觀測工作台:首屏以 `data-density-guardrail="compact-observability-workbench"``AI 觀測 / 風險優先 / 下一步` 與 golden signals 先呈現狀態、數字與操作入口hero lede、signal note、route desc、host meta 與資料來源長句不得佔用第一層視覺。`tests/test_observability_text_density_guardrails.py` 必須鎖住 compact marker 與 hidden explanatory copy。

View File

@@ -77,6 +77,7 @@ Baymard 的商品頁與比較 UX 研究強調:使用者需要清楚的 product
- AI quality surface rollout: `/observability/quality_trend` 已套用 compact AI quality workbench guardrails`tests/test_quality_trend_text_density_guardrails.py` 鎖住首屏短標籤、品質/知識/行動成效核心訊號與 hidden explanatory copy。
- AI cost surface rollout: `/observability/budget` 已套用 compact AI cost workbench guardrails`tests/test_budget_text_density_guardrails.py` 鎖住首屏短標籤、成本/預警/節流核心訊號與 hidden explanatory copy。
- AI business surface rollout: `/observability/business_intel` 已套用 compact AI business workbench guardrails`tests/test_business_intel_text_density_guardrails.py` 鎖住首屏短標籤、商業戰果/閉環/競品核心訊號與 hidden explanatory copy。
- AI runtime surface rollout: `/observability/host_health` 已套用 compact AI runtime workbench guardrails`tests/test_host_health_text_density_guardrails.py` 鎖住首屏短標籤、主機級聯/自癒/節流核心訊號與 hidden explanatory copy。
## 下一步 TODO 候選
@@ -92,6 +93,7 @@ Baymard 的商品頁與比較 UX 研究強調:使用者需要清楚的 product
- 已完成: `/observability/quality_trend` 首屏以「品質回饋 / 知識可靠 / 行動成效」短標籤與四個核心數字呈現 AI 建議可靠性。
- 已完成: `/observability/budget` 首屏以「成本守門 / 節流狀態 / 知識策略」短標籤與四個核心數字呈現 AI 成本治理狀態。
- 已完成: `/observability/business_intel` 首屏以「戰果追蹤 / 閉環成效 / 競品訊號」短標籤與四個核心數字呈現 AI 商業轉化狀態。
- 已完成: `/observability/host_health` 首屏以「主機級聯 / 自癒閉環 / 成本節流」短標籤與四個核心數字呈現 AI runtime 健康狀態。
## 參考來源

View File

@@ -152,6 +152,10 @@
- 首屏改成 `data-density-guardrail="compact-business-workbench"`,以「戰果追蹤 / 閉環成效 / 競品訊號」短標籤承接 AI 商業狀態。
- hero 說明、決策節奏註解、KPI 小註、panel 說明與頁尾資料來源從可見 UI 退場,保留高信心未跟進、平均信心分、有效率、競品監測、外部促銷活動監控、策略族群、最近建議與閉環學習紀錄。
- `tests/test_business_intel_text_density_guardrails.py` 已鎖住 compact marker、第一層商業訊號與 explanatory copy hidden contract。
- `/observability/host_health` 密集 AI runtime 工作台文字密度 guard 已完成:
- 首屏改成 `data-density-guardrail="compact-runtime-workbench"`,以「主機級聯 / 自癒閉環 / 成本節流」短標籤承接 AI runtime 狀態。
- hero 說明、KPI 小註與頁尾重複標題從可見 UI 退場保留建議服務離線、AIOps 未解、自癒成功率、節流供應商、AI 建議服務主機、健康趨勢、自癒閉環、工具層與事件紀錄。
- `tests/test_host_health_text_density_guardrails.py` 已鎖住 compact marker、第一層 runtime 訊號與 explanatory copy hidden contract。
已完成 / 下一步,必須照順序:

View File

@@ -20,6 +20,9 @@
.runtime-kicker { color: var(--obs-accent); font-size: .76rem; letter-spacing: .13em; text-transform: uppercase; font-weight: 800; }
.runtime-title { margin: .45rem 0 .25rem; font-family: var(--momo-font-display, "Inter", "Noto Sans TC", system-ui, sans-serif); font-size:var(--obs-title-size); letter-spacing: 0; line-height: .98; }
.runtime-subtitle { color: var(--obs-muted); max-width: 820px; line-height: 1.7; }
.runtime-mode-row { display:flex; flex-wrap:wrap; gap:.5rem; margin-top:.75rem; }
.runtime-mode { display:inline-flex; align-items:center; min-height:28px; padding:.32rem .65rem; border:1px solid var(--obs-line); border-radius:10px; background:rgba(255,255,255,.62); color:var(--obs-muted); font-size:.74rem; font-weight:850; white-space:nowrap; }
.runtime-subtitle, .runtime-signal small, .runtime-footer-copy { display:none; }
.runtime-command { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .8rem; margin-top: 1.2rem; }
.runtime-signal { padding: .95rem; border: 1px solid var(--obs-line); border-radius: 20px; background: rgba(255,255,255,.62); }
.runtime-label { color: var(--obs-muted); font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; }
@@ -58,9 +61,10 @@
{% for provider, info in throttle_state.items() %}{% if info.throttled %}{% set throttled.count = throttled.count + 1 %}{% endif %}{% endfor %}
<div class="container-fluid mt-3">
<section class="runtime-hero">
<section class="runtime-hero" data-density-guardrail="compact-runtime-workbench">
<div class="runtime-kicker"><i class="fas fa-heartbeat me-1"></i> 基礎設施生命線 · AI 建議服務 / 工具服務 / 自癒</div>
<h1 class="runtime-title">基礎設施生命線</h1>
<div class="runtime-mode-row" aria-label="AI runtime 狀態模式"><span class="runtime-mode">主機級聯</span><span class="runtime-mode">自癒閉環</span><span class="runtime-mode">成本節流</span></div>
<p class="runtime-subtitle">先看 AI 建議服務、工具服務與自癒是否正常,避免 AI 建議與比價流程中斷。</p>
<div class="runtime-command">
<div class="runtime-signal"><div class="runtime-label">建議服務離線</div><span class="runtime-value {% if down.count > 0 %}status-bad{% else %}status-good{% endif %}">{{ down.count }}</span><small class="text-muted">{{ ollama_hosts|length }} 台即時探測</small></div>
@@ -95,7 +99,7 @@
</div>
<div class="runtime-actions">
{% if h.unhealthy_mark %}<span class="badge bg-warning">30 秒異常標記</span>{% endif %}
{% if h.unhealthy_mark or not h.healthy %}<button class="btn btn-sm btn-outline-danger" onclick="triggerAutoHeal({{ h.label|tojson }})"><i class="fas fa-band-aid me-1"></i>AutoHeal</button>{% endif %}
{% if h.unhealthy_mark or not h.healthy %}<button class="btn btn-sm btn-outline-danger" onclick="triggerAutoHeal({{ h.label|tojson }})"><i class="fas fa-band-aid me-1"></i>啟動自癒</button>{% endif %}
</div>
</div>
{% endfor %}
@@ -168,7 +172,7 @@
{% if embed_queue_pending > 0 or embed_queue_failed > 0 %}<div class="alert alert-warning mt-3"><strong>Embedding 重試佇列:</strong>待處理 {{ embed_queue_pending }} 筆 · 失敗 {{ embed_queue_failed }} 筆</div>{% endif %}
<p class="text-muted mt-3"><small><i class="fas fa-robot me-1"></i>AI 基礎設施生命線</small></p>
<p class="text-muted mt-3 runtime-footer-copy"><small><i class="fas fa-robot me-1"></i>AI 基礎設施生命線</small></p>
</div>
{% set host_health_payload = {

View File

@@ -0,0 +1,45 @@
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
def test_host_health_uses_compact_runtime_workbench_contract():
template = (ROOT / "templates/admin/host_health.html").read_text(encoding="utf-8")
assert 'data-density-guardrail="compact-runtime-workbench"' in template
assert 'aria-label="AI runtime 狀態模式"' in template
assert "主機級聯" in template
assert "自癒閉環" in template
assert "成本節流" in template
def test_host_health_keeps_runtime_signals_and_hides_explanatory_copy():
template = (ROOT / "templates/admin/host_health.html").read_text(encoding="utf-8")
for marker in ["建議服務離線", "AIOps 未解", "自癒成功率", "節流供應商"]:
assert marker in template
assert ".runtime-subtitle, .runtime-signal small, .runtime-footer-copy { display:none; }" in template
assert 'class="runtime-subtitle"' in template
assert "runtime-footer-copy" in template
def test_host_health_preserves_ai_runtime_workflows_and_non_raw_wording():
template = (ROOT / "templates/admin/host_health.html").read_text(encoding="utf-8")
for marker in [
"AI 建議服務主機",
"健康趨勢摘要",
"自癒閉環 7 日",
"工具層與節流",
"成本節流狀態",
"工具服務 24h 工作量",
"最近 10 筆事件",
"最近 10 筆自癒",
"啟動自癒",
]:
assert marker in template
for forbidden in ["Runtime", "raw payload", "raw endpoint", "manual_required", "candidate queue", "資料表:"]:
assert forbidden not in template