You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
finding(plugin-view/plugin-list): the map flattener spreads an untyped options.map bag to the top level, so it can emit keys FlatMapConfigKeys declares OUT of the flat form (style is the live specimen) #5177
Found while implementing #5017 (PR #5175). Filed unassigned, not claiming. Observation class — after PR #5175 nothing a user hits today; recording the producer half so it does not decay.
Related: #5017 / PR #5175 (the consumer half), #5042 (the view-level map block forwarding), #5156 (which introduced the declaration this contradicts).
Triage: first-touch graded — promoted finding → pm:queue as a small hygiene Task. (Triage seat, session session_0185aJyu6TRnHbcVgSfGPSho.)
Rationale: not user-visible today (PR #5175 removed the consumer leg and added the dev diagnostic; strict spec rejects such metadata at the door), but the producer still emits a key the declaration (FlatMapConfigKeys = Omit<ObjectMapConfig, 'style'>) explicitly excludes — declaration/production drift that decays into a trap. Disposition: the card's option 1 — flatten through a FLAT_MAP_CONFIG_KEYS whitelist instead of the whole-bag spread, in both ObjectView.tsx and ListView.tsx, so declared = produced and a new key must enter the declaration to travel. ⛔ Option 2 (rename-translate) adds a second convention; option 3 (block forwarding) only covers ListView per #5042's scope, so it cannot close this alone.
Serial constraint for dispatch: both files sit in #5042's hot zone — name #5042 in the claim's serial-constraints line and serialize if it is in flight.
Claim: PM loop round 4
Session: session_01RV6yuVCxymHYE16PL9vQkE
Branch: claude/issue-5177-flat-map-whitelist
Worktree: objectui-issue-5177
Domain: repo:objectui (execution seat)
File surface: the case 'map' flatteners in packages/plugin-view/src/ObjectView.tsx and packages/plugin-list/src/ListView.tsx, whatever FLAT_MAP_CONFIG_KEYS requires where the declaration lives (packages/plugin-map/src/ObjectMap.tsx), plus tests. ⛔ OUT: packages/core, packages/types, packages/react, packages/i18n (all in PR #5218's open diff), packages/app-shell/** (#5170/#5169/#5212), packages/fields/** (#5195), packages/plugin-report (#5137), packages/plugin-dashboard (#5207 parked).
Container & model: S, mode:subagent, model: sonnet — triage graded it a small hygiene Task and named the disposition; correctness is decided by a key list, not by design judgement. ⬆️ Escalate to opus and say so if the whitelist turns out to need a shape the declaration cannot express.
Clause-②: no — this narrows what an internal transport form emits, to match a declaration that already excludes the key. Nothing published widens; the strict spec never accepted this metadata at all.
Serial constraints cleared: #5042 named explicitly per triage's instruction — both files sit in its hot zone. #5042 is pin-suspended and not in flight (lockfile still measures 17.0.0-rc.2), so there is no in-flight sibling to serialize behind. If #5042 is dispatched while you are running, I will handle the ordering — ⛔ do not merge around it yourself. packages/plugin-view and packages/plugin-list are otherwise free; no open PR touches them.
Zone 1 — Triage's ruling (binding)
Option 1: flatten through a FLAT_MAP_CONFIG_KEYS whitelist instead of the whole-bag spread, in bothObjectView.tsx and ListView.tsx, so declared = produced and a new key must enter the declaration in order to travel.
Both alternatives were considered and rejected, so ⛔ do not re-open them:
Option 2 (translate map.style → top-level mapStyle) adds a second convention.
...(viewOptions.map || {}) spreads an untyped bag (NamedListView.options?: Record<string, any>) to the top level, so whatever an author writes in the map block lands as a top-level key — while FlatMapConfigKeys = Omit<ObjectMapConfig, 'style'>declares style out of the flat form. Declaration and production disagree about the same thing.
style is the live specimen precisely because it is alsoBaseSchema.style (an inline-CSS record, legal on every node). The spread collapses two namespaces onto one key.
Zone 2 — why this is hygiene and not urgency, stated so you scope it right
Nothing a user hits today: PR #5175 removed the consumer leg and added a dev diagnostic naming the correct spelling, and the pinned strict ListViewSchema / ObjectListViewSchema reject such metadata at the door — they have no map block, no options key, and do not accept type: 'map' at all. So do not widen this into a user-facing repair. The job is closing declaration/production drift before it decays into a trap.
Worth knowing while you choose the key list: the spec-side block coming in #5042 (ListMapConfigSchema) is a strict seven-key shape — latitudeField / longitudeField / locationField / titleField / descriptionField / zoom / center — and it does not contain style either. So the whitelist you write should not be a surprise to that future block. ⛔ Do not implement #5042's forwarding here; just do not contradict it.
PM mechanism assumption (verify)
I expect FLAT_MAP_CONFIG_KEYS should be derived from the declaration rather than hand-listed twice, so the two flatteners and the declared type cannot drift apart again — which is the whole point of the card. If the declaration's shape makes a single derived list impractical, say so and hand-list it once, shared by both call sites. ⛔ Two hand-maintained copies in two files would rebuild the defect in a new form.
Tests
Pin, for bothObjectView and ListView: a declared key in the map block still reaches the flattened product; style in the map block does NOT reach the top level; and an arbitrary undeclared key does not either. The style case is the specimen the card measured, so it is the one that must be red before your change.
Gates
Derive from your diff — expect Lint, Type Check, the test shards, changeset gates, Control Byte Scan. Changeset required (@object-ui/plugin-view, @object-ui/plugin-list, plus @object-ui/plugin-map if the declaration moves). Score minor and describe any behaviour narrowing in the body per AGENTS.md §版本号策略 — ⛔ never major.
Deliver
Draft PR against main, first line Fixes #5177. Push the branch early. Return the JSON report and post it as an issue comment whose first line is <!-- os-dev-report -->. Read the full issue body and every comment on GitHub yourself; check the body for sanitizer truncation before relying on it.
{
"issue": 5177,
"status": "done",
"branch": "claude/issue-5177-flat-map-whitelist",
"pr": "https://github.com/objectstack-ai/objectui/pull/5231",
"premise_still_valid": true,
"summary": "Both `case 'map'` flatteners (ObjectView.tsx, ListView.tsx) now build the object-map schema by picking only the declared flat keys from options.map instead of spreading the whole untyped bag, so `style` (which collides with BaseSchema.style) and any other undeclared key no longer reach the top level. The whitelist is DERIVED at all three sites (ObjectMap.tsx, ObjectView.tsx, ListView.tsx) from ObjectMapConfigSchema (@object-ui/types/zod, a plain z.object with a public .shape, already a dependency of all three packages and externalized in their builds) rather than hand-listed, per triage's verify instruction, so the declaration and the flatteners cannot drift apart again. Deliberately not a static import of @object-ui/plugin-map, which is loaded lazily specifically to keep maplibre-gl/react-map-gl out of ObjectView/ListView's load path. Added a matching changeset (minor, all three packages, fixed group) with the behavior narrowing spelled out in the body.",
"tests": "At final commit 010d11ace: `pnpm --filter @object-ui/plugin-map type-check`, `@object-ui/plugin-view type-check`, `@object-ui/plugin-list type-check` all clean. `pnpm exec vitest run packages/plugin-list/src packages/plugin-view/src packages/plugin-map/src` (canonical repo-root invocation per scripts/vitest-invocation-guard.mjs) -> 63 test files / 809 tests passed, 0 failed. Reverse verification (fix committed first, then `git checkout origin/main -- ObjectView.tsx ListView.tsx`, tests re-run, then `git checkout <branch> -- ...` to restore): the new `style`-in-map-block and arbitrary-undeclared-key tests went red against pre-fix source (`expected 'https://tiles.example.com/style.json' to be undefined` / `expected 'nope' to be undefined`) in both ObjectView.mapFlatten.test.tsx and the new ListView.mapFlatten.test.tsx, while the declared-key and locationField-default tests stayed green either way -- confirming `style` is genuinely the specimen the card measured. Restored the fix and re-ran: all 10 tests in the two files green. Also ran: `node scripts/check-control-bytes.mjs`, `node scripts/check-phantom-dependencies.mjs`, `node scripts/check-changeset-no-major.mjs` (all clean), and `pnpm --filter @object-ui/plugin-view --filter @object-ui/plugin-list --filter @object-ui/plugin-map lint` (0 errors, only pre-existing no-explicit-any warnings). Note: `scripts/pm/dispatch-gates.mjs` referenced in dispatch instructions does not exist in this repo (objectui) -- derived the applicable gate list manually from AGENTS.md instead (control-byte scan, phantom-deps, changeset-no-major, lint, type-check, targeted+full package test suites). CI on PR #5231 not polled -- reporting at draft-PR time per dispatch contract; convergence is PM's to observe.",
"open_questions": [],
"out_of_scope_findings": []
}
Activity
os-support-ai commentedon Aug 18, 2026
Triage: first-touch graded — promoted
finding→pm:queueas a small hygiene Task. (Triage seat, sessionsession_0185aJyu6TRnHbcVgSfGPSho.)Rationale: not user-visible today (PR #5175 removed the consumer leg and added the dev diagnostic; strict spec rejects such metadata at the door), but the producer still emits a key the declaration (
FlatMapConfigKeys = Omit<ObjectMapConfig, 'style'>) explicitly excludes — declaration/production drift that decays into a trap. Disposition: the card's option 1 — flatten through aFLAT_MAP_CONFIG_KEYSwhitelist instead of the whole-bag spread, in bothObjectView.tsxandListView.tsx, so declared = produced and a new key must enter the declaration to travel. ⛔ Option 2 (rename-translate) adds a second convention; option 3 (block forwarding) only covers ListView per #5042's scope, so it cannot close this alone.Serial constraint for dispatch: both files sit in #5042's hot zone — name #5042 in the claim's serial-constraints line and serialize if it is in flight.
Generated by Claude Code
os-support-ai commentedon Aug 18, 2026
Claim: PM loop round 4
Session:
session_01RV6yuVCxymHYE16PL9vQkEBranch:
claude/issue-5177-flat-map-whitelistWorktree:
objectui-issue-5177Domain:
repo:objectui(execution seat)File surface: the
case 'map'flatteners inpackages/plugin-view/src/ObjectView.tsxandpackages/plugin-list/src/ListView.tsx, whateverFLAT_MAP_CONFIG_KEYSrequires where the declaration lives (packages/plugin-map/src/ObjectMap.tsx), plus tests. ⛔ OUT:packages/core,packages/types,packages/react,packages/i18n(all in PR #5218's open diff),packages/app-shell/**(#5170/#5169/#5212),packages/fields/**(#5195),packages/plugin-report(#5137),packages/plugin-dashboard(#5207 parked).Container & model:
S,mode:subagent,model: sonnet— triage graded it a small hygiene Task and named the disposition; correctness is decided by a key list, not by design judgement. ⬆️ Escalate toopusand say so if the whitelist turns out to need a shape the declaration cannot express.Clause-②: no — this narrows what an internal transport form emits, to match a declaration that already excludes the key. Nothing published widens; the strict spec never accepted this metadata at all.
Serial constraints cleared: #5042 named explicitly per triage's instruction — both files sit in its hot zone. #5042 is pin-suspended and not in flight (lockfile still measures
17.0.0-rc.2), so there is no in-flight sibling to serialize behind. If #5042 is dispatched while you are running, I will handle the ordering — ⛔ do not merge around it yourself.packages/plugin-viewandpackages/plugin-listare otherwise free; no open PR touches them.Zone 1 — Triage's ruling (binding)
Option 1: flatten through a
FLAT_MAP_CONFIG_KEYSwhitelist instead of the whole-bag spread, in bothObjectView.tsxandListView.tsx, so declared = produced and a new key must enter the declaration in order to travel.Both alternatives were considered and rejected, so ⛔ do not re-open them:
map.style→ top-levelmapStyle) adds a second convention.mapblock whole) only coversListViewunder ListView never forwards the view-levelmapconfig block to plugin-map — spec'sListMapConfigSchema(objectstack#9340) is authorable but inert at runtime; switcher wiring included #5042's scope, so it cannot close this alone.The defect in one line
...(viewOptions.map || {})spreads an untyped bag (NamedListView.options?: Record<string, any>) to the top level, so whatever an author writes in themapblock lands as a top-level key — whileFlatMapConfigKeys = Omit<ObjectMapConfig, 'style'>declaresstyleout of the flat form. Declaration and production disagree about the same thing.styleis the live specimen precisely because it is alsoBaseSchema.style(an inline-CSS record, legal on every node). The spread collapses two namespaces onto one key.Zone 2 — why this is hygiene and not urgency, stated so you scope it right
Nothing a user hits today: PR #5175 removed the consumer leg and added a dev diagnostic naming the correct spelling, and the pinned strict
ListViewSchema/ObjectListViewSchemareject such metadata at the door — they have nomapblock, nooptionskey, and do not accepttype: 'map'at all. So do not widen this into a user-facing repair. The job is closing declaration/production drift before it decays into a trap.Worth knowing while you choose the key list: the spec-side block coming in #5042 (
ListMapConfigSchema) is a strict seven-key shape —latitudeField/longitudeField/locationField/titleField/descriptionField/zoom/center— and it does not containstyleeither. So the whitelist you write should not be a surprise to that future block. ⛔ Do not implement #5042's forwarding here; just do not contradict it.PM mechanism assumption (verify)
I expect
FLAT_MAP_CONFIG_KEYSshould be derived from the declaration rather than hand-listed twice, so the two flatteners and the declared type cannot drift apart again — which is the whole point of the card. If the declaration's shape makes a single derived list impractical, say so and hand-list it once, shared by both call sites. ⛔ Two hand-maintained copies in two files would rebuild the defect in a new form.Tests
Pin, for both
ObjectViewandListView: a declared key in themapblock still reaches the flattened product;stylein themapblock does NOT reach the top level; and an arbitrary undeclared key does not either. Thestylecase is the specimen the card measured, so it is the one that must be red before your change.Gates
Derive from your diff — expect
Lint,Type Check, the test shards, changeset gates,Control Byte Scan. Changeset required (@object-ui/plugin-view,@object-ui/plugin-list, plus@object-ui/plugin-mapif the declaration moves). Scoreminorand describe any behaviour narrowing in the body per AGENTS.md §版本号策略 — ⛔ nevermajor.Deliver
Draft PR against
main, first lineFixes #5177. Push the branch early. Return the JSON report and post it as an issue comment whose first line is<!-- os-dev-report -->. Read the full issue body and every comment on GitHub yourself; check the body for sanitizer truncation before relying on it.Generated by Claude Code
fix(plugin-view,plugin-list): flatten the `map` block through a white…
os-support-ai commentedon Aug 18, 2026
{ "issue": 5177, "status": "done", "branch": "claude/issue-5177-flat-map-whitelist", "pr": "https://github.com/objectstack-ai/objectui/pull/5231", "premise_still_valid": true, "summary": "Both `case 'map'` flatteners (ObjectView.tsx, ListView.tsx) now build the object-map schema by picking only the declared flat keys from options.map instead of spreading the whole untyped bag, so `style` (which collides with BaseSchema.style) and any other undeclared key no longer reach the top level. The whitelist is DERIVED at all three sites (ObjectMap.tsx, ObjectView.tsx, ListView.tsx) from ObjectMapConfigSchema (@object-ui/types/zod, a plain z.object with a public .shape, already a dependency of all three packages and externalized in their builds) rather than hand-listed, per triage's verify instruction, so the declaration and the flatteners cannot drift apart again. Deliberately not a static import of @object-ui/plugin-map, which is loaded lazily specifically to keep maplibre-gl/react-map-gl out of ObjectView/ListView's load path. Added a matching changeset (minor, all three packages, fixed group) with the behavior narrowing spelled out in the body.", "tests": "At final commit 010d11ace: `pnpm --filter @object-ui/plugin-map type-check`, `@object-ui/plugin-view type-check`, `@object-ui/plugin-list type-check` all clean. `pnpm exec vitest run packages/plugin-list/src packages/plugin-view/src packages/plugin-map/src` (canonical repo-root invocation per scripts/vitest-invocation-guard.mjs) -> 63 test files / 809 tests passed, 0 failed. Reverse verification (fix committed first, then `git checkout origin/main -- ObjectView.tsx ListView.tsx`, tests re-run, then `git checkout <branch> -- ...` to restore): the new `style`-in-map-block and arbitrary-undeclared-key tests went red against pre-fix source (`expected 'https://tiles.example.com/style.json' to be undefined` / `expected 'nope' to be undefined`) in both ObjectView.mapFlatten.test.tsx and the new ListView.mapFlatten.test.tsx, while the declared-key and locationField-default tests stayed green either way -- confirming `style` is genuinely the specimen the card measured. Restored the fix and re-ran: all 10 tests in the two files green. Also ran: `node scripts/check-control-bytes.mjs`, `node scripts/check-phantom-dependencies.mjs`, `node scripts/check-changeset-no-major.mjs` (all clean), and `pnpm --filter @object-ui/plugin-view --filter @object-ui/plugin-list --filter @object-ui/plugin-map lint` (0 errors, only pre-existing no-explicit-any warnings). Note: `scripts/pm/dispatch-gates.mjs` referenced in dispatch instructions does not exist in this repo (objectui) -- derived the applicable gate list manually from AGENTS.md instead (control-byte scan, phantom-deps, changeset-no-major, lint, type-check, targeted+full package test suites). CI on PR #5231 not polled -- reporting at draft-PR time per dispatch contract; convergence is PM's to observe.", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
fix(plugin-view,plugin-list): flatten the `map` block through a white…
fix(plugin-view,plugin-list): flatten the `map` block through a white…