diff --git a/apps/presentation/dashboard/src/features/personal-workspace/goal-research-progress.css b/apps/presentation/dashboard/src/features/personal-workspace/goal-research-progress.css
index 14341f069e..b0dff8caf6 100644
--- a/apps/presentation/dashboard/src/features/personal-workspace/goal-research-progress.css
+++ b/apps/presentation/dashboard/src/features/personal-workspace/goal-research-progress.css
@@ -95,11 +95,12 @@
.research-progress-basis dt, .research-usage-basis dt { color: var(--pw-muted); }
.research-progress-basis dd, .research-usage-basis dd { margin: 0; }
.research-progress code { font: inherit; font-family: var(--font-mono); }
-.research-progress-values { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; margin-block: 16px; }
+.research-progress-values { display: grid; grid-template-columns: minmax(0, 1.5fr) repeat(2, minmax(0, 1fr)); gap: 16px; margin-block: 16px; }
.research-progress-values > div { min-width: 0; }
.research-progress-values dt { font-size: var(--text-body); color: var(--pw-muted); }
.research-progress-values dd { margin: 8px 0; font-size: var(--text-title); font-weight: 600; font-variant-numeric: tabular-nums; }
.research-progress-values dd > span { font-size: var(--text-body); font-weight: 400; color: var(--pw-muted); }
+.research-input-breakdown { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-block-start: 8px; font-size: var(--text-body); font-weight: 400; color: var(--pw-muted); }
.research-usage { padding-block: 12px 8px; }
.research-usage-heading { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.research-progress .research-usage p, .research-progress .research-source-detail p { font-size: var(--text-body); margin-block: 8px; }
@@ -141,6 +142,7 @@
.research-native-reading { gap: 12px 16px; }
.research-native-reading > .research-native-best { flex-basis: 100%; margin-inline-end: 0; }
.research-progress-values { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
+ .research-input-reading { grid-column: 1 / -1; }
.research-analysis-values { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.research-usage-basis { grid-template-columns: 1fr; gap: 4px; }
.research-progress-basis dd, .research-usage-basis dd { margin-bottom: 8px; }
diff --git a/apps/presentation/dashboard/src/features/personal-workspace/goal-research-progress.tsx b/apps/presentation/dashboard/src/features/personal-workspace/goal-research-progress.tsx
index 440765b04d..19158d44b0 100644
--- a/apps/presentation/dashboard/src/features/personal-workspace/goal-research-progress.tsx
+++ b/apps/presentation/dashboard/src/features/personal-workspace/goal-research-progress.tsx
@@ -284,11 +284,14 @@ export function ResearchProgress({pack: p, packs, selectedId, zh, onSelect, onCi
{measured?.applicability === "historical" ?
{zh ? "历史捕获:用量来源已变化或不可读,当前用量未核验。" : "Historical capture: the usage source changed or is unavailable; current usage is unverified."}
: null}
{!usage ? {zh ? "尚无用量捕获;未测,不记零。" : "No usage capture; unmeasured, not zero."}
: null}
{usage ? {usage.method === "codex_observed_session_counters_v1" ? (zh ? "仅已观测计数;未记录的请求、后续用量、继承前缀、设置、评测和操作者成本未知。" : "Observed counters only. Unrecorded requests, later usage, inherited prefixes, setup, evaluation and operator costs remain unknown.") : (zh ? "仅本次完整捕获;继承前缀、设置、原生评测、操作者及后续未完成轮不包含。" : "This complete capture only; inherited prefixes, setup, native evaluation, operator work and later incomplete Turns are excluded.")}
: null}
+ {zh ? "会话输入包含缓存与未缓存输入;下方全部请求使用独立核对口径,是结构输入占比的分母,不能与会话计数相加。" : "Session input includes cached and uncached input. All-request input below uses the separately reconciled basis and is the input-share denominator; do not add it to session counters."}
- - {zh ? "捕获窗口跨度" : "Captured elapsed time"}
- {usage ? duration(usage.elapsed_seconds) : "—"}
- - {zh ? "未缓存输入" : "Uncached input"}
- {usage ? number(usage.uncached_input_tokens) : "—"} tokens
+ - {zh ? "会话输入" : "Session input"}
- {usage ? number(usage.input_tokens) : "—"} tokens
+ {usage ? {zh ? "缓存" : "Cached"} {number(usage.cached_input_tokens)}{zh ? "未缓存" : "Uncached"} {number(usage.uncached_input_tokens)} : null}
+
- {zh ? "输出(含推理)" : "Output (includes reasoning)"}
- {usage ? number(usage.output_tokens) : "—"} tokens
+ - {zh ? "捕获窗口跨度" : "Captured elapsed time"}
- {usage ? duration(usage.elapsed_seconds) : "—"}
{incomplete ?
{zh ? "末轮未完成" : "Final Turn incomplete"}
@@ -314,7 +317,9 @@ export function ResearchProgress({pack: p, packs, selectedId, zh, onSelect, onCi
{coverage?.status === "verified" ? <>
{number(coverage.unique_requests)} {zh ? "次请求" : "requests"} · {number(coverage.compaction_requests)} {zh ? "次上下文压缩" : "context compactions"}
- - {zh ? "全部请求 · 未缓存输入" : "All requests · uncached input"}
- {number(coverage.all_requests.input_tokens - coverage.all_requests.cached_input_tokens)} tokens
+ - {zh ? "全部请求 · 输入" : "All requests · input"}
- {number(coverage.all_requests.input_tokens)} tokens
+ {zh ? "缓存" : "Cached"} {number(coverage.all_requests.cached_input_tokens)}{zh ? "未缓存" : "Uncached"} {number(coverage.all_requests.input_tokens - coverage.all_requests.cached_input_tokens)}
+
- {zh ? "全部请求 · 输出" : "All requests · output"}
- {number(coverage.all_requests.output_tokens)} tokens
- {zh ? "其中压缩 · 未缓存输入" : "Of which compaction · uncached input"}
- {number(coverage.compaction.input_tokens - coverage.compaction.cached_input_tokens)} tokens
- {zh ? "其中压缩 · 输出" : "Of which compaction · output"}
- {number(coverage.compaction.output_tokens)} tokens
diff --git a/examples/personal-workspace-browser/evidence/input-denominator-reading/after-desktop.png b/examples/personal-workspace-browser/evidence/input-denominator-reading/after-desktop.png
new file mode 100644
index 0000000000..d5373e75c2
Binary files /dev/null and b/examples/personal-workspace-browser/evidence/input-denominator-reading/after-desktop.png differ
diff --git a/examples/personal-workspace-browser/evidence/input-denominator-reading/after-phone-counters.png b/examples/personal-workspace-browser/evidence/input-denominator-reading/after-phone-counters.png
new file mode 100644
index 0000000000..cc6c0ba3fd
Binary files /dev/null and b/examples/personal-workspace-browser/evidence/input-denominator-reading/after-phone-counters.png differ
diff --git a/examples/personal-workspace-browser/evidence/input-denominator-reading/after-phone-en.png b/examples/personal-workspace-browser/evidence/input-denominator-reading/after-phone-en.png
new file mode 100644
index 0000000000..ceaa8aa41f
Binary files /dev/null and b/examples/personal-workspace-browser/evidence/input-denominator-reading/after-phone-en.png differ
diff --git a/examples/personal-workspace-browser/evidence/input-denominator-reading/after-phone.png b/examples/personal-workspace-browser/evidence/input-denominator-reading/after-phone.png
new file mode 100644
index 0000000000..dcd5e86fd9
Binary files /dev/null and b/examples/personal-workspace-browser/evidence/input-denominator-reading/after-phone.png differ
diff --git a/examples/personal-workspace-browser/evidence/input-denominator-reading/before-desktop.png b/examples/personal-workspace-browser/evidence/input-denominator-reading/before-desktop.png
new file mode 100644
index 0000000000..0fc2313299
Binary files /dev/null and b/examples/personal-workspace-browser/evidence/input-denominator-reading/before-desktop.png differ
diff --git a/examples/personal-workspace-browser/evidence/input-denominator-reading/before-phone.png b/examples/personal-workspace-browser/evidence/input-denominator-reading/before-phone.png
new file mode 100644
index 0000000000..2470925930
Binary files /dev/null and b/examples/personal-workspace-browser/evidence/input-denominator-reading/before-phone.png differ
diff --git a/examples/personal-workspace-browser/evidence/input-denominator-reading/first-desktop.png b/examples/personal-workspace-browser/evidence/input-denominator-reading/first-desktop.png
new file mode 100644
index 0000000000..3080d50161
Binary files /dev/null and b/examples/personal-workspace-browser/evidence/input-denominator-reading/first-desktop.png differ
diff --git a/examples/personal-workspace-browser/evidence/input-denominator-reading/first-phone.png b/examples/personal-workspace-browser/evidence/input-denominator-reading/first-phone.png
new file mode 100644
index 0000000000..4c4ff040b5
Binary files /dev/null and b/examples/personal-workspace-browser/evidence/input-denominator-reading/first-phone.png differ
diff --git a/examples/personal-workspace-browser/research-history.mjs b/examples/personal-workspace-browser/research-history.mjs
index f7df7f36c4..952415c536 100644
--- a/examples/personal-workspace-browser/research-history.mjs
+++ b/examples/personal-workspace-browser/research-history.mjs
@@ -1219,7 +1219,9 @@ Path(sys.argv[1]).write_text(json.dumps({'goal_id':goal,'display_name':'Syntheti
await analysisClosed();
await page.setViewportSize({width: 1280, height: 900});
await progress.locator('.research-progress-basis > summary').click();
- assert.equal(await progress.locator(".research-progress-values dd").filter({hasText: /^100 tokens$/}).count(), 1, "Uncached input is shown without charging cache twice");
+ const inputReading = progress.locator('.research-input-reading');
+ assert.match(await inputReading.innerText(), /1,?100.*1,?000.*100/s,
+ 'Session input includes cache, with cached and uncached subsets kept distinct');
// Actual observations precede provenance; details and help remain operable.
assert.equal(await progress.locator('.research-usage-detail').evaluate(e => e.open), false);
assert.doesNotMatch(await progress.innerText(), /codex_complete_session_counters_v1/);