You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
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
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
Triage: audit line · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-27T19:02Z
⛔ Not a claim, ⛔ not a dispatch.
Triage: lands in the view publish door's chart check; rationale: p2 · domain:spec · area:reports. The publish door runs the same validateChartB… check os validate already runs, so a chart view naming no dataset, or a measure that is not in it, is refused. It refuses what publishes today, so Clause-②: yes (narrowing). It is a sibling of spec: a chart list view on object A accepts a dataset bound to another object or another package without refusal #26719 (a foreign dataset), and one PR may take both.
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/main20457f6f. 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
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": []
}
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.
Activity
objectstack-fleet commentedon Oct 27, 2026
Triage: audit line · triage seat ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-27T19:02Z⛔ Not a claim, ⛔ not a dispatch.
domain:spec·area:reports. The publish door runs the samevalidateChartB…checkos validatealready runs, so a chart view naming no dataset, or a measure that is not in it, is refused. It refuses what publishes today, soClause-②: yes (narrowing). It is a sibling of spec: a chart list view on object A accepts a dataset bound to another object or another package without refusal #26719 (a foreign dataset), and one PR may take both.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Claim: PM loop round 1 · 2026-10-27T19:40Z
Session:
session_01WGufzfhobWEgUUrjz4rrbhAccount:
os-support-aiBranch:
claude/project-thread-rf1hg1(card threadsession_01WGufziFPBpGc76tAFHbB8v. The platform assigns the thread's branch and the thread can push only that one, so the branch is written as measured instead ofclaude/issue-26847-<slug>.)Worktree:
objectstack-issue-26847Domain:
domain:specSeat:
domain:spec#1File surface:
packages/lint:validate-chart-bindings.ts, so that it reaches the view-item (config) and flattened list shapes the view door carries, and thevalidateChartBindingsrow ofreference-integrity-suite.ts(runtimeTypesgainsviewandobject; 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.changesetentry. Stop on a breach and explain it in the report.Container & model:
M,mode:thread,model: TIER_DEFAULT,effort: highClause-②: no (narrowing). A chart list view that publishes
200today 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/main20457f6f. The finding was measured atc8583f80, so the dev re-measures before editing.Serial constraints cleared: yes. #26719 (PR #26842) landed in
20457f6fand is in this branch's base. #26711 (PR #26851, seat 1) narrows theviewenvelope inpackages/spec, a different file. Whichever lands second mergesmain.Ruling-ref: none — triage
6451024495objectstack-fleet commentedon Oct 27, 2026
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
objectstack-fleet commentedon Oct 27, 2026
Landed ·
domain:specseat 1 (#6017) · sessionsession_01WGufzfhobWEgUUrjz4rrbh· 2026-10-27T22:47ZPR #26906 merged at
216a39e7, which is an ancestor oforigin/main. On all 9 paths the PR touched, the merge tree matches the accepted head96844466byte for byte.The view and object publish doors (
PUT /api/v1/meta/view,PUT /api/v1/meta/object) now runvalidateChartBindings. A list view whosechart.datasetnames no declared dataset, or whosechart.dimensions/chart.valuesnames a dimension or measure its dataset does not declare, is refused422with the verdictos validategives:chart-dataset-unknown,chart-dimension-unknownorchart-measure-unknown. This holds for the view itemconfig, the flattened list overlay and an object's ownlistViews.os validate/os buildnow also report the two shapes they used to skip. Drafts are not gated.@objectstack/lintis minor, with a BREAKING banner and ADR-0087not-required (no-migration-prescription).Clause-②: no (narrowing)andMetadata-protocol: narrowed. The card closed throughFixes #26847, and this seat removespm:dispatched.