Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,11 @@ sdk/agentflow/**/__pycache__/
sdk/agentflow/**/*.py[cod]
integrations/agentflow_integrations/**/__pycache__/
integrations/agentflow_integrations/**/*.py[cod]
# Local Iceberg warehouse/runtime state (intentionally untracked).
/warehouse/agentflow/
# Local Iceberg warehouse/runtime state (intentionally untracked). DV2 SQL/Python
# source under warehouse/agentflow/dv2/ is tracked normally — only the generated
# lake and build output are excluded here.
/warehouse/agentflow/orders/
/warehouse/agentflow/dv2/reference/build/
# Root API usage DuckDB runtime state (intentionally untracked).
/agentflow_api.duckdb
agentflow_bench_debug*.duckdb*
Expand Down
2 changes: 1 addition & 1 deletion docs/helm-deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ If `ingress.enabled=true`, verify the configured host instead of using port-forw

- `helm/agentflow/values.schema.json` is the chart contract for runtime values consumed from Helm.
- If you add, rename, or make required a field under `config.tenants` or `secrets.apiKeys`, update the schema, chart defaults, and environment-specific values together.
- Keep the mounted file shape in `templates/configmap.yaml` and `templates/secret.yaml` aligned with the runtime Pydantic models in `src/ingestion/tenant_router.py` and `src/serving/api/auth/manager.py`.
- Keep the mounted file shape in `templates/configmap.yaml` and `templates/secret.yaml` aligned with the runtime Pydantic models in `src/tenancy.py` and `src/serving/api/auth/manager.py`.
- Validate contract changes with `helm lint helm/agentflow -f k8s/staging/values-staging.yaml` before staging rehearsal.

## Upgrade
Expand Down
2 changes: 1 addition & 1 deletion docs/security-audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ This is stronger than soft application filtering because the query builder rewri

The current evidence supports the claim "tenant-scoped DuckDB schemas with fail-closed query resolution." It does not support broader claims such as end-to-end isolation across every external dependency.

Evidence: `src/ingestion/tenant_router.py`, `src/serving/semantic_layer/query/sql_builder.py`, `src/serving/semantic_layer/query/engine.py`, `tests/integration/test_tenant_isolation.py`
Evidence: `src/tenancy.py`, `src/serving/semantic_layer/query/sql_builder.py`, `src/serving/semantic_layer/query/engine.py`, `tests/integration/test_tenant_isolation.py`

## 4. Input Validation and Contract Safety

Expand Down
2 changes: 1 addition & 1 deletion src/ingestion/cdc/normalizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from datetime import UTC, datetime
from typing import Any

from src.ingestion.tenant_router import TenantRouter
from src.tenancy import TenantRouter

_SOURCE_BY_CONNECTOR: dict[str, str] = {
"postgresql": "postgres_cdc",
Expand Down
2 changes: 1 addition & 1 deletion src/serving/semantic_layer/query/contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

from typing import Protocol

from src.ingestion.tenant_router import TenantRouter
from src.serving.backends import ServingBackend
from src.serving.backends.duckdb_backend import DuckDBBackend
from src.serving.semantic_layer.catalog import DataCatalog
from src.tenancy import TenantRouter


class SQLBuilderHost(Protocol):
Expand Down
2 changes: 1 addition & 1 deletion src/serving/semantic_layer/query/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@

import duckdb

from src.ingestion.tenant_router import TenantRouter
from src.serving.backends import create_backend
from src.serving.backends.duckdb_backend import DuckDBBackend
from src.serving.db_pool import DuckDBPool
from src.serving.duckdb_connection import connect_duckdb
from src.serving.semantic_layer.catalog import DataCatalog
from src.tenancy import TenantRouter

from .entity_queries import EntityQueryMixin
from .metric_queries import MetricQueryMixin
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion tests/integration/test_tenant_isolation.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
from fastapi import FastAPI, Request
from fastapi.testclient import TestClient

from src.ingestion.tenant_router import TenantRouter
from src.serving.api.main import app
from src.serving.api.routers.agent_query import router as agent_router
from src.serving.cache import QueryCache
from src.serving.semantic_layer.catalog import DataCatalog
from src.serving.semantic_layer.query_engine import QueryEngine
from src.tenancy import TenantRouter

pytestmark = pytest.mark.integration

Expand Down
2 changes: 1 addition & 1 deletion tests/unit/test_tenant_router_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
from types import SimpleNamespace
from typing import cast

from src.ingestion.tenant_router import TenantRouter
from src.serving.semantic_layer.catalog import DataCatalog
from src.serving.semantic_layer.query.sql_builder import SQLBuilderMixin
from src.tenancy import TenantRouter


def test_tenant_router_reuses_loaded_config(
Expand Down