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 }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
finding(react): useSettledSchema republishes an equal payload as a fresh object, so an adapter swap costs two record queries — the half of commandment #10 it breaches #10106
Dedupe words: useSettledSchema def identity · getObjectSchema republish equal payload · duplicate record query on adapter swap · objectui#6862 settled def · provider object two queries
Surfaced by the objectui#10036 dev while removing two useMemo/useCallback identity dependencies from ObjectGantt; the site is outside that card's file surface and it correctly did not reach into it. ⚠️Wholly 转述 — ⛔ NOT re-run by the domain:ui#2 execution seat. ⭐ It is filed with that label rather than dressed as a seat reading (说明 GG). ⛔ No priority:* / type: the triage seat's sole production. domain:ui inherited from the in-flight parent objectui#10036.
The claim, and the contract it is measured against
Swapping the context adapter on provider object costs TWO record queries, not one:
useSettledSchema re-reads getObjectSchema through the new adapter and settles a FRESH def object for a byte-identical answer;
objectSchema is a genuine member of the fetch effect's value list, so the query runs again when that fresh object lands.
AGENTS.md §5 commandment #10 states the contract verbatim:
a provider that refetches may not republish an equal payload as a new object, and a consumer that needs stability keys on the data, not on a cache
⇒ the first half of that sentence is what useSettledSchema is reported to breach. Site: packages/react/src/hooks/useSettledSchema.ts.
⭐ Why this is filed now rather than noticed later
The objectui#10036 pin measured it and deliberately did NOT pin the exact count for that case — so ⭐ the pin will ⛔ not go red on the day this is repaired, and the observation would otherwise have lived only in a hand-back. ⚠️ That also means nothing in the tree fails today because of it: this card is the only carrier.
⚠️ It is unchanged by PR #10100 — before and after alike. ⛔ That PR neither caused nor fixed it.
Acceptance
The two-query behaviour on an object-provider adapter swap is re-measured first-hand, with a control in the same command (a swap that should cost ONE query, so a 「two」 is a discrimination and ⛔ not a counting artefact).
If it reproduces: the repair is at the producer — republish the equal payload as the same object — ⛔ not by making the consumer key on a cache, which is the half of commandment [WIP] Enhance every detail of the designer #10 that names the wrong cure.
A pin that pins the COUNT, so the next reader is told by a red test rather than by a card.
⚠️ If it does not reproduce, say so and close not planned with the reading — ⛔ a 转述 card that fails its own re-take is a closed card, not a smaller one.
Claim: PM loop — 2026-09-20 shift, batch slot 2/2 (ceiling 2)
Session: session_018HrVaotisyhgmot9o2MLRq
Branch: claude/issue-10106-settled-schema-equal-payload
Worktree: objectui-issue-10106
Domain: domain:ui (triage's; ⛔ not re-routed here)
Seat: domain:ui#2
File surface: packages/react/src/hooks/useSettledSchema.ts and its tests. ⛔ Nothing else.
Container & model: M, mode:subagent, model: opus. ⛔ No tier output is quoted: scripts/pm/dispatch-gates.mjs REFUSES for this repo.
Clause-②: no — a provider's republish identity. No exported symbol and no key on a published payload moves. ⚠️ The dev re-declares from its actual diff and STOPS if the repair turns out to change an exported shape.
⚠️This card is wholly 转述. This seat filed it from objectui#10036's hand-back and ⛔ re-ran nothing. ⇒ its FIRST deliverable is the re-take, and ⭐ 「it does not reproduce」 is a legitimate, complete outcome — the card says so in its own acceptance: close not planned with the reading. ⛔ A 转述 card that fails its own re-take is a closed card, ⛔ not a smaller one to force through.
Hot-file serial queue: the only other card in flight is #10039 (packages/app-shell/src/console/ai/** + views/studio-design/**), disjoint from packages/react.
os-dev-report
{
"issue": 10106,
"status": "done",
"branch": "claude/issue-10106-settled-schema-equal-payload",
"pr": "#10149",
"session": "session_018HrVaotisyhgmot9o2MLRq",
"premise_still_valid": true,
"summary": "The second-hand claim REPRODUCES, re-measured first-hand before any edit. On the real consumer (ObjectGantt, instrumented adapter, provider object), swapping the adapter when the new adapter answers byte-identically as a FRESH object cost 2 find calls carrying the SAME expand set [['owner'], ['owner']]; the control in the same command — both adapters returning the SAME def object — cost 1; a second control with a genuinely different def cost 2 with the second call widening to ['owner','account']. So 'two' is a discrimination, not a counting artefact. Repaired at the PRODUCER per AGENTS.md section 5 commandment #10: useSettledSchema now keeps the object consumers already hold when a refetch's answer is value-equal, via a module-private isEqualPayload and a settle() closure; nothing moved into a consumer's dependency list and no cache was added. After the repair the subject reads 1 and both controls are unchanged. A COUNT pin with its controls ships in packages/react/src/hooks/tests/useSettledSchema.equalPayload-10106.test.tsx. No exported symbol and no key on a published payload moves; Clause-② re-declared as 'no' from the actual diff.",
"tests": "RED-before: the pin run against the hook proved byte-identical to origin/main IN THE SAME COMMAND (git hash-object == HEAD blob == bb550f98d) -> 2 failed | 3 passed; the two subject assertions failed and all three controls passed. GREEN-after: same pin with the repair on disk (blob f287de8b6, printed in the same command) -> 5 passed. ABLATION from the committed state (settle bail-out replaced by the pre-repair unconditional republish): mutation proved by content AND hash, never by exit code — injected-marker count 1, removed-guard count 0, blob f287de8b6 -> ae320ff3b; pin went 2 failed | 3 passed (same two, controls green). Restore proved the same way: blob back to f287de8b6 and git diff HEAD empty; the script carried an absolute-path trap on EXIT/INT/TERM. SUITES at fe23217 with a clean tree printed in the same command: packages/react in full plus every useSettledSchema consumer pin (gantt fetch gate, calendar, kanban x2, gallery, timeline, tree, view) and the two doc-example reader gate suites -> 115 files / 1353 tests passed. TYPE-CHECK @object-ui/react: tsc --noEmit and tsc -p tsconfig.test.json both clean; the test project SELECTS the new pin (--listFiles finds it). GATES re-run LAST at fe23217 with nothing unstaged, all exit 0: check:control-bytes, check:new-line-citations, check:doc-examples, check:doc-example-ids, check:doc-example-readers, check:doc-snippets, check:doc-types, check:readme-exports, check:test-path-roots, check:vi-mock-specifiers, check:unreferenced-sources, check:pending-changeset-literals, check-changeset-presence, check-changeset-fixed, check-changeset-no-major, eslint on both changed files (0 errors; 15 any warnings, the sibling test file carries 16 and the repo sets no --max-warnings, deliberately). NOT-A-VERDICT, recorded as such: check:doc-examples and check:readme-exports first answered PRECONDITION NOT MET / population COLLAPSED with no dist on disk (readme-exports reported typesResolved 0 against a floor of 2). Both were then re-run properly after turbo run build over the filter the gate itself prints; the greens above are from those runs, with a healthy population (readme-exports: 3384 export symbols from 36 of 40 packages, 58 keys compared). CHANGESET decided by running the gate, not from memory: check-changeset-presence exited 1 naming @object-ui/react; a patch changeset was added and it now exits 0. Every heavy run went through /home/user/objectstack/scripts/pm/os-verify-lock.sh with OS_VERIFY_LOCK_SLOT=issue-10106; every verdict read from its printed VERDICT line, and every exit code captured after a redirect, never across a pipe. NOT MEASURED locally, declared to CI: the repo-wide pnpm lint / pnpm test / turbo type-check farm runs, which CI owns.",
"mcp_calls": "0 — no MCP GitHub tool was called, read or write. All GitHub access was curl against the REST proxy.",
"api_writes": "2 — POST /repos/objectstack-ai/objectui/pulls (draft PR #10149, the only PR-body write; no PATCH followed); POST /repos//issues/10106/comments (this report). NO label write: the dispatch forbade applying any label, and it is also the standing rule here — this repo's skip-changeset label is read by no workflow and exempts nothing, and it would be inapplicable anyway because a real changeset was added. The PR's labels (package: react, tests) were set by the repo's labeler, not by this seat, and were left alone. No ready flip, no auto-merge, no assignee write.",
"open_questions": [],
"out_of_scope_findings": [
"noted, not filed: useSettledSchema.test.ts's case 're-fetches when dataSource identity changes even if the key does not' carries a comment claiming 'Ready flips false the instant the source changes, same mechanism as a key change'. The code does not do that — ready is resolution.key === key and an adapter swap leaves the key alone, so ready stays true, which is precisely the mechanism this card rests on. The case's assertions are correct and still pass; only the sentence is wrong. Not filed: a false comment is not one of the three fileable classes (not a reproducible defect, not a breach of a declared contract, not an authoring trap), and the in-place-fix exemption fails its same-defect-class condition. Who will meet it: the next reader of this hook's tests — most likely whoever repairs or reviews an adapter-swap question here, since the sentence argues against this card's own finding. The correct statement is now written and pinned in the new file in the same directory.",
"noted, not filed: packages/react/README.md documents useSettledSchema with the same recipe and is NOT falsified by this change, so commandment #2 asks for nothing; the new producer guarantee travels to consumers through the changeset body instead. Left untouched because the claimed file surface is the hook and its tests, nothing else. Successor: none required — no sentence in it became false.",
"noted, not filed: the COUNT is pinned at the hook's boundary through the recipe its own @example publishes. A count pin on a real consumer (ObjectGantt) would be strictly closer to the card's wording, and the throwaway probe that produced the gantt reading showed it is cheap, but packages/plugin-gantt is outside this card's file surface. Successor: whoever lands PR #10100 (objectui#10036) is already in that file."
]
}
⭐ The 转述 claim REPRODUCES — and the control is what makes that a finding
This card was filed wholly second-hand and its first deliverable was the re-take, with 「it does not reproduce」 named as a complete outcome. It reproduces, and the measurement discriminates:
leg
adapters
find calls
subject
new adapter answers byte-identically as a FRESH object
2, carrying the SAME expand set [['owner'], ['owner']]
control A, same command
both adapters return the SAME def object
1
control B, same command
a genuinely different def
2, and the second call widens to ['owner','account']
⇒ 「two」 is a discrimination, ⛔ not a counting artefact: one control shows the count can be 1, the other shows a legitimate 2 looks different at the wire. ⭐ And it was taken on the real consumer (ObjectGantt, instrumented adapter, provider object), ⛔ not on a synthetic harness.
Repaired at the PRODUCER, which is the half of commandment #10 that names the right cure: useSettledSchema now keeps the object consumers already hold when a refetch's answer is value-equal. ⛔ Nothing moved into a consumer's dependency list and ⛔ no cache was added — the other half of the same sentence, avoided.
The ablation is the discriminating one: the settle bail-out replaced by the pre-repair unconditional republish ⇒ the same two assertions fail and the three controls stay green. Mutation proved by content AND hash, restore proved by blob-equals-HEAD plus empty git diff HEAD, ⛔ never by an exit code.
⭐ A COUNT pin ships with it — which is what the card asked for, so the next reader is told by a red test rather than by a card.
⛔ Why this is NOT being landed right now
Two independent reasons, and either alone is sufficient:
11 of 36 checks are still PENDING at this reading.⚠️ This seat armed auto-merge over exactly that state earlier today and an advisory check came back red and merged — see objectui#10148. ⭐ 「放行认门禁 job 的结论,⛔ 不认聚合读数」: eleven unreported checks are not conclusions.
Bundle Analysis is RED on main (objectui#10148). Every PR built on that base inherits the red, for bytes that are ⛔ not its own — the gate says so in its own words. ⇒ landing into it would add PRs that merged with a red advisory check, which is how a red gate stops being noticed.
⇒ the PR stays draft, alongside #10147 (objectui#10039), until objectui#10148's decision lands. ⛔ Neither is red on its own merits, and ⛔ neither is being reworked.
Three notes carried, ⛔ none filed, and the first one is sharp
⭐ useSettledSchema.test.ts's case 「re-fetches when dataSource identity changes even if the key does not」 carries a comment claiming 「Ready flips false the instant the source changes, same mechanism as a key change」. The code does not do that — ready is resolution.key === key, and an adapter swap leaves the key alone, so ready stays true. ⇒ ⚠️that sentence argues against this card's own finding, and it is false. ⛔ Correctly not filed (a false comment is none of the three classes, and the in-place carve-out fails its same-class condition) — and the correct statement is now written and pinned in the new file in the same directory, which is the better answer than a card nobody takes.
packages/react/README.md documents the same recipe and is ⛔ NOT falsified, so commandment #2 asks for nothing; the new producer guarantee travels through the changeset body instead.
The COUNT is pinned at the hook's boundary via the recipe its own @example publishes; a pin on the real consumer would be strictly closer to the card's wording, and the throwaway probe showed it is cheap — ⛔ but packages/plugin-gantt is outside this card's surface, and the successor is named (whoever is next in that file).
Two gates answered PRECONDITION NOT MET / population COLLAPSED on an unbuilt tree (readme-exports reported typesResolved 0 against a floor of 2) and are recorded as not-a-verdict, then re-run properly over a healthy population (3,384 export symbols from 36 of 40 packages). ⭐ The greens quoted are from the second runs.
Activity
os-tesla commentedon Sep 20, 2026
Claim: PM loop — 2026-09-20 shift, batch slot 2/2 (ceiling 2)⚠️ The dev re-declares from its actual diff and STOPS if the repair turns out to change an exported shape.
Session:
session_018HrVaotisyhgmot9o2MLRqBranch:
claude/issue-10106-settled-schema-equal-payloadWorktree:
objectui-issue-10106Domain:
domain:ui(triage's; ⛔ not re-routed here)Seat:
domain:ui#2File surface:
packages/react/src/hooks/useSettledSchema.tsand its tests. ⛔ Nothing else.Container & model: M,
mode:subagent,model: opus. ⛔ No tier output is quoted:scripts/pm/dispatch-gates.mjsREFUSES for this repo.Clause-②: no — a provider's republish identity. No exported symbol and no key on a published payload moves.
not plannedwith the reading. ⛔ A 转述 card that fails its own re-take is a closed card, ⛔ not a smaller one to force through.Hot-file serial queue: the only other card in flight is #10039 (
packages/app-shell/src/console/ai/**+views/studio-design/**), disjoint frompackages/react.Claimed at 2026-09-20T14:06Z.
Generated by Claude Code
os-tesla commentedon Sep 20, 2026
os-dev-report
{
"issue": 10106,
"status": "done",
"branch": "claude/issue-10106-settled-schema-equal-payload",
"pr": "#10149",
"session": "session_018HrVaotisyhgmot9o2MLRq",
"premise_still_valid": true,
"summary": "The second-hand claim REPRODUCES, re-measured first-hand before any edit. On the real consumer (ObjectGantt, instrumented adapter, provider
object), swapping the adapter when the new adapter answers byte-identically as a FRESH object cost 2findcalls carrying the SAME expand set [['owner'], ['owner']]; the control in the same command — both adapters returning the SAME def object — cost 1; a second control with a genuinely different def cost 2 with the second call widening to ['owner','account']. So 'two' is a discrimination, not a counting artefact. Repaired at the PRODUCER per AGENTS.md section 5 commandment #10: useSettledSchema now keeps the object consumers already hold when a refetch's answer is value-equal, via a module-private isEqualPayload and a settle() closure; nothing moved into a consumer's dependency list and no cache was added. After the repair the subject reads 1 and both controls are unchanged. A COUNT pin with its controls ships in packages/react/src/hooks/tests/useSettledSchema.equalPayload-10106.test.tsx. No exported symbol and no key on a published payload moves; Clause-② re-declared as 'no' from the actual diff.","tests": "RED-before: the pin run against the hook proved byte-identical to origin/main IN THE SAME COMMAND (git hash-object == HEAD blob == bb550f98d) -> 2 failed | 3 passed; the two subject assertions failed and all three controls passed. GREEN-after: same pin with the repair on disk (blob f287de8b6, printed in the same command) -> 5 passed. ABLATION from the committed state (settle bail-out replaced by the pre-repair unconditional republish): mutation proved by content AND hash, never by exit code — injected-marker count 1, removed-guard count 0, blob f287de8b6 -> ae320ff3b; pin went 2 failed | 3 passed (same two, controls green). Restore proved the same way: blob back to f287de8b6 and
git diff HEADempty; the script carried an absolute-path trap on EXIT/INT/TERM. SUITES at fe23217 with a clean tree printed in the same command: packages/react in full plus every useSettledSchema consumer pin (gantt fetch gate, calendar, kanban x2, gallery, timeline, tree, view) and the two doc-example reader gate suites -> 115 files / 1353 tests passed. TYPE-CHECK @object-ui/react:tsc --noEmitandtsc -p tsconfig.test.jsonboth clean; the test project SELECTS the new pin (--listFiles finds it). GATES re-run LAST at fe23217 with nothing unstaged, all exit 0: check:control-bytes, check:new-line-citations, check:doc-examples, check:doc-example-ids, check:doc-example-readers, check:doc-snippets, check:doc-types, check:readme-exports, check:test-path-roots, check:vi-mock-specifiers, check:unreferenced-sources, check:pending-changeset-literals, check-changeset-presence, check-changeset-fixed, check-changeset-no-major, eslint on both changed files (0 errors; 15anywarnings, the sibling test file carries 16 and the repo sets no --max-warnings, deliberately). NOT-A-VERDICT, recorded as such: check:doc-examples and check:readme-exports first answered PRECONDITION NOT MET / population COLLAPSED with no dist on disk (readme-exports reported typesResolved 0 against a floor of 2). Both were then re-run properly afterturbo run buildover the filter the gate itself prints; the greens above are from those runs, with a healthy population (readme-exports: 3384 export symbols from 36 of 40 packages, 58 keys compared). CHANGESET decided by running the gate, not from memory: check-changeset-presence exited 1 naming @object-ui/react; a patch changeset was added and it now exits 0. Every heavy run went through /home/user/objectstack/scripts/pm/os-verify-lock.sh with OS_VERIFY_LOCK_SLOT=issue-10106; every verdict read from its printed VERDICT line, and every exit code captured after a redirect, never across a pipe. NOT MEASURED locally, declared to CI: the repo-widepnpm lint/pnpm test/turbo type-checkfarm runs, which CI owns.","mcp_calls": "0 — no MCP GitHub tool was called, read or write. All GitHub access was curl against the REST proxy.",
"api_writes": "2 — POST /repos/objectstack-ai/objectui/pulls (draft PR #10149, the only PR-body write; no PATCH followed); POST /repos//issues/10106/comments (this report). NO label write: the dispatch forbade applying any label, and it is also the standing rule here — this repo's skip-changeset label is read by no workflow and exempts nothing, and it would be inapplicable anyway because a real changeset was added. The PR's labels (
package: react,tests) were set by the repo's labeler, not by this seat, and were left alone. No ready flip, no auto-merge, no assignee write.","open_questions": [],
"out_of_scope_findings": [
"noted, not filed: useSettledSchema.test.ts's case 're-fetches when dataSource identity changes even if the key does not' carries a comment claiming 'Ready flips false the instant the source changes, same mechanism as a key change'. The code does not do that —
readyisresolution.key === keyand an adapter swap leaves the key alone, soreadystays true, which is precisely the mechanism this card rests on. The case's assertions are correct and still pass; only the sentence is wrong. Not filed: a false comment is not one of the three fileable classes (not a reproducible defect, not a breach of a declared contract, not an authoring trap), and the in-place-fix exemption fails its same-defect-class condition. Who will meet it: the next reader of this hook's tests — most likely whoever repairs or reviews an adapter-swap question here, since the sentence argues against this card's own finding. The correct statement is now written and pinned in the new file in the same directory.","noted, not filed: packages/react/README.md documents useSettledSchema with the same recipe and is NOT falsified by this change, so commandment #2 asks for nothing; the new producer guarantee travels to consumers through the changeset body instead. Left untouched because the claimed file surface is the hook and its tests, nothing else. Successor: none required — no sentence in it became false.",
"noted, not filed: the COUNT is pinned at the hook's boundary through the recipe its own @example publishes. A count pin on a real consumer (ObjectGantt) would be strictly closer to the card's wording, and the throwaway probe that produced the gantt reading showed it is cheap, but packages/plugin-gantt is outside this card's file surface. Successor: whoever lands PR #10100 (objectui#10036) is already in that file."
]
}
Generated by Claude Code
os-tesla commentedon Sep 20, 2026
IMPLEMENTATION ACCEPTED · LANDING HELD. PR #10149 (head
fe23217e9, 3 files, +309 −3), reviewed 2026-09-20T14:36Z. NOT governed (0 of 3 paths).⭐ The 转述 claim REPRODUCES — and the control is what makes that a finding
This card was filed wholly second-hand and its first deliverable was the re-take, with 「it does not reproduce」 named as a complete outcome. It reproduces, and the measurement discriminates:
findcalls[['owner'], ['owner']]['owner','account']⇒ 「two」 is a discrimination, ⛔ not a counting artefact: one control shows the count can be 1, the other shows a legitimate 2 looks different at the wire. ⭐ And it was taken on the real consumer (
ObjectGantt, instrumented adapter, providerobject), ⛔ not on a synthetic harness.Repaired at the PRODUCER, which is the half of commandment #10 that names the right cure:
useSettledSchemanow keeps the object consumers already hold when a refetch's answer is value-equal. ⛔ Nothing moved into a consumer's dependency list and ⛔ no cache was added — the other half of the same sentence, avoided.The ablation is the discriminating one: the settle bail-out replaced by the pre-repair unconditional republish ⇒ the same two assertions fail and the three controls stay green. Mutation proved by content AND hash, restore proved by blob-equals-HEAD plus empty
git diff HEAD, ⛔ never by an exit code.⭐ A COUNT pin ships with it — which is what the card asked for, so the next reader is told by a red test rather than by a card.
⛔ Why this is NOT being landed right now
Two independent reasons, and either alone is sufficient:
Bundle Analysisis RED onmain(objectui#10148). Every PR built on that base inherits the red, for bytes that are ⛔ not its own — the gate says so in its own words. ⇒ landing into it would add PRs that merged with a red advisory check, which is how a red gate stops being noticed.⇒ the PR stays draft, alongside #10147 (objectui#10039), until objectui#10148's decision lands. ⛔ Neither is red on its own merits, and ⛔ neither is being reworked.
Three notes carried, ⛔ none filed, and the first one is sharp
⭐⚠️ that sentence argues against this card's own finding, and it is false. ⛔ Correctly not filed (a false comment is none of the three classes, and the in-place carve-out fails its same-class condition) — and the correct statement is now written and pinned in the new file in the same directory, which is the better answer than a card nobody takes.
useSettledSchema.test.ts's case 「re-fetches when dataSource identity changes even if the key does not」 carries a comment claiming 「Ready flips false the instant the source changes, same mechanism as a key change」. The code does not do that —readyisresolution.key === key, and an adapter swap leaves the key alone, soreadystays true. ⇒packages/react/README.mddocuments the same recipe and is ⛔ NOT falsified, so commandment #2 asks for nothing; the new producer guarantee travels through the changeset body instead.The COUNT is pinned at the hook's boundary via the recipe its own
@examplepublishes; a pin on the real consumer would be strictly closer to the card's wording, and the throwaway probe showed it is cheap — ⛔ butpackages/plugin-ganttis outside this card's surface, and the successor is named (whoever is next in that file).Two gates answered
PRECONDITION NOT MET/population COLLAPSEDon an unbuilt tree (readme-exportsreportedtypesResolved 0against a floor of 2) and are recorded as not-a-verdict, then re-run properly over a healthy population (3,384 export symbols from 36 of 40 packages). ⭐ The greens quoted are from the second runs.Generated by Claude Code
fix(react): republish an equal object definition as the same object (…