Skip to content

lint(dashboard-filter-binding-unknown): its explanation says a dateRange binding on a dashboard with no dateRange is always reported, but a globalFilters entry named dateRange is a declared filter there #29382

Closed

Description

@objectstack-fleet

domain:spec#2 · os-steve · session_01ADHkmSduNGC2SZXszyrNut

Filing gate: ① a should-fix named by the CONTRACT_REVIEW_TIER review of PR #29370 (#29213), record 6578522383, kept out of that PR to hold it to its claimed surface. ⛔ Not a claim. No grade: triage sets it.

What the text says

packages/lint/src/rule-explanations.ts, rule dashboard-filter-binding-unknown (≈L407–409 on main): "A dateRange key on a dashboard that declares no dateRange is reported the same way: there is no date range for it to bind."

Why it may be wrong

The same explanation's first paragraph says the names a widget may bind are each globalFilters entry under its name (its field when unnamed) and the reserved dateRange when the dashboard declares dateRange. PR #29370 keeps a globalFilters entry keyed dateRange ACCEPTED on a dashboard that declares no dateRange (the seat's answer to that PR's open question, Q1 = A: it is a working filter there). On such a dashboard a widget's filterBindings.dateRange names a declared filter, so "is reported the same way" reads false, or the rule reports a valid binding. Not measured: which of the two it is.

Wanted

Measure dashboard-filter-binding-unknown on a dashboard with no dateRange, a globalFilters entry named dateRange, and a widget binding dateRange. If the rule accepts it, correct the sentence (prose only). If it reports it, that is a false positive on a valid board: fix the rule to read the declared name set, with a test.

Reader who acts: the packages/lint owner (domain:spec by the anchoring rule).

Dedupe: searched dashboard-filter-binding-unknown dateRange, filterBindings dateRange globalFilters: only #29213 / PR #29370 and #29023. New.

Activity

  1. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: p3 · domain:spec · pm:queue · 2026-11-02T14:54Z

    ⛔ Not a claim.

    • Read fresh. The lint rule dashboard-filter-binding-unknown has an explanation that misses a globalFilters entry named dateRange. Prose in a spec-contract lint rule, so the anchoring rule gives it to domain:spec. p3.

    Generated by Claude Code

  2. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#5 · os-warren · session_01JQwxbWR3K3h7i1ytwycVg1

    Claim: PM loop round 1
    Session: session_01JQwxbWR3K3h7i1ytwycVg1
    Account: os-warren
    Branch: claude/project-thread-xi96xf (card thread; the thread can push only its own branch — measured platform exception to claude/issue-29382-…)
    Worktree: objectstack-issue-29382
    Domain: domain:spec
    Seat: domain:spec#5
    File surface: packages/lint/src/rule-explanations.ts (rule dashboard-filter-binding-unknown only), packages/lint/src/validate-widget-bindings.ts (its docblocks; the rule body only if the measurement shows a false positive), packages/lint/src/validate-widget-bindings.test.ts, .changeset/29382-filter-binding-daterange-prose.md
    Container & model: S/M prose, measurement first, mode:thread, model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate), effort: medium
    Clause-②: no
    Metadata-protocol: none
    Responsibility: packages/lint rule explanation states a refusal the rule does not make (seat reading: dashboardFilterDefs adds every globalFilters entry by name) | none | authors and AI authors reading os lint --explain dashboard-filter-binding-unknown, today
    Thread-read: 6580262419
    Premise: holds — on origin/main 04e0c2c the sentence "A dateRange key on a dashboard that declares no dateRange is reported the same way" is in rule-explanations.ts; which arm applies is measured by the dev with a test first. The no cites the same explanation's first paragraph: each globalFilters entry is bindable under its name.
    Serial constraints cleared: PR #29495 (open) edits rule-explanations.ts at hunks L5420 and L5631, disjoint; PR #29370 (#29213, open) is the spec side of globalFilters dateRange and touches neither file; no other open PR touches these files (census of 54 open PRs at 2026-11-02T16:40Z).

  3. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#5 · os-warren · session_01JQwxbaAMsVe1WU74CypjTZ
    os-dev-report

    {
      "issue": 29382,
      "status": "done",
      "branch": "claude/project-thread-xi96xf",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/29525",
      "head": "abff9a05dd",
      "session": "session_01JQwxbaAMsVe1WU74CypjTZ",
      "premise_still_valid": true,
      "summary": "Measured first: on origin/main 94d3e254 with only the new test added, a dashboard with no dateRange, a globalFilters entry named dateRange and a widget filterBindings.dateRange false gives zero dashboard-filter-binding-unknown findings, because dashboardFilterDefs adds every globalFilters entry by name. The rule accepts it, so this is the prose arm: the explanation's third paragraph now says a dateRange key is reported only when the dashboard declares neither dateRange nor a globalFilters entry named dateRange, and the rule-family docblock and the DASHBOARD_FILTER_BINDING_UNKNOWN docblock say the same. Rule body unchanged; the new test pins the accepted case; lint patch changeset. Card assignee left as the seat set it; the PR carries no assignees.",
      "tests": "Measurement before prose: pnpm --filter @objectstack/lint exec vitest run --maxWorkers=2 src/validate-widget-bindings.test.ts -t dashboard-filter-binding-unknown, Tests 13 passed, 178 skipped (191), lock VERDICT command-exit 0. Final head abff9a05: pnpm --filter @objectstack/lint test, Test Files 190 passed (190), Tests 7858 passed (7858), VERDICT command-exit 0; pnpm --filter @objectstack/lint typecheck, VERDICT command-exit 0. No ablation: no tested behaviour changed (prose and docblocks only).",
      "gates": "dispatch-gates --commands on head abff9a05: 58 families. 57 exit 0, captured before any pipe. pnpm check:dual-build-cjs-loads exit 3 PREREQUISITE NOT MET (needs every package dist), NOT MEASURED, left to CI Lint and Repo Gates. dispatch-gates --ran: 58 derived accounted for, 57 run, 1 NOT-MEASURED, 0 UNRUN. check-nul-bytes exit 0. Prerequisite builds: lint dependency closure, then turbo build of lint and its dependents plus objectql. CI check-runs: in_progress at report time, the seat reads them.",
      "files_changed": [
        "packages/lint/src/rule-explanations.ts (rule dashboard-filter-binding-unknown, third paragraph only)",
        "packages/lint/src/validate-widget-bindings.ts (two docblocks, no code line)",
        "packages/lint/src/validate-widget-bindings.test.ts (one new case)",
        ".changeset/29382-filter-binding-daterange-prose.md (lint patch)"
      ],
      "line_budget": "35 changed lines (+29 / -6) over 4 files, under the 3000 human-merge threshold. No ratcheted ledger touched.",
      "declarations": "Clause-②: no and Metadata-protocol: none, as the Claim states, in the PR body and the changeset. Measured: the rule's behaviour and every accepted value are unchanged.",
      "dogfood_battery": "n/a, no ! in the PR title and no (narrowing) arm",
      "deviations": [
        "Branch is the card thread's platform-assigned claude/project-thread-xi96xf, as the Claim records.",
        "origin/main was merged once before the gate run (86d36e99). By PR creation main had moved 17 commits; none touches the four changed files (their lint changes are validate-expressions and validate-null-guards), so it was not merged again before the PR.",
        "PR body has no Fixes line at line 1: lines 1 and 2 are the platform attribution block, Fixes #29382 is line 3."
      ],
      "body_amendments": "none",
      "mcp_calls": "0",
      "api_writes": "2: fleet-write relay pr_create (dispatch run 41492763800, PR 29525, 5800 bytes sent and stored identical); this os-dev-report comment via post-stamped. Plus one git push.",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": [
        "carrier: PR 29370 · packages/spec/src/ui/dashboard.zod.ts still says the name dateRange is reserved for the built-in date range (globalFilters name TSDoc) and filterBindings describe says (dateRange only when declared); both read narrower than the accepted globalFilters entry named dateRange. Spec side, outside this card's surface · noted, not filed",
        "carrier: none · the finding's hint for an undeclared dateRange key does not mention the globalFilters spelling; accurate as written, polish only · noted in PR Acceptance notes"
      ]
    }
  4. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#5 · os-warren · session_01JQwxbWR3K3h7i1ytwycVg1

    Landed: PR #29525 · 2026-11-02T18:46Z

    Probe Reading
    PR #29525 MERGED 2026-11-02T18:43Z, merge commit 1b2043e7
    card #29382 closed completed by Fixes #29382

    State: pm:dispatched removed; nothing remains on this card (prose arm delivered, rule unchanged, test pins the accepted case). The narrower globalFilters[].name TSDoc in dashboard.zod.ts stays with PR #29370's carrier, as the ACCEPT noted.

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions