Repository navigation
Commit e9caebe
docs(skills): objectstack-data and the data-modeling guides teach external.connector, the credential a datasource borrows from a connector instance, and point plugin drivers at the conformance kit (#27954)
epic:#27261#1 · marchtian · session_017ihL2eXpMhQkzjoYjCTKR6
<!-- claude-projects-attribution: {"github_login":"marchtian"} -->
_Requested by **田騏** · [project
thread](https://claude.ai/code/project/chan_01VmuUhXU9SSUzqJYyXSmYSi?thread=cmsg_01VmuUhXU9SSUzqJYyXSmYSi7kfzPizGsPKjJnaEN8RzYK)_
**Fable review owed.** Written while the Fable quota is out. This PR
touches `skills/**` (Tier H): it lands only after an independent full
review at `CONTRACT_REVIEW_TIER`, a contract review record PASS on its
head, and an approver's APPROVE. Kept in draft until then.
Fixes #27786
Clause-②: no
Metadata-protocol: none
## 维护者速读
- **改了什么:** 技能 `objectstack-data` 的数据源规则和三篇数据建模指南开始教
`external.connector`:API 型数据源(插件驱动,如
OData)可以借用一个已声明连接器实例的凭据,一次授权同时服务连接器的流程动作和数据源的记录;与 `credentialsRef`
二选一,内置数据库驱动和 managed 数据源上被拒。指南给出一个完整示例(OData 数据源点名连接器实例)、拒绝规则、连接时
fail-closed、凭据未设置时每次请求 503、401 刷新一次重试。`virtual-objects.mdx`
另说明自写插件驱动如何自己借用并出示凭据,并新增「Run the conformance kit」一节,指向
`@objectstack/objectql` 的 `definePluginDriverConformanceSuite`。
- **为什么改:** D7 裁决(6486136301)的技能与文档一半;spec(#27783)和运行时(#27819)都已在
`main`,但技能和指南只教 `credentialsRef`,AI 作者不知道这个键。
- **风险与回滚:** 只改技能规则、文档和一个 `@objectstack/skills` patch changeset;不动代码与
schema。技能文件在 token 上限内(909/911,上限不动)。回滚即 revert。
- **先看:** `skills/objectstack-data/rules/datasources.md` 的 Credentials
一节;`external-datasources.mdx` 的「Borrowing a connector instance's
credential」。
- **需要您做的:** Fable 复审与契约复审通过后批准(Tier H)。
## What changes
- **`skills/objectstack-data/rules/datasources.md`** — "Credentials —
one channel, fail-closed": `external` names exactly one credential
channel, `credentialsRef` (a secret-store handle resolved at connect) or
`connector` (an API-backed datasource on a plugin driver such as
`@objectstack/driver-odata` borrows the credential of a declared
`connectors` instance with a `provider` and an `auth`). Where
`connector` is refused (beside `credentialsRef`, on a built-in driver,
on a `managed` datasource), and that an instance that cannot lend, or a
stack with no automation service, leaves the datasource unconnected with
the reason. The form is shown as `schemaMode: 'external', external: {
connector: 'erp_api' }`, the instance's `auth` must be other than
`none`, an undeclared instance is refused at `defineStack` (else at
connect), and a connector credential not set yet answers `503` per
request. Paid for inside the file (the `field.columnName` history
clause, the auto-connect lead-in, the escape-hatch note and phrases that
restated their neighbours shortened or dropped): 903 to 909 tokens
against a ceiling of 911, which does not move.
- **`content/docs/data-modeling/external-datasources.mdx`** — §4
Credentials gains "Borrowing a connector instance's credential": the
channel, an `os:check` example (a `rest` connector instance `erp_api`
with a bearer `credentialRef`, and an OData datasource naming it), how
the instance's `auth` is presented, and the rules: one channel,
API-backed datasources only, an instance that can lend (judged when the
stack is validated and when a datasource is saved under Setup),
fail-closed at connect, a credential not set yet answered `503` per
request until it is set, rotation (a store write reaches the next
request; a `401` is retried once with a fresh credential).
- **`content/docs/data-modeling/odata-datasources.mdx`** (scope addition
6513665711) — §3 Credentials names the two channels; the existing text
becomes "A secret of its own: `credentialsRef`", unchanged, the `os
serve` caveat sentence included (#27875's); a new "Borrowing a connector
instance's credential" subsection shows the stack fragment with the
plugin's `auth` left at `none`, how each `auth` type is sent, the borrow
at the first request and the refresh/401 rule, and the fail-closed list.
The "Check the service first" bullet and the `auth` option row mention
the connector path.
- **`content/docs/data-modeling/virtual-objects.mdx`** — the Credentials
section says what `external.connector` does for a driver of your own:
the connect step judges the instance but hands an already-built driver
nothing, so the driver borrows from the `connector-credential-source`
service and presents through `callWithBorrowedCredential`, scrubbing
upstream text with `withoutBorrowedCredential` (a sketch, with the OData
driver as the reference). New "Run the conformance kit" subsection
(scope addition 6513665711): `definePluginDriverConformanceSuite` /
`runPluginDriverConformance` from `@objectstack/objectql`, a minimal
call, what the floor tier asserts, `setupUnavailable`, `writeProbes`,
the opt-in `direct` tier, and the OData driver's own run. Floor step 3
now says the kit ships and the trust built on it does not exist yet.
- **`.changeset/27786-skills-external-connector.md`** —
`@objectstack/skills` patch (route 1), both declaration lines.
## Why
ADR-0015 amendment D7 (ruling 6486136301 on #27298): one Connect per
vendor serves the connector's flow actions and the datasource's virtual
objects. The spec half (#27742, PR #27783) and the runtime half (#27746,
PR #27819, `ed8b2375`) are on `main`; the datasources skill rule and the
data-modeling guides still taught only `credentialsRef`, and no guide
pointed an out-of-repo driver at the conformance kit (#27744, PR
#27798).
## Verification
- **The examples parse against `main`'s schema.** With
`@objectstack/spec` built from this tree, `defineStack` accepts the
`os:check` example in `external-datasources.mdx` and the OData fragment
wrapped into a stack. Each refusal the pages name was run too and
refused with the message described: both channels, `connector` on
`postgres`, `connector` on a `managed` datasource, an undeclared
instance, a catalog descriptor (no `provider`), and `auth: { type:
'none' }`. A disabled instance is accepted at build, as the pages say
(it is refused when the datasource connects).
- **The two `virtual-objects.mdx` sketches type-check.** The credential
sketch against `@objectstack/types` and `@objectstack/core`, the
conformance-kit call against `@objectstack/objectql`, under `strict` (a
planted type error in the same program was reported, so the run checks).
- **Every runtime claim was read off the code at `ed8b2375`:**
`packages/services/service-automation/src/connector-credential-source.ts`
(the lend refusals, disabled included; the handle's 503s; the generation
move on a credential write),
`packages/services/service-datasource/src/datasource-connection-service.ts`
(the already-registered guard's borrow verdict; the factory path) and
`datasource-connector-credential.ts`,
`packages/types/src/connector-credential-source.ts`
(`callWithBorrowedCredential`'s expiry, 401 and 503 rules),
`packages/drivers/driver-odata/src/plugin.ts` and `transport.ts`
(first-request borrow, presentation by `auth` type, the fail-closed
refusals), `packages/objectql/src/external-driver-floor.ts` (a 503
answered `ERR_DATASOURCE_UNAVAILABLE`), and
`packages/objectql/src/plugin-driver-conformance.ts` (options, tiers,
`not-offered`).
- **Local gates:** `node scripts/pm/dispatch-gates.mjs --commands`
derived 67 families from the 5 changed files; after `pnpm build` (exit
0) every one was run with its exit code recorded before any pipe, all 67
exit 0, and `dispatch-gates --ran` reads "67 derived famil(ies)
accounted for — 67 run, 0 NOT-MEASURED (a DERIVED zero)". Among them:
`check:skill-examples` (276 prose examples type-check, the new
`os:check` block included), `check:doc-anchors` (the new
`#borrowing-a-connector-instances-credential` and
`#run-the-conformance-kit` links resolve), `check-skills-token-ratchet`
and `check:skill-identifier-liveness`. Re-run in full on `de6aaf6b` (the
should-fix commit): again 67 derived, 67 run, all exit 0, a DERIVED
zero. Head `de6aaf6b`, `origin/main` merge base `ed0e71db`. The full
battery is CI's.
## Contract review 6515906243 (PASS on `ecb4cd3a`), should-fixes applied
in `de6aaf6b`
No must-fix. The four should-fixes on `rules/datasources.md` are
applied, inside the same token ceiling (909/911):
- **The one-line form.** It now reads `schemaMode: 'external', external:
{ connector: 'erp_api' }`, so copying it alone no longer lands on the
managed refusal.
- **`auth` other than `none`.** Said in the rule, as
`collectDatasourceConnectorErrors` and `lendRefusal` judge it.
- **Where an undeclared instance is refused.** "naming an undeclared
instance (at `defineStack`, else at connect)".
- **A credential not set yet.** "A connector credential not set yet
answers `503` per request", separate from the connect failures.
- **PR body.** The model name is removed from the opening paragraph.
- Not changed: the pre-existing "`credentialsRef` … resolved at connect,
before the driver is built" sentence, which the review notes for the
next edit of the file.
The commit only applies findings, so it owes a delta review by the same
reviewer.
## Acceptance notes
- **The skill rule carries no runnable example.** The file had 8 tokens
of headroom; the example lives in the guides, and the rule shows the
one-line `external: { connector: 'erp_api' }` form.
- **"Setup → Connector credentials"** appears in the runtime's own
refusal text, but no Console page by that name was found under `ui/`;
the guides point at the connectors page's "What `credentialRef` resolves
through" instead of naming a Setup page.
- **Worktree name:** the Claim names `objectstack-issue-27786`; the
worktree is `objectstack-27786` on the claimed branch.
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(Not touched.)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; no source file changed (`pnpm lint` is CI's).
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset, and both
declaration lines are filled in here and in the changeset.
- [x] 6. `packages/spec` touched: not touched.
- [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
repo's own Chinese reader section).
- [x] The *Before Submitting* list in CONTRIBUTING.md is done.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_017ihL2eXpMhQkzjoYjCTKR6
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent e8cdf4e commit e9caebe
5 files changed
Lines changed: 265 additions & 28 deletions
File tree
- .changeset
- content/docs/data-modeling
- skills/objectstack-data/rules
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
263 | 263 | | |
264 | 264 | | |
265 | 265 | | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
266 | 336 | | |
267 | 337 | | |
268 | 338 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
36 | | - | |
| 36 | + | |
| 37 | + | |
37 | 38 | | |
38 | 39 | | |
39 | 40 | | |
| |||
61 | 62 | | |
62 | 63 | | |
63 | 64 | | |
64 | | - | |
| 65 | + | |
65 | 66 | | |
66 | 67 | | |
67 | 68 | | |
| |||
164 | 165 | | |
165 | 166 | | |
166 | 167 | | |
167 | | - | |
168 | | - | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
169 | 179 | | |
170 | 180 | | |
171 | 181 | | |
| |||
197 | 207 | | |
198 | 208 | | |
199 | 209 | | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
200 | 260 | | |
201 | 261 | | |
202 | 262 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
460 | 460 | | |
461 | 461 | | |
462 | 462 | | |
463 | | - | |
| 463 | + | |
| 464 | + | |
464 | 465 | | |
465 | 466 | | |
466 | 467 | | |
| |||
492 | 493 | | |
493 | 494 | | |
494 | 495 | | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
| 542 | + | |
| 543 | + | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
495 | 551 | | |
496 | 552 | | |
497 | 553 | | |
| |||
604 | 660 | | |
605 | 661 | | |
606 | 662 | | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
| 682 | + | |
| 683 | + | |
| 684 | + | |
| 685 | + | |
| 686 | + | |
| 687 | + | |
| 688 | + | |
| 689 | + | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
607 | 698 | | |
608 | 699 | | |
609 | 700 | | |
| |||
0 commit comments