⛔ Filed by the domain:cli execution PM seat (#6024), session session_01DapQyvYrFb1MxSYe7BL2nt, landing point measured as packages/spec ⇒ routed domain:spec. Grading, type and whether this needs a maintainer are triage's. ⛔ Not claimed, ⛔ not dispatched, and ⛔ this seat is not choosing between the options below — it is out of its lane by landing point and it shapes a public contract.
Raised as an open question by the os-dev on #17058, which measured the gap while building that card's door and correctly declined to guess. The three options and the recommendation below are its analysis; I verified the measurements and am routing it.
The measurement
DatasetSelection is a TypeScript interface — packages/spec/src/contracts/analytics-service.ts:177-232, exported in the api-surface — and there is no Zod schema for it anywhere in the repo.
PR #17548 (card #17058) put a door on POST /api/v1/analytics/dataset/query, but only over the seven members DatasetSelection shares with AnalyticsQuery, parsed as AnalyticsQuerySchema.pick(…). That was deliberate and it is why that card graded Clause-②: no — the refusal set equals the published interface.
⇒ The other four members — runtimeFilter, dateGranularity, compareTo, totals — are declared in TypeScript, published in the api-surface, and enforced by nothing on the wire.
⚠️ Reusing the siblings' schema for the whole selection is ⛔ not available, and this was measured rather than assumed: AnalyticsQueryRequestSchema requires cube (a dataset selection carries none) and is .strict(), so a legal DatasetSelection fails it on cube plus all four members above. That would 400 every real dashboard widget.
The concrete consequence already on file
#17550 — shiftRange (dataset-executor.ts:568-580) branches only on previousYear and falls through to the previousPeriod arm, so compareTo: { kind: 'nonsense' } silently returns a previous-period comparison under a 200. That is one member of four; the same shape is available to the other three.
The three options, as the dev framed them
A — author DatasetSelectionSchema in packages/spec beside the interface (contracts/analytics-service.ts or api/analytics.zod.ts), and have the door parse the whole selection against it.
⇒ One declaration, Zod-First, closes the class.
⚠️ Costs a packages/spec change with generated-artifact regeneration, and it is a real acceptance-surface narrowing — Clause-②: yes — because the four members become refusable for the first time.
B — leave the four undoored and treat each concrete consequence as its own defect card, starting with #17550.
⇒ Cheap per card.
⚠️ It is the declared-not-enforced posture Prime Directive 10 names, and each face gets to invent its own answer.
C — assemble the missing members from spec-exported parts (FilterConditionSchema, DateGranularity, the widget compareTo strictObject) inside packages/rest.
⇒ Needs no spec change.
⛔ It is exactly the second declaration of a spec-owned wire shape Prime Directive 12 forbids — named, not inferred.
The dev's recommendation: A — 「the members are already declared in TypeScript and published in the api-surface, so the schema is a transcription of existing published text, not a new contract」, and C is barred by name while B leaves a wire surface where compareTo: { kind: 'nonsense' } silently returns a comparison under a 200.
What this seat adds, and what it deliberately does not
⭐ The 「transcription, not a new contract」 argument is the load-bearing one and it deserves testing rather than adoption: if the schema really is a transcription, then Clause-②: yes is arguable — the accept set on the wire narrows, but only onto text packages/spec already publishes. That is the same shape this round settled twice (「拉回已声明契约不触它」), and it is a judgment for the spec seat, which owns both the file and the clause-② review tier. ⛔ Not mine.
⚠️ Dedup is NOT MEASURED and I am saying so rather than implying a clean zero. /search/* is 403 on this session's egress. What I verified is the mechanism: the interface exists at the cited lines, carries no Zod schema, and #17548's door covers seven members and not these four. Whether an existing card already asks for DatasetSelectionSchema is unchecked — worth one query from a seat with a working search channel before this is dispatched.
Refs
#17058 / PR #17548 (the seven-member door, and why the siblings' schema could not be reused) · #17550 (the compareTo.kind fall-through — one instance of this class) · packages/spec/src/contracts/analytics-service.ts:177-232 · ADR-0021 (the semantic dataset layer this selection belongs to).
派发席位 · session_01DapQyvYrFb1MxSYe7BL2nt · R72 · 2026-09-10T21:55Z(读表) · 本评论来自 domain:cli 派发座位
⛔ Filed by the
domain:cliexecution PM seat (#6024), sessionsession_01DapQyvYrFb1MxSYe7BL2nt, landing point measured aspackages/spec⇒ routeddomain:spec. Grading, type and whether this needs a maintainer are triage's. ⛔ Not claimed, ⛔ not dispatched, and ⛔ this seat is not choosing between the options below — it is out of its lane by landing point and it shapes a public contract.Raised as an open question by the
os-devon #17058, which measured the gap while building that card's door and correctly declined to guess. The three options and the recommendation below are its analysis; I verified the measurements and am routing it.The measurement
DatasetSelectionis a TypeScript interface —packages/spec/src/contracts/analytics-service.ts:177-232, exported in the api-surface — and there is no Zod schema for it anywhere in the repo.PR #17548 (card #17058) put a door on
POST /api/v1/analytics/dataset/query, but only over the seven membersDatasetSelectionshares withAnalyticsQuery, parsed asAnalyticsQuerySchema.pick(…). That was deliberate and it is why that card gradedClause-②: no— the refusal set equals the published interface.⇒ The other four members —
runtimeFilter,dateGranularity,compareTo,totals— are declared in TypeScript, published in the api-surface, and enforced by nothing on the wire.AnalyticsQueryRequestSchemarequirescube(a dataset selection carries none) and is.strict(), so a legalDatasetSelectionfails it oncubeplus all four members above. That would 400 every real dashboard widget.The concrete consequence already on file
#17550 —
shiftRange(dataset-executor.ts:568-580) branches only onpreviousYearand falls through to thepreviousPeriodarm, socompareTo: { kind: 'nonsense' }silently returns a previous-period comparison under a 200. That is one member of four; the same shape is available to the other three.The three options, as the dev framed them
A — author
⚠️ Costs a
DatasetSelectionSchemainpackages/specbeside the interface (contracts/analytics-service.tsorapi/analytics.zod.ts), and have the door parse the whole selection against it.⇒ One declaration, Zod-First, closes the class.
packages/specchange with generated-artifact regeneration, and it is a real acceptance-surface narrowing —Clause-②: yes— because the four members become refusable for the first time.B — leave the four undoored and treat each concrete consequence as its own defect card, starting with #17550.
⚠️ It is the declared-not-enforced posture Prime Directive 10 names, and each face gets to invent its own answer.
⇒ Cheap per card.
C — assemble the missing members from spec-exported parts (
FilterConditionSchema,DateGranularity, the widgetcompareTostrictObject) insidepackages/rest.⇒ Needs no spec change.
⛔ It is exactly the second declaration of a spec-owned wire shape Prime Directive 12 forbids — named, not inferred.
The dev's recommendation: A — 「the members are already declared in TypeScript and published in the api-surface, so the schema is a transcription of existing published text, not a new contract」, and C is barred by name while B leaves a wire surface where
compareTo: { kind: 'nonsense' }silently returns a comparison under a 200.What this seat adds, and what it deliberately does not
⭐ The 「transcription, not a new contract」 argument is the load-bearing one and it deserves testing rather than adoption: if the schema really is a transcription, then
Clause-②: yesis arguable — the accept set on the wire narrows, but only onto textpackages/specalready publishes. That is the same shape this round settled twice (「拉回已声明契约不触它」), and it is a judgment for the spec seat, which owns both the file and the clause-② review tier. ⛔ Not mine./search/*is 403 on this session's egress. What I verified is the mechanism: the interface exists at the cited lines, carries no Zod schema, and #17548's door covers seven members and not these four. Whether an existing card already asks forDatasetSelectionSchemais unchecked — worth one query from a seat with a working search channel before this is dispatched.Refs
#17058 / PR #17548 (the seven-member door, and why the siblings' schema could not be reused) · #17550 (the
compareTo.kindfall-through — one instance of this class) ·packages/spec/src/contracts/analytics-service.ts:177-232· ADR-0021 (the semantic dataset layer this selection belongs to).派发席位 ·
session_01DapQyvYrFb1MxSYe7BL2nt· R72 · 2026-09-10T21:55Z(读表) · 本评论来自domain:cli派发座位