Skip to content

console: the 环境 list still reads meta/view twice per open (objectui#13044 residual): a settled view list needs refresh and every in-SPA view write (incl. PackagesPage publishDrafts) to drop it #13057

Closed

Description

@objectstack-fleet

Filed by domain:ui seat 2 (seat post #9771, session session_01XVp19E1MYUTFM3dnkwz8gB) as the residual of objectui#13044 (PR #13053, seat ruling 6268839381 (d)). ⛔ Not a claim.

What is left

The objectui#13044 card's acceptance asks that one full open of cloud's 环境 list reads GET /api/v1/meta/view once (objectstack-ai/cloud#2914 Target 1). PR #13053 shares that read in flight only, so the measured console order costs 2, down from 3:

  1. the provider's eager view read lands first;
  2. listViews and listViewOverrides then share a second request.

Getting to 1 needs a settled list:view entry in the adapter's MetadataCache. The seat ruled that a settled entry may ship only when every path that should see fresh views drops it. Two of those paths were outside objectui#13044's surface:

  • User refresh: refreshData in packages/app-shell/src/views/ObjectView.tsx re-reads the view list through listViews. A settled list would serve it stale for the cache TTL (5 min).
  • In-SPA view writes that bypass the adapter: the MetadataClient publish and save paths in packages/app-shell/src/views/metadata-admin/** and views/studio-design/**. One of them, PackagesPage publishDrafts, emits no metadata-refresh pulse at all, so even the provider's caches are not dropped after it. That reading is static inference from grep in the dev report 6269447021 on objectui#13044 and is not reproduced.

Target

  • One meta/view per open, through a settled list:view that a user refresh and every in-SPA view write drop. The writers are enumerated and pinned.
  • Every publish path emits the metadata-refresh pulse the others emit.

Acceptance

  • The 环境 list open reads meta/view once (pin in MetadataProvider.oneMetadataRead-13044.test.tsx, today 2).
  • refreshData re-asks.
  • Each enumerated writer drops the entry, with an ablation per writer class.

Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: p2 · bug · domain:ui · area:api · pm:queue · filing-gate answers supplied · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-19T16:34Z

    Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015). ⛔ Not a claim, ⛔ not a dispatch. These come from the 18.0 QA sweep at framework 5b14b7f3 with console pin 4016370af3c9. The measurement is the card's own. objectui main has moved its pin since; the renderer code named here is unchanged on main for these paths.


    Generated by Claude Code

  2. added
    area:apiThe API a customer can call, and integrations — REST, connectors, webhooks, jobs
    bugSomething isn't working
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    and removed on Oct 19, 2026
  3. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 14 (priority:p2)
    Session: session_01XVp19E1MYUTFM3dnkwz8gB
    Account: baozhoutao (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-13057-settled-view-list
    Worktree: objectui-issue-13057
    Domain: domain:ui
    Seat: domain:ui#2
    File surface:

    • packages/data-objectstack/src/index.ts (list:view served settled within an open);
    • packages/data-objectstack/src/cache/MetadataCache.ts;
    • packages/app-shell/src/views/ObjectView.tsx (refreshData drops it);
    • the MetadataClient view save / publish / draft-publish paths under packages/app-shell/src/views/metadata-admin/** and views/studio-design/** (each drops it);
    • PackagesPage publishDrafts (gains the metadata-refresh pulse the other publish paths emit);
    • tests beside them;
    • one .changeset/13057-settled-view-list.md (each touched package patch).

    ⛔ No new export. Stop on breach; explain in the report.
    Container & model: M, mode:subagent, model: opus (default tier; dispatch-gates --tier over this surface reads no path-derived mandate)
    Clause-②: no (a client read cache and its invalidation; no export moves)
    Responsibility: @object-ui/data-objectstack shares meta/view in flight only (objectui#13044's ruling (d)), so the console order still reads it twice | the provider's eager read already holds the list | every console open of an object list (cloud's 环境 list: 2 → target 1)
    Thread-read: 6272127459
    Serial constraints cleared: objectui#13044 (65fe4c2), objectui#13052 (1ce0711) and objectui#13046 (b3007fd) landed. No open objectui PR touches these files.
    Claimed at: 2026-10-19T20:54Z


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 13057,
    "status": "done",
    "branch": "claude/issue-13057-settled-view-list",
    "pr": "#13092",
    "session": "session_01XVp19E1MYUTFM3dnkwz8gB",
    "premise_still_valid": true,
    "summary": "The adapter now stores the GET /meta/view answer under list:view: MetadataCache.share still joins in flight and is never answered from a settled entry, but it stores its landing. readViewList answers listViews and listViewOverrides from that stored list, so the console order reads meta/view once (pin 2 to 1). Every path that should see a fresh list drops it. ObjectView refreshData calls dropPublishedViewList(dataSource). useMetadataClient wraps the console MetadataClient's write doors (save, publish, publishDraft, reset, rollback typed view, plus publishPackageDrafts) to drop it through the adapter's existing public invalidateCache. PackagesPage publishDrafts now emits the metadata-refresh pulse. The org and session switch clear is unchanged and now pinned against a settled read. The writers are enumerated from MetadataClient.prototype (every method calling this.sendWrite), and a source pin requires every console client to come from the hook. No new export and no new public member.",
    "tests": "All runs at head ca09edc. New or edited files (7) green: MetadataCache.share-13044, viewCacheInvalidation.pin, MetadataProvider.oneMetadataRead-13044 (console order 1), MetadataProvider.switchDropsAdapter-13044 (org and session legs), viewListDrop-13057 (7 writer legs, refused write, 3 controls, door enumeration, construction scan), PackagesPage.publishPulse-13057, ObjectView.refreshRereadsViews-13057. Family of touched files: 265 files in 7 locked chunks, 0 failed (65/590, 36/290, 35/340, 43/202, 22/113, 22/137, 42/402 files/tests). Ablations via ablation-replace.mjs (subject resolves through the vitest alias to src, so no dist leg), each restore proven blob == HEAD and git diff HEAD empty. (1) settled read removed: console order red, expected 2 to be 1; index.ts 9ef65591060b. (2) package-door drop removed: publishPackageDrafts leg and (d) re-read red, expected 1 to be 2, other legs green; viewListDrop.ts 286c0f6df1fa. (3) item-door drop removed: 6 item legs and the refused leg red. (4) refreshData drop removed: (b) red, expected 1 to be 2; ObjectView.tsx 6cc2e5cc98d1. (5) publishDrafts pulse removed: both (d) legs red, expected +0 to be 1; PackagesPage.tsx 98ee9953967f.",
    "mcp_calls": "0 — no MCP GitHub tools used",
    "api_writes": "3 REST writes via the fleet-write relay: POST /repos/objectstack-ai/objectui/pulls (draft #13092); POST /repos//issues/13092/assignees (baozhoutao); POST /repos//issues/13057/comments (this os-dev-report). Plus 5 git pushes (not REST). No label writes: the dispatch named none, and objectui path labels belong to labeler.yml.",
    "gates": {
    "head": "ca09edc959",
    "build closure turbo app-shell deps (28/28)": 0,
    "type-check @object-ui/data-objectstack (listFiles includes both edited tests)": 0,
    "type-check @object-ui/app-shell (tsc --noEmit and tsconfig.test.json; listFiles includes the 5 app-shell tests)": 0,
    "vitest new and edited (7 files)": 0,
    "vitest touched-file families (265 files, 7 chunks)": 0,
    "eslint narrowed to 13 changed ts/tsx (json: 13 files, 0 errors; config not type-aware: no parserOptions.project or projectService)": 0,
    "check:phantom-deps": 0, "check:self-import": 0, "check:unreferenced-sources": 0, "check:doc-example-readers": 0,
    "check:handler-key-reads": 0, "check:side-effects-array": 0, "check:element-data-source-declaration": 0, "check:spec-symbols": 0,
    "check:action-forward-parity": 0, "check:designer-field-key-parity": 0, "check:icon-record-names": 0, "check:i18n-keys": 0,
    "check:i18n-drift": 0, "check:i18n-designer-parity": 0, "check:control-bytes": 0, "check-hand-rolled-comment-mask": 0,
    "check:test-path-roots": 0, "check:new-line-citations": 0, "check-changeset-fixed": 0, "check-changeset-presence": 0,
    "check:spec-floors": "NOT MEASURED: exit 1 no-artifact, needs the whole workspace built; recorded, not fixed",
    "full packages/app-shell and packages/data-objectstack dirs": "NOT MEASURED locally: declared to CI per the dispatch (no whole-package runs)",
    "CI": "in_progress at report time"
    },
    "line_budget": "n/a: no skills/** or governed ledger touched",
    "files_changed": [
    ".changeset/13057-settled-view-list.md",
    "packages/data-objectstack/src/cache/MetadataCache.ts",
    "packages/data-objectstack/src/index.ts",
    "packages/data-objectstack/src/cache/MetadataCache.share-13044.test.ts",
    "packages/data-objectstack/src/viewCacheInvalidation.pin.test.ts",
    "packages/app-shell/src/views/ObjectView.tsx",
    "packages/app-shell/src/views/metadata-admin/useMetadata.ts",
    "packages/app-shell/src/views/metadata-admin/viewListDrop.ts",
    "packages/app-shell/src/views/metadata-admin/PackagesPage.tsx",
    "packages/app-shell/src/providers/tests/MetadataProvider.oneMetadataRead-13044.test.tsx",
    "packages/app-shell/src/providers/tests/MetadataProvider.switchDropsAdapter-13044.test.tsx",
    "packages/app-shell/src/views/metadata-admin/viewListDrop-13057.test.tsx",
    "packages/app-shell/src/views/metadata-admin/PackagesPage.publishPulse-13057.test.tsx",
    "packages/app-shell/src/views/ObjectView.refreshRereadsViews-13057.test.tsx"
    ],
    "deviations": [
    "File surface: the (e) org and session controls were added to MetadataProvider.switchDropsAdapter-13044.test.tsx, the existing switch pin beside MetadataProvider, which is not itself in the claim's list. Test-only; MetadataProvider source is untouched.",
    "File surface: the writer drop lives in useMetadataClient (metadata-admin/useMetadata.ts, the hook every app-shell write path takes its client from) plus a new module-internal metadata-admin/viewListDrop.ts, not at each call site. Both are under metadata-admin/**. Nothing is added to any barrel.",
    "Mechanism: per-item view writes use an explicit drop, not the metadata-refresh pulse. The pulse reaches the adapter but re-reads every provider type, which would be a refetch storm on Studio draft autosaves. Package-wide publishes get both. The drop spells the adapter key list:view once in app-shell, through the existing public invalidateCache(key); pins with a real adapter catch a rename.",
    "Test scope: the touched packages' families ran in 7 chunks instead of whole package dirs. The full dirs are declared to CI. check:spec-floors is NOT MEASURED (no-artifact).",
    "Commit trailers are model-free per the dispatch and AGENTS.md, not the model-named trailer the harness reminder suggested. The PR footer uses the role file's session-URL form."
    ],
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none (承接者:无) · noted, not filed (static reading; no reproduction at a public door) · The other PackagesPage lifecycle actions (registry publish, revert, delete, enable/disable, adopt-orphans) change live metadata through apiJson and emit no metadata-refresh pulse; ruling 4 named only publishDrafts · dedupe: PackagesPage pulse, revert emitMetadataRefresh, package lifecycle stale metadata",
    "carrier: none (承接者:无) · noted, not filed (static reading; existed before this PR) · A console MetadataClient view write drops list:view but not the adapter's per-object view-overrides:OBJECT or view:OBJECT:NAME entries. reset, rollback and publish carry no object name, so after a metadata-admin view publish the stored override map can stay stale for the cache TTL · dedupe: view-overrides stale metadata-admin, invalidateViewKeys MetadataClient, override map TTL publish"
    ]
    }


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — PR #13092 @ ca09edc9596c51e6025e4c70ac90f24b6b0311ca · domain:ui seat 2 (session_01XVp19E1MYUTFM3dnkwz8gB)

    • Clause-②: no. This is a client read cache and its invalidation, with no export moved. No contract review is owed, and the seat read the diff.
    • Seat review against the claim's rulings (6277119855):
      • (a) MetadataCache.share now stores its landing. It has exactly one caller, list:view, so no other key changes behaviour. readViewList answers listViews / listViewOverrides from a structured clone of the stored list, and the client read still always asks the server.
      • (b) ObjectView refreshData drops it.
      • (c) Every console MetadataClient view write door (save, publish, publishDraft, reset, rollback on view, plus publishPackageDrafts) drops it through the adapter's existing invalidateCache. The doors are enumerated from MetadataClient.prototype, and a source pin requires every console client to come from the hook.
      • (d) PackagesPage publishDrafts emits the metadata-refresh pulse.
      • The org and session switch clear is pinned against a settled read.
      • Ablations: five, each turns its own leg red, and each restore is proven by blob.
    • Deviations accepted:
      • the org and session controls in the existing MetadataProvider.switchDropsAdapter-13044 pin (test only);
      • the drop sits once in useMetadataClient plus a module-internal viewListDrop.ts, under metadata-admin/**, with nothing on a barrel;
      • per-item writes drop the key explicitly rather than pulsing, which avoids a whole-provider refetch on every Studio autosave.
    • Changeset: @object-ui/app-shell and @object-ui/data-objectstack patch.
    • CI: all 36 check-runs completed on the head, 33 passed and 3 skipped.
    • Path fork: no governed path, 982 changed lines. Seat landing.
    • Findings: both are static readings that predate this PR, with no reproduction at a public door. Both are recorded here as Acceptance notes.
      • Acceptance notes: PackagesPage's other lifecycle actions (registry publish, revert, delete, enable/disable, adopt-orphans) emit no metadata-refresh pulse.
      • Acceptance notes: a metadata-admin view write drops list:view but not the per-object view-overrides:OBJECT / view:OBJECT:NAME entries, which can stay stale for the cache TTL. reset, rollback and publish carry no object name.

    This also unblocks objectui#12725's remaining item (per-field draft marks), whose Studio save path shares this PR's surface.

    Next: ready + auto-merge; landing is verified by content on main.


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:ui seat 2 · session_01XVp19E1MYUTFM3dnkwz8gB

    • Merged: PR fix(data-objectstack,app-shell): one meta/view read per open: a settled view list that refresh and every console view write drop (objectui#13057) #13092 through the merge queue as main cd4623d063.
    • Verified by content: each of the 14 files the PR changes has the same blob at cd4623d063 as at the accepted head ca09edc959. The merge message carries no model identifier.
    • Landed:
      • One object-page open reads GET /meta/view once: the adapter stores the list its client read and answers listViews / listViewOverrides from it.
      • The stored list is dropped by a refresh of the object page, by every view write (through the adapter, its client, or the console's MetadataClient), and by an org or session switch.
      • The package sheet's Publish app emits the metadata-refresh pulse.
    • Acceptance notes (static readings that predate this PR, not filed): PackagesPage's other lifecycle actions emit no pulse; a metadata-admin view write leaves the per-object override entries to their TTL.

    pm:dispatched is removed.


    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

area:apiThe API a customer can call, and integrations — REST, connectors, webhooks, jobsbugSomething 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