- Footer.svelte: replace hardcoded '2025' with new Date().getFullYear()
- build.sh: append git short hash to APP_VERSION for all bundle commands
(bundle, bundle:embeddings, bundle:light). Format: '0.5.2+58d06fb2'.
Previously only the tag was passed (e.g. '0.5.2'), and .git was not
available in Docker context so vite.config.js fell back to '0.0.0'.
Verified: frontend assets contain '0.5.2+58d06fb2', getFullYear() replaces
hardcoded 2025.
Canonical variables:
- AUTH_SECRET_KEY — JWT signing key for backend + agent (was split across
AUTH_SECRET_KEY / JWT_SECRET)
- SERVICE_JWT — agent→backend service token
- No JWT_SECRET fallback: decoder fails with migration guidance if only
JWT_SECRET is set
Compose files unified:
- docker-compose.yml, docker-compose.enterprise-clean.yml,
docker-compose.e2e.yml — all use AUTH_SECRET_KEY
- build.sh generated compose now passes AUTH_SECRET_KEY + ENCRYPTION_KEY
to backend
Env examples unified and completed:
- .env.example — comprehensive template, all compose vars
- .env.enterprise-clean.example — production template
- backend/.env.example — backend-only run
- docker/.env.agent.example — agent-only run
- NEW: .env.current.example, .env.master.example,
.env.e2e.example, frontend/.env.example
Tests aligned:
- conftest sets AUTH_SECRET_KEY (canonical value matched across test files)
- test mocks use canonical name
- 1176 passed, 0 failed
- Added python-jose[cryptography] to requirements-agent.txt
- Made sqlalchemy.orm.Session and TokenBlacklist imports lazy in jwt.py
so decode_token works without pulling ORM models into agent image
- Added src/core/auth/__init__.py, config.py, jwt.py to agent Dockerfile COPY
- Added AUTH_SECRET_KEY env var to agent compose (reads from JWT_SECRET)
In Docker builds, .git directory is not available in the container,
so git describe --tags fails and fallback is '0.0.0'. Now:
- build.sh passes --build-arg APP_VERSION=${tag} to frontend build
- Dockerfile accepts ARG APP_VERSION and sets ENV
- vite.config.js checks process.env.APP_VERSION first, then git describe
- build.sh bundle_release() now builds ss-tools-agent:{tag} from
docker/Dockerfile.agent alongside backend and frontend
- Generated docker-compose.enterprise-clean.yml includes agent service
(image: + pull_policy: never, port 7860, depends_on: backend)
- Manifest .txt and .json include agent image fields
- sha256sums and load instructions updated for three images
- Static docker-compose.enterprise-clean.yml adds agent service (build
from source) for local 'up enterprise-clean' profile
- Enable response_format (json_object) for all providers including Kilo/OpenRouter
- Skip reasoning_effort for Kilo/OpenRouter (returns 400 — mandatory reasoning)
- Add structured_outputs fallback: retry once without response_format if upstream
provider (e.g. StepFun) rejects it with 'structured_outputs is not supported'
- Handle model refusal field (refusal) instead of treating as empty content
- Fix None-handling guards for message/finish_reason/content fields
- Apply same fixes to both preview.py and executor.py _call_openai_compatible
- Connect orphaned TermCorrectionPopup, BulkReplaceModal, BulkCorrectionSidebar
Move dataset review clarification into the assistant workspace and
rework the review page into a chat-centric layout with execution rails.
Add session-scoped assistant actions for mappings, semantic fields,
and SQL preview generation. Introduce optimistic locking for dataset
review mutations, propagate session versions through API responses,
and mask imported filter values before assistant exposure.
Refresh tests, i18n, and spec artifacts to match the new workflow.
BREAKING CHANGE: dataset review mutation endpoints now require the
X-Session-Version header, and clarification is no longer handled
through ClarificationDialog-based flows