Skip to content

lint: an overlay write (no package) of a list view bound to an object that exists nowhere answers 200 with no issue — validateListViewFieldRefs skips it and no other rule judges a view write's binding #24668

Closed

Description

@objectstack-fleet

Filing gate: ① a defect with a named locus. The declared contract is #24563's: the standalone list-view door "reaches the author who made the typo". It does not hold on the overlay door for the binding itself. Reader: the domain:spec seat, in packages/lint. Filed by domain:spec seat 2 (#18549), session session_019oFY6Hi35J7atvgVFnmoaK, from out-of-scope finding (a) of PR #24630. The contract review 6278531343 judged it class a. ⛔ Not a claim.

Measured

Why it matters

A view bound to a misspelled or deleted object is stored, and fails only at render. #24563's changeset says such a view fails at render with "This view's query was rejected". Under a package closure, PR #24630 now refuses the same body (list-view-object-outside-closure). The overlay door and os validate still say nothing.

Shape of a fix (not decided here)

The skip-1 rationale in the module docblock is: there, an unresolved binding may come from another package, and defineStack / validateObjectReferences own it. Neither owns it on a view write. The options:

  • extend validateObjectReferences's runtimeTypes to view for the binding key;
  • or have the overlay door judge the binding against the whole collection, where "exists nowhere" is decidable.

Clause-②: a narrowing, so it falls under the protocol-class 「是否提前」 rule (6261447528).

Dedupe

I ran a semantic issue search for overlay list view bound to nonexistent object accepted save door view data.object unresolved no advisory. It returned 19 hits. The relevant one is #24563, the in-closure half that PR #24630 fixes. None covers the overlay door.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: p2 · bug · lane domain:spec (confirmed) · area:records · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-19T22:58Z

    Triage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch. Fresh read on origin/main 191e0430ef.

    Self-labelled check.

    • The lane fits the table: packages/lint is domain:spec by the anchoring rule (SKILL.md:163).
    • All three answers are present: ①, the domain:spec seat in packages/lint, and a dedupe of 19 hits.

    Premise holds on main.

    • validate-list-view-field-refs.ts:710 returns silently when !graph.has(object).
    • reference-integrity-suite.ts:224 runs validateObjectReferences on ['flow', 'dataset'] only, so nothing judges a view write's binding outside a closure.

    Why p2.

    First act: the booted reading the card names, PUT /api/v1/meta/view/:name with no ?package=.

    Protocol class (a narrowing): the 「是否提前」 question goes to the maintainer, with the lean not for 18.0.

    finding comes off.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Seat hold · domain:spec seat 2 (#18549) · session session_019oFY6Hi35J7atvgVFnmoaK · 2026-10-19T23:16Z · ⛔ Not a claim.

    This card is in this seat's lane queue with a free slot. It is not dispatched: under rule 6261447528, a protocol-class card waits for the maintainer's 「是否提前」 answer. The seat put the question to the maintainer in its session chat at 2026-10-19T23:16Z, and the answer is recorded here when it comes.

    Seat lean: pull it into 18.0. It is the overlay twin of #24563, which landed in 18.0 (9f12d06770). A list view bound to an object that exists nowhere already fails at render, so refusing it at save breaks no working app. Shipping 18.0 with the in-closure binding refused and the overlay binding accepted would be the inconsistency. The work is S: the booted reading first, then one rule's runtimeTypes or the overlay door.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruled: pull into 18.0 · recorded by domain:spec seat 2 (#18549) · session session_019oFY6Hi35J7atvgVFnmoaK · 2026-10-20T03:38Z

    The maintainer's word, in this seat's session chat at 2026-10-20T03:38Z, verbatim: 「都派」. It answers the 「是否提前」 question (rule 6261447528) that the seat put to the maintainer for this card, #24668, #24677 and #24669 together, after the seat hold 6279455883. All three land in 18.0.

    Label change in this act: target:v18 is added, executing that word. The source is the maintainer, verbatim 「都派」, in seat 2's session chat. The grade, the lane and area:* are unchanged.

    The seat dispatches in grade order as batch 2 slots free: #24668 and #24677 (p2) now, #24669 (p3) at the next free slot.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 · 2026-10-20T03:41Z · the overlay save door refuses a list view bound to an object that exists nowhere (the overlay twin of #24563)
    Pulled into 18.0 on the maintainer's word in this session's chat, verbatim: 「都派」 (record 6282766352). The seat's batch 2 (「并发2」) holds it beside #24677.
    Session: session_019oFY6Hi35J7atvgVFnmoaK (the seat; the dev is an os-dev subagent of this session)
    Account: zhuangjianguo (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-24668-overlay-list-view-unknown-object
    Worktree: objectstack-issue-24668
    Domain: domain:spec
    Seat: domain:spec#2 (seat post #18549)
    File surface (paths on origin/main 7e7e605de3 or later; stop on a breach and explain it in the report):


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Dispatched · domain:spec seat 2 · session session_019oFY6Hi35J7atvgVFnmoaK · 2026-10-20T03:46Z · for claim 6282802907.

    mode:subagent: the dev is an os-dev subagent of this session, on branch claude/issue-24668-overlay-list-view-unknown-object, at the default tier. batch 2: it runs beside #24677. #24669 waits for the next free slot.

    The dev verifies the card's premises before editing, starting with the booted or real-door reading, and stops with a fork on any breach. The spec-lane fixture rule applies: the consumer packages run after the change, and every out-of-lane fixture is listed for the seat to declare. The engine rider for the protocol-layer pin is on #6367 (6282830389).

    The dev reports here as an os-dev-report comment and opens a draft PR. The contract review (narrowing face) runs before the queue.


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 24668,
    "status": "done",
    "branch": "claude/issue-24668-overlay-list-view-unknown-object",
    "pr": "#24789",
    "session": "session_019oFY6Hi35J7atvgVFnmoaK — mode:subagent, the seat's id (the claim 6282802907's Session line)",
    "premise_still_valid": true,
    "summary": "Route (a): validateListViewFieldRefs refuses an unresolvable list-view binding as list-view-object-unknown (error, one finding per list view, at the binding key) when told its snapshot is the whole collection (ListViewFieldRefOptions.wholeCollection). The reference-integrity suite sets that flag for a runtime write with no closure in force (runtimeWriteType set, packageScope absent), so the overlay save door answers 422 INVALID_METADATA and stores nothing. The CLI, drafts, resolving bindings and the #24563 closure verdict are unchanged; a closure still wins over the flag, an empty collection judges nothing, and the nearest-name suggestion lives in the hint, not the message, so the gate's differential fingerprint does not move. P1 booted (examples/app-crm, pnpm dev:crm -- --fresh): before (base 4b114ed, lint dist proven base) PUT /api/v1/meta/view/nosuch_obj.qavfy_r1 with no ?package= answered 200, stored, served with diagnostics.valid true, and GET /api/v1/data/nosuch_obj answered 404 OBJECT_NOT_FOUND; after, the same PUT answered 422 INVALID_METADATA [list-view-object-unknown at views[0].data.object] and nothing was stored (showcase and todo gave the same). P2 held: the no-package snapshot is registry.listItems('object') folded with the stored rows, and resolveWritePackageScope narrows nothing. Through the door, a probe list view bound to each served object was admitted for 82/82 objects on CRM (75 sys* objects from 15 packages, 6 crm objects, 1 overlay object saved with no package), 109/109 on showcase and 76/76 on todo. Census: 0 of 49 shipped views (crm 10, showcase 36, todo 3; multi-package ships none) and 0 of the served built-in list views bind an object that exists nowhere. files_changed: packages/lint/src/{validate-list-view-field-refs.ts, reference-integrity-suite.ts, index.ts, runtime-gate.whole-collection.test.ts (new), runtime-gate.package-closure.test.ts, runtime-gate.view-writes.test.ts}; packages/metadata-protocol/src/protocol.runtime-authoring-gate.test.ts (declared rider #6367); packages/objectql/src/{delete-meta-response-conformance, environment-overlay-five-types, protocol-commit-history, protocol-metadata-row-actor, protocol-publish-canonical-fold, protocol-recorded-by-null, protocol-revert-org-scope, protocol-save-meta-repo-path-real-engine, publish-meta-response-conformance, save-meta-response-conformance}.test.ts; packages/rest/src/{meta-diff-default-range-labels, meta-view-chart-binding, meta-view-overlay-options-bag}.test.ts; .changeset/24668-overlay-list-view-unknown-object.md (new); .changeset/24563-list-view-out-of-closure.md (one sentence); content/docs/deployment/validating-metadata.mdx (one sentence). deviations: (1) G1's '#24563 pins stay unchanged' was falsified for exactly the assertions that pinned the overlay silence the ruling reverses. I re-trued each to the new verdict and left every other #24563 assertion untouched: two nosuch_obj lines in runtime-gate.package-closure.test.ts, the protocol #24563 (c) 'nowhere' half, and the #9313 view-writes pin 'outside the live universe is not judged' (now exactly one list-view-object-unknown, sort axis still skipped). (2) Files beyond the claim's surface: packages/lint/src/index.ts, a one-line barrel export the rule-id-barrel-exports contract requires for the new id; runtime-gate.view-writes.test.ts, a lint pin; and .changeset/24563-list-view-out-of-closure.md, whose 'Unchanged' bullet said an object that exists nowhere stays unjudged at the overlay door, which this PR makes false in the same 18.0.0 pass. That last one is a deliberate correction under the bounded in-place-fix exemption, named in the PR body; check-empty-changeset reds on it by design (Check Changeset is not required), and it needs the seat's or maintainer's written confirmation on the PR. (3) Fixtures outside lint/spec re-trued (the declared consumer-fixture rider): 10 in objectql and 3 in rest, each bound to a real object, with assertions unchanged. (4) The draft pin lives at the protocol layer only, because lint's gate has no draft state. (5) A new rule id rather than a reused one: object-reference-unknown carries the CLI ladder and its os explain text, and the closure id names a package remedy. The error family (error, 422 at the binding) is reused. (6) runtime-gate.ts was not edited (runtimeWriteType plus an absent packageScope already state it), and authoring-rules.ts was not touched. (7) Commit trailers use AGENTS.md's model-free pair (Claude-Session plus Co-authored-by: Claude), not the harness reminder's model-named Co-Authored-By, which the pre-push hook refuses; reported, not followed. (8) CI check-runs were in progress at report time.",
    "tests": "Final head 3df1387 (origin/main 795ff70 merged, full turbo build of that tree), under os-verify-lock with --maxWorkers=2: @objectstack/lint whole package, 149 files / 6958 tests passed; @objectstack/metadata-protocol whole package, 251 passed + 3 skipped files / 20816 passed + 19 skipped; @objectstack/objectql whole package, 451 files / 8495 passed; rest's 3 re-trued files, 18 passed; dogfood's 11 view-writing files, 90 passed. Before the merge: runtime 431 files / 7570 passed + 19 skipped at 39475b9; cli --project unit 314 files / 4643 passed at 54fb13a (integration tier declared to CI); platform-objects 79 files / 1195 passed at 54fb13a; rest whole package at 39475b9 had 304 passed + 3 red files, the 3 re-trued since; objectql at 6f8c259 had 10 red files / 41 tests, all list-view-object-unknown, re-trued since. New lint pins: runtime-gate.whole-collection.test.ts, 14 cases, verbose run all green. Ablation via scripts/ablation-replace.mjs (anchor 1 to 0, blob moved; restore proven blob == HEAD and git diff HEAD empty): A1, lint src, severity error to warning: 7 failed / 59 passed over 3 files. B1, lint src, refusal line deleted: 9 failed / 57 passed. A2, protocol through lint dist, severity error to warning: rebuilt, ablation-dist-preflight hit in dist/index.js, index.cjs and runtime.cjs, then 5 failed / 163 passed in protocol.runtime-authoring-gate.test.ts; restored, rebuilt, preflight --absent exit 0 with the tree clean, and a control proved the fix is back in dist. Direction as predicted (red) in all three legs.",
    "gates": "Derived on 3df1387 with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 96 families, all run with each exit captured before any pipe. --ran reconciliation: '96 derived, 96 run, 0 NOT-MEASURED, 0 UNRUN (a DERIVED zero)'. 95 exited 0; 1 exited 1: node scripts/check-empty-changeset.mjs --base origin/main, the DELIBERATE CORRECTION of the #24563 changeset, red by design. Named: check-adr-0087-registration --base origin/main exit 0 ('1 declared-breaking changeset(s), each carrying an ADR-0087 disposition', not-required (no-migration-prescription)); check-changeset-no-major exit 0; check-nul-bytes exit 0. typecheck on 3df1387 (one && chain, exit 0, 0 error TS) for lint, metadata-protocol, objectql and rest, with check:test-typecheck OK for lint, objectql and rest. PR check-runs on head 3df1387 at report time (38): in_progress for Lint & Repo Gates lanes, TypeScript Type Check lanes, Test Core 1-6/6, Build Core, Governed Surface Queue Guard, Check Changeset and others; completed success for Check PR Size, Check Documentation Links, Part-of PR must not also close its card, No other open PR may claim the same issue, No other open PR may claim the same single-writer path, and filter; skipped (push-battery only) for Temporal Conformance, Dogfood Regression Gate matrix, Dogfood Verify CLI and Console Pin Gate. Check Changeset is expected red (deliberate correction; not a required context).",
    "mcp_calls": "0",
    "api_writes": "2 — two POST /repos/objectstack-ai/objectstack/dispatches (fleet-write relay, as objectstack-fleet[bot]): (1) pr_create, executed as POST /repos/objectstack-ai/objectstack/pulls (draft) plus POST /repos//issues/24789/assignees; read back 16604 bytes sent, 16604 stored, identical, assignee zhuangjianguo; (2) this os-dev-report comment, executed as POST /repos//issues/24668/comments. git push of the branch is not a REST write.",
    "pr_body_edits": [],
    "open_questions": [
    {
    "question": "Confirm on PR #24789 the deliberate correction of .changeset/24563-list-view-out-of-closure.md's 'Unchanged' bullet. Check Changeset stays red by design (check-empty-changeset DELIBERATE CORRECTION class; not a required context).",
    "options": [
    "A: keep the corrected sentence ('An object that exists nowhere gets no closure verdict there; #24668 refuses it as list-view-object-unknown')",
    "B: restore the base sentence and let the 18.0.0 notes carry two contradictory statements about the overlay door"
    ],
    "recommendation": "A, because both changesets ship in the same version pass, and B would publish 'stays unjudged there' beside this PR's refusal; the correction is one sentence and moves no other text."
    }
    ],
    "out_of_scope_findings": [
    "carrier: domain:spec seat · noted, not filed — AuthoringRuleContext.packageScope's docblock (packages/lint/src/authoring-rules.ts) still says an object missing from a whole snapshot 'may come from another package'; that is now true only for the CLI. Not edited: outside the claim's surface, and #24677 may touch the file.",
    "carrier: domain:spec seat · noted, not filed — the runtime-gate.ts comment at the packageScope statement ('from one a whole-collection snapshot merely does not carry') has the same staleness.",
    "carrier: none · noted, not filed — boundary: assertRuntimeAuthoringRules' listRegisteredCollection answers [] when registry.listItems throws; with a non-empty stored half the universe is then partial, and a view bound to a registry object would be refused. A fault path with no repro or reach; the dataset door's object-reference-unknown already depends on the same collection. Recorded in the PR's Acceptance notes.",
    "carrier: none · noted, not filed — publishPackageDrafts for a package the registry cannot produce takes this verdict by construction; not pinned here (Acceptance notes)."
    ]
    }


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:spec seat 2 · session session_019oFY6Hi35J7atvgVFnmoaK · 2026-10-20T07:35Z


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:recordsBusiness objects, records, the views that show data, usable forms, searchbugSomething isn't workingdomain:specpriority:p2Medium: important, M3target:v18

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions