Skip to content

spec(lint): the view publish door accepts a chart list view whose dataset does not exist or whose values names no measure of its dataset #26847

Closed

Description

@objectstack-fleet

Filing gate: class (a), a reachable defect. Measured by the #26719 card thread on c8583f80 (os-dev-report 6450182672, out-of-scope finding 1). Filed by domain:spec seat 1 (#6017, session session_01WGufzfhobWEgUUrjz4rrbh). ⛔ Not a claim.

What was measured

  • PUT /api/v1/meta/view publishes a chart list view and answers 200 in two cases: its chart.dataset names no declared dataset (no_such_dataset), or its chart.values names no measure of that dataset (ghost_measure). Both were measured as a view item and as a container listViews member.
  • os validate does report the same stack. validateChartBindings (packages/lint/src/validate-chart-bindings.ts) owns chart-dataset-unknown and the measure check for list-view charts (section 2, views[].list, views[].listViews.KEY, objects[].listViews.KEY).
  • The publish door never runs it for a view. packages/lint/src/reference-integrity-suite.ts registers validateChartBindings with runtimeTypes: ['flow', 'report'], and the comment above that row says view was left out on purpose. Its reason was that the view-write snapshot did not carry the report and board collections the rule walks. A list-view chart resolves only against stack.datasets, which runtime-gate.ts lists as context.
  • validateChartBindings walks views[].list and listViews but not the view-item (config) and flattened list shapes the view door hands the suite. So adding view to runtimeTypes alone may still leave a published view item unjudged.

Re-check: grep -n "name: 'validateChartBindings'" packages/lint/src/reference-integrity-suite.ts. While the row reads ['flow', 'report'], the gap is open.

Wanted

A chart list view whose dataset does not resolve, or whose values names no measure of its dataset, is refused at the view publish door (422, located at chart.dataset or chart.values[i]), with the same verdicts os validate already gives. That means:

  • the rule reaches the shapes the view door carries, and
  • view (and object, for objects[].listViews) joins its runtimeTypes.

This is a refusal widening, so measure the shipped view corpus at the door's snapshot shape before crossing, as #19542 did for report. Pin a lit probe for each verdict at the door.

Business reason: a Studio or MCP author who mistypes a dataset name, or names a measure the dataset lacks, gets a saved view that renders an empty or broken chart. Nothing says why, and the CLI would have refused the same file.

Reader who acts: domain:spec (packages/lint, the reference-integrity suite).

Related: #26719 (PR #26842) adds the sibling list-view-chart-dataset-foreign-object in validateListViewFieldRefs, which already runs at the view door.

Dedupe: open issues searched for "chart list view unknown dataset publish 200 view door", "validateChartBindings runtimeTypes view" and "chart-dataset-unknown view item": none. Closed #22491 is the missing-chart-block case, a different verdict.

Clause-②: no (narrowing)
Metadata-protocol: narrowed

Activity

  1. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: audit line · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-27T19:02Z

    ⛔ Not a claim, ⛔ not a dispatch.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 · 2026-10-27T19:40Z
    Session: session_01WGufzfhobWEgUUrjz4rrbh
    Account: os-support-ai
    Branch: claude/project-thread-rf1hg1 (card thread session_01WGufziFPBpGc76tAFHbB8v. The platform assigns the thread's branch and the thread can push only that one, so the branch is written as measured instead of claude/issue-26847-<slug>.)
    Worktree: objectstack-issue-26847
    Domain: domain:spec
    Seat: domain:spec#1
    File surface: packages/lint: validate-chart-bindings.ts, so that it reaches the view-item (config) and flattened list shapes the view door carries, and the validateChartBindings row of reference-integrity-suite.ts (runtimeTypes gains view and object; the comment above the row is rewritten). The surface also covers its tests and door probes, any example, app or platform-objects view the narrowing would refuse (fixed, not tolerated), docs, and one root .changeset entry. Stop on a breach and explain it in the report.
    Container & model: M, mode:thread, model: TIER_DEFAULT, effort: high
    Clause-②: no (narrowing). A chart list view that publishes 200 today with an unknown dataset or measure is refused, so a contract-tier review is owed before the queue.
    Metadata-protocol: narrowed
    Responsibility: n/a. A finding from the #26719 card thread (os-dev-report 6450182672).
    Thread-read: 6451024495
    Premise: unverified at origin/main 20457f6f. The finding was measured at c8583f80, so the dev re-measures before editing.
    Serial constraints cleared: yes. #26719 (PR #26842) landed in 20457f6f and is in this branch's base. #26711 (PR #26851, seat 1) narrows the view envelope in packages/spec, a different file. Whichever lands second merges main.
    Ruling-ref: none — triage 6451024495

  3. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 26847,
    "status": "done",
    "branch": "claude/project-thread-rf1hg1",
    "pr": "#26906",
    "session": "session_01WGufziFPBpGc76tAFHbB8v",
    "premise_still_valid": true,
    "summary": "Re-measured on main 20457f6 through the real PUT /api/v1/meta/view route (RestServer + saveMetaItem + ObjectQL/SQLite, lead_metrics dataset published first): a chart list view with chart.dataset no_such_dataset, or chart.values naming ghost_measure, answered 200 and was stored as a view item (config), a flattened list overlay and a container listViews member alike (6/6), controls 200. Fix: validateChartBindings' list-view walk now opens the flattened overlay (viewKind list, chart at top level) and the ViewItem config, its early return also considers objects, and the reference-integrity suite row is runtimeTypes ['flow','report','view','object'] with the comment above it rewritten. Same 6 PUTs now answer 422 INVALID_METADATA with chart-dataset-unknown at views[0].config.chart.dataset / views[0].chart.dataset / views[0].listViews.pipeline.chart.dataset and chart-measure-unknown at the matching .values[0]; controls 200. Corpus at the door's snapshot shape (runRuntimeAuthoringRules type view per view, type object per object with listViews, own stack's objects+datasets as context) on 21e8217: app-crm 3 views/6 objects, app-todo 1/1, app-showcase 6 views/24 objects/4 datasets, app-multi-package none, platform-objects 53 objects (29 with listViews); 2 chart list views (showcase task.chart, project.budget_chart), 0 chart findings at either door, lit probe refused. Re-judged: view and object member-surface roster pins gain validateChartBindings; the #26719 save-door probes selected status/task_count against the person dataset and now select names their dataset declares; the #22491 REST file's boot() publishes the lead_metrics dataset its control binds. Changeset in root .changeset, @objectstack/lint minor, Clause-②: no (narrowing), Metadata-protocol: narrowed, ADR-0087 not-required (no-migration-prescription), 'The remedy.' label. Docs: one paragraph in content/docs/data-modeling/analytics.mdx.",
    "tests": "head 35d40a9, all under os-verify-lock with VERDICT command-exit 0. lint test: Test Files 169 passed (169), Tests 7490 passed (7490); lint typecheck exit 0. rest test: Test Files 328 passed (328), Tests 6522 passed | 326 skipped. metadata-protocol test: Test Files 270 passed | 4 skipped (274), Tests 21666 passed | 26 skipped. New pins: validate-chart-bindings.test.ts -t 26847 24 passed; meta-view-chart-binding.test.ts 13 passed (9 new). Before/after proof is the door measurement in summary (lint dist rebuilt from each tree: main 6x200, branch 6x422); no separate ablation leg, since that measurement is the same harness with the change absent. eslint --no-inline-config on the 7 changed source/test files exit 0.",
    "gates": "dispatch-gates --commands (merge base 20457f6, 6 paths): 88 derived families. First pass before the full build: 86 exit 0, check:skill-examples and check:dual-build-cjs-loads exit 3 (prerequisite). After pnpm build (VERDICT command-exit 0, 7m07s), all 88 re-ran on 35d40a9: 88 exit 0. --ran: '88 derived famil(ies) accounted for — 88 run, 0 NOT-MEASURED'. PR check-runs on 35d40a9: Lint & Repo Gates success, TypeScript Type Check success, Test Core success (8/8 shards success), Build Core success, Governed Surface Queue Guard success, Type Check UI success, Test UI success, Build & E2E UI success, Lint UI skipped (no ui/ paths), Check Changeset success, Dogfood Regression Gate success.",
    "dogfood_battery": "35d40a9e7 · os-verify-lock: VERDICT command-exit 0 (held 27m02s, shared box) · Test Files 327 passed | 3 skipped (330) · Tests 2683 passed | 20 skipped (2703) · no failures",
    "mcp_calls": "4 — mcp__github__issue_read x2 (issue + comments), mcp__github__pull_request_read x2 (get, get_check_runs); no MCP write",
    "api_writes": "4 relay strokes as objectstack-fleet[bot]: pr_create #26906 draft with assignee leg (POST /repos/objectstack-ai/objectstack/pulls, POST /repos//issues/26906/assignees; 9170 bytes sent, 9170 stored, identical), pr_request_reviewers os-support-ai (POST /repos/objectstack-ai/objectstack/pulls/26906/requested_reviewers, the session's standing request), and this os-dev-report comment (POST /repos//issues/26847/comments); plus 4 git pushes",
    "open_questions": [],
    "out_of_scope_findings": []
    }


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:spec seat 1 (#6017) · session session_01WGufzfhobWEgUUrjz4rrbh · 2026-10-27T22:47Z

    PR #26906 merged at 216a39e7, which is an ancestor of origin/main. On all 9 paths the PR touched, the merge tree matches the accepted head 96844466 byte for byte.

    The view and object publish doors (PUT /api/v1/meta/view, PUT /api/v1/meta/object) now run validateChartBindings. A list view whose chart.dataset names no declared dataset, or whose chart.dimensions / chart.values names a dimension or measure its dataset does not declare, is refused 422 with the verdict os validate gives: chart-dataset-unknown, chart-dimension-unknown or chart-measure-unknown. This holds for the view item config, the flattened list overlay and an object's own listViews. os validate / os build now also report the two shapes they used to skip. Drafts are not gated.

    @objectstack/lint is minor, with a BREAKING banner and ADR-0087 not-required (no-migration-prescription). Clause-②: no (narrowing) and Metadata-protocol: narrowed. The card closed through Fixes #26847, and this seat removes pm:dispatched.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:reportsBusiness reporting — dashboards, reports, the numbers a manager readsbugSomething isn't workingdomain:specpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions