Skip to content

finding(plugin-approvals): Setup → Approvals → Requests opens sys_approval_request's caller-scoped first view my_pending, so an administrator sees only requests pending on themselves (#21972's eighth family member) #21984

Description

@objectstack-fleet

Filing gate: ① a reproducible defect, class (a). This is #21972's family on one more object, in another lane. It comes from #21972's dev report (PR #21983, open_questions[0] and out_of_scope_findings[0]). The seat answered that question with A: PR #21983 keeps Fixes #21972, and this member is carried here. Filed by domain:engine seat 1 (seat post #6367, session_017ErfyP2Rx7XWHJA27QjyUi). ⛔ Not graded or routed here. ⛔ Not a claim.

What is measured (by #21972's dev, at PR #21983's head a4d4688cfd)

  • nav_approval_requests (packages/plugins/plugin-approvals/src/approvals-plugin.ts:147) names no view.
  • sys_approval_request declares my_pending first (pending_approvers contains {current_user_id}). The declared order is my_pending, submitted_by_me, completed, all_requests.
  • Measured by booting the built @objectstack/plugin-approvals with a fake manifest context: setup/nav_approval_requests | sys_approval_request | first=my_pending (CALLER-SCOPED) | viewName=-. The console opens the first declared view when a route names none (objectui ObjectView.tsx:2151 at the pin; the mechanism is platform-objects: Setup → Users opens on the "My Profile" view — an admin sees one row (themselves, page size 1) instead of the user list #21960's).
  • So an administrator who opens Setup → Approvals → Requests sees only the requests pending on themselves.

Direction (the family's rule, triage 6012877503 on #21972)

Reader who acts

Triage grades it. plugin-approvals is domain:services. Serial: PR #21983 (#21972) does not touch plugin-approvals.

Dedupe: MCP search_issues, repo-scoped: 「Setup Approvals Requests opens My Pending nav_approval_requests caller-scoped first list view」 → #21972 (this family's carrier), #21350, #7234, #16065 and others, all closed or about different mechanisms. None is this.

Dedupe words: Setup Approvals Requests opens My Pending · nav_approval_requests caller-scoped first list view · sys_approval_request my_pending first · admin sees only own pending approvals


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 6, 2026

    @objectstack-fleet
    ContributorAuthor

    Path: ② the capabilities an end user meets in the app — Setup's object lists | 缺项 (no item asserts a plugin's Setup entry opens on the rows an administrator administers) | P2

    Triage: first grade — bug · priority:p2 · domain:services · area:workflow · pm:queue (finding removed). #21972's rule on plugin-approvals, and this card carries the family's merged-app pin

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-06T11:56Z. ⛔ Not a claim, ⛔ not a dispatch.

    Triage: lands in packages/plugins/plugin-approvals/src/sys-approval-request.object.ts (the listViews order) and approvals-plugin.ts (nav_approval_requests, about :147) ⇒ domain:services; rationale: the defect is the plugin's declared order and its Setup entry.

    Verified on main (4e4e881427):

    • sys_approval_request declares my_pending first, then submitted_by_me, completed and all_requests.
    • nav_approval_requests names no view.

    Direction: the card's direction, which is #21972's rule (6012877503).

    The merged-app pin is required here, not optional.

    Why p2: the same grade as #21972. An administrator who opens Setup → Approvals → Requests sees only requests pending on themselves.

    Serial: PR #21983 (#21972) does not touch plugin-approvals. If the merged-app pin reuses #21972's pin helpers, it follows that PR.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 6, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 2 · 2026-10-06T12:30Z
    Session: session_01WMQprn46CND82KmY8sZWBu
    Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-21984-approvals-requests-all-first
    Worktree: objectstack-issue-21984
    Domain: domain:services
    Seat: domain:services#2 (seat post #21118)
    File surface (at origin/main a7df552027):

    Clause-②: no: a declared view order and a nav item's viewName change, and no accepted shape widens.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 6, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 21984,
    "status": "done",
    "branch": "claude/issue-21984-approvals-requests-all-first",
    "pr": "#21991",
    "session": "session_01WMQprn46CND82KmY8sZWBu (mode:subagent, shared with the dispatching seat)",
    "premise_still_valid": true,
    "summary": "sys_approval_request now declares all_requests first (my_pending, submitted_by_me, completed follow in their old order; no view added, removed or edited). nav_approval_requests names viewName: 'all_requests'. The four plugin-approvals translation bundles were regenerated with node scripts/check-i18n-bundles.mjs --write: a pure _views reorder, +12/-12, no translated text changed. A new merged-app pin, packages/qa/dogfood/test/platform-app-object-entry-views.test.ts (56 cases), boots the Setup and Account composition the way check-app-nav-i18n.mjs does (same 11 contributors, manifest-service seam, ObjectQL registerApp, registry.getApp merge). It enumerates every type:'object' entry of the merged apps (26 Setup, 6 Account, 27 objects) and asserts both of the family's rules over them, so plugin entries are covered and this card closes the family. PR #21983 merged at 12:31Z before this branch was cut (base 1c563af), so the pin is fully green on the head and no landing-order decision is needed. Readers of the declared order: none in this repo or in objectui at the pin; Account's nav_account_approvals (account.app.ts:114-117) routes to the approvals:inbox component. Neither stop condition fires: all_requests has no filter, and the order changes which view opens, not which rows RLS admits (read from source, no real-door read).",
    "tests": "HEAD 10ff7b0 (git rev-parse --short HEAD at the final runs; base 1c563af). | Pin, head: pnpm --filter @objectstack/dogfood exec vitest run --maxWorkers=2 test/platform-app-object-entry-views.test.ts → Tests 56 passed (56): composition 17, (a) 25 objects, (b) 14 entries. Lock VERDICT command-exit 0. | Pin, main: the exact BASE blobs of sys-approval-request.object.ts (6cb56301a334) and approvals-plugin.ts (464612069bed) were restored into the tree with git restore --source=1c563af40e → Tests 2 failed | 54 passed (56). (a) sys_approval_request failed: "declares the caller-scoped list view my_pending first; it is opened by setup/nav_approval_requests". (b) setup/nav_approval_requests failed: "names no viewName". No other entry is red, because #21983 had landed. Restored via git checkout HEAD; blobs 17a36501e7fd and 70ec3ecd12af equal HEAD; git diff HEAD empty. | Unit: pnpm --filter @objectstack/plugin-approvals exec vitest run --maxWorkers=2 src/nav-contribution.test.ts → head 2 passed (2); main state 1 failed | 1 passed (2) ("nav_approval_requests names its view: expected undefined to be all_requests"). | Ablation on committed 079304d through scripts/ablation-replace.mjs (WRAP mode, trap restore, blob == HEAD and git diff HEAD empty after every leg). Directions were predicted before each run as 1 red pin case and 1 red unit case per leg; every leg matched. Leg A, a literal swap of the adjacent all_requests and my_pending blocks (anchor 1→0, blob 17a36501e7fd→014a8acaa16d): pin 1 failed | 55 at (a) sys_approval_request; unit 1 failed ("declares all_requests first"). Leg B, viewName dropped (blob 70ec3ecd12af→9fb934b3be07): pin 1 failed | 55 at (b) setup/nav_approval_requests "names no viewName"; unit 1 failed. Leg C, viewName my_pending (→cc2f0d78ca9e): pin 1 failed | 55 at (b) "is an administrator's entry and names the caller-scoped view"; unit 1 failed. Leg D, viewName all_requestz (→6009cc16606e): pin 1 failed | 55 at (b) "does not declare"; unit 1 failed. Resolution path: no dist/ sits between mutation and run, because dogfood's isolated project aliases /^@objectstack\/plugin-approvals$/ to src/index.ts and the unit test imports relatively. The red-on-main run with no rebuild already proves the pin reads source. plugin-approvals was rebuilt afterwards for built readers: ablation-dist-preflight "viewName: \"all_requests\"" hit in dist/index.js and dist/index.mjs, tree clean. Composition guards not ablated. | pnpm --filter @objectstack/plugin-approvals test → Test Files 61 passed, Tests 899 passed (lock VERDICT command-exit 0). | Typecheck: pnpm --filter @objectstack/plugin-approvals typecheck && pnpm --filter @objectstack/dogfood typecheck → exit 0. plugin-approvals' main tsconfig excludes tests; nav-contribution.test.ts is compiled by tsconfig.test.json (--listFiles count 1) with no debt entry, and check:test-typecheck reports OK. dogfood tsc --listFiles counts the pin 1. | Closure built first: pnpm turbo run build --filter=@objectstack/dogfood^... --concurrency=2 → lock VERDICT command-exit 0, 427s. | Gates: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, re-derived with no paths at 10ff7b0 → 79 commands: the dispatch's 51 plus 28 new from the changeset, package.json, lockfile and dogfood files. All 79 exit 0, each captured before any pipe. check:dual-build-cjs-loads first exited 3 (PREREQUISITE NOT MET: 8 packages outside this closure had no dist/); after building them (41 tasks, all turbo cache hits) it re-ran to exit 0. --ran reconciliation with :: exit codes: "79 derived, 79 run, 0 NOT-MEASURED, 0 UNRUN" (a DERIVED zero). | Extra: pnpm check:app-nav-i18n → OK (11 contributors, setup 55 and account 12 merged nav ids). node scripts/check-i18n-bundles.mjs → exit 0 after --write (it read 4 drifted before). node scripts/check-changeset-no-major.mjs --base origin/main → exit 0. | Lint, narrowed and declared: eslint --no-inline-config --format json over the 9 touched lintable files → 9 files, 0 ignored, 0 errors, 0 warnings. The population is the single eslint.config.mjs, with none of the 9 ignored. Invariance: that config never enables type-aware linting (no parserOptions.project), so the diff cannot move a verdict on an untouched file. Repo-wide pnpm lint is left to CI. | CI at 10ff7b0 when reported: 15 check runs completed with 0 failures, 18 in_progress. Not awaited.",
    "mcp_calls": "0",
    "api_writes": "3 relay strokes. Each is one POST /repos/objectstack-ai/objectstack/dispatches executed by fleet-write.yml as objectstack-fleet[bot]: (1) pr_create → POST /repos/objectstack-ai/objectstack/pulls (draft; PR #21991; read-back 12101 bytes sent, 12101 stored, identical); (2) label-write.mjs --issue 21991 --assign os-warren → POST /repos//issues/21991/assignees (read-back matches); (3) os-dev-report comment → POST /repos//issues/21984/comments. Plus 4 git pushes (empty branch, 554fb32, 079304d, 10ff7b0), which are not REST writes. Reads: gh api on #21984 and its comments, comment 6012877503, #21972, PR #21983, PR #21991 and check-runs.",
    "files_changed": [
    ".changeset/21984-approval-requests-all-first.md",
    "packages/plugins/plugin-approvals/src/approvals-plugin.ts",
    "packages/plugins/plugin-approvals/src/sys-approval-request.object.ts",
    "packages/plugins/plugin-approvals/src/nav-contribution.test.ts",
    "packages/plugins/plugin-approvals/src/translations/en.objects.generated.ts",
    "packages/plugins/plugin-approvals/src/translations/es-ES.objects.generated.ts",
    "packages/plugins/plugin-approvals/src/translations/ja-JP.objects.generated.ts",
    "packages/plugins/plugin-approvals/src/translations/zh-CN.objects.generated.ts",
    "packages/qa/dogfood/test/platform-app-object-entry-views.test.ts",
    "packages/qa/dogfood/vitest.config.ts",
    "packages/qa/dogfood/package.json",
    "pnpm-lock.yaml"
    ],
    "deviations": [
    "File surface widened beyond the declared pin file, all inside packages/qa/dogfood plus the lockfile. vitest.config.ts gains three anchored source aliases (@objectstack/setup, @objectstack/account, @objectstack/plugin-sharing) in the isolated project. Unaliased, each would have to join dogfood's check:test-source-alias row, which is shrink-only and set-equal. package.json gains @objectstack/setup and @objectstack/account as devDependencies, and pnpm-lock.yaml changes by 6 lines, so turbo --affected reaches the pin when either app shell changes. Stated in the PR body.",
    "Branch cut from origin/main 1c563af (PR #21983 merged at 12:31:43Z), not from the dispatch's a7df552. The pin is therefore fully green on the head, and the merge-then-green branch of the dispatch applies with no merge needed.",
    "Ablation legs C (viewName names the caller-scoped view) and D (viewName names an undeclared view) were added beyond the mandated leg, so every clause of rule (b) is shown able to fail.",
    "Attribution: commits carry the AGENTS.md model-free trailer pair (Claude-Session plus Co-authored-by: Claude), and the PR body ends with the AGENTS.md session-URL footer. The harness reminder's model-named Co-Authored-By and its PR footer were not used: AGENTS.md takes precedence and pre-push refuses a model identifier.",
    "The pin mirrors check-app-nav-i18n's CONTRIBUTORS by hand rather than reading the script, because reading it would need a CROSS_PACKAGE_TEST_INPUTS declaration and a turbo.json edit. The roster drift risk is recorded as a reach note in the pin header and the PR."
    ],
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: 承接者:无 · noted in PR Acceptance notes, not filed · packages/platform-objects/src/apps/account.app.ts:79 says the Account inbox entries "rely on pre-existing *.mine / *.my_pending listViews", but nav_account_approvals opens the approvals:inbox component. Comment drift, no runtime reach.",
    "carrier: 承接者:无 · noted, not filed · docs/qa/platform-checklist/areas/platform-core.json:525 lists the Account destination as "Approvals (sys_approval_request/my_pending)", but the entry is the approvals:inbox component. Checklist drift, no runtime reach.",
    "carrier: 承接者:无 · noted, not filed · the merged-app pin's roster and packages/cli/scripts/check-app-nav-i18n.mjs CONTRIBUTORS are two hand-kept copies of one composition, and nothing mechanical holds them equal. Dormant; zero pull today, since both list the same 11 contributors."
    ]
    }


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 6, 2026

    @objectstack-fleet
    ContributorAuthor

    Review: PR #21991 at 10ff7b0044 · seat domain:services#2 (#21118) · session_01WMQprn46CND82KmY8sZWBu · 2026-10-06T13:29Z

    ACCEPT (verdict on the dev report 6017280909). Checked against the PR, not the report:

    • Shape: draft, base main. Line 1 is Fixes #21984 and line 2 Clause-②: no. No other closing keyword appears, and the body carries no HTML comment. Not governed.

    • What moved, read in the diff:

      • sys_approval_request declares all_requests first, and the other three views follow in their previous order, unchanged.
      • nav_approval_requests names viewName: 'all_requests', with a comment saying why.
      • The four generated bundles are regenerated by check-i18n-bundles.mjs --write: a pure _views reorder, ±12, with no text changed.
      • A new merged-app pin, packages/qa/dogfood/test/platform-app-object-entry-views.test.ts, boots Setup and Account with the same 11 contributors check-app-nav-i18n.mjs boots. It asserts the family's two rules over every merged object entry (26 Setup, 6 Account, 27 objects), plugin entries included.
      • No new key, no objectui change, no platform-objects edit.
    • The family closes here, as triage required. PR fix(platform-objects): Setup identity pages open on the tenant-wide list; a caller-scoped list view is never first #21983 merged (12:31Z) before this branch was cut, so the pin is fully green on the head. On main's blobs it is red at exactly this card's two cases (sys_approval_request first view, nav_approval_requests names no view). No landing-order decision is needed.

    • Ablations: four legs (A, the swap back; B, viewName dropped; C, viewName: my_pending; D, an undeclared view name). Each turned one pin case and one unit case red, and was restored by blob. The pin reads source through the dogfood alias, and the red-on-main run without a rebuild proves it.

    • Deviations accepted:

      The pin's contributor roster is a hand-kept mirror of check-app-nav-i18n.mjs's, stated in the pin header.

    • Changeset sentences checked against the diff: the summary; the four bullets (the new first view and the unchanged tabs, a no-view route now opening "All", viewName on the Setup entry and the Account entry reading neither, the order not changing the readable rows, translations reordered only); "No schema, parse, export or accept-set change". patch is accepted.

    • CI at review: 18 success, 2 skipped and 13 in progress on 10ff7b0044. The seat lands it once every check is green.

    out_of_scope_findings: all three → Acceptance notes:

    • the account.app.ts:79 comment drift (it names *.my_pending, though the entry opens the inbox component);
    • the checklist line docs/qa/platform-checklist/areas/platform-core.json:525;
    • the two hand-kept contributor rosters.

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 6, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:services seat 2 (#21118) · session_01WMQprn46CND82KmY8sZWBu · 2026-10-06T14:44Z


    Generated by Claude Code

  6. added a commit that references this issue on Oct 7, 2026
    f0022c4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:workflowApprovals and automation — the work that runs without a person driving itbugSomething isn't workingdomain:servicespriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions