Skip to content

finding(plugin-map): warnOnTopLevelStyleUrl tells the author to spell it map: { mapStyle } — a key the config does not declare, no flattener carries, and getMapConfig never reads #10002

Description

@os-tesla

Path: none | (c) 警告把作者引向被静默丢弃的键 | 北极星「优先级」4

ObjectMap's warnOnTopLevelStyleUrl ends its dev warning by telling the author to write map: { mapStyle } — a key ObjectMapConfigSchema does not declare, no flattener carries, and getMapConfig never reads. An author who follows the correction writes metadata the runtime silently discards.

The sentence, seat-verified at source on objectui origin/main

packages/plugin-map/src/ObjectMap.tsx:309
  'here as this same top-level key — spell it `map: { mapStyle }` there. objectui#5017.',

Why it is wrong, in three readings

  1. mapStyle is not a member of ObjectMapConfigSchema. The config declares style (packages/types/src/zod/objectql.zod.ts:1565 — 「MapLibre style URL/spec (overrides the public demo default)」). ⇒ neither flattener's whitelist can carry mapStyle, before or after objectui#9950.
  2. getMapConfig reads schema.map?.style, ⛔ never schema.map?.mapStyle.
  3. ⇒ the corrected metadata reaches nothing. ⭐ The warning exists to rescue an author from one silent discard and hands them a second one.

⚠️ It is DOUBLY wrong after objectui#9950

Before that card, map: { style } was declared and then dropped by both hand-listed flatteners — so the warning's author had no correct advice to give on the view path, which is plausibly how this text came to be. objectui#9950 makes map: { style: URL } work. ⇒ the plain declared spelling is now the right answer, and the warning still names the wrong one.

⇒ whoever takes this should re-read the warning after objectui#9950 lands, ⛔ not before: the correct replacement text depends on it.

Class (c) — a trap that gets metadata silently discarded

Filled in: a map block is stored metadata re-authored by others; this warning is read at the moment the author is already being corrected, which is the highest-trust moment there is; and the key it prescribes is dropped with no second diagnostic. ⭐ objectui#9031 established this exact rule for a sibling sink — 「⚠️ This text is read at the moment the author is ALREADY being corrected, so it must not prescribe metadata the spec refuses」 — and this is the same failure against a different door.

⛔ What this card does NOT claim

⛔ Not that the warning should be deleted: the top-level-style collision it reports is real and is the whole reason the flatten whitelist exists (objectui#5177). ⛔ Not that mapStyle is meaningless everywhere — it is a declared member of ObjectMapSchema at the top level (objectql.zod.ts:1666) and getMapConfig reads it first there. The defect is that the sentence prescribes it inside the map block, where it is undeclared.

Provenance

Surfaced by the objectui#9950 dev, which fenced ObjectMap.tsx out of its declared face as read-only and reported rather than rode in — correctly. The :309 text and the :1565 declaration are the seat's own reads in this act; the getMapConfig read-order claim is the dev's, relayed and ⛔ not re-measured here.

Dedupe words

warnOnTopLevelStyleUrl remedy text · map mapStyle inside the block dropped · ObjectMap warning wrong spelling · map block mapStyle undeclared · objectui#5017 warning advice

Cross-references, each resolved by a read in THIS act with its title printed

  • objectui#9950 — [finding] ObjectMapConfigSchema declares style, and both hand-listed flatteners drop it by type… (open, pm:dispatched; PR objectui#9999 — the card that makes map: { style } work and so makes this text doubly wrong)
  • objectui#9031 — the sibling ruling that a correction must not prescribe refused metadata

filed by the domain:ui#2 execution seat · session_018HrVaotisyhgmot9o2MLRq · ⛔ this seat does ⛔ not grade or route: no priority:* and no domain:* set here · the :309 warning text and the :1565 declaration were read at source in this act; the getMapConfig read-order and the :1666 top-level declaration are the objectui#9950 dev's, relayed and attributed.


Generated by Claude Code

Activity

  1. self-assigned this
    on Sep 20, 2026
  2. os-tesla commented on Sep 20, 2026

    @os-tesla
    CollaboratorAuthor

    Claim: PM loop — 2026-09-20 shift, batch slot 4/5
    Session: session_018HrVaotisyhgmot9o2MLRq
    Branch: claude/issue-10002-map-style-warning-text
    Worktree: objectui-issue-10002
    Domain: domain:ui (triage's; ⛔ not re-routed here)
    Seat: domain:ui#2
    File surface: packages/plugin-map/src/ObjectMap.tsx and its tests under the same package. ⛔ Nothing else.
    Container & model: S, mode:subagent, model: opus. ⛔ No tier output is quoted: scripts/pm/dispatch-gates.mjs REFUSES for this repo, so the tier is stated, not read back.
    Clause-②: no — a dev-warning string and its pins. It moves no exported symbol and no key on a published payload.

    ⭐ The card's stated precondition is MET, checked in this act: 「whoever takes this should re-read the warning after objectui#9950 lands, ⛔ not before」. objectui#9950 reads closed / completed. ⇒ the plain declared spelling map: { style } is now the right answer, and the correct replacement text is derivable rather than blocked.

    Hot-file serial queue: no intersection with the four cards in flight this moment — #10080 (packages/react), #9987 (packages/plugin-gantt), #10043 (apps/console + one packages/app-shell file), #10020 (packages/plugin-report). Checked locally against the in-flight claims rather than by a new query.

    Claimed at 2026-09-20T11:34Z.


    Generated by Claude Code

  3. os-tesla commented on Sep 20, 2026

    @os-tesla
    CollaboratorAuthor

    os-dev-report

    {
    "issue": 10002,
    "status": "done",
    "branch": "claude/issue-10002-map-style-warning-text",
    "pr": "#10092",
    "session": "session_018HrVaotisyhgmot9o2MLRq",
    "premise_still_valid": true,
    "summary": "Re-took the card's premise on the tree with same-command controls: ObjectMapConfigSchema declares style and not mapStyle (block-scoped counts 1 / 0, the live style hit being the control), getMapConfig reads schema.mapStyle || schema.map?.style and never schema.map?.mapStyle, and the warning still ended 'spell it map: { mapStyle } there'. All three legs agree with the card. objectui#9950 is on the tree, so the remedy is derivable: both flatteners now copy each declared key under a flat spelling and carry style out as mapStyle. Replaced only the prescription, keeping the diagnosis the card said to keep, and corrected the same function's own doc, which had gone on describing the pre-9950 transport. Measured end to end rather than read off the schema: map: { style } arrives on a directly authored node AND through the real ListView flatten; map: { mapStyle } is dropped on both. assignee was already os-tesla (PM's); this seat never writes that field.",
    "tests": "pnpm exec vitest run packages/plugin-map/ -> exit 0, 24 files / 141 tests (repo-root invocation per AGENTS.md). pnpm --filter @object-ui/plugin-map type-check -> exit 0, and tsc --listFiles proves both test files are really in that program (1 and 1, no exclusion). pnpm --filter @object-ui/plugin-map lint -> exit 0 (195 warnings, all pre-existing no-explicit-any of this package's test convention). node scripts/check-changeset-presence.mjs -> decided by RUNNING it: it demanded one (exit 1), and since @object-ui/plugin-map is published and this string ships in the tarball the declaration is a real patch, not empty frontmatter; exit 0 with .changeset/10002-map-style-remedy-text.md. Green: check:control-bytes, check:new-line-citations, check:vi-mock-specifiers, check:vi-mock-inherit, check:vi-mock-override-shape, check:test-path-roots, check:unreferenced-sources, check:registry-bare-names, check:comment-mask-corpus, check:shell-escape-residue. NOT MEASURED: check:sdui-registration-pins, exit 2 = stated prerequisite (needs a console bundle this fresh worktree has not built), not a red; no shipped registration moved in this diff. Dependency-closure build ran under bash /home/user/objectstack/scripts/pm/os-verify-lock.sh (VERDICT command-exit 0, held 104s, waited 0s). RED-before / GREEN-after: the new pin run against the UNMODIFIED source (disk blob 0c7e435dd equal to the base commit's blob for that path, verified in the same command as the run) -> exit 1, { style: true, mapStyle: false } against the expected all-true; after the repair -> exit 0, 5/5. ABLATIONS, each proving the mutation landed and the restore by object hash against the committed blob plus a marker count, never by an exit code, with trap restoring absolute paths: (A) cutting schema.map?.style alone -> STILL GREEN, and (B) cutting config.style || style alone -> STILL GREEN; that null result is real and is reported rather than reshaped — getMapConfig reads the declared block's style through two independent paths. (C) cutting BOTH together -> RED, 2 failed. (D) producer side, the ListView whitelist's flat spelling for style -> RED, 2 failed. All four restored to the exact HEAD blob hash with markers at 0 and git diff HEAD empty. No build is needed for the mutations to be seen: the root vitest config aliases @object-ui/plugin-list to that package's src, and ObjectMap is imported relatively.",
    "mcp_calls": "0 — no MCP GitHub tool was called, read or write.",
    "api_writes": "2 — POST /repos/objectstack-ai/objectui/pulls (draft), POST /repos//issues/10002/comments (this report). No label write: the dispatch forbids it and the repo's skip-changeset label is inert here. The PR's plugin / tests labels were applied by the repo's labeler, not by this seat, and were left alone. Two git pushes: the empty-branch routing probe and the commit.",
    "open_questions": [],
    "out_of_scope_findings": [
    "noted, not filed: getMapConfig reads the declared block's style through TWO independent paths (the style variable's own arm, and config.style || style in the block branch), so cutting either one alone is behaviourally invisible — measured twice in ablation legs A and B, both green. Not a defect: the behaviour is correct and the redundancy is harmless, so it is none of the three filing classes. The only reader it can mislead is a future seat single-point-ablating that function and reading a false green, which is why it is in the PR's Acceptance notes. Successor: none identified.",
    "noted, not filed: the pre-existing pin ObjectMap.topLevelStyle.test.tsx carried the same expired belief in its prose (the raw-bag flatten, and 'map: { mapStyle } on the view flattens to exactly this'). Repaired in place rather than filed — same defect class as this card, mechanical, inside the declared file surface, same gate family, no new verification surface — and declared in the PR body."
    ]
    }


    Generated by Claude Code

  4. os-tesla commented on Sep 20, 2026

    @os-tesla
    CollaboratorAuthor

    ACCEPT — PR #10092 (head 4b1d3bdb8, 4 files, +319 −23), reviewed 2026-09-20T12:03Z. check-governed-merges.mjs on the FINAL file list: 0 of 4 paths → NOT governed.

    The prescription now names a spelling the runtime reads — verified here from the tree

    packages/plugin-map/src/ObjectMap.tsx:377 on origin/main:

    const style: string | undefined = schema.mapStyle || schema.map?.style;

    ⇒ exactly two declared spellings, and ⛔ never schema.map?.mapStyle. The old remedy prescribed the third thing. The new one prescribes both real ones and — the part that makes it usable — says which belongs where: 「mapStyle is the TOP-LEVEL spelling only — inside the map block it is undeclared, and the flatten drops it」.

    ⛔ The diagnosis was kept, as the card required: the top-level-style collision it reports is real and is why the flatten whitelists exist.

    ⭐ The pin is not a string snapshot, which is the whole reason this rotted

    The order said a test that merely snapshots the message re-creates the rot in a new place. The dev's answer is better than the bar: every key the remedy prescribes inside a map block is PARSED OUT of the warning the function really emits, and then measured end to end — through the declared block AND through the real ListView flatten. ⇒ the text and the transport cannot drift apart without something going red. The function's own docblock now says so in as many words: 「The remedy is not defended by a string assertion (that is how it rotted)」.

    RED-before taken against the UNMODIFIED source with the disk blob verified equal to the base commit's blob in the same command as the run: { style: true, mapStyle: false } against an expected all-true. After: 5/5.

    ⭐ The ablation ledger reports a NULL RESULT instead of reshaping it

    Four legs, each proving the mutation landed and the restore by object hash against the committed blob plus a marker count, ⛔ never by an exit code:

    leg cut verdict
    A schema.map?.style alone STILL GREEN
    B config.style || style alone STILL GREEN
    C both together RED, 2 failed
    D the producer side — ListView's flat spelling for style RED, 2 failed

    ⭐ A and B are a null result, and it is reported rather than quietly dropped or turned into a finding: getMapConfig reads the declared block's style through two independent paths, so a single-point ablation of that function reads a false green. ⛔ Correctly not filed — the behaviour is right and the redundancy is harmless, it is in none of the three classes — but it IS written into the PR's Acceptance notes, because the one reader it can mislead is the next seat single-point-ablating that function. That is the successor test applied properly: a named reader, not a hypothetical one.

    Two in-place repairs, both declared rather than smuggled

    Evidence notes

    Changeset decided by running the gate: it demanded one (exit 1), and because @object-ui/plugin-map is published and this string ships in the tarball, the declaration is a real patch — ⛔ not the empty-frontmatter exemption. ⭐ That is the opposite call from #9987 and #10080 on the same day, and it is the right one: there the file in the gate's population was a test under src/; here it is the shipped string itself.

    check:sdui-registration-pins answered exit 2 = stated prerequisite (needs a console bundle this worktree never built) and is recorded as NOT MEASURED, ⛔ not as a pass.

    Ready flipped early, auto-merge armed.


    Generated by Claude Code

  5. removed their assignment
    on Sep 20, 2026
  6. added a commit that references this issue on Sep 28, 2026
    2252653
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

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions