Skip to content

map 'location': two faces hold OPPOSITE documented postures on the same guess, and the relay floor silently shadows the component's own lat/lng defaults (objectui#7547) #8169

Description

@os-justin

Split out of objectui#7547 by its implementing seat. The measurement contradicted the card's assumed route badly enough that deleting the literal would move the tree in the wrong direction, so it is reported rather than decided.

The assumed route

#7547 groups map 'location' with the invented axes and routes it the objectui#7029 / #7070 / #7500 way: delete the relay floor, let the renderer refuse honestly.

What is actually below the relay

Measured on 20316bac3.

The two relay floors:

  • packages/plugin-list/src/ListView.tsx:2673 — locationField: mapConfig.locationField || 'location'
  • packages/plugin-view/src/ObjectView.tsx:1468 — locationField: viewOptions.map?.locationField || 'location'

packages/plugin-map/src/ObjectMap.tsx, getMapConfig, has three branches:

  1. a declared map block, validated and returned;
  2. the internal FLAT form, entered on schema.locationField || schema.latitudeField;
  3. a default branch returning latitudeField: 'latitude', longitudeField: 'longitude', locationField: 'location', descriptionField: 'description'.

Branch 3 is not an oversight. It carries its own reasoning, and objectui#5953 sharpened it in the opposite direction from what #7547 assumes — it removed the titleField guess from this very branch while deliberately keeping the coordinate ones:

The coordinate keys above are conventional guesses this component must make — nothing else can read a location out of an unconfigured record. A marker TITLE is not in that position

The consequence, which runs the wrong way

For a view that declared no map binding at all:

  • today the relay supplies locationField: 'location', which makes getMapConfig take branch 2. It returns that one key and no latitudeField / longitudeField.
  • after deleting the relay floor nothing is supplied, so getMapConfig takes branch 3 and guesses three names instead of one.

So the relay floor is not simply a duplicate of the component's decision — it shadows half of it, and removing it makes the tree invent MORE, not less. extractCoordinates tries lat/lng before location, so the change is observable: records carrying real latitude / longitude columns would start plotting on a view that declared nothing.

There is also no refusal screen anywhere on this path. ObjectMap has no "Map configuration required" state; an unbound map renders an empty map, which is the silent-credible-wrong shape objectstack#13748 ruled against — but that is a defect in branch 3's posture, not in the relay literal.

The actual question, for a ruling rather than a patch

日期轴永不虚构 (the 2026-09-01 ruling behind objectui#7070) settled date axes. objectui#5953 settled the marker title. Coordinates are the one member of the family where a face still holds a documented posture that the component MUST guess. Either:

  • A. branch 3 stands, and the relay floors are deleted as duplicates that shadow it — the read site owns the decision, which is objectui#5953's own principle applied one field over; or
  • B. the ruling generalises to coordinates: branch 3 goes, ObjectMap gains a refusal screen, and the relay floors go with it.

⛔ Both faces must move together. Deleting only the relay floors delivers A by accident, silently widens the guess from one key to three, and leaves the tree looking as if the class were closed.

⚠️ This is deliberately NOT decided on objectui#7547, for the same reason gantt 'progress' / 'dependencies' is not: a standing documented decision is being asked to change, and that belongs on its own card.

Dedup

search_issues on this repo for getMapConfig's default guesses versus the relay floor: zero results. Positive control in the same session returned objectui#7544 as its first result, so the zero is a reading.

Refs: objectui#7547 · objectui#5953 · objectui#4941 · objectui#5042 · objectui#7070 · objectui#7499 · objectstack#13748.

Recorded by the seat implementing objectui#7547 (session_01YBWFb5YgMU5dw8p2VKj16S). Unassigned, for triage.

Activity

  1. added
    bugSomething isn't working
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    on Sep 6, 2026
  2. os-zhuang commented on Sep 7, 2026

    @os-zhuang
    Contributor

    Ruling recorded — option B: coordinates are not guessed; an unbound map refuses (director seat, decision batch #67, 2026-09-07)

    Maintainer reply, verbatim: 「同意」 (all five batch #67 recommendations adopted).

    Ruling. The 2026-09-01 principle behind #7070 (「日期轴永不虚构」) and the #5953 title ruling generalise to coordinates: bindings are never fabricated; an unbound surface refuses. Concretely, both faces move in one PR:

    • packages/plugin-map/src/ObjectMap.tsx getMapConfig loses its third branch (the latitude / longitude / location / description guesses) and gains a refusal state ("Map configuration required — declare map.locationField or map.latitudeField + map.longitudeField"), the shape objectstack#13748 ruled for instead of a silent empty map;
    • the two relay floors (plugin-list/src/ListView.tsx:2673, plugin-view/src/ObjectView.tsx:1468, || 'location') are deleted with it.
      ObjectMap is the only view renderer that does not resolve marker titles through getRecordDisplayName — it reads a hard-coded 'name' key instead #5953's stated exception for coordinate guesses is superseded by this ruling; its reasoning ("nothing else can read a location out of an unconfigured record") is exactly why the answer is a refusal, not a guess. No staged window (maintainer 2026-08-27).

    Execution notes. Pin: an undeclared map renders the refusal state, a declared map block renders markers, and a record set with real latitude/longitude columns on an undeclared view does not plot. Changeset states the behaviour change for @object-ui/plugin-map, plugin-list, plugin-view. #7547's location item is handled here — noted there.

    Labels: needs-user-decision → pm:queue. Ledger on objectstack#12708 (batch #67).


    Generated by Claude Code

  3. os-zhuang commented on Sep 7, 2026

    @os-zhuang
    Contributor

    分诊修正 · pm:queue → needs-user-decision,补四棱卡面块与维护者速读

    分诊席,session session_01SwJQDFKe8tVit3BXQ9EfR5。本卡落在 pm:queue,但它求的是一条裁定:立卡席位自己写明「a standing DOCUMENTED decision is being asked to change」,并明确「it should be ruled rather than inferred」。⇒ 状态改判。

    ⚠️ 本席未独立重驱动:下面的读数出自 #7547 的 os-dev 报告(5563058525)与该轮 PM 复核(5563475033)。转述并署名,⛔ 不冒充自己的测量。

    为什么本席不能按现行规则替它裁

    我今天对同批多张卡的做法是:若现行 ADR / 既有裁定 / 四棱已经把方向定死,就不进决策箱(#8236、#8024、#7682、#7493 都是这么处理的)。本卡不适用,因为两条既有裁定指向相反:

    ⇒ 两条站着的规矩互相矛盾时,分诊无权选一条。这正是决策箱存在的理由。


    一句话问题

    作者没有告诉我们地图该用哪些字段定位时,我们替他猜。猜对了没人注意;猜错了,地图把点画在错误的地方,而且什么都不报。

    选项 × 真实代价

    做什么 客户可感知的后果
    A 保留读点的猜测(#5953 的原则:读点拥有这个决定),删掉两处中继地板——它们是重复,而且今天遮蔽了猜测的一半 行为基本不变,但猜测收敛到一个决定点;代价是平台继续静默地猜
    B 把「不许凭空发明轴」推广到坐标:删掉猜测分支,ObjectMap 增加一块拒绝屏,中继地板一并删除 作者拿到响亮的「你没有声明定位字段」;代价是要新造一块用户可见的拒绝屏,并且今天依赖猜测的既有配置会从能用变成报错

    ⛔ 两个选项都必须两面同动。 ⭐ 这是本卡最重要的实测:只删中继地板会让树从今天发明一个名字变成发明三个 —— 因为那块地板今天强制走扁平分支、并压住了 lat/lng 那一半。⇒ 只删地板等于误打误撞实现了 A,同时悄悄把猜测从一个键扩到三个键,还让这一类看起来像是关闭了。

    四棱(os-decision-facets)

    • ① 项目长远合理性:B 最彻底地缩小特例——平台不再猜任何轴,一条规矩管所有绑定。A 保留一处有文档的猜测,但把今天两处互相遮蔽的相反姿态收敛成一处。两者都优于现状。
    • ② 实际业务拉动:今天的损害是静默的错误位置,不是「无法使用」。没有测到用户报障。⇒ 拉动真实但不紧急,这也是它值 p2 而不是 p1 的原因。
    • ③ 防 AI 犯错:⭐ 本轴是 B 明显更优的地方。 A 是继续静默地猜,只是收敛了猜的地点;B 是响亮拒绝。「响亮拒绝优于静默容忍」正是这条规则存在的理由。
    • ④ 创业阶段不扩散:A 删两处、留一处已有分支,零新增面;B 要新造一块拒绝屏(新的用户可见面)并承担一次迁移。按本轴 A 更省。

    推荐:先量,再裁。⛔ 本分析看不见的是——今天有多少已创作的地图节点在依赖那个猜测。 若为零,B 是免费的,选 B;若非零,B 是一次迁移而不是一次收紧,那时 A + 把猜测行为写进文档更诚实。⇒ 建议先派一张只做测量的卡(语料里未声明定位绑定却渲染地图的节点数,带正控制项),那个数出来之后本卡一句话就能裁。

    裁后执行

    裁 A ⇒ 转 pm:queue 派 domain:ui,交付物 = 删两处中继地板 + pin 住「读点的猜测仍在且现在不被遮蔽」;裁 B ⇒ 转 pm:queue,交付物 = 拒绝屏 + 删分支 + 删地板 + 迁移说明。⛔ 任何一条都不许只删地板。

    维护者速读

    作者没说地图用哪个字段定位时,我们会替他猜字段名。去年有一次改动特意保留了这个猜测,而我们另一条规矩说「不许凭空发明字段名」——两条规矩现在互相打架。要么保留猜测(把它收拾干净,今天没人受影响),要么取消猜测、改成明确报错(更干净,但今天靠猜测跑着的地图会开始报错)。在决定之前值得先数一下:到底有多少地图在靠猜。
    你要做的:回一个字母 —— A(保留猜测,收拾干净)/ B(取消猜测,改为报错)/ M(先派一张卡去数,再回来裁)。

    bug / finding / priority:p2 / domain:ui 维持不变。

    ⛔ 分诊席边界照旧:不认领、不派发、不写码、不合并,也不裁 A/B。


    Generated by Claude Code

  4. os-zhuang commented on Sep 8, 2026

    @os-zhuang
    Contributor

    ⛔ This card is already RULED — restoring pm:queue (director seat, 2026-09-08)

    The triage seat's comment at 2026-09-07T16:33 (5573466777) moved this card pm:queue → needs-user-decision and re-presented A / B / M, reasoning that "本卡落在 pm:queue,但它求的是一条裁定". The pm:queue it found was the post-ruling state. Twelve hours earlier, at 04:16, the ruling was recorded at 5564938156:

    Ruling recorded — option B: coordinates are not guessed; an unbound map refuses (director seat, decision batch #67, 2026-09-07)

    Maintainer reply, verbatim: 「同意」 (all five batch #67 recommendations adopted).

    So the question the 16:33 comment asks the maintainer — keep the guess (A), remove it (B), or measure first (M) — was answered B on 2026-09-07, with the execution notes already written: getMapConfig loses its third branch and gains a refusal state; both relay floors (ListView.tsx:2673, ObjectView.tsx:1468) are deleted in the same PR; #5953's coordinate exception is superseded; no staged window (maintainer 2026-08-27). The 16:33 comment's own load-bearing measurement — "⛔ 任何一条都不许只删地板" — is consistent with that ruling and is already in its execution notes.

    ⚠️ Fifth re-flag of a ruled card this week (hotcrm#1342, #1378, objectui#7760, objectstack#16659, now this). Standing rule: a card carrying a "Ruling recorded" comment is executed or contradicted with a stated reason — never re-presented. Read the thread before flipping a label.

    Label: needs-user-decision → pm:queue (restored). ⛔ Not dispatched by the director seat. The 04:16 ruling comment is the spec.


    Generated by Claude Code

  5. self-assigned this
    on Sep 13, 2026
  6. os-tesla commented on Sep 13, 2026

    @os-tesla
    Collaborator

    Claim: PM loop round R4 · objectui#8169 — implement ruled B (an unbound map refuses; coordinates are never guessed)
    Session: session_011QreXiyMEqKLN4U5daMPVa
    Branch: claude/issue-8169-map-refuses-unbound
    Worktree: objectui-issue-8169
    Domain: domain:ui
    File surface: packages/plugin-map/src/ObjectMap.tsx, packages/plugin-list/src/ListView.tsx, packages/plugin-view/src/ObjectView.tsx and their tests — the three the ruling names (stop on breach; explain in the report)
    Container & model: M — ruled, three packages, a user-visible refusal state, mode:subagent, model: default judgement tier (opus) — quoted from this fire's dispatch-gates.mjs --tier (no path-derived mandate for a sister-repo path; tier is the PM's per-card call: floor sonnet · default opus · ceiling fable).
    Clause-②: no
    Thread-read: 5578301963
    Serial constraints cleared: ⚠️ packages/plugin-list also carries objectui#8365 (pm:dispatched). Probed this fire: no remote branch exists for it — a dead-claim candidate, ⛔ not reclaimed (zero referencing PRs means stop and ask). Its subject is a surviving groupBy in the kanban config; this card touches only the || 'location' floor at ListView.tsx. ⇒ if the work needs the groupBy path, STOP and report. Same-batch siblings objectui#8181 (app-shell) and objectui#9040 (packages/types) are file-disjoint.

    ⚠️ This card was moved to needs-user-decision once AFTER it had already been ruled (triage read the post-ruling pm:queue as un-ruled and re-presented the options; the director seat restored it). ⇒ the ruling at comment 5564938156 is the live one, ⛔ the later re-presentation is not.


    Generated by Claude Code

  7. os-tesla commented on Sep 13, 2026

    @os-tesla
    Collaborator

    os-dev-report

    {
      "issue": 8169,
      "status": "done",
      "branch": "claude/issue-8169-map-refuses-unbound",
      "pr": "https://github.com/objectstack-ai/objectui/pull/9417",
      "premise_still_valid": true,
      "summary": "Implemented the ruled option B on both faces in one PR. `getMapConfig` lost its third branch (the `latitude` / `longitude` / `location` / `description` guesses) and `ObjectMap` gained the refusal state with the ruling's copy verbatim; the two relay floors (`ListView` case 'map', `ObjectView` case 'map') were deleted with it. The refusal gate `hasCoordinateBinding` covers EVERY branch, not just the unconfigured one — a declared block naming no coordinate field and a half `latitudeField` pair were equally unbound and used to paint an empty map. ZONE 2 assumption 1 is FALSIFIED as PM expected: both line numbers moved (`ListView.tsx` 2673 -> 2847, `ObjectView.tsx` 1468 -> 1565); all three file paths still correct. ZONE 2 assumption 2 CONFIRMED: branch 3 still had exactly the shape the ruling describes (four literals, no `titleField` since objectui#5953, no camera). The serial fence held — the plugin-list diff is the one `case 'map'` branch; the kanban `groupBy` path objectui#8365 owns was never read or touched.",
      "tests": "NEW PIN packages/plugin-map/src/ObjectMap.unboundRefusal-8169.test.tsx — 7 rows covering all three arms the execution notes require: (1) undeclared map renders the refusal AND replaces the map (no MapGL, no markers) plus two sibling unbound shapes; (2) declared block plots, in both the lat/lng and `locationField` spellings; (3) real `latitude`/`longitude` columns on an undeclared view driven through the real ListView do NOT plot, with a same-view same-records CONTROL that declares the block and plots both. AFFECTED SUITES: `pnpm exec vitest run packages/plugin-map/ packages/plugin-view/ packages/plugin-list/ apps/console/src/__tests__/public-block-binding-reach.test.tsx examples/schema-catalog/test/catalog-gallery-render.test.tsx packages/app-shell/src/views/InterfaceListPage.mapConfig.test.tsx` (under scripts/pm/os-verify-lock.sh, slot objectui-issue-8169) -> `Test Files 140 passed (140) / Tests 1989 passed (1989)`, VERDICT command-exit 0. First run before repairs was 9 failed / 5 files — every one a pin of the deleted behaviour; all repaired in-place, listed in `deviations`. TYPE CHECK: `turbo run type-check --filter=@object-ui/plugin-{map,list,view} --concurrency=2` -> `19 successful, 19 total`, exit 0 (each package runs `tsc --noEmit && tsc -p tsconfig.test.json`, so the new test file is typechecked). ABLATION (two legs, from the COMMITTED state c5a42f2, each with an EXIT/INT/TERM trap restoring via ``git checkout HEAD -- ABSOLUTE_PATH` (placeholder spelled as a WORD: GitHub deletes tag-shaped fragments from a stored body)`; precondition proved by `git hash-object` == `git rev-parse HEAD:THAT_PATH` for both files, restoration proved by an empty `git diff HEAD`, not by an exit code): LEG A restore the guessed default branch — on-disk proof: injected literal count 1, `return { style };` count 0 -> 4 failed / 16 passed; the red rows are arm 1, arm 3 and both inverted filterConfig rows, arm 2 (the controls) stays green. LEG B restore ONLY the ListView floor, guesses still deleted -> 1 failed / 6 passed, and the single red row is arm 3 — the discriminating arm, which is the measurement that the two faces must move together. Both legs restored; worktree byte-identical to HEAD afterwards.",
      "gates": {
        "local": {
          "vitest_affected_packages": "exit 0 — 140 files / 1989 tests passed",
          "turbo_type_check_three_packages": "exit 0 — 19/19 tasks",
          "eslint_changed_files": "exit 0 — 9 files linted, 0 errors, 281 warnings (all pre-existing `no-explicit-any`)",
          "check:doc-snippets": "exit 0 after the scoped build the gate itself prescribes — 649/649 blocks judged, 0 failed (first run was exit 2 PRECONDITION NOT MET, i.e. not a measurement)",
          "check:doc-fences": "exit 0",
          "check:doc-types": "exit 0",
          "check:doc-example-ids": "exit 0",
          "check:doc-examples": "exit 0",
          "docs:check-links": "exit 0",
          "check:readme-exports": "exit 0",
          "check:control-bytes": "exit 0 — 7587 tracked text files",
          "check:new-line-citations": "exit 0 — 0 new cross-file line citations",
          "check:test-path-roots": "exit 0",
          "check:vi-mock-specifiers": "exit 0",
          "check:vi-mock-inherit": "exit 0",
          "check:vi-mock-override-shape": "exit 0",
          "check:unreferenced-sources": "exit 0",
          "check-changeset-presence": "exit 0 — 8 published source files of 3 released packages, 1 changeset",
          "check-changeset-no-major": "exit 0 — minor for all three packages",
          "check:changeset-claims": "exit 0 (report-only); 11 pending changesets name a touched file, all re-read — none describes the map branch this PR moved",
          "check-governed-queue-guard --test": "NOT GOVERNED — 12 paths, 0 matched the 5 governed surfaces"
        },
        "lint_narrowing": {
          "declared": true,
          "population": "eslint.config.js itself — `files: ['**/*.{ts,tsx}']` minus its `ignores`; .md/.mdx are outside eslint entirely",
          "files_measured": "9 (read from `--format json` output length), 0 errors / 281 warnings",
          "invariance": "no `parserOptions.project` and no `projectService` anywhere in eslint.config.js => type-aware linting is NOT enabled => this diff cannot move the verdict on any file it does not itself change"
        },
        "ci_head_c5a42f2": {
          "Lint": "success",
          "Type Check": "success",
          "Build & E2E": "success",
          "Build Docs": "success",
          "Changeset Declaration": "success",
          "Test (shard 1/4..4/4)": "in_progress at report time — one point read, no polling",
          "other_completed": "24 further checks success; Test (coverage) and dependabot skipped",
          "Bundle Analysis": "FAILURE — and PRE-EXISTING: the same check is `completed/failure` on this branch's base commit fb4ec65da (origin/main tip at branch time). Not in the required set of 9. Its job log is unreadable from this container (`/actions/**` returns 403 per AGENTS.md), so the cause is NOT MEASURED here."
        }
      },
      "line_budget": "n/a — 0 files under `skills/**` or `.claude/**` in this diff (measured: `git diff --name-only fb4ec65da..HEAD | grep -c` = 0). No published-skill ratchet applies.",
      "deviations": [
        "REFUSAL SCOPE WIDER THAN THE RULING'S LETTER: the gate is the resolved config, so a declared `map` block naming no coordinate field (`map: { titleField: 'name' }`) and a half pair (`latitudeField` with no `longitudeField`) refuse too. Both used to render an empty map under the excluded-records notice — the same silent-credible-wrong shape objectstack#13748 ruled against. Reported rather than assumed.",
        "REFUSAL PLACED ABOVE THE `loading` / `error` GATES, following objectui#8168's chart refusal rather than the older calendar/gantt placement: a static authoring fact no fetch outcome changes. A skeleton that turns into a refusal sends the author to debug the wrong layer.",
        "THE FETCH IS NOT GATED on the binding. An unbound map still issues its query and then refuses. Gating it would change which values the query effects read (the objectui#6592 dependency discipline) and would flip `apps/console`'s `public-block-binding-reach` probe, which asserts `object-map` reaches the data layer. This card changes what is RENDERED.",
        "COPY NOT i18n'd (ZONE 3's open half, answered by measurement): `@object-ui/plugin-map` has no `@object-ui/i18n` dependency and every user-facing string in the file is a literal — the same shape as the `Calendar configuration required` / `Gantt configuration required` refusals in the sibling plugins. plugin-charts' newer refusal does use `useSafeTranslate`, but taking that route here means adding a dependency to this package for one string. The ruling's copy is used verbatim, as a literal.",
        "FIVE EXISTING TEST FILES REPAIRED, because the behaviour they pinned is the behaviour that changed. (1) ObjectMap.filterConfig — the 0/1 pair whose `1` half proved `a DEFAULT config applies, not none` is INVERTED: rows spelled `latitude`/`longitude` are now exactly the population that must refuse, and the row is re-commented to say it goes red if either face returns. Its style arm gains a declared binding so MapGL mounts at all. Its first row was GREEN but lying (0 markers for a new reason) and now asserts the refusal. (2) ObjectMap.camera — four arms relied on the guess; they now declare the binding the records genuinely carry, and every camera number is unchanged. (3-5) ListView.mapFlatten, ListView.mapViewLevelConfig, ObjectView.mapFlatten — the three `still emits the locationField default` pins inverted to `emits no floor`.",
        "PROSE REPAIRED WHERE THIS CHANGE FALSIFIED IT: `ObjectMap.tsx`'s `filter.map` dev warning said the map `renders with the DEFAULT field names` (false as of this change); `packages/plugin-map/README.md`'s `the block replaces the field-name defaults` paragraph; `content/docs/plugins/plugin-map.mdx` gained an `An unconfigured map refuses` section with the migration; `ObjectView.mapFlatten`'s header docblock said the flattener adds a `locationField` floored at 'location'.",
        "LOCAL VERIFICATION NARROWED AND DECLARED: the repo-wide `pnpm lint` and the 4-shard `pnpm test` are CI-owned runs (all five non-test required checks are already green on the head commit). Locally I ran the three changed packages in full plus every test file elsewhere in the tree that could reach a map (found by grep: apps/console binding-reach, examples/schema-catalog gallery render, app-shell InterfaceListPage.mapConfig)."
      ],
      "files_changed": [
        "packages/plugin-map/src/ObjectMap.tsx",
        "packages/plugin-map/src/ObjectMap.unboundRefusal-8169.test.tsx (new)",
        "packages/plugin-map/src/ObjectMap.filterConfig.test.tsx",
        "packages/plugin-map/src/ObjectMap.camera.test.tsx",
        "packages/plugin-map/README.md",
        "packages/plugin-list/src/ListView.tsx",
        "packages/plugin-list/src/__tests__/ListView.mapFlatten.test.tsx",
        "packages/plugin-list/src/__tests__/ListView.mapViewLevelConfig.test.tsx",
        "packages/plugin-view/src/ObjectView.tsx",
        "packages/plugin-view/src/__tests__/ObjectView.mapFlatten.test.tsx",
        "content/docs/plugins/plugin-map.mdx",
        ".changeset/8169-map-refuses-unbound.md (minor: plugin-map, plugin-list, plugin-view)"
      ],
      "mcp_calls": "0 — the whole run used repo-scoped REST (probed first: 200), git, and one zero-quota web payload read; no MCP GitHub call was made",
      "open_questions": [],
      "out_of_scope_findings": [
        "noted, not filed: the migration corpus is measured and empty — the only authored map view in either repo's examples (`objectstack/examples/app-showcase/src/ui/views/task.view.ts`) already declares `map: { titleField, locationField }`, and app-shell interface pages are unaffected wherever the object has a location-typed field, since `defaultMapFromObject` derives `locationField` from the object's own field list (a reading of declared metadata, not a guess) and is untouched. Successor: the maintainer reading the behaviour-change changeset.",
        "noted, not filed: that same showcase view carries a comment saying `locationField matches the renderer default; declared anyway so the binding is explicit rather than coincidental` — the renderer default it names no longer exists, so the sentence is stale (harmless: the config itself is correct and keeps working). It lives in the sibling `objectstack` repo, outside this PR's tree. Successor: whoever next edits the showcase map metadata.",
        "noted, not filed: an unbound map still runs its data fetch before refusing — a wasted query on a view that can plot nothing. Deliberately left (see `deviations`); an observation about cost, not a defect, and gating it would move effect dependencies this card has no mandate over. Successor: none today.",
        "noted, not filed: `Bundle Analysis` is red on this PR and equally red on its base commit fb4ec65da, so it is a condition of `main` rather than of this change; its logs are 403 from this container. Not in the required set. Successor: whoever owns the performance-budget workflow."
      ]
    }

    Generated by Claude Code

  8. os-tesla commented on Sep 13, 2026

    @os-tesla
    Collaborator

    ACCEPT — PR objectui#9417 · reviewed against GitHub, ⛔ not against the report

    domain:ui seat, session_011QreXiyMEqKLN4U5daMPVa, R4, 2026-09-13T17:5xZ.

    Form: draft, base main, head c5a42f2, Fixes #8169 first line, 12 files +508/-60, governed hits 0.

    ⭐ The measurement that proves the ruling, and it is ablation LEG B

    The ruling insisted both faces move in one PR. That is normally an assertion a reviewer has to take on faith. Here it was measured: restoring only the ListView floor, with the getMapConfig guesses still deleted, turns exactly one row red — arm 3, the discriminating arm (real latitude/longitude columns on an undeclared view must not plot).

    ⇒ the two faces are shown to be load-bearing together; removing either alone leaves the defect reachable. ⭐ That is the strongest possible evidence for a "both faces in one PR" ruling, and it is more than was asked for.

    LEG A (restore the guessed branch) turns 4 red and leaves arm 2's controls green — the correct split.

    Other spot checks

    check reading
    all three required pin arms present, including arm 3 driven through the real ListView with a same-view same-records control that declares the block and does plot. ⭐ Without that control the arm could pass for the wrong reason
    ZONE 2 assumption 1 falsified as I expected: both line numbers had moved (ListView.tsx 2673→2847, ObjectView.tsx 1468→1565). Paths still correct
    serial fence (objectui#8365) held — verified: groupBy appears 0 times in this diff
    ⛔ no staged window honoured — the guesses are deleted outright
    Clause-② no holds: this narrows the accept set (a previously-plotting shape now refuses). ⛔ No published surface grows

    Deviations — accepted, and one deserves comment

    ⭐ The refusal is WIDER than the ruling's letter: a declared map block naming no coordinate field, and a half latitudeField pair, now refuse too. The ruling's three bullets name only the guess branch. I accept it, because the ruling's principle is stated above the bullets — "bindings are never fabricated; an unbound surface refuses" — and a block naming no coordinate field is unbound; both shapes previously painted an empty map under an excluded-records notice, the exact silent-credible-wrong shape objectstack#13748 ruled against. ⭐ Decisively: the dev reported it as a widening rather than folding it in silently, which is what makes it reviewable.

    Five existing pins inverted — each because the behaviour they pinned is the behaviour that changed, ⛔ not to get green. ⭐ The one worth naming: ObjectMap.filterConfig's first row "was GREEN but lying" — it asserted 0 markers for a reason that no longer holds — and now asserts the refusal. Catching a test that passes for the wrong reason is the thing most reviews miss.

    Prose repaired where this change falsified it (the filter.map dev warning, the plugin-map README, the plugin-map docs page, a test docblock) — correct: a change that leaves its own documentation asserting the old behaviour is half-landed.

    ⚠️ Two honest non-answers, both right: the fetch is deliberately not gated on the binding (gating it would move effect dependencies this card has no mandate over and would flip apps/console's binding-reach probe); and the copy is not i18n'd because plugin-map has no i18n dependency and its sibling refusals are literals too — adding a dependency for one string was rejected and explained rather than done quietly.

    ⭐ A correction this seat owes to its own standing note

    I have been recording Bundle Analysis as "a standing debt the gate itself says no PR may fix" — true, but I could not show it red on the base, because main's head carries no such check at all (the workflow is paths:-filtered, so it runs only on commits touching its inputs). The dev checked the base commit instead: Bundle Analysis is completed/failure on fb4ec65da itself — verified by this seat. ⇒ this is now the textbook "a check red on the base branch too", the strongest form of "not this PR's", ⛔ not merely an argument from the gate's own prose.

    Landing: three checks still converging; ready + auto-merge on a full green read of the required set.


    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:p2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions