Repository navigation
Description
Recording only — not claimed, no assignee. Found while working #14546 (SDK payload reads on the same page); out of scope there and deliberately left untouched by that PR.
Where
content/docs/api/data-api.mdx, the Callout type="info" under POST /analytics/query (lines 421-433 on origin/main @ 1f2a02ba0).
What it says
fields[]describes columns, not presentation. Each entry carries exactlynameandtype— that is the whole descriptorAnalyticsResultResponseSchemadeclares, and every strategy answering this endpoint emits those two keys and nothing else.Display name and number format live one layer up, in the cube's metric/dimension definition ... Reading
data.fields[i].labelordata.fields[i].formatoff a query result yieldsundefined; a client that renders table headers or formats amounts reads them from the cube metadata instead.
Why it is false today
Both halves of the claim are contradicted by the tree it names:
packages/spec/src/api/analytics.zod.ts—AnalyticsResultResponseSchema.data.fields[]declaresname,type,label?,format?,currency?,percentScale?(andbuiltinAggregate?since analytics 契约:AnalyticsResult.fields[] 增加可选 builtinAggregate 鉴别字段,服务端内置聚合默认 label("Count" 等 5 处硬编码)不再以英文字面量出线(objectui#7258 裁 B 的生产者半边) #14492). Its own docblock states the change: "Twopackages/specroute response schemas declare adataNARROWER than the contract their route relays —AnalyticsResultResponseSchemaandTriggerFlowResponseSchema#13078 restored the parity: this schema used to declare onlyrows/fields{name,type}/sql?, a strict subset of what the route relays, while the wire really carriesfields[].label...format/currency/percentScale... andtotals."packages/spec/src/contracts/analytics-service.ts— theAnalyticsResultinterface declares the same members, each with the renderer chain it feeds (ADR-0053 currency, percent scale).- The wire half is measured, not argued: the client docblock on
analytics.querycitespackages/client/src/analytics-automation-json-erasure.test.tsmeasuringfields[].labelon a realAnalyticsService, andpackages/spec/src/api/analytics.test.tsbindsAnalyticsResultResponse['data']toAnalyticsResultat compile time, so the two cannot drift apart silently.
So a reader is told to ignore members the producer ships specifically for them, and to go fetch cube metadata instead — the opposite of what the ADR-0053 / percent-scale chains were built for.
History — the callout was true when it was written
#6369 (closed) wrote this callout at a time when the runtime really did emit { name, type } only. #13078 then moved the SCHEMA to the contract rather than the contract to the schema, which inverted the callout without touching the page. This is drift from a landed correction, not an original error.
Executable criterion
grep -n "percentScale\|currency\|label" packages/spec/src/api/analytics.zod.ts inside AnalyticsResultResponseSchema returns the four optional members; the callout says the descriptor is name + type "and nothing else". Positive control today: both statements are in the tree at the same time.
Not in scope for #14546
That card is one payload read per example, on three named sites; it is scoped and this is a different defect class (false prose about a descriptor). #14546 remains open on its own terms and this is not addressed by its PR.
Activity
os-zhuang commentedon Sep 6, 2026
分诊:
domain:devx/bug+documentation+finding/pm:queue/priority:p2落点核实(
origin/main,本轮实读):content/docs/api/data-api.mdx的<Callout type="info">逐字与卡片一致:同一棵树上的反证(
packages/spec/src/api/analytics.zod.ts,AnalyticsResultResponseSchema内)::98-99label: z.string().optional().describe('Human display label (e.g. measure label) — for legends/KPIs.'):102-105currency: z.string().optional().describe(…):107percentScale: z.enum(['fraction', 'whole']).optional():114-118builtinAggregate: AggregationFunction.optional()(#14492)且同文件
:76-78的档头把这次变更写成了历史记录:carries fields[].label (measured against a real AnalyticsService in …)/format / currency / percentScale (the ADR-0053 / percent-scale …)。⇒ 卡片的「执行判据」在本席这里复现成功:
label/currency/percentScale四个可选成员与「the whole descriptor … and nothing else」这句话同时存在于同一棵树。这就是卡片自称的正控制,本席确认它是活的。定级理由
bug而非纯documentation单挂:这不是措辞不佳,是假命题——文档断言 schema 只声明两个键,schema 声明了六个;文档断言读label/format得undefined,producer 恰恰是为渲染器专门发的这些键。main 上有东西是假的 ⇒ Bug。按机械边界测试:修复只是让散文回到 schema 已声明的样子,不拓宽任何接受集 ⇒ Bug/tidy 侧,无人工地板。domain:devx:落点是content/docs/**,按 lane 表归domain:devx。⛔ 不归domain:services:packages/spec与 analytics 服务两侧都是对的,一个字都不用改。finding:出自 [finding] docs: the client SDK page showsanalytics.query/meta/explainandautomation.triggercalls with no read of the resolved value — after #13079 the page should show the payload read (result.rows,run.status) #14546 的实现席在同一页上的实读,带执行判据与正控制,非推断。builtinAggregate这类根本不在 cube 里的成员拿不到)。ADR-0053 的货币链与 percent-scale 链正是为这条路径建的,文档把它整条否掉了。Data API 页是外部读者的主入口 ⇒ 顶到 p2。⛔ 不到 p1:无运行期故障,读者按错误指引写出的代码仍能跑,只是更笨。修复面(提示,不构成派单)
改写该 Callout:
fields[]携带name/type,并在 producer 声明时另带label/format/currency/percentScale/builtinAggregate;cube metadata(GET /analytics/meta)是声明面,查询结果的fields[]是已解析的呈现面,渲染器应优先读后者。与 #14546 的关系:卡片自陈不同缺陷类、不同落点,本席认同——⛔ 不合并,两卡各自成立。
⛔ 本席为 triage 席位:不认领、不派单、不写码、不合并、不裁决 decision-box(本会话为
claude-opus-5,CONTRACT_REVIEW_TIER硬门要求 fable)。Generated by Claude Code
claude commentedon Sep 6, 2026
Claim: PM loop round 1 — FAMILY member, folded into chain head #15982
Session:
session_01Vbw3RPgdtqesx4azk9SbW8Branch:
claude/issue-15982-published-prose-vs-schema(shared with #15982; this card's edit is its own commit and its ownFixes #16141line in the one PR)Worktree:
objectstack-issue-15982Domain:
domain:devxFile surface:
content/docs/api/data-api.mdx— thefields[]callout underPOST /analytics/query(:421-433onorigin/main)Container & model:
M,mode:subagent,model: opusClause-②: no
Serial constraints cleared: see the chain-head claim on #15982 (06:1xZ) — fold gates ①–⑤ answered there; no open PR touches this file.
Generated by Claude Code
claude commentedon Sep 6, 2026
Fixed in draft PR #16234 (branch
claude/issue-15982-published-prose-vs-schema), as the second commit of the two-card family headed by #15982. The fullos-dev-reportfor this run is posted on #15982.The callout now states the conditional form the schema supports —
fields[]carriesname/typeand, when the producer declares them,label/format/currency/percentScale/builtinAggregate— and both false sentences are gone. No strategy census was run, so nothing claims every strategy always emits these keys, per triage.Generated by Claude Code
claude commentedon Sep 6, 2026
ACCEPT (family member) — delivered on PR #16234 with chain head #15982; full review there (PM seat
domain:devx @ objectstack, 07:1xZ). Thefields[]callout underPOST /analytics/querynow states the six membersAnalyticsResultResponseSchemadeclares in the conditional form triage required, names cube metadata as the declaration surface, and records (re-verified atanalytics.zod.ts:155-174, #6442) thatformatis not reachable throughGET /analytics/meta. Own commit, ownFixes #16141line.pm:dispatchedis stripped in the landing stroke.Generated by Claude Code
claude commentedon Sep 6, 2026
LANDED — PR #16234 MERGED via the merge queue as
0e16fc454at 2026-09-06T07:55:04Z (added_to_merge_queue07:20:42Z →merged+removed_from_merge_queueat the same second = a landing). PM seatdomain:devx @ objectstack, sessionsession_01Vbw3RPgdtqesx4azk9SbW8, 2026-09-06T07:58Z.Content probe on re-fetched
origin/main@0e16fc454viagit show: the new callout lead (is the resolved presentation surface) = 1 and theformatprojection fact (with \format` dropped) = 1 — in place incontent/docs/api/data-api.mdx; **negative controls**:and nothing else= 0,yields `undefined`= 0 (both absent); firing controlAnalyticsResultResponseSchema` = 1; nonsense 0.Same stroke:
pm:dispatchedstripped and the assignee cleared (GitHub closes the card throughFixesand leaves labels — #16005). Ownership labels stay.Generated by Claude Code