Track the practice cluster's Helm values in Git
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
name: Validate Helm chart
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- infra/helm/**
|
||||
- .github/workflows/helm-chart.yml
|
||||
pull_request:
|
||||
paths:
|
||||
- infra/helm/**
|
||||
- .github/workflows/helm-chart.yml
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: azure/setup-helm@v4
|
||||
with:
|
||||
version: v3.17.3
|
||||
- name: Lint chart
|
||||
run: helm lint infra/helm/medical-chatbot
|
||||
- name: Render default and production manifests
|
||||
run: |
|
||||
helm template default infra/helm/medical-chatbot > /tmp/default.yaml
|
||||
helm template production infra/helm/medical-chatbot \
|
||||
--values infra/helm/medical-chatbot/values-prod.yaml \
|
||||
> /tmp/production.yaml
|
||||
grep -q 'ANSWER_MODEL_ID: "qwen.qwen3-next-80b-a3b"' /tmp/production.yaml
|
||||
grep -q 'RERANK_ENABLED: "true"' /tmp/production.yaml
|
||||
grep -q 'checksum/runtime-config:' /tmp/production.yaml
|
||||
|
||||
# The practice cluster is only evidence for the production migration
|
||||
# while it renders the same behavioural contract as production, so both
|
||||
# of its releases are asserted here rather than trusted by review.
|
||||
- name: Render practice manifests
|
||||
run: |
|
||||
helm template medical-chatbot-app infra/helm/medical-chatbot \
|
||||
--values infra/helm/medical-chatbot/values-practice.yaml \
|
||||
> /tmp/practice-app.yaml
|
||||
helm template medical-chatbot-data infra/helm/medical-chatbot \
|
||||
--values infra/helm/medical-chatbot/values-practice-data.yaml \
|
||||
> /tmp/practice-data.yaml
|
||||
|
||||
# Behavioural parity with the audited production runtime contract.
|
||||
grep -q 'ANSWER_MODEL_ID: "qwen.qwen3-next-80b-a3b"' /tmp/practice-app.yaml
|
||||
grep -q 'ANSWER_PROVIDER: "bedrock-converse"' /tmp/practice-app.yaml
|
||||
grep -q 'EMBEDDING_PROVIDER: "cohere-v4"' /tmp/practice-app.yaml
|
||||
grep -q 'EMBEDDING_DIMENSIONS: "1024"' /tmp/practice-app.yaml
|
||||
grep -q 'EVIDENCE_MINIMUM_SCORE: "0.12"' /tmp/practice-app.yaml
|
||||
grep -q 'RERANK_ENABLED: "true"' /tmp/practice-app.yaml
|
||||
grep -q 'AWS_REGION: "us-east-1"' /tmp/practice-app.yaml
|
||||
grep -q 'checksum/runtime-config:' /tmp/practice-app.yaml
|
||||
grep -q 'host: readytochat.realvuxbaro.me' /tmp/practice-app.yaml
|
||||
|
||||
# The app release must own neither data StatefulSet: PostgreSQL and
|
||||
# Qdrant belong to the data release, so an app-side sync failure or
|
||||
# prune can never delete the corpus or the query history. Only those
|
||||
# two use volumeClaimTemplates — the observability PVCs are the app
|
||||
# release's own and are expected here.
|
||||
#
|
||||
# `set -e` ignores a command whose status is inverted with `!`, so
|
||||
# every must-NOT-contain assertion is written as an explicit exit.
|
||||
refute() {
|
||||
if grep -q "$2" "$1"; then
|
||||
echo "::error::$1 must not contain: $2"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
refute /tmp/practice-app.yaml 'volumeClaimTemplates'
|
||||
grep -q 'medical-chatbot-data-medical-chatbot-qdrant' /tmp/practice-app.yaml
|
||||
|
||||
# ...and the data release must own nothing else.
|
||||
refute /tmp/practice-data.yaml 'medical-chatbot-data-medical-chatbot-ai-service'
|
||||
refute /tmp/practice-data.yaml 'kind: Ingress'
|
||||
grep -q 'volumeClaimTemplates' /tmp/practice-data.yaml
|
||||
@@ -0,0 +1,250 @@
|
||||
# ArgoCD production migration state — 2026-08-17
|
||||
|
||||
## Purpose
|
||||
|
||||
Shared handoff for Codex and Claude. This is the current operational reference
|
||||
for the personal production-to-ArgoCD migration. Re-check live state before a
|
||||
mutation because runtime and Git revisions can change after this snapshot.
|
||||
|
||||
## Current verdict
|
||||
|
||||
**Latency parity achieved for the measured post-fix scope.** After aligning the
|
||||
personal k3s practice environment with production on Qwen and reranking, a
|
||||
controlled five-pair test showed practice at 12.194 seconds average and
|
||||
production at 12.842 seconds average, with zero errors or timeouts. There is no
|
||||
measured systematic k3s latency penalty remaining.
|
||||
|
||||
This verdict is specifically about runtime latency parity. It does not mean the
|
||||
production migration is ready to cut over: tracked ArgoCD values, immutable
|
||||
production images, state restore, DNS rollback and broader soak/regression gates
|
||||
remain open.
|
||||
|
||||
## Owner intent
|
||||
|
||||
- Production must eventually run through ArgoCD.
|
||||
- The separate personal k3s/ArgoCD EC2 is the rehearsal environment used to
|
||||
discover migration risk before cutover.
|
||||
- The intended cutover is to move `realvuxbaro.me` to the proven k3s workload.
|
||||
- Keep the existing Compose production EC2 intact as the DNS-level rollback
|
||||
until the ArgoCD deployment has passed its acceptance window.
|
||||
|
||||
## Hard boundary
|
||||
|
||||
- Do not access, modify, or push to `git.vinmec.tech`.
|
||||
- Do not access or mutate the team's ArgoCD/k3s infrastructure.
|
||||
- The active scope is the owner's personal GitHub repository, personal AWS
|
||||
account, Compose production EC2, and personal practice k3s/ArgoCD EC2.
|
||||
- No team Gitea or team infrastructure action occurred in the 2026-08-17 Codex
|
||||
session. Reading an old Claude memory that mentioned Gitea did not authorize
|
||||
or cause a connection to it.
|
||||
|
||||
## Topology at this snapshot
|
||||
|
||||
| Role | Runtime | Address / identity | State |
|
||||
| --- | --- | --- | --- |
|
||||
| Current production | Docker Compose on EC2 `i-039fc8f6102467a54` (`t3.large`) | `realvuxbaro.me`, `52.0.158.61` | Live; rollback source |
|
||||
| Migration rehearsal | k3s + ArgoCD on EC2 `i-035cd1f80f4462455` (`t3.large`) | `readytochat.realvuxbaro.me`, `argocd.realvuxbaro.me` | Live, Synced, Healthy |
|
||||
| Source repository | Private GitHub | `BaoVu2k4/vsf-duocthu` | Active source for both personal environments |
|
||||
|
||||
The practice instance is currently `t3.large`. Older Claude memory that says it
|
||||
is still `t3.medium` is stale.
|
||||
|
||||
## Production evidence collected by Codex
|
||||
|
||||
Codex added and manually dispatched the read-only workflow
|
||||
`.github/workflows/audit-production-runtime.yml`.
|
||||
|
||||
- Commit: `2ff65d9` (`Add read-only production runtime audit`).
|
||||
- GitHub Actions run: `31993964589`, passed.
|
||||
- The commit touched only the new manual audit workflow. It did not match the
|
||||
existing production deploy workflow's path filters and did not restart the
|
||||
Compose stack.
|
||||
- Production checkout revision: `df57e6b0806daccb13970dff2aecb7b7dd33eddd`,
|
||||
branch `master`.
|
||||
- `ai-service`, `web`, PostgreSQL, and Qdrant containers: running.
|
||||
- `/health`: HTTP 200; `/ready`: HTTP 200.
|
||||
- Qdrant collection: `duocthu_v1`, 15,100 points, green, cosine, 1,024
|
||||
dimensions.
|
||||
- Persistent data mounts: Docker volumes `docker_postgres-data` and
|
||||
`docker_qdrant-data`.
|
||||
|
||||
Safe production AI runtime contract:
|
||||
|
||||
| Setting | Effective value |
|
||||
| --- | --- |
|
||||
| `ANSWER_PROVIDER` | `bedrock-converse` |
|
||||
| `ANSWER_MODEL_ID` | `qwen.qwen3-next-80b-a3b` |
|
||||
| `EMBEDDING_PROVIDER` | `cohere-v4` |
|
||||
| `EMBEDDING_DIMENSIONS` | `1024` |
|
||||
| `EVIDENCE_MINIMUM_SCORE` | `0.12` |
|
||||
| `RERANK_ENABLED` | `true` |
|
||||
| `MAX_WALL_CLOCK_MS` | `40000` |
|
||||
| `MAX_LLM_CALLS_PER_TURN` | `8` |
|
||||
| `AWS_REGION` | `us-east-1` |
|
||||
| `QDRANT_COLLECTION` | `duocthu_v1` |
|
||||
| `OTEL_ENABLED` | `true` |
|
||||
| `OTEL_SAMPLE_RATIO` | `1.0` |
|
||||
|
||||
No credential, secret value, patient data, or raw `.env.prod` content was
|
||||
printed or stored.
|
||||
|
||||
## Practice evidence collected by Codex
|
||||
|
||||
The ArgoCD API was read using the gitignored local practice credential file.
|
||||
No practice Application or cluster resource was mutated during this audit.
|
||||
|
||||
- Application `medical-chatbot-app`: target `master`, compared revision
|
||||
`f9c20a67943e1df3c9e0cb08d01ebaaee48c0470`, Synced, Healthy, automated
|
||||
prune and self-heal enabled.
|
||||
- AI image:
|
||||
`ghcr.io/baovu2k4/vsf-duocthu-ai-service:f9c20a67943e1df3c9e0cb08d01ebaaee48c0470`.
|
||||
- Application `medical-chatbot-data` separately owns PostgreSQL and Qdrant.
|
||||
- Practice AI config explicitly selects `deepseek.v3.2` and does not expose a
|
||||
Helm value for `RERANK_ENABLED`, so the application default is `false`.
|
||||
- Practice and production therefore differ in at least two behavior-changing
|
||||
settings: answer model and rerank enablement.
|
||||
|
||||
## Corrected conclusions
|
||||
|
||||
- Config drift is real: production runs Qwen with reranking enabled; practice
|
||||
runs DeepSeek with reranking disabled.
|
||||
- The drift is a strong explanation for practice tail latency and
|
||||
`request_budget_exhausted`, but causality must be confirmed by running the
|
||||
same model/config and an interleaved benchmark.
|
||||
- Claude's claim that both environments were on the exact same commit
|
||||
`f9c20a6` was false. Production was observed at `df57e6b`; practice was at
|
||||
`f9c20a6`. The commits between them did not change AI application source, so
|
||||
this correction does not remove the proven configuration drift.
|
||||
- Production behavior/data/config is the migration baseline. Docker Compose is
|
||||
not the target architecture; it remains the rollback implementation.
|
||||
|
||||
## Runtime parity remediation applied
|
||||
|
||||
Codex fixed and deployed the main behavior-changing drift to the personal
|
||||
practice environment on 2026-08-17.
|
||||
|
||||
- Commit `5a1a600` added Helm mappings for embedding dimensions, evidence
|
||||
threshold, AWS region and rerank enablement. It also added a runtime-config
|
||||
checksum to the AI Deployment Pod template so a ConfigMap change causes an
|
||||
actual rollout instead of leaving the old process alive.
|
||||
- `values-prod.yaml` now records the observed production baseline: Qwen
|
||||
`qwen.qwen3-next-80b-a3b`, Cohere v4, 1,024 dimensions, evidence threshold
|
||||
`0.12`, reranking enabled and AWS region `us-east-1`.
|
||||
- Helm validation run `31995055293`: one chart linted, zero failed; default and
|
||||
production manifests rendered and asserted.
|
||||
- Full CI run `31995055272`: ingestion pytest, AI ruff+pytest, and web
|
||||
lint+build all passed.
|
||||
- The personal ArgoCD practice Application accepted the Qwen+rerank baseline
|
||||
and converged at revision `5a1a600`: Synced and Healthy.
|
||||
- Effective practice manifest after convergence: Qwen, rerank `true`, Cohere
|
||||
v4, 1,024 dimensions, threshold `0.12`, `us-east-1`, and a non-empty
|
||||
`checksum/runtime-config` Pod annotation.
|
||||
- CloudWatch over the post-rollout six-minute window recorded 24 Qwen
|
||||
invocations and no DeepSeek invocation. This confirms the exercised path no
|
||||
longer used DeepSeek; CloudWatch remains account-aggregate rather than
|
||||
environment-labelled.
|
||||
|
||||
Small live parity sample through each environment's real `/api/chat` path:
|
||||
|
||||
| Scope | Practice | Production |
|
||||
| --- | ---: | ---: |
|
||||
| Initial smoke | 8.75 s | 8.94 s |
|
||||
| Three explicit attribute questions — average | 15.33 s | 11.96 s |
|
||||
| Three explicit attribute questions — maximum | 22.84 s | 15.54 s |
|
||||
| Errors/timeouts in the three-question sample | 0 | 0 |
|
||||
|
||||
All three explicit questions were answerable with grounded evidence and one
|
||||
citation in both environments. The initial unaccented overview question was
|
||||
answerable on practice but clarified for a missing attribute on production, so
|
||||
behavioral determinism still needs a larger test set.
|
||||
|
||||
Conclusion: the major model/rerank drift is fixed and the observed 2–3x tail /
|
||||
40-second timeout pattern did not reproduce after parity. Practice remained
|
||||
about 28% slower on the three-question sample and had a 22.84-second maximum,
|
||||
so this is evidence of a material fix, not proof that all residual latency is
|
||||
gone. Run a larger interleaved soak before production cutover.
|
||||
|
||||
### Residual-latency investigation
|
||||
|
||||
The apparent 28% residual above did not survive a controlled follow-up. Five
|
||||
additional pairs used the same explicit Zolpidem attribute query, alternated
|
||||
which environment ran first, used fresh conversations, and captured each Tempo
|
||||
trace.
|
||||
|
||||
| Environment | N | Average | Median | Minimum | Maximum | Errors |
|
||||
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
|
||||
| Practice | 5 | 12.194 s | 12.036 s | 11.876 s | 12.691 s | 0 |
|
||||
| Production | 5 | 12.842 s | 12.333 s | 10.803 s | 15.217 s | 0 |
|
||||
|
||||
Practice was 0.648 seconds faster on average in this controlled sample. There
|
||||
is no remaining systematic practice slowdown demonstrated by the data.
|
||||
|
||||
Tempo provider-span averages:
|
||||
|
||||
| Operation | Practice | Production |
|
||||
| --- | ---: | ---: |
|
||||
| Qwen understanding | 5.456 s | 4.795 s |
|
||||
| Qwen generation | 5.271 s | 5.793 s |
|
||||
| Qwen entailment | 0.711 s | 0.640 s |
|
||||
|
||||
The distributions overlap and the faster side changes per call/stage. Output
|
||||
length explains the clearest tail: production round 5 returned 1,426
|
||||
characters and spent 8.048 seconds in generation; the common 910-character
|
||||
outputs spent roughly 4.5–5.4 seconds. Restricting comparison to the common
|
||||
910-character outputs gave generation averages of about 5.14 seconds on
|
||||
practice and 5.23 seconds on production.
|
||||
|
||||
Infrastructure checks also ruled out the earlier throttle hypothesis:
|
||||
|
||||
- both instances are `t3.large` in the same `us-east-1d` availability zone,
|
||||
subnet and VPC;
|
||||
- practice CPU averaged 15.7% and peaked at 34.87% over the observed 30-minute
|
||||
window;
|
||||
- practice retained roughly 599 CPU credits and had zero surplus-credit usage;
|
||||
- retrieval remained millisecond-scale, while the varying time was inside
|
||||
Bedrock provider spans.
|
||||
|
||||
Final latency diagnosis: the former large gap was caused by the now-fixed
|
||||
DeepSeek/rerank configuration drift. The smaller post-fix gap from the first
|
||||
three queries was sampling noise from managed Bedrock inference and variable
|
||||
generated-output length, not a persistent k3s penalty. No additional
|
||||
environment-specific latency fix is justified by the measured state. Reducing
|
||||
the absolute approximately 12-second response time would be a separate RAG
|
||||
architecture change because a normal turn currently performs understanding,
|
||||
generation and entailment as sequential Qwen calls.
|
||||
|
||||
## Migration risks currently open
|
||||
|
||||
1. The live practice Applications use untracked inline Helm values. This is not
|
||||
yet a complete Git source of truth.
|
||||
2. `values-prod.yaml` still uses mutable `latest` image tags; it is not safe for
|
||||
cutover as written even though its behavior settings now match production.
|
||||
3. PostgreSQL/Qdrant snapshot, restore, rollback, ingress/TLS/DNS, secrets,
|
||||
resource limits, and failure recovery still need explicit rehearsal gates.
|
||||
|
||||
## Workspace ownership and current edits
|
||||
|
||||
- Main worktree `D:\VSF-DUOCTHU`, branch `agent/query-history`, contains
|
||||
pre-existing uncommitted Claude/user changes in three Helm files concerning
|
||||
optional AWS static credentials plus untracked slide/material files. Do not
|
||||
stage, overwrite, or discard them accidentally.
|
||||
- Codex created clean worktree `D:\VSF-DUOCTHU-codex-argocd`, branch
|
||||
`agent/argocd-prod-migration`, from `origin/master` to isolate migration work.
|
||||
- No Helm migration change has been made in that clean worktree yet at this
|
||||
checkpoint.
|
||||
- A stale Claude worktree under `.claude/worktrees/agent-a1f5e73fc2ce814e8`
|
||||
contains unrelated, uncommitted table-reconstruction work from 2026-08-05.
|
||||
|
||||
## Next safe execution order
|
||||
|
||||
1. Move the practice Application's stable non-secret config out of inline Helm
|
||||
values and into a tracked values file; keep only dynamic image tags and
|
||||
secret references outside Git.
|
||||
2. Verify the actual running Pod environment, image digest, Qdrant identity,
|
||||
health, readiness and traces through a cluster-level inspection path.
|
||||
3. Run a larger interleaved production/practice benchmark and compare
|
||||
p50/p95/p99,
|
||||
timeout rate, answer decisions and citations.
|
||||
4. Rehearse state restore and DNS rollback. Do not repoint `realvuxbaro.me`
|
||||
until the gates and rollback path pass.
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# Claude claim — 2026-08-17 (afternoon)
|
||||
|
||||
Continuing the Codex ArgoCD migration thread at the owner's instruction. Codex's
|
||||
own worktree `D:\VSF-DUOCTHU-codex-argocd` was clean at `1684e10` with nothing
|
||||
in flight when this claim was taken.
|
||||
|
||||
## Owned by Claude in this session
|
||||
|
||||
- `infra/helm/medical-chatbot/values-practice.yaml` (new)
|
||||
- `infra/helm/medical-chatbot/values-practice-data.yaml` (new)
|
||||
- `.github/workflows/helm-chart.yml` (practice render + assertions)
|
||||
- The two personal practice ArgoCD Application specs
|
||||
(`medical-chatbot-app`, `medical-chatbot-data`) — moving inline values into
|
||||
the tracked files above.
|
||||
|
||||
Worktree: `D:\VSF-DUOCTHU-claude-gitops`, branch `agent/gitops-tracked-values`.
|
||||
|
||||
## Not touched
|
||||
|
||||
- `git.vinmec.tech`, team ArgoCD/k3s, team repos — hard boundary, unchanged.
|
||||
- The Compose production EC2 and `realvuxbaro.me`. `infra/helm/**` is not in
|
||||
`deploy.yml`'s path filters, so pushing this work cannot restart production.
|
||||
- The uncommitted AWS-static-credentials Helm diff in the main worktree
|
||||
`D:\VSF-DUOCTHU` (branch `agent/query-history`). Left exactly as found.
|
||||
|
||||
## Which migration risk this closes
|
||||
|
||||
Open risk 1 in `ARGOCD_PRODUCTION_MIGRATION_STATE_2026-08-17.md`: the live
|
||||
practice Applications carried their entire configuration in untracked inline
|
||||
`spec.source.helm.values`, so the cluster could drift from the repository with
|
||||
no commit recording it — the same class of failure that left practice on
|
||||
DeepSeek with reranking off while production ran Qwen with reranking on.
|
||||
|
||||
Image tags stay inline deliberately: `.github/scripts/sync_practice_argocd.py`
|
||||
regex-rewrites them on every push, so a tag committed to Git would be stale by
|
||||
design. Nothing secret was inline, so nothing secret moves.
|
||||
|
||||
Equivalence was checked before the Application specs were edited: both tracked
|
||||
files parse to structures identical to the live inline values with only the
|
||||
`aiService.image` / `web.image` blocks removed.
|
||||
@@ -10,8 +10,12 @@ data:
|
||||
QDRANT_URL: {{ default (printf "http://%s-qdrant:6333" (include "medical-chatbot.fullname" .)) .Values.qdrant.url | quote }}
|
||||
QDRANT_COLLECTION: {{ .Values.aiService.config.qdrantCollection | quote }}
|
||||
EMBEDDING_PROVIDER: {{ .Values.aiService.config.embeddingProvider | quote }}
|
||||
EMBEDDING_DIMENSIONS: {{ .Values.aiService.config.embeddingDimensions | quote }}
|
||||
EVIDENCE_MINIMUM_SCORE: {{ .Values.aiService.config.evidenceMinimumScore | quote }}
|
||||
AWS_REGION: {{ .Values.aiService.config.awsRegion | quote }}
|
||||
ANSWER_PROVIDER: {{ .Values.aiService.config.answerProvider | quote }}
|
||||
ANSWER_MODEL_ID: {{ .Values.aiService.config.answerModelId | quote }}
|
||||
RERANK_ENABLED: {{ .Values.aiService.config.rerankEnabled | quote }}
|
||||
ENTITIES_PATH: {{ .Values.aiService.config.entitiesPath | quote }}
|
||||
METRICS_ENABLED: {{ .Values.aiService.config.metricsEnabled | quote }}
|
||||
OTEL_ENABLED: {{ and .Values.observability.enabled .Values.aiService.config.otelEnabled | quote }}
|
||||
@@ -40,6 +44,7 @@ spec:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: ai-service
|
||||
annotations:
|
||||
checksum/runtime-config: {{ dict "config" .Values.aiService.config "environment" .Values.global.environment "qdrantUrl" .Values.qdrant.url "observabilityEnabled" .Values.observability.enabled | toJson | sha256sum | quote }}
|
||||
prometheus.io/scrape: "true"
|
||||
prometheus.io/path: /metrics
|
||||
prometheus.io/port: "8000"
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
# k3s practice cluster — the `medical-chatbot-data` release.
|
||||
#
|
||||
# Companion to values-practice.yaml. The practice cluster deliberately splits
|
||||
# the chart into two ArgoCD Applications so that PostgreSQL and Qdrant survive
|
||||
# every app rollout, prune and self-heal: only this release owns the
|
||||
# PersistentVolumeClaims, so an app-side sync failure can never delete the
|
||||
# 15,100-point corpus or the query history.
|
||||
#
|
||||
# It therefore runs *only* the stateful half — PostgreSQL and Qdrant are left
|
||||
# at their chart defaults (`enabled: true`) and everything else is switched off.
|
||||
#
|
||||
# Kept inline on the Application rather than here: nothing. This release has no
|
||||
# image tag that CI rewrites and no secret, so it is fully tracked in Git.
|
||||
|
||||
global:
|
||||
environment: k3s-practice
|
||||
|
||||
aiService:
|
||||
enabled: false
|
||||
|
||||
web:
|
||||
enabled: false
|
||||
|
||||
observability:
|
||||
enabled: false
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
@@ -0,0 +1,72 @@
|
||||
# k3s practice cluster — the `medical-chatbot-app` release.
|
||||
#
|
||||
# This file is the Git source of truth for every stable, non-secret setting of
|
||||
# the practice rehearsal environment. It exists because the same values used to
|
||||
# live only inside the ArgoCD Application's inline `spec.source.helm.values`,
|
||||
# where they were invisible to review, diff and rollback: the cluster could
|
||||
# drift from the repository without a single commit recording it. That is how
|
||||
# practice ended up on DeepSeek with reranking off while production ran Qwen
|
||||
# with reranking on.
|
||||
#
|
||||
# Two things deliberately stay OUT of this file and remain inline on the
|
||||
# Application:
|
||||
#
|
||||
# - `aiService.image` / `web.image` — rewritten on every push by
|
||||
# `.github/scripts/sync_practice_argocd.py`, which regex-replaces the tag
|
||||
# in the inline values. A tag committed here would be stale by design.
|
||||
# - anything secret. Nothing in the practice release currently needs one;
|
||||
# Bedrock authenticates through the node's instance role.
|
||||
#
|
||||
# ArgoCD applies `valueFiles` in order and then the inline values last, so the
|
||||
# image block inline still wins over anything the chart defaults set here.
|
||||
#
|
||||
# The behavioural settings below mirror the production runtime contract audited
|
||||
# on 2026-08-17 (see coordination/ARGOCD_PRODUCTION_MIGRATION_STATE_2026-08-17.md).
|
||||
# Practice is only useful as a migration rehearsal while they stay in sync.
|
||||
|
||||
global:
|
||||
environment: k3s-practice
|
||||
# The GHCR packages are private; without this the Pods fail ImagePullBackOff.
|
||||
imagePullSecrets:
|
||||
- name: ghcr-pull-secret
|
||||
|
||||
# PostgreSQL and Qdrant are owned by the separate `medical-chatbot-data`
|
||||
# release so that redeploying the app never touches persistent state. This
|
||||
# release therefore runs neither, and points at the data release's Services.
|
||||
postgres:
|
||||
enabled: false
|
||||
|
||||
qdrant:
|
||||
enabled: false
|
||||
url: http://medical-chatbot-data-medical-chatbot-qdrant.medical-chatbot-data.svc.cluster.local:6333
|
||||
|
||||
secret:
|
||||
postgresHost: medical-chatbot-data-medical-chatbot-postgres.medical-chatbot-data.svc.cluster.local
|
||||
|
||||
aiService:
|
||||
config:
|
||||
embeddingProvider: cohere-v4
|
||||
embeddingDimensions: 1024
|
||||
evidenceMinimumScore: 0.12
|
||||
awsRegion: us-east-1
|
||||
answerProvider: bedrock-converse
|
||||
answerModelId: qwen.qwen3-next-80b-a3b
|
||||
rerankEnabled: true
|
||||
|
||||
observability:
|
||||
grafana:
|
||||
# Practice-only convenience: the rehearsal cluster is a throwaway box and
|
||||
# Grafana sits behind the same ingress host. Never set this on production.
|
||||
anonymousAdmin: true
|
||||
|
||||
ingress:
|
||||
enabled: true
|
||||
className: traefik
|
||||
host: readytochat.realvuxbaro.me
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
tls:
|
||||
- hosts:
|
||||
- readytochat.realvuxbaro.me
|
||||
secretName: readytochat-tls
|
||||
@@ -7,7 +7,12 @@ aiService:
|
||||
tag: latest
|
||||
config:
|
||||
embeddingProvider: cohere-v4
|
||||
embeddingDimensions: 1024
|
||||
evidenceMinimumScore: 0.12
|
||||
awsRegion: us-east-1
|
||||
answerProvider: bedrock-converse
|
||||
answerModelId: qwen.qwen3-next-80b-a3b
|
||||
rerankEnabled: true
|
||||
otelSampleRatio: 0.25
|
||||
|
||||
web:
|
||||
|
||||
@@ -31,8 +31,12 @@ aiService:
|
||||
port: 8000
|
||||
config:
|
||||
embeddingProvider: disabled
|
||||
embeddingDimensions: 1024
|
||||
evidenceMinimumScore: 0.12
|
||||
awsRegion: us-east-1
|
||||
answerProvider: disabled
|
||||
answerModelId: deepseek.v3.2
|
||||
rerankEnabled: false
|
||||
# The Dockerfile bakes the catalog file in at this path; config.py's own
|
||||
# repo-relative default only resolves inside a full monorepo checkout,
|
||||
# not this flattened image layout. Matches apps/ai-service/.env.example.
|
||||
|
||||
Reference in New Issue
Block a user