Two assertions in the docker-marker test files had drifted from the live API and were only caught by the scheduled nightly CI job (run #24947963804, 2026-04-26 04:12 UTC): - tests/test_docker_full.py::test_app_returns_html_on_root expected 200 on GET / — but app/web/router.py:189-193 always returns 302 (to /dashboard for authenticated users, /login otherwise) since the auth middleware landed. Updated to use follow_redirects=False and assert 302 + location. - tests/test_e2e_docker.py::TestDockerHealth::test_health_has_duckdb read data["checks"]["duckdb"|"database"] — but the health payload shape is {"services": {"duckdb_state": ..., "data": ..., "users": ...}} and has been since app/api/health.py was last refactored. Updated to read services["duckdb_state"]["status"] — same pattern used by the (passing) tests/test_api.py::TestHealth suite, so the two test layers now agree. Both fixes are test-only; no application behavior changes.
8.4 KiB
Changelog
All notable changes to Agnes AI Data Analyst.
Format: Keep a Changelog. Versions follow Semantic Versioning, pre-1.0 — public surface (CLI flags, REST endpoints, instance.yaml schema, extract.duckdb contract) may shift between minor versions; breaking changes called out under Changed or Removed with the BREAKING marker.
CalVer image tags (stable-YYYY.MM.N, dev-YYYY.MM.N) are produced for every CI build; semver tags (v0.X.Y) are cut at release boundaries and reference the same commit as a stable-* tag from the same day.
[Unreleased]
Internal
- Fix nightly
docker-e2eCI failures: refresh two stale assertions that had drifted from the live API.tests/test_docker_full.py::test_app_returns_html_on_rootnow expects the auth-aware302 → /login(root has redirected since the auth middleware landed);tests/test_e2e_docker.py::TestDockerHealth::test_health_has_duckdbnow readsservices["duckdb_state"](current health-payload shape, already validated bytests/test_api.py). No application behavior change — these only ran in the scheduled nightly job, so the drift went unnoticed for several PRs.
0.11.1 — 2026-04-26
Patch release — hotfix the missed Caddy env passthrough that should have shipped with 0.11.0, plus codify changelog discipline so this kind of drift gets caught at PR review time next time.
Fixed
docker-compose.ymlcaddy service now passesCADDY_TLSthrough to the container (- CADDY_TLSbare-form passthrough). Without it theCaddyfile{$CADDY_TLS:default}substitution always falls back to cert-file mode regardless of what the operator wrote into.env, and Caddy crash-loops on Let's Encrypt / internal-CA deployments. Should have shipped with #52; first attempt was #55, accidentally closed before merging.
Internal
CLAUDE.md— non-negotiable changelog discipline: every PR touching user-visible behavior must updateCHANGELOG.mdunder## [Unreleased]in the same PR.
0.11.0 — 2026-04-26
First tagged semver release. The version = "2.x" strings that appeared in earlier pyproject.toml snapshots were arbitrary placeholders from the initial scaffold and never reflected actual API maturity — resetting to pre-1.0 to signal that things may still shift.
Added — Auth
- Google Workspace groups on
/profile. OAuth callback fetches the signed-in user's group memberships via Cloud Identity (searchTransitiveGroupswith thesecuritylabel — seedocs/auth-groups.mdfor the GCP setup checklist and thesecurity-vs-discussion_forumgotcha). Profile link added to the user dropdown. - Password reset + invite flows for web and admin (
/auth/password/reset,/admin/users/invite). - Personal access tokens (PAT) with separate
:typ=patJWT claim, per-token revoke, last-used IP tracking, "My tokens" + admin "All tokens" UI. - Email magic-link provider (itsdangerous-signed token).
- Optional
SEED_ADMIN_PASSWORDto pre-hash the seed admin (dev convenience).
Added — Deploy
keboola-deploy.ymlworkflow. Tag-triggered alternative torelease.ymlfor shared dev VMs that want explicit "deploy when I tag" semantics. Publishes immutable:keboola-deploy-<tag>+ floating:keboola-deploy-latestalias.- Caddy + Let's Encrypt + corporate-CA TLS.
Caddyfileparametrized via$CADDY_TLSenv var so a single file serves three regimes: cert-file (corp PKI), Let's Encrypt auto-issue, Caddy-internal-CA. URL-driven cert rotation with self-signed fallback (scripts/grpn/agnes-tls-rotate.sh).docker-compose.tls.ymloverlay closes host:8000when Caddy fronts. dev_instancesschema incustomer-instanceTerraform module gains optionaltls_mode+domain(mirrorsprod_instance).infra-v1.6.0tag.- Optional Google OAuth credentials from Secret Manager. Module reads
google-oauth-client-{id,secret}at boot if present; graceful fallback so non-Google deployments aren't affected. LOCAL_DEV_MODE+make local-dev-up/local-dev-downfor one-keystroke local stack with magic-link auth pre-wired.- Per-developer
dev-<prefix>-latestGHCR alias for branches matching<prefix>/<branch>— push-to-deploy on personal dev VMs. /setupweb wizard for first-time instance setup, plus headlessPOST /api/admin/configureandPOST /api/admin/discover-and-register.- Smoke-test job in CI (Docker-in-CI after every release) +
scripts/smoke-test.shfor post-deploy verification.
Added — CLI
- Wheel distribution + auto-update check on startup.
--versionflag,--dry-run+X/Nprogress onda sync, durable sync (atomic writes + manifest hash + retry on transient errors).- gzip on JSON/HTML responses (server-side).
Added — Data
- Remote query engine. Two-phase BigQuery + DuckDB engine for tables too large to sync locally (
--register-bqflag). - Business metrics. Standardized
metric_definitionstable in DuckDB with starter pack importer (da metrics import). /api/healthreturnsversion,channel,commit_sha,image_tag,schema_version.- Custom connector mount support (
connectors/custom/). - OpenAPI snapshot test for breaking-change detection.
Added — Docs / tooling
docs/auth-groups.md,docs/DEPLOYMENT.md,docs/HACKATHON.md,docs/ONBOARDING.mdrunbooks.scripts/debug/probe_google_groups.py— stdlib-only probe for diagnosing Cloud Identity API issues without a deploy cycle.- Schema migration safety tests (idempotency, data preservation, snapshot).
- Pre-migration snapshot of
system.duckdbbefore schema upgrades. - Auto-generated JWT and session secrets with file persistence (
/data/state/.jwt_secret). - Startup banner logging version, channel, and schema version.
Changed
- BREAKING (deployment) — Caddy compose profile renamed
production→tls. Existingdocker compose --profile production up -dinvocations need to switch. - BREAKING (deployment) — Default
Caddyfilemode is now cert-file (tls /certs/fullchain.pem /certs/privkey.pem); for the previous Let's Encrypt auto-issue behaviour setCADDY_TLS=tls <ops-email>in.env. Seedocs/auth-groups.mdandCaddyfileinline docs. - Schema migration v5→v6→v7: adds
users.active,personal_access_tokenstable,personal_access_tokens.last_used_ip. Auto-applied at boot. - Image-level
AGNES_VERSIONnow sourced frompyproject.tomlat build time (no more drift betweenda --versionand the package metadata). - Vendor-agnostic OSS rule codified in
CLAUDE.md— customer-specific names, hostnames, project IDs belong in consumer infra repos, not in this OSS distribution.
Fixed — Security
- Open-redirect guard for backslash in
safe_next_path. SessionMiddleware max_age=3600 + https_only(was browser-session forever, plain-HTTP-OK).- Timezone-aware datetimes in Keboola metadata cache.
- Atomic magic-link token consumption (closes double-use race under concurrent clicks).
- Bootstrap backdoor closed when passwordless seed admin exists.
- urllib3 1.26→2.6.3 (resolves 4 Dependabot security alerts).
- argon2-cffi adopted for password hashing.
- See docs/padak-security.md for the full audit.
Fixed — Other
uvicorn --proxy-headers --forwarded-allow-ips='*'so OAuth callbacks resolve to https when behind a TLS terminator.scripts/grpn/agnes-tls-rotate.shhardened:--max-redirs 0+--proto '=https'on cert fetch, post-fetch PEM validation (rejects HTML error pages from corp portals),ulimit -c 0to suppress coredumps that could leak the unencrypted privkey, POSIX-safe${arr[@]+"${arr[@]}"}array expansion.scripts/tls-fetch.sh— generic URL fetcher (sm://,gs://,https://,file://) with redirect refusal + PEM validation.kbcstoragemoved to optional dep — unblocks urllib3 security updates; primary Keboola path now uses the DuckDB Keboola extension.- Dependencies consolidated into
pyproject.toml(no morerequirements.txt).
Internal
- Test suite expanded to 1357+ tests (4 layers — unit, integration, web smoke, journey).