Skip to content

console issues requests it cannot use: GET /api/v1/meta/_drafts (403) for a member without metadata edit on every record page, and Studio GET /api/v1/meta/object/<name>?package= (404) for a draft object it just created #25894

Closed

Description

@os-steve

Filing gate ① a defect with a named landing site (two stray requests, one family: the console asks the runtime for things the runtime answers 4xx by design). Batch-of: 2026-10-25 browser pass on @objectstack/* 18.1.0 (23 cards: hotcrm 10, objectui 10, objectstack 3). Filed by the maintainer's account (os-steve) from the HotCRM pass driven in session session_01AwpXhq2nFKU6J7GmbCEmZu; ⛔ not a claim. Grade and routing are objectui triage's.

What is seen (@objectstack/console 18.1.0)

  1. Signed in as sales.manager@objectos.ai (a member, no metadata edit), opening an opportunity record from the approvals inbox fires GET /api/v1/meta/_drafts → 403, logged as a resource error in the browser console. The page is fine; the request has no reader for this member. Observed on every record page open in that session (the pass's network log, failed=403 GET …/api/v1/meta/_drafts).
  2. In Studio, after 新建对象 → 存为草稿 on a writable package (com.default.com-test-browser), the object page fires GET /api/v1/meta/object/com_test_browser_repair_ticket?package=com.default.com-test-browser → 404 (the draft is not published, so the runtime meta endpoint has no such object). The Studio page renders from the draft store regardless. u11-object-created.png.

reach: the public UI, each measured once; no user-visible breakage, but each is a red request in every session's console and one more call per page.

Expected

  • The drafts probe runs only for a session that holds metadata edit (the capability the console already reads for the Studio entry), or the runtime answers 200 with an empty list for others.
  • Studio's object page reads a draft object from the draft store only, and asks the runtime meta endpoint only for a published object.

Dedupe

MCP search_issues objectui "meta drafts request returns 403 for non admin user" → 0 hits; the 404 half: none found in the Studio searches run for this batch (#13125, objectstack-ai/objectui#12965 are unrelated). Report: REPORT.md §4.6, §7 S5.

Activity

  1. added
    area:studioChanging a running app without code — authoring, publish, docs and the portal
    bugSomething isn't working
    and removed on Oct 25, 2026
  2. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    Contributor

    Triage: first grade — bug · priority:p3 · domain:ui · area:studio · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-25T12:57Z

    ⛔ Not a claim, ⛔ not a dispatch. finding comes off.

    • Gate GET /meta/_drafts on the metadata-edit grant the page already knows, and the Studio draft-object read on the package scope it needs. These are noise requests, not data exposure.

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    Contributor

    Transferred 2026-10-26T02:57Z from objectstack-ai/objectui#13520, with its comments and timeline; the old URL redirects here. objectui moved into this repository as the ui/ workspace (epic #25677) and is being archived (#25854). The body is left exactly as filed.

    Paths. The body names no file paths; the UI code it describes lives under ui/ here (the Console is ui/apps/console, the libraries ui/packages/*).

    References. The bare issue numbers in the body were written in objectui and now resolve against this repository by mistake; read them as objectstack-ai/objectui#12965, objectstack-ai/objectui#13125.

    No stale pm:dispatched or assignee to strip.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    Contributor

    Claim: PM loop round 1
    Session: session_017iXjUm1rujwDk7f3KT1Pkk (seat); implementing card thread session_011fs46jjQVe98Y5YTfDTixa
    Account: os-steve
    Branch: claude/project-thread-bpb6pu (platform-assigned card-thread branch; a card thread can push only its assigned branch, and the name carries no issue number, so this claim is the identity record)
    Worktree: the card thread's own container
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: the ui/packages/app-shell caller(s) of GET /api/v1/meta/_drafts for a member without the metadata-edit grant (candidates: console/home/HomePage.tsx, the pending-changes / DraftChangesPanel.tsx path), the Studio draft-object read, their tests, and scripts/sdui-manifest.record.json (derived hash). Fix per triage (2026-10-25 12:57Z): gate _drafts on the metadata-edit grant the page already knows, and gate the Studio draft-object read on the package scope it needs. The thread names the exact files before coding; a file outside app-shell needs a claim amendment first (stop on breach; explain in the report). ⛔ ui/.github/** and the root .github/workflows/ci.yml are out of bounds (maintainer's word, ui-merge epic in flight). Changeset in the root .changeset/.
    Container & model: S, mode:thread, model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate), effort: medium
    Clause-②: no (gating internal reads; no exported type change)
    Metadata-protocol: none
    Responsibility: n/a: renderer defect in ui/, the producing code is the cited ui file; no platform path covers it; reached through the public Console
    Thread-read: 6407215447
    Premise: holds (read-only check by the seat at origin/main 39a78b1: _drafts readers live in app-shell HomePage.tsx, useNavTargetLabel.ts and DraftChangesPanel.tsx 2026-10-26T09:45Z)
    Serial constraints cleared: #25984 (#25890, pending changes in app-shell) lands first if the files overlap; this PR then merges origin/main before the queue (open-PR file scan 2026-10-26T09:45Z)

    Dispatch order handed to the card thread by the project coordinator (three partitions: ruling / mechanism hypotheses / suggested route); the dev does not claim, and starts only once this claim names its branch.

  5. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    Contributor

    os-dev-report

    {
     "issue": 25894,
     "status": "done",
     "branch": "claude/project-thread-bpb6pu",
     "pr": "https://github.com/objectstack-ai/objectstack/pull/26056",
     "head": "e32db4656aa04c4063e3990e4e4aaf4a8d123c75",
     "session": "session_011fs46jjQVe98Y5YTfDTixa",
     "premise_still_valid": true,
     "summary": "Both stray requests located on origin/main 39a78b15. (1) The env-wide GET /meta/_drafts a member reaches is Home's drafts row (usePendingDraftsRow, HomePage.tsx); it now reads only behind the new useCanReadPendingDrafts(), whose cohort is the door's own (studio.access, setup.access or manage_metadata, mirroring mayReadPendingDrafts / ADR-0106 D4). It is not manage_metadata alone: a setup.access admin keeps the row. Unknown fails open. (2) The only producer of GET /meta/object/NAME?package=PKG is DraftChangesPanel's EntryDetail published read. Under Studio's Publish confirm posture it fired before new-vs-update classification; the drill-in now waits for its classification and skips the published read for kind new. A failed classification still reads both ways. PR assignee set to os-steve via the relay pr_create (the card has none; the project's PR-attribution rule names os-steve); no reviewer request sent (no relay op used for it, MCP writes barred).",
     "tests": "cd ui && vitest run --maxWorkers=2 packages/app-shell/src/preview/__tests__/DraftChangesPanel packages/app-shell/src/console/home/__tests__/HomePage under os-verify-lock: Test Files 29 passed (29), Tests 186 passed (186) after one fix-up in the new Home test (harness liveness probe). Ablation: HomePage.tsx and DraftChangesPanel.tsx reset to origin/main (grep markers useCanReadPendingDrafts 0 / awaitingKind 0 on disk), the two new files re-run: Tests 4 failed, 5 passed (the 4 headline cases red, the 5 controls green); restored by git checkout HEAD, git diff HEAD empty, markers back to 2 / 3. Tests import app-shell src, so no dist rebuild is in the path. pnpm --filter @object-ui/app-shell type-check (after the app-shell ^... closure build): VERDICT command-exit 0, 0 TS errors, at e32db465.",
     "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack (no paths) derived 35 commands at e32db465; all exit 0, including node scripts/check-sdui-manifest.mjs (registry hash unchanged: app-shell is not a registry package, so scripts/sdui-manifest.record.json needs no re-record; gen-sdui-manifest-node.mjs re-run produced no diff). --ran reconciliation with per-command exit codes: 34 derived families, 34 run, 0 NOT-MEASURED (a derived zero). CI check-runs on PR 26056: in_progress at report time.",
     "dogfood_battery": "n/a — no ! in the PR title and Clause-② no",
     "mcp_calls": "4 — issue_read get, issue_read get_comments x2, pull_request_read get_files (PR 25984 overlap check); no MCP write tool",
     "api_writes": "2 — relay pr_create (objectstack-fleet[bot], run 40307908116, body read back byte-identical, assignee os-steve), this os-dev-report issue comment via post-stamped.mjs",
     "deviations": [
      "sdui manifest record not re-recorded: generator re-run shows the registry sources hash unchanged (3fe91623…), so the file has no diff",
      "four existing Home tests (12601, 12602, 12604, 13136) gained useCanReadPendingDrafts in their explicit useCanAuthorMetadata mock factories; same app-shell test surface the Claim names",
      "full app-shell suite left to CI Test Core (declared narrowing: every DraftChangesPanel* and HomePage* test file run locally)",
      "PR assignee os-steve set via relay although the card carries none"
     ],
     "files_changed": [
      ".changeset/25894-no-drafts-request-without-grant.md",
      "ui/packages/app-shell/src/hooks/useCanAuthorMetadata.ts",
      "ui/packages/app-shell/src/console/home/HomePage.tsx",
      "ui/packages/app-shell/src/preview/DraftChangesPanel.tsx",
      "ui/packages/app-shell/src/console/home/__tests__/HomePage.draftsReadGate-25894.test.tsx",
      "ui/packages/app-shell/src/preview/__tests__/DraftChangesPanel.newEntryNoPublishedRead-25894.test.tsx",
      "ui/packages/app-shell/src/console/home/__tests__/HomePage.greetingAndApps-12601.test.tsx",
      "ui/packages/app-shell/src/console/home/__tests__/HomePage.myWork-12602.test.tsx",
      "ui/packages/app-shell/src/console/home/__tests__/HomePage.recentlyAccessed-12604.test.tsx",
      "ui/packages/app-shell/src/console/home/__tests__/HomePage.pendingDraftsPackageName-13136.test.tsx"
     ],
     "open_questions": [],
     "out_of_scope_findings": [
      "carrier: none — noted in PR Acceptance notes, not filed: DraftChangesPanel per-member classification still answers 404 for a new email_template member (that read is the classification itself)"
     ],
     "serial": "PR 25984 (card 25890) also edits DraftChangesPanel.tsx in different hunks; this branch merges origin/main after it lands"
    }

    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:studioChanging a running app without code — authoring, publish, docs and the portalbugSomething isn't workingdomain:uipriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions