backend-core Service Catalog and commons-core Boundary¶
Context and Problem Statement¶
backend-core is being cleansed into the untool.ai data/model runtime plane. It already owns concrete runtime surfaces such as UDA connectors, LLM Gateway, Agent Gateway, credentials broker entrypoints, OTel bootstrap, auth/RBAC enforcement, SSRF checks, secret resolution, and contract export tooling.
At the same time, commons-core is becoming the cross-cutting substrate for shared rules, contracts, SDK/MCP surfaces, validators, and forged client types. If backend-core continues to define fleet-wide rules locally, every second spoke will duplicate auth, privacy, error, identity, finops, contract, and security semantics.
The question: which parts of the backend-core service catalog stay here, which parts are consumed from commons-core, and which parts split runtime from contract/rule ownership?
Decision Drivers¶
- backend-core should stay focused on provider-differentiated runtime: data plane, model/AI gateways, graph/vector execution, ingest, egress enforcement, and runtime telemetry.
- commons-core should own reusable rules, contracts, validators, SDKs, MCP surfaces, and forged typed clients.
- Cross-spoke behavior must not drift across auth, audit, error, privacy, identity, finops, NATS, contract, and telemetry guardrails.
- Enterprise posture needs policy, audit, privacy, budget, and identity enforcement at runtime without duplicating policy definitions.
- OSS posture needs open interfaces, swappable providers, public contracts, conformance kits, and low-friction generated clients.
- Accelerators should make data faster and more open: embed-on-land, semantic cache, provenance everywhere, self-describing APIs, and forge-emitted clients.
Decision Outcome¶
Adopt the backend-core service catalog with three ownership tags:
| Tag | Meaning |
|---|---|
[Own] |
backend-core expands and operates this runtime. |
[Consume] |
backend-core uses a commons-core SDK/MCP/tooling surface and keeps only a thin client or call site. |
[Split] |
runtime/enforcement stays in backend-core; contract/rule/schema/client lives in commons-core. |
The anchoring rule is:
backend-core owns provider-differentiated runtime. commons-core owns cross-cutting rules, contracts, validators, SDK/MCP surfaces, and forged typed clients.
Service Catalog Boundary¶
| Lane | Service family | Boundary |
|---|---|---|
| Data plane and UDA | [Own] UDA connector runtime, cross-modal semantic search, CDC/stream ingest, object/blob service; [Split] ingest/parsing contracts. |
backend-core runs data movement and source-specific execution; commons-core owns connector/parser contracts and conformance. |
| AI and model gateways | [Own] LLM Gateway, embeddings, RAG orchestration; [Split] Agent Gateway contracts, web search/tool contracts, guardrail rule packs. |
backend-core runs provider routing and gateway enforcement; commons-core owns vendor-neutral contracts and policy/rule definitions. |
| Semantic and ontology layer | [Split] ontology sift/sieve runtime and knowledge graph contracts; [Consume] schema abstraction/adapter builder. |
backend-core executes against data/graph state; commons-core owns validators, proof formats, and forge surfaces. |
| Platform integration and messaging | [Split] platform capability messaging; [Consume] central memory, distributed locks, runbook triggers. |
backend-core emits/consumes runtime events; commons-core owns shared schemas, validators, and orchestration clients. |
| Security, identity, governance | [Split] auth/RBAC, credentials broker; [Own] audit trail runtime and SSRF/egress guard; [Consume] privacy/PII, error validator, identity broker, security broker. |
backend-core enforces per-request behavior; commons-core owns rule definitions, schemas, and clients. |
| Ops, observability, FinOps, sustainability | [Own] observability bootstrap; [Split] health endpoints; [Consume] DB diagnostics, finops guardrails, ESG/carbon. |
backend-core emits live runtime data; commons-core owns shared checks, budgets, diagnostic and carbon models. |
| Developer experience and openness | [Own] contract-first pipeline, test console, public capability catalog, sample-data/notebooks, data marketplace publisher. |
backend-core exposes self-describing runtime surfaces; commons-core receives forged clients and shared contract packages. |
Architecture Rules¶
- Do not move UDA connectors, provider routers, parser execution, graph/vector query execution, or gateway enforcement out of backend-core unless the runtime itself becomes a separate platform service.
- Do move shared contracts, validators, rule definitions, generated client types, and conformance kits into commons-core.
- Do not let backend-core depend on private implementation details inside commons-core. Consume stable SDK/MCP/tool contracts.
- Do not let commons-core depend on backend-core runtime modules.
- A
[Split]service must name both sides explicitly in code/docs: backend runtime owner and commons rule/contract owner. - Every new backend-core route or provider capability must be contract-first and forge-compatible.
Consequences¶
Positive:
- backend-core stays lean and runtime-focused.
- Other spokes can consume the same rules/contracts instead of reimplementing them.
- Enterprise controls become consistent across data, model, graph, and agent surfaces.
- OSS users get open contracts, conformance kits, swappable providers, and generated clients.
- The platform can ship accelerators such as embed-on-land, semantic cache, citation graphs, and self-describing APIs without muddling ownership.
Negative / trade-offs:
- The first extraction needs compatibility wrappers and duplicated tests for a short period.
[Split]services require more discipline than local-only code because each change may touch backend-core and commons-core.- Commons-core package boundaries must be cleaned before publishing; generated/dist artifacts in the current worktree are noisy and should not define the source package shape.
Implementation Notes¶
The detailed migration table lives in:
.agent/plans/backend-core-service-catalog-cleansing.md
Start with shared plumbing extraction because it is already duplicated by design:
audit,errors,ssrf,secrets,env, andotelmove to commons-owned package surfaces with backend-core wrappers.authfollows after exact compatibility tests cover JWT/JWKS, role extraction, disabled-auth local principal, and denial audit emission.- Credentials broker splits into service runtime in backend-core and shared client/contracts in commons-core.
- Contract export/drift tooling migrates toward commons governance commands while backend-core keeps route-specific exporters.
Validation¶
Backend-core validation:
python -m pytest -q tests/test_env_bootstrap.py tests/test_secret_resolution.py tests/test_ssrf.py
python -m pytest -q tests/test_connections_api.py tests/test_pipelines_api.py tests/test_credentials.py
python -m pytest -q tests/test_agent_gateway.py tests/test_llm_gateway.py
python scripts/export_openapi.py
python scripts/export_agent_gateway_contract.py
python scripts/export_llm_gateway_contract.py
python scripts/check_tier_separation.py
commons-core validation after package extraction:
python -m pytest -q
python -m compileall sdk/python/untool_common
Decision Log¶
| Date | Decision |
|---|---|
| 2026-06-01 | Ratify backend-core as provider-differentiated runtime owner and commons-core as shared rule/contract/SDK/MCP owner. |
| 2026-06-01 | Adopt [Own], [Consume], and [Split] tags for every backend-core service family. |
| 2026-06-01 | Start cleansing with shared plumbing extraction through compatibility wrappers before broad service expansion. |