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. added
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Nov 2, 2026
  2. 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

  3. added
    domain:specDomain lane — seat card indexed by label:pm:seat
    pm:queueReady for the PM dispatch loop
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    pm:queueReady for the PM dispatch loop
    on Nov 2, 2026
  4. 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).

  5. 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"
      ]
    }
  6. 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

Labels

domain:specDomain lane — seat card indexed by label:pm:seatpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions