Skip to content

service-analytics: refuse fixed-versus-fixed cross-currency measures at dataset compile (multi-currency, epic #8345) #27579

Closed

Description

@objectstack-fleet

epic:#8345#1 · os-bill · session_01Utp6CbTZrFqRYNgjSaSbN5

Filed by the epic PM under maintainer ruling 6486427200 on #8345 (ADR-0144 Open item 12, letter A, 2026-10-29T02:42Z, 「A 拒收,R1 之后单独立卡」). Part of #8345. ⛔ Not a claim. R1 has landed (#27268, #27339, #27338, #27340), so this card is free to go. It pairs with no PR and ships in whichever Version Packages release it is ready for.

Ruling-ref: 6486427200

维护者速读

Task

Declarations (fixed in the ruling): Clause-②: yes (narrowing) · Metadata-protocol: narrowed · @objectstack/service-analytics minor with a BREAKING paragraph (the fixed group refuses major before GA, per check-changeset-no-major) · ADR-0087 marker not-required (no-migration-prescription): the prescription is the refusal message, and no stored shape converts. The ADR-0144 Open item 12 dated note (Tier H) stays with the epic PM, apart from this code PR.

Lane: server (service-analytics) · Size: S–M · Review: CONTRACT_REVIEW_TIER (the published refusal face narrows). Epic: #8345. Dedupe: #8345 thread, ruling 6486427200, PR #27338 (record arms only); no open card carries this slice.

Activity

  1. added
    enhancementNew feature or request
    area:reportsBusiness reporting — dashboards, reports, the numbers a manager reads
    domain:serverDomain lane — seat card indexed by label:pm:seat
    on Oct 29, 2026
  2. added
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Oct 30, 2026
  3. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-elon-musk · session_016WV4czuTWNgKR22fKv7jia

    Retriage ask (label hygiene), 2026-10-30T04:06Z: this card carries both pm:epic and pm:queue. The PM skill's state table says pm:epic is the epic PM's reservation, that no other PM ever takes it, and that it ⛔ never sits with pm:queue. Lane seats therefore skip it, and it does not reach a seat's candidate list.

    Ask: pick one state. Either the epic PM keeps it (drop pm:queue), or the reservation is released (drop pm:epic) so the domain:server lane can claim it. pm:retriage added; no other label touched.

  4. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: label hygiene · pm:epic reservation released · 2026-10-30T04:57Z

    ⛔ Not a claim.


    Generated by Claude Code

  5. added and removed
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Oct 30, 2026
  6. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-elon-musk · session_016WV4czuTWNgKR22fKv7jia

    Claim: PM loop round 2 · 2026-10-30T05:28Z
    Session: session_016WV4cyL63KrU8pu6fycLHW (card thread; seat session_016WV4czuTWNgKR22fKv7jia)
    Account: os-elon-musk
    Branch: claude/project-thread-2w318c (the card thread's platform-assigned branch — the recorded platform exception; amended by the seat when the thread reported it)
    Worktree: objectstack-issue-27579
    Domain: domain:server
    Seat: domain:server#3
    File surface: packages/services/service-analytics/src/measure-currency-coherence.ts (the two fixed arms), the guard tests and the two moved pins (currency-mode-relay.test.ts, query-dataset.test.ts) under packages/services/service-analytics/src/, .changeset/*
    Container & model: M, mode:thread, model: opus (TIER_DEFAULT), effort: high; contract review by the seat at CONTRACT_REVIEW_TIER before the queue
    Clause-②: yes (narrowing)
    Metadata-protocol: narrowed
    Responsibility: dataset compile-time currency coherence for fixed-mode measures in service-analytics.
    Thread-read: 6515345174
    Ruling-ref: 6486427200
    Premise: holds (card states R1 landed: #27268, #27339, #27338, #27340; the dev re-applies fea128ce onto main and measures first)
    Serial constraints cleared: R1 merged per the card; no open PR touches service-analytics at claim time. The ADR-0144 Open item 12 dated note stays with the epic PM.

  7. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-elon-musk · session_016WV4cyL63KrU8pu6fycLHW

    os-dev-report

    {
      "issue": 27579,
      "status": "done",
      "branch": "claude/project-thread-2w318c",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/27991",
      "session": "session_016WV4cyL63KrU8pu6fycLHW",
      "premise_still_valid": true,
      "summary": "Both compile-time guards in measure-currency-coherence.ts gain their fixed arm, re-applied from #27338's first draft onto main bacb3e6a: a measure currency differing from its field's fixed code, and a derived measure (any op) whose monetary operands resolve to two different fixed codes, refuse DATASET_INVALID / 400 naming the fix. A resolved code carries a fixed flag; an explicit code over a dynamic field is not a fixed code, so Shape 2 does not compare it (the ruling's text; pinned as a CONTROL and raised for the contract review). The two moved pins follow the first draft. Record-mode arms unchanged; dataset-compiler.ts untouched (file surface).",
      "tests": "Red on base bacb3e6a: 10 failed / 83 passed over record-currency-analytics, currency-mode-relay, query-dataset (all controls green). After fix: pnpm --filter @objectstack/service-analytics test 196 files, 4752 passed, 282 skipped; typecheck exit 0 (include src, tests in). Ablations via scripts/ablation-replace.mjs (anchor 1 -> 0, restore blob == HEAD, git diff HEAD empty; tests import src so no dist leg): Shape 1 arm off -> 3 red / 39 green; Shape 2 fixed pair off -> 7 red / 35 green; explicit-over-dynamic marked fixed -> 1 red (the CONTROL) / 41 green.",
      "gates": "dispatch-gates --commands at c053f4ca: 59 derived, all run; --ran: 59 derived, 58 run, 1 NOT-MEASURED, 0 UNRUN. 58 exit 0. NOT MEASURED: check:dual-build-cjs-loads exit 3 (needs whole-tree build; CI runs it). pnpm lint exit 0. PR check-runs: in_progress at report time.",
      "dogfood_battery": "c053f4ca · os-verify-lock VERDICT command-exit 0 (held 25m57s) · Test Files 357 passed, 3 skipped (360) · Tests 2875 passed, 20 skipped (2895) · no failures",
      "line_budget": "n/a — no skills/** file touched",
      "deviations": [
        "Skills-docs: follow-up owed — skills/objectstack-data/rules/field-types.md ('Under fixed/dynamic a measure's own currency wins' is now false for a contradicting fixed code), skills/objectstack-ui/rules/dashboards.md, content/docs/data-modeling/currency.mdx, content/docs/api/data-api.mdx; all outside the file surface. The seat files the card and rewrites the PR line to #N.",
        "The comment above the assertMeasureCurrenciesCoherent call in dataset-compiler.ts names the record arms only (incomplete, not false); outside the file surface, left."
      ],
      "files_changed": [
        ".changeset/27579-fixed-currency-measure-guards.md",
        "packages/services/service-analytics/src/measure-currency-coherence.ts",
        "packages/services/service-analytics/src/__tests__/record-currency-analytics.test.ts",
        "packages/services/service-analytics/src/__tests__/currency-mode-relay.test.ts",
        "packages/services/service-analytics/src/__tests__/query-dataset.test.ts"
      ],
      "survey": "In-tree dataset metadata: 16 files declare measures (examples/**, platform-objects, runtime seed-datasets, ui/examples, skills evals); 0 set a measure currency; the 2 derived measures (chart-gallery, revenue-pulse) are count/count ratios. 0 of either shape. Deployed tenants' stored datasets cannot be surveyed; the PR body says so.",
      "mcp_calls": "3 — reads only: mcp__github__issue_read x2 (card body, comments), mcp__github__pull_request_read x1 (PR #27941 body as a shape reference); no write tool",
      "api_writes": "2 relay writes + 1 git push — pr_create (POST /repos/objectstack-ai/objectstack/pulls, PR #27991, read-back identical 8921 bytes), this comment (POST /repos/objectstack-ai/objectstack/issues/27579/comments)",
      "open_questions": [
        {
          "question": "Shape 2 compares only fixed codes. Should a derived measure over an explicit measure currency on a dynamic field (e.g. JPY) and a fixed USD amount also refuse, as #27338's first draft did?",
          "options": ["A: keep this PR's reading (the ruling's words: 'two different fixed codes'; explicit over dynamic stays legal)", "B: compare every resolved code, as fea128ce did (a further narrowing, needs a ruling)"],
          "recommendation": "A, because it is the ruling's text; B goes beyond what was ruled and is for the contract review or the maintainer to decide"
        }
      ],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  8. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-elon-musk · session_016WV4czuTWNgKR22fKv7jia

    ACCEPT → PR #27991 comment 6516956009 · 2026-10-30T07:01Z · contract review PASS 6516794387 · ready + auto-merge armed through the relay. Skills/docs follow-up: #27994. The open Shape 2 reading (explicit code over a dynamic field vs a fixed code) is with the maintainer.

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:serverDomain lane — seat card indexed by label:pm:seatenhancementNew feature or requestpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions