Repository navigation
Commit 4bc077d
docs(automation): connector credential texts follow the degrade rule (ADR-0097 note, clearConnectorCredential 503, QA item) (#28346)
domain:spec#2 · os-tesla · session_01L9qibx5r5nhDMwpRs4SL6D
<!-- claude-projects-attribution: {"github_login":"os-tesla"} -->
_Requested by **Tesla** · [project
thread](https://claude.ai/code/project/chan_01AXsQkLFKRdQCqQ3RTr6Jao?thread=cmsg_01AXsQkLFKRdQCqQ3RTr6JaoBztoGKkaTTuEcZrcnG8Yhv)_
Fixes #27429
Clause-②: no (text only)
Metadata-protocol: none
## 维护者速读
- 改了什么:六处文字跟上连接器凭据的现行规则:ADR-0097
加一条带日期的修订说明和一行指引,`clearConnectorCredential` 的拒绝清单补上 `503`,连接器文档与 MCP
提供方的一句注释不再把"凭据引用解析不到"归为启动失败,QA
清单的一条用例改为验收"降级"而不是"启动失败",自动化服务里连接器物化函数的说明注释同样改正。
- 为什么改:#27237
之后,凭据引用解析不到时只把该连接器实例降级(应用照常启动,管理员事后补填凭据即可恢复),清除已存凭据会把在线实例拆下;这六处仍写着旧规则,AI
和作者读到会照着错的规则写元数据、写测试。
- 风险与回滚:只改注释、文档和 QA 清单文字,不动任何运行行为;回滚即 revert 本 PR。ADR 改动使本 PR 属 Tier
H,需要授权审批。
- 先看:`docs/adr/0097-declarative-connector-instances.md` 中 "Runtime
reconcile"
下的新修订说明;`docs/qa/platform-checklist/areas/integration-system.json` 条目
`integration-system.connector-auth-kind-application` 的 `acceptance[2]` 与
`negative[2]`;`packages/spec/src/contracts/automation-service.ts` 的
`clearConnectorCredential` 注释。
- 两分钟验证:`pnpm check:platform-checklist && pnpm
check:adr-symbol-anchors`,预期两个都通过(清单校验认可 revision 5,ADR 里引用的
`#degradeConnectorForCredential` 能解析到代码)。
- 需要你做的:以 os-zhuang 审批本 PR(Tier H,ADR 一行);之后由席位落地。
## What changes
#27237 (PR #27344) made an unresolved or refused `credentialRef` degrade
its instance instead of failing the boot, and its credential door's
`DELETE` tears a live instance down. Five texts still stated the old
rule, and a sixth (the materializer's own docblock) was folded in by the
seat's claim amendment. Each was measured against `main` at `501c864d`
(`plugin.ts#degradeConnectorForCredential`, `#clearConnectorCredential`,
`#doorCredentialChain`, `#scheduleDeclarativeRetry`) before it was
rewritten. None of them had been fixed by a later PR; the card's line
numbers had drifted (noted per item).
1. **`docs/adr/0097-declarative-connector-instances.md`** (Tier H;
triage 6490151714's cross-domain exception).
- A dated amendment note under "Runtime reconcile": an unresolvable
`credentialRef` leaves the reload list, as it left the boot list (the §6
note). A reference no source answers for degrades its instance at boot
and on a reload alike, and a live connector under that name is torn down
first; that is how a cleared stored credential takes its instances down.
A stored credential the deployment cannot read right now (unreadable
store, no crypto provider yet) degrades too but leaves a live connector
serving. Both go on the backoff. A host resolver that throws keeps the
old rule (fatal at boot, logged and skipped on reload). Each fact is
read from `degradeConnectorForCredential` and the reconcile's `catch`
around `resolveConnectorCredential`.
- A one-line pointer in the "Upstream availability" lead, after "stay
fatal at boot", naming the notes under §6 and under "Runtime reconcile".
- The header's `Amended by` line gains the entry for this note, as every
earlier amendment of this ADR has one.
2. **`packages/spec/src/contracts/automation-service.ts`**,
`IAutomationService.clearConnectorCredential`: the refusal list gains
`503 SERVICE_UNAVAILABLE` (when the store cannot be read or written,
`ConnectorCredentialUnavailableError` in `#clearConnectorCredential`, or
the tenancy posture cannot be read, `#doorCredentialChain`), nothing
changed. Docblock only.
3. **`content/docs/automation/connectors.mdx`** (card ≈L361, now L407):
the inline-secret example's "a reference, resolved at boot" becomes
"resolved at materialization (unset, it degrades the instance)". The
failure table at L593 already states the degrade.
4. **`packages/connectors/connector-mcp/src/mcp-provider.ts`** (card
≈L243, now L273): the comment no longer groups a rejected credential
"like an unresolvable credentialRef" on the fatal side; it says an
unresolvable reference never reaches the factory, since the materializer
degrades its instance first.
5. **`docs/qa/platform-checklist/areas/integration-system.json`**, item
`integration-system.connector-auth-kind-application` (card L1943 /
L1992, now L1961 / L2010), revision 4 → 5 with a history row:
`acceptance[2]` grades the degrade (api oracle: the degraded descriptor
naming the reference and its remedies, the boot's warn line, the
dispatch failure) and `negative[2]` fails a boot that dies on it; the
title, `fixtures.requires[2]` (the env → `sys_connector_credential` →
host resolver chain), `steps[3]`, `steps[5]`, `automated.ref` and
`source[2]` follow. The cited pin "fails boot loudly when credentialRef
does not resolve" no longer exists; the item now cites "degrades the
instance, naming the reference, when credentialRef does not resolve"
(`connector-materialization.test.ts`) and "missing → degraded naming the
reference; set → ready; clear → degraded again"
(`connector-credential-door.test.ts`), both run below.
6. **`packages/services/service-automation/src/plugin.ts`**, the
`materializeDeclaredConnectors` docblock (≈L2093; added by the seat's
claim amendment): the boot-fatal / reload-skipped list no longer names
an unresolvable `credentialRef` (it names the host resolver that throws,
which does keep that rule), and a paragraph says such a reference
degrades its instance in both modes, tearing a live connector down first
(`{@link degradeConnectorForCredential}`). Comment only.
No changeset: the diff publishes no behaviour, only comment and docblock
text (`skip-changeset` declared at create).
## Tests
No test changes: text only. The two pins the QA item now cites exist and
pass (output under Verification).
## Acceptance notes
- `@objectstack/lint` author-facing text says a `credentialRef` is
"resolved at boot" (`credential-literal.ts` ≈L22,
`lint-flow-credential-literals.ts` ≈L29, `rule-explanations.ts` ≈L4705,
the last pinned at `lint-flow-credential-literals.test.ts` ≈L502). It
describes where the secret lives rather than the failure rule, so it is
loose rather than wrong; carrier: none, noted only.
- ADR-0097's 2026-10-27 note (PR #26798) still says a rejected MCP
credential sits "beside an unresolvable `credentialRef`" on the fatal
side. The 2026-10-28 note right after it already reverses the
rejected-credential half, and the new lead pointer covers the
`credentialRef` half; the dated note itself is left as written
(amendments are append-only).
- `clearConnectorCredential` also answers `400 VALIDATION_ERROR` for an
empty or oversized reference (`#credentialRefOfRequest`), which its
docblock does not list either. Left out: the ruling grants this one
docblock line for the `503`.
- The QA item's new `acceptance[2]` was not run live (no echo-upstream
fixture in this container); its evidence is this body and the item's
history row, as RUNNER.md asks for a ledger edit's own verification.
## Verification
<details><summary>pins the QA item cites</summary>
- Under the verify lock: `pnpm --filter @objectstack/service-automation
exec vitest run --maxWorkers=2 src/connector-materialization.test.ts
src/connector-credential-door.test.ts -t 'TWO_CASE_NAMES' (the two names
above)` → Test Files 2 passed (2), Tests 2 passed | 82 skipped (84);
VERDICT command-exit 0.
</details>
<details><summary>derived gates</summary>
- At `8b24dd6d` (after the sixth text): `node
scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derives 98 families (the 95 below plus
`check-tenant-audit-census` and its `--self-test`, and
`check:durability-log-level`), each run with stdin from `/dev/null`,
exit code recorded before any pipe, after a dts rebuild of
`@objectstack/service-automation` (record:
`27429-gates-ran-8b24dd6d.list` in the seat's out folder). `--ran`
reconciliation: 98 derived, 98 run, 0 NOT-MEASURED, 0 UNRUN, all exit 0.
- At `eef6c15b` (the five texts): 95 families, record
`27429-gates-ran-eef6c15b.list`, after a dts build of every non-ui,
non-docs package (turbo, lock VERDICT command-exit 0).
`check-plugin-teardown-shape --self-test` first exited 3 on the shallow
clone (its pinned control `621a4876` unreachable); after `git fetch
origin 621a487 --depth=1` it exited 0. `--ran`: 95 derived, 95 run, 0
NOT-MEASURED, 0 UNRUN, all exit 0.
</details>
---
_Generated by [Claude
Code](https://claude.ai/code/session_01L9qibx4wGGSrBq1y8R1CVJ)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 4fa4f2c commit 4bc077d
6 files changed
Lines changed: 52 additions & 22 deletions
File tree
- content/docs/automation
- docs
- adr
- qa/platform-checklist/areas
- packages
- connectors/connector-mcp/src
- services/service-automation/src
- spec/src/contracts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
415 | 415 | | |
416 | 416 | | |
417 | 417 | | |
418 | | - | |
| 418 | + | |
419 | 419 | | |
420 | 420 | | |
421 | 421 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| |||
167 | 167 | | |
168 | 168 | | |
169 | 169 | | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
170 | 183 | | |
171 | 184 | | |
172 | 185 | | |
173 | 186 | | |
174 | | - | |
| 187 | + | |
| 188 | + | |
175 | 189 | | |
176 | 190 | | |
177 | 191 | | |
| |||
0 commit comments