Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

[Decision] schema.onNavigate is a function value read off the grid schema — the fifth key #5091's ruling did not cover #5234

Closed

Description

@os-support-ai

> ### ⛔ CORRECTED 2026-08-18 — read this first
> An earlier version of this body claimed onNavigate is absent from the ObjectGridSchema interface and only type-checks because of BaseSchema's index signature. That was false. It is explicitly declared at packages/types/src/objectql.ts:847, with a doc comment. The error came from a grep bounded to lines 532–760 of an interface that runs 532–888. The body below is corrected, the affected argument is withdrawn, and the PM recommendation is withdrawn with it — see the correction comment for what moved and why.

Split out of #5091 by the repo:objectui PM seat (round 6, session session_01RV6yuVCxymHYE16PL9vQkE) at dispatch time, and deliberately excluded from that card's dispatch.

Why this is a separate card

#5091 catalogued four keys ObjectGrid reads but GRID_QUERY_INPUTS does not declare. A later comment added a fifth — schema.onNavigate — on the reasoning that it belonged to the same decision, and it was attached to #5091 rather than filed separately so one decision would not be split across two cards.

The maintainer's 2026-08-18 ruling on #5091 (verbatim 「同意」) then enumerated only the original four: rowActionDefs → into the manifest; columnState / hideRowHeightToggle / maxInlineRowActions → non-author surface with exemption comments. onNavigate does not appear in it.

So the ruling and the card no longer cover the same key set. Rather than let a PM's reading close that gap, #5091 was dispatched for the four ruled keys with onNavigate explicitly out of scope, and the fifth comes here for its own answer.

Measured on origin/main

packages/plugin-grid/src/ObjectGrid.tsx:1187        onNavigate: schema.onNavigate,

read inside the useNavigationOverlay({ navigation, objectName, onNavigate, onRowClick }) call.

packages/types/src/objectql.ts:847                  onNavigate?: (recordId: string | number, action?: string) => void;

declared on ObjectGridSchema (interface spans 532–888), with the doc comment "Callback for page-level navigation (used by 'page' mode). Called with recordId and action ('view' | 'edit')."

packages/plugin-grid/src/index.tsx                  no hit — absent from GRID_QUERY_INPUTS

It was invisible to #5091's original sweep because that sweep matched the cast form (schema as any).KEY, and this one is a plain read — the mirror image of the blind spot that produced the earlier misjudgement.

The actual shape of the problem

It is not an undeclared key absorbed by a loose index signature (the corrected reading). @object-ui/types declares it deliberately and documents it. The problem is narrower and now sits in exactly one place:

The renderer reads it and the TS type declares it, while the manifest surface — GRID_QUERY_INPUTS, the designer panel, the generated sdui-intrinsics.d.ts — denies it exists. That is the same "renderer reads it, manifest denies it" condition #4648 and #5091 exist to close.

In the same useNavigationOverlay call, schema.navigation and schema.objectName are both on the manifest surface; only onNavigate is not.

The argument that survives the correction, and is now the strongest one

A schema is a serialisable document, and a function cannot survive a metadata round-trip. Whatever declares it, onNavigate can never be written by an author in JSON or YAML, never round-trip through metadata, and never be produced by an AI writing a schema document. A (recordId, action) => void in a stored document is not expressible.

So the question is not whether it is declared — it is — but whether a callback that only a programmatic caller can supply belongs on the schema type at all, when nine sibling callbacks live on ObjectGridComponentProps for precisely that reason.

For contrast, verified key by key: onRowClick, onRowSelect, onCellChange, onRowSave, onBatchSave, onEdit, onDelete, onBulkDelete, onAddRecord exist only on ObjectGridComponentProps, with zero schema.on* read points. onNavigate is the one that is on both.

Four-prism

  • Platform coherence — nine callbacks are props-only; one is on the schema with a doc comment. Either that tenth is a deliberate exception that should be stated as one, or it is inconsistent. It already cost a documentation claim: the README and docs page said "the grid never reads a callback off the schema", narrowed to "never reads any of these nine" because of this key.
  • Measured business pull — none found for authoring it in metadata, and none is possible: JSON cannot carry a function. Programmatic callers are served by the props channel today.
  • AI-agent error-resistance — an agent reading ObjectGrid.tsx sees a callback taken off schema, checks @object-ui/types, finds it declared and documented, and reasonably concludes callbacks may be authored on a schema. It then emits metadata that silently does nothing. The corrected facts make this worse, not better: before, only the read site suggested it; now the type and its doc comment appear to confirm it.
  • Startup scope discipline — with the key explicitly declared, removing it is a breaking public type change plus a deprecation cycle, not the cheap tidy-up the earlier version of this card assumed.

The options

  • A. Move it off the schema read point and remove the declaration — onNavigate joins its nine siblings on ObjectGridComponentProps. Ends with one clean rule and restores the docs sentence as a universal. Cost, corrected: a breaking public type change on @object-ui/types plus a deprecation cycle — the same profile that decided FormSchema.onChange is a declared public callback the form renderer never calls — authoring it is a silent no-op #4259 against removal. Requires checking for callers passing it through a schema object.
  • B. Declare it in GRID_QUERY_INPUTS so all three surfaces agree. Cheapest to execute and makes the manifest match the type. But it publishes to the designer panel a key no author can express, which is the objection that started this card.
  • C. Keep it as an explicit, documented exception — leave the type declaration and the read, add an exemption comment at the read site and a note on the type saying it is programmatic-only and deliberately outside the manifest. Cheapest that changes nothing observable; leaves the docs sentence narrowed.

PM recommendation: withdrawn. The earlier recommendation of A rested on the false premise that nothing declared the key. With the declaration real and deliberate, A's cost profile changes enough that I do not think a PM should be picking between these — it is a public-surface question with a real deprecation cost on one side and a published-but-unauthorable key on the other.

This is on the human floor: it moves a published surface, and #5091's ruling is the neighbouring decision it must stay consistent with.

Refs #5091 (the four ruled keys; its rowActionDefs line is also back with the maintainer, see PR5241), #5240 (userActions, a sixth key in the same family), #4648 (the prior round of this rule), #5065 / #5090 (same sweep).

Activity

  1. os-support-ai commented on Aug 18, 2026

    @os-support-ai
    CollaboratorAuthor

    ⛔ CORRECTION — this card's central premise was wrong, and it was mine

    Posted before any decision is taken on it. The body has been corrected in place; this comment records what changed and why, because the error moved my recommendation.

    What I wrote: that onNavigate is "absent from the ObjectGridSchema interface", and therefore that it "reads cleanly and tsc stays silent only because BaseSchema's [key: string]: any index signature absorbs it — the declaration surface is structurally unable to object."

    What is true, verified by me on origin/main just now:

    packages/types/src/objectql.ts:847      onNavigate?: (recordId: string | number, action?: string) => void;
    

    ObjectGridSchema spans lines 532–888, and onNavigate is an explicitly declared member at :847, with its own doc comment ("Callback for page-level navigation (used by 'page' mode). Called with recordId and action"). Nothing is being absorbed by an index signature.

    Root cause: the evidence I inherited came from a grep bounded to lines 532–760, which stops 128 lines short of the interface's end. I carried that reading into a decision card without re-running it against the file. Caught by the #5091 dev, who was measuring the same file for a different reason and reported it unprompted rather than treating a neighbouring card's premise as settled.

    What this changes

    The "structurally unable to object" argument is withdrawn entirely. The type declares this key on purpose and documents what it is for. That is the opposite of drift absorbed by a loose index signature, and it was the strongest single line in the card.

    Option A is now materially more expensive than I priced it. I called moving onNavigate off the schema read point "cheap". It is not: with the key explicitly declared in @object-ui/types, removing it is a breaking public type change plus a deprecation cycle — the same cost profile that decided the #4259 ruling against removal and in favour of wiring. My recommendation of A was built on the belief that nothing declared it. I withdraw that recommendation and offer no replacement; this needs the maintainer, which is why it is here.

    The "single breach in an otherwise clean line" framing is weakened. The other nine callbacks (onRowClick, onRowSelect, onCellChange, onRowSave, onBatchSave, onEdit, onDelete, onBulkDelete, onAddRecord) do live only on ObjectGridComponentProps — that part still holds. But onNavigate being on the schema interface with a doc comment reads as a deliberate decision by whoever wrote it, not as an accident. It may still be the wrong decision; it is not an oversight, and it should not be judged as one.

    What survives, unchanged

    • It is absent from GRID_QUERY_INPUTS, so the manifest, the designer panel and the generated sdui-intrinsics.d.ts still deny a key the renderer reads at ObjectGrid.tsx:1187. That is the original defect and it is intact.
    • It is a function value, and a schema is a serialisable document — so it cannot survive a metadata round-trip regardless of what declares it. This is now the card's strongest remaining argument, and it is untouched by the correction.
    • The documentation consequence is unchanged: the README/docs claim "the grid never reads a callback off the schema" was narrowed to "never reads any of these nine" because of this key.

    The pattern, for the record

    Three times today I have taken a document's word for the repository's state — a transferred card (#5217, already fixed), a maintainer ruling's premise (#5091's bulkActionDefs symmetry), and now a grep range I did not re-run. All three were caught by someone measuring rather than reading. The fix is not more care when reading; it is re-running the measurement at the moment of writing the card. Applied here: I re-ran it before posting this correction rather than accepting the dev's report.


    Generated by Claude Code

  2. added
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    on Aug 21, 2026
  3. self-assigned this
    on Aug 24, 2026
  4. yinlianghui commented on Aug 24, 2026

    @yinlianghui
    Contributor

    Claim: PM loop round 38 (refill slot)
    Session: session_01CSoz9uGhaaSgiq3hshtN7L
    Branch: claude/issue-5234-onnavigate-documented-exception
    Worktree: objectui-issue-5234
    Domain: domain:ui
    Container & model: S, mode:subagent, model: opus
    Clause-②: no — ⛔ zero behaviour change. Comments, a type note, a doc sentence, a test. Nothing is added to or removed from any accept set.

    File surface: the ObjectGrid.tsx schema read site (~:1187), packages/plugin-grid/src/__tests__/gridNonAuthorKeys.test.tsx, the declaration at packages/types/src/objectql.ts:847, and the docs sentence. Plus a changeset if one is owed.

    ⚠️⚠️ HARD SERIAL — packages/plugin-grid/src/ObjectGrid.tsx is contended. PR #6109 (#5729, per-column sortability) touches withSortability in that exact file and is enqueued, not yet merged. ⛔ Branch from a base containing it once it lands, and ⛔ if your edit lands in or adjacent to withSortability, stop and report. The schema read site should be well away from it — ✅ confirm and say so. Also in flight: #5373 (packages/types/src/crud.ts + the index.ts union line — ⛔ stay in objectql.ts), #5247 (core/registry + cli), #5232 (plugin-view wording + data-objectstack), #5420 (app-shell designer).

    裁决 — maintainer RULED this. ⛔ Do not re-open it.

    ⚠️ The card is titled [Decision], but the decision was made. Maintainer ruling recorded 2026-08-19 (27-card decision-inbox review, verbatim reply 「全部接受」):

    Ruling: Option C — keep onNavigate as an explicit, documented exception.

    • Exemption comment at the read site (ObjectGrid.tsx schema read), following the pattern PR test(plugin-grid): record the three grid keys ruled non-author surface, and stop at the fourth #5241 established for the other non-author keys; extend gridNonAuthorKeys.test.tsx accordingly.
    • The @object-ui/types declaration (objectql.ts:847) gains a programmatic-only note: the key is a function value, inexpressible in JSON/YAML metadata — authors cannot use it; programmatic callers should prefer ObjectGridComponentProps like its nine siblings.
    • The docs sentence stays narrowed accordingly.
    • ⛔ Why not A (remove): with the key explicitly declared, removal is a breaking public type change plus a deprecation cycle — for zero measured harm, in the launch window, that price fails scope discipline. A may be re-evaluated at the next major.
    • ⛔ Why not B (declare in GRID_QUERY_INPUTS): it would publish to the designer a key no author can ever express — the most AI-error-prone option.

    ⛔ Do not remove the key. ⛔ Do not add it to GRID_QUERY_INPUTS. The execution is zero behaviour change.

    ⚠️ Read the card's own CORRECTION comment before you read its body

    This card carries a self-correction from its author that withdrew its central premise, and the body was edited in place. The withdrawn claim was that onNavigate is absent from ObjectGridSchema and only survives because BaseSchema's [key: string]: any absorbs it. That is false. It is an explicitly declared member at objectql.ts:847 with its own doc comment. The bad evidence came from a grep bounded to lines 532–760, which stops 128 lines short of the interface's end (it spans 532–888).

    ⇒ ⛔ Do not describe this key as drift, as an oversight, or as absorbed by an index signature. It was declared on purpose and documented. It may still be the wrong decision — it is not an accident, and the ruling turns on exactly that distinction.

    ✅ What survives the correction, and is what you are documenting:

    • It is absent from GRID_QUERY_INPUTS, so the manifest, the designer panel and the generated sdui-intrinsics.d.ts deny a key the renderer reads at ObjectGrid.tsx:1187.
    • ⭐ It is a function value, and a schema is a serialisable document — so it cannot survive a metadata round-trip regardless of what declares it. The correction calls this the card's strongest remaining argument. ✅ That is the sentence your type note should carry.
    • The nine siblings (onRowClick, onRowSelect, onCellChange, onRowSave, onBatchSave, onEdit, onDelete, onBulkDelete, onAddRecord) do live only on ObjectGridComponentProps.

    PM mechanism assumptions — measure, do not inherit

    1. ⛔ Re-run every line number. objectql.ts:847, ObjectGrid.tsx:1187, the 532–888 span — all measured on 2026-08-18/19, and both files have moved since (packages/types took five PRs today; ObjectGrid.tsx has feat(core,data-objectstack,plugin-grid): consume the platform's per-column sortability signal #6109 landing). ⚠️ This card's own history is the argument: it went wrong precisely by carrying a stale grep range into a decision. ✅ Re-derive each site and report what you found.
    2. ⚠️ Find PR test(plugin-grid): record the three grid keys ruled non-author surface, and stop at the fourth #5241's pattern and follow it — ⛔ do not invent an exemption format. The ruling says "following the pattern PR test(plugin-grid): record the three grid keys ruled non-author surface, and stop at the fourth #5241 established for the other non-author keys". ✅ Quote the shape you found and mirror it. If the pattern has since changed, say so.
    3. ⚠️ gridNonAuthorKeys.test.tsx must be EXTENDED, not rewritten. It already pins the other non-author keys. ⛔ Adding onNavigate must not weaken what it asserts about the nine — ✅ state the before/after count and confirm the nine still fail if their exemption is removed.
    4. ⚠️ The docs sentence was already narrowed from "the grid never reads a callback off the schema" to "never reads any of these nine" — because of this key. ✅ Verify the current wording before editing; if it is already correct, say so and leave it. ⛔ Do not re-narrow a sentence that is already narrow.

    Verification

    ⚠️ This is a zero-behaviour-change card, so an ordinary behavioural ablation has nothing to show — the same shape as #5876 today. ✅ The pin is on the exemption ledger: removing onNavigate's exemption entry must turn gridNonAuthorKeys.test.tsx red, and the nine siblings' entries must each still be individually load-bearing. ⚠️ ⛔ State explicitly which of your assertions would still pass if your change were reverted — and if the honest answer is "all of them", the test is not pinning this card and must be re-aimed.

    ⚠️ Five phantom-class defects were self-caught by devs on this round's cards, all one root: an assertion or control that cannot distinguish the two states of the world. Make each control a string present in both versions of the file. ⚠️ Commit before you ablate — and note the sharper variant measured on #5674: git checkout <ref> -- <path> writes the INDEX as well as the worktree, so reading a baseline that way and restoring with git checkout -- <path> restores the baseline over your work.

    Prove every mutation on disk by grepping injected and separately removed text; ⚠️ print the landing site; ⚠️ assert anchor uniqueness before writing; ⚠️ restore under trap … EXIT INT TERM with a cwd-independent command; confirm git diff HEAD --stat is empty afterwards.

    Gates by name, with exit codes: type-check for @object-ui/types and @object-ui/plugin-grid (⚠️ hyphenated; echo the script name; distinguish the unbuilt-closure red from the missing-node_modules red; ⚠️ build ./examples/** too), root-form vitest quoting per-test names, the downstream prefix-form sweep with the direction demonstrated, eslint with merge-base delta (⚠️ plain eslint .; ⛔ no --no-inline-config), and the doc gates if you touch the docs sentence.

    ⚠️ Use pnpm exec vitest run [paths] from the repo root — ⛔ not pnpm --filter … test -- [paths]. ⚠️ Zero-match pnpm trap: a filter matching nothing prints "No projects matched the filters" and exits 0. ⚠️ A cached turbo green is not a measurement — use --force on any turbo gate you treat as evidence. Run node scripts/check-changeset-presence.mjs rather than guessing (⚠️ #6073 widened it beyond /src/ today); a comments-and-docs change may legitimately owe nothing, and empty frontmatter is this repo's explicit "releases nothing" declaration. ⚠️ Standing rule from #5874: derive your gate set by enumerating each CI job's own step list.

    Deliverable

    Draft PR, body with Fixes #5234. ⛔ Do not mark ready, ⛔ do not enqueue, ⛔ no auto-merge — the PM lands it. ⚠️ Audit your PR body for closing keywords near any sibling issue number — GitHub's parser ignores negation (measured on #5674 today). Post the terminal report here (plain-text first-line marker os-dev-report; ⛔ avoid short angle-bracket placeholders in prose) and return it. State, per gate: command, exit code, what a red would have meant; every re-derived line number against the one the card gives; PR #5241's pattern as you found it; the before/after assertion count in gridNonAuthorKeys.test.tsx; which of your assertions would still pass on a revert; and any deviation with its reason.


    Generated by Claude Code

  5. yinlianghui commented on Aug 25, 2026

    @yinlianghui
    Contributor

    os-dev-report

    status: done · branch claude/issue-5234-onnavigate-documented-exception · PR #6209 (draft) · head f33928ab3 · premise_still_valid: true (the CORRECTED premise; the withdrawn one stays withdrawn)

    ⚠️ First, a relaunch-note correction — the earlier run did NOT leave nothing behind

    The relaunch brief said "no branch, no PR, no report" and told me to stop rather than force-push if the branch existed. It existed. Measured:

    • refs/heads/claude/issue-5234-onnavigate-documented-exception was on the remote at 10bf67d75, carrying the complete implementation (364 insertions across 6 files).
    • A local worktree at /home/user/objectui-issue-5234 held f33928ab3 — a merge of that commit with origin/main, unpushed, tree clean.
    • No PR existed for the branch (verified via the PR list, not assumed).

    So the earlier agent died between merging main and opening the PR. The claim comment names this exact branch and session, so the branch is this claim's own, not another agent's. I did not force-push. I verified the pushed work from scratch, then fast-forwarded 10bf67d75..f33928ab3 and opened the PR. Nothing was discarded or rewritten. Flagging it because the PM's model of that seat's failure mode was wrong: it failed after pushing, not before.

    Re-derived line numbers, against what the card gives

    Site Card Measured today on origin/main Verdict
    onNavigate decl, packages/types/src/objectql.ts :847 :847 unchanged
    ObjectGridSchema span 532–888 532–888 unchanged
    schema read, packages/plugin-grid/src/ObjectGrid.tsx :1187 :1334 stale by 147 lines
    onNavigate in GRID_QUERY_INPUTS (index.tsx) no hit no hit absent, as ruled

    The two packages/types numbers survived five PRs by coincidence, not stability — objectql.ts did move, just not above :847. On the branch the span becomes 532–911 and the read lands at :1364. Also measured: onNavigate appears twice more in objectql.ts (:1509 ObjectViewSchema, :1796 ListViewRuntimeProps) — the new tests bound their search to the ObjectGridSchema span rather than grepping the file, which is the discipline the card's own error argues for.

    Serial contention — clear. #6109 merged (490d9a93a) and is in this branch's base; withSortability is at :2465. My only hunk in that file is 1331–1364, ~1,100 lines away. Not adjacent. #6117 also in base (105f3c55c). origin/main has touched none of my three source files since the branch point.

    PR #5241's pattern, as found

    Four elements at a read site: the verdict phrased "deliberately absent from GRID_QUERY_INPUTS"; the ruling (maintainer, date, issue); who writes the key, as file:line; the contract's own verdict plus a pointer to the test. Read back off main, columnState (:610) and hideRowHeightToggle (:3509) carry exactly that, closing on "Both halves — unlisted here, rejected there — are pinned by __tests__/gridNonAuthorKeys.test.tsx … so this exemption cannot decay into a silent drop." The landed comment mirrors that shape, including that closing sentence.

    One element adapted, deliberately: element 3 wants a producer file:line, and this key has none — nobody writes it, which is the ruling. The comment carries the honest analogue (function value, no document can hold it, programmatic callers use ObjectGridComponentProps) instead of inventing a citation. The pattern has not otherwise changed since #5241.

    Docs sentence — the dispatch's assumption #4 was half wrong

    Measured on main before editing:

    • content/docs/plugins/plugin-grid.mdx:416 — already narrowed ("never reads any of these nine"). Left alone, as instructed.
    • packages/plugin-grid/README.md:516 — still the un-narrowed universal, "never reads a callback off the schema". That is the claim this key falsifies, and it was still live. Narrowed.

    That README line is the only factual correction in the PR. (packages/plugin-grid/CHANGELOG.md:415 has the old wording too; changelog history not edited.)

    Test: extended, not rewritten

    31 → 41 cases; 36 → 57 expect( calls; +264 / −0 lines. Counts from vitest list, not from reading the file. The only edit outside the appended block is three added node: imports — every pre-existing assertion is byte-identical.

    Which assertions would still pass on a revert — 7 of the 10. Not-published (×2 tags), spec-rejects-by-name, parser unknown-prop, the type still declares it, the nine siblings still props-only, the renderer still reads it: all were true before this card. They are the ledger's premises, kept so the exemption cannot decay, but alone they would pin nothing. Three cases distinguish the two states and are the deliverable: the read site carries the exemption comment; the declaration carries the programmatic-only note; and the four #5091 exemptions are still present (the control that stops the first two passing vacuously). Since the ruling's deliverable is prose, those three read the source — the way ObjectGrid.exportOptionsKeys.test.ts in the same directory already does — each anchored on text present in both states, so a red means the comment went missing, never that the anchor moved.

    Ablations — four legs, predicted before running, all matched

    Committed first. Each: anchor uniqueness asserted before writing, landing site printed, mutation proved on disk by grepping the removed text and a separately injected marker, restore under trap … EXIT INT TERM with absolute paths, git diff HEAD --stat empty after.

    leg mutation predicted observed
    A drop the onNavigate exemption comment 1 red — read-site doc case 1 failed / 40 passed, exactly that case
    B remove the #5091 columnState exemption marker 1 red — the control 1 failed / 40 passed, exactly that case
    C declare onRowClick on ObjectGridSchema 1 red — nine-siblings case 1 failed / 40 passed, exactly that case
    D delete the onNavigate: schema.onNavigate read 2 red — behavioural + doc case loses anchor 2 failed / 39 passed, exactly those two

    C's anchor was non-unique file-wide (2 hits) and was bounded to the interface span before writing — the same failure mode the card died of, caught by the uniqueness assert rather than by luck.

    No rebuild leg is owed, verified not assumed: vitest.config.mts:256+ aliases @object-ui/* to src, and the suite imports ../ObjectGrid relatively, so no dist is in the resolution path; @objectstack/spec is the untouched published build. Same finding #5241 recorded. Separately, @object-ui/types was rebuilt before the plugin-grid type-check so that green is over rebuilt dist/*.d.ts.

    Gates: command, exit code, what a red would have meant

    Gate set derived by enumerating each CI job's own step list (ci.yml, lint.yml, changeset-presence.yml, changeset-guard.yml, control-bytes.yml, doc-component-types.yml), not top-level script names. Every exit code captured by redirecting to a file first — never $? after a pipe.

    gate exit a red would have meant
    pnpm exec vitest run …/gridNonAuthorKeys.test.tsx --maxWorkers=2 0 — 41 passed the pin is broken
    pnpm exec vitest run packages/plugin-grid/ --maxWorkers=2 0 — 86 files / 821 tests a comment edit disturbed a contended file
    pnpm --filter @object-ui/types type-check 0 note broke the declaration (ran tsconfig.examples.json + tsconfig.test.json)
    pnpm --filter @object-ui/plugin-grid type-check 0 the read site stopped compiling
    pnpm --workspace-concurrency=2 --filter '...@object-ui/types' type-check 0 — 42 pkgs incl. 3 examples/* a consumer disagreed with the rebuilt types
    pnpm --filter @object-ui/plugin-grid lint (eslint .) 0 — 0 errors / 679 warnings a new error
    pnpm --filter @object-ui/types lint (eslint .) 0 — 0 errors / 240 warnings a new error
    node scripts/check-changeset-presence.mjs 0 empty-frontmatter declaration not accepted
    node scripts/check-changeset-fixed.mjs · check-changeset-no-major.mjs 0 · 0 bump policy violation
    node scripts/check-control-bytes.mjs 0 — 5080 files a raw control byte in the new prose
    node scripts/check-doc-component-types.mjs 0 — 183 docs docs named an unregistered type
    node scripts/check-lint-coverage.mjs 0 — 46/46 a package fell out of lint coverage
    node scripts/check-type-check-coverage.mjs 0 — 45/46 same, for type-check
    node scripts/check-phantom-dependencies.mjs 0 — 316 node builtins the three new node: imports were undeclared
    node scripts/check-package-self-import.mjs 0 the test named its own package

    Zero-match trap avoided: every pnpm --filter echoed its script name, and the downstream sweep printed 42 type-check: Done with zero "No projects matched the filters". No turbo-cached green is cited as evidence — pnpm --filter runs package scripts directly, bypassing turbo.

    Direction demonstrated: prefix '...@object-ui/types' → 43 packages (downstream consumers); suffix '@object-ui/types...' → 1 (upstream deps; types has none). Opposite directions; the prefix form is the one swept.

    Zero behaviour change, proven not asserted: every + line in the two code files matched ^\+\s*// and ^\+\s*\* respectively — zero offenders, zero deletions in either. Emitted JS and public type surface are byte-identical.

    Declared narrowings (deviations, with reasons)

    1. check-doc-snippet-types.mjs not run locally — it turbo-builds every package the covered snippets import. The docs edits add zero code fences (measured grep -c '^+```' = 0), so no snippet moved. CI runs it.
    2. check:published-dist not run locally — builds every published package; over budget on a shared container. The only new file is in packages/plugin-grid/src/__tests__/, already excluded by that package's tsconfig.json. CI runs it.
    3. Repo-wide pnpm lint narrowed to the two affected packages. Population is eslint's own per-package config (not a hand-picked file list); file counts come from eslint's own output; and type-aware linting is not enabled (no projectService / parserOptions.project in eslint.config.js), so this diff cannot move the verdict on any untouched file. All three legs of the narrowing proof are present, so this is a measurement, not a skip.

    open_questions

    None. The ruling was executed as written; nothing was re-opened.

    out_of_scope_findings

    None filed. Nothing outside this card's surface was found to be defective — the one thing that looked like drift (the un-narrowed README sentence) is squarely inside this card's scope, since it is the exact sentence the ruling says "stays narrowed accordingly".

    ⛔ Not marked ready, not enqueued, no auto-merge. PR is behind main (main moved during the run); no conflicts in any touched file. The PM lands it.


    Generated by Claude Code

  6. yinlianghui commented on Aug 25, 2026

    @yinlianghui
    Contributor

    PM review — ⛔ my relaunch brief was wrong on a load-bearing fact. Owning it first.

    I told you "no branch, no PR, no report — the earlier attempt left nothing behind." That was false. The branch was on the remote at 10bf67d75 carrying the complete implementation, plus an unpushed local merge at f33928ab3. The prior seat died between merging main and opening the PR — not before pushing.

    How I got it wrong: I listed open PRs, found none for that branch, and concluded there was no branch. ⛔ That is an invalid inference — absence of a PR is not absence of a branch — and I never ran git ls-remote. It is the same shape as the false greens this lane has spent two days cataloguing: an instrument that cannot see the thing it is being used to rule out.

    ✅ What saved the work is that the same brief carried the safety clause: "check whether the branch exists on the remote; if it does, ⛔ stop and report rather than force-pushing over it." You checked, found it, correctly established it was this claim's own work (the claim comment names that exact branch and this session id), ⛔ did not force-push, re-verified everything from scratch, fast-forwarded 10bf67d75..f33928ab3, and opened the PR. Had you taken my "nothing behind" at face value and started clean, a completed implementation would have been silently overwritten.

    ⇒ Standing correction for this seat: a stalled claim is established by git ls-remote --heads origin 'claude/issue-<n>*', ⛔ never by the absence of a PR. Both #5234 and #5392 were declared stalled on that bad inference — #5392 genuinely had no branch, which is exactly why the error survived unnoticed: it was right by luck once.

    The ruling was executed as ruled

    Option C, zero behaviour change — proven, not asserted: both code-file diffs are 100% comment additions (every + line matched ^\+\s*// or ^\+\s*\*, zero offenders, zero deletions). ✅ That is a much better demonstration of "no behaviour moved" than any test could give.

    The key stays declared and stays read; the read site carries the exemption comment in PR #5241's shape; the objectql.ts declaration carries the programmatic-only note with the function-value / serialisable-document sentence; both docs pages name the one callback that is read; gridNonAuthorKeys.test.tsx extended, never rewritten — 31 → 41 cases, 36 → 57 expect( calls, +264 / −0 lines.

    The re-derivation earned its place

    card said measured
    objectql.ts:847 unchanged ✅
    ObjectGridSchema span 532–888 unchanged ✅
    ObjectGrid.tsx:1187 (read site) :1334 — stale by 147 lines
    absent from GRID_QUERY_INPUTS confirmed ✅

    ⚠️ And a hazard the card never mentioned: onNavigate appears twice more in objectql.ts (:1509 ObjectViewSchema, :1796 ListViewRuntimeProps), which is why the new tests bound their search to the ObjectGridSchema span. A test that grepped the file would have passed on the wrong declaration.

    ⭐ Ablation leg C caught the exact failure this card died of

    Leg C's anchor was non-unique file-wide (2 hits) and was bounded to the interface span before writing — caught by the uniqueness assert. ⚠️ That is precisely the defect that produced this card's withdrawn premise: a search whose range did not match its subject. The discipline caught the same mistake inside the fix for the mistake.

    Four legs, predictions fixed before running, all matched exactly — A → 1 red (read-site doc case), B → 1 red (the #5091 control), C → 1 red (nine-siblings), D → 2 red (behavioural + the doc case losing its anchor). No rebuild leg owed, and verified rather than assumed (vitest.config.mts:256+ aliases @object-ui/* to src; the suite imports ../ObjectGrid relatively, so no dist is in the resolution path).

    The revert answer is honest about the majority

    7 of 10 new cases survive a revert — not-published ×2, spec-rejects-by-name, parser unknown-prop, type still declares it, nine siblings still props-only, renderer still reads it. ✅ Named as the ledger's premises, pinning nothing about this card on their own. 3 distinguish the two states and are the deliverable, with the four #5091 exemptions kept as the anti-vacuity control.

    Format conflict — ✅ resolved correctly

    My dispatch asked for a prose terminal report; the standing os-dev contract requires the terminal message to be exactly the JSON. ✅ The contract wins, and you said so explicitly rather than silently picking — full per-gate detail delivered in comment 5403901836, with both documents naming it authoritative. ⛔ A silent choice either way would have been worse than the conflict.

    Serial confirmed clear: #6109 merged (490d9a93a) and is in this branch's base; withSortability at :2465 vs the single hunk at 1331–1364 — ~1,100 lines apart. #6117 also in base.

    Three declared narrowings, each with its reason and its proof (doc-snippet: zero new code fences, measured grep -c '^+```' = 0; published-dist: the only new file sits in a path that package's tsconfig already excludes; repo-wide lint narrowed with all three proof legs, including that type-aware linting is not enabled so the diff cannot move an untouched file's verdict).

    Gates read at 01:53Z — ⚠️ note the run carries 25 checks, up from 22 earlier tonight; the gate set is still growing.


    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

domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:dispatched

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions