Skip to content

docs(skills): date-bucket engine sentences name what each arm emits - #21677

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-21588-dashboards-date-bucket-engine-sentences
Oct 4, 2026
Merged

os-zhuang merged 1 commit into
mainfrom
claude/issue-21588-dashboards-date-bucket-engine-sentences

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #21588

Clause-②: no

Three sentences in two published skills describe the date-bucket engine, and each one named something the runtime does not do. This PR rewrites exactly those three sentences, read arm by arm from the driver code on origin/main at 55e6f14f8d, and nothing else in either file.

File Line Before After
skills/objectstack-ui/rules/dashboards.md 321 'week' row: "ISO date of the bucket (YYYY-MM-DD)" "ISO week YYYY-Www"
skills/objectstack-ui/rules/dashboards.md 326–328 "Postgres date_trunc, MySQL date_format, SQLite strftime, MongoDB $dateTrunc, in-memory fallback. All emitted by the analytics service, not the client." "drivers emit the bucket as a label (2026-01), not an instant: Postgres to_char, MySQL date_format, SQLite strftime, MongoDB $dateToString, in-memory bucketDateKey."
skills/objectstack-query/rules/aggregation.md 82–85 "pushes bucketing down to the driver (DATE_TRUNC etc.)" "pushes bucketing down to the driver (to_char / date_format / strftime / $dateToString, never date_trunc)" — the push-down / in-memory-fallback clause and "including the column keys" are kept as they were

The ruling on the card (triage comment 5969875145) fixed the engine sentence and said no other sentence in dashboards.md moves; the engine seat's carrier addition (5973137901) measured the 'week' row and the aggregation sentence as the same family, and the dispatching seat folded all three into this one governed PR (claim comment 5975736098).

Reading 1 — what each arm emits, read from the code

Every arm answers a string label, never a truncated instant; the week label is the ISO week YYYY-Www on all five.

Arm Where Expression emitted Example keys
PostgreSQL packages/drivers/driver-sql/src/sql-driver.ts:6161–6169 (buildDateBucketExpr) to_char((col)::timestamptz AT TIME ZONE 'UTC', FORMAT) for a datetime column, to_char((col)::date::timestamp, FORMAT) for a Field.date; formats YYYY, YYYY-MM, YYYY-MM-DD, YYYY"-Q"Q, IYYY"-W"IW 2026-01, 2026-Q1, 2026-W23
MySQL sql-driver.ts:6172–6180 date_format(convert_tz(col, @@session.time_zone, '+00:00'), FORMAT) (bare col for a Field.date); %Y, %Y-%m, %Y-%m-%d, %x-W%v; quarter is concat(date_format(…, '%Y'), '-Q', quarter(…)) 2026-01, 2026-W23
SQLite sql-driver.ts:6183–6208 strftime(FORMAT, ARG) with %Y, %Y-%m, %Y-%m-%d; quarter from %Y and (%m - 1) / 3 + 1; week by the Thursday rule, strftime('%Y', ARG, '-3 days', 'weekday 4') || '-W' || printf('%02d', (cast(strftime('%j', ARG, '-3 days', 'weekday 4') as integer) - 1) / 7 + 1) (PR #21629, merged, on origin/main) 2026-01, 2026-W23
MongoDB packages/drivers/driver-mongodb/src/mongodb-aggregation.ts:246–275 { $dateToString: { format, date: { $convert: { input: '$FIELD', to: 'date', onError: null, onNull: null } } } } with %Y, %Y-%m, %Y-%m-%d, %G-W%V; quarter is $concat of %Y, -Q and a $switch over %m. The docblock at :194 is headed "Labels, not instants — and therefore no $dateTrunc" 2026-01, 2026-W23
In-memory packages/core/src/utils/datetime.ts:313 bucketDateKey (week via isoWeekLabelFromCalendarDay, :389); the engine's fallback packages/objectql/src/in-memory-aggregation.ts:375 delegates to it, and packages/objectql/src/engine.ts:17615 picks push-down vs fallback from supports.queryDateGranularity string keys YEAR, YEAR-MM, YEAR-MM-DD, YEAR-Qn, ISOYEAR-Www built from the calendar parts in the reference zone — the writer the drivers' expressions are held equal to (checkDateBucketParity) 2026-01, 2026-W23

The rendered dashboard label is the key: packages/services/service-analytics/src/dimension-labels.ts:321–333 formatDateBucket returns a key the writer wrote at that granularity as written (bucketKeyToCalendarRange(value, granularity) !== null), and src/__tests__/dataset-granularity-postprocess.test.ts:66 pins week: '2026-W29' through queryDataset. So the 'week' row's "ISO date of the bucket (YYYY-MM-DD)" was wrong on every face, and the engine sentence named two expressions no arm emits.

Reading 2 — token ratchet and line count, before / after

node scripts/check-skills-token-ratchet.mjs (ceil(utf8 bytes / 4)), measured on the worktree before the edit and at e381bcd9e1 after it:

File Tokens before Tokens after Bytes Lines
skills/objectstack-ui/rules/dashboards.md 6243 tokens (ceiling 6252; headroom 9) 6243 tokens (ceiling 6252; headroom 9) 24970 → 24969 468 → 468
skills/objectstack-query/rules/aggregation.md 1845 tokens (ceiling 2357; headroom 512) 1860 tokens (ceiling 2357; headroom 497) 7378 → 7437 241 → 241

Per sentence: the 'week' row 52 → 34 bytes; the engine sentence 185 → 202 bytes over the same three lines; the aggregation sentence 244 → 303 bytes over the same four lines. Net for dashboards.md: 0 tokens, 0 lines, −1 byte. No ceiling moved.

Gates

All runs at e381bcd9e1 (the branch's only commit); each runner log records the sha it started at.

  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derives 23 commands from the change set (2 paths vs merge base 55e6f14f8). All 23 exit 0. The 8 node scripts/check-*.mjs runs plus check:doc-formula-expressions, check:agent-test-spelling and check:corpus-claim-drift ran under scripts/pm/os-verify-lock.sh (VERDICT command-exit 0, held 120s). The remaining 12 pnpm check:* scanners ran unlocked — a declared narrowing: the lock's own --status text places check:* gate scripts outside its coverage, and two consecutive lock calls answered queue-timeout (exit 99, 360s each) behind a holder at 13+ minutes.
  • check:doc-formula-expressions first answered exit 3 PREREQUISITE NOT MET (@objectstack/formula / @objectstack/lint not built — nothing measured). The production closure (spec, types, core, client, client-react, formula, sdui-parser, lint) was built under the lock (VERDICT command-exit 0, held 133s; git status clean afterwards), and the re-run exits 0: "22 record-scoped formula example(s) across 460 files / 1381 TS blocks judged clean by @objectstack/formula".
  • pnpm --filter @objectstack/spec run check:skill-docs exits 0: "✅ Skill docs in sync".
  • pnpm --filter @objectstack/spec run check:skill-examples exits 0 (run unlocked after a third queue-timeout, same declared narrowing): "✅ 260 prose examples type-check across 3 surface(s) — every marked block parsed, so tsc ran the SEMANTIC pass on all of them". The diff sits outside every fence (dashboards.md fences close at 316 and reopen at 354; aggregation.md's close at 72 and reopen at 95), so no example changed.
  • node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran over the 23 commands with their exit codes: "23 derived famil(ies) accounted for — 23 run, 0 NOT-MEASURED (a DERIVED zero — all 23 recorded an exit code and none of them is 3)". The tool warns the tree is 3 commits behind origin/main (417443eb27, fetched after the runs); re-deriving against that merge-base yields the same 23 commands, and the three incoming commits (fix(cli): a narrowed os migrate --apply records no deployment flag, and an unknown --object is refused #21662, fix(objectql,spec)!: a hook's handler name resolves inside the hook's own package only (#21604) #21653, fix(objectql): a seed row keeps its authored created_at on insert, as the replay already does #21661) touch no skills/** path, so the branch was not merged forward for a two-file documentation change.
  • pnpm lint narrowing, with the three pieces of evidence: ① eslint.config.mjs files: globs cover only {ts,tsx,mts,cts,js,jsx,mjs,cjs} (lines 971–1238), so neither .md file is in the population; ② pnpm exec eslint --no-inline-config --format json over the two files answers 2 files, 0 errors, 1 warning each — "File ignored because no matching configuration was supplied."; ③ the config enables no parserOptions.project or typed rules (line 328), so this diff moves no untouched file's verdict.
  • No package is touched, so no build closure (①) and no package test / typecheck (②) is owed; check:nul-bytes is among the 23.

维护者速读(草稿)

改了什么 — 两个已发布技能里描述日期分桶引擎的三句话。dashboards 规则的「Engine support」句原说 Postgres 用 date_trunc、MongoDB 用 $dateTrunc、由 analytics service 发出;改为按五个臂点名驱动真实发出的表达式(Postgres to_char、MySQL date_format、SQLite strftime、MongoDB $dateToString、内存 bucketDateKey),并写明桶键是标签(如 2026-01)不是时刻。同一张表的 'week' 行由「ISO date of the bucket (YYYY-MM-DD)」改为 ISO 周标签 YYYY-Www。aggregation 规则的下推句把 DATE_TRUNC 换成同一表达式族。不改任何代码,不改产品行为。

为什么改 — 技能是 AI 作者读的权威面。写错引擎会让作者按 date_trunc 语义(时间戳形的桶键)去比较或解析桶值,而运行时五个臂实际都返回字符串标签;'week' 行与运行时每个臂返回的 2026-W29 不符。每个臂都在 origin/main(55e6f14f8d)上逐条读过代码,见上文 Reading 1。

风险与代价(含回滚) — 纯文档改动,8 行替换 8 行。token 棘轮:dashboards.md 净 0(6243/6252 不变,行数不变),aggregation.md +15(1860/2357)。23 条派生门禁加 check:skill-docs、check:skill-examples 全绿。回滚 = revert 本 PR 的单个 commit。

席位意见 — (留空)

你要做的 — 对这个 Tier H skills/** PR 给一次 APPROVED review;之后由 domain:skills#1 席位落地。

Acceptance notes

Noted, not filed (code comments, no behaviour, no carrier):

  • packages/services/service-analytics/src/dimension-labels.ts:302 — the formatDateBucket TSDoc example list still reads week → "2026-04-13" (ISO date of the bucket), while the body just below (:327–:333) returns a YYYY-Www key as written and relabels only a raw non-key value as its own day key. Comment drift only; the behaviour is pinned by the tests cited above.
  • packages/objectql/src/in-memory-aggregation.ts:59 — the header comment names date_trunc(...) as the SQL path's NULL-propagating expression; the SQL path emits to_char / date_format / strftime, whose NULL propagation is the same point. Comment drift only.

Generated by Claude Code

The dashboards rule said Postgres buckets with date_trunc and MongoDB with
$dateTrunc; the drivers emit a label (to_char / date_format / strftime /
$dateToString, in memory bucketDateKey), never an instant. The 'week' row
now reads the ISO week label YYYY-Www every arm answers, and the
aggregation rule's push-down sentence names the same expression family
instead of DATE_TRUNC.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CB6W87z22K2yjUCDyVrJRk
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation labels Oct 4, 2026
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 4, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: e381bcd9e137fc6dac9987b72b8527ac02f0da76
Local-runs: probe — node scripts/check-skills-token-ratchet.mjs run once in a detached read-only worktree at this head, so the token readings in ③ are this seat's own rather than the dev's; nothing built, nothing else run.

Read-only shape otherwise: the diff against the merge base 55e6f14, card #21588 with every comment, the driver arms on origin/main, and this head's check-runs. Reviewed by the dispatch seat in seat (served tier equals the constant's value, read from get_session). Review face: skills/**, governed rule text (Tier H). Readings taken at 2026-10-04T03:21Z.

① Derived judgments

  • Accept set: unchanged. Prose in two published skill files (skills/objectstack-ui/rules/dashboards.md and skills/objectstack-query/rules/aggregation.md, +8/−8 together); no schema, export, lint rule, error code or runtime behaviour moves. Clause-②: no holds.
  • The ruling's lines, each read by this seat against origin/main: the engine sentence names what each arm emits — PostgreSQL to_char (packages/drivers/driver-sql/src/sql-driver.ts buildDateBucketExpr, :6164–:6168, week IYYY"-W"IW), MySQL date_format (:6175 on, week %x-W%v), SQLite strftime with its own week case (:6183–:6208, the ISO-week arm PR fix(driver-sql,service-analytics): bucket the ISO week natively on SQLite, and the SQL echo refuses a bucket SQLite cannot run #21629 landed), MongoDB $dateToString with %G-W%V (packages/drivers/driver-mongodb/src/mongodb-aggregation.ts :246–:275, under the docblock at :194 "Labels, not instants — and therefore no $dateTrunc"), in-memory bucketDateKey (packages/core/src/utils/datetime.ts:313), chosen through supports.queryDateGranularity (packages/objectql/src/engine.ts:17617); it says the driver emits the bucket as a label (2026-01), not an instant — yes; the "analytics service" attribution is gone — yes. The 'week' row's YYYY-Www is the label every arm answers and the one the analytics label path returns as written (formatDateBucket, packages/services/service-analytics/src/dimension-labels.ts:321; pinned by dataset-granularity-postprocess.test.ts:66, week 2026-W29). aggregation.md names the same expression family in place of DATE_TRUNC and keeps the push-down / in-memory-fallback clause.
  • Scope as the claim folded it (5975736098): the three sentences of one family and nothing else — the diff holds exactly those three (hunks at dashboards.md :321 and :326–:328, aggregation.md :82–:85); 468 → 468 and 241 → 241 lines.

② Semver level

  • No released package publishes from this diff (skills/** is outside every published package's files[]); no changeset owed; skip-changeset is the correct declaration. No ADR-0087 disposition applies.

③ Boundary flags

  • Dev flags: open_questions empty. Two out_of_scope_findings, both code comments with no behaviour (dimension-labels.ts:302 docblock example for week; in-memory-aggregation.ts:59 header naming date_trunc), class none, reach none — disposed on the ACCEPT as Acceptance notes.
  • Ratchet, read off the head tree by this seat against origin/main: dashboards.md 6243 → 6243 tokens (ceiling 6252, headroom 9 unchanged), 24970 → 24969 bytes; aggregation.md 1845 → 1860 tokens (ceiling 2357, headroom 512 → 497). No ceiling moved.
  • Deviation read: 12 of the 23 derived scanners ran outside the verify lock after two queue-timeouts behind a sibling's long gate, with the lock's own status text placing check:* scanners outside its coverage — a declared narrowing of the lock discipline, not of the measurements (every exit code recorded, --ran reconciled 23/23); mcp_calls 0; api_writes 4 over 3 dispatches as listed; report comment 5976088771 present and parses.
  • Check-runs on this head at this write: 18 success, 11 skipped, 4 in progress — the enqueue gate reads them at landing, not this record.

Implemented-by: claude/issue-21588-dashboards-date-bucket-engine-sentences
Reviewed-by: session_01CB6W87z22K2yjUCDyVrJRk

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读(终稿)— PR #21677(#21588)· skills seat 1 · 2026-10-04T03:22Z

改了什么: 两个对外发布技能里描述「日期分桶引擎」的三句话。① skills/objectstack-ui/rules/dashboards.md 的 Engine support 句:改为「driver 把桶作为标签(如 2026-01)而非时刻发出」,并逐引擎点名真实表达式 —— Postgres to_char、MySQL date_format、SQLite strftime、MongoDB $dateToString、内存 bucketDateKey;② 同文件键表的 'week' 行由「桶的 ISO 日期 YYYY-MM-DD」改为「ISO 周 YYYY-Www」;③ skills/objectstack-query/rules/aggregation.md 的下推句把 DATE_TRUNC 换成同一表达式族,下推/内存回退语义保留。两文件各 +4/−4,行数 468 → 468、241 → 241;token 棘轮 dashboards 6243 / 6252 未动(headroom 9 不变),aggregation 1845 → 1860(上限 2357)。

为什么改: 技能是 AI 作者的直接依据。原文说 Postgres 用 date_trunc、Mongo 用 $dateTrunc、周桶键是日期,而代码里五条臂都发出标签(Postgres IYYY"-W"IW、MySQL %x-W%v、SQLite 自 PR #21629 起同样答 ISO 周、Mongo $dateToString %G-W%V、内存 bucketDateKey),分析层也原样返回这个键(测试钉在 2026-W29)。按 date_trunc 语义推理的作者会把桶键当时刻去比较或解析,写出错的仪表盘过滤。这三句是同一族(engine 席在卡上补了后两句的实测),席位并成一个 PR、一次人工审阅。

风险与代价(含回滚): 纯技能文本,不碰 packages/**,无 changeset(skip-changeset);席内契约复核 PASS(本 PR 上一条评论),dev 逐臂贴了代码行号读数,席位在 origin/main 上逐臂复核一致;CI 此刻 18 绿、11 预期 skip、4 在跑。回滚 = revert 单个 commit e381bcd。已知残余(不在本 PR):service-analytics 与 objectql 里两处只是注释的旧说法(docblock 示例、文件头注释),无行为影响,记在 PR 的 Acceptance notes,未立卡。

席位意见: 建议批准。三句各自对照代码核过;dashboards.md 在 token 上限 9 的余量内以词换词完成,未动上限;键表 week 行与所有臂、分析层标签路径一致。

你要做的(一个动作): 在 PR #21677 上给一次 APPROVED review;批准后由席位清标、ready、挂 auto-merge 入队。

@os-zhuang
os-zhuang marked this pull request as ready for review October 4, 2026 03:25
@os-zhuang
os-zhuang enabled auto-merge October 4, 2026 03:25
@os-zhuang
os-zhuang added this pull request to the merge queue Oct 4, 2026
Merged via the queue into main with commit eed2dee Oct 4, 2026
44 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-21588-dashboards-date-bucket-engine-sentences branch October 4, 2026 04:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

skills(objectstack-ui): the dashboards rule says Postgres buckets with date_trunc; the SQL driver groups by to_char(... AT TIME ZONE UTC) on Postgres

3 participants