You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Grid empty state says "No results found / Try adjusting your filters or search query." for an object that simply has no records and no filter #13142
预期:没有记录时说没有记录并给出新建入口(同一对象在 Studio Data 栏显示 "Nothing here yet / Create your first record to get started.");只有存在筛选或搜索时才提示调整筛选。
实际:显示 "No results found" 和 "Try adjusting your filters or search query.",但并没有筛选可调。
Claim: PM loop round 16 (priority:p3)
Session: session_01XVp19E1MYUTFM3dnkwz8gB
Account: baozhoutao (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-13142-grid-first-run-empty
Worktree: objectui-issue-13142
Domain: domain:ui
Seat: domain:ui#2
File surface (one root cause: the grid's empty row does not tell "no records" from "filtered to nothing"):
packages/plugin-grid/src/ObjectGrid.tsx: the grid, which knows its filters and search, supplies the first-run empty state when no query is active, through the existing emptyState replacement path (objectui#11068);
plugin-grid i18n rows only if no existing key fits (list.firstRunTitle and its kin are the precedent);
tests beside it;
one .changeset/13142-grid-first-run-empty.md (@object-ui/plugin-gridpatch).
⛔ packages/components/src/renderers/complex/data-table.tsx is not touched (objectui#13192 is open on it), and no new DataTable or schema prop. Stop on breach; explain in the report.
Container & model: S, mode:subagent, model: opus (default tier; no path-derived mandate)
Clause-②: no (internal render choice, no schema or prop change)
Responsibility: ObjectGrid passes DataTable's filtered-empty copy for an object with no records and no query | ListEmptyState already splits list.noMatches from list.firstRunTitle on hasActiveQuery | every user opening a grid on an empty object
Thread-read: none
Serial constraints cleared:
objectui#13192 (draft, another session) edits data-table.tsx; this card stays out of it.
os-dev-report
{
"issue": 13142,
"status": "done",
"branch": "claude/issue-13142-grid-first-run-empty",
"pr": "#13217",
"session": "session_01XVp19E1MYUTFM3dnkwz8gB",
"premise_still_valid": true,
"summary": "ObjectGrid now handles an empty grid itself when no emptyState is authored. With no search term and no declared filter it draws DataEmptyState with list.firstRunTitle / list.firstRunMessage. With a search term (its own box or the host search prop) it keeps the table row "No results found" and the hint. With a declared filter alone it draws list.noMatches / list.viewFilterNoMatchesMessage, the ListEmptyState precedent. An authored emptyState still wins wherever it did before. The four list.* defaults were added to GRID_DEFAULT_TRANSLATIONS, so no new key, prop or schema member. data-table.tsx is untouched. Premise verified on origin/main 3cec090: the table row was the only default and its condition reads only the row count. Note: in ListView, the flat and grouped grids are pre-empted by ListView own ListEmptyState, so the reporter surface is a host that mounts object-grid directly (for example ObjectView without renderListView). Not browser-measured.",
"tests": "All at HEAD 700c5b9, vitest --maxWorkers=1 under os-verify-lock. (1) New ObjectGrid.firstRunEmptyState-13142.test.tsx plus 11068/11227/12270 empty-state files: Test Files 4 passed, Tests 36 passed. (2) Every test file in plugin-grid / plugin-view / plugin-list / app-shell / apps/console that names object-grid or ObjectGrid and builds an empty fixture: plugin-grid 18 files 147 passed; plugin-view 34 files 339 passed; app-shell+plugin-list+console 15 files 246 passed; registry-inputs-spec-parity 260 passed. Full package directories are declared to CI, not run. (3) Closure build --filter @object-ui/plugin-grid^... exit 0; pnpm --filter @object-ui/plugin-grid type-check exit 0; tsc -p tsconfig.test.json --listFiles includes both edited and new test files. (4) eslint, package semantics, on 3 changed files: 0 errors and 223 warnings, the same 223 as ObjectGrid.tsx at base. With --no-inline-config there is 1 error, the pre-existing static-components line whose disable comment that flag ignores; my diff did not add it. (5) Battery, all exit 0: phantom-deps, self-import, unreferenced-sources, doc-example-readers, handler-key-reads, side-effects-array, element-data-source-declaration, spec-symbols, action-forward-parity, designer-field-key-parity, icon-record-names, i18n-keys, i18n-drift, i18n-designer-parity, control-bytes, check-hand-rolled-comment-mask, check-changeset-fixed, check-changeset-presence. (6) Ablation via objectstack scripts/ablation-replace.mjs, src-resolved test with no dist: userQueryEmptiedRows forced to true, anchor x1 to x0, blob 817693dd260f to 92642afcaf73. Result: 4 failed / 6 passed, the 3 (a) rows and the (c) filter-alone row. Restore: blob after = HEAD blob 817693dd260f and git diff HEAD empty, re-checked by git hash-object.",
"mcp_calls": "0",
"api_writes": "2 relay strokes so far: pr_create (POST /repos/objectstack-ai/objectui/pulls draft + POST /issues/13217/assignees, read back identical, assignee baozhoutao) and this os-dev-report comment (POST /repos//issues/13142/comments). Plus 2 git pushes (empty branch probe, 700c5b9). Zero label writes: objectui and dispatch named none.",
"open_questions": [
{
"question": "Pin (c) as worded ("0 rows with a user filter shows the same as (b)") cannot be expressed at ObjectGrid. The grid has no user-filter or quick-filter control. The only host that hands it a user filter is ListView (grouped server fetch), which merges it into filter (selfQueryFilter), and ListView draws its own ListEmptyState first from its window under the same filter. So on every surface where the grid empty state is visible, filter is the view base filter. I pinned (c) as "filter + term = (b)" and "filter alone: never first-run, never adjust-your-filters". Is this acceptable?",
"options": [
"A accept as implemented",
"B add a host prop telling the grid the filter is the user one (a new prop, outside the claimed surface)"
],
"recommendation": "A: the ambiguous path is pre-empted by ListView, and B adds surface with no visible consumer."
},
{
"question": "A declared (base) filter with 0 rows: rulings 1/4 read strictly give the first-run copy. I used the ListEmptyState view-filter copy (No matching records / No records match this view filter) so the grid does not repeat objectui#4155 (first-run invitation over a filtered view of a full object). Keep it?",
"options": [
"A keep view-filter copy (implemented)",
"B first-run copy for base filter too"
],
"recommendation": "A: it matches the named precedent, and B reintroduces a measured defect class."
}
],
"out_of_scope_findings": [
"carrier: objectui#13192 (open on data-table.tsx) · DataTable own empty row still says Try adjusting your filters wherever DataTable is used without ObjectGrid (e.g. ObjectDataTable in plugin-dashboard); noted, not filed"
],
"gates": "see tests; all exit 0 at 700c5b9",
"files_changed": [
"packages/plugin-grid/src/ObjectGrid.tsx",
"packages/plugin-grid/src/tests/ObjectGrid.firstRunEmptyState-13142.test.tsx",
"packages/plugin-grid/src/tests/ObjectGrid.declaredKeys-11068.test.tsx",
".changeset/13142-grid-first-run-empty.md"
],
"deviations": "none on the write path; worktree removed after PR. Literal pin (c) reinterpreted (see open_questions[0])."
}
os-dev-report addendum (patch round 1, head 2c9922c)
CI on 700c5b9 was red in "Test (shard 4/16)" on gridNeedsDataSourceBareArray-9580.test.tsx. My family sweep missed it: it built the file set from empty-array fixtures, and this file empties the grid through bind with nothing bound.
9580, row 5 (bind CONTROL). The column header was only a probe for "the block rendered and the gate stayed silent". The row now finds the grid's own object-grid-empty-state test id instead. Its subject is unchanged: no no-data-source panel for a bind placement. No bare-array behaviour moved, since rows 1-2 (the gate fires for a bare array) still pass. Commit 9c22ed2.
A second casualty found by the re-sweep:columnSpellingDiagnosticRender.test.tsx, the objectui#8348 bare-array row. It is a row-less grid whose renderGrid helper read headers with getAllByRole, so it threw. The helper now uses queryAllByRole. The other rows assert exact header lists, so an empty list still fails them. The 8348 row asserts the empty state and an empty header list. Its subject is unchanged: the diagnostic stays silent for good columns and fires once for bad ones, and both legs pass. Commit 2c9922c.
Re-sweep 1, the copy strings. I grepped tests for No results found, table.noResults, noResultsHint and Try adjusting your filters. The hits that can reach ObjectGrid are the 3 plugin-grid empty-state files and registry-inputs-spec-parity. The others are DataTable or ObjectDataTable tests plus the CommandPalette test, which cannot reach the grid. All 14 non-snapshot hits plus 9580 ran: 15 files, 399 tests passed.
Re-sweep 2, the wider set. Every test file in plugin-grid not run in round 0 (155 files, in 3 batches): 49/330, 53/487 (the 1 failure is the columnSpelling row above, fixed and re-run 13/13), and 53/482. Every test file in plugin-list and plugin-view that names object-grid or ObjectGrid and was not run in round 0: 80 files, 814 tests passed. Together with round 0, every plugin-grid test file has now run locally.
Gates at 2c9922c. The closure build plus pnpm --filter @object-ui/plugin-grid type-check exit 0. eslint on the 2 edited tests gives 0 errors, with the same warning counts as base (2 and 3). The full pre-tsc battery, comment-mask, changeset-fixed and changeset-presence all exit 0. Not run locally (left to CI): the app-shell, console and other packages' grid-naming files outside the round-0 set.
PR body not edited. One addendum stroke on the relay.
Clause-②: no. No new prop, key or schema member; data-table.tsx is untouched. No contract review is owed, and the seat read the report.
Seat review: with no authored emptyState, ObjectGrid now draws its own empty state. With no search term and no declared filter, it shows the first-run copy (list.firstRunTitle / list.firstRunMessage). With a search term (its own box or the host search prop), it keeps "No results found" and the hint. With a declared filter alone, it shows the ListEmptyState view-filter copy (list.noMatches / list.viewFilterNoMatchesMessage). An authored emptyState still wins wherever it did. The four list.* defaults sit in GRID_DEFAULT_TRANSLATIONS.
Dev questions, ruled by the seat:
Q1, pin (c): A. ObjectGrid holds no user-filter control; the one host that passes a user filter (ListView) draws its own ListEmptyState first. The pin as re-expressed ("filter + term" = (b); "filter alone" is never first-run and never "adjust your filters") holds the ruled behaviour without a new prop.
Q2, base filter alone: A. It keeps the view-filter copy, the ListEmptyState precedent, and avoids objectui#4155's first-run invitation over a filtered view of a full object. Ruling 4 put a base filter outside "user query" so as not to call it adjustable. This copy honours that, and the order's literal first-run reading is superseded.
Pins: the new file covers first-run, search, filter + term, and filter alone, with the authored-emptyState CONTROLs. The ablation (userQueryEmptiedRows forced true) turned the first-run and filter-alone rows red, and the restore was proven by blob. The grid, view, list, app-shell and console families that build an empty fixture are green.
Patch round 1 (after CI red on 700c5b98d0, shard 4/16): two existing pins used the old table row as a probe for "the grid rendered". gridNeedsDataSourceBareArray-9580 row 5 now finds object-grid-empty-state, and its subject (no no-data-source panel for a bind placement) is unchanged. columnSpellingDiagnosticRender's helper reads headers with queryAllByRole, and the objectui#8348 diagnostic legs are unchanged. The re-sweep ran every plugin-grid test file, plus 80 plugin-list and plugin-view files naming the grid.
Changeset: @object-ui/plugin-gridpatch.
CI: all 36 check-runs completed on the head, 33 passed and 3 skipped.
Path fork: no governed path. Seat landing.
Findings: Acceptance notes. DataTable's own empty row still says "Try adjusting your filters" wherever it is mounted without ObjectGrid (for example ObjectDataTable in plugin-dashboard). Its reach is unmeasured, and data-table.tsx is held by the open objectui#13192, so it is not filed here. The browser pass was not measured.
Next: ready + auto-merge; landing is verified by content on main.
Verified by content: each of the 6 files the PR changes has the same blob at f0300beff2 as at the accepted head 2c9922ceb8. The merge message carries no model identifier.
Landed: with no authored emptyState, an empty ObjectGrid draws a first-run state ("Nothing here yet") when no search term and no declared filter are in force. A declared filter alone shows the view-filter copy, and a search term keeps "No results found".
Activity
objectstack-fleet commentedon Oct 20, 2026
Claim: PM loop round 16 (
priority:p3)Session:
session_01XVp19E1MYUTFM3dnkwz8gBAccount:
baozhoutao(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-13142-grid-first-run-emptyWorktree:
objectui-issue-13142Domain:
domain:uiSeat:
domain:ui#2File surface (one root cause: the grid's empty row does not tell "no records" from "filtered to nothing"):
packages/plugin-grid/src/ObjectGrid.tsx: the grid, which knows its filters and search, supplies the first-run empty state when no query is active, through the existingemptyStatereplacement path (objectui#11068);list.firstRunTitleand its kin are the precedent);.changeset/13142-grid-first-run-empty.md(@object-ui/plugin-gridpatch).⛔
packages/components/src/renderers/complex/data-table.tsxis not touched (objectui#13192 is open on it), and no new DataTable or schema prop. Stop on breach; explain in the report.Container & model:
S,mode:subagent,model: opus(default tier; no path-derived mandate)Clause-②: no (internal render choice, no schema or prop change)
Responsibility:
ObjectGridpasses DataTable's filtered-empty copy for an object with no records and no query |ListEmptyStatealready splitslist.noMatchesfromlist.firstRunTitleonhasActiveQuery| every user opening a grid on an empty objectThread-read: none
Serial constraints cleared:
data-table.tsx; this card stays out of it.aaa1296f94,plugin-grid) landed.ObjectGrid.tsx(read at 08:45Z).Claimed at: 2026-10-20T08:39Z
Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
os-dev-report
{
"issue": 13142,
"status": "done",
"branch": "claude/issue-13142-grid-first-run-empty",
"pr": "#13217",
"session": "session_01XVp19E1MYUTFM3dnkwz8gB",
"premise_still_valid": true,
"summary": "ObjectGrid now handles an empty grid itself when no emptyState is authored. With no search term and no declared filter it draws DataEmptyState with list.firstRunTitle / list.firstRunMessage. With a search term (its own box or the host search prop) it keeps the table row "No results found" and the hint. With a declared filter alone it draws list.noMatches / list.viewFilterNoMatchesMessage, the ListEmptyState precedent. An authored emptyState still wins wherever it did before. The four list.* defaults were added to GRID_DEFAULT_TRANSLATIONS, so no new key, prop or schema member. data-table.tsx is untouched. Premise verified on origin/main 3cec090: the table row was the only default and its condition reads only the row count. Note: in ListView, the flat and grouped grids are pre-empted by ListView own ListEmptyState, so the reporter surface is a host that mounts object-grid directly (for example ObjectView without renderListView). Not browser-measured.",
"tests": "All at HEAD 700c5b9, vitest --maxWorkers=1 under os-verify-lock. (1) New ObjectGrid.firstRunEmptyState-13142.test.tsx plus 11068/11227/12270 empty-state files: Test Files 4 passed, Tests 36 passed. (2) Every test file in plugin-grid / plugin-view / plugin-list / app-shell / apps/console that names object-grid or ObjectGrid and builds an empty fixture: plugin-grid 18 files 147 passed; plugin-view 34 files 339 passed; app-shell+plugin-list+console 15 files 246 passed; registry-inputs-spec-parity 260 passed. Full package directories are declared to CI, not run. (3) Closure build --filter @object-ui/plugin-grid^... exit 0; pnpm --filter @object-ui/plugin-grid type-check exit 0; tsc -p tsconfig.test.json --listFiles includes both edited and new test files. (4) eslint, package semantics, on 3 changed files: 0 errors and 223 warnings, the same 223 as ObjectGrid.tsx at base. With --no-inline-config there is 1 error, the pre-existing static-components line whose disable comment that flag ignores; my diff did not add it. (5) Battery, all exit 0: phantom-deps, self-import, unreferenced-sources, doc-example-readers, handler-key-reads, side-effects-array, element-data-source-declaration, spec-symbols, action-forward-parity, designer-field-key-parity, icon-record-names, i18n-keys, i18n-drift, i18n-designer-parity, control-bytes, check-hand-rolled-comment-mask, check-changeset-fixed, check-changeset-presence. (6) Ablation via objectstack scripts/ablation-replace.mjs, src-resolved test with no dist: userQueryEmptiedRows forced to true, anchor x1 to x0, blob 817693dd260f to 92642afcaf73. Result: 4 failed / 6 passed, the 3 (a) rows and the (c) filter-alone row. Restore: blob after = HEAD blob 817693dd260f and git diff HEAD empty, re-checked by git hash-object.",
"mcp_calls": "0",
"api_writes": "2 relay strokes so far: pr_create (POST /repos/objectstack-ai/objectui/pulls draft + POST /issues/13217/assignees, read back identical, assignee baozhoutao) and this os-dev-report comment (POST /repos//issues/13142/comments). Plus 2 git pushes (empty branch probe, 700c5b9). Zero label writes: objectui and dispatch named none.",
"open_questions": [
{
"question": "Pin (c) as worded ("0 rows with a user filter shows the same as (b)") cannot be expressed at ObjectGrid. The grid has no user-filter or quick-filter control. The only host that hands it a user filter is ListView (grouped server fetch), which merges it into filter (selfQueryFilter), and ListView draws its own ListEmptyState first from its window under the same filter. So on every surface where the grid empty state is visible, filter is the view base filter. I pinned (c) as "filter + term = (b)" and "filter alone: never first-run, never adjust-your-filters". Is this acceptable?",
"options": [
"A accept as implemented",
"B add a host prop telling the grid the filter is the user one (a new prop, outside the claimed surface)"
],
"recommendation": "A: the ambiguous path is pre-empted by ListView, and B adds surface with no visible consumer."
},
{
"question": "A declared (base) filter with 0 rows: rulings 1/4 read strictly give the first-run copy. I used the ListEmptyState view-filter copy (No matching records / No records match this view filter) so the grid does not repeat objectui#4155 (first-run invitation over a filtered view of a full object). Keep it?",
"options": [
"A keep view-filter copy (implemented)",
"B first-run copy for base filter too"
],
"recommendation": "A: it matches the named precedent, and B reintroduces a measured defect class."
}
],
"out_of_scope_findings": [
"carrier: objectui#13192 (open on data-table.tsx) · DataTable own empty row still says Try adjusting your filters wherever DataTable is used without ObjectGrid (e.g. ObjectDataTable in plugin-dashboard); noted, not filed"
],
"gates": "see tests; all exit 0 at 700c5b9",
"files_changed": [
"packages/plugin-grid/src/ObjectGrid.tsx",
"packages/plugin-grid/src/tests/ObjectGrid.firstRunEmptyState-13142.test.tsx",
"packages/plugin-grid/src/tests/ObjectGrid.declaredKeys-11068.test.tsx",
".changeset/13142-grid-first-run-empty.md"
],
"deviations": "none on the write path; worktree removed after PR. Literal pin (c) reinterpreted (see open_questions[0])."
}
objectstack-fleet commentedon Oct 20, 2026
os-dev-report addendum (patch round 1, head 2c9922c)
CI on 700c5b9 was red in "Test (shard 4/16)" on
gridNeedsDataSourceBareArray-9580.test.tsx. My family sweep missed it: it built the file set from empty-array fixtures, and this file empties the grid throughbindwith nothing bound.bindCONTROL). The column header was only a probe for "the block rendered and the gate stayed silent". The row now finds the grid's ownobject-grid-empty-statetest id instead. Its subject is unchanged: no no-data-source panel for abindplacement. No bare-array behaviour moved, since rows 1-2 (the gate fires for a bare array) still pass. Commit 9c22ed2.columnSpellingDiagnosticRender.test.tsx, the objectui#8348 bare-array row. It is a row-less grid whoserenderGridhelper read headers withgetAllByRole, so it threw. The helper now usesqueryAllByRole. The other rows assert exact header lists, so an empty list still fails them. The 8348 row asserts the empty state and an empty header list. Its subject is unchanged: the diagnostic stays silent for good columns and fires once for bad ones, and both legs pass. Commit 2c9922c.Re-sweep 1, the copy strings. I grepped tests for
No results found,table.noResults,noResultsHintandTry adjusting your filters. The hits that can reachObjectGridare the 3 plugin-grid empty-state files andregistry-inputs-spec-parity. The others are DataTable or ObjectDataTable tests plus the CommandPalette test, which cannot reach the grid. All 14 non-snapshot hits plus 9580 ran: 15 files, 399 tests passed.Re-sweep 2, the wider set. Every test file in plugin-grid not run in round 0 (155 files, in 3 batches): 49/330, 53/487 (the 1 failure is the columnSpelling row above, fixed and re-run 13/13), and 53/482. Every test file in plugin-list and plugin-view that names object-grid or ObjectGrid and was not run in round 0: 80 files, 814 tests passed. Together with round 0, every plugin-grid test file has now run locally.
Gates at 2c9922c. The closure build plus
pnpm --filter @object-ui/plugin-grid type-checkexit 0. eslint on the 2 edited tests gives 0 errors, with the same warning counts as base (2 and 3). The full pre-tsc battery, comment-mask, changeset-fixed and changeset-presence all exit 0. Not run locally (left to CI): the app-shell, console and other packages' grid-naming files outside the round-0 set.PR body not edited. One addendum stroke on the relay.
Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
ACCEPT — PR #13217 @
2c9922ceb84cc2bfc69cd551ac4d3f60193c299c·domain:uiseat 2 (session_01XVp19E1MYUTFM3dnkwz8gB)data-table.tsxis untouched. No contract review is owed, and the seat read the report.emptyState,ObjectGridnow draws its own empty state. With no search term and no declared filter, it shows the first-run copy (list.firstRunTitle/list.firstRunMessage). With a search term (its own box or the hostsearchprop), it keeps "No results found" and the hint. With a declared filter alone, it shows theListEmptyStateview-filter copy (list.noMatches/list.viewFilterNoMatchesMessage). An authoredemptyStatestill wins wherever it did. The fourlist.*defaults sit inGRID_DEFAULT_TRANSLATIONS.ObjectGridholds no user-filter control; the one host that passes a user filter (ListView) draws its ownListEmptyStatefirst. The pin as re-expressed ("filter + term" = (b); "filter alone" is never first-run and never "adjust your filters") holds the ruled behaviour without a new prop.ListEmptyStateprecedent, and avoids objectui#4155's first-run invitation over a filtered view of a full object. Ruling 4 put a base filter outside "user query" so as not to call it adjustable. This copy honours that, and the order's literal first-run reading is superseded.emptyStateCONTROLs. The ablation (userQueryEmptiedRowsforced true) turned the first-run and filter-alone rows red, and the restore was proven by blob. The grid, view, list, app-shell and console families that build an empty fixture are green.700c5b98d0, shard 4/16): two existing pins used the old table row as a probe for "the grid rendered".gridNeedsDataSourceBareArray-9580row 5 now findsobject-grid-empty-state, and its subject (no no-data-source panel for abindplacement) is unchanged.columnSpellingDiagnosticRender's helper reads headers withqueryAllByRole, and the objectui#8348 diagnostic legs are unchanged. The re-sweep ran every plugin-grid test file, plus 80 plugin-list and plugin-view files naming the grid.@object-ui/plugin-gridpatch.DataTable's own empty row still says "Try adjusting your filters" wherever it is mounted withoutObjectGrid(for exampleObjectDataTablein plugin-dashboard). Its reach is unmeasured, anddata-table.tsxis held by the open objectui#13192, so it is not filed here. The browser pass was not measured.Next: ready + auto-merge; landing is verified by content on
main.Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
Landed ·
domain:uiseat 2 ·session_01XVp19E1MYUTFM3dnkwz8gBmainf0300beff2.f0300beff2as at the accepted head2c9922ceb8. The merge message carries no model identifier.emptyState, an emptyObjectGriddraws a first-run state ("Nothing here yet") when no search term and no declared filter are in force. A declared filter alone shows the view-filter copy, and a search term keeps "No results found".pm:dispatchedis removed.Generated by Claude Code
fix(plugin-grid): an empty grid with no query draws the first-run sta…