Repository navigation
Commit 5e99bd9
docs(adr): ADR-0097 "Upstream availability" states the mcp credential-rejection carve-out (fatal configuration fault, never retried) (#26985)
<!-- claude-projects-attribution: {"github_login":"os-steve"} -->
_Requested by **Steve** · [project
thread](https://claude.ai/code/project/chan_01FdL1XeUyvVNxLreh3F4Qi9?thread=cmsg_01FdL1XeUyvVNxLreh3F4Qi9X1enG32HTqd5EwZdc8niqU)_
Fixes #26809
Clause-②: no
Metadata-protocol: none
## 维护者速读
- **改了什么**:ADR-0097「Upstream availability」一节追加一条带日期的修订注(append-only):MCP
服务器**拒收凭据**(connect / handshake / `tools/list` 收到 HTTP 401 /
403)是**配置错误**——启动即失败、reload 时跳过、不重试;原句不改。文件头 `**Amended by**` 行同步补一条目。
- **为什么改**:PR #26798(#26709 第 3(b) 项)已让 `mcp` provider 这样分类,但 ADR
原句仍说「所有 connect / `tools/list` 失败都归为 unavailable(降级重试)」。读 ADR 的 agent /
运维会得出「凭据错了会自动重试」的错误结论,而运行时实际直接拒绝启动。
- **风险与回滚**:仅 `docs/adr/0097-declarative-connector-instances.md`
一个文件、+20/-1 行,不发布、无 changeset。回滚即 revert 本 PR。
- **先看**:`docs/adr/0097-declarative-connector-instances.md`
的修订注(「Upstream availability」节 `mcp` 段落之后),再看第 8 行 `**Amended by**` 新条目。
- **两分钟验证**:`pnpm check:adr-symbol-anchors && pnpm
check:adr-index`,预期两者绿;`git grep -n "classifies connect" --
docs/adr/0097*` 仍恰好 1 处(原句未动)。
- **需要你做的**:批准本 PR(`docs/adr/**` 受管面 Tier H,席位不 ready / 不 arm / 不入队)。
## What changes
One file, `docs/adr/0097-declarative-connector-instances.md`:
- **A dated, append-only amendment note** under "Upstream availability:
degrade, don't die", directly after the paragraph that says the `mcp`
provider classifies connect / `tools/list` failures as unavailable. The
note states the one exception past transport validation: a credential
the MCP server rejects (HTTP 401 / 403 on connect, handshake or
`tools/list`) is a configuration fault, thrown plain — fatal at boot, a
skipped entry on reload, never `CONNECTOR_UPSTREAM_UNAVAILABLE`, never
retried — on the fatal side of the section's own split beside an
unresolvable `credentialRef` and the `openapi` provider's non-retryable
`4xx` on its spec fetch. It says why (retrying cannot make a wrong,
missing or under-scoped credential valid; a degraded instance retried
with backoff reads as "server down") and how the rejection is told apart
(the MCP SDK's own `StreamableHTTPError` 401 / 403 or
`UnauthorizedError` in the `cause` chain; a JSON-RPC error merely
carrying code 401 stays operational). The original sentence is **not
rewritten** (AGENTS.md Prime Directive 13).
- **A second entry on the header's existing `**Amended by**` line**
pointing at that note, so a reader of the header learns where the record
was amended, as it already does for ADR-0143.
Every claim in the note is read off `origin/main`, not invented: the
classification and its reason from
`packages/connectors/connector-mcp/src/mcp-provider.ts#credentialRejectionStatus`
and `#createMcpProviderFactory` (the catch branch and its docblock), the
"skipped on reload" half from this ADR's own "Runtime reconcile"
section, and the real-server pin from
`packages/connectors/connector-mcp/src/mcp-http-discovery-faults.test.ts`
(`credential rejection — real Streamable-HTTP server`: 401 and 403 throw
plain and are sent once; a declarative instance answered 401 fails
`kernel.bootstrap()` with no degraded reason and no retry).
Anchors are `path#symbol` as the ADR symbol-anchor gate requires (no
`file:line`). The note cites #26709 item 3(b) and PR #26798 as the card
asks.
## Tests
No code changes, no tests added or edited. No forced test edits.
## Acceptance notes
- The card body asks for the note to cite "#26709 item 3(b) and the PR";
the note's heading carries both, matching this file's existing
`Amendment note (date, source)` convention and ADR-0092 / ADR-0099's
non-ADR amendment notes.
- The card delta asked for "the Status-line `Amended` entry if the
file's convention has one". This file's convention is the `**Amended
by**:` header line (ADR-0005 carries several comma-separated entries
there); the `**Status**:` line itself is untouched, so `check:adr-index`
still reads the record as `Accepted` (the index reads the status keyword
earliest in that line, and `Amended` is in its vocabulary — adding it to
the Status line could have re-keyed the record).
- `skills/**` is not touched: no skill page teaches the `openapi` or
`mcp` provider (PR #26798's body measured 0 hits for the provider
spellings under `skills/`), so no skill text owes a mirror of this note.
- Not published (`docs/adr/**` is on the changeset fast lane): no
changeset; `skip-changeset` is declared on the `pr_create` stroke.
## Verification
Head `f15b7824` (worktree `objectstack-issue-26809`, base `origin/main`
7bb8084, merge base 7bb8084).
<details><summary>Derived gates — node scripts/pm/dispatch-gates.mjs
--commands --repo objectstack-ai/objectstack (21 commands) and --ran
reconciliation</summary>
```
21 command(s) derived (13 by path, 8 whole-tree); exit codes captured per command before any pipe (runner: bash -c CMD < /dev/null; EXIT recorded):
20 exit 0 on the first pass; 1 exit 3 (PREREQUISITE NOT MET, nothing measured):
pnpm --filter @objectstack/lint run check:doc-formula-expressions — needs @objectstack/formula + @objectstack/lint dist
fix applied: os-verify-lock: VERDICT command-exit 0 · held the lock 91s (turbo run build --filter=@objectstack/formula --filter=@objectstack/lint, 4 tasks)
rerun: pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 0
check:adr-symbol-anchors ✅ 2724 anchors across 145 records resolve — 592 symbol (566 declaration, 26 literal), 2085 file-level, 47 cross-repo, 6 exempt, 31 continuation. 0 line anchors survive
check:adr-index adr-index --report: OK — docs/adr/README.md is current, every record parsed, self-test 46 assertions green
check:adr-anchors OK (91 anchored file(s), every governing ADR still referenced; 139 decision number(s) …)
check:adr-links, check:doc-authoring, check:nul-bytes, check:pm-governed-merges, check:pm-prior-rulings, check:closed-ceremony-text, check:gitlink-declared, check:ci-filter-parity, check:cross-package-test-inputs, check:driver-memory-census, check:refd-timer-probe, check:watch-hint-literal, check-closing-keyword-parity (+ --self-test), check-comment-mask-corpus, plan-test-core-shards --self-test: exit 0
--ran (node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran ran.txt):
✓ dispatch-gates --ran: 21 derived famil(ies) accounted for — 21 run, 0 NOT-MEASURED (a DERIVED zero — all 21 recorded an exit code and none of them is 3).
```
</details>
<details><summary>Tier (dispatch-gates --tier)</summary>
```
Model tier — MANDATORY: claude-fable-5-1 (derived from the file surface, not recalled).
- docs/adr/0097-declarative-connector-instances.md ⇢ 'docs/adr/**' … no one-line exemption
Changed lines — 21 (+20 / -1; generated files INCLUDED) vs the human-merge threshold 3000: under.
```
</details>
Not built, not tested locally: the diff touches no package (local
verification scope ① / ② are empty); `pnpm lint` and every whole-tree
family are CI's — see this PR's check-runs.
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(no code change)
- [x] 2. Every name I added uses the casing for its kind. (none added)
- [x] 3. No formatter ran; `pnpm lint` is CI's (no lintable file
changed).
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. Nothing publishes: no changeset, `skip-changeset`; both
declaration lines are above.
- [x] 6. `packages/spec` touched: n/a.
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English (the 维护者速读 block is the
required Chinese business view).
Card thread: `session_01ADHkmSPesP5MpCBMrkkQw5`, dispatched by
`domain:skills#1` (`session_01ADHkmSrRBdu9MdC6fc33Uu`).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01ADHkmSPesP5MpCBMrkkQw5
---
_Generated by [Claude
Code](https://claude.ai/code/session_01ADHkmSPesP5MpCBMrkkQw5)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent eae9a58 commit 5e99bd9
1 file changed
Lines changed: 20 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| |||
190 | 190 | | |
191 | 191 | | |
192 | 192 | | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
193 | 212 | | |
194 | 213 | | |
195 | 214 | | |
| |||
0 commit comments