Skip to content

spec: an API-backed datasource's external block names a declared connector instance and borrows its credential (D7, ruling 6486136301) — epic #27261 P2 #27742

Closed

Description

@objectstack-fleet

epic:#27261#1 · marchtian · session_017ihL2c5z3q4h8inrn5kwqV
Filing gate: ③ maintainer-directed — 田騏 at 2026-10-29T21:58Z 「现在启动全部 P2」 (epic comment 6509296853, D1 amended), at 2026-10-29T21:59Z 「OData 驱动 只做 v4」 (6509311454), at 2026-10-29T22:01Z 「同意」 (generic P2 parts open source in this repository; vendor-specific drivers such as Salesforce stay out of it).
Ruling-ref: 6486145005 (#27299, Tier B = declarative OData) · 6486136301 (#27298, D7) · 6471382887 (#27261 D1–D6)
Dedupe (open AND closed): "OData datasource driver $metadata import connector credential external datasource" → 5 hits, none this work (#27298 is the ruled decision card).
Reader: the epic PM (#27261) dispatches it in the epic subtree.
type: Feature

维护者速读

  • 做什么: 数据源的 external 块加一个可选键,点名一个已声明的连接器实例,借用它的授权(静态、oauth2、app-credential、signed 都行)。实例不存在则构建时拒收。
  • 为什么: SAP / Dynamics 365 都用 OAuth2;一次授权让流程动作和虚拟对象读数共用,重连一次两边都恢复。这是 D7 裁决。
  • 注意: 改已发布 spec,落地前需 Fable 完整复审与契约复审,Tier H 需您批准。
  • 需要您做的: 合并前批准。

Task

Clause-②: yes · Metadata-protocol: added (minor). Touches packages/spec/src/**: full Fable review and a CONTRACT_REVIEW_TIER record before landing; Tier H.

Activity

  1. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#27261#1 · marchtian · session_017ihL2c5z3q4h8inrn5kwqV
    Claim: PM loop round 8 2026-10-29T22:11Z
    Session: session_017ihL2c5z3q4h8inrn5kwqV (epic PM); implementing card thread session_017ihL2eRfGhMmx9N4rdwNtG
    Account: marchtian
    Branch: claude/project-thread-15sb9m (the card thread's platform-assigned branch — measured platform exception to claude/issue-<n>-<slug>)
    Worktree: objectstack-issue-27742
    Domain: domain:spec
    Seat: epic:#27261#1 (epic PM; no domain:* seat). Maintainer order, 田騏 2026-10-29T21:58Z: 「现在启动全部 P2」 (D7, ruling 6486136301, letter A)
    File surface: packages/spec/src/data/datasource.zod.ts (one optional external member naming a connector instance) and the build-time reference check, their tests, docs/adr/0015-external-datasource-federation.md (the D7 amendment note), generated references the spec change re-records, .changeset/** (stop on breach; explain in the report)
    Container & model: S, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: high
    Clause-②: yes
    Metadata-protocol: added
    Responsibility: ruling 6486136301 on #27298 (D7), filed by the maintainer's P2 start on epic #27261
    Thread-read: none
    Premise: holds — on origin/main a datasource's credentials come only from external.credentialsRef; no datasource key names a connector instance.
    Serial constraints: #27746 (runtime seam) is Blocked-by this card. Contract face (published spec, Clause-②: yes, an ADR): the PR body says "Fable review owed"; it needs a full Fable review, a CONTRACT_REVIEW_TIER record PASS and the maintainer's approval (Tier H) before it lands.

  2. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
     "issue": 27742,
     "status": "done",
     "branch": "claude/project-thread-15sb9m",
     "pr": "https://github.com/objectstack-ai/objectstack/pull/27783",
     "session": "session_017ihL2eRfGhMmx9N4rdwNtG",
     "premise_still_valid": true,
     "summary": "ExternalDatasourceSettingsSchema gains optional `connector` (snake_case name of a declared connector instance whose credential an API-backed datasource borrows, ADR-0015 amendment D7 / ruling 6486136301). DatasourceSchema refuses it beside a bound credentialsRef (exclusive, not precedence), on a built-in DRIVER_VOCABULARY driver (prescribes credentialsRef) and on a managed plugin-driver datasource (prescribes schemaMode external); validateCrossReferences gains collectDatasourceConnectorErrors, refusing at defineStack / os validate (STACK_CROSS_REFERENCE_INVALID 422) a name with no connectors entry, an entry with no provider, or an instance with no auth / auth none. ADR-0015 gets a D7 amendment note answering the ruling's open reading (the (organization, connector instance) binding fits an environment-level datasource under #27230 S1: one organization per environment means exactly one connection; a no-organization read takes ADR-0143 D4's exactly-one rule, fail-closed otherwise). Liveness row `planned` (runtime half is #27746), credential-name ratchet allow-lists the key with its reason, changeset minor.",
     "tests": "On eda26e3c under os-verify-lock: `pnpm --filter @objectstack/spec test` Test Files 756 passed (756), Tests 22468 passed | 1 todo, command-exit 0 (4m15s); `pnpm --filter @objectstack/spec typecheck` command-exit 0 (1m22s). New: src/stack-datasource-connector.test.ts (8 cases) and the external.connector block in src/data/datasource.test.ts (11 cases). Ablations via scripts/ablation-replace.mjs (mutation landed, restored, git diff HEAD empty): removing the collectDatasourceConnectorErrors call (blob c8cc7c644281 to e0bfdb0f2204) gives stack test 5 failed / 3 passed (controls green); disabling the parse-refusal guard (blob e0f177402a59 to 1090eb4caaf4) gives 4 failed / 7 passed. First full spec run caught the credential-name ratchet (metadata-credential-fields.test.ts) flagging datasource:external.connector; allow-listed with a reason, re-run green.",
     "gates": "Local, eda26e3c (after one merge of origin/main): dispatch-gates --commands derived 111 families; 105 exit 0 first pass, 6 exit 3 (plugin-teardown fixture, lint build, built dists) each re-run exit 0 after its prerequisite; `dispatch-gates --ran`: 111 derived, 111 run, 0 NOT-MEASURED, 0 UNRUN. spec check:generated 14/14 up to date. PR check-runs: in_progress at report time (not waited, per contract).",
     "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
     "mcp_calls": "6 — mcp__github__issue_read x5 (#27742 body, #27742 comments x2, #27298 comments, #27230), mcp__github__pull_request_read x1 (#27658 body as a template); no write tool",
     "api_writes": "2 relay writes as objectstack-fleet[bot]: pr_create (draft #27783, assignees marchtian mirrored from the card) and this os-dev-report comment; plus git push of the branch",
     "open_questions": [],
     "out_of_scope_findings": [
      "carrier: #27746 · noted, not filed — no runtime reads external.connector until the runtime half lands; it should ship in the same release (liveness row planned, changeset says so)",
      "carrier: #27746 · noted, not filed — a runtime-created (Studio) datasource never passes defineStack, so the instance-declared check must also run at the runtime's boot/save seams",
      "carrier: epic PM (#27261) · noted, not filed — the epic body §4 item 8 amendment per the ruling is the epic PM's edit",
      "carrier: PM (Skills-docs follow-up owed) · skills/objectstack-data/rules/datasources.md, content/docs/data-modeling/virtual-objects.mdx, content/docs/data-modeling/external-datasources.mdx still teach credentialsRef as the only channel; teach external.connector with or after #27746",
      "carrier: none · noted, not filed — no scripts/adr-anchors file added (not on the claim's file surface); both refusal sites cite ADR-0015 D7 in comments"
     ]
    }
  3. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#27261#1 · marchtian · session_017ihL2c5z3q4h8inrn5kwqV
    Landed · 2026-10-30T01:39Z

    PR #27783 merged through the queue as b373263195 on 2026-10-30T01:37:25Z (head 400e1b09; contract review PASS 6511230689 + delta PASS 6511651329 at CONTRACT_REVIEW_TIER, which also served as the full review of the spec and ADR change; seat ACCEPT 6511694932; Tier H APPROVED by os-zhuang). The datasource external block accepts connector, which names a declared connector instance to borrow its credential (D7). It is exclusive with credentialsRef and refused on built-in drivers and managed datasources. ADR-0015 carries the D7 note. Follow-ons: the runtime half #27746 (PR #27819, same release; it flips the liveness row to live), the composed counterpart #27803, and skills and docs #27786.

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions