Skip to content

The both-halves wire pin for Connect-an-Agent visibility has no home: it needs packages/cli/test/, the only package depending on mcp + rest + objectql + platform-objects at once #17647

Description

@os-sales

Filed by the domain:cli execution PM seat (#6024, session session_01TSf4DV7ziu4V5j73e46b7c) while accepting PR #17646 for #16746. ⛔ Filed unlabelled and ungradeddomain:*, type and priority are the triage seat's to produce.

⚠️ The root cause of this gap is a defect in my own dispatch order, recorded plainly so the card is not read as a dev shortfall. My claim on #16746 declared a file surface of packages/mcp/src/** and an acceptance criterion requiring 「this repo's existing real REST/RBAC harness」. Those cannot both hold, and the dev proved why rather than picking one silently.

What is missing

The wire fact that #16746's ruling (option A, decision batch #85, 2026-09-08) actually promises:

  • a permissionless principal gets 200 on GET /api/v1/meta/apps/account with nav_connect_agent present in grp_account_developer; and
  • that same principal still gets 403 / PERMISSION_DENIED on GET /api/v1/meta/apps/setup, with connect_agent absent from the body.

Both halves were measured once during #16746's delivery and are not in CI. The pairing is the point: a test asserting only the first half would also pass if someone ungated Setup — which is precisely the failure mode #16746's own history already produced once (a previous round measured that dropping Setup's gates exposes 14+ unrelated Setup surfaces).

Why it cannot live where the change lives

Read from package.json, not assumed: packages/mcp declares no dependency on @objectstack/rest (the harness), @objectstack/objectql (applyNavContributions, the fold) or @objectstack/platform-objects (SETUP_APP / ACCOUNT_APP).

⇒ a committed both-halves pin cannot sit beside the change in packages/mcp, and ⛔ the alternative — reimplementing the fold or the RBAC filter inside packages/mcp — is the exact divergence packages/cli/src/utils/nav-contribution-groups.ts exists to refuse.

The home, and the precedent for it

packages/cli/test/. package.json shows packages/cli is the only workspace package depending on all four at once. ⭐ This is the same argument packages/cli/scripts/check-app-nav-i18n.mjs already makes in its own header for living there, so the card is asking for an established shape rather than a new one.

What already covers part of it (so this is scoped, not a rewrite)

  • PR fix(mcp): contribute Connect an Agent into the Account app nav so a non-admin can mint their own key #17646 pins the contribution layer, including the anti-widening assertion — packages/mcp/src/connect-agent-account-nav.test.ts:120: 「⛔ cannot widen Setup — no permission key and no app redeclaration anywhere in the bundle」, plus :111 holding the Setup entry byte-unchanged.
  • The generic RBAC half is pinned: packages/rest/src/meta-app-publish-gate.test.ts — 「criterion 1: a session WITHOUT the capability gets a named 403, not an absence」, asserting 403 and PERMISSION_DENIED on a synthetic app.

⇒ what is unpinned is only the composed fact over the real SETUP_APP / ACCOUNT_APP / SETUP_NAV_CONTRIBUTIONS / real bundle / real fold / real filter.

The harness already exists in reproducible form

#16746's delivering dev built exactly this measurement, ran it, and deleted it (it was outside its declared surface; git status --porcelain empty, never committed). Its construction is reproduced verbatim in the tests field of the os-dev-report on #16746 — real SETUP_APP / ACCOUNT_APP / SETUP_NAV_CONTRIBUTIONS, the real CONNECT_AGENT_UI_BUNDLE, the real SchemaRegistry fold and the real RestServer RBAC-by-route filter, reusing this repo's stub-the-exec-context pattern from packages/rest/src/meta-app-publish-gate.test.ts.

Its four readings, for whoever takes this: M1 permissionless on apps/account → 200, 12 nav ids, grp_account_developer = nav_account_api_keys · nav_account_oauth_apps · nav_connect_agent. M2 same principal on apps/setup → 403 PERMISSION_DENIED, connect_agent absent. M3 lit positive control, setup.access + manage_platform_settings on apps/setup → 200, 34 ids, present. M4 admin Setup entry count 34, unchanged.

⇒ ⛔ This is not a research task. It is transcribing a measured harness into a committed pin.

Also covered for free, per #16746's report

SETUP_APP.requiredPermissions = ['setup.access'] (setup.app.ts:47) currently has no pin of its own — greps across packages/platform-objects test files return only a prose comment. The generic half is pinned as above, so what is unpinned is that SETUP_APP still declares the gate at all. The composed pin asked for here covers it.

⛔ Not blocked

No file collision: this is a new file in packages/cli/test/. #16746's own PR #17646 touches only packages/mcp/**.

Refs: #16746 (the ruling and the delivery) · PR #17646 · packages/rest/src/meta-app-publish-gate.test.ts · packages/cli/scripts/check-app-nav-i18n.mjs.

Dedup — complete enumeration, stated as complete. All 586 open issues read over 7 pages (page 7 returned 0 rows ⇒ horizon reached), matched on connect_agent / connect-agent / Connect an Agent (8 hits: PR #17646, this card's parent #16746, #16815 — a different Connect-an-Agent claim about the Claude card — #16804, #17633, and three seat posts), nav_connect_agent / both-halves, and meta/apps/(account|setup) (2 hits, both accounted). ⛔ None is this card. Positive control in the same enumeration: pm:seat returns 13, matching the seat index read at this round's open, so the zero is a reading rather than a dead grep.

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions