Validation: In-app registration with Keycloak phone field and Lead sync
Verdict: FAIL
Re-validated 2026-07-17. Previous validation also FAIL; root cause has shifted from messaging test failures (now fixed by PR #76) to minitest/mock infrastructure issue and secret placeholder values.
Ticket
ldraney/intelligentstaffingsystems#59 — In-app registration: post-Keycloak flow, phone validation, LeadsController reconciliation. Merged via PR #72 (commit
dfe3b8d). Board item #1831 on board-iss.Environment
Production cluster, namespace
intelligentstaffingsystems. URL: https://intelligentstaffingsystems.ai. ArgoCD application: intelligentstaffingsystems (Synced / Degraded). Keycloak realm: iss at https://keycloak.tail5b443a.ts.net/realms/iss.Two pods in namespace:
intelligentstaffingsystems-6d6896dd95-ls9k4— Running, 1/1, 0 restarts, 11h. Serving traffic on old image.intelligentstaffingsystems-8474c67bc8-nxphp— Init:CrashLoopBackOff, 0/1, 13 restarts, 42m. New ReplicaSet failing to start.
Tiers Executed
Tier 1 (local tests) — blocked, CI test step broken. Tier 3 (production) — executed, image not updated.
Checks
| # | Criterion | How Verified | Result | Evidence |
|---|---|---|---|---|
| 1 | Woodpecker pipeline green for merge commit | mcp__woodpecker__get_pipeline_status (pipeline #90, latest push to main) | FAIL | Pipeline #90: clone OK, database OK, bundle-install OK, lint OK, security OK, <strong>test FAIL</strong> (exit 1), build-and-push SKIPPED. Error: <code>cannot load such file -- minitest/mock (LoadError)</code> from <code>test/test_helper.rb:4</code>. Ruby 3.4 moved minitest/mock out of stdlib into bundled_gems. All pipelines since #19 have failed; no new image has been pushed to Harbor. |
| 2 | New image tag propagated to pods | <code>kubectl get pods -n intelligentstaffingsystems -o jsonpath='{.items[*].spec.containers[*].image}'</code> | FAIL | Both pods running image <code>harbor.tail5b443a.ts.net/intelligentstaffingsystems/app:93b9a79b8a88cbb07a7f8fda1b6d85803580cbbb</code>. This corresponds to commit <code>93b9a79</code> ("fix: align pipeline push repo with Argo CD Image Updater annotation"), which is <strong>many commits behind</strong> PR #72's merge at <code>dfe3b8d</code>. No new image was ever built because build-and-push is always skipped. |
| 3 | Pod running and ready, restarts = 0 | <code>kubectl get pods -n intelligentstaffingsystems</code> + <code>kubectl describe pod</code> | FAIL | Old pod (ReplicaSet <code>6d6896dd95</code>): Running, 0 restarts — healthy but on pre-PR-#72 code. New pod (ReplicaSet <code>8474c67bc8</code>): <code>Init:CrashLoopBackOff</code>, 13 restarts. Init container <code>migrate</code> fails: <code>ActiveRecord::DatabaseConnectionError: There is an issue connecting with your hostname: PLACEHOLDER_POSTGRES_HOST</code>. The Kubernetes secret <code>intelligentstaffingsystems-secrets</code> contains placeholder values. |
| 4 | Smoke test: health endpoint returns 200 | <code>curl -s -o /dev/null -w "%{http_code}" https://intelligentstaffingsystems.ai/up</code> | PASS (stale) | Both <code>/</code> and <code>/up</code> return HTTP 200. However, this is the old deployment serving on pre-PR-#72 code. The registration feature is NOT present. |
| 5 | Post-Keycloak registration flow (SessionsController 3-path resolve_lead with phone) | Cannot verify — code not deployed | FAIL | PR #72 added <code>extract_phone</code>, <code>sync_phone</code>, and 3-path <code>resolve_lead</code> (by sub, by email claim, walk-in) to SessionsController. Code is in the repo at commit <code>dfe3b8d</code> but not in the running container image (<code>93b9a79</code>). |
| 6 | Phone validation (Lead::PHONE_FORMAT) on Lead model | Cannot verify — code not deployed | FAIL | <code>PHONE_FORMAT = /\A\+?[\d\s\-\(\)\.]{7,20}\z/</code> regex and format validation exist in source but not in running image. |
| 7 | Keycloak register.ftl theme with phone field | Keycloak theme deployment is separate ticket (platform#541, board #1865) | N/A | The <code>register.ftl</code> and <code>register.css</code> files are in the repo. Their deployment to Keycloak is tracked by platform#541 (done) and svc#184 (#1864, in validation). This ticket covers only Rails-side wiring. |
| 8 | Backfill migration (phone placeholders for existing leads) | Cannot verify — migration never ran in production | FAIL | Migration <code>20260717100000_backfill_lead_phone_placeholders.rb</code> exists in source but the image containing it was never deployed. The new pod's migrate init container crashes before reaching this migration (PLACEHOLDER_POSTGRES_HOST). |
Regression Check
The existing site at
intelligentstaffingsystems.ai returns HTTP 200 at / and /up. No regression from the merge — the old deployment continues serving. However, ArgoCD health is Degraded due to the new pod's CrashLoopBackOff, indicating a deployment configuration problem independent of the code change.Root Cause
Two independent blockers prevent PR #72's code from reaching production:
- CI test runner broken (minitest/mock LoadError): Ruby 3.4's
bundled_gemschange movedminitest/mockout of the standard library.test/test_helper.rb:4doesrequire 'minitest/mock'which fails. The original messaging test failures (from the first validation) were fixed by PR #76, but this new infrastructure issue now blocks all pipelines. Theteststep exits 1, causingbuild-and-pushto be skipped. No new image has been pushed since commit93b9a79. - Kubernetes secret has placeholder values: The new ReplicaSet's init container
migratefails becausePOSTGRES_HOSTin secretintelligentstaffingsystems-secretsis set toPLACEHOLDER_POSTGRES_HOST. Even if a new image were built, it could not deploy until the secret is corrected.
Discovered Issues
- BLOCKER: minitest/mock LoadError in CI. All Woodpecker pipelines fail at the test step.
require 'minitest/mock'is no longer available in Ruby 3.4 without an explicit gem dependency. Fix: addgem "minitest"(with version that includes mock) to Gemfile, or adjust test_helper to not require minitest/mock if it's not needed. This blocks ALL ISS deployments. - BLOCKER: PLACEHOLDER_POSTGRES_HOST in prod secrets. The Kubernetes secret
intelligentstaffingsystems-secretshas a placeholder for POSTGRES_HOST. Any new pod (even on the same image) will fail to start. The old running pod predates this secret change. - ArgoCD Degraded health. Application shows Synced/Degraded. The CrashLoopBackOff pod from the new ReplicaSet is the cause.