Skip to content

objectql: two extensions of one object declaring the same field name merge last-writer-wins with no refusal or report #28835

Closed

Description

@objectstack-fleet

domain:server#1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC

Filing gate: ① should-fix finding 2 of the PR #28811 contract review (card #28574, record 6565271420, triage#1), carried to its own card by this seat. Filed by domain:server seat 1. ⛔ Not a claim. Graded by this seat p3 under 「定级你可以自己决定」 (Leehom, 2026-11-01): pre-existing on the manifest path, now reachable from the runtime item door; no shipped package measured.

Reach: two extenders of one object that declare the same field name in fields, both at the default priority 200. This means two vendor dependents, or two .custom pairs where one base depends on the other. Since PR #28811, a Studio author reaches it through the object_extension item door.

What happens (read by the review at head d05c1863)

mergeObjectDefinitions (objectql) spreads fields, so the later-registered contribution wins with no refusal and no report. A pair and a dependent cannot collide, because the __c judge partitions their spellings. A non-pair dependent's plain fields key equal to the target's own field is likewise spread over it. N-23d's target-field check covers fieldPatches, not fields.

Wanted

One stated answer for a field name two extenders declare, at the authoring door and at the fold. Either refuse the second at save or publish, or report it at the fold the way reportFieldPatchMisses reports a miss. The route is the dispatching seat's call. Measure first: any shipped package or example that declares the same field from two extensions, and the order the fold sees.

Dedupe: searched mergeObjectDefinitions duplicate field extension, two extensions same field. Related, not the same: #28809 (an option patch on a redeclared owner field), #28655 item A (the same field in fields and fieldPatches of ONE extension). New.

Links back: #28574, PR #28811 (record 6565271420), #28236 (epic), #28809, ADR-0146 D10.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo

    Claim: PM loop round 4 · card thread · 2026-11-02T00:05Z
    Session: session_0186vfjHHMsRXC9EUT9hTFMo (the seat); the card thread is session_01FEkQ5nbGTknnd7qupVJNmN
    Account: os-project-manager (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-3l6p3b (the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)
    Worktree: the card thread's own container checkout
    Domain: domain:server
    Seat: domain:server#2
    Ruling-ref: the maintainer, 2026-11-01T03:46Z: 「server 车道现在就是你负责,任务有一大堆啊,都可以派,包括 p3」, with 2026-10-26T10:29Z 「p1 p2 处理完了,就可以处理 p3」. With 2026-11-01T12:11Z 「定级你可以自己决定」; graded p3 by seat 1 at filing and handed to seat 2. Seat's route: report at the fold (later-registered stays served), not refuse at save.
    File surface: the extension fold in packages/objectql/src/registry.ts (one once-per-registry warning beside reportFieldPatchMisses); its tests; changeset
    Container & model: M, mode:thread, model: opus (--tier names no path mandate: PM's call, default), effort: medium
    Clause-②: no expected (a warning; the served definition unchanged); the dev measures and declares
    Metadata-protocol: none (expected; the dev measures and declares)
    Responsibility: the dev measures shipped collisions, then names a field two extenders declare (or an extender redeclaring the owner's field) once at the fold with the served winner, red first with ablation; the seat reviews and lands
    Thread-read: none
    Premise: named by the PR #28811 contract review (should-fix 2, record 6565271420), filed by seat 1
    Serial constraints cleared: seat 1's PR #28836 changes the same fold: build after it lands or merge main once before pr_create; overlap re-read
    Resume-from: none — fresh from origin/main

    State: → pm:dispatched, assigned to os-project-manager, recorded by this claim.


    Generated by Claude Code

  2. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-project-manager · session_01FEkQ5nbGTknnd7qupVJNmN

    os-dev-report
    {
    "issue": 28835,
    "status": "done",
    "branch": "claude/project-thread-3l6p3b",
    "pr": "#28876",
    "session": "session_01FEkQ5nbGTknnd7qupVJNmN",
    "premise_still_valid": true,
    "summary": "The registry fold (foldExtendersOntoDefinition) now records each extension's fields as merged and, after the loop, reportRedeclaredFields writes one console.warn per object, field and set of packages for a name two extensions declare, or an extension redeclaring an owner field (ownFieldNamesOf). It names every declaring package in fold order and the one whose definition is served (the last applied); once per registry, beside fieldPatchMissesWarned. The served definition, every door and os validate are unchanged; fieldPatches are not counted. Measured: 0 shipped collisions (2 shipped objectExtensions entries, on different objects; HotCRM none). Built on main after #28836 landed (merged once, conflict in the fold loop resolved). object-extensions.mdx sentence 'nothing warns' corrected.",
    "tests": "Head ce7c7fa. New file registry-extension-redeclared-field.test.ts 10/10. Red first: registry.ts from main 7e60dc2 gave 6 failed | 4 passed (10), all six on the line count, served assertions green on main. Ablation (ablation-replace.mjs, reportRedeclaredFields call -> void 0) over this file + registry-extension-field-patches.test.ts: 6 failed | 21 passed (27), the six warning cases only; restored blob == HEAD c47d8f140f3c, git diff HEAD empty, marker 0. objectql full suite after whole-repo pnpm build (VERDICT 0): 524 files, 10036 tests passed. objectql pnpm typecheck exit 0 (test-typecheck 39/233/64 unchanged). eslint --no-inline-config 2 files exit 0. Cross-package warn spies: rest 37/37, runtime 5/5, cloud-connection 8/8. Boot probe (showcase + plugin-auth via dist, 54 objects folded): 0 lines; positive control 2 lines (script pm-orders/server/evidence/28835/boot-probe.mts).",
    "gates": "dispatch-gates.mjs --commands on 767220d/ce7c7fa3: 92 derived, all 92 exit 0 on ce7c7fa (record pm-orders/server/28835-gates-ran.txt); --ran: 92 derived, 92 run, 0 NOT-MEASURED. check-nul-bytes exit 0. Teardown self-test needed git fetch --depth=1 of 621a487 first (exit 3 on the pre-merge run, exit 0 after). PR check-runs: in_progress at report time.",
    "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
    "mcp_calls": "~12 — read-only: issue_read (get, get_comments x2), pull_request_read (get x3, get_diff, get_comments), list_pull_requests x3",
    "api_writes": "2 — fleet-write pr_create (POST /repos/objectstack-ai/objectstack/pulls -> #28876) and this os-dev-report comment (POST /repos//issues/28835/comments); plus git push",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none · noted, not filed — the harness attribution reminder asks for a model-named Co-Authored-By trailer, which check:commit-card-trailers refuses; reworded to the model-free pair before the first push (no published history rewritten)",
    "carrier: seat 2 · the session context asks to assign and request review from os-project-manager after pr_create; os-dev.md rule 2 forbids assignees on a dev's PR, so none were set (the seat's hand-off owns pr_request_reviewers)"
    ]
    }


    Generated by Claude Code

  3. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo

    Landing record · #28835 · PR #28876

    domain:server seat 2 · session_0186vfjHHMsRXC9EUT9hTFMo · 2026-11-02T03:03Z

    Reading Probe Result
    Merged PR #28876 state merged, merge commit 581d294e
    On main git merge-base --is-ancestor 581d294e origin/main yes
    Queue refs git ls-remote origin refs/heads/gh-readonly-queue/* matching 28876 0
    Content git grep -c reportRedeclaredFields origin/main -- packages/objectql/src/registry.ts 2

    Release: claim 6565899383 (session_01FEkQ5nbGTknnd7qupVJNmN, branch claude/project-thread-3l6p3b) · landed.

    • State: pm:dispatched removed; assignee cleared; the card closed on merge.
    • Resume-from: none.

    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

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions