feat(spec): analytics authorable strictness + the data/ mixed(p) verdicts (#4001 data batch D) - #8695
Conversation
…#4001 batch D) - data/analytics.zod.ts: all 8 sites strictObject (cube family + query family); the live behaviour change is the nested timeDimensions[] item that used to ride through the already-strict /analytics/query wrapper - seed-loader.zod.ts: re-verdicted wire (producer enumeration — all framework code; the authored half of seeding is SeedSchema, already strict) - field-value.zod.ts: re-verdicted open (ADR-0104 record-data value contracts) - ledger prose + regenerated counts (data/ unresolved 22 -> 0, strip 132 -> 124) - semantic migration entry under protocol-18 + changeset (minor + BREAKING + ADR-0087 disposition, the #8666 precedent) - batchd pin test: doors, per-carrier closures, alias claims, wrapper composition, deliberate non-closures Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E5tUwGM3LQoqErTfkvRW7W
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
📓 Docs Drift CheckThis PR changes 1 package(s): 106 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
⛔ 7 release-owned page(s) also reference the affected code. These are read-only:
|
Part of #4001 (data batch D — the per-schema read for the 22 unresolved
mixed (p)sites; the campaign umbrella stays open).What this is
The dispatch's mandated per-site door measurement (carrier + BFS with positive AND negative controls in the same run + parse-site probes) over the whole
data/remainder:seed-loader.zod.ts(12),analytics.zod.ts(8),field-value.zod.ts(2). Pre-change ledger regeneration confirmed zero drift (the freshness proof), so the 22-site premise held; the verdicts split three ways:analytics.zod.ts— authorable on both halves, all 8 sites CLOSEDdefineCube()parses an author literal (the showcase example authors through it) anddefineStack({ analyticsCubes })carries every cube through the stack parse. BFS from the 26 metadata-type roots +ObjectStackSchema(6689 nodes): the cube family resolves REACHABLE, withObjectSchemaas positive control, a fresh uncarried shape as negative control, and a synthetic-carrier flip proving the walker sees carriers — same run./analytics/query's top level has been strict since /analytics/query 的请求体形状取决于装没装 service-analytics(降级 shim 收信封、真引擎收裸 AnalyticsQuery),且发错形状静默生成空 SELECT #3878 (AnalyticsQueryRequestSchema), but top-level strictness does not recurse. Measured onmain:timeDimensions: [{ dimension, granuarity: 'day' }]rode through the strict wrapper with the typo silently stripped — the query bucketed the whole range as one group under an ordinary 200. The nested item now rejects with the rename in the message.publik, a metrictitle, a joinrelationshipp(falling back tomany_to_one— a different join than authored, under a successful parse),refreshKey.sqll— all parsed clean and vanished. All reject now, each with a curated prescription; every alias claim is anchored to the declaration that makes it true and pinned in the batch test.CubeRegistry.registertakes typed objects without a parse;analytics_cuberesolves nogetMetadataTypeSchemaentry sosaveMetaItemnever parses one; artifact ingest parses the compiled definition BEFOREapplyProtectionstamps). Pinned in the test so the day that flips, the envelope question is re-asked.data-objectstacksends only declared keys (cube/measures/dimensions/where) to/analytics/query.seed-loader.zod.ts— re-verdictedwire(12 sites; the provisional "authored" half did not survive measurement)The old split claimed
SeedLoaderConfig/SeedIdentity/ReferenceResolutionare authored. Enumerated: every producer is framework code —runtime/app-plugin.ts×3,runtime/domains/packages.ts,metadata-protocolapplySeedBodies+validate(),cloud-connectionmarketplace install — all parsing config LITERALS written in code.ReferenceResolutionis BUILT bybuildDependencyGraphfrom field metadata;SeedIdentityis server-constructed by declaration. The authored half of seeding isSeedSchema(already strict, a registered type) — it enters only as theseeds[]VALUE, so author typos in seed files are rejected TODAY through the nested strict parse. Internal service contract (ISeedLoaderService), same class asdata-engine.zod.ts. No schema change.field-value.zod.ts— re-verdictedopen(2 sites; the row's own prediction, now measured)LocationValueSchema/AddressSchemaare ADR-0104 record-data VALUE contracts: consumed validation-only (record-validatorstores the value verbatim —.stripnever actually strips anything), written by end users / devices / geocoders whose extras are legitimate data (heading/speedon a GPS payload,districton a geocoded address — exactly the openness siblingFileValueSchemadeclares withz.looseObject). Enforcement posture belongs to ADR-0104's evidence-gated warn-first rollout, not this ratchet. One caveat recorded rather than glossed: alocation/addressfield's authoreddefaultValueliteral validates through the same contract, so an author's extra key there is admitted silently — splitting the contract strict-for-defaults/open-for-records would fork ADR-0104's one contract. No schema change.Ledger
Prose verdicts hand-written; all numbers via
gen:strictness-ledgerregeneration (zero pre-change drift, regenerated post-change):data/unresolved 22 → 0,data/strip 90 → 82, global strip 132 → 124, global authorable strip stays 2 (the deliberately parkedFormFieldBaseSchema+ heldIndexSchema).analytics.zod.ts's remaining-strip row leaves the map by reaching zero (the reverse pin demands the deletion).check:strictness-ledgergreen AND reverse-verified in the predicted direction (Class cell flipped back → gate red, counts not current → restored from commit → green).Post-cut changeset clause (the PR #8666 precedent)
Acceptance-narrowing after the v17.0.0 cut: changeset
minor+ BREAKING body annotation + ADR-0087 disposition marker (registered analytics-authorable-unknown-keys-refused) + semantic migration entry under the protocol-18 step (entry FILE added;registry.tsregenerated viagen:migration-registry, never hand-edited).Verification
See the report comment on #4001 for the full command list with evidence; headline: spec suite green at HEAD; consumer pins green with zero fixture edits (service-analytics 1675, driver-memory 752, runtime dispatcher+seed pins 341, rest analytics 30, objectql aggregation/having/meta 142);
objectstack validategreen on showcase (its real authored cube is the positive control);check:generated13/13; gate union derived from the actual diff viadispatch-gates.mjsand run locally — final HEAD quoted in the report comment.Generated by Claude Code