Skip to content

Commit 461b0d3

Browse files
docs(adr-0143): note that the installer-client server slice landed (PR #29097) (#29483)
<!-- claude-projects-attribution: {"github_login":"os-steve"} --> _Requested by **Steve** · [project thread](https://claude.ai/code/project/chan_01FdL1XeUyvVNxLreh3F4Qi9?thread=cmsg_01FdL1XeUyvVNxLreh3F4Qi9R78d9rMi7xMzr2YvZvjWfQ)_ Fixes #29256 Clause-②: no Metadata-protocol: none domain:server#2 · os-steve · session_01ADHkmPosotet8HaKtCv2id ## 维护者速读 - 改了什么:在 ADR-0143 D2 的「Slices」条下追加一条 2026-11-02 修订注记,记录服务端半边已随 PR #29097 落地;原句一字未改。 - 为什么改:原句写着「服务端未落地前,声明 `clientSource: 'installer'` 的实例会因缺 `clientId` 被判为降级」,#29097 合并后这已不是现状,读者会误以为该键仍不生效。 - 风险与回滚:只改文档,不发布任何包、不改行为;回滚即撤掉本 PR。 - 先看:`docs/adr/0143-outbound-connector-auth-is-open-tier.md` D2.1 修订注记末尾「Slices」条下新增的引用块(仅此一处)。 - 两分钟验证:`node scripts/check-adr-symbol-anchors.mjs`,应看到全部锚点解析通过(比 main 多 4 个符号锚、2 个文件锚)。 - 需要你做的:批准本 PR(受治理 Tier H 文档面,草稿状态等待 GOVERNED_APPROVERS 批准)。 ## What changes - `docs/adr/0143-outbound-connector-auth-is-open-tier.md`: one append-only amendment note, a nested blockquote under the "Slices" bullet of the 2026-11-02 D2.1 note. It records that the server slice landed in PR #29097 (`ec0316ea44`): the connect door takes the installer's client as the closed body `{ clientId, clientSecret? }`; the grant handle uses it for authorize, the code exchange and every refresh; the connection state answers `client { source, clientId, hasSecret }` and never the secret; an instance declaring `clientSource: 'installer'` is no longer held degraded for a missing `clientId`. It names the ui slice, #28869 (open), and what the Console does until it lands. - The sentence beginning "Until the server slice lands" is not rewritten. The Status line and the `Amends` header are untouched (the card's acceptance asks for the note only). - Every fact in the note is read off `origin/main` source at `aca58cdb` (route ledger row, the service's begin rule, `grant-handle.ts#endpointOf`'s kind match, the contract interface, the `clientSource` schema description) and PR #29097's body. Key names: ruling of record `6580268872`, letter A. ## Tests Docs only: no test, no ablation (os-dev: docs are not ablated). The note's six new anchors are checked by `check:adr-symbol-anchors`. ## Acceptance notes - `skip-changeset`: `docs/adr/**` publishes nothing. - No ADR index regeneration was owed: `check:adr-index` reports `docs/adr/README.md` current. - The #29106 card's governed note is on ADR-0066; no shared index file is touched by either. - Governed Tier H: this PR stays a draft until a `GOVERNED_APPROVERS` approval. ## Verification Head `0a3e4078` (the note commit `794155db` plus a merge of `origin/main` `8ca9dd7b`, a `scripts/pm` change). The derived gate list is identical on both heads, and all 21 were re-run on `0a3e4078`. <details><summary>Symbol anchors: main vs this head</summary> - `origin/main` `aca58cdb`: `2977 anchors across 148 records resolve — 702 symbol (675 declaration, 27 literal), 2228 file-level`. - `0a3e4078`: `2983 anchors across 148 records resolve — 706 symbol (679 declaration, 27 literal), 2230 file-level` — the four new symbol anchors (`installerClientOfBegin`, `parseKeptConnectionClient`, `endpointOf`, `ConnectorConnectionState`) and the two test-file anchors all resolve. </details> <details><summary>Derived gates (dispatch-gates --commands, 21 commands)</summary> All 21 exit 0 on `794155db` and again on `0a3e4078`: `check-adr-links` (+ `--self-test`), `check-closing-keyword-parity` (+ `--self-test`), `check-comment-mask-corpus`, `plan-test-core-shards --self-test`, `@objectstack/lint check:doc-formula-expressions` (after `turbo run build --filter=@objectstack/formula --filter=@objectstack/lint` under `os-verify-lock.sh`, VERDICT command-exit 0), `check:adr-anchors`, `check:adr-index`, `check:adr-symbol-anchors`, `check:ci-filter-parity`, `check:closed-ceremony-text`, `check:cross-package-test-inputs`, `check:doc-authoring`, `check:driver-memory-census`, `check:gitlink-declared`, `check:nul-bytes`, `check:pm-governed-merges`, `check:pm-prior-rulings`, `check:refd-timer-probe`, `check:watch-hint-literal`. `dispatch-gates --ran`: 21 derived, 21 run, 0 NOT-MEASURED, 0 UNRUN. </details> --- _Generated by [Claude Code](https://claude.ai/code/session_01ADHkmPosotet8HaKtCv2id)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 325944b commit 461b0d3

1 file changed

Lines changed: 28 additions & 0 deletions

File tree

‎docs/adr/0143-outbound-connector-auth-is-open-tier.md‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,34 @@ carry and forbid; exact key spelling is the spec slice's, reviewed against this
250250
> declared and not served, and its schema description says so: off `provider: 'mcp'` over http an
251251
> instance that declares it is held degraded for a missing `clientId`, and on MCP over http the
252252
> provider registers a client dynamically instead of taking the installer's.
253+
>
254+
> > **Amended (2026-11-02, #29256) — the server slice landed (PR #29097).** The sentence above that
255+
> > begins "Until the server slice lands" records the state before PR #29097, merged on 2026-11-02 as
256+
> > `ec0316ea44`. The key names are the maintainer's ruling of record `6580268872`, letter A.
257+
> >
258+
> > - **The connect door takes the installer's client.** `POST
259+
> > /api/v1/automation/connectors/:name/connection` reads the closed body `{ clientId, clientSecret? }`
260+
> > and hands it to the service as `client`. An instance declaring `clientSource: 'installer'` begun
261+
> > without one, a client offered to an instance that declares its own or registers one dynamically,
262+
> > and any other body key are refused `400 VALIDATION_ERROR`. The read and revoke legs take no client.
263+
> > The rule is `packages/services/service-automation/src/plugin.ts#installerClientOfBegin`.
264+
> > - **The grant handle uses it for authorize, exchange and refresh.** The authorization URL carries its
265+
> > id, the code is exchanged as it, and every refresh sends it. It is kept in the connection's client
266+
> > record, its secret encrypted at rest through the `secret` channel as D3 states, and read back by
267+
> > `packages/services/service-automation/src/oauth2-grant/installer-client.ts#parseKeptConnectionClient`.
268+
> > A kept client whose kind no longer matches the declaration is a reconnect, never used:
269+
> > `packages/services/service-automation/src/oauth2-grant/grant-handle.ts#endpointOf`.
270+
> > - **The state never reads the secret.** The connection state answers
271+
> > `client { source: 'installer', clientId, hasSecret }`, and never the secret:
272+
> > `packages/spec/src/contracts/automation-service.ts#ConnectorConnectionState`.
273+
> > - **The instance is served.** An instance declaring `clientSource: 'installer'` is no longer held
274+
> > degraded for a missing `clientId`, and on MCP over http discovery finds the endpoints and registers
275+
> > no client. The schema description no longer says the key is not served.
276+
> > - **The ui slice is #28869, still open.** Until it lands, the Console begins a connect with no
277+
> > client, so such an instance is refused there with the 400 that names the vendor registration step;
278+
> > the door above connects it. The pins are
279+
> > `packages/services/service-automation/src/connector-connection-door.test.ts` and
280+
> > `packages/qa/dogfood/test/connector-installer-oauth-client.dogfood.test.ts`.
253281
254282
### D3 — Secrets are references; tokens are runtime state in a connection record
255283

0 commit comments

Comments
 (0)