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
server: serve the target's name and id for a referenceNameVisible lookup when the caller cannot read the target (#29171 ruling B) #29460
Filing gate: ③ follow-up the ruling assigns. Director ruling 6574398310 (batch #454 item 2, letter B, maintainer 「454 同意」) says "server and ui cards are filed by the spec seat once the key lands, citing this ruling". The key landed in PR #29379 (9467a1b40e, 2026-11-02 15:23Z), which closes #29171. ⛔ Not a claim. No grade: triage sets it.
Reader: domain:server, the objectql / REST read and $expand path.
What is declared and not served
FieldSchema.referenceNameVisible (packages/spec/src/data/field.zod.ts ≈L1731) is an optional boolean on lookup and user fields only, default off, refused on every other type. Its describe opens [PLANNED — not yet served]. Today a caller who can read the referencing record but not the target gets the restricted-record posture: no name and no id (objectui#13335's 「受限记录」).
What the ruling binds (verbatim scope)
When a field declares referenceNameVisible: true and the caller can read the referencing record but cannot read the target, the engine returns the target's name and id, nothing else.
$expand on that field returns the same: name + id, never other fields.
displayField does not widen it.
The same key covers sys_user names, through user fields and through lookups to sys_user. There is no separate carve-out.
A caller who can read the target gets exactly what it gets today.
Placement is the referencing field. No target-object switch.
Readings the contract review asked the implementer to take from ADR-0079 D4
Resolve the display name through nameField ?? displayNameField ?? derivation, with the floor Record #id, not a literal nameField read.
A multiple: true lookup returns name + id per element.
Done when
The read and $expand branches serve name + id under the conditions above. A test pins each condition with a control: the field without the key stays restricted, a readable target is unchanged, and an $expand of another field returns nothing extra.
The planned marker on the key flips to served. Add or flip the liveness row in packages/spec/liveness/field.json citing the server test. That one spec edit is owed to the spec lane, or rides with a seat-agreed surface amendment.
Hand the ui card (filed beside this one) the response shape it renders.
Claim: PM loop round 1 · card thread · 2026-11-02T17:21Z
Session: session_01ADHkmQJdgarUjPLNgFBY67 (the seat); the card thread is cse_01ADHkmRXbaXBLCJeJXfoh21
Account: os-steve (the seat's linked user; the card's assignee)
Branch: claude/project-thread-jdgmh0
Worktree: the card thread's own container checkout
Domain: domain:server
Seat: domain:server#3
Ruling-ref: the maintainer, verbatim, in the project thread: 「开 server 2、3、5 号席位, 前任已经下班,接手所有开发,包括跟进之前未完成的开发落地。」
File surface: packages/objectql/src/engine.ts ($expand sub-read and the plain read of a reference) and the files it cites for the display-name resolver; REST read tests in packages/rest/src/; packages/spec/src/data/field.zod.ts (the referenceNameVisible describe marker only) and packages/spec/liveness/field.json (its row), a seat-agreed surface amendment; generated reference docs that describe derives; a changeset in .changeset/
Container & model: card thread cmsg_01FdL1XeUyvVNxLreh3F4Qi95v1bE93v4RhtAn6F7LSiDY, mode:thread, model: opus (--tier names no path mandate: PM's call, default), effort: xhigh
Clause-②: yes (widening)
Metadata-protocol: none
Responsibility: serve the declared key under ruling 6574398310 (name and id only, for a target the caller cannot read); controls and ablations as the delta lists; full dogfood battery on the final head
Thread-read: 6581850357
Premise: holds (site re-read on origin/maina9227793 by the seat before dispatch)
Serial constraints cleared: none on seat 3 ($expand path free); protocol.ts frozen by seat 5 and not on this surface
Resume-from: none — fresh from origin/main
State: pm:queue → pm:dispatched, assigned to os-steve, recorded by this claim. Order: project file server-seat3/standard-order.md + server-seat3/29460-delta.md.
{
"issue": 29460,
"status": "done",
"branch": "claude/project-thread-jdgmh0",
"pr": "https://github.com/objectstack-ai/objectstack/pull/29576",
"session": "session_01ADHkmRXbaXBLCJeJXfoh21",
"premise_still_valid": true,
"summary": "A `lookup` or `user` field declaring `referenceNameVisible: true` now answers, on `$expand`, `{ id, name, readRefused: true }` for a target the reader is refused (the object's read gate, its required permissions, or its row scope), per element on `multiple: true`; everything else keeps today's answer. The name is read by the engine from the refused ids and the ADR-0079 name column only, under the tenant-kept elevation; the caller's nesting (projection, nested expand, filter, order) and the field's displayField never reach that read. A field-level rule on the name column (FLS, maskingRule, a formula reading through a reference, a non-title column) serves the floor `Record #<id>` (open question 1). The describe drops its planned marker and the liveness row records the key live, citing the REST test.",
"readings_baseline": "main a9227793, real ObjectQL over SQLite + security plugin + REST server, a member caller: plain engine read, REST GET by id and REST list (no $expand) hold the bare FK id for every target (readable, row-scope-hidden, gate-refused, dangling). $expand: readable target = full record; row-scope-hidden, gate-refused or dangling = bare id (the gate-refused sub-read logs a warn). sys_user: a user the row scope admits is expanded, one it does not keeps the bare id. The card's 'no name and no id' is the ui's placeholder (its own follow-up read of the target is refused). No sys_user name carve-out exists in the engine or the plugins.",
"ui_handoff": "#29462 — after $expand of a referenceNameVisible field each value is: the expanded record (reader may read the target, exactly as without the key) | { id, name, readRefused: true } (reader refused the target; name may be the floor 'Record #<id>') | the bare id (no record has the id, a record of another organization, no key on the field, or no $expand). Per element on multiple: true. The table is in the PR body.",
"report_face": "record-recognisers.mjs --template --paths <the 12 paths>: the schema face, CONTRACT_REVIEW_TIER, Scope hits packages/spec/src/data/field.zod.ts",
"tests": "packages/rest/src/data-reference-name-visible.test.ts (new): 23/23 on this head (`cd packages/rest && pnpm exec vitest run --maxWorkers=2 src/data-reference-name-visible.test.ts`, under os-verify-lock, VERDICT command-exit 0). Red leg on the pre-change objectql build: 13 failed | 8 passed | 1 skipped (22, the suite as it then stood; every served case red, every control green). Spec: field-reference-name-visible + field + liveness suites 3 files 181 passed. Package suites on the final head: objectql 534/534 files, 10391 tests passed; rest 374/374 files, 7080 passed, 332 skipped; spec 792/792 files, 23522 passed, 1 todo. Ablations (scripts/ablation-replace.mjs --hold, objectql rebuilt, ablation-dist-preflight present, suite run, --restore proven blob == HEAD; final rebuild, every marker --absent, git status --porcelain empty, suite 23/23): A1 caller nesting + displayField forwarded into the name read and its row spread into the value → 15 failed (nested projection, nested expand, displayField pins among them); A2 key gate removed → 2 failed (without-key controls, user and lookup); A3 FLS answer ignored → 1 failed (FLS floor, received 'Payroll' for 'Record #l1'); A4 maskingRule ignored → 1 failed (masking floor); A5 formula hop computed under elevation → 2 failed (formula floor, nested-expand pin); A6 name read loses the caller's organization → 1 failed (other-organization pin, 'v_other' named); A7 names served on the unexpanded read → 1 failed (unexpanded-read pin); A8 a name invented for an id the name read did not return → 4 failed (dangling, per-element, list, other-organization); A9 the probe's readable answer dropped → 1 failed (readable-target-own-filter control). Three plants (A1, A7, A8) were first refused by ablation-replace because the replacement carried the anchor verbatim (anchor count did not fall); rewritten so the anchor changes and rerun.",
"gates": "after the last commit (7e8a7b30, the main merge): `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` → 109 commands; each run with < /dev/null, exit captured before any pipe: 109/109 exit 0 (check-plugin-teardown-shape pin fetched first). `--ran` reconcile (separately): 109 derived, 109 run, 0 NOT-MEASURED (a DERIVED zero), 0 UNRUN. `pnpm lint` exit 0. typecheck objectql / rest / spec exit 0 (each includes check:test-typecheck). Build: turbo build ./packages/** 78/78. CI check-runs: not yet read, the draft was just opened.",
"dogfood_battery": "os-verify-lock VERDICT command-exit 0 (held 29m15s, shared box) · Test Files 397 passed, 3 skipped (400) · Tests 3277 passed, 28 skipped (3305) · no failures",
"line_budget": "12 files, +872 / -35: objectql src +315 / -3 (new module 246, engine.ts 64, hydration 5/3), rest test +489, spec src +39 / -26 (field.zod.ts 27/15, forced test edit 12/11), liveness +6 / -1, generated docs +5 / -5, changeset +18",
"files_changed": [
".changeset/29460-reference-name-visible-served.md",
"content/docs/references/data/field.mdx (generated)",
"content/docs/references/data/object.mdx (generated)",
"content/docs/references/system/migration.mdx (generated)",
"packages/objectql/src/engine-file-reference-hydration.ts",
"packages/objectql/src/engine-reference-name-visible.ts (new)",
"packages/objectql/src/engine.ts",
"packages/rest/src/data-reference-name-visible.test.ts (new)",
"packages/spec/liveness/field.json",
"packages/spec/liveness/state-counts/field.md (generated)",
"packages/spec/src/data/field-reference-name-visible.test.ts (forced test edit)",
"packages/spec/src/data/field.zod.ts"
],
"deviations": [
"Served on $expand only, not on the plain read: ADR-0104 D1 has every unexpanded reference answer its stored form (the bare id, already the 'id' half); serving a name there would hand a refused reader a richer value than a reader of the target gets. Open question 2.",
"A name column kept from the reader by a field-level rule serves the floor 'Record #<id>' rather than the name (the delta listed FLS among the refusals the key serves through; the describe as declared did not mention field-level rules, so serving would bypass the grant). Decided toward no bypass, declared, and put in open question 1 with options; not silent.",
"The served value carries `readRefused: true` beside `{ id, name }` (the FileRefusedValueSchema `metadataRefused` precedent), so a renderer can tell a refused target from a readable one expanded with a narrow projection. Public name chosen by the thread (names are the seat's call).",
"File surface beyond the Claim's list: the body lives in a new module `packages/objectql/src/engine-reference-name-visible.ts` (the engine split host pattern; engine.ts carries the call site and a thin private method), `isReadRefusal` exported from `engine-file-reference-hydration.ts` (one refusal predicate for both sub-reads), the forced spec test edit, and the regenerated `object.mdx`, `migration.mdx` and liveness `state-counts/field.md`.",
"PR opened through the relay op pr_create with no assignees and no reviewer requests (standard order; MCP writes forbidden).",
"The main-merge commit's message was amended before the first push to carry the model-free trailer pair."
],
"mcp_calls": "4 — mcp__github__issue_read (get #29460, get_comments #29460 x2, get #29462); no write tools",
"api_writes": "2 — fleet relay pr_create objectstack-ai/objectstack#29576 (run 41511593123, 12176 bytes sent = stored); fleet relay comment on #29460 via post-stamped.mjs (this report)",
"open_questions": [
{
"question": "The target's name column is itself kept from the reader by a field-level rule (FLS read false, a maskingRule, or a formula reading through another reference). Serve the name, or the floor?",
"options": [
"A (this PR): the floor 'Record #<id>' with the id; the describe says field-level rules on the name column still hold",
"B: serve the name regardless; amend the describe to say the key lifts field-level rules on the name column too (drop three checks in servableNameField; ablations A3 to A5 show the effect)"
],
"recommendation": "A, because it serves the ruling's 'name and id' without widening any field grant, B stays a contained follow-up if ruled, and a reader who can read the row but not its name column is served exactly what it is served without the key ('can read the target => as today')."
},
{
"question": "Plain (unexpanded) reads: serve the name there too?",
"options": [
"A (this PR): $expand only; an unexpanded read answers the stored bare id for every reader (ADR-0104 D1)",
"B: serve { id, name, readRefused } on the plain read for refused targets only (an ADR-0104 D1 amendment; a refused reader would get a richer value than a reader of the target)"
],
"recommendation": "A, because the bare id already is the 'id' half, and the ui expands the field when it wants the name."
},
{
"question": "A named Zod schema for the served value beside FileRefusedValueSchema in packages/spec/src/data/field-value.zod.ts?",
"options": [
"A: a spec-lane follow-up card (the lane is winding down; this PR exports the TypeScript shape ReferenceNameOnlyValue from the engine module only)",
"B: leave it unnamed in spec; the describe states the shape"
],
"recommendation": "A when the spec lane next opens, because the ui card can then import the shape instead of restating it."
}
],
"security_findings": "none",
"out_of_scope_findings": [],
"head": "7e8a7b30a46677129ad483194fb982a74f36e85b"
}
git grep -n "export async function serveReferenceNames" origin/main -- packages/objectql/src/engine-reference-name-visible.ts
line 111
Landed: merged as b8615258.
A lookup or user field that declares referenceNameVisible: true now answers { id, name, readRefused: true } on $expand for a target the reader is refused, per element on a multi-value field.
The name comes from an engine-owned, tenant-kept read of the id and the ADR-0079 name column only. When a field-level rule keeps the name column from the reader, the Record # floor is served instead.
Every other case answers as before.
The describe marker is flipped to served, and the liveness row is live.
The seat ACCEPT is on the PR as 6587915481, and the schema-face contract review PASS is 6586900765. Fixes #29460 closed this card on merge.
Activity
objectstack-fleet commentedon Nov 2, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: p2 ·
domain:server·pm:queue· 2026-11-02T16:03Z⛔ Not a claim.
referenceNameVisiblelookup when the caller cannot read the target. The key landed in PR feat(spec): a lookup can declare its target's name visible to every reader of the record (referenceNameVisible) #29379. p2. ⛔ Serve exactly what the ruling names, the name and the id, and nothing else of the target. Anything wider is a security boundary and goes back to the maintainer.Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67
Claim: PM loop round 1 · card thread · 2026-11-02T17:21Z
Session:
session_01ADHkmQJdgarUjPLNgFBY67(the seat); the card thread iscse_01ADHkmRXbaXBLCJeJXfoh21Account:
os-steve(the seat's linked user; the card's assignee)Branch:
claude/project-thread-jdgmh0Worktree: the card thread's own container checkout
Domain:
domain:serverSeat:
domain:server#3Ruling-ref: the maintainer, verbatim, in the project thread: 「开 server 2、3、5 号席位, 前任已经下班,接手所有开发,包括跟进之前未完成的开发落地。」
File surface:
packages/objectql/src/engine.ts($expand sub-read and the plain read of a reference) and the files it cites for the display-name resolver; REST read tests inpackages/rest/src/;packages/spec/src/data/field.zod.ts(thereferenceNameVisibledescribe marker only) andpackages/spec/liveness/field.json(its row), a seat-agreed surface amendment; generated reference docs that describe derives; a changeset in.changeset/Container & model: card thread
cmsg_01FdL1XeUyvVNxLreh3F4Qi95v1bE93v4RhtAn6F7LSiDY,mode:thread,model: opus(--tiernames no path mandate: PM's call, default),effort: xhighClause-②: yes (widening)
Metadata-protocol: none
Responsibility: serve the declared key under ruling 6574398310 (name and id only, for a target the caller cannot read); controls and ablations as the delta lists; full dogfood battery on the final head
Thread-read: 6581850357
Premise: holds (site re-read on
origin/maina9227793by the seat before dispatch)Serial constraints cleared: none on seat 3 ($expand path free); protocol.ts frozen by seat 5 and not on this surface
Resume-from: none — fresh from
origin/mainState:
pm:queue→pm:dispatched, assigned toos-steve, recorded by this claim. Order: project file server-seat3/standard-order.md + server-seat3/29460-delta.md.objectstack-fleet commentedon Nov 2, 2026
domain:server#3 · os-steve · session_01ADHkmRXbaXBLCJeJXfoh21
os-dev-report
{ "issue": 29460, "status": "done", "branch": "claude/project-thread-jdgmh0", "pr": "https://github.com/objectstack-ai/objectstack/pull/29576", "session": "session_01ADHkmRXbaXBLCJeJXfoh21", "premise_still_valid": true, "summary": "A `lookup` or `user` field declaring `referenceNameVisible: true` now answers, on `$expand`, `{ id, name, readRefused: true }` for a target the reader is refused (the object's read gate, its required permissions, or its row scope), per element on `multiple: true`; everything else keeps today's answer. The name is read by the engine from the refused ids and the ADR-0079 name column only, under the tenant-kept elevation; the caller's nesting (projection, nested expand, filter, order) and the field's displayField never reach that read. A field-level rule on the name column (FLS, maskingRule, a formula reading through a reference, a non-title column) serves the floor `Record #<id>` (open question 1). The describe drops its planned marker and the liveness row records the key live, citing the REST test.", "readings_baseline": "main a9227793, real ObjectQL over SQLite + security plugin + REST server, a member caller: plain engine read, REST GET by id and REST list (no $expand) hold the bare FK id for every target (readable, row-scope-hidden, gate-refused, dangling). $expand: readable target = full record; row-scope-hidden, gate-refused or dangling = bare id (the gate-refused sub-read logs a warn). sys_user: a user the row scope admits is expanded, one it does not keeps the bare id. The card's 'no name and no id' is the ui's placeholder (its own follow-up read of the target is refused). No sys_user name carve-out exists in the engine or the plugins.", "ui_handoff": "#29462 — after $expand of a referenceNameVisible field each value is: the expanded record (reader may read the target, exactly as without the key) | { id, name, readRefused: true } (reader refused the target; name may be the floor 'Record #<id>') | the bare id (no record has the id, a record of another organization, no key on the field, or no $expand). Per element on multiple: true. The table is in the PR body.", "report_face": "record-recognisers.mjs --template --paths <the 12 paths>: the schema face, CONTRACT_REVIEW_TIER, Scope hits packages/spec/src/data/field.zod.ts", "tests": "packages/rest/src/data-reference-name-visible.test.ts (new): 23/23 on this head (`cd packages/rest && pnpm exec vitest run --maxWorkers=2 src/data-reference-name-visible.test.ts`, under os-verify-lock, VERDICT command-exit 0). Red leg on the pre-change objectql build: 13 failed | 8 passed | 1 skipped (22, the suite as it then stood; every served case red, every control green). Spec: field-reference-name-visible + field + liveness suites 3 files 181 passed. Package suites on the final head: objectql 534/534 files, 10391 tests passed; rest 374/374 files, 7080 passed, 332 skipped; spec 792/792 files, 23522 passed, 1 todo. Ablations (scripts/ablation-replace.mjs --hold, objectql rebuilt, ablation-dist-preflight present, suite run, --restore proven blob == HEAD; final rebuild, every marker --absent, git status --porcelain empty, suite 23/23): A1 caller nesting + displayField forwarded into the name read and its row spread into the value → 15 failed (nested projection, nested expand, displayField pins among them); A2 key gate removed → 2 failed (without-key controls, user and lookup); A3 FLS answer ignored → 1 failed (FLS floor, received 'Payroll' for 'Record #l1'); A4 maskingRule ignored → 1 failed (masking floor); A5 formula hop computed under elevation → 2 failed (formula floor, nested-expand pin); A6 name read loses the caller's organization → 1 failed (other-organization pin, 'v_other' named); A7 names served on the unexpanded read → 1 failed (unexpanded-read pin); A8 a name invented for an id the name read did not return → 4 failed (dangling, per-element, list, other-organization); A9 the probe's readable answer dropped → 1 failed (readable-target-own-filter control). Three plants (A1, A7, A8) were first refused by ablation-replace because the replacement carried the anchor verbatim (anchor count did not fall); rewritten so the anchor changes and rerun.", "gates": "after the last commit (7e8a7b30, the main merge): `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` → 109 commands; each run with < /dev/null, exit captured before any pipe: 109/109 exit 0 (check-plugin-teardown-shape pin fetched first). `--ran` reconcile (separately): 109 derived, 109 run, 0 NOT-MEASURED (a DERIVED zero), 0 UNRUN. `pnpm lint` exit 0. typecheck objectql / rest / spec exit 0 (each includes check:test-typecheck). Build: turbo build ./packages/** 78/78. CI check-runs: not yet read, the draft was just opened.", "dogfood_battery": "os-verify-lock VERDICT command-exit 0 (held 29m15s, shared box) · Test Files 397 passed, 3 skipped (400) · Tests 3277 passed, 28 skipped (3305) · no failures", "line_budget": "12 files, +872 / -35: objectql src +315 / -3 (new module 246, engine.ts 64, hydration 5/3), rest test +489, spec src +39 / -26 (field.zod.ts 27/15, forced test edit 12/11), liveness +6 / -1, generated docs +5 / -5, changeset +18", "files_changed": [ ".changeset/29460-reference-name-visible-served.md", "content/docs/references/data/field.mdx (generated)", "content/docs/references/data/object.mdx (generated)", "content/docs/references/system/migration.mdx (generated)", "packages/objectql/src/engine-file-reference-hydration.ts", "packages/objectql/src/engine-reference-name-visible.ts (new)", "packages/objectql/src/engine.ts", "packages/rest/src/data-reference-name-visible.test.ts (new)", "packages/spec/liveness/field.json", "packages/spec/liveness/state-counts/field.md (generated)", "packages/spec/src/data/field-reference-name-visible.test.ts (forced test edit)", "packages/spec/src/data/field.zod.ts" ], "deviations": [ "Served on $expand only, not on the plain read: ADR-0104 D1 has every unexpanded reference answer its stored form (the bare id, already the 'id' half); serving a name there would hand a refused reader a richer value than a reader of the target gets. Open question 2.", "A name column kept from the reader by a field-level rule serves the floor 'Record #<id>' rather than the name (the delta listed FLS among the refusals the key serves through; the describe as declared did not mention field-level rules, so serving would bypass the grant). Decided toward no bypass, declared, and put in open question 1 with options; not silent.", "The served value carries `readRefused: true` beside `{ id, name }` (the FileRefusedValueSchema `metadataRefused` precedent), so a renderer can tell a refused target from a readable one expanded with a narrow projection. Public name chosen by the thread (names are the seat's call).", "File surface beyond the Claim's list: the body lives in a new module `packages/objectql/src/engine-reference-name-visible.ts` (the engine split host pattern; engine.ts carries the call site and a thin private method), `isReadRefusal` exported from `engine-file-reference-hydration.ts` (one refusal predicate for both sub-reads), the forced spec test edit, and the regenerated `object.mdx`, `migration.mdx` and liveness `state-counts/field.md`.", "PR opened through the relay op pr_create with no assignees and no reviewer requests (standard order; MCP writes forbidden).", "The main-merge commit's message was amended before the first push to carry the model-free trailer pair." ], "mcp_calls": "4 — mcp__github__issue_read (get #29460, get_comments #29460 x2, get #29462); no write tools", "api_writes": "2 — fleet relay pr_create objectstack-ai/objectstack#29576 (run 41511593123, 12176 bytes sent = stored); fleet relay comment on #29460 via post-stamped.mjs (this report)", "open_questions": [ { "question": "The target's name column is itself kept from the reader by a field-level rule (FLS read false, a maskingRule, or a formula reading through another reference). Serve the name, or the floor?", "options": [ "A (this PR): the floor 'Record #<id>' with the id; the describe says field-level rules on the name column still hold", "B: serve the name regardless; amend the describe to say the key lifts field-level rules on the name column too (drop three checks in servableNameField; ablations A3 to A5 show the effect)" ], "recommendation": "A, because it serves the ruling's 'name and id' without widening any field grant, B stays a contained follow-up if ruled, and a reader who can read the row but not its name column is served exactly what it is served without the key ('can read the target => as today')." }, { "question": "Plain (unexpanded) reads: serve the name there too?", "options": [ "A (this PR): $expand only; an unexpanded read answers the stored bare id for every reader (ADR-0104 D1)", "B: serve { id, name, readRefused } on the plain read for refused targets only (an ADR-0104 D1 amendment; a refused reader would get a richer value than a reader of the target)" ], "recommendation": "A, because the bare id already is the 'id' half, and the ui expands the field when it wants the name." }, { "question": "A named Zod schema for the served value beside FileRefusedValueSchema in packages/spec/src/data/field-value.zod.ts?", "options": [ "A: a spec-lane follow-up card (the lane is winding down; this PR exports the TypeScript shape ReferenceNameOnlyValue from the engine module only)", "B: leave it unnamed in spec; the describe states the shape" ], "recommendation": "A when the spec lane next opens, because the ui card can then import the shape instead of restating it." } ], "security_findings": "none", "out_of_scope_findings": [], "head": "7e8a7b30a46677129ad483194fb982a74f36e85b" }Stamped 2026-11-02T19:38Z.
Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67
Landing record · #29460 · PR #29576
domain:serverseat 3 ·session_01ADHkmQJdgarUjPLNgFBY67· 2026-11-02T21:04Zgit ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-29576-*'git merge-base --is-ancestor b8615258 origin/maingit grep -n "export async function serveReferenceNames" origin/main -- packages/objectql/src/engine-reference-name-visible.tsb8615258.lookuporuserfield that declaresreferenceNameVisible: truenow answers{ id, name, readRefused: true }on$expandfor a target the reader is refused, per element on a multi-value field.Record #floor is served instead.live.6587915481, and the schema-face contract review PASS is6586900765.Fixes #29460closed this card on merge.referenceNameVisibleis served on$expandonly; the #29171 ruling names the plain read too, which ADR-0104 D1 fixes at the stored id #29580, labelledneeds-user-decision. The seat recommends A, the$expand-only delivery.referenceNameVisibledescribe namesnameFieldwhere the engine resolves the ADR-0079 display name, lists three of its five name floors, and the served{ id, name, readRefused }value has no named schema #29579.referenceNameVisiblelookup's name as plain text, and add its Studio form row (#29171 ruling B) #29462. The response shape table is in the PR feat(objectql): a referenceNameVisible lookup or user field names a target the reader is refused, on $expand (#29460) #29576 body.pm:dispatchedand the assignee removed in the same round.