Fingerprint the Qdrant corpus by content, not by count

This commit is contained in:
2026-08-17 14:31:56 +07:00
parent c778f7e9cc
commit d1c9933b9e
8 changed files with 391 additions and 43 deletions
@@ -10,6 +10,23 @@
{{- end -}}
{{- end -}}
{{/*
Container image reference.
The tag is demanded explicitly rather than defaulted so that a values file
which deliberately leaves it unset fails the render instead of silently
inheriting the chart's `local` development tag. Production and practice both
supply an immutable commit SHA per deploy — practice through the ArgoCD
Application's inline values, rewritten by sync_practice_argocd.py and a
chart that guessed a tag here would deploy something nobody asked for.
Usage: {{ include "medical-chatbot.image" (dict "image" .Values.web.image "name" "web") }}
*/}}
{{- define "medical-chatbot.image" -}}
{{- $tag := required (printf "%s.image.tag must be set to an immutable tag (a commit SHA); the chart will not guess one" .name) .image.tag -}}
{{- printf "%s:%s" (required (printf "%s.image.repository must be set" .name) .image.repository) $tag -}}
{{- end -}}
{{- define "medical-chatbot.labels" -}}
app.kubernetes.io/name: {{ include "medical-chatbot.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
@@ -55,7 +55,7 @@ spec:
{{- if .Values.aiService.migration.enabled }}
initContainers:
- name: migrate
image: "{{ .Values.aiService.image.repository }}:{{ .Values.aiService.image.tag }}"
image: {{ include "medical-chatbot.image" (dict "image" .Values.aiService.image "name" "aiService") | quote }}
imagePullPolicy: {{ .Values.aiService.image.pullPolicy }}
command: ["python", "migrate.py"]
envFrom:
@@ -69,7 +69,7 @@ spec:
{{- end }}
containers:
- name: ai-service
image: "{{ .Values.aiService.image.repository }}:{{ .Values.aiService.image.tag }}"
image: {{ include "medical-chatbot.image" (dict "image" .Values.aiService.image "name" "aiService") | quote }}
imagePullPolicy: {{ .Values.aiService.image.pullPolicy }}
ports:
- { name: http, containerPort: 8000 }
@@ -22,7 +22,7 @@ spec:
{{- toYaml .Values.global.imagePullSecrets | nindent 8 }}
containers:
- name: web
image: "{{ .Values.web.image.repository }}:{{ .Values.web.image.tag }}"
image: {{ include "medical-chatbot.image" (dict "image" .Values.web.image "name" "web") | quote }}
imagePullPolicy: {{ .Values.web.image.pullPolicy }}
env:
- name: AI_SERVICE_URL
+27 -2
View File
@@ -1,10 +1,33 @@
# Production values for the eventual ArgoCD cutover of realvuxbaro.me.
#
# Not live yet: production still runs Docker Compose on its own EC2, which is
# the DNS-level rollback for the migration. This file is what the production
# ArgoCD Application will render from once the rehearsal gates pass.
#
# The behavioural settings mirror the production runtime contract audited on
# 2026-08-17 — see coordination/ARGOCD_PRODUCTION_MIGRATION_STATE_2026-08-17.md.
global:
environment: production
# The GHCR packages are private, same as on the practice cluster. The Secret
# must exist in the target namespace before the first sync.
imagePullSecrets:
- name: ghcr-pull-secret
aiService:
replicaCount: 2
image:
tag: latest
repository: ghcr.io/baovu2k4/vsf-duocthu-ai-service
# Deliberately empty. Production must run an immutable, verifiable image,
# so the tag is supplied per deploy as a commit SHA — through the ArgoCD
# Application's inline values, exactly as the practice cluster does. A
# `latest` here would make "which code is production running?" unanswerable
# and would break rollback, since the same tag would point at new content.
#
# `medical-chatbot.image` turns this empty value into a hard render error
# rather than a silent fallback to the chart's `local` development tag.
tag: ""
pullPolicy: Always
config:
embeddingProvider: cohere-v4
embeddingDimensions: 1024
@@ -18,7 +41,9 @@ aiService:
web:
replicaCount: 2
image:
tag: latest
repository: ghcr.io/baovu2k4/vsf-duocthu-web
tag: ""
pullPolicy: Always
ingress:
enabled: true