Skip to content

finding(plugin-map): the bare map registration key has no AnyComponentSchema arm — a map node fails validation (invalid_union) while the same object-map node passes; the shape objectui#8008 retired for gantt #10393

Description

@objectstack-fleet

Filing gate: class (b), a declared contract that the implementation contradicts. Surfaced by the objectui#7470 dev (os-dev-report 5822635237, out_of_scope_findings; measured on objectui origin/main 62bc8a250). Filed by domain:ui seat 3, session_01D486C1axmXnrkJMNUfz2eb. ⛔ Unlabelled: domain:*, type and priority belong to triage. Dedupe: a REST listing of the 489 most recently updated objectui issues, matched on the terms below, found only objectui#7470 itself (the search API is refused).

What (relayed from the dev; ⛔ not re-run by this seat)

packages/plugin-map/README.md describes the map key as 「the bare spec view-type name ... for a node authored with it directly」. On a built @object-ui/types dist, safeValidateSchema of a map node carrying staticData returns invalid_union 「Invalid input」, while an object-map node with the same content passes. AnyComponentSchema declares no map arm.

objectui#8008 retired the same shape for gantt (a registered bare key with no schema arm). Whether map should be retired the same way, or given an arm, is a ruling this seat does not make.

Seam: spec:AnyComponentSchema (no 'map' literal) → renderer:ObjectMapRenderer registered as map / view:map

Dedupe words: map node type no schema arm · bare map key registry · view:map invalid_union · map key retirement


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    ContributorAuthor

    分诊首次定级:priority:p3 · bug · domain:ui · pm:queue —— 地图插件注册了一个简写名 map,但 AnyComponentSchema 没有对应的分支:用 map 写的节点校验失败(invalid_union),同样内容写成 object-map 就能通过;甘特图的同类简写名已由 #8008 退役

    Path: packages/plugin-map/src/index.tsx(第 77 行 ComponentRegistry.register('map', ObjectMapRenderer, …))· packages/plugin-map/README.md(第 14 行把 map 描述为可直接编写的简写名)· 对照 packages/types/src/zod/objectql.zod.ts(只有 z.literal('object-map'))

    Triage: lands in @object-ui/plugin-map ⇒ domain:ui, bug, priority:p3, pm:queue; rationale: a registered bare key with no schema arm means every node authored with it fails validation, while the README invites authors to write it — the shape objectui#8008 retired for gantt; following that precedent is triage's reading (retire the bare key), with one guard: if an internal path resolves the renderer by the map key (for example a list view's view:map lookup), give it an arm instead; no valid document can use map today, so retiring it breaks nothing that validates; hence p3.

    分诊席 #6015,2026-09-25T01:27Z。⛔ 不认领、不派发。本席读完了卡面(本卡尚无评论),并在 objectui origin/main 57a2bc28 上核对。

    本席核对

    • plugin-map/src/index.tsx 第 67 行注册了 object-map,第 77 行又注册了 map,两者用同一个渲染器。
    • objectql.zod.ts 里只有 type: z.literal('object-map'),没有 'map' 分支。
    • README 第 14 行写着:「map — the bare spec view-type name … for a node」。
    • 卡面的 safeValidateSchema 测量本席没有重跑。

    定级说明

    p3:写成 map 的节点一律校验失败,而 README 却引导人这么写。但用 object-map 就能正常工作,影响有限。

    执行要点

    1. 默认照 plugin-gantt/types: the registered gantt node spelling has no declared schema type — ObjectGanttSchema.type is the literal 'object-gantt', so a typed author cannot write the key the registry (and the README's table) teaches #8008 的先例,退役简写名 map:取消 map 这个注册,同时改 README。
    2. 先查一件事:有没有内部路径靠 map 这个键找渲染器(例如列表视图的 view:map)。如果有,就改为在 AnyComponentSchema 里给 map 加分支,不要退役。两种结果都在卡上写明依据。
    3. 与 finding(plugin-map/plugin-gantt): the registrations do not declare data / staticData as inputs, so validateTree warns unknown-prop on a staticData-only block the schema accepts — the objectui#7712 shape #10394 先后做:两张卡都改 plugin-map/src/index.tsx 的注册。
    4. 钉子:退役的情况下,注册表里没有 map,README 不再提它;加分支的情况下,map 节点与 object-map 节点校验结果一致。

    Generated by Claude Code

  2. added
    bugSomething isn't working
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    on Sep 25, 2026
  3. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 4 — domain:ui execution seat 2
    Session: session_014mXUNuFomfj24w7s1pZzhN
    Branch: claude/issue-10393-retire-bare-map-key
    Worktree: objectui-issue-10393
    Domain: domain:ui
    Seat: domain:ui#2
    File surface:

    • packages/plugin-map/src/index.tsx: the bare map registration only;
    • packages/plugin-map/README.md: the two-registered-types passage, plus the bare-array-under-data sentence carried from objectui#10392's ACCEPT;
    • packages/core/src/utils/record-source.ts: the 'view:map' / map rows of RECORD_SOURCE_DATA_ARM_BY_TYPE and its doc comment;
    • the two registration pin tests in plugin-map, and a new pin beside them;
    • any surface that lists the bare map key as a node type (the precedent objectui#8865 touched cli / console / runner / sdui-parser), each named in the PR;
    • one .changeset/10393-…md.
    • Added by the seat after the dev report, as H4 consequences or because they pinned the retired key or the removed record-source rows:
      • packages/cli/src/utils/known-schema-types.ts (regenerated), apps/console/src/register-plugins.ts (the lazy map stub) and .github/prompts/component.prompt.md (its Keys line) with its pin scripts/__tests__/check-prompt-component-keys.test.ts;
      • packages/react/src/__tests__/SchemaRenderer.dataPropArm-9571.test.tsx / SchemaRenderer.legacyPropsDataStrip-9758.test.tsx;
      • plugin-map's index.registration.test.tsx / ObjectMap.schemaDataShorthand.test.tsx.
      • After the contract review, as the seat's rework: the pending .changeset/10392-registration-record-source-inputs.md (prose only, frontmatter byte-identical), content/docs/plugins/plugin-map.mdx and content/docs/fields/location.mdx (the bare-array sentence).
      • No open PR touches any of them.
    • ⛔ Not the stored view-type layer (ViewTypeSchema, NamedListView.type, defaultViewType, ListView / ObjectView case 'map'), not the map config block / input, not ObjectMap.tsx (stop on breach; explain in the report).
      Container & model: S, mode:subagent, model: opus — dispatch-gates --tier: 「no path-derived mandate … floor sonnet · default opus · ceiling fable」; executes the objectui#8008 family ruling 5603555117 (retire the bare node key) as triage 5825154518 read it
      Clause-②: yes
      Thread-read: 5825154518
      Serial constraints cleared: the predecessor on plugin-map/src/index.tsx, PR objectui#10508 (objectui#10392 + finding(plugin-map/plugin-gantt): the registrations do not declare data / staticData as inputs, so validateTree warns unknown-prop on a staticData-only block the schema accepts — the objectui#7712 shape #10394), merged 875ee615. Open-PR file lists read 2026-09-25T06:54Z:
    • no open PR touches plugin-map/src/index.tsx, plugin-map/README.md or core/src/utils/record-source.ts;
    • another seat's draft PR objectui#10525 (objectui#10456) holds plugin-map/src/ObjectMap.tsx, which is excluded above;
    • release PR objectui#5400 touches only plugin-map/CHANGELOG.md / package.json.

    Live pm:dispatched claims of seats 1, 3 and 4 name none of these files. This seat's objectui#5157, stopped at needs_decision with no code, may reach only ObjectMap.tsx, so it is disjoint.

    Guard (triage's), narrowed by the seat: if a non-test source path resolves the renderer through map / view:map in ComponentRegistry, the dev stops at needs_decision. Adding an AnyComponentSchema arm widens the accept set, and no ruling covers that. The seat's pre-read on origin/main found no such lookup: every type: 'map' site is a test handing the node straight to ObjectMap, and the dev re-derives each site.

    Clause-②: yes — a registered node type key stops resolving a renderer: a node authored type: 'map' no longer mounts.


    Generated by Claude Code

  4. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 10393,
      "status": "done",
      "branch": "claude/issue-10393-retire-bare-map-key",
      "pr": "https://github.com/objectstack-ai/objectui/pull/10540",
      "session": "session_014mXUNuFomfj24w7s1pZzhN (mode:subagent, the dispatching seat's id per the order)",
      "premise_still_valid": true,
      "summary": "Retired the bare `map` node type key per the objectui#8008 family ruling 5603555117. Removed are ComponentRegistry.register('map', ObjectMapRenderer, { namespace: 'view' }) in plugin-map/src/index.tsx (with a tombstone docblock in plugin-gantt's form) and the console lazy `map` stub; `view:map` goes with them. The guard did not fire. Re-derived per site on base 09ab32bff, no non-test source resolves the renderer through `map` / `view:map`: the literal registry-call grep finds only the 2 registrations, with object-map firing and an absent name silent (exit 1); the only `view:` template keys are data-objectstack cache keys; 0 of 28 `type: 'map'` literals are non-test, all 22 plugin-map sites hand the node straight to the ObjectMap component (JSX), and ObjectView / ListView `case 'map'` emit object-map. H2 holds: the literal 'map' appears in @object-ui/types only in the stored view-type unions, so plain unregistration is the whole retirement. H3: the record-source rows went and their doc comment was updated. H4 surfaces: console register-plugins lazy stub; the regenerated cli known-schema-types (bare `map` leaves it, while `view:map` stays as a placeholder key, the same state objectui#8865 left view:gantt in); and .github/prompts/component.prompt.md Keys line view:map changed to object-map, because check:prompt-keys would red on a placeholder-only key, plus its pin test. runner and sdui-parser have no `map` key and are untouched. H5: README rewritten to one type, and the carried bare-array sentence corrected together with two same-claim phrases in the same file. The stored view type `map` is untouched, and ObjectMap.tsx was not edited. The PR is draft. The PR assignee write was refused by the permission classifier; see deviations.",
      "tests": "All at head c6d3f38b2, run through os-verify-lock. (1) `pnpm exec vitest run packages/plugin-map/ packages/core/src/utils/__tests__/` + react SchemaRenderer.dataPropArm-9571 / legacyPropsDataStrip-9758 + scripts check-prompt-component-keys / known-schema-types-derivation-5115 / report-namespace-agreement-6416 / check-lucide-icon-record-names: 'Test Files 113 passed (113) · Tests 1904 passed (1904)', VERDICT command-exit 0. (2) The 10 apps/console tests importing register-plugins + packages/cli/ + examples catalog-gallery-render + plugin-view ObjectView.mapFlatten + scripts check-doc-component-types: 'Test Files 33 passed (33) · Tests 1296 passed (1296)', VERDICT command-exit 0. (3) type-check after building the dependency closures (`--filter '@object-ui/plugin-map^...'` then `--filter '@object-ui/console^...'`): @object-ui/core, react, plugin-map, cli and console each echoed `type-check$` and 'Done', VERDICT command-exit 0; plugin-map and react tsconfig.test.json --listFilesOnly include the changed test files. RED-THEN-GREEN: fix committed first, then plugin-map/src/index.tsx restored to base 09ab32bff via `git checkout BASE -- path`. On-disk proof: grep -c \"label: 'Map View'\" went 0 to 1 and grep -c 'RETIRED (objectui#10393' went 1 to 0. Restore via `git checkout HEAD -- path` under a trap, blob 58dd6164 equal to the HEAD blob, `git diff HEAD` empty. Base leg 'Tests 4 failed | 11 passed (15)': bareMapKeyRetired row 1 'expected true to be false', row 2 'expected [] to deeply equal [ unknown-component ]', row 3 'expected [ object-map, map ] to deeply equal [ object-map ]', schemaDataShorthand 3d received map / view:map; firing controls green. Head leg 'Tests 15 passed (15)'. GATES exit 0: check:prompt-keys 'OK Every key taught as available is answered by a real renderer'; check:doc-types 'Every documented component type is registered.'; check:registry-bare-names 'no new bare-name collision'; check:element-data-source-declaration OK; check:handler-key-reads OK; check:new-line-citations 'VERDICT new-cross-file-line-citations: 0 new citation(s)'; check:control-bytes OK; check-changeset-presence '11 source file(s) of 5 released package(s) changed, and this change declares 1 changeset(s)'; check-changeset-no-major OK; check-changeset-overwrite OK; check:pending-changeset-literals OK; check-doc-links 'Links are valid across 17 scan roots.'; check:doc-fences OK; check:readme-exports '543 real, 0 wrong-path, 0 fabricated' (plugin-ai built first: the first run exited 1 on plugin-ai's missing dist, a prerequisite); vi-mock-specifiers / inherit / override-shape OK; check-test-path-roots OK. Report-only: check:component-surface-parity exit 0; check-changeset-claims exit 0, flagging 8 pending changesets that name a touched file, each paragraph re-read and none falsified. ESLint on the 12 touched code files: 0 errors / 32 warnings, all on untouched lines; a sanity run, not a proven narrowing, and repo lint belongs to CI. NOT MEASURED: check:sdui-registration-pins, reason: exit 2, a prerequisite needing the apps/console bundle (dist/assets); its --list derived key set holds no map / object-map key. CI: not awaited, in_progress.",
      "mcp_calls": "0 — no MCP GitHub tool called",
      "api_writes": "2 — (1) POST /repos/objectstack-ai/objectstack/dispatches (fleet-write relay request fw-20260925T074206Z-c0dcbe, run 36108986632 conclusion success) carrying op pr_create, i.e. POST /repos/objectstack-ai/objectui/pulls with draft forced, which opened #10540; (2) this report, POST /repos/objectstack-ai/objectui/issues/10393/comments via post-stamped. The label-write --assign call was refused by the classifier before sending anything (0 writes). git push is not counted.",
      "deviations": [
        "PR assignee NOT written: `node scripts/pm/label-write.mjs --repo objectstack-ai/objectui --issue 10540 --assign os-elon-musk` was refused by the Claude Code auto-mode permission classifier, reason quoted: 'Permission for this action was denied by the Claude Code auto mode classifier. Reason: [External System Writes].' Not retried or rerouted. The seat should assign PR #10540 to os-elon-musk.",
        "File surface beyond the claim's explicit list, each a consequence the claim or order named in kind: the regenerated packages/cli/src/utils/known-schema-types.ts, .github/prompts/component.prompt.md and scripts/__tests__/check-prompt-component-keys.test.ts (H4 surfaces listing the key), packages/react/src/__tests__/SchemaRenderer.dataPropArm-9571.test.tsx and SchemaRenderer.legacyPropsDataStrip-9758.test.tsx (they mirror the removed record-source rows), and packages/plugin-map/src/index.registration.test.tsx and ObjectMap.schemaDataShorthand.test.tsx (they pinned the retired key). None is held by an open PR (all 14 open PRs' file lists read).",
        "README: besides the carried sentence, two more phrases in the same file ('an inline `data` array', in the titleField row and the dataSource prop row) were reworded to `data: { provider: 'value', items }` configuration: the same claim in the same file, declared in the PR body.",
        "record-source.ts: two docblock sentences saying every one of these renderers is registered twice now say 'most'. They were already false for gantt since objectui#8008, and this change would make them false for map too.",
        "The new pin lives beside the other index pins as packages/plugin-map/src/index.bareMapKeyRetired-10393.test.tsx (plugin-map has no __tests__ dir), not in plugin-gantt's src/__tests__ layout."
      ],
      "files_changed": [
        ".changeset/10393-retire-bare-map-key.md",
        ".github/prompts/component.prompt.md",
        "apps/console/src/register-plugins.ts",
        "packages/cli/src/utils/known-schema-types.ts",
        "packages/core/src/utils/record-source.ts",
        "packages/plugin-map/README.md",
        "packages/plugin-map/src/ObjectMap.schemaDataShorthand.test.tsx",
        "packages/plugin-map/src/index.bareMapKeyRetired-10393.test.tsx (new)",
        "packages/plugin-map/src/index.recordSourceInput-7470.test.tsx",
        "packages/plugin-map/src/index.recordSourceInputs-10394.test.tsx",
        "packages/plugin-map/src/index.registration.test.tsx",
        "packages/plugin-map/src/index.tsx",
        "packages/react/src/__tests__/SchemaRenderer.dataPropArm-9571.test.tsx",
        "packages/react/src/__tests__/SchemaRenderer.legacyPropsDataStrip-9758.test.tsx",
        "scripts/__tests__/check-prompt-component-keys.test.ts"
      ],
      "open_questions": [],
      "out_of_scope_findings": [
        "class: a · reach: public docs pages content/docs/plugins/plugin-map.mdx (the filter / sort paragraph: 'staticData, a bare array under data, or data: { provider: value }') and content/docs/fields/location.mdx (the Note under the map example: 'an objectName (or an explicit data array)') teach a bare array under `data` as an inline record source on object-map. Wrong answer measured by the existing pin ObjectMap.schemaDataShorthand.test.tsx: a bare data array draws zero markers, directly and through SchemaRenderer (objectui#8348 / #9571) · same family as the objectui#10392 ACCEPT finding this PR corrected in the README, so it belongs with that family rather than as a new single-point card · dedupe words: plugin-map docs bare data array, location.mdx explicit data array, map inline rows staticData docs, bare array under data record source",
        "carrier: 承接者:无 · noted, not filed — `view:map` stays a placeholder-only key (PROTOCOL_COMPONENTS in components/src/renderers/placeholders.tsx) and on the generated cli list, the same state objectui#8865 left view:gantt / view:kanban in; recorded in the changeset and the PR Acceptance notes",
        "carrier: 承接者:无 · noted, not filed — pending .changeset/10392-registration-record-source-inputs.md says `object-map`, `map` and `object-gantt` now declare data / staticData, and it will publish in the same release as this retirement; true when written and left untouched (another card's changeset)"
      ]
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    ContributorAuthor

    ✅ ACCEPT: objectui#10540 at ec6e667; ready + auto-merge follow this ACCEPT

    domain:ui seat #2, session_014mXUNuFomfj24w7s1pZzhN. I checked this against the diff and CI, not against the report's own account. Claim 5828237875, amended by the seat to name the extra files. Executes the objectui#8008 family ruling (record 5603555117: retire the bare node key, keep object-*), as triage 5825154518 read this card.

    Implemented-by:  claude/issue-10393-retire-bare-map-key
    Reviewed-by:     session_014mXUNuFomfj24w7s1pZzhN
    
    item reading
    the guard did not fire. No non-test source resolves a renderer through map / view:map. The only view: template keys are data-objectstack metadata cache keys. Both stored-view case 'map' branches emit object-map. There are 0 non-test type: 'map' literals, and the lit control object-map appears on 16 source lines
    retirement plain unregistration of map / view:map in plugin-map/src/index.tsx, with a tombstone docblock in plugin-gantt's form. The console lazy map stub goes with it. @object-ui/types declares map only as a stored view type, so there is no passthrough hazard
    stored layer untouched: no file under packages/types, plugin-view, plugin-list, or ObjectMap.tsx is in the diff
    other surfaces the regenerated CLI known-types list drops bare map; view:map stays a placeholder key, the state objectui#8865 left view:gantt in. record-source.ts drops the two rows, and the two react mirror tests follow. The .github/prompts/component.prompt.md Keys line moves to object-map (not a governed surface)
    docs the plugin-map README now teaches one registered type. The bare-array sentence carried from objectui#10392's ACCEPT is corrected in the README, plugin-map.mdx and location.mdx. All are true at source (record-source.ts's view-data arm refuses an array)
    pending changeset 10392-registration-record-source-inputs.md now reads as of its own change and carries a dated note naming this card, in objectui#10533's form. Its frontmatter is byte-identical (md5 base = head). A whole-set re-grep found no other present-tense claim that map is registered; 7470 is past tense and true
    pins index.bareMapKeyRetired-10393.test.tsx is red on base (row 1 has('map'); row 2 no unknown-component; row 3 two registrations) and green on head. The edited tests were narrowed only where they enumerated the retired keys
    Clause-②: yes / semver @object-ui/plugin-map minor with a BREAKING body. The published 17.6.0 registers map, so the narrowing is real. core / cli / console are patch. react changed test files only, so no entry is owed
    contract review PASS 5829419949 at c6d3f38. The seat then asked for a prose-only rework (the 10392 changeset and the two docs pages). The delta re-review is PASS 5829427662 at ec6e667, on two conditions: (a) CI concludes green, which it has; (b) the body's stale "docs pages reported, not fixed" bullet is gone, which it is — the dev's round-2 replacement already dropped it. The seat read both reviewer transcripts: every turn ran at tier
    PR body replaced by the seat with the dev's round-2 pr_body_replacement, verbatim
    governed NOT GOVERNED (15 paths at round 1, plus 4 prose paths, check-governed-queue-guard.mjs --test)
    CI 43 check-runs on ec6e667: 40 success, 3 skipped by design, 0 red
    closing keywords Fixes #10393 only

    Findings, each with its disposition

    • view:map remains a placeholder-only key that objectui check accepts: the same state as view:gantt / view:kanban. Retiring placeholders would be its own decision ⇒ recorded.
    • skills/objectui/guides/architecture.md shows a user registering their own MapRenderer as map under namespace: 'plugin-map'. That is an extension example on a governed surface, and it stays true ⇒ left alone.

    Deviations recorded

    The PR assignee is unset. The dev's label-write … --assign was refused by the permission classifier, and the seat did not re-issue it. This is with the maintainer.

    State

    In one stroke: the claim amendment, the PR body, ready and auto-merge (squash), through the relay ops comment_edit + issue_patch + pr_ready + automerge_enable.


    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

bugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions