feat(analytics): analytics over federated objects honors the remote table (ADR-0062 Phase 3, D6)#2200
Merged
os-zhuang merged 4 commits intoJun 22, 2026
Conversation
… (ADR-0062 Phase 1) Declare an external datasource → it auto-connects to a live ObjectQL driver and its federated objects are queryable with ZERO app code (no onEnable). Implements ADR-0062 Phase 1 (D1/D2/D5) toward epic #2163. D1 — one connect path: new DatasourceConnectionService owns the single "definition → live driver" path (factory build → credentialsRef resolve → connect → registerDriver under the datasource name → registerDatasourceDef → DDL-free syncObjectSchema per bound object). The runtime-admin registerPool now delegates to it; AppPlugin auto-connects code-defined datasources. Exposed as the 'datasource-connection' kernel service. D2 — opt-in-safe gate: connect only when external, an object explicitly binds via object.datasource, or autoConnect:true. Managed datasources referenced only by a datasourceMapping rule (e.g. app-crm's :memory: datasources) stay metadata-only — existing apps byte-for-byte unchanged. Adds datasource.autoConnect to the spec. D5 — lifecycle/ordering/policy: connect in AppPlugin.start() before the kernel:ready validation gate (init-all-then-start-all). Fail-fast for declared external + onMismatch:'fail'; degrade otherwise (always for runtime-admin/ rehydrate). New host-injectable DatasourceConnectPolicy (open-core default allows; multi-tenant host binds a stricter fail-closed policy) consulted before connect. Tests: 15 connection-service unit tests + 5 runtime integration tests (auto-connect, managed-unrouted stays metadata-only, queryable end-to-end, deny policy). onEnable + ctx.drivers.register remains a supported, idempotent escape hatch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…TS build)
The context logger interface types error(message, error?: Error) — passing a meta
object {appId, error} tripped the tsup DTS build (TS2353) even though tsc --noEmit
passed. Switch to a single interpolated message; the rethrow still surfaces the
real cause to the kernel.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…062 Phase 2, D3) A declared external.credentialsRef MUST resolve to a cleartext secret before the driver is built — an absent secret store or an unresolvable/undecryptable ref now fails closed (clear message, datasource left unconnected) instead of silently building a driver without the credential. Follows the same fail-fast (declared external + onMismatch:fail) vs degrade policy as connect failures. Converges with the runtime-admin secret path (same SecretBinder threaded through the shared connection service). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ADR-0062 Phase 3, D6) NativeSQLStrategy hand-compiles FROM/columns that bypass the driver's physical resolution (remoteName/remoteSchema/columnMap), so it would aggregate against the wrong table for a federated object. It now declines any query whose base or joined object is external (new optional StrategyContext.isExternalObject hook, reported by the analytics plugin from the object's external block), routing it to the ObjectQLStrategy whose engine.aggregate goes through the driver's getBuilder (#2138/#2149). Reuses the driver's resolution rather than re-implementing it; until a native-SQL fast path exists, external analytics is correct (via ObjectQL) instead of silently wrong. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 2 package(s): 91 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
xuyushun441-sys
force-pushed
the
feat/adr-0062-credentials-p2
branch
from
June 22, 2026 12:18
688a28b to
9911bc2
Compare
xuyushun441-sys
added a commit
that referenced
this pull request
Jun 22, 2026
…062 Phase 2, D3) (#2199) * feat(datasource): fail-closed credential resolution at connect (ADR-0062 Phase 2, D3) A declared external.credentialsRef MUST resolve to a cleartext secret before the driver is built — an absent secret store or an unresolvable/undecryptable ref now fails closed (clear message, datasource left unconnected) instead of silently building a driver without the credential. Follows the same fail-fast (declared external + onMismatch:fail) vs degrade policy as connect failures. Converges with the runtime-admin secret path (same SecretBinder threaded through the shared connection service). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(analytics): analytics over federated objects honors the remote table (ADR-0062 Phase 3, D6) (#2200) * feat(datasource): reject field.columnName on external + drop showcase onEnable bridge (ADR-0062 Phase 4, D7/D8) (#2203) --------- Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ADR-0062 Phase 3 — native-analytics SQL over external objects (D6)
Stacked on #2199 (Phase 2) → #2198 (Phase 1). Merge those first; this PR's base is the Phase 2 branch.
Analytics over a federated object now aggregates against the correct remote table instead of silently querying the wrong one.
Problem
NativeSQLStrategyhand-compilesFROM "<object>"and bare column references. These bypass the driver's physical-table resolution (external.remoteName/remoteSchema/columnMap), so for a federated object whose object name ≠ remote table it queries the wrong table (or errors).Fix (reuse the driver's resolution — don't re-implement it)
NativeSQLStrategy.canHandlenow declines any query whose base or joined object is federated.ObjectQLStrategy, whoseengine.aggregate()goes through the driver'sgetBuilder— which already honoursremoteName/remoteSchema(fix(driver-sql,objectql): honor external.remoteName/remoteSchema in the federation read path (ADR-0015) #2138/feat(driver-sql): honor external.columnMap on federated objects (ADR-0015) #2149). So external analytics is correct via the single source of truth (the driver), and native-SQL never hits the wrong table ("disabled beats silently-wrong", per the ADR).StrategyContext.isExternalObject(objectName)hook, reported by the analytics plugin from the object'sexternalblock. Purely additive — with no hook, managed-object behavior is unchanged.A native-SQL fast path for external objects (exposing
physicalTableFor/physicalColumnForon the driver) and deepercolumnMap-in-GROUP BYsupport are noted as follow-ups in the ADR.Tests
canHandle: declines external base object, declines external joined object, accepts managed object, no-hook legacy path unchanged. Fullservice-analyticssuite green (147).Closes (partially) #2163 — Phase 3.
🤖 Generated with Claude Code