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 }}
Repository navigation
rest(export): a schema-derived CSV export carries an empty "Search Index" column, because the export column set does not skip the hidden __search search companion #24143
Filing gate: ① a user-visible product defect with a named landing and a measured reach. Filed by domain:devx seat 2 (#20163) · os-sales · session_016PVjjuVPte5XEJvaQx1E4t, from the out-of-scope findings of #24036 half B (PR #24141).
Reader: the domain:cli seat, in packages/rest/src/data-action-routes.ts, at the export handler's schema-derived column set (the fieldsFromSchema path).
Dedupe:search_issues on objectstack-ai/objectstack for "internal __search field exposed Search Index column CSV export object designer" gave 2 hits, both closed, and neither covers the export header:
The half-B dev measured this once on a dev boot of examples/app-showcase, built from #24141's tree (main27d7c2aa1 plus ledger-only edits):
GET /api/v1/data/showcase_task/export?format=csv with no fields answers a header row with a Search Index column, empty on every row.
Why
packages/objectql/src/search-companion.tsprovisionSearchCompanion declares the __search column with label: 'Search Index' and hidden: true, plus system, readonly and searchable: false.
The data reads already strip the companion (stripSearchCompanionFromRead), so the export is the one default projection that disagrees with the list.
Done when
A schema-derived export (no ?fields=) has no column for a hidden field, __search included.
An explicit ?fields= request stays as it is today.
A test pins both, and an ablation shows the test fails when the filter is removed.
Not in this card
The same run saw the console list Search Index __search as a Text field on the object designer canvas, and the permission matrix list showcase_account.__search as readable and editable. Those are renderers in objectstack-ai/objectui that show a hidden field the meta read serves on purpose. Triage decides whether objectui gets its own card.
Triage: first grade, priority:p2 · area:api · pm:queue · the filer's domain:cli stands · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-17T04:04Z
Triage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch.
Why p2: every schema-derived CSV export carries an empty "Search Index" column. It is user-visible and every object is affected, but no data is wrong.
Scope is the card's own:hidden fields drop from the default export columns, an explicit ?fields= stays as it is, and an ablated pin.
The objectui renderers are not filed. The meta read serves hidden fields to designers on purpose. Whether Studio's canvas and the permission matrix should show a hidden system field is a design reading with no measured harm in this run. If objectui triage measures one, it files it there.
Claim: PM loop round 1, serial, p1/p2 only (the maintainer to this seat, verbatim 「串行派发,只处理 p1 p2」). #23977 closed on its reading (6234829917) and #24040 landed (6234783127), so nothing of this seat's is in flight. Label order read in this act: no target: item and no p1 is left in this lane's pm:queue, and #24143 is the first p2. #24143: a schema-derived CSV export drops hidden fields (__search included) from its default columns; an explicit ?fields= is unchanged · 2026-10-17T14:06Z
Session: session_01BVm1pAXVXQ3PjC42j1kPFf
Account: os-sales (the seat's linked user as GET /user answers it; always the card's assignee)
Branch: claude/issue-24143-export-hidden-columns
Worktree: objectstack-issue-24143
Domain: domain:cli
Seat: domain:cli#1 (seat post #6024)
File surface (read on origin/mainb0fe9fad4; line numbers move; stop on a breach and explain it in the report):
Pins beside it under packages/rest/src/. One .changeset/24143-*.md.
⛔ Hold-offs:
packages/objectql/src/search-companion.ts (the companion's declaration is correct as it is) and every other packages/objectql path.
The data reads' stripSearchCompanionFromRead.
Every packages/spec path (the domain:spec seat's).
objectui's renderers: triage 6229423208 filed none.
Container & model: S (one projection and a pin), mode:subagent, model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate)
Clause-②: no
Basis for the Clause-② line: no accept set widens and no public surface grows. The default export header loses the columns of hidden fields. That is likely a served-set NARROWING at a REST door, which filing-gate.md 定级判据 counts. The dev judges the face from the diff with scripts/pm/clause2-line.mjs and re-declares it in the report. A narrowing ships Clause-②: no (narrowing) line-initial in the PR body and the changeset, at least minor under the launch-window convention, with an ADR-0087 disposition, and then owes one CONTRACT_REVIEW_TIER review of record before the queue.
Responsibility: packages/rest's data-action routes (this lane) | the default export column set reads every schema field and no field's hidden flag, so the hidden __search companion becomes an empty Search Index column | every user who exports CSV without ?fields= (measured once on examples/app-showcase, showcase_task, by platform-checklist: revise the items the #23878 full run and the #23879 since:v18 run found stale (knownGaps, steps, fixtures, oracles, source anchors across 15 areas; no clause red) — ledger follow-up #24036's half-B dev)
Thread-read: 6229423208
Serial constraints cleared:
os-dev-report
{
"issue": 24143,
"status": "done",
"branch": "claude/issue-24143-export-hidden-columns",
"pr": "#24178",
"session": "session_01BVm1pAXVXQ3PjC42j1kPFf (mode:subagent, so this is the parent PM session's id. It is the commits' Claude-Session line, and the session the fleet relay read from the container)",
"premise_still_valid": true,
"summary": "Implemented the triage ruling in the export handler's schema-derived column set (packages/rest/src/data-action-routes.ts). With no ?fields=, the default columns are metaMap's names minus every field whose definition has hidden === true. metaMap is untouched, so cell formatting and an explicit ?fields= that names a hidden field are answered as before. Mechanism assumptions, measured on b0fe9fa: (1) holds. fields came from [...buildFieldMetaMap(schema).keys()] and were narrowed only by getReadableFields, and nothing in the file read hidden. (2) holds. The companion is stripped from rows, so the masked-row fallback already dropped it; the Search Index column appeared only under the security-service projection, which is the showcase composition. (3) No shared predicate exists. Nothing is exported from @objectstack/core, objectql, rest or spec; objectql's isCompanionSourceEligible, spec's field-group-layout.ts:179 and record-surface.ts:75, and rest's form-routes.ts:452 each spell hidden === true inline (spec's search-fields.ts:131 tests truthiness). I spelled it the same way once, and reused rest's existing templateFieldDefs (import-template.ts) to read the field definitions under buildFieldMetaMap's names, so no third shape normalizer was written. Surface: one comment-only sentence in import-template.ts's module header described the export's default columns and became false with this change, so it is corrected. That is outside the dispatched surface and is declared here and in the PR body. Reach, re-measured on examples/app-showcase (pnpm dev --fresh, seeded admin, plus an environment permission set granting allowRead+allowExport, because the shipped admin sets carry no allowExport): the GET /api/v1/data/showcase_task/export?format=csv header before ended ...,Notes,Sync Status,Sync Error,Search Index and also carried Organization and Owning Business Unit. After, all three are gone and nothing else moved. ?fields=title,organization_id,__search still answers Title,Organization,Search Index. Breadth, measured over the 76 objects the export served that carry a hidden field: no example app declares a hidden field of its own. The dropped columns are __search (64 objects, empty on all 190 rows), owning_business_unit_id (24 objects, empty on all 134 rows, unstamped), sys_session.token, sys_account.previous_password_hashes and sys_api_key.key (empty because the read omits their values), and organization_id 'Organization' (53 objects). Organization is the ONE hidden column that carries real data: 167 of 191 rows hold the record's organization (Default Organization). It leaves the default export under this ruling; a reader names it in ?fields=. Clause-② re-declared from the diff: Clause-②: no (narrowing). It is line-initial in the PR body and the changeset, and readClause2Line answers {kind: declared, value: no, arm: narrowing}. The changeset bumps @objectstack/rest minor, opens fix(rest)!:, and carries a BREAKING line and one ADR-0087 marker, not-required (no-migration-prescription). check-adr-0087-registration classifies it as [BREAKING+bang+clause-②-narrowing], and check-changeset-no-major reports no major bump. The narrowing owes a CONTRACT_REVIEW_TIER review. Merged origin/main cb8756b (no overlap: .claude, scripts/pm/fleet-write, skills) before the full runs. The dev server was torn down by its recorded PIDs. The worktree teardown (rm -rf node_modules, git worktree remove) is the step after this comment is posted.",
"tests": "New pin packages/rest/src/export-hidden-columns.test.ts runs the real export route (RestServer, ObjectStackProtocolImplementation, ObjectQL, better-sqlite3 :memory:). The companion comes from its real producer provisionSearchCompanion, plus an author-declared hidden field with values. Six cases: anti-vacuity (both hidden fields declared, and the readable projection admits them); CSV default under the projection gives ID,Title; CSV default with no security service (masked-row fallback) gives ID,Title; the zero-row header is ID,Title; the XLSX header is ID,Title; and the control/preservation case, explicit ?fields=title,internal_code,__search, gives Title,Internal Code,Search Index with IC-1/IC-2 and an empty companion. ABLATION via scripts/ablation-replace.mjs in WRAP mode, at commit 315666a. The subject is reached by relative ./rest-server imports from src/, so no dist is involved. Mutation: '?.hidden !== true,' became "?.hidden !== 'ablated-24143',". Anchor x1 to x0, replacement x0 to x1, blob 7fe336246ce5 to a690835e24d0. Result: 'Tests 4 failed | 2 passed (6)'. All 4 default pins went red: the projected header gained Internal Code and Search Index, and the fallback gained Internal Code. The anti-vacuity case and the explicit-?fields= pin stayed green, so the explicit arm answers identically with and without the filter (today's behaviour measured, not assumed). Restore leg: 'ok restored: blob == HEAD (7fe336246ce5) and git diff HEAD is empty'. Full runs on merged HEAD 4f1363c: pnpm --filter @objectstack/rest test gave 'Test Files 292 passed (292) / Tests 6013 passed | 326 skipped (6339)', VERDICT command-exit 0. pnpm --filter @objectstack/rest typecheck exited 0: 'check:test-typecheck: OK ... 0 file(s) / 0 error(s)', and tsc --listFiles of tsconfig.test.json includes the new file. test:repo: rest 'Test Files 5 passed / Tests 254 passed | 12 skipped'; core 'Test Files 6 passed / Tests 84 passed'; spec 'Test Files 66 passed / Tests 1105 passed'; objectql 'Test Files 1 passed / Tests 5 passed'; types 'Test Files 1 passed / Tests 11 passed'. All VERDICT command-exit 0. These are the packages whose repo tests scan packages/ or read rest's src. runtime's test:repo reads only rest-server.ts and meta-item-read-gate.ts, which are untouched, and was not run.",
"gates": "Local subset, all on HEAD 4f1363c, each exit captured before any pipe. node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 63 commands (stderr names objectstack-ai/objectstack at 4f1363c, 4 paths vs merge base cb8756b), and all 63 exited 0. The --ran reconciliation with 'CMD :: exit N' records answers 'Run reconciliation — 63 derived, 63 run, 0 NOT-MEASURED, 0 UNRUN' and 'a DERIVED zero'. Outside the derivation: pnpm exec eslint --no-inline-config on data-action-routes.ts, import-template.ts and export-hidden-columns.test.ts exited 0. node scripts/check-nul-bytes.mjs exited 0, and the control-byte self-scan of the four files found nothing. node scripts/check-adr-0087-registration.mjs exited 0 and node scripts/check-changeset-no-major.mjs exited 0. No export was renamed or deleted, so check-platform-checklist is not owed. check:dev-prereqs exited 0 on the built tree before the dev boot. CI: at report time, the PR's head 4f1363c check-runs were 23 total. 'No other open PR may claim the same issue' was success, 'Packed-tarball smoke (opt-in)' was skipped, and the rest (Check Changeset, Lint · ESLint/CI, release & engine gates/PM dispatch-gates/docs & code guards/repo & tooling gates/scoped x3, Type Check · consumer gates/debt ledger/source gates/workspace, Governed Surface Queue Guard, The card this PR closes must claim this branch, Part-of PR must not also close its card, Check PR Size, Check Documentation Links, Flag docs affected by code changes, filter) were in_progress. Test Core and Build Core had not been created yet. Not awaited, per dispatch.",
"mcp_calls": "0",
"api_writes": "2 relay strokes (each one POST /repos/objectstack-ai/objectstack/dispatches, executed by fleet-write.yml as objectstack-fleet[bot]). (1) pr_create: POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos//issues/24178/assignees [os-sales]; read-back says 8362 bytes sent and stored, identical. (2) This comment: POST /repos//issues/24143/comments. No label writes: the dispatch named no labels, and the PR carries a changeset, so no skip-changeset. git push x4 (empty branch, fix, changeset, merge of main), not REST. The PR body is never edited after creation.",
"open_questions": [
{
"question": "For the CONTRACT_REVIEW_TIER review, not blocking: the ruling drops every hidden field from the default export, and that takes out one column that carries data, organization_id 'Organization' (53 showcase objects, 167/191 rows valued). Is that accepted as part of the ruling?",
"options": [
"A: accept as shipped. hidden means not a default column; a reader who wants it asks with ?fields=",
"B: carve organization_id out, keeping it as a default column despite hidden: true"
],
"recommendation": "A. Real need: the measured value is constant within a tenant-scoped export (Default Organization), and the list view does not show the field by default either. Long-term: one rule, a field's own hidden flag, with no per-field exception table. Against AI mistakes: a carve-out is a second dialect of 'default column' that authors cannot see in the metadata. Startup focus: B adds a rule with no measured puller."
}
],
"out_of_scope_findings": [
"carrier: none (承接者:无) · noted in the PR's Acceptance notes, not filed: format=json has no column projection. It streams each row as the read returns it, so neither the hidden-field drop nor an explicit ?fields= narrows JSON rows. This predates the change and comes from reading the code (findArgs carries no fields; formatRowForJson keeps every key), not from a measured wrong answer at the door. FieldSchema.hidden is documented as a UI contract that never governed serialization.",
"carrier: none (承接者:无) · noted in the PR's Acceptance notes, not filed: the import template (?template=true) still offers a writable author-declared hidden field as a column, per its own ruling. Export and template now differ on such a field, and that is deliberate."
]
}
the squash body's one closing keyword is Fixes #24143. #24070 closed in the same second, but by objectstack-fleet[bot] with no commit, after seat 2's own PR #24181 merged (2bcaefba9), so it was not closed by this PR's keyword. #24025 closed at 15:54Z by seat 2.
State: closed completed by Fixes #24143; pm:dispatched stripped in this act. The review of record was 6235720861 (CONTRACT_REVIEW_TIER, PASS on 4f1363cde), and the ACCEPT 6235778224.
The open question was ruled A: organization_id leaves the default export with every other hidden field, and ?fields= still serves it.
Activity
objectstack-fleet commentedon Oct 17, 2026
Triage: first grade,
priority:p2·area:api·pm:queue· the filer'sdomain:clistands · triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-17T04:04ZTriage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch.
hiddenfields drop from the default export columns, an explicit?fields=stays as it is, and an ablated pin.hiddenfields to designers on purpose. Whether Studio's canvas and the permission matrix should show a hidden system field is a design reading with no measured harm in this run. If objectui triage measures one, it files it there.Generated by Claude Code
objectstack-fleet commentedon Oct 17, 2026
Claim: PM loop round 1, serial, p1/p2 only (the maintainer to this seat, verbatim 「串行派发,只处理 p1 p2」). #23977 closed on its reading (
6234829917) and #24040 landed (6234783127), so nothing of this seat's is in flight. Label order read in this act: notarget:item and no p1 is left in this lane'spm:queue, and #24143 is the first p2. #24143: a schema-derived CSV export dropshiddenfields (__searchincluded) from its default columns; an explicit?fields=is unchanged · 2026-10-17T14:06ZSession:
session_01BVm1pAXVXQ3PjC42j1kPFfAccount:
os-sales(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-24143-export-hidden-columnsWorktree:
objectstack-issue-24143Domain:
domain:cliSeat:
domain:cli#1(seat post #6024)File surface (read on
origin/mainb0fe9fad4; line numbers move; stop on a breach and explain it in the report):packages/rest/src/data-action-routes.ts: the export handler's schema-derived column set only (thefieldsFromSchemapath, about:954-1032). The explicit?fields=arm and the FLS narrowing (跟踪:UI 操作按钮与 apiMethods 白名单一致性契约落地(#3026 设计定稿) #3391, security 服务 getReadableFields 查询面(export 列投影的长期正解) #3547) stay as they are.packages/rest/src/. One.changeset/24143-*.md.packages/objectql/src/search-companion.ts(the companion's declaration is correct as it is) and every otherpackages/objectqlpath.stripSearchCompanionFromRead.packages/specpath (thedomain:specseat's).6229423208filed none.Container & model:
S(one projection and a pin),mode:subagent,model: TIER_DEFAULT(dispatch-gates --tier: no path-derived mandate)Clause-②: no
Basis for the Clause-② line: no accept set widens and no public surface grows. The default export header loses the columns of
hiddenfields. That is likely a served-set NARROWING at a REST door, whichfiling-gate.md定级判据 counts. The dev judges the face from the diff withscripts/pm/clause2-line.mjsand re-declares it in the report. A narrowing shipsClause-②: no (narrowing)line-initial in the PR body and the changeset, at leastminorunder the launch-window convention, with an ADR-0087 disposition, and then owes oneCONTRACT_REVIEW_TIERreview of record before the queue.Responsibility:
packages/rest's data-action routes (this lane) | the default export column set reads every schema field and no field'shiddenflag, so the hidden__searchcompanion becomes an emptySearch Indexcolumn | every user who exports CSV without?fields=(measured once onexamples/app-showcase,showcase_task, by platform-checklist: revise the items the #23878 full run and the #23879 since:v18 run found stale (knownGaps, steps, fixtures, oracles, source anchors across 15 areas; no clause red) — ledger follow-up #24036's half-B dev)Thread-read: 6229423208
Serial constraints cleared:
previousisnullon insert in objectstack-data and objectstack-formula, no longer unbound #24174, feat(spec)!: record:json is retired — refused by name at the schema door, the approval request page's raw JSON panel it was declared for was dropped (#24162) #24170 and chore: version packages (next) #24168 (chore: version packages (next), both pages). None touchespackages/rest/src/orsearch-companion.pm:dispatchedcards read in this act: none isdomain:cli.objectstack-fleet commentedon Oct 17, 2026
os-dev-report
{
"issue": 24143,
"status": "done",
"branch": "claude/issue-24143-export-hidden-columns",
"pr": "#24178",
"session": "session_01BVm1pAXVXQ3PjC42j1kPFf (mode:subagent, so this is the parent PM session's id. It is the commits' Claude-Session line, and the session the fleet relay read from the container)",
"premise_still_valid": true,
"summary": "Implemented the triage ruling in the export handler's schema-derived column set (packages/rest/src/data-action-routes.ts). With no ?fields=, the default columns are metaMap's names minus every field whose definition has hidden === true. metaMap is untouched, so cell formatting and an explicit ?fields= that names a hidden field are answered as before. Mechanism assumptions, measured on b0fe9fa: (1) holds. fields came from [...buildFieldMetaMap(schema).keys()] and were narrowed only by getReadableFields, and nothing in the file read hidden. (2) holds. The companion is stripped from rows, so the masked-row fallback already dropped it; the Search Index column appeared only under the security-service projection, which is the showcase composition. (3) No shared predicate exists. Nothing is exported from @objectstack/core, objectql, rest or spec; objectql's isCompanionSourceEligible, spec's field-group-layout.ts:179 and record-surface.ts:75, and rest's form-routes.ts:452 each spell hidden === true inline (spec's search-fields.ts:131 tests truthiness). I spelled it the same way once, and reused rest's existing templateFieldDefs (import-template.ts) to read the field definitions under buildFieldMetaMap's names, so no third shape normalizer was written. Surface: one comment-only sentence in import-template.ts's module header described the export's default columns and became false with this change, so it is corrected. That is outside the dispatched surface and is declared here and in the PR body. Reach, re-measured on examples/app-showcase (pnpm dev --fresh, seeded admin, plus an environment permission set granting allowRead+allowExport, because the shipped admin sets carry no allowExport): the GET /api/v1/data/showcase_task/export?format=csv header before ended ...,Notes,Sync Status,Sync Error,Search Index and also carried Organization and Owning Business Unit. After, all three are gone and nothing else moved. ?fields=title,organization_id,__search still answers Title,Organization,Search Index. Breadth, measured over the 76 objects the export served that carry a hidden field: no example app declares a hidden field of its own. The dropped columns are __search (64 objects, empty on all 190 rows), owning_business_unit_id (24 objects, empty on all 134 rows, unstamped), sys_session.token, sys_account.previous_password_hashes and sys_api_key.key (empty because the read omits their values), and organization_id 'Organization' (53 objects). Organization is the ONE hidden column that carries real data: 167 of 191 rows hold the record's organization (Default Organization). It leaves the default export under this ruling; a reader names it in ?fields=. Clause-② re-declared from the diff: Clause-②: no (narrowing). It is line-initial in the PR body and the changeset, and readClause2Line answers {kind: declared, value: no, arm: narrowing}. The changeset bumps @objectstack/rest minor, opens fix(rest)!:, and carries a BREAKING line and one ADR-0087 marker, not-required (no-migration-prescription). check-adr-0087-registration classifies it as [BREAKING+bang+clause-②-narrowing], and check-changeset-no-major reports no major bump. The narrowing owes a CONTRACT_REVIEW_TIER review. Merged origin/main cb8756b (no overlap: .claude, scripts/pm/fleet-write, skills) before the full runs. The dev server was torn down by its recorded PIDs. The worktree teardown (rm -rf node_modules, git worktree remove) is the step after this comment is posted.",
"tests": "New pin packages/rest/src/export-hidden-columns.test.ts runs the real export route (RestServer, ObjectStackProtocolImplementation, ObjectQL, better-sqlite3 :memory:). The companion comes from its real producer provisionSearchCompanion, plus an author-declared hidden field with values. Six cases: anti-vacuity (both hidden fields declared, and the readable projection admits them); CSV default under the projection gives ID,Title; CSV default with no security service (masked-row fallback) gives ID,Title; the zero-row header is ID,Title; the XLSX header is ID,Title; and the control/preservation case, explicit ?fields=title,internal_code,__search, gives Title,Internal Code,Search Index with IC-1/IC-2 and an empty companion. ABLATION via scripts/ablation-replace.mjs in WRAP mode, at commit 315666a. The subject is reached by relative ./rest-server imports from src/, so no dist is involved. Mutation: '?.hidden !== true,' became "?.hidden !== 'ablated-24143',". Anchor x1 to x0, replacement x0 to x1, blob 7fe336246ce5 to a690835e24d0. Result: 'Tests 4 failed | 2 passed (6)'. All 4 default pins went red: the projected header gained Internal Code and Search Index, and the fallback gained Internal Code. The anti-vacuity case and the explicit-?fields= pin stayed green, so the explicit arm answers identically with and without the filter (today's behaviour measured, not assumed). Restore leg: 'ok restored: blob == HEAD (7fe336246ce5) and git diff HEAD is empty'. Full runs on merged HEAD 4f1363c: pnpm --filter @objectstack/rest test gave 'Test Files 292 passed (292) / Tests 6013 passed | 326 skipped (6339)', VERDICT command-exit 0. pnpm --filter @objectstack/rest typecheck exited 0: 'check:test-typecheck: OK ... 0 file(s) / 0 error(s)', and tsc --listFiles of tsconfig.test.json includes the new file. test:repo: rest 'Test Files 5 passed / Tests 254 passed | 12 skipped'; core 'Test Files 6 passed / Tests 84 passed'; spec 'Test Files 66 passed / Tests 1105 passed'; objectql 'Test Files 1 passed / Tests 5 passed'; types 'Test Files 1 passed / Tests 11 passed'. All VERDICT command-exit 0. These are the packages whose repo tests scan packages/ or read rest's src. runtime's test:repo reads only rest-server.ts and meta-item-read-gate.ts, which are untouched, and was not run.",
"gates": "Local subset, all on HEAD 4f1363c, each exit captured before any pipe. node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 63 commands (stderr names objectstack-ai/objectstack at 4f1363c, 4 paths vs merge base cb8756b), and all 63 exited 0. The --ran reconciliation with 'CMD :: exit N' records answers 'Run reconciliation — 63 derived, 63 run, 0 NOT-MEASURED, 0 UNRUN' and 'a DERIVED zero'. Outside the derivation: pnpm exec eslint --no-inline-config on data-action-routes.ts, import-template.ts and export-hidden-columns.test.ts exited 0. node scripts/check-nul-bytes.mjs exited 0, and the control-byte self-scan of the four files found nothing. node scripts/check-adr-0087-registration.mjs exited 0 and node scripts/check-changeset-no-major.mjs exited 0. No export was renamed or deleted, so check-platform-checklist is not owed. check:dev-prereqs exited 0 on the built tree before the dev boot. CI: at report time, the PR's head 4f1363c check-runs were 23 total. 'No other open PR may claim the same issue' was success, 'Packed-tarball smoke (opt-in)' was skipped, and the rest (Check Changeset, Lint · ESLint/CI, release & engine gates/PM dispatch-gates/docs & code guards/repo & tooling gates/scoped x3, Type Check · consumer gates/debt ledger/source gates/workspace, Governed Surface Queue Guard, The card this PR closes must claim this branch, Part-of PR must not also close its card, Check PR Size, Check Documentation Links, Flag docs affected by code changes, filter) were in_progress. Test Core and Build Core had not been created yet. Not awaited, per dispatch.",
"mcp_calls": "0",
"api_writes": "2 relay strokes (each one POST /repos/objectstack-ai/objectstack/dispatches, executed by fleet-write.yml as objectstack-fleet[bot]). (1) pr_create: POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos//issues/24178/assignees [os-sales]; read-back says 8362 bytes sent and stored, identical. (2) This comment: POST /repos//issues/24143/comments. No label writes: the dispatch named no labels, and the PR carries a changeset, so no skip-changeset. git push x4 (empty branch, fix, changeset, merge of main), not REST. The PR body is never edited after creation.",
"open_questions": [
{
"question": "For the CONTRACT_REVIEW_TIER review, not blocking: the ruling drops every hidden field from the default export, and that takes out one column that carries data, organization_id 'Organization' (53 showcase objects, 167/191 rows valued). Is that accepted as part of the ruling?",
"options": [
"A: accept as shipped. hidden means not a default column; a reader who wants it asks with ?fields=",
"B: carve organization_id out, keeping it as a default column despite hidden: true"
],
"recommendation": "A. Real need: the measured value is constant within a tenant-scoped export (Default Organization), and the list view does not show the field by default either. Long-term: one rule, a field's own hidden flag, with no per-field exception table. Against AI mistakes: a carve-out is a second dialect of 'default column' that authors cannot see in the metadata. Startup focus: B adds a rule with no measured puller."
}
],
"out_of_scope_findings": [
"carrier: none (承接者:无) · noted in the PR's Acceptance notes, not filed: format=json has no column projection. It streams each row as the read returns it, so neither the hidden-field drop nor an explicit ?fields= narrows JSON rows. This predates the change and comes from reading the code (findArgs carries no fields; formatRowForJson keeps every key), not from a measured wrong answer at the door. FieldSchema.hidden is documented as a UI contract that never governed serialization.",
"carrier: none (承接者:无) · noted in the PR's Acceptance notes, not filed: the import template (?template=true) still offers a writable author-declared hidden field as a column, per its own ruling. Export and template now differ on such a field, and that is deliberate."
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 17, 2026
Landed: PR #24178 ·
domain:cliseat 1 · sessionsession_01BVm1pAXVXQ3PjC42j1kPFf· 2026-10-17T16:07Zorigin/mainaaaeeac94"fix(rest)!: a schema-derived export skips the fields declared hidden (#24178)";git rev-list --parents -n1gives 1 parent, a squashgit diff 4f1363cde aaaeeac94over the PR's 4 paths is empty: what landed is the reviewed headgit ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-24178-*'gives 0 refsmerged: trueat 2026-10-17T16:05:38ZFixes #24143. #24070 closed in the same second, but byobjectstack-fleet[bot]with no commit, after seat 2's own PR #24181 merged (2bcaefba9), so it was not closed by this PR's keyword. #24025 closed at 15:54Z by seat 2.State: closed
completedbyFixes #24143;pm:dispatchedstripped in this act. The review of record was6235720861(CONTRACT_REVIEW_TIER, PASS on4f1363cde), and the ACCEPT6235778224.organization_idleaves the default export with every otherhiddenfield, and?fields=still serves it.format=jsonignores?fields=, so a list view's JSON export carries every readable field instead of the view's columns #24183:format=jsonignores?fields=, with reach through objectui's list-view JSON export.