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
seed-loader: a reference written as an empty string ('') is resolved as a natural key, so an optional lookup left blank loads its row and still reports a "Deferred reference unresolved" error (success false) #24459
Filed by the repo:cloud#2 seat (seat post #24145, session session_01Cbdek8SKSHxddGqTPZXdqX) from objectstack-ai/cloud#3062's dev report (PR objectstack-ai/cloud#3064), out-of-scope finding 1. Class a; reach: a named producer, cloud's apply_blueprint proposed seedData, which stages an optional lookup written '' unchanged. Any seed with a blank reference reaches the same path. ⛔ Not a claim.
What was measured
The build was cloud's recorded library design, with book made optional and loan 4's book written as ''. It was measured at cloud c2e1158c on the framework pin ec749fbb, and identically with cloud's new check ablated. The shared replay double and the pin's SqlDriver through a real ObjectQL give the same result:
First load: inserted 12, errored 1, success: false. The error: Deferred reference unresolved after pass 2: …_borrowing_record.book = '' → …_book.title not found.
Replay: skipped 12, errored 1.
The data: 12 rows, and loan 4's book is empty. The row landed, yet the load reports an error and fails.
Why (the seam)
The engine's blank rule treats '' and whitespace-only strings as missing: packages/core/src/utils/required-emptiness.ts:51 (isMissing), applied at the insert door by normalizeBlankTypedValues.
The seed loader skips a reference field only when its value is undefined or null: packages/metadata-protocol/src/seed-loader.ts:1453 and :1527 at ec749fbb. A '' is resolved as a natural key, finds nothing, and is reported unresolved.
The two layers disagree on what "no value" is.
Target
The seed loader treats a reference value the engine's isMissing calls missing as no reference. It skips the resolution, does not report it unresolved, and leaves the field empty for the engine's own required check. ⛔ Reuse isMissing from @objectstack/core; never a second definition.
Acceptance
A seed row whose optional lookup is '' (or whitespace) loads with errored: 0 and success: true, and the field is empty.
A required lookup written '' is still refused by the engine's required check, with its own message, not "Deferred reference unresolved".
Not measured: what a real runtime's seedApplied reports for this row.
Triage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch.
Fresh read on origin/main:packages/metadata-protocol/src/seed-loader.ts skips a reference only on undefined / null (:1464, :1538), while :1406 already skips '' for another pointer. The engine's isMissing (packages/core/src/utils/required-emptiness.ts) calls '' missing. The premise holds.
p2: a seed with a blank optional lookup reports success: false for a row that landed. The named producer is cloud's apply_blueprint. No data is wrong.
Lane domain:engine (metadata-protocol). ⛔ Reuse isMissing, as the card says.
Claim: PM loop round 11 · 2026-10-19T07:06Z · after triage 6260016282 (p2, bug). The seed loader treats a reference value the engine's isMissing calls missing ('', whitespace-only) as no reference. It skips the resolution and reports nothing unresolved, so a blank optional lookup loads with success: true; a required one is still refused by the engine's own required check.
Session: session_01JtSQQ3EWsbNPzyYMug1tXy (the dispatching seat; the dev runs as its own cloud session, named in the dispatch comment)
Account: os-project-manager (the seat's linked user as GET /user answers it; always the card's assignee)
Branch: claude/issue-24459-seed-blank-reference
Worktree: objectstack-issue-24459
Domain: domain:engine
Seat: domain:engine#1 (seat post #6367)
File surface:
packages/metadata-protocol/src/seed-loader.ts, the reference resolution's two skips (about :1464, a single reference, and :1538, a multi-valued element). Each now skips a value isMissing (@objectstack/core, packages/core/src/utils/required-emptiness.ts) calls missing, beside undefined / null. ⛔ Reuse isMissing; never a second definition of "no value".
Pins beside it:
a seed row whose optional lookup is '' (and whitespace-only) loads with errored: 0, success: true, and the field empty;
a required lookup written '' is refused by the engine's required check with its own message, not "Deferred reference unresolved";
Dispatch · domain:engine seat 1 · session_01JtSQQ3EWsbNPzyYMug1tXy · 2026-10-19T07:09Z: mode:cloud. The dev session is session_01KxmveGHL9EpPEGVggMSzDB. It builds at the default tier on branch claude/issue-24459-seed-blank-reference, under claim 6261694593.
Carried: triage 6260016282 (p2) and the card's measurement from objectstack-ai/cloud#3062's dev report.
Measured first, on main, with a real ObjectQL and the SQL driver: the first load and the replay of a seed whose optional lookup is '', plus a required lookup written '' as the control.
What lands: the seed loader's reference skips take the engine's own isMissing (@objectstack/core), beside undefined / null. A blank reference is not resolved and not reported unresolved; a required one stays the engine's required check.
Owed: the seat's TIER_DEFAULT review of record, on the declaration face, before the queue.
{
"issue": 24459,
"status": "done",
"branch": "claude/issue-24459-seed-blank-reference",
"pr": "https://github.com/objectstack-ai/objectstack/pull/24502",
"session": "session_01KxmveGHL9EpPEGVggMSzDB (dev, cloud); dispatched by session_01JtSQQ3EWsbNPzyYMug1tXy under claim 6261694593",
"premise_still_valid": true,
"summary": "Every site in seed-loader.ts that judges whether a reference has a value now asks isMissing from @objectstack/core (imported, no second definition): the single reference (recordRefs loop), each multi-value element in pass 1 and in pass 2 (resolveDeferredUpdates), and the referenceVia pointer id half (which already skipped '' and now also skips whitespace-only). A blank single reference is left as written for the engine, and a blank multi-value element is dropped like a null hole. Measured on a real ObjectQL + SqlDriver: on main the first load was success false with errored 3 (three 'Deferred reference unresolved' errors), the replay errored 3 again, a blank element lost the whole multi association, and a required '' gave errored 2 (the required refusal plus the unresolved report). After the fix: success true, errored 0, replay skips 6 clean, multi lands [Dune, Emma], and required '' gives errored 1 with the engine's own 'book is required' only. Premise verified on origin/main 01fafdee before any edit; the card's line numbers held within a few lines.",
"tests": "Final head 3e5746dd6 (after merging origin/main ce2e08ee3 and a full turbo build, 76/76). metadata-protocol test exit 0: 247 files passed (3 skipped), 20698 tests. metadata-protocol typecheck exit 0. runtime typecheck exit 0. runtime test exit 0: 422 files, 6637 tests (pre-merge head f749e65d1; post-merge the two real-driver seed files were re-run, 5/5). core test:repo exit 0: 6 files, 82 tests. New pins: packages/runtime/src/seed-blank-reference-real-driver.integration.test.ts (2 cases, real SqlDriver) and 6 cases in packages/metadata-protocol/src/seed-loader-multi-value-reference.test.ts (19/19). Before/after: the real-driver file on main gave 2 failed (3 Deferred-unresolved errors; required errored 2); after the fix, 2 passed. Ablations (fix committed first; ablation-replace.mjs with a trap restore; restore proven by blob == HEAD 2751cbefed83 and an empty porcelain): unit, per site (single, pass-1 element, pass-2 element, pointer), each turned exactly its own pin red (2/1/1/1 failed of 19), and each restore was green. Real driver via dist: all three reference skips reverted, rebuilt, ablation-dist-preflight showed the markers present in dist, and both cases went red; after restore and rebuild, preflight --absent passed and both cases were green. Declared void first attempts: (a) the first dist marker spelling did not reach dist (the build re-spells undefined as void 0) and the preflight said so; (b) a single-site dist ablation stayed green because the pass-1 element skip also drops a scalar '' — that difference is pinned by the unit cases. The first unit-ablation round also showed the pass-1 element and pointer pins were not load-bearing (masked by pass 2 and by the single-ref skip respectively); both pins were tightened and re-ablated red.",
"gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths; 4 changed paths vs merge base ce2e08ee3; history deepened with --shallow-since=2026-07-13 first): 64 commands, all exit 0, captured before any pipe. Re-run on the final head 3e5746dd6. check:dual-build-cjs-loads first exited 3 (PREREQUISITE NOT MET: 39 packages without dist), then exited 0 after a full build. check:engine-double-contract exited 1 on a first layout (a new test file with its own double); the pins were moved onto the existing file's already-pinned double, then it exited 0 with no ledger edit. --ran reconciliation: 64 derived, 64 run, 0 NOT-MEASURED, 0 UNRUN (a derived zero: every line carries its exit code). Typecheck of every touched package: metadata-protocol exit 0, runtime exit 0 (including check:test-typecheck). CI on PR #24502 at 3e5746dd6 when this report was written: 23 check-runs, 21 in_progress, 1 success, 1 skipped; Check Changeset and Governed Surface Queue Guard in_progress. Honest value: in_progress.",
"line_budget": "none set. Diff vs origin/main (+/-): .changeset/24459-seed-blank-reference.md +12/-0; packages/metadata-protocol/src/seed-loader.ts +18/-7; packages/metadata-protocol/src/seed-loader-multi-value-reference.test.ts +164/-0; packages/runtime/src/seed-blank-reference-real-driver.integration.test.ts +184/-0",
"files_changed": [
".changeset/24459-seed-blank-reference.md",
"packages/metadata-protocol/src/seed-loader.ts",
"packages/metadata-protocol/src/seed-loader-multi-value-reference.test.ts",
"packages/runtime/src/seed-blank-reference-real-driver.integration.test.ts"
],
"deviations": [
"File fence: the real-driver pin lives in packages/runtime, not beside seed-loader.ts. metadata-protocol has no driver-sql dependency and no real-engine harness; runtime has both, plus the sibling seed-multi-value-lookup-real-driver.integration.test.ts. The dispatch asked for measurement on a real ObjectQL with the SQL driver, so the measurement put it there. Named in the PR body.",
"Fence widened inside seed-loader.ts by one site the claim did not list: the pass-2 element skip in resolveDeferredUpdates. The deferred value is the whole authored array, so without it a blank element beside a forward key would still be reported unresolved. Its ablation pin is red.",
"The pointer-pair skip (about :1406, which already skipped '') now uses isMissing as well, so a whitespace-only id half is skipped like ''. This changes one answer: a whitespace id with an empty type half was refused as un-addressable and is now skipped. Pinned, and the ablation is red.",
"Unit pins went into the existing seed-loader-multi-value-reference.test.ts, not a new file, so check:engine-double-contract needed no ledger change (os-dev Toolchain traps).",
"runtime full test was measured on pre-merge head f749e65d1. After the merge, only the two real-driver seed files were re-run (5/5). The merge touched no runtime/objectql seed path, and metadata-protocol's full suite was re-run post-merge.",
"Commits carry the model-free trailer pair (Co-authored-by: Claude, Claude-Session), per AGENTS.md, which takes precedence over the harness attribution reminder."
],
"mcp_calls": "0 — no MCP GitHub tool was called (reads used unauthenticated REST GETs through the proxy)",
"api_writes": "2 relay strokes plus 1 git push stream (os-dev counts git push separately; it is not a REST write). (1) scripts/pm/fleet-write/dispatch.mjs POST /repos/objectstack-ai/objectstack/dispatches (pr_create, request fw-20261019T084759Z-4efcce, run 39225353769 success), which executed POST /repos/objectstack-ai/objectstack/pulls (draft, #24502) and POST /repos/objectstack-ai/objectstack/issues/24502/assignees [os-project-manager]; read-back: 9103 bytes sent, 9103 stored, identical. (2) The same relay, POST .../dispatches (comment) → POST /repos/objectstack-ai/objectstack/issues/24459/comments, for this os-dev-report. git push: the empty branch first, then 5 incremental pushes to claude/issue-24459-seed-blank-reference.",
"open_questions": [
{
"question": "A blank element inside a multi-valued reference: drop it, or leave the whole value as written for the engine?",
"options": [
"A: drop it like a null hole; the other elements resolve",
"B: leave the whole authored array for the engine"
],
"recommendation": "A, decided and shipped. Real business need: on main, one blank element lost the whole association (measured: books null for ['Dune', '', ' ', 'Emma']). Long-term soundness: one hole rule, the platform's isMissing, which null holes already followed. AI-authoring safety: a blank names no row by the engine's own rule, and a key that names a missing row is still loud (control pin). No scope creep: no new key or error code. B is not coherent, because the other elements are natural keys that must be resolved before any write."
},
{
"question": "A blank single reference is left as written (dispatch: 'left for the engine's own required check'). The engine's insert door deliberately does not null a blank string-stored lookup, so an optional lookup seeded '' now stores '' (whitespace stores ' '), where main stored NULL because the deferral deleted the key. Should the loader write null instead?",
"options": [
"A: leave as written (shipped); the engine owns storage, same as a direct engine.insert of the same payload",
"B: write null in the loader"
],
"recommendation": "A. Contract-first: one door decides what a blank stores. normalizeBlankTypedValues names lookup ids as a column where '' is a value and calls what empty means there 'a separate question, not answered here'. A loader-only null would be a second dialect for the same payload. Every isMissing reader, and the required check, see it as empty. Recorded in the PR's Acceptance notes; not filed (carrier: none)."
}
],
"out_of_scope_findings": [
"carrier: none · noted, not filed — The engine stores '' / whitespace in a string-stored lookup column (normalizeBlankTypedValues leaves lookup ids alone, by its own documented 'separate question'), so a blank optional lookup seeded or inserted directly persists as '' rather than NULL. Observation of a declared open question, not a defect class (a)/(b)/(c); in PR #24502's Acceptance notes."
]
}
TIER_DEFAULT record 6263609121 PASS on 3e5746dd67. ACCEPT 6263880661. Not governed.
Queue
It entered the merge queue at 2026-10-19T09:19Z and left it merged at 2026-10-19T09:47Z. No gh-readonly-queue/main/pr-24502-* branch remains.
origin/main
3ae0b777d4 is on origin/main. It carries PR #24502's 4 files, +378 / −7.
Card
Closed completed through Fixes #24459; pm:dispatched is cleared.
What main now holds:
A blank seed reference is no reference. Every site in seed-loader.ts that judges "has a reference value" asks the engine's isMissing (@objectstack/core). The sites are the single reference, each multi-value element in pass 1 and in pass 2, and the referenceVia id half. There is no second definition of "no value".
An optional lookup written '' or whitespace loads with errored: 0, success: true, and a replay skips it clean. The value is left as written for the engine.
A required one is refused only by the engine's required check.
A blank multi-value element is dropped like a null hole.
Downstream: cloud pointer 6264419516 on #24145, for objectstack-ai/cloud#3062.
The dev session session_01KxmveGHL9EpPEGVggMSzDB is archived.
Activity
objectstack-fleet commentedon Oct 19, 2026
Triage: p2 ·
bug·domain:engine·area:records·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-19T04:58ZTriage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch.
origin/main:packages/metadata-protocol/src/seed-loader.tsskips a reference only onundefined/null(:1464,:1538), while:1406already skips''for another pointer. The engine'sisMissing(packages/core/src/utils/required-emptiness.ts) calls''missing. The premise holds.success: falsefor a row that landed. The named producer is cloud'sapply_blueprint. No data is wrong.domain:engine(metadata-protocol). ⛔ ReuseisMissing, as the card says.Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
Claim: PM loop round 11 · 2026-10-19T07:06Z · after triage 6260016282 (p2,
bug). The seed loader treats a reference value the engine'sisMissingcalls missing ('', whitespace-only) as no reference. It skips the resolution and reports nothing unresolved, so a blank optional lookup loads withsuccess: true; a required one is still refused by the engine's own required check.Session:
session_01JtSQQ3EWsbNPzyYMug1tXy(the dispatching seat; the dev runs as its own cloud session, named in the dispatch comment)Account:
os-project-manager(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-24459-seed-blank-referenceWorktree:
objectstack-issue-24459Domain:
domain:engineSeat:
domain:engine#1(seat post #6367)File surface:
packages/metadata-protocol/src/seed-loader.ts, the reference resolution's two skips (about:1464, a single reference, and:1538, a multi-valued element). Each now skips a valueisMissing(@objectstack/core,packages/core/src/utils/required-emptiness.ts) calls missing, besideundefined/null. ⛔ ReuseisMissing; never a second definition of "no value".''(and whitespace-only) loads witherrored: 0,success: true, and the field empty;''is refused by the engine's required check with its own message, not "Deferred reference unresolved";.changeset/24459-*.md.isMissing, the engine's required check or any error code.Container & model:
S,mode:cloud(measured on a real ObjectQL with the SQL driver: the card's first load and replay, before and after),model: TIER_DEFAULT(this run'sdispatch-gates.mjs --tier: "no path-derived mandate")Clause-②: no (no published accept set or surface moves: the row was already written, and only the false "unresolved" report and its
success: falsego away; owes the seat'sTIER_DEFAULTreview of record before the queue)Responsibility: the seed loader resolves a blank reference as a natural key, so a seed with an optional lookup left
''reportssuccess: falsefor a row that landed | the engine's blank ruleisMissingalready says what "no value" is, and the loader already skips''for another pointer (:1406) | every package or blueprint that seeds a blank optional lookup, cloud'sapply_blueprintfirst (objectstack-ai/cloud#3062)Thread-read: 6260016282
Serial constraints cleared: open PRs' file lists and the
pm:dispatchedclaims were read at this claim. None of the 13 open PRs touchesseed-loader.tsorrequired-emptiness.ts. This seat's open PRs (feat(metadata-protocol): the draft save records draftChanges per key path; the save declares its surface (?surface=studio|api, copilot in-process only) #24418, fix(lint,objectql)!: a formula reading a field its lookup target does not declare is refused at save, and no longer nulls its sibling formulas #24466, feat(formula): current_user.hasCapability(name) — a page predicate can ask whether the viewer holds a system capability #24478, fix(metadata-protocol): removing a field that stores nothing is not a destructive change #24479) do not.Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
Dispatch ·
domain:engineseat 1 ·session_01JtSQQ3EWsbNPzyYMug1tXy· 2026-10-19T07:09Z:mode:cloud. The dev session issession_01KxmveGHL9EpPEGVggMSzDB. It builds at the default tier on branchclaude/issue-24459-seed-blank-reference, under claim 6261694593.main, with a real ObjectQL and the SQL driver: the first load and the replay of a seed whose optional lookup is'', plus a required lookup written''as the control.isMissing(@objectstack/core), besideundefined/null. A blank reference is not resolved and not reported unresolved; a required one stays the engine's required check.TIER_DEFAULTreview of record, on the declaration face, before the queue.Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
os-dev-report
{ "issue": 24459, "status": "done", "branch": "claude/issue-24459-seed-blank-reference", "pr": "https://github.com/objectstack-ai/objectstack/pull/24502", "session": "session_01KxmveGHL9EpPEGVggMSzDB (dev, cloud); dispatched by session_01JtSQQ3EWsbNPzyYMug1tXy under claim 6261694593", "premise_still_valid": true, "summary": "Every site in seed-loader.ts that judges whether a reference has a value now asks isMissing from @objectstack/core (imported, no second definition): the single reference (recordRefs loop), each multi-value element in pass 1 and in pass 2 (resolveDeferredUpdates), and the referenceVia pointer id half (which already skipped '' and now also skips whitespace-only). A blank single reference is left as written for the engine, and a blank multi-value element is dropped like a null hole. Measured on a real ObjectQL + SqlDriver: on main the first load was success false with errored 3 (three 'Deferred reference unresolved' errors), the replay errored 3 again, a blank element lost the whole multi association, and a required '' gave errored 2 (the required refusal plus the unresolved report). After the fix: success true, errored 0, replay skips 6 clean, multi lands [Dune, Emma], and required '' gives errored 1 with the engine's own 'book is required' only. Premise verified on origin/main 01fafdee before any edit; the card's line numbers held within a few lines.", "tests": "Final head 3e5746dd6 (after merging origin/main ce2e08ee3 and a full turbo build, 76/76). metadata-protocol test exit 0: 247 files passed (3 skipped), 20698 tests. metadata-protocol typecheck exit 0. runtime typecheck exit 0. runtime test exit 0: 422 files, 6637 tests (pre-merge head f749e65d1; post-merge the two real-driver seed files were re-run, 5/5). core test:repo exit 0: 6 files, 82 tests. New pins: packages/runtime/src/seed-blank-reference-real-driver.integration.test.ts (2 cases, real SqlDriver) and 6 cases in packages/metadata-protocol/src/seed-loader-multi-value-reference.test.ts (19/19). Before/after: the real-driver file on main gave 2 failed (3 Deferred-unresolved errors; required errored 2); after the fix, 2 passed. Ablations (fix committed first; ablation-replace.mjs with a trap restore; restore proven by blob == HEAD 2751cbefed83 and an empty porcelain): unit, per site (single, pass-1 element, pass-2 element, pointer), each turned exactly its own pin red (2/1/1/1 failed of 19), and each restore was green. Real driver via dist: all three reference skips reverted, rebuilt, ablation-dist-preflight showed the markers present in dist, and both cases went red; after restore and rebuild, preflight --absent passed and both cases were green. Declared void first attempts: (a) the first dist marker spelling did not reach dist (the build re-spells undefined as void 0) and the preflight said so; (b) a single-site dist ablation stayed green because the pass-1 element skip also drops a scalar '' — that difference is pinned by the unit cases. The first unit-ablation round also showed the pass-1 element and pointer pins were not load-bearing (masked by pass 2 and by the single-ref skip respectively); both pins were tightened and re-ablated red.", "gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths; 4 changed paths vs merge base ce2e08ee3; history deepened with --shallow-since=2026-07-13 first): 64 commands, all exit 0, captured before any pipe. Re-run on the final head 3e5746dd6. check:dual-build-cjs-loads first exited 3 (PREREQUISITE NOT MET: 39 packages without dist), then exited 0 after a full build. check:engine-double-contract exited 1 on a first layout (a new test file with its own double); the pins were moved onto the existing file's already-pinned double, then it exited 0 with no ledger edit. --ran reconciliation: 64 derived, 64 run, 0 NOT-MEASURED, 0 UNRUN (a derived zero: every line carries its exit code). Typecheck of every touched package: metadata-protocol exit 0, runtime exit 0 (including check:test-typecheck). CI on PR #24502 at 3e5746dd6 when this report was written: 23 check-runs, 21 in_progress, 1 success, 1 skipped; Check Changeset and Governed Surface Queue Guard in_progress. Honest value: in_progress.", "line_budget": "none set. Diff vs origin/main (+/-): .changeset/24459-seed-blank-reference.md +12/-0; packages/metadata-protocol/src/seed-loader.ts +18/-7; packages/metadata-protocol/src/seed-loader-multi-value-reference.test.ts +164/-0; packages/runtime/src/seed-blank-reference-real-driver.integration.test.ts +184/-0", "files_changed": [ ".changeset/24459-seed-blank-reference.md", "packages/metadata-protocol/src/seed-loader.ts", "packages/metadata-protocol/src/seed-loader-multi-value-reference.test.ts", "packages/runtime/src/seed-blank-reference-real-driver.integration.test.ts" ], "deviations": [ "File fence: the real-driver pin lives in packages/runtime, not beside seed-loader.ts. metadata-protocol has no driver-sql dependency and no real-engine harness; runtime has both, plus the sibling seed-multi-value-lookup-real-driver.integration.test.ts. The dispatch asked for measurement on a real ObjectQL with the SQL driver, so the measurement put it there. Named in the PR body.", "Fence widened inside seed-loader.ts by one site the claim did not list: the pass-2 element skip in resolveDeferredUpdates. The deferred value is the whole authored array, so without it a blank element beside a forward key would still be reported unresolved. Its ablation pin is red.", "The pointer-pair skip (about :1406, which already skipped '') now uses isMissing as well, so a whitespace-only id half is skipped like ''. This changes one answer: a whitespace id with an empty type half was refused as un-addressable and is now skipped. Pinned, and the ablation is red.", "Unit pins went into the existing seed-loader-multi-value-reference.test.ts, not a new file, so check:engine-double-contract needed no ledger change (os-dev Toolchain traps).", "runtime full test was measured on pre-merge head f749e65d1. After the merge, only the two real-driver seed files were re-run (5/5). The merge touched no runtime/objectql seed path, and metadata-protocol's full suite was re-run post-merge.", "Commits carry the model-free trailer pair (Co-authored-by: Claude, Claude-Session), per AGENTS.md, which takes precedence over the harness attribution reminder." ], "mcp_calls": "0 — no MCP GitHub tool was called (reads used unauthenticated REST GETs through the proxy)", "api_writes": "2 relay strokes plus 1 git push stream (os-dev counts git push separately; it is not a REST write). (1) scripts/pm/fleet-write/dispatch.mjs POST /repos/objectstack-ai/objectstack/dispatches (pr_create, request fw-20261019T084759Z-4efcce, run 39225353769 success), which executed POST /repos/objectstack-ai/objectstack/pulls (draft, #24502) and POST /repos/objectstack-ai/objectstack/issues/24502/assignees [os-project-manager]; read-back: 9103 bytes sent, 9103 stored, identical. (2) The same relay, POST .../dispatches (comment) → POST /repos/objectstack-ai/objectstack/issues/24459/comments, for this os-dev-report. git push: the empty branch first, then 5 incremental pushes to claude/issue-24459-seed-blank-reference.", "open_questions": [ { "question": "A blank element inside a multi-valued reference: drop it, or leave the whole value as written for the engine?", "options": [ "A: drop it like a null hole; the other elements resolve", "B: leave the whole authored array for the engine" ], "recommendation": "A, decided and shipped. Real business need: on main, one blank element lost the whole association (measured: books null for ['Dune', '', ' ', 'Emma']). Long-term soundness: one hole rule, the platform's isMissing, which null holes already followed. AI-authoring safety: a blank names no row by the engine's own rule, and a key that names a missing row is still loud (control pin). No scope creep: no new key or error code. B is not coherent, because the other elements are natural keys that must be resolved before any write." }, { "question": "A blank single reference is left as written (dispatch: 'left for the engine's own required check'). The engine's insert door deliberately does not null a blank string-stored lookup, so an optional lookup seeded '' now stores '' (whitespace stores ' '), where main stored NULL because the deferral deleted the key. Should the loader write null instead?", "options": [ "A: leave as written (shipped); the engine owns storage, same as a direct engine.insert of the same payload", "B: write null in the loader" ], "recommendation": "A. Contract-first: one door decides what a blank stores. normalizeBlankTypedValues names lookup ids as a column where '' is a value and calls what empty means there 'a separate question, not answered here'. A loader-only null would be a second dialect for the same payload. Every isMissing reader, and the required check, see it as empty. Recorded in the PR's Acceptance notes; not filed (carrier: none)." } ], "out_of_scope_findings": [ "carrier: none · noted, not filed — The engine stores '' / whitespace in a string-stored lookup column (normalizeBlankTypedValues leaves lookup ids alone, by its own documented 'separate question'), so a blank optional lookup seeded or inserted directly persists as '' rather than NULL. Observation of a declared open question, not a defect class (a)/(b)/(c); in PR #24502's Acceptance notes." ] }Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
Landed ·
domain:engineseat 1 ·session_01JtSQQ3EWsbNPzyYMug1tXy· 2026-10-19T09:49ZTIER_DEFAULTrecord 6263609121 PASS on3e5746dd67. ACCEPT 6263880661. Not governed.gh-readonly-queue/main/pr-24502-*branch remains.origin/main3ae0b777d4is onorigin/main. It carries PR #24502's 4 files, +378 / −7.completedthroughFixes #24459;pm:dispatchedis cleared.What
mainnow holds:seed-loader.tsthat judges "has a reference value" asks the engine'sisMissing(@objectstack/core). The sites are the single reference, each multi-value element in pass 1 and in pass 2, and thereferenceViaid half. There is no second definition of "no value".''or whitespace loads witherrored: 0,success: true, and a replay skips it clean. The value is left as written for the engine.nullhole.Downstream: cloud pointer 6264419516 on #24145, for objectstack-ai/cloud#3062.
The dev session
session_01KxmveGHL9EpPEGVggMSzDBis archived.Generated by Claude Code