Skip to content

spec: the blueprint dashboard widget has no aggregation slot, so an AI-built 「平均面试评分」 metric sums (908 instead of an average); add an optional aggregate (objectstack-ai/cloud#3607 row 2 ruling A) #30430

Closed

Description

@objectstack-fleet

repo:cloud#3 · hotlong · session_01Q4EjjRhUZjdy8VXs6Kkur2

Filing gate: executing a recorded ruling. The maintainer ruled objectstack-ai/cloud#3607 row 2 A (record 6656298548; their selection, verbatim: 「A spec 加聚合字段(推荐)」). This card is the spec half. objectstack-ai/cloud#3607 keeps the cloud half (the designer emits it, the compile requires it), pm:blocked on this card.

Owner. The repo:cloud lane (repo:cloud#3, #30278) follows it to close. It widens a published schema (Clause-②: yes (widening)), so it is spec-lane work; triage routes it. Priority p2, inherited from objectstack-ai/cloud#3607.

维护者速读

AI 通过 MCP 搭建的仪表盘里,标题写着「平均面试评分」的组件显示的是 12 个分数的总和 908。原因是蓝图的仪表盘组件只有 measure,没有「聚合方式」字段,平台按字段类型自动选(数值字段求和),AI 想要平均值也无处可写。按裁决,给组件加一个可选的 aggregate。

Measured

  • On staging bd085bb0 (objectstack-ai/cloud#3607 row 2, app app.nnf5 招聘管理), the server's own propose_blueprint wrote {chart:'metric', measure:'score'} for a widget titled 「平均面试评分」, and the dashboard summed 12 scores (908).
  • The seat read packages/spec/src/ai/solution-blueprint.zod.ts:202-216 at objectstack origin/main. BlueprintDashboardSchema widgets declare id, title, object, chart, measure, groupBy and condition, and nothing else. measure's describe says: "The aggregation is chosen automatically from the field type — a money field SUMs, a percentage/rate AVERAGEs".
  • The cloud#3607 dev also measured that cloud's defaultAggregateFor averages only percent. So a plain number field can never be averaged through a blueprint (report: objectstack-ai/cloud#3607 comment 6652310415).

The ruled design

  1. An optional aggregate: 'sum' | 'avg' | 'min' | 'max' | 'count' on the blueprint widget, in the lenient schema and in the strict mirror the dev named. Its describe states what each value means and that count needs no measure field.
  2. The measure describe is rewritten so it no longer tells the author the aggregation is automatic: the aggregation is what aggregate says.
  3. ⛔ No title heuristics anywhere (option C was rejected).

Acceptance

  • Schema tests: each value is accepted; an unknown value is refused by the strict mirror; an absent value still parses (it is optional).
  • The liveness ledger row for the new key, with its consumer named: objectstack-ai/cloud#3607's cloud half reads it. It is planned until that lands.
  • Clause-②: yes (widening), with the spec-lane contract review on record.

Dedupe (issues, open and closed, 2026-11-05): repo:objectstack-ai/objectstack blueprint widget aggregate is:issue returned 13 hits (#14302, #15449, #14298, …), none on this slot.

Added 2026-11-05: the calendar date key (objectstack-ai/cloud#3607 row 1 residue, ruling B)

The maintainer ruled B on the calendar date key; the record is on objectstack-ai/cloud#3607, and their selection, verbatim, is 「B 现在加 spec 键」. It belongs to the same spec PR as the widget aggregate.

  • Today (packages/spec/src/ai/solution-blueprint.zod.ts:163): BlueprintViewSchema declares object, name, label, type, columns, groupBy, filters, …, and has no date key. A calendar view therefore cannot say which date field it schedules on. Cloud binds the first declared date or datetime field and names it in the success envelope (objectstack-ai/cloud PR feat(client,spec)!: delete 21 dead SDK methods + the four ghost route tables under them (#3612) #3616).
  • Add: an optional date-field key on the blueprint view, in the lenient schema and the strict mirror, meaningful for type: 'calendar'. Name it after the target the spec already uses, calendar.startDateField; the spec lane decides the exact key. Its describe states that it is ignored for other view types, or refused for them; the spec lane chooses, and the choice is stated.
  • Acceptance: schema tests for the key on a calendar view, a strict-mirror refusal of a wrong type, and a liveness ledger row whose consumer is the objectstack-ai/cloud#3607 cloud half (planned until it lands).

Activity

  1. added
    bugSomething isn't working
    repo:cloudCard routed whole to the cloud PM: needs cloud code, a producer or a fact (cloud owns it to closure)
    on Nov 5, 2026
  2. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: audit · p1 · domain:spec · 2026-11-05T12:01Z

    ⛔ Not a claim.


    Generated by Claude Code

  3. added
    domain:specDomain lane — seat card indexed by label:pm:seat
    pm:queueReady for the PM dispatch loop
    priority:p1High: required for production / M2
    on Nov 5, 2026
  4. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K

    Claim: PM loop round 20 (p1)
    Session: session_01WGufzfgvGexKn9vLHsy89K
    Account: os-support-ai
    Branch: the card thread's own claude/project-thread-* branch, named in the dev's hand-back and restated in a later claim (a measured platform exception to claude/issue-30430-…)
    Worktree: objectstack-issue-30430
    Domain: domain:spec
    Seat: domain:spec#3
    File surface: packages/spec/src/ai/solution-blueprint.zod.ts (the lenient BlueprintDashboardSchema widget and BlueprintViewSchema, and their strict mirrors), its tests, the regenerated spec ledgers and docs, and a liveness row if the ledger governs these keys. ⛔ Not cloud, not the dashboard runtime, no title heuristics.
    Container & model: S, mode:thread, model: TIER_DEFAULT, effort: high
    Clause-②: yes (widening: an optional aggregate on the blueprint dashboard widget and an optional calendar date-field key on the blueprint view)
    Metadata-protocol: added (expected; the dev confirms with check-changeset-no-major)
    Responsibility: an AI-built 「平均面试评分」 metric sums the scores (908) instead of averaging them, and a blueprint calendar view cannot name its date field | BlueprintDashboardSchema widgets have no aggregation slot and measure's describe says the aggregation is automatic; BlueprintViewSchema has no date key | every blueprint the MCP designer builds (objectstack-ai/cloud#3607, staging bd085bb0)
    Thread-read: 6657459787
    Premise: holds at origin/main by reading: solution-blueprint.zod.ts :202-216 (widget keys id, title, object, chart, measure, groupBy, condition; measure's describe :211 says the aggregation is chosen automatically) and :163 (BlueprintViewSchema, no date key). The dev re-measures before editing.
    Human floor: the maintainer's rulings on objectstack-ai/cloud#3607: row 2 A (record 6656298548, 「A spec 加聚合字段(推荐)」) and the calendar date key B (「B 现在加 spec 键」).
    Serial constraints cleared: no open PR touches solution-blueprint.zod.ts.

  5. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 5, 2026
  6. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K

    Claim: PM loop round 20 (p1), restated with the branch
    Session: session_01WGufzfgvGexKn9vLHsy89K
    Account: os-support-ai
    Branch: claude/project-thread-yz95oc (the card thread's own branch, a measured platform exception to claude/issue-30430-…); card thread session session_01WGufzhYPN1JqnojTxfq2Pc
    Worktree: objectstack-issue-30430
    Domain: domain:spec
    Seat: domain:spec#3
    File surface: packages/spec/src/ai/solution-blueprint.zod.ts (the lenient BlueprintDashboardSchema widget and BlueprintViewSchema, and their strict mirrors), its tests, the regenerated spec ledgers and docs, and a liveness row if the ledger governs these keys. ⛔ Not cloud, not the dashboard runtime, no title heuristics.
    Container & model: S, mode:thread, model: TIER_DEFAULT, effort: high
    Clause-②: yes (widening: an optional aggregate on the blueprint dashboard widget and an optional calendar date-field key on the blueprint view)
    Metadata-protocol: added (expected; the dev confirms with check-changeset-no-major)
    Responsibility: an AI-built 「平均面试评分」 metric sums the scores (908) instead of averaging them, and a blueprint calendar view cannot name its date field | BlueprintDashboardSchema widgets have no aggregation slot and measure's describe says the aggregation is automatic; BlueprintViewSchema has no date key | every blueprint the MCP designer builds (objectstack-ai/cloud#3607, staging bd085bb0)
    Thread-read: 6657819796
    Premise: holds at origin/main by reading: solution-blueprint.zod.ts :202-216 (widget keys id, title, object, chart, measure, groupBy, condition; measure's describe :211 says the aggregation is chosen automatically) and :163 (BlueprintViewSchema, no date key). The dev re-measures before editing.
    Human floor: the maintainer's rulings on objectstack-ai/cloud#3607: row 2 A (record 6656298548, 「A spec 加聚合字段(推荐)」) and the calendar date key B (「B 现在加 spec 键」).
    Serial constraints cleared: no open PR touches solution-blueprint.zod.ts.

  7. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#3 · os-support-ai · session_01WGufzhYPN1JqnojTxfq2Pc
    os-dev-report
    Stamp: 2026-11-05T13:16Z

    {
      "issue": 30430,
      "status": "done",
      "branch": "claude/project-thread-yz95oc",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/30484",
      "head": "4960c1d3",
      "session": "session_01WGufzhYPN1JqnojTxfq2Pc",
      "premise_still_valid": true,
      "summary": "Blueprint dashboard widgets gain aggregate (sum, avg, min, max, count), optional on the lenient schema and required-but-nullable on the strict mirror, from one shared tuple and one shared meaning sentence. measure's describe no longer says the aggregation is automatic and neither side tells the model to infer from the title. Blueprint views gain startDateField (the built view's calendar.startDateField), snake_case, read on calendar views and ignored, not refused, on the other types. Count rule: count counts records and needs no measure; a measure beside it is not read; sum/avg/min/max need a numeric measure, stated in the describe, not refused by the spec (the strict mirror cannot state a cross-key rule; the cloud compile judges it). Liveness does not govern the solution blueprint (not a registered, unregistered-kind or spec-only type), so no row. No reader in this repo; cloud#3607's cloud half is the consumer.",
      "tests": "at 4960c1d3 under os-verify-lock: pnpm build 119/119 tasks; spec test 814/814 files, 25610 passed 1 todo; spec typecheck exit 0; solution-blueprint.test.ts 85/85. Ablation 1 (src): strict widget aggregate renamed, blob 1d11f8e14420 to 82c3c8c15327, 11 failed of 85, restored to HEAD blob, git diff HEAD empty. Ablation 2 (src): lenient view startDateField renamed, blob 1d11f8e14420 to 45bbf04c1b37, 3 failed of 85, restored to HEAD blob. Spec tests import from src, no rebuild needed.",
      "gates": "dispatch-gates --commands at 4960c1d3: 102 derived, 102 run, every exit 0 (check-plugin-teardown-shape --self-test exited 3 on the shallow clone, re-run exit 0 after fetching pinned fixture 621a4876); --ran reconciliation: 102 run, 0 NOT-MEASURED, exit 0. check-changeset-no-major with the PR body as event: exit 0 on Metadata-protocol added; control with none exits 1. CI check-runs: in_progress at report time.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "2 — issue_read get and get_comments on #30430 (read-only)",
      "api_writes": "2 — relay pr_create (#30484, draft, no assignees, body read back byte-identical, 13194 bytes), this os-dev-report comment via post-stamped.mjs; git push x2 not REST",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": [
        "carrier: cloud · sum/avg/min/max with measure absent or count is not refused by the spec; the cloud compile must refuse or report it per widget · stated in the aggregate describe and the PR body",
        "carrier: cloud · startDateField is ignored on non-calendar views; the cloud applier reads it on calendar only and should name a declared field that is not date/datetime · stated in the describe"
      ]
    }
  8. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K

    Accepted: PR #30484, head e16fea95. The ACCEPT is 6660227797; the contract review is 6659170858 (PASS), both on the PR. It lands through the merge queue. The cloud half's two acceptance items are carried in the PR body for objectstack-ai/cloud#3607.

  9. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#3 · os-sales · session_01L6bhgTqqeHSwZYJmApbDCa

    Landed: PR #30484 merged at d2e2f6f7. An AI blueprint dashboard widget may now declare aggregate (sum / avg / min / max / count), and a blueprint view startDateField (the date field a calendar view schedules by), on the lenient schema and its strict mirror alike (nullable there). measure's describe now names the field only; the aggregation is aggregate's, and measure: "count" is the legacy spelling of aggregate: "count". The card closed by Fixes; this seat (taken over from domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K on the maintainer's order, recorded on the seat post #18883) removes pm:dispatched.

    The merge queue landed it at 2026-11-05T15:36:50Z.

    Carried, objectstack-ai/cloud#3607 (the cloud half, repo:cloud), with its two acceptance items from the ACCEPT (PR #30484 comment 6660227797):

    1. a sum / avg / min / max widget whose measure is absent, "count" or not a numeric field is refused per widget, never summed as a record count;
    2. startDateField is read on calendar views only, and one naming no date or datetime field is refused, never replaced by the first date field.

    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

bugSomething isn't workingdomain:specDomain lane — seat card indexed by label:pm:seatpriority:p1High: required for production / M2repo:cloudCard routed whole to the cloud PM: needs cloud code, a producer or a fact (cloud owns it to closure)

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions