merge: reconcile staging deployment histories
Deploy staging to test server / deploy (push) Successful in 12m36s

This commit is contained in:
linmeng
2026-07-30 13:26:44 +08:00
73 changed files with 5578 additions and 330 deletions
+10 -7
View File
@@ -413,11 +413,14 @@ previous-revision smoke SHA must remain pending. If the create flag, migration
flag, deployment SHA, or strict UUID allowlist is invalid, creation audience
must be `paused`, including for the smoke account.
After the smoke sequence below passes, set
After the smoke sequence below passes, use the guarded rollout workflow to set
`RECTIFICATION_V3_SYNTHETIC_SMOKE_SHA` to the exact deployed 40-character
lowercase Git SHA, remove `RECTIFICATION_V3_SYNTHETIC_SMOKE_USER_IDS`, and
restart the web container. Then fetch health again and
verify all of the following against the revision that passed validation:
lowercase Git SHA, remove `RECTIFICATION_V3_SYNTHETIC_SMOKE_USER_IDS`, enable
`RECTIFICATION_AGENT_V5_ENABLED=true`, disable shadow mode, set the canary to
100 percent, and restart both the web and rectification worker containers. The
workflow writes these selectors together so public Case creation cannot silently
fall back to the fixed `v4_legacy` projector. Then fetch health again and verify
all of the following against the revision that passed validation:
- `deployment.gitCommit` exactly equals the tested 40-character Git SHA;
- `rollout.conversationalRectificationV3.protocol` is
@@ -441,9 +444,9 @@ sequence. A plain HTTP `200` is not substitute evidence:
event, then a clear event. Verify the ambiguous/future facts do not score.
4. Pause, reload, and resume from a second authenticated browser session.
Verify no second rectification charge.
5. Reach a candidate, verify the prior active time is still in force, reject a
mismatched candidate confirmation, then explicitly confirm the exact
candidate. Verify the time changes atomically.
5. Reach a stable candidate range and verify the prior active time remains in
force. Confirm that no exact minute can be accepted and that rectification
does not write `profiles.active_birth_time`.
6. Explicitly continue the saved ordinary question. Verify one normal
consultation reservation. Delete its chat and verify the account case still
resumes/loads.
@@ -102,12 +102,16 @@ awk \
-v create="$creation_enabled" \
-v migrations="true" \
-v smoke_sha="$smoke_sha" \
-v smoke_users="$smoke_user_ids" '
-v smoke_users="$smoke_user_ids" \
-v agent_enabled="$creation_enabled" '
BEGIN {
values["RECTIFICATION_V3_CREATE_ENABLED"] = create
values["RECTIFICATION_V3_MIGRATIONS_READY"] = migrations
values["RECTIFICATION_V3_SYNTHETIC_SMOKE_SHA"] = smoke_sha
values["RECTIFICATION_V3_SYNTHETIC_SMOKE_USER_IDS"] = smoke_users
values["RECTIFICATION_AGENT_V5_ENABLED"] = agent_enabled
values["RECTIFICATION_AGENT_V5_SHADOW"] = "false"
values["RECTIFICATION_AGENT_V5_CANARY_PERCENT"] = "100"
}
{
split($0, parts, "=")
@@ -146,6 +150,18 @@ compose=(docker compose -p jyotisha-staging --env-file .env.staging "${compose_f
"${compose[@]}" config --quiet
"${compose[@]}" up -d --no-build --pull never --force-recreate --no-deps web rectification-v4-worker
for service in web rectification-v4-worker; do
container="$(docker ps -q --filter 'label=com.docker.compose.project=jyotisha-staging' --filter "label=com.docker.compose.service=$service" | head -n 1)"
[ -n "$container" ] || {
echo "staging $service container is missing after rollout" >&2
false
}
runtime_env="$(docker inspect --format '{{range .Config.Env}}{{println .}}{{end}}' "$container")"
grep -Fxq "RECTIFICATION_AGENT_V5_ENABLED=$creation_enabled" <<<"$runtime_env"
grep -Fxq "RECTIFICATION_AGENT_V5_SHADOW=false" <<<"$runtime_env"
grep -Fxq "RECTIFICATION_AGENT_V5_CANARY_PERCENT=100" <<<"$runtime_env"
done
health=""
for _ in $(seq 1 30); do
health="$(curl --fail --silent --show-error "$STAGING_URL/api/health" 2>/dev/null || true)"
+10 -1
View File
@@ -6,7 +6,16 @@ if [ "$#" -ne 2 ] || [ ! -d "$1" ] || [ ! -d "$2" ]; then
exit 1
fi
rsync -az --delete \
destination_deploy="$2/deploy"
if [ -d "$destination_deploy" ]; then
docker run --rm --pull never --network none --read-only --user 0:0 \
--cap-drop ALL --cap-add CHOWN --security-opt no-new-privileges \
-v "$destination_deploy:/destination" postgres:17-alpine \
chown -R "$(id -u):$(id -g)" /destination
chmod -R u+rwX "$destination_deploy"
fi
rsync -az --delete --no-owner --no-group \
--exclude='/.git/' \
--exclude='/.env*' \
--exclude='/.docker/' \