Skip to content

feat(spec,runtime): an organization-scoped manage_connector_connections capability gates the connector connection door (ADR-0143 D5) - #28400

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-6ytsf3
Oct 31, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-6ytsf3

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Tesla · project thread

Fixes #28327

Clause-②: yes (widening)
Metadata-protocol: added
Skills-docs: updated here — content/docs/automation/connectors.mdx names the connect door's capability; no skill under skills/** teaches that door's gate

维护者速读

  • 改了什么:新增组织级能力 manage_connector_connections,连接器 OAuth2 连接的四个入口(查看状态、发起连接、回调、撤销)改为只认这个能力,不再认平台级的 manage_metadata。
  • 为什么改:给连接器绑定供应商账号是"组织"的事(ADR-0143 Q1 = A),却用平台级元数据权限把关;S4 控制台连接流程上线前要先把权限放对。
  • 风险与回滚:平台管理员(admin_full_access)默认持有,行为不变;组织管理员默认不持有,需显式授予(不放宽任何人)。该入口今早才合并、尚未发版,没有已发布的调用方失去权限。回滚即还原本 PR。
  • 先看:packages/runtime/src/domains/automation.ts(refuseUngrantedConnectorConnectionAccess)、packages/spec/src/security/capabilities.ts(新条目)、packages/runtime/src/domains/automation-connector-connection-door.test.ts(两个方向的钉子)。
  • 两分钟验证:pnpm --filter @objectstack/runtime exec vitest run src/domains/automation-connector-connection-door.test.ts,预期 22 个测试全绿,其中"manage_metadata alone no longer admits"与"organization administrator on the shipped grant is refused"各 4 条。
  • 需要你做的:组织管理员是否应默认持有该能力(放宽,属人工地板),请裁决;代码本身无需你操作,席位落地。

What changes

  • @objectstack/spec: PLATFORM_CAPABILITIES gains manage_connector_connections (label "Manage Connector Connections", scope: 'org'), the capability ADR-0143 D5 delegates to the server slice. ADMIN_FULL_ACCESS_CAPABILITIES (the eval fixture admin_full_access is built from) carries it; no other shipped set does.
  • @objectstack/runtime: the connection door's gate (refuseUngrantedConnectorConnectionAccess) asks CONNECTOR_CONNECTION_CAPABILITY = manage_connector_connections for all four members: GET / POST / DELETE /automation/connectors/:name/connection and GET /automation/connectors/oauth/callback. Fail-closed, only isSystem bypassing, placed where it was (ahead of the service probe and the query checks). The refusal text names the new capability. The four route-ledger rows say so.
  • Setup widget (@object-ui/fields, @object-ui/i18n): the capability picker's curated label set and capability.label.manage_connector_connections in useFieldTranslation and all ten locale packs (the spec-parity and locale-parity pins require both).
  • Docs: content/docs/automation/connectors.mdx named manage_metadata for the connect calls; it now names the new capability and who holds it.
  • Changeset 28327-manage-connector-connections.md (minor on the four moved packages).

Untouched, by the order's serial note: no provider and no connector-credential-source.ts edit (#26702 S2 owns those). The credential door (/connectors/credential-refs) and its Setup nav entry keep manage_metadata: they act on environment-level credentials, not on an organization's connection.

Tests

  • packages/runtime/src/domains/automation-connector-connection-door.test.ts: the refusal pins name the new capability; new pins, each over all four members:
    • manage_metadata alone, and the whole platform-only set (manage_metadata, studio.access, setup.access, manage_users, manage_platform_settings) without the new capability → 403 PERMISSION_DENIED, no service member called.
    • the organization administrator's shipped grant (manage_org_users, setup.access, setup.write, manage_mailboxes) → 403, no member called; the same grant plus manage_connector_connections → 200 and the member called once with the caller's organization.
    • isSystem passes without the capability; an absent capability list is refused.
    • the gate's constant is the spec-declared, org-scoped capability.
  • packages/spec/src/identity/platform-admin-capabilities.test.ts: ADMIN_FULL_ACCESS_CAPABILITIES carries it and it is declared org.
  • packages/plugins/plugin-security: default-permission-sets.test.ts pins admin_full_access as its only shipped holder; the platform-administrator envelopes in four golden/equivalence suites gain it (the TENANT_ADMIN envelopes stay without it).

Acceptance notes

  • Default grant to organization administrators is NOT made. ADR-0143 says Console Connect / Reconnect is organization-level, and the order's security floor says this card tightens and widens no one. Adding the capability to organization_admin / organization_admin_no_bypass would let every organization owner or admin connect a vendor account where today they cannot: a widening of an access-control boundary, which is a human floor in this lane. Until ruled, an organization administrator connects only after an explicit grant. Ablation 3 below shows the pin that holds this.
  • The manage_metadata → manage_connector_connections move narrows the door relative to main for a set that grants manage_metadata without admin_full_access. The door landed with feat(service-automation): serve oauth2 connector instances per dispatch, and connect an authorization_code instance per organization (ADR-0143 S1) #28317 (2026-10-31 08:28Z) and its changeset 26702-connector-oauth2-connections.md is still pending in .changeset/, so no published version served it: no released caller loses access, and the Clause-② arm is declared on the protocol change (a new accepted capability name).
  • The door test transcribes the organization administrator's grant rather than importing it (runtime does not depend on plugin-security); the seeded-set side is pinned in plugin-security.

Verification

Implementation commit 7354e08f4 on base origin/main 3ba520691; head 3979c8fbb merges origin/main ac09e7b85 (no overlapping file). After the merge: install, rebuild of the runtime closure, pnpm --filter @objectstack/spec check:generated exit 0 (14 artifacts up to date), and the door, spec, five plugin-security and ui parity files re-run green (22 / 403 / 92 / 68 tests).

Build and tests
  • pnpm --filter '@objectstack/runtime^...' --filter @objectstack/runtime build → VERDICT command-exit 0.
  • door test + packages/runtime/src/domains/packages-capability-gate.test.ts → Test Files 2 passed, Tests 101 passed; spec src/identity/platform-admin-capabilities.test.ts src/security/ → Test Files 16 passed, Tests 403 passed.
  • pnpm --filter @objectstack/plugin-security test → Test Files 238 passed, Tests 5125 passed / 45 skipped.
  • pnpm --filter @objectstack/runtime test → Test Files 491 passed, Tests 7981 passed / 19 skipped.
  • pnpm --filter @objectstack/runtime typecheck, pnpm --filter @objectstack/spec typecheck → exit 0 (same lock run, VERDICT command-exit 0).
  • ui, from ui/: vitest run packages/fields/src/widgets/CapabilityMultiSelectField packages/i18n/src/__tests__/all-locales-key-parity.test.ts packages/i18n/src/__tests__/en-zh-key-parity.test.ts → Test Files 4 passed, Tests 68 passed.
  • lint: eslint --no-inline-config over the touched non-ui files → exit 0; ui/ eslint over the touched ui files → exit 0 (3 pre-existing warnings in CapabilityMultiSelectField.tsx, none on changed lines).
Ablations (each through scripts/ablation-replace.mjs, restored to the HEAD blob with an empty git diff HEAD)

The subjects are imported from source by relative path (./automation.js, ./default-permission-sets.js), so no dist rebuild sits between mutation and run.

  1. Put manage_metadata back beside the new capability in the gate → door test: 4 failed / 18 passed, exactly the four "manage_metadata alone no longer admits the caller" cases.
  2. Remove the gate (return undefined) → door test: 13 failed / 9 passed: every refusal pin, every manage_metadata-alone pin, every organization-administrator pin and the fail-closed pin.
  3. Add the capability to the organization_admin shipped set → plugin-security: 4 failed / 28 passed: the "no other shipped set carries the connector connection capability" pin (expected [ 'admin_full_access', …(2) ] to deeply equal [ 'admin_full_access' ]) and the three per-posture TENANT_ADMIN envelope goldens.
Derived gates

node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 7354e08f4: 113 families derived, each run with stdin closed, exit codes recorded before any pipe. --ran reconciliation: 113 derived, 111 run, 2 NOT-MEASURED, 0 UNRUN.

  • Three first runs exited on a missing build or shallow history and were re-run after clearing it, green: check-plugin-teardown-shape.mjs --self-test (fetched its pinned fixture commit), check:skill-examples and pnpm --dir ui exec vitest run scripts/ (built @objectstack/client and @objectstack/client-react; then Test Files 169 passed / 2 skipped).
  • NOT MEASURED, reason: prerequisite not met (exit 3, nothing read): pnpm check:dual-build-cjs-loads (needs every package's dist/, i.e. a full pnpm build) and pnpm check:i18n (needs the built CLI and its extract closure). No committed translation bundle names a capability, so neither reads a file this diff changes; both run in CI's Lint & Repo Gates.

Generated by Claude Code

…tion-scoped manage_connector_connections capability

ADR-0143 D5 delegates who may connect, reconnect or revoke a connector
connection to a capability the server slice declares. Connecting a vendor
account is an organization act (Q1 = A), so the door now asks a new
org-scoped capability instead of the platform-scoped manage_metadata.

- spec: PLATFORM_CAPABILITIES gains manage_connector_connections (org);
  ADMIN_FULL_ACCESS_CAPABILITIES carries it, no other shipped set does.
- runtime: the four door members (status, begin, callback, revoke) ask it,
  fail-closed, only isSystem bypassing; route-ledger rows say so.
- ui: the Setup capability picker labels it in all ten locales.
- tests: both directions pinned (manage_metadata alone refused; the
  organization administrator's shipped grant refused, admitted with the
  capability), default-set pins updated.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9qibwTBxFYpcsutpHMRHe
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling labels Oct 31, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/runtime, @objectstack/spec, touching 15 documentable anchor(s).

16 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: node scripts/docs-audit/affected-docs.mjs --json 125ad062d2eaf49687a89489766a284ba60aa618.

⛔ 7 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails.

What this run could not see
  • 1 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 60 of 212 client-bound route-ledger rows — the other 152 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 152: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 97 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 173 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 125ad062d2eaf49687a89489766a284ba60aa618 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 76ffb693d86fa805ee047cebfce7e1ead811e7e3 — the merge of head 3979c8fbbdd6fc3f31c7d875e4d8af1093844ad7 into base 125ad062d2eaf49687a89489766a284ba60aa618, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 76ffb693d86fa805ee047cebfce7e1ead811e7e3 && git checkout 76ffb693d86fa805ee047cebfce7e1ead811e7e3
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 125ad062d2eaf49687a89489766a284ba60aa618 3979c8fbbdd6fc3f31c7d875e4d8af1093844ad7 && git checkout -B drift-repro 125ad062d2eaf49687a89489766a284ba60aa618 && git merge --no-ff 3979c8fbbdd6fc3f31c7d875e4d8af1093844ad7

node scripts/docs-audit/affected-docs.mjs --json 125ad062d2eaf49687a89489766a284ba60aa618

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 125ad062d2eaf49687a89489766a284ba60aa618 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#1 · os-tesla · session_01L9qibw58ehQ2gRHP2h2Puz

Contract-review-claim: session_01L9qibw58ehQ2gRHP2h2Puz · head 3979c8fbbdd6fc3f31c7d875e4d8af1093844ad7 · 2026-10-31T11:45Z

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#1 · os-tesla · session_01L9qibw58ehQ2gRHP2h2Puz

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 3979c8fbbdd6fc3f31c7d875e4d8af1093844ad7
Local-runs: none
Scope: packages/spec/src/security/capabilities.ts (the manage_connector_connections entry of PLATFORM_CAPABILITIES, scope: 'org'), packages/spec/src/identity/eval-user.zod.ts (ADMIN_FULL_ACCESS_CAPABILITIES carries it), packages/runtime/src/domains/automation.ts (CONNECTOR_CONNECTION_CAPABILITY, the deny message, refuseUngrantedConnectorConnectionAccess), packages/runtime/src/route-ledger.ts (the four connection-door rows), the door test and the spec and plugin-security pins and goldens, ui/packages/fields CapabilityMultiSelectField.tsx and useFieldTranslation.ts, the ten capability.label.manage_connector_connections locale rows, content/docs/automation/connectors.mdx, .changeset/28327-manage-connector-connections.md

Inputs: card #28327 (the SF4 finding of #28317's review, record 6539266538: the S1 door gated on the platform-scoped manage_metadata while connecting is an organization act; triage 6539801921 p1 security with Clause-②: yes and the one-PR exception for the spec declaration; the seat's claim 6541956120 and the dev report 6542678512 with its three ablations and the open question on the organization administrator's default), PR #28400 (body with the four door members, the default-grant table and the human-floor note; 25 files, +173/−28, the diff read whole), ADR-0143 on main (D5: who may connect, reconnect or revoke is a capability check the server slice declares; Q1 decided A: one connection per instance per organization, Console Connect is organization-level), the 70 check-runs on this head (read 2026-10-31T11:55Z: all 70 runs completed, none failed, none cancelled, none in progress; success: Build & E2E UI, Build Core, Build Docs, Build UI Deps, Check Changeset, Check Documentation Links, Dogfood Regression Gate, Flag docs affected by code changes, Governed Surface Queue Guard, Lint & Repo Gates, Lint UI, Lint · CI, release & engine gates, Lint · ESLint, Lint · PM dispatch-gates, Lint · docs & code guards, Lint · repo & tooling gates, Lint · scoped · query-options erasure, Lint · scoped · slot lookup & corpus, Lint · scoped · tooling self-tests, Live E2E UI, PR-body guards (claim · duplicate · Part-of · single-writer path), Plan Test Core shards, Spec property liveness, Test Core, Test Core (all 8), Test UI, Test UI (all 16), Type Check UI, Type Check · consumer gates, Type Check · debt ledger, Type Check · source gates, Type Check · workspace, TypeScript Type Check, filter; skipped: 18.x upgrade harness (opt-in), Auto Label, Check PR Size, Dogfood Regression Gate (matrix shard/3), Dogfood Verify CLI, Packed-tarball smoke (opt-in), Schedule gate · skip when a green push run covers the commit, Temporal Conformance (live PG + MySQL), UI Published Artifacts), and the tree at this head: default-permission-sets.ts grants organization_admin exactly manage_org_users, setup.access, setup.write, manage_mailboxes (what the door test transcribes as ORG_ADMIN_GRANT), the credential door and the flow authoring and toggle doors keep FLOW_AUTHORING_CAPABILITY (manage_metadata), and no other reader of manage_metadata names the connection door. The head is a clean merge of main ac09e7b8; its two files that moved on main since the seat's base (connectors.mdx, route-ledger.ts) show no evaluated hunk in the merge, and the head is mergeable today.

① Derived judgments

  • The capability is declared where the registry lives and shaped like its neighbours - right. One PlatformCapability row with name, label, description, scope: 'org', after manage_mailboxes; PLATFORM_CAPABILITY_NAMES derives from the array, so lint and gating know the name at once, a permission set may grant it in systemPermissions, and a resource may name it in requiredPermissions. org is the right scope: the door acts on the caller's own organization's connection (Q1 = A) and the holder never sees a token.
  • The door asks that capability and nothing else, fail-closed - right. refuseUngrantedConnectorConnectionAccess admits isSystem, then a caller whose systemPermissions holds manage_connector_connections, and refuses everyone else 403 PERMISSION_DENIED ahead of the service probe and the query checks, for all four members (GET/POST/DELETE :name/connection, GET oauth/callback). manage_metadata alone, even with the whole platform-admin bundle beside it, no longer admits; an absent capability list refuses; the walled postures still serve the holder. The door test pins each of those both ways, and the dev's ablations (gate also admits manage_metadata → 4 pins red; gate removed → 13 red; organization_admin granted → 4 plugin-security pins red) show the pins hold the line.
  • Default grants widen by exactly one set - right. ADMIN_FULL_ACCESS_CAPABILITIES carries the capability, so admin_full_access holders (platform administrators) reach the door as they did under manage_metadata; every other shipped set, the two organization-administrator sets included, withholds it, pinned by holders toEqual ['admin_full_access'] in plugin-security and by the transcribed grant in the door test. The six goldens that spell out the platform-admin envelope gain the one name. No released caller loses access: the door landed in feat(service-automation): serve oauth2 connector instances per dispatch, and connect an authorization_code instance per organization (ADR-0143 S1) #28317 inside this unreleased line, as the changeset says.
  • The declaration follows the capability everywhere it is read - right. The four route-ledger rows name the capability and say manage_metadata does not admit; connectors.mdx says the three connect calls need the organization-scoped capability and how it is granted; the Setup capability picker's curated set and the field default carry the label, and the ten packs carry it under capability.label with the locale-parity pins. The spec pin asserts the entry is org and in the admin list.
  • Clause-② yes (widening) and Metadata-protocol: added - accepted. A new member of PLATFORM_CAPABILITIES is a protocol addition an author can write into a permission set; nothing is narrowed for an author. The runtime side is a narrowing for a caller who held only manage_metadata, which the changeset states in plain words and which affects no published version.
  • Check-runs as gate verdicts - read as above; every latest run per name on this head completed green or skipped, Spec property liveness among them.

② Semver level

  • @objectstack/spec, @objectstack/runtime minor; @object-ui/fields, @object-ui/i18n minor - accepted. A served capability name is a minor on spec and runtime; the two ui packages gain one label key each (a new capability.label row in every pack), which is a widening and takes minor by the dev's choice; patch would also have been defensible under the ui precedent, and either is fine for an additive key.

③ Boundary flags

④ Design judgment

  • Tried: a caller holding the capability but no tenantId (the handlers' own 400 VALIDATION_ERROR for a caller with no organization still applies after the gate, unchanged); the callback reached by a browser whose session lacks the capability after an administrator began the connect (refused 403, which is right: the same person began it); whether the capability should also cover the credential door (no: credential references are platform configuration and keep manage_metadata, as the SF4 finding scoped it). Nothing to add.

Verdict reasoning. The capability is one well-formed org-scoped registry row, the four door members ask it alone and fail closed with the platform administrator the only default holder, the ledger, docs, picker and packs follow the declaration, the pins hold under three ablations, the one open question is a maintainer ruling the PR does not pre-empt, and every latest check on this head is green or skipped.

Implemented-by: claude/project-thread-6ytsf3
Reviewed-by: session_01L9qibw58ehQ2gRHP2h2Puz

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#1 · os-tesla · session_01L9qibz3ZUbZ8Qcn1rDw9yc

维护者速读

  • 改了什么:连接器的 OAuth 连接入口(查看状态、发起连接、回调、撤销四个接口)原来只要平台级的 manage_metadata 权限就能用,现在改为只认新增的组织级权限 manage_connector_connections。默认只有平台管理员(admin_full_access)持有它;组织管理员要单独授予。Setup 的权限选择器和 10 种语言包里加了它的名字。
  • 为什么改:security: a dedicated org-scoped manage_connector_connections capability for connecting OAuth2 connector instances (before ADR-0143 S4's Console flow) #28327:给一个组织连接第三方账号是组织内的动作,而 manage_metadata 是平台级权限,口径不对;ADR-0143 D5 本就把这个权限交给服务端切片来定义,要在 S4 控制台连接页上线前落地。
  • 风险与回滚:只收紧不放宽:只持有 manage_metadata 的人不能再用这四个接口;这些接口在 feat(service-automation): serve oauth2 connector instances per dispatch, and connect an authorization_code instance per organization (ADR-0143 S1) #28317 才加入,尚未发版,没有已发布的调用方受影响。回滚即 revert。
  • 先看:packages/runtime/src/domains/automation.ts 的 refuseUngrantedConnectorConnectionAccess,packages/spec/src/security/capabilities.ts 新增的一行。
  • 两分钟验证:pnpm --filter @objectstack/runtime exec vitest run src/domains/automation-connector-connection-door.test.ts,全部通过。
  • 需要你做的:S4 上线前裁一件事:组织管理员是否默认持有这个权限(本 PR 不给,见席位意见)。

席位意见:契约复审 PASS(6543044473),四个接口失败即拒、两向都有消融 pin;组织管理员默认授权是放宽,留给你在 S4 前裁,不挡本 PR。可以直接落地。

席位核对

ACCEPT · seat domain:server#1 · head 3979c8fb · 2026-10-31T11:58Z

  1. Shape: Fixes #28327, draft, base main, 25 files, +173/−28: the spec capability row (the triage-granted one-PR exception, 6539801921), ADMIN_FULL_ACCESS_CAPABILITIES, the door gate and four route-ledger rows in packages/runtime, plugin-security pins and goldens, the Setup picker label + 10 locale rows, connectors.mdx, changeset. The ui rows and the docs line are the card's "Setup widget" and the declaration following its readers; accepted as part of the card's Wanted.
  2. Premise measured: at the claim, capabilities.ts had no manage_connector_connections and feat(service-automation): serve oauth2 connector instances per dispatch, and connect an authorization_code instance per organization (ADR-0143 S1) #28317 had merged; the head is a clean merge of main ac09e7b8.
  3. Gates / check-runs: contract review PASS 6543044473 on this head (70 runs completed, none failed). At this read 59 success / 13 skipped / 1 in progress (a re-triggered Check Changeset); auto-merge waits for it. Dev: 111 of 113 derived gates exit 0, 2 NOT MEASURED (dual-build-cjs-loads, i18n; CI carries), lint green, 3 ablations red then restored (os-dev-report 6542678512).
  4. Accepted deviations: none.
  5. Out of scope: whether organization_admin / organization_admin_no_bypass hold the capability by default is a widening reserved to the maintainer, to be ruled before ADR-0143 S4 ships; if granted, it is a one-line follow-up card. Skills-docs: none — Metadata-protocol: added.
  6. Landing: check-governed-merges --pr 28400 NOT governed, 201 changed lines ≤ 3000. The seat readies the PR and arms auto-merge under the maintainer's 「按 pm-dispatch 审过的pr你可以自主落地」.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

security: a dedicated org-scoped manage_connector_connections capability for connecting OAuth2 connector instances (before ADR-0143 S4's Console flow)

1 participant