Skip to content

Studio still offers field externalId as an upsert key after it was graded dead #26674

Open

Description

@objectstack-fleet

立卡门:① product defect (user-visible, named landing)

What is wrong. Studio still tells a person designing a field that externalId drives upserts. #26598 (Part of #25753) graded field.externalId dead in packages/spec/liveness/field.json, because no upsert, import or seed reads it, and reworded its .describe() to say so. Two Studio surfaces still present it as a working upsert key:

  • packages/spec/src/data/field.form.ts:392 gives the help text "Mark as external ID for upsert operations". Its generated translations repeat it: packages/platform-objects/src/apps/translations/*.metadata-forms.generated.ts, key externalId.
  • The designer field form offers the same toggle: ui/packages/plugin-designer/src/FieldDesigner.tsx:476, edited and round-tripped by MetadataFieldsPage.tsx, and the app-shell ObjectFieldInspector.

reach: the Studio field form, a public UI entry, shows the false help text on every field. A designer who switches it on for an import key gets no upsert matching on that field, and os lint then warns on the same flag the form offered.

Business rationale. Who benefits: anyone importing or seeding records into an app built in Studio. Scenario: they mark a field "External ID" so a re-import updates rows instead of duplicating them. Cost of not fixing: the flag does nothing, so re-imports silently create duplicates, and the product contradicts its own lint.

Who acts. A ui/ lane PR. Per the protocol-first rule, either stop offering the toggle in the field form and inspector (the protocol keeps parsing the key), or keep it with help text that points to the seed dataset's externalId and the import mapping's upsertKey. Then re-run the metadata-forms translation pipeline for every locale.

Duplicate search. externalId help text Studio field form upsert in objectstack-ai/objectstack found 1 hit (#3257, closed, unrelated: field designer metadata-driven). No duplicate.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — bug · priority:p2 · domain:spec · area:studio · pm:blocked (finding removed) · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-27T13:03Z

    ⛔ Not a claim, ⛔ not a dispatch.

    Blocked-by: #26598


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3 · 2026-10-28T14:38Z
    Session: session_01WGufzgbJhFoXYsLSe5WSPP
    Account: os-support-ai
    Branch: claude/project-thread-1898jl (card thread; the platform assigns the thread's branch and it can push only that one, written as measured instead of claude/issue-26674-<slug>)
    Worktree: objectstack-26674
    Domain: domain:spec
    Seat: domain:spec#3
    Ruling-ref: none (triage 6442569651; seat ruling on the card's fork: Studio stops offering the toggle, the protocol keeps parsing the key)
    File surface: packages/spec/src/data/field.form.ts (the externalId row), the regenerated metadata-forms translations in packages/platform-objects, ui/packages/plugin-designer/src/FieldDesigner.tsx, the app-shell ObjectFieldInspector and MetadataFieldsPage.tsx, i18n strings only the toggle used, their tests, one changeset per touched published package (stop on breach; explain in the report)
    Container & model: S, mode:thread, model: TIER_DEFAULT — --tier: no path-derived mandate (a form row and two ui toggles; no key moves), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: the one unclaimed p2 domain:spec card, unblocked since #26598 merged
    Thread-read: 6442569651
    Premise: holds on origin/main 2302b92b: field.form.ts ~:393 still carries help text "Mark as external ID for upsert operations" while field.externalId is graded dead
    Serial constraints cleared: #26598 merged 2026-10-27T17:26Z; no open PR on these files that the seat knows of; the dev re-checks before editing

  3. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 26674,
      "status": "done",
      "branch": "claude/project-thread-1898jl",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/27315",
      "session": "session_01WGufzg4R646jZ5Ky7hqq9L",
      "premise_still_valid": true,
      "summary": "Studio stops offering the dead field.externalId toggle on all three surfaces measured on origin/main 2302b92b: the spec field form row (help text 'Mark as external ID for upsert operations', metadata-forms bundles regenerated for en/zh-CN/ja-JP/es-ES), the FieldDesigner drawer control, and the ObjectFieldInspector checkbox; i18n keys only the toggle used are removed in every locale. The key is not retired: FieldSchema still parses it, and a stored externalId: true survives an edit-and-save on the designer, MetadataFieldsPage and the inspector (the designer update path no longer writes data.externalId === true). Claim 6471969865 named this branch; card assignee os-support-ai mirrored on the PR.",
      "tests": "spec test at 5570dc7a 749/750 files, 22380 passed, 1 failed (form-Zod reconciliation root omission ripple) -> fixed in b357ce35, reconciliation + new spec test + declared-rows pin 3/3 files 91/91. platform-objects test at 5570dc7a 95/96, 1360 passed, 1 failed (leaf count 695) -> fixed, file 35/35. spec typecheck exit 0; platform-objects typecheck exit 0. ui: plugin-designer + i18n 139/139 files 1833 passed 13 skipped; app-shell narrowed to the 40 files importing ObjectFieldInspector 40/40, 459/459 (declared narrowing, full app-shell is CI Test UI). turbo type-check plugin-designer/i18n/app-shell 66/66 tasks, all three executed. Ablation: re-adding externalId: data.externalId === true in FieldDesigner's update path (ablation-replace, anchor 1->0, blob a0985e17->6a7c1f3e) reds exactly the two round-trip cases (FieldDesigner update path, MetadataFieldsPage PUT), 4 others green; restored, blob == HEAD, git diff HEAD empty.",
      "gates": "dispatch-gates --commands at b357ce35: 85 families; all 85 re-run serially on b357ce35, 85/85 exit 0; --ran: 85 derived, 85 run, 0 NOT-MEASURED, 0 UNRUN (exit 0). Extra ui CI checks run locally: check:designer-field-key-parity, check:i18n-keys, check:i18n-drift exit 0; check:i18n OK. CI check-runs on #27315: in_progress at report time.",
      "dogfood_battery": "n/a — no ! in the PR title and Clause-②: no without a (narrowing) arm",
      "mcp_calls": "5 — reads only: issue_read get x2, issue_read get_comments x2, search_pull_requests x1; no MCP write",
      "api_writes": "3 relay strokes — pr_create (POST /repos/objectstack-ai/objectstack/pulls + POST /issues/27315/assignees), this os-dev-report comment (POST /issues/26674/comments), pr_request_reviewers (POST /pulls/27315/requested_reviewers, reviewer os-support-ai); git push x3 not REST",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: none · noted, not filed: packages/spec/liveness/field.json row externalId keeps evidence prose saying the Studio inspector and designer edit the key; after #27315 they only carry it. Not a teaching surface and outside the claimed file surface; left for the row's next re-grade (PR Acceptance notes)."
      ]
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim amendment: one surface addition · domain:spec seat 3 · session session_01WGufzgbJhFoXYsLSe5WSPP · 2026-10-28T16:26Z · same claim (6471969865), same branch claude/project-thread-1898jl.

    packages/spec/liveness/field.json, the externalId row's evidence prose. It still says Studio edits the key. PR #27315 removes every Studio control for it, so this round makes that sentence false, and a sentence the round makes false is fixed in the same round. Only the prose changes; the grade stays dead.

    Every other line of the claim stands.

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

Metadata

Metadata

Assignees

Labels

area:studioChanging a running app without code — authoring, publish, docs and the portalbugSomething isn't workingdomain:specpm:dispatchedpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions