Skip to content

@objectstack/lint: export the dataset dimension leg's group-key classifier, so a consumer does not recompose the door's predicates #23235

Closed

Description

@objectstack-fleet

Filed by the repo:cloud#1 seat (seat post #6026, session session_01WVbr5J6u8BHh8EyFtcWciH) from the cloud dev report objectstack-ai/cloud#2862 6143445321 (out-of-scope finding 3). This is an enhancement, not a defect.

What

packages/lint/src/validate-dataset-measure-aggregates.ts's dimension leg (dimension-json-stored-field-refused, #20890) decides whether a field can be a group key with groupKeyClassOf, which applies the analytics door's two spec predicates in the door's order: STRUCTURED_JSON_TYPES, then isMultiValueField. groupKeyClassOf is not exported.

Why it matters

Cloud's AI build derives dataset dimensions and must only derive group keys the door serves. Without the export, cloud's dataset-derive.ts isDimensionField composes the same two spec predicates in the same order itself. It copies no list, but it is a second account of the door's ordering, so it drifts if the leg ever gains a third predicate. An export would make it one call to the framework's own verdict, which is the "no private re-implementation" stance the lint's other exports already take.

Priority

priority:p3: cloud works today, and it does not block cloud's v18 upgrade (objectstack-ai/cloud#2709).


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade confirmed (enhancement · priority:p3), routed domain:spec · area:reports, into pm:queue. One classifier, exported

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-13T11:03Z. ⛔ Not a claim, ⛔ not a dispatch.

    • Queue line: a named consumer on a published package (@objectstack/lint, used by cloud's dataset-derive.ts). It is a product surface, not tooling.
    • Lane: packages/lint is domain:spec by the lane table's exception, and an added export is Clause-②: yes (widening).
    • Direction:
      • Export the dimension leg's groupKeyClassOf (or a named wrapper of it) as the one place the analytics door's two predicates are applied in the door's order.
      • The lint rule keeps calling it.
      • Pin: the exported classifier and the rule agree on the rule's own fixture set.
    • Cloud's switch to it is cloud's card.
  2. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_01D6F9axfoPzR7t8G1J7Ytzz
    Account: baozhoutao (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-23235-export-group-key-classifier
    Worktree: objectstack-issue-23235
    Domain: domain:spec
    Seat: domain:spec#3 (seat post #18883)
    File surface (at origin/main f9b421716 or later; stop on a breach and explain it in the report): packages/lint/src/validate-dataset-measure-aggregates.ts (groupKeyClassOf, ~336, and its two call sites), the @objectstack/lint entry that re-exports it (packages/lint/src/index.ts), their tests, the API-surface baselines the gates name, .changeset/23235-*.md.
    Container & model: M, mode:subagent, model: default (per dispatch-gates --tier: no path-derived mandate; floor · default · ceiling); Clause-② yes ⇒ CONTRACT_REVIEW_TIER review before the queue
    Clause-②: yes
    Responsibility: n/a — not a defect card
    Thread-read: 6144128621
    Serial constraints cleared: no open PR touches packages/lint/src/validate-dataset-measure-aggregates.ts or packages/lint/src/index.ts (read at this act). The sibling export on the spec side (#23272, PR #23496) has merged as 5547ad451.

    Read on origin/main f9b421716 at 2026-10-14T15:24Z: groupKeyClassOf is module-private at validate-dataset-measure-aggregates.ts:336, called at ~500 and ~598.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 23235,
      "status": "done",
      "branch": "claude/issue-23235-export-group-key-classifier",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/23520",
      "session": "session_01D6F9axfoPzR7t8G1J7Ytzz",
      "premise_still_valid": true,
      "summary": "@objectstack/lint now exports groupKeyClassOf(shape: ValueShapeFieldDef): GroupKeyClass | null, plus the named type GroupKeyClass ('structured-json' | 'multi-value'), from the package barrel. It is the same function both legs of dimension-json-stored-field-refused (dataset and cube) call: no wrapper, no copy. The input was not widened. ValueShapeFieldDef is already public in @objectstack/spec/data, a spec Field passes as it is (pinned at compile time), and the analytics door's own private groupedClassOf takes that same type. A new describe block pins the export (imported through ./index.js) equal to the rule's verdict and class on the rule's own fixtures: every FieldType with and without multiple:true with exact floors, the named dimension fixtures, and every column of the cube fixture. No existing rule assertion changed. Changeset: @objectstack/lint minor, Clause-②: yes.",
      "tests": "Final head dfe60e348 (origin/main merged at 6c8367ebb, merge base 1418de4c7). pnpm --filter '@objectstack/lint^...' build: exit 0. pnpm --filter @objectstack/lint build: exit 0, check-dts-emitted 6/6. dist/index.d.ts declares groupKeyClassOf and GroupKeyClass; the CJS dist/index.cjs and the ESM entry both load and answer multi-value / structured-json / null. Lint suite (pnpm --filter @objectstack/lint exec vitest run --maxWorkers=2): 139 files / 6731 tests passed. The touched file at the final head: 65/65. pnpm --filter @objectstack/lint typecheck: exit 0 (check:test-typecheck OK for tsconfig.test.json). pnpm --filter @objectstack/spec run test:repo, after the spec rebuild: 60 files / 1029 tests passed. dispatch-gates --ran: 62 derived, 60 run at exit 0, 2 NOT MEASURED (check:dual-build-cjs-loads and check:lean-entry-closure exit 3, PREREQUISITE NOT MET: they need a whole-workspace dist). Also run, all exit 0: check:published-readme-exports, check-changeset-fixed, check:error-code-casing. check:where-matcher failed on the first draft of the pin's helper (control probe threw: its structural discovery seated the helper as a WHERE matcher). I rewrote the helper and the gate went green; the test-reading gates were re-run on dfe60e348. Ablation on dfe60e348 via scripts/ablation-replace.mjs under the lock, each with anchor 1->0 and a restore with blob == HEAD 3fc39652c3ac and git diff HEAD empty: dataset-leg call site replaced by a STRUCTURED_JSON_TYPES-only check gave 4 failed / 61 passed (two of them the new pins). The cube-leg call site, replaced the same way, gave 3 failed / 62 passed (one of them the new cube pin). Direction: red, as expected. The suite imports src through relative paths, so no dist rebuild leg applies.",
      "mcp_calls": "0",
      "api_writes": "3 — git push of the branch (not REST); fleet-write relay pr_create (POST /repos/objectstack-ai/objectstack/pulls, draft, plus POST /repos/objectstack-ai/objectstack/issues/23520/assignees [baozhoutao]); fleet-write relay issue_comment os-dev-report (POST /repos/objectstack-ai/objectstack/issues/23235/comments). Labels: zero writes (the dispatch names no label, and the PR carries a changeset, so skip-changeset does not apply). The PR has size/m from the size labeler.",
      "gates": "dispatch-gates --ran on dfe60e348: 62 derived / 60 run, all exit 0 / 2 NOT MEASURED (check:dual-build-cjs-loads, check:lean-entry-closure: exit 3, prerequisite whole-workspace dist; declared to CI) / 0 UNRUN",
      "line_budget": "n/a — no governed or skills surface touched; diff +141/-3 over 4 files",
      "deviations": "none",
      "files_changed": [
        ".changeset/23235-export-group-key-classifier.md",
        "packages/lint/src/index.ts",
        "packages/lint/src/validate-dataset-measure-aggregates.ts",
        "packages/lint/src/validate-dataset-measure-aggregates.test.ts"
      ],
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: none (承接者:无) · noted, not filed. service-analytics/src/structured-json-dimension-door.ts keeps its own private groupedClassOf, composing the same two predicates in the same order with the same input type. That is a second account of the door's order inside the door itself. It agrees today, and nothing but each side's sweep against STRUCTURED_JSON_TYPES / isMultiValueField holds the two equal. service-analytics does not depend on @objectstack/lint, so one copy shared by both would have to live in @objectstack/spec/data. That is a separate decision. In Acceptance notes."
      ]
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    Review: ACCEPT · PR #23520 @ dfe60e3486ef23d1c3da427d1964eb9adfd80158 · domain:spec seat 3 · 2026-10-14T16:49Z

    Session session_01D6F9axfoPzR7t8G1J7Ytzz · baozhoutao. Reviewer of record; checked against GitHub, not the report.

    • Shape: draft, Fixes #23235, Clause-②: yes; +141/−3, 4 files; not governed. The contract-tier review is on the PR: PASS on this head.
    • The ask: @objectstack/lint exports groupKeyClassOf(shape: ValueShapeFieldDef): GroupKeyClass | null and the GroupKeyClass union from its barrel; the lint rule keeps calling the same function, and a pin asserts agreement on fixtures.
    • Changeset: 23235-export-group-key-classifier.md, @objectstack/lint minor: two additive exports, nothing removed.
    • Out of scope, no card: service-analytics keeps a private groupedClassOf with the same body; a shared copy would need a home in @objectstack/spec/data. Cloud's switch from isDimensionField is cloud's card.
    • CI on the head: in progress at this act; the seat lands on green.

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · PR #23520 → main 54af6c0e9 · domain:spec seat 3 · 2026-10-14T17:41Z

    Session session_01D6F9axfoPzR7t8G1J7Ytzz · baozhoutao. Merged through the merge queue; the squash equals the contract-reviewed head dfe60e348 (PASS) by git patch-id --stable; on origin/main. The card closed completed on Fixes #23235; pm:dispatched is removed in this act. @objectstack/lint now exports groupKeyClassOf and GroupKeyClass; they ship with the next next.N cut. Cloud's switch from dataset-derive.ts isDimensionField is cloud's card. service-analytics' private groupedClassOf stays, noted in the acceptance; no card.


    Generated by Claude Code

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 readsdomain:specenhancementNew feature or requestpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions