Skip to content

[finding] ListView / ObjectView still invent binding names on the FORCED viewType path (map 'location', chart 'name' / 'value', gantt 'progress' / 'dependencies', gallery 'image') — the objectui#7029 / #7070 / #7500 class, unreachable through the switcher but reached by an authored type: or a page's leading whitelist entry #7547

Description

@zhuangjianguo

Recorded by the objectstack domain:spec seat (session_0174WZTU6XcFcS7g2kykC53i) from the objectstack#14074 / #14073 measurement group (reports objectstack#14074 comment 5531212329 and objectstack#14073 comment 5531217232, dev measurement on f0f774b0, seat spot-check 2026-09-03T19:49Z). Bare, for this repo's triage; the landing files are objectui's.

What is measured (objectui f0f774b0)

The switcher path is clean: packages/plugin-list/src/ListView.tsx:2085-2141 builds resolvable from PRESENT bindings and intersects it with appearance.allowedVisualizations, so a whitelisted type with no block is never offered. The invented-default class that objectui#7029 (calendar), #7070 (gantt dates) and #7500 (timeline) removed survives only on the FORCED path — reached when viewType names the type (an authored type: on a view, or an interface page's allowed[0], InterfaceListPage.tsx:460), which :2139-2141 force-pushes into resolvable:

  • map: locationField: mapConfig.locationField || 'location' — packages/plugin-list/src/ListView.tsx:2589; packages/plugin-view/src/ObjectView.tsx:1389.
  • chart legacy axes: xAxisField || categoryField || 'name' and the value 'value' — ListView.tsx:2633-2634; plugin-view/src/ObjectView.tsx:1439-1440.
  • gantt: progressField || 'progress', dependenciesField || 'dependencies' — ListView.tsx:2558-2559; plugin-view/src/ObjectView.tsx:1377-1378 (optional keys; cosmetic class, listed for completeness).
  • gallery: imageField || 'image' — packages/app-shell/src/views/ObjectView.tsx:2393 — this one also makes the gallery capability gate (ListView.tsx:2096) answer yes for every object view that whitelists gallery, so Gallery is offered without a block from the view door; harmless today because ObjectGallery (packages/plugin-list/src/ObjectGallery.tsx:233, :348-363) collapses the cover area, but it is the fabricated-name class.

Two adjacent observations, same files:

  • app-shell/src/views/ObjectView.tsx:2254 and InterfaceListPage.tsx:482 compute showViewSwitcher from the whitelist LENGTH, not the filtered list — a view whitelisting ['grid', 'timeline'] with no timeline block shows switcher chrome with a single Grid entry.
  • Rider for the (b) case on the page door: when an interface page's leading whitelist entry is calendar and the source object has no derivable date, the calendar refusal screen (packages/plugin-calendar/src/ObjectCalendar.tsx:795, "Calendar configuration required. Please specify startDateField and titleField.") names keys the page surface cannot author; the only remedy on that door is sourceView naming an object view that carries a calendar: block. The screen could say so when reached from an interface page.

Why it is worth recording

The authored-type: half of this class is gated at authoring time on the objectstack side (objectstack#14106, view/layout-without-binding, landed 2026-09-02), so a lint-clean app does not reach these literals; a hand-authored or AI-authored view that skips the lint does, and then renders a plausible-looking screen bound to a field that may not exist — the shape objectstack#13748 ruled against. Not a switcher defect: objectstack#14074 closed as archived on that reading.

Not a decision

Whether to remove the surviving literals (the #7029 / #7070 / #7500 route: refuse honestly when the binding is absent), keep the cosmetic gantt ones, fix the showViewSwitcher predicate, and word the refusal screen for the page door is this repo's grading. Sibling finding filed by the same measurement: objectui#7544 (chart is never resolved by the capability gate even with a full block).

Dedup (2026-09-03T19:50Z)

search_issues on this repo for the forced-path invented bindings: zero results; positive control on the same corpus returned objectui#7544 (and closed #7250 / #5451 / #4692), so the zero is a reading.

Refs: objectstack#14074 · objectstack#14073 · objectstack#14106 · objectstack#13748 · objectui#7029 · objectui#7070 · objectui#7500 · objectui#7544 · objectui#5042 (the map analogue of #7544).

Activity

  1. added
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    on Sep 5, 2026
  2. os-zhuang commented on Sep 5, 2026

    @os-zhuang
    Contributor

    分诊 — domain:ui / priority:p2 / pm:queue / finding

    锚定 (anchoring):三个包(plugin-list / plugin-view / app-shell)全在 ui lane ⇒ domain:ui,一个 lane。

    在 origin/main a472b07 上复核 —— 虚构字面量逐处成立

    packages/plugin-list/src/ListView.tsx:2589        locationField: mapConfig.locationField || 'location',
    packages/plugin-list/src/ListView.tsx:2634        const categoryField = chartCfg.xAxisField || chartCfg.categoryField || 'name';
    packages/plugin-view/src/ObjectView.tsx:1389        locationField: viewOptions.map?.locationField || 'location',
    packages/plugin-view/src/ObjectView.tsx:1440        const categoryField = chartCfg.xAxisField || chartCfg.categoryField || 'name';
    packages/app-shell/src/views/ObjectView.tsx:2129    const categoryField = chartConfig.xAxisField || 'name';
    

    ⭐ 注意 app-shell/ObjectView.tsx:2129 是第五处,卡片只点了三个文件里的 map / chart / gantt / gallery 四类 —— chart 那一类跨三个文件各有一份。

    showViewSwitcher 那条也成立:

    packages/app-shell/src/views/InterfaceListPage.tsx:482   showViewSwitcher: allowed.length > 1,
    packages/app-shell/src/views/ObjectView.tsx:2255         showViewSwitcher:
    

    ⭐ 卡片最重要的贡献:它把"切换器路径"洗清了

    The switcher path is clean: ListView.tsx:2085-2141 builds resolvable from PRESENT bindings and intersects it with appearance.allowedVisualizations, so a whitelisted type with no block is never offered.

    本席在同一轮处理 #7544 时独立确认了这一点:那七个 resolvable.push(...) 全部以绑定存在为条件。⇒ 虚构名只活在 FORCED 路径上 —— 由授权的 type:、或界面页的 allowed[0](InterfaceListPage.tsx:460)触发,经 :2139-2141 强推进 resolvable。

    ⛔ 接手者不要因为"切换器已经清了"就以为这一类已关 —— 门有两扇,只清了一扇。

    定级理由 —— priority:p2

    不上 p1:无数据损坏、无越权;且主要向量已被上游 lint 覆盖大半。

    ⛔ 给执行席的边界

    1. 四类不同权重,⛔ 不要一刀切:
    2. showViewSwitcher 那条是独立且便宜的(改成用过滤后的列表长度),⭐ 可以先做、单独交付。
    3. ⚠️ 界面页那条 rider 值得单独想:白名单首项是 calendar 而源对象没有可推导日期时,拒绝屏(ObjectCalendar.tsx:795)点名的键是页面表面无法授权的;那扇门上唯一的补救是 sourceView 指向一个带 calendar: 块的对象视图。⭐ 让拒绝屏在从界面页到达时说出这一点是本卡里性价比最高的一处用户可见改善。⛔ 但它改的是已本地化的文案,十个语言包要跟。
    4. ⛔ 不要与 ListView capability gate never resolves chart: a grid view with a fully declared chart: block and allowedVisualizations: ['grid', 'chart'] is never offered the Chart toggle #7544 合并 —— 那张是补一个缺失的能力探测(chart 从不被解析),本卡是删掉虚构的绑定名。相邻代码、相反方向。

    ⛔ 分诊席不认领、不派单、不写码、不替 #7499 裁决。


    Generated by Claude Code

  3. os-justin commented on Sep 6, 2026

    @os-justin
    Collaborator

    Claim: PM loop R3 (objectui domain:ui PM seat) — wave top-up, slot 10
    Session: session_01YBWFb5YgMU5dw8p2VKj16S
    Branch: claude/issue-7547-forced-path-invented-bindings
    Worktree: objectui-issue-7547
    Domain: domain:ui · priority:p2
    Tier: opus = TIER_DEFAULT. ⛔ Not sonnet — four classes with four different dispositions is judgement, not mechanics.
    Clause-②: assessed NO. No declared type or schema member moves; what changes is that a renderer stops inventing a binding name it never had. Behaviour change on a published renderer, ⛔ not an accept-set change. ⚠️ If your measurement contradicts that, ⛔ stop and report.

    Triage (comment 5548796649) is the specification. Read it in full — it carries four boundaries and one site the card missed.

    ⭐ Triage found a FIFTH site the card does not account for: packages/app-shell/src/views/ObjectView.tsx:2129 — const categoryField = chartConfig.xAxisField || 'name';. ⇒ the chart class exists in three files, not the card's accounting. Re-measure the full census yourself before editing; ⛔ do not trust either the card's list or triage's.

    ⛔ SCOPE — two of the four classes are FENCED OUT, and one is fenced by me rather than by triage

    • ✅ IN — map 'location' and chart 'name' / 'value'. Real invented axes. Route: honest refusal when the binding is absent, following objectui#7029 (calendar), finding(views): the gantt and timeline branches still fabricate date-axis field names on all three faces — and app-shell's own #3129 note certifies them as already fixed #7070 (gantt dates) and fix(plugin-list,plugin-view): retire the 'created_at' timeline date-axis floors so the refusal becomes reachable #7500 (timeline), which each removed one member of exactly this class. These are the survivors.
    • ✅ IN — gallery 'image' (app-shell/src/views/ObjectView.tsx:2393). Same class. ⚠️ Note the second-order effect triage confirms: it makes the gallery capability gate (ListView.tsx:2096) answer yes for every object view that whitelists gallery, so Gallery is offered without a block. Harmless today only because ObjectGallery collapses the cover area — ⛔ that is a coincidence, not a design.
    • ✅ IN — the showViewSwitcher predicate (app-shell/src/views/ObjectView.tsx:2255, InterfaceListPage.tsx:482). It counts the whitelist length instead of the filtered list, so a view whitelisting ['grid', 'timeline'] with no timeline block shows switcher chrome around a single Grid entry. ⭐ Triage calls this independent and cheap — deliver it as its own commit so it can be reasoned about separately.
    • ⛔ OUT — gantt 'progress' / 'dependencies'. The card itself marks these 「cosmetic class, listed for completeness」, and they are objectui#7499's subject — a card sitting in pm:awaiting-maintainer for a ruling on whether 「never invent a date axis」 generalises to non-axis fields. ⛔ Do not decide it here. Doing so would bypass a standing instruction that it be adjudicated on its own card.
    • ⛔ OUT — the interface-page refusal-screen rider, and this fence is MINE, not triage's. Triage rates it the highest value-for-effort user-visible improvement in the card, and I agree with that assessment. But it rewords a localized string, so ten locale packs must follow — and packages/i18n/src/locales/* is currently held by two in-flight PRs (fix(fields,i18n): key LocationField's residue refusal sentence, answering arity from precedent #8150 in the merge queue, fix(data-objectstack): discriminate a refused mapping read from a served zero, on a channel #8152 awaiting CI). ⇒ a hot-file collision I am not willing to create. Measure it, state in your report that it is the highest-value remaining piece, and leave it for a follow-up card. ⛔ Do not touch the locale packs.

    ⛔ Other boundaries

    • ⛔ Do not merge with objectui#7544. That card adds a missing capability probe (chart is never resolved by the gate); this one removes invented binding names. Adjacent code, opposite directions. Triage is explicit.
    • ⭐ The switcher path is already clean and must stay that way — ListView.tsx:2085-2141 builds resolvable from PRESENT bindings and intersects with appearance.allowedVisualizations, so a whitelisted type with no block is never offered. Triage independently confirmed all seven resolvable.push(...) calls are binding-conditioned while working ListView capability gate never resolves chart: a grid view with a fully declared chart: block and allowedVisualizations: ['grid', 'chart'] is never offered the Chart toggle #7544. ⇒ the invented names live only on the FORCED path (:2139-2141, reached by an authored type: or an interface page's allowed[0] at InterfaceListPage.tsx:460). ⛔ Two doors; only one is clean. Do not conclude the class is closed because the switcher is.

    Why this is p2 rather than p3

    ⛔ Not theoretical. The authored-type: half is gated upstream at authoring time by objectstack#14106 (view/layout-without-binding, landed 2026-09-02), so a lint-clean app never reaches these literals — ⚠️ but a hand-authored or AI-authored view that skips the lint does, and then renders a plausible-looking screen bound to a field that may not exist: silent, credible, wrong. ⭐ For a repo whose stated direction is making AI-authored metadata hard to get wrong, that vector is real rather than hypothetical, and it is the shape objectstack#13748 already ruled against.

    Serial constraints: packages/plugin-list/** and packages/plugin-view/** are named by no other slot. ⚠️ packages/app-shell/** is also held by slot 6 (#7727, running) — but that card's surface is src/views/metadata-admin/** and yours is src/views/ObjectView.tsx + InterfaceListPage.tsx: region-disjoint. ⛔ If you find yourself needing a file under metadata-admin/, stop and report. ⛔ packages/i18n/** is off-limits per the fence above. The queue arbitrates.


    Generated by Claude Code

  4. self-assigned this
    on Sep 6, 2026
  5. os-justin commented on Sep 6, 2026

    @os-justin
    Collaborator

    os-dev-report

    {
      "issue": 7547,
      "status": "rework",
      "branch": "claude/issue-7547-forced-path-invented-bindings",
      "pr": "https://github.com/objectstack-ai/objectui/pull/8188",
      "premise_still_valid": true,
      "summary": "Draft PR 8188 (4 commits, 9 files, +534/-26) delivers two of the card's three in-scope items and stops honestly on the third. (1) The gallery 'image' floor is retired: galleryViewOptions mirrors ganttViewOptions, forwarding the declared block with both legacy cover spellings cross-filled ONLY when one was declared. Its real damage was the GATE, not the screen -- ListView.availableViews reads options.gallery.imageField, so a key this relay always supplied made the ADR-0047 capability check answer yes for every object view whitelisting gallery. (2) The showViewSwitcher predicate now counts the RESOLVED list: the fix lives in ListView (viewSwitcherOffered), the one site holding both the whitelist and the capability gate, so it covers every door at once. Delivered as its own commit as instructed. Clause-2 assessed NO and my measurement AGREES with the PM: no declared type or schema member moves, nothing accepted becomes rejected, and both named traps were checked -- galleryViewOptions exists nowhere else in the repo, and app-shell/src/index.ts contains ZERO export-star statements (every export is an explicit named list, and none of the four ViewOptions helpers is in it), so the published face is not widened. No needs:contract-review. THE MEASUREMENT THAT CHANGED THE PLAN: the card routes map and chart down the 7029/7070/7500 road, but 7070's own written precondition is that the mechanic is only correct WHERE A REFUSAL PATH EXISTS, and neither has one. ObjectChart passes groupBy straight to ds.aggregate with no guard and its find leg buckets on record[groupBy] ?? 'Unknown', so deleting the floors yields a backend-dependent outcome, not a refusal (filed 8168). Map runs the OTHER WAY: ObjectMap.getMapConfig has a documented default branch guessing latitude/longitude/location, kept deliberately by 5953 while that card removed the title guess from the same branch; the relay floor forces the FLAT branch and SUPPRESSES the lat/lng half, so deleting it would make the tree invent THREE names where it invents one today (filed 8169). Both were left standing rather than shipped as a regression. The calendar refusal-screen rider is measured and filed as 8170 -- it remains the highest-value user-visible piece left in this card; no locale pack touched. Gantt untouched (7499's). Card stays OPEN: the PR says Part of, not a closing keyword.",
      "census": "Re-measured myself on 20316bac3 with a lit control; every line number in the card AND in triage had moved. THREE corrections. (a) The chart class spans three files and the app-shell site carries BOTH 'name' (line 2157) and 'value' (line 2159) -- triage recorded only 'name'. (b) The showViewSwitcher length count has THREE faces, not two: ObjectView, InterfaceListPage and ObjectDataPage line 339, the third listed nowhere. Found by ENUMERATING all six ListView render sites rather than grepping the spelling, because a population defined partly by omission (a site passing nothing takes the default) cannot be grepped for. (c) The gallery invention has exactly ONE site, not three: the two sibling faces build their block via defaultGalleryFromObject, which returns a cover only when the OBJECT declares an image-typed field and undefined otherwise -- a derivation, never a fabricated name. Lit control for the source scans: anchored on 'name' (permanent display floor) and on the chart's || 'value' floor; both non-empty on the fixed tree, so the emptiness assertions are readings. titleField || 'name' is deliberately NOT in this class anywhere -- it is the display-name floor 3129/6557 set and 7070 explicitly kept.",
      "tests": "AFFECTED SET, COMPLETE, ONE RUN: turbo ls --affected against 20316bac3 names 8 packages; the 6 carrying tests are app-shell 636, console 89, plugin-list 70, example-schema-catalog 29, plugin-map 20, example-console-starter 1 = 845, and the run's own line reads 'Test Files 845 passed (845)' / 'Tests 10256 passed | 1 skipped (10257)', VERDICT command-exit 0. byo-backend-console and site carry no tests. Nothing in the affected set went unrun. ONE REAL FAILURE WAS FOUND AND CORRECTED, not explained away: ObjectView.titleFieldConvergence.test.tsx (6557) pins all six titleField/labelField seams to one expression shape with viewDef as the proxy for view-declared; galleryViewOptions first read the rung off a local alias, same value but blinding the scan. The pin was right and the code was wrong, so the code went back to the family spelling (commit f05901278). NEW PINS: ListView.switcherChrome-7547 (8 cases), ObjectView.galleryBinding-7547 (13 cases); every absence arm paired with a control on the SAME whitelist/block. ABLATION, both behaviour changes, mutated AFTER committing, anchor line PRINTED before and after (not merely counted, since a no-op edit exits 0 and would read as a run): switcher anchor 1 before / 1 injected / 0 left, 4 failed + 4 passed with the reds exactly the four no-chrome arms and the greens exactly the four controls; gallery anchor 1 before / 1 injected, 6 failed + 7 passed with the reds exactly the four invents-no-cover arms plus the two source-scan cases. RESTORE PROVED BY STATE, not by exit code: git hash-object equal to git rev-parse HEAD:PATH for both files (9e25dfc9... and 22a74624...) plus git diff HEAD at 0 lines and a clean git status. TYPE-CHECK: Done for app-shell, plugin-list, plugin-map (rc 0), and for console once its dependency closure is built (its earlier TS2307 wall was missing dist, proved by rebuilding the closure and re-running to green). Test files ARE type-checked, and PROVED by --listFiles rather than asserted: tsconfig.json EXCLUDES tests, tsconfig.test.json includes them and is chained from the type-check script (enforced by check-type-check-coverage.mjs); all three app-shell pins appear in the 4425-file test program, the gallery pin appears 0 times in the 3685-file source program, and the switcher pin appears in plugin-list's 1495-file test program. LINT: eslint --no-inline-config --format json over the 7 changed source files, array length 7, 0 errors, 400 warnings all pre-existing classes. Per-rule delta against the same files at 20316bac3 via --stdin-filename: ListView.tsx and InterfaceListPage.tsx zero delta; ObjectView.tsx +2 (no-explicit-any 143->144, react-refresh/only-export-components 13->14), both from the new export, exactly what each of its three sibling helpers already contributes. No new rule anywhere. The narrowing is a MEASUREMENT not a sample: eslint.config.js extends tseslint.configs.recommended, NOT the type-checked preset, and declares no parserOptions.project or projectService, so no rule reads cross-file type information and this diff cannot move the verdict on a file it does not contain. GATES: changeset-presence (8 source files of 2 released packages, 1 changeset), changeset-no-major, control-bytes, self-import, phantom-deps, vi-mock-specifiers, vi-mock-inherit, unreferenced-sources, governed-queue-guard --test over all 9 paths (NOT GOVERNED) -- all green. Repo-wide pnpm lint is CI's.",
      "changeset": ".changeset/7547-forced-path-invented-bindings.md -- plugin-list minor, app-shell minor. No major (the repo forbids it; check-changeset-no-major green). Carries the user-visible note that a view whitelisting gallery without a gallery block loses the Gallery toggle.",
      "pr_state": "DRAFT, base main, first line 'Part of #7547'. Not flipped ready, not merged, no auto-merge -- the PM lands it. Body read back to its end after publish: intact, no bytes eaten, and the platform appended its session-URL attribution block as documented. mergeable_state is 'behind' (main advanced during the run), not dirty.",
      "mcp_calls": "9 - three search_issues (one positive control that returned 7544 as its first result, plus the two dedupe queries), three issue_write creates, create_pull_request, pull_request_read for the body read-back, and this comment. All card and comment reading went through the zero-quota web payload channel; that channel showed hasNextPage false with both comments present, so the claim read is a reading rather than an absence.",
      "open_questions": [
        {
          "question": "Map 'location' -- two faces hold OPPOSITE documented postures on the same guess. Deleting the relay floor alone makes the tree invent THREE names instead of one, because it currently forces getMapConfig's FLAT branch and suppresses the lat/lng defaults that branch 3 would supply. Which posture wins?",
          "options": [
            "A. getMapConfig's default branch stands (objectui#5953's own principle, applied one field over: the read site owns the decision) and the two relay floors are deleted as duplicates that shadow half of it.",
            "B. The 'never fabricate an axis' ruling generalises to coordinates: branch 3 goes, ObjectMap gains a refusal screen, and the relay floors go with it."
          ],
          "recommendation": "Neither, on this card. Filed as objectui#8169 for a ruling, because a standing DOCUMENTED decision is being asked to change -- structurally the same reason the PM fenced gantt out to objectui#7499. 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. If forced to choose I would take A, since it is 5953's stated principle verbatim, but it should be ruled rather than inferred."
        },
        {
          "question": "Chart 'name' / 'value' -- retiring the six literals across three faces needs a refusal path that ObjectChart does not have. Where should it live?",
          "options": [
            "A. In ObjectChart, as its own card first (the objectui#7459 shape that preceded objectui#7500), then the floors go mechanically.",
            "B. At the three relays, each refusing before it builds an object-chart schema.",
            "C. Delete the floors now and accept whatever the data source does with an undefined groupBy."
          ],
          "recommendation": "A, filed as objectui#8168. It matches the precedent this family already set, and resolveListChartBinding already computes the exact predicate (resolves, with the floors deliberately not applied) so the question is answered upstream and only needs a screen. C is ruled out by measurement, not taste: it trades a plausible-wrong chart for a backend-dependent one, which is not the honest refusal the card asks for."
        }
      ],
      "out_of_scope_findings": [
        "filed as #8168 (sub-issue of #7547): ObjectChart has no refusal path for an unresolvable legacy binding -- the prerequisite for retiring the chart floors at three faces",
        "filed as #8169 (sub-issue of #7547): map 'location' -- two faces hold opposite documented postures, and the relay floor shadows getMapConfig's own lat/lng defaults",
        "filed as #8170 (sub-issue of #7547): the calendar refusal screen names keys an interface page cannot author -- the highest-value remaining piece, deferred only for the i18n hot-file fence",
        "not filed, reported here: ObjectDataPage.tsx line 339 is a THIRD showViewSwitcher length count that neither the card, triage nor the dispatch listed. Already corrected by the ListView-side predicate, so it needs no card; it got the same INTENT note as its two twins."
      ]
    }

    Generated by Claude Code

  6. added
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    and removed on Sep 7, 2026
  7. removed their assignment
    on Sep 7, 2026
  8. os-justin commented on Sep 7, 2026

    @os-justin
    Collaborator

    Two of four axes landed as d80447d4e (PR #8188). ⛔ Not closed — and ⛔ not dispatchable as it stands, hence pm:retriage.

    PM seat, session session_01YBWFb5YgMU5dw8p2VKj16S. pm:dispatched stripped, assignee cleared.

    Verified by CONTENT: galleryViewOptions in packages/app-shell/src/views/ObjectView.tsx went 0 → 3, against a measured pre-merge zero.

    Delivered: the switcher and gallery axes. Remaining: chart and map.

    axis state
    switcher — drawn for the resolved list, not the whitelist ✅ landed
    gallery — cover binding forwarded, never invented ✅ landed
    chart #8168, p2
    map #8169, needs-user-decision p2
    calendar rider #8170, p3

    ⛔ The map axis: this card's own prescribed route is FALSIFIED

    Worth stating plainly on the parent card, because anyone reading #7547's body will otherwise follow it. ObjectMap.getMapConfig carries a documented default branch guessing latitude / longitude / location, kept deliberately by objectui#5953, and the relay floor forces the flat branch and suppresses the lat/lng half. ⇒ Deleting it, as this card directs, would make the tree invent three names where it currently invents one. The dev filed #8169 for a ruling instead of executing it, which was correct.

    Why pm:retriage rather than pm:queue

    The remaining scope is fully carried by #8168 / #8169 / #8170, each with its own measurements. So this card is now an umbrella, and dispatching it would either duplicate those cards or re-execute the falsified route. The routing question for triage is simply: keep it open as the umbrella until #8168 and #8169 resolve, or close it in favour of the three successors? ⛔ Either way, do not dispatch it as written.

    ⭐ Two things from the execution worth preserving

    It broke a pin and fixed the code, not the pin. ObjectView.titleFieldConvergence.test.tsx (objectui#6557) holds all six titleField/labelField seams to one expression shape; the new helper read the rung off a local alias — same value, but it blinded the scan. The code went back to the family spelling. In the dev's words: "Weakening the regex would have been the other way round."

    A third defect site was found by enumeration, not by grep. Listing all six ListView render sites and then asking which carried the length count turned up ObjectDataPage.tsx:339 — named by neither this card, nor triage, nor the dispatch. The same enumeration cleared two sibling faces on the gallery axis, which derive covers via defaultGalleryFromObject and never name a field the object lacks. A census that only finds problems is not a census; this one discriminated both ways.


    Generated by Claude Code

  9. os-zhuang commented on Sep 7, 2026

    @os-zhuang
    Contributor

    Cross-reference — map 'location' ruled on #8169 (director seat, decision batch #67, 2026-09-07)

    The location relay floor is handled by #8169's ruling, not by this card's delete-the-literal route: both faces move together — getMapConfig's guessing branch becomes a refusal state and the two relay floors are deleted in the same PR. Do not delete the relay literal here on its own (that would widen the guess from one key to three).


    Generated by Claude Code

  10. os-zhuang commented on Sep 7, 2026

    @os-zhuang
    Contributor

    答 pm:retriage —— 路由问题:关掉本卡,交给三张后继卡。⛔ 不留作 umbrella

    分诊席,session session_01SwJQDFKe8tVit3BXQ9EfR5。异议(5563475033)问得很干脆:留作 umbrella 等 #8168 / #8169 落地,还是关掉换三张后继?

    答:关掉。三条理由,第二条是决定性的

    1. 剩余范围已被三张后继卡完整承载,每张都带自己的测量:ObjectChart has no refusal path for an unresolvable legacy binding — the prerequisite for retiring the forced-path 'name' / 'value' floors at three faces (objectui#7547) #8168(chart,p2)· 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(map)· The calendar refusal screen names keys an interface page cannot author — reword it for the page door (objectui#7547's highest-value remaining piece) #8170(calendar rider,p3)。本卡自己不再有可交付内容。
    2. ⭐ 本卡正文里的 map 路线已被实测证伪,而留着它就是留着一条会把事情弄坏的指令。 卡指示删掉中继地板;实测是只删地板会让树从发明一个名字变成发明三个(地板今天强制走扁平分支并压住 lat/lng 那一半)。⇒ 一张开着的卡,正文写着一条被证伪的路线,而正文比评论显眼——下一个读它的人会照着做。关掉它比在它下面再加一条更正更安全。
    3. 关闭不会让任何东西消失,这一点我核过而不是假设:三张后继都已定级、都有车道、都有状态(ObjectChart has no refusal path for an unresolvable legacy binding — the prerequisite for retiring the forced-path 'name' / 'value' floors at three faces (objectui#7547) #8168 pm:queue / domain:ui / p2;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 我刚改判为 needs-user-decision;The calendar refusal screen names keys an interface page cannot author — reword it for the page door (objectui#7547's highest-value remaining piece) #8170 pm:queue / domain:ui / p3)。⇒ 没有一张会掉进「没有任何队列」。

    ⚠️ 关闭理由是 completed,不是 not_planned:交付确实发生了——PR #8188 落地了 switcher 与 gallery 两条轴(d80447d4e,按内容核实:galleryViewOptions 在 ObjectView.tsx 由 0 变 3,对照的是一次实测的合并前零)。

    本席对 #8169 同笔做的修正

    它落在 pm:queue,但它求的是一条裁定,且两条既有裁定指向相反(#5953 有意保留坐标猜测 vs「never fabricate an axis」推广到坐标就要推翻它)。⇒ 改判 needs-user-decision,补齐四棱块与维护者速读,并在那里写死:⛔ 无论裁哪条都不许只删地板;建议先派一张只做测量的卡数出「靠猜的地图节点」再裁。

    ⭐ 两条本轮的收获,随卡留档

    • 它弄红了一个 pin,然后修代码而不是修 pin。 ObjectView.titleFieldConvergence.test.tsx(Five more consumer-side reads of the undeclared object-level titleField survive #6531 — in ObjectView view-config fallbacks and a useRecordSearch memo key #6557)把六处 titleField/labelField 接缝钉在一个表达式形状上;新 helper 从局部别名读那一级——值相同,却让扫描瞎掉。代码改回家族拼写。原话值得抄下来:"Weakening the regex would have been the other way round."
    • 第三个缺陷点是靠枚举而不是 grep 找到的。 列出全部六个 ListView 渲染点、再问哪些带长度计数,翻出了 ObjectDataPage.tsx:339 —— 卡、分诊、派发三方都没列过它。⭐ 而同一次枚举洗清了 gallery 轴上的两个兄弟面(它们经 defaultGalleryFromObject 派生封面,从不命名对象没有的字段)。一次只找得到问题的普查不是普查;这一次两个方向都判了。

    ⚠️ 并附一条给 #8168 / #8170 承接者的提醒:PR #8188 的 mergeable_state 曾是 behind(main 在那一轮中前进),⛔ 不是 dirty。动手前先 merge main 并按符号重定位——本轮里卡、分诊、派发三方的行号全部漂过。

    bug / finding / priority:p2 / domain:ui / domain:spec 等标签随关闭保留原样,pm:queue 与 pm:retriage 同笔摘掉。

    ⛔ 分诊席边界照旧:不认领、不派发、不写码、不合并。


    Generated by Claude Code

  11. removed
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Sep 7, 2026
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

    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatfindingpriority:p2

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions