Repository navigation
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
Activity
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.tsxand its tests under the same package. ⛔ Nothing else.
Container & model: S,mode:subagent,model: opus. ⛔ No tier output is quoted:scripts/pm/dispatch-gates.mjsREFUSES 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 spellingmap: { 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+ onepackages/app-shellfile), #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
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
ACCEPT — PR #10092 (head
4b1d3bdb8, 4 files, +319 −23), reviewed 2026-09-20T12:03Z.check-governed-merges.mjson 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:377onorigin/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: 「mapStyleis the TOP-LEVEL spelling only — inside themapblock it is undeclared, and the flatten drops it」.⛔ The diagnosis was kept, as the card required: the top-level-
stylecollision 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
mapblock is PARSED OUT of the warning the function really emits, and then measured end to end — through the declared block AND through the realListViewflatten. ⇒ 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?.stylealoneSTILL GREEN B config.style || stylealoneSTILL GREEN C both together RED, 2 failed D the producer side — ListView's flat spelling forstyleRED, 2 failed ⭐ A and B are a null result, and it is reported rather than quietly dropped or turned into a finding:
getMapConfigreads the declared block'sstylethrough 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
- The same function's docblock had gone on describing the pre-[finding] ObjectMapConfigSchema declares
style, and both hand-listed flatteners drop it by type (Omit<ObjectMapConfig,'style'>) — an authored map style parses green and renders on the public demo tiles #9950 transport. Repaired in the same commit — this change is what made it false. - The pre-existing pin
ObjectMap.topLevelStyle.test.tsxcarried the same expired belief in its prose. Repaired in place rather than filed, with the reason given: same defect class, mechanical, inside the declared file surface, same gate family, no new verification surface. ⭐ Declared in the PR body, ⛔ not left for a reviewer to notice.
Evidence notes
Changeset decided by running the gate: it demanded one (exit 1), and because
@object-ui/plugin-mapis published and this string ships in the tarball, the declaration is a realpatch— ⛔ 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 undersrc/; here it is the shipped string itself.check:sdui-registration-pinsanswered 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
- The same function's docblock had gone on describing the pre-[finding] ObjectMapConfigSchema declares
- added a commit that references this issue
on Sep 28, 2026
Path: none | (c) 警告把作者引向被静默丢弃的键 | 北极星「优先级」4
ObjectMap'swarnOnTopLevelStyleUrlends its dev warning by telling the author to writemap: { mapStyle }— a keyObjectMapConfigSchemadoes not declare, no flattener carries, andgetMapConfignever reads. An author who follows the correction writes metadata the runtime silently discards.The sentence, seat-verified at source on objectui
origin/mainWhy it is wrong, in three readings
mapStyleis not a member ofObjectMapConfigSchema. The config declaresstyle(packages/types/src/zod/objectql.zod.ts:1565— 「MapLibre style URL/spec (overrides the public demo default)」). ⇒ neither flattener's whitelist can carrymapStyle, before or after objectui#9950.getMapConfigreadsschema.map?.style, ⛔ neverschema.map?.mapStyle.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 makesmap: { 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⚠️ 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.
mapblock 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 — 「⛔ What this card does NOT claim
⛔ Not that the warning should be deleted: the top-level-
stylecollision it reports is real and is the whole reason the flatten whitelist exists (objectui#5177). ⛔ Not thatmapStyleis meaningless everywhere — it is a declared member ofObjectMapSchemaat the top level (objectql.zod.ts:1666) andgetMapConfigreads it first there. The defect is that the sentence prescribes it inside themapblock, where it is undeclared.Provenance
Surfaced by the objectui#9950 dev, which fenced
ObjectMap.tsxout of its declared face as read-only and reported rather than rode in — correctly. The:309text and the:1565declaration are the seat's own reads in this act; thegetMapConfigread-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 adviceCross-references, each resolved by a read in THIS act with its title printed
style, and both hand-listed flatteners drop it by type… (open,pm:dispatched; PR objectui#9999 — the card that makesmap: { style }work and so makes this text doubly wrong)filed by the
domain:ui#2execution seat ·session_018HrVaotisyhgmot9o2MLRq· ⛔ this seat does ⛔ not grade or route: nopriority:*and nodomain:*set here · the:309warning text and the:1565declaration were read at source in this act; thegetMapConfigread-order and the:1666top-level declaration are the objectui#9950 dev's, relayed and attributed.Generated by Claude Code