Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .changeset/26633-report-period-export-eval.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
'@objectstack/skills': patch
---

docs(skills): objectstack-ui gains an eval for a report's `dateRange` and `exportOptions`

Clause-②: no
Metadata-protocol: none

- **Before.** The skill taught a report's `dateRange` in `rules/dashboards.md`, but no eval checked that an agent authoring a report reaches for `dateRange` on a `type: 'date'` dataset dimension and for `exportOptions` with `csv` / `xlsx`. An agent could hand-roll a `runtimeFilter` window on the date column, invent a report permission key for export, declare a second preset table, or place either key on a `joined` container, and nothing scored that wrong.
- **Now.** A third eval file, `evals/report-period-export.json`, carries one report-authoring prompt whose assertions require `dateRange: { dimension, defaultRange }` and `exportOptions` with `'csv'` / `'xlsx'`, name the existing permission-set `allowExport` as the only export gate, and refuse a `joined` container, a `close_date` filter window, a `presets:` table and an invented permission key. `evals/README.md` lists the file.
- No schema, key or behaviour changes.
23 changes: 21 additions & 2 deletions scripts/check-skills-token-ratchet.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -679,10 +679,18 @@ export const CEILINGS = new Map([
// objectstack-automation
['skills/objectstack-automation/evals/approvals/test-revise-loop.md', 1329],

// objectstack-ui — the two authored eval files; its `references/react-blocks.md`
// objectstack-ui — the three authored eval files; its `references/react-blocks.md`
// is generator-owned and carries no row here on purpose (see the boundary
// section). Its JSON twin was retired by #14296 item 3 and is gone entirely.
['skills/objectstack-ui/evals/README.md', 289],
// 289 -> 335 (#26633): the README lists the third eval file,
// `report-period-export.json`, in one three-line entry (+196 bytes). The
// README's four sections share no sentence, so there was no duplicate to cut
// (0 bytes). On `origin/main` the file was 1143 bytes (286 tokens, headroom
// 3); the LANDED file is 1339 bytes -> 335 tokens, ceiling +46, pinned AT the
// measurement. Same ruling as the `analytics-inline-vs-dataset.json` row
// below (2026-10-27, tap A: 「A:先削重复,余额按实测提高」).
// ceil($(wc -c < skills/objectstack-ui/evals/README.md) / 4) == ceil(1339 / 4)
['skills/objectstack-ui/evals/README.md', 335],
// 1102 -> 1229: the aggregate × field-type rule and the multi-value-dimension
// rule (card #24425, the skills half of cloud#2861 ruling B) each gain one
// regression case — a `formula` under `sum` and a `multiselect` as the
Expand Down Expand Up @@ -710,6 +718,17 @@ export const CEILINGS = new Map([
// Maintainer ruling 2026-10-27 (Warren, decision card 「skills 修复卡的教学和 eval 都撞 token 天花板,怎么付?」,
// option A tapped at 01:21Z), verbatim and untranslated: 「A:先削重复,余额按实测提高」.
['skills/objectstack-ui/evals/analytics-inline-vs-dataset.json', 1348],
// INITIAL measurement (#26633): the third authored eval file — ONE
// report-authoring prompt for `dateRange` on a `type: 'date'` dataset
// dimension and `exportOptions` csv / xlsx under the base object's
// `allowExport`, the eval owed by the spec PR that added both keys. A new
// file because both sibling eval files sat at headroom 0 and the analytics
// file was held by an open PR. Nothing in it restates anything (0 bytes
// cut); 1828 bytes -> 457 tokens, pinned AT the measurement — zero headroom,
// so the next token added here is paid for by deleting one from this file.
// Same ruling as the row above (2026-10-27, tap A: 「A:先削重复,余额按实测提高」).
// ceil($(wc -c < skills/objectstack-ui/evals/report-period-export.json) / 4) == ceil(1828 / 4)
['skills/objectstack-ui/evals/report-period-export.json', 457],

// objectstack-ui `rules/` — the five files the #14296 item 1 split created.
// Each row is an INITIAL measurement AT its landed count, so every one starts
Expand Down
3 changes: 3 additions & 0 deletions skills/objectstack-ui/evals/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ view / page / dashboard / report metadata.
dashboard/report widgets: when a data need fits a `defineDataset`, when it
must escalate to a stored field or app code, and when an ad-hoc
in-page `<ObjectChart>` needs no dataset at all.
- `report-period-export.json` — a non-`joined` report's `dateRange` (one
`type: 'date'` dataset dimension) and `exportOptions` (csv / xlsx under the
base object's `allowExport` permission).
- `views-apps-actions-pages.json` — `defineView` containers, `App.create`
navigation, `defineAction` surfaces, record / interface pages, package
docs, wizard forms.
Expand Down
16 changes: 16 additions & 0 deletions skills/objectstack-ui/evals/report-period-export.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"skill_name": "objectstack-ui",
"description": "Report period and export (ADR-0021 dataset reports): a non-joined report windows ONE `type: 'date'` dataset dimension through `dateRange` and declares its download in `exportOptions`; who may export stays the base object's `allowExport` permission.",
"evals": [
{
"id": 1,
"prompt": "The opportunity_metrics dataset (base object opportunity) declares the amount_sum measure and the stage and close_date dimensions (close_date is type: 'date', dateGranularity: 'quarter'). Add a pipeline-by-stage summary report that opens on the current quarter, lets the viewer pick another period, and lets users who may already export opportunities download the table as CSV or Excel. Emit the metadata.",
"expected_output": "One non-joined defineReport bound to opportunity_metrics (rows: ['stage'], values: ['amount_sum']) with `dateRange: { dimension: 'close_date', defaultRange: 'this_quarter', allowCustomRange: true }` — the dataset's `type: 'date'` dimension and the dashboard's own preset names, never a second preset table or a hand-rolled `runtimeFilter` window on close_date — and `exportOptions: { formats: ['csv', 'xlsx'] }` (optionally `includeHeaders` / `fileNamePrefix`). Who may download is the base object's existing permission-set `allowExport`, named in words: no report permission key is invented, and neither key is placed on a `joined` container (refused).",
"files": [],
"assertions": {
"must_contain": ["defineReport", "dateRange", "dimension: 'close_date'", "defaultRange: 'this_quarter'", "exportOptions", "'csv'", "'xlsx'", "allowExport"],
"must_not_contain": ["type: 'joined'", "blocks:", "close_date: {", "presets:", "permissions.export", "canExport", "allowExport: true", "'pdf'"]
}
}
]
}
Loading