Skip to content

IAM/Profile Default Cutover Proof Task

Agent workflow: follow README.md for Audit -> Investigate -> Code -> Test -> Fix; this pack owns only the final proof package for default IAM/Profile route promotion.

Dispatch type: orchestrator

Owner: orchestrator with iam-service, profile-service, api-gateway, browser QA, and migration owners.

Problem:

The auth-service to iam-service rename is not a request to create a deployable auth-service. Native IAM/Profile service foundations, UUID-backed promoted target schemas, backfill tooling, Compose proof, local K8s proof, and non-default route rehearsals exist. The remaining high-risk gap is proving a specific default gateway route set against production-like populated IAM/Profile targets, with browser evidence and a tested rollback path.

Goal:

Create the final promotion evidence bundle for selected default /api/auth*, profile, and KYC compatibility routes while preserving the rule that frontend apps call only api-gateway or an approved BFF. This pack must not implement new identity/profile features; it verifies readiness to change default routing. Frontend apps call only api-gateway or an approved BFF during this proof.

Legacy source evidence:

  • /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/auth/**
  • /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/app-data/**
  • /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/web

Writable files:

  • deploy/gateway/routes.auth-native-example.json
  • deploy/gateway/routes.auth-native-localhost-example.json
  • deploy/gateway/routes.profile-native-example.json
  • deploy/gateway/routes.profile-native-localhost-example.json
  • docs/qa/iam-profile-default-cutover-proof.md
  • docs/qa/auth-route-browser-smoke.md
  • docs/qa/auth-route-live-smoke.md
  • docs/qa/profile-route-browser-smoke.md
  • docs/qa/profile-route-live-smoke.md
  • docs/qa/iam-profile-route-rollback-rehearsal.md
  • docs/microservices/iam-profile-implementation-report.md
  • docs/agents/service-tasks/iam-profile-default-cutover-proof.md
  • docs/agents/service-tasks/iam-profile-cutover-hardening.md
  • scripts/test/iam-profile-default-cutover-review-artifact.sh

Orchestrator-owned files:

  • Default gateway route tables, root Makefile, browser QA artifacts, VitePress navigation, and final promotion/rollback decision records. deploy/gateway/routes.json is review-only unless this task is running a separately approved promotion or rollback step with matching proof artifacts.

Delegated gateway verification scope:

  • Route examples: deploy/gateway/routes.auth-native-example.json, deploy/gateway/routes.auth-native-localhost-example.json, deploy/gateway/routes.profile-native-example.json, deploy/gateway/routes.profile-native-localhost-example.json, and the eventual deploy/gateway/routes.json promotion diff.
  • Test scripts: scripts/test/auth-route-coverage.sh, scripts/test/profile-route-coverage.sh, scripts/test/auth-route-live-smoke.sh, scripts/test/auth-route-browser-smoke.mjs, scripts/test/profile-route-live-smoke.sh, scripts/test/profile-route-browser-smoke.mjs, scripts/test/iam-profile-route-rollback-rehearsal.sh, and scripts/test/iam-profile-live-populated-validation.sh. scripts/test/iam-profile-default-cutover-proof-bundle.sh is the orchestrator wrapper that ties these artifacts together for a single target review. scripts/test/iam-profile-default-cutover-review-artifact.sh validates a completed production-like proof bundle offline before a human promotion review.
  • QA docs: docs/qa/auth-route-live-smoke.md, docs/qa/auth-route-browser-smoke.md, docs/qa/profile-route-live-smoke.md, docs/qa/profile-route-browser-smoke.md, docs/qa/iam-profile-route-rollback-rehearsal.md, and docs/qa/iam-profile-default-cutover-proof.md.
  • Makefile targets: make test-auth-routes, make test-profile-routes, make test-auth-routes-live, make test-auth-routes-browser, make test-auth-routes-session-browser, make test-profile-routes-live, make test-profile-routes-browser, make test-iam-profile-route-rollback, and make test-iam-profile-live-populated-validation.

Tasks:

  • [x] Define the exact default route candidate list. Include only routes whose native gateway rehearsal already exists and whose legacy response envelope is proven from browser/runtime evidence. Keep broad /api/auth, broad /api/admin, fallback, and unrelated profile/admin routes legacy unless the candidate list explicitly proves them. Current status: docs/qa/iam-profile-default-cutover-proof.md lists auth-google-config and auth-me as eligible for the next default candidate review, lists every other IAM/Profile native rehearsal as blocked with a reason, and make test-iam-profile-default-cutover-candidates guards that this list stays complete while deploy/gateway/routes.json remains legacy-safe.
  • [x] Add a review-only default route candidate diff package. The scripts/test/iam-profile-default-candidate-diff.sh helper generates candidate-routes.json, candidate-routes.diff, and summary.json for the two currently eligible read-only IAM routes from the service-DNS native route table. It fails if deploy/gateway/routes.json already activates pending candidates or if any blocked auth/profile/KYC route would be included.
  • [x] Add an opt-in candidate gateway live smoke for the same read-only route set. scripts/test/iam-profile-default-candidate-live-smoke.sh reuses the auth route live smoke against a prepared candidate table, checks the gateway route headers for auth-google-config and auth-me, and verifies all blocked auth/profile/KYC routes remain inactive while broad auth, admin, and fallback stay legacy_proxy. Local candidate proof was captured under output/qa/iam-profile-default-candidate-live-20260709-094220/.
  • [x] Add an opt-in candidate browser smoke for the same read-only route set. scripts/test/iam-profile-default-candidate-browser-smoke.sh runs the auth route Playwright smoke with AUTH_ROUTE_BROWSER_EXPECT_ROUTE_SET=candidate-readonly, so the default candidate table may contain only auth-google-config and auth-me before broad auth/legacy_proxy. The wrapper requires api-gateway, records defaultRouteTableModified=false, and keeps blocked auth/profile/KYC routes out of the candidate browser proof. Local candidate browser proof was captured under output/qa/iam-profile-default-candidate-browser-20260709-095159/.
  • [x] Add an opt-in candidate rollback smoke for the same read-only route set. scripts/test/iam-profile-default-candidate-rollback-smoke.sh requires the generated candidate route table, validates that only auth-google-config and auth-me are active, then reuses the IAM/Profile rollback rehearsal against deploy/gateway/routes.json through api-gateway. It records defaultRouteTableModified=false and proves broad auth, admin, and fallback return to legacy_proxy. Local candidate rollback proof was captured under output/qa/iam-profile-default-candidate-rollback-20260709-095948/.
  • [x] Refresh the complete local non-default candidate chain after applying the local IAM/Profile schemas. The 2026-07-10 artifacts under output/qa/iam-profile-default-candidate-localhost-20260710-1544/, output/qa/iam-profile-default-candidate-live-20260710-1547/, output/playwright/iam-profile-default-candidate-browser-20260710-1548/, and output/qa/iam-profile-default-candidate-rollback-20260710-1548/ agree on the Gateway-normalized candidate hash. They prove only the two read-only IAM routes and preserve default auth, admin, and fallback as legacy_proxy; they are not production-like promotion evidence.
  • [x] Add a reproducible disposable populated candidate runtime. Run IAM_PROFILE_DEFAULT_CANDIDATE_ISOLATED_CONFIRM=disposable-populated make test-iam-profile-default-candidate-isolated to backfill fresh owner databases, validate UUID metadata on those same databases, then run actual IAM/Profile, candidate Gateway, public-web browser, and rollback Gateway processes. Its artifact records targetProvenance=disposable-populated, defaultRouteTableModified=false, and routePromotionApproved=false; it is a regression proof, not a substitute for the production-like bundle below.
  • [x] Add an opt-in auth session lifecycle browser smoke for the non-default auth-native route set. scripts/test/auth-route-session-browser-smoke.* proves browser-originated register, login, authenticated me, refresh-token rotation, old-refresh rejection, session restoration after refresh, logout, and refresh-after-logout rejection through api-gateway. Local proof was captured under output/playwright/auth-route-session-browser-smoke-20260709-100744/, with access tokens, refresh tokens, and passwords redacted from artifacts.
  • [ ] Attach production-like populated target validation. Run the read-only cutover gate with the captured loader report: IAM_PROFILE_LIVE_VALIDATION_CONFIRM=live-populated IAM_PROFILE_LIVE_VALIDATION_RUN_REPORT=/path/to/migrator-run.json IAM_PROFILE_LIVE_VALIDATION_REQUIRE_RUN_REPORT=1 IAM_DATABASE_URL=postgres://.../hoctapaz_iam_db?sslmode=disable PROFILE_DATABASE_URL=postgres://.../hoctapaz_profile_db?sslmode=disable make test-iam-profile-live-populated-validation. The attached postload-reconciliation evidence must show every item matched, zero issues, zero rejected rows, source/target hashes, non-empty target rows, completed migration_runs, and clean owner-local orphan checks. Current blocker snapshot: the latest local bundle at output/qa/iam-profile-default-cutover-proof-bundle-20260710-083035/ is mode=self-test / targetProvenance=fixture_only and is intentionally rejected by IAM_PROFILE_DEFAULT_CUTOVER_PROOF_BUNDLE_ARTIFACT_DIR=output/qa/iam-profile-default-cutover-proof-bundle-20260710-083035 make test-iam-profile-default-cutover-review-artifact. It does not replace production-like populated target validation.
  • [x] Add a single proof-bundle wrapper for the default cutover review. scripts/test/iam-profile-default-cutover-proof-bundle.sh runs populated target validation, UUID readiness/FK/PK promotion checks, candidate diff, candidate live smoke, candidate browser smoke, and candidate rollback smoke into one artifact tree. Its summary.json records routePromotionApproved=false and defaultRouteTableModified=false, so a green bundle is a coherent evidence package, not automatic production approval.
  • [x] Add an offline proof-bundle artifact review guard. scripts/test/iam-profile-default-cutover-review-artifact.sh validates an already captured bundle from IAM_PROFILE_DEFAULT_CUTOVER_PROOF_BUNDLE_ARTIFACT_DIR, rejects fixture/self-test summaries, requires mode=live, targetProvenance=production-like, populated target minimums greater than one, a passed required migrator run report, matching candidate/gateway route-table hashes, and no default route modification or automatic promotion. Current proof: the guard rejects the latest self-test bundle, confirming that a green wrapper self-test cannot be mistaken for a route-promotion artifact.
  • [ ] Attach live UUID metadata validation from the same populated target DSNs: make test-iam-profile-uuid-primary-key-readiness, make test-iam-profile-uuid-foreign-key-validation, and make test-iam-profile-uuid-primary-key-promotion with their required confirmation variables.
  • [ ] Capture gateway live smoke for the promoted route set through api-gateway, not direct service hostnames. The evidence must include selected status codes, gateway route headers, request ids, and proof that sibling non-candidate routes still hit the intended legacy route.
  • [ ] Capture browser proof for login, refresh/session restoration, logout, password reset/change where promoted, Google auth entry/config where promoted, profile update routes where promoted, and teacher/admin KYC routes where promoted. Browser proof must use gateway URLs and must not expose raw tokens or credentials in screenshots, logs, or telemetry.
  • [ ] Capture rollback proof after promotion. Run make test-iam-profile-route-rollback against the rollback table and record how to restore deploy/gateway/routes.json to the previous legacy/default state. Rollback proof must include route-header checks for at least one IAM route, one profile/KYC route when promoted, one broad legacy sibling route, and the fallback route.
  • [ ] Update docs/qa/iam-profile-default-cutover-proof.md with target DSNs redacted, route table revisions, command outputs, browser artifact paths, and rollback commands. Do not mark the cutover approved if any candidate route lacks validation, browser, live gateway, or rollback evidence.

Acceptance:

  • No deployable auth-service, auth-service task pack, auth-service OpenAPI contract, or auth-service deployment is introduced.
  • IAM remains the only owner of credentials, sessions, JWT/JWKS, roles, permissions, organization membership access, parent-student access permission, teacher subject scopes, staff permission scopes, and security logs.
  • Profile remains the only owner of display profile, avatar/display metadata, role-specific profile data, teacher KYC storage/review state, and parent-child read models.
  • Frontend and browser proof use api-gateway or BFF URLs only; no frontend route calls iam-service or profile-service directly.
  • Default-route promotion is tied to production-like populated validation with IAM_PROFILE_LIVE_VALIDATION_RUN_REPORT=/path/to/migrator-run.json and IAM_PROFILE_LIVE_VALIDATION_REQUIRE_RUN_REPORT=1; fixture-only evidence is insufficient and must be rejected by make test-iam-profile-default-cutover-review-artifact.
  • Rollback is tested after promotion and documented before the cutover is called complete.
  • Any final text-id cleanup remains a separate migration task after default route behavior and rollback have been proven.

Verification:

  • make test-auth-routes test-profile-routes
  • make test-iam-profile-default-cutover-candidates
  • make test-iam-profile-default-candidate-diff
  • IAM_PROFILE_DEFAULT_CANDIDATE_LIVE_CONFIRM=auth-candidate GATEWAY_BASE_URL=http://localhost:<port> make test-iam-profile-default-candidate-live
  • IAM_PROFILE_DEFAULT_CANDIDATE_BROWSER_CONFIRM=auth-candidate WEB_BASE_URL=http://localhost:<web-port> GATEWAY_BASE_URL=http://localhost:<gateway-port> make test-iam-profile-default-candidate-browser
  • IAM_PROFILE_DEFAULT_CANDIDATE_ROLLBACK_CONFIRM=auth-candidate-rollback GATEWAY_BASE_URL=http://localhost:<gateway-port> make test-iam-profile-default-candidate-rollback
  • IAM_PROFILE_DEFAULT_CANDIDATE_ISOLATED_CONFIRM=disposable-populated make test-iam-profile-default-candidate-isolated
  • AUTH_ROUTE_LIVE_CONFIRM=auth-native make test-auth-routes-live
  • AUTH_ROUTE_BROWSER_CONFIRM=auth-native make test-auth-routes-browser
  • AUTH_SESSION_BROWSER_CONFIRM=auth-session make test-auth-routes-session-browser
  • PROFILE_ROUTE_LIVE_CONFIRM=profile-native PROFILE_ROUTE_LIVE_SEED_CONFIRM=seed-profile make test-profile-routes-live
  • PROFILE_ROUTE_BROWSER_CONFIRM=profile-native PROFILE_ROUTE_BROWSER_SEED_CONFIRM=seed-profile make test-profile-routes-browser
  • IAM_PROFILE_ROUTE_ROLLBACK_CONFIRM=default-legacy make test-iam-profile-route-rollback
  • IAM_PROFILE_LIVE_VALIDATION_CONFIRM=live-populated IAM_PROFILE_LIVE_VALIDATION_RUN_REPORT=/path/to/migrator-run.json IAM_PROFILE_LIVE_VALIDATION_REQUIRE_RUN_REPORT=1 IAM_DATABASE_URL=postgres://.../hoctapaz_iam_db?sslmode=disable PROFILE_DATABASE_URL=postgres://.../hoctapaz_profile_db?sslmode=disable make test-iam-profile-live-populated-validation
  • IAM_PROFILE_UUID_PK_READINESS_CONFIRM=uuid-primary-key-readiness IAM_DATABASE_URL=postgres://... PROFILE_DATABASE_URL=postgres://... make test-iam-profile-uuid-primary-key-readiness
  • IAM_PROFILE_UUID_FK_VALIDATION_CONFIRM=uuid-foreign-key-validation IAM_DATABASE_URL=postgres://... PROFILE_DATABASE_URL=postgres://... make test-iam-profile-uuid-foreign-key-validation
  • IAM_PROFILE_UUID_PK_PROMOTION_CONFIRM=uuid-primary-key-promotion IAM_DATABASE_URL=postgres://... PROFILE_DATABASE_URL=postgres://... make test-iam-profile-uuid-primary-key-promotion
  • IAM_PROFILE_DEFAULT_CUTOVER_PROOF_BUNDLE_CONFIRM=default-cutover-proof IAM_PROFILE_DEFAULT_CUTOVER_TARGET_PROVENANCE=production-like IAM_PROFILE_LIVE_VALIDATION_RUN_REPORT=/path/to/migrator-run.json IAM_PROFILE_LIVE_VALIDATION_REQUIRE_RUN_REPORT=1 IAM_PROFILE_LIVE_VALIDATION_MIN_ACCOUNTS=<expected-min-account-rows> IAM_PROFILE_LIVE_VALIDATION_MIN_MAP_ROWS=<expected-min-migration-map-rows> IAM_DATABASE_URL=postgres://... PROFILE_DATABASE_URL=postgres://... GATEWAY_BASE_URL=http://localhost:<gateway-port> WEB_BASE_URL=http://localhost:<web-port> make test-iam-profile-default-cutover-proof-bundle
  • IAM_PROFILE_DEFAULT_CUTOVER_PROOF_BUNDLE_ARTIFACT_DIR=output/qa/iam-profile-default-cutover-proof-bundle-<timestamp> make test-iam-profile-default-cutover-review-artifact
  • make test-service-task-packs
  • pnpm docs:build

Go-platform documentation is generated from repository Markdown.