Appearance
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.jsondeploy/gateway/routes.auth-native-localhost-example.jsondeploy/gateway/routes.profile-native-example.jsondeploy/gateway/routes.profile-native-localhost-example.jsondocs/qa/iam-profile-default-cutover-proof.mddocs/qa/auth-route-browser-smoke.mddocs/qa/auth-route-live-smoke.mddocs/qa/profile-route-browser-smoke.mddocs/qa/profile-route-live-smoke.mddocs/qa/iam-profile-route-rollback-rehearsal.mddocs/microservices/iam-profile-implementation-report.mddocs/agents/service-tasks/iam-profile-default-cutover-proof.mddocs/agents/service-tasks/iam-profile-cutover-hardening.mdscripts/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.jsonis 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 eventualdeploy/gateway/routes.jsonpromotion 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, andscripts/test/iam-profile-live-populated-validation.sh.scripts/test/iam-profile-default-cutover-proof-bundle.shis the orchestrator wrapper that ties these artifacts together for a single target review.scripts/test/iam-profile-default-cutover-review-artifact.shvalidates 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, anddocs/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, andmake 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.mdlistsauth-google-configandauth-meas eligible for the next default candidate review, lists every other IAM/Profile native rehearsal as blocked with a reason, andmake test-iam-profile-default-cutover-candidatesguards that this list stays complete whiledeploy/gateway/routes.jsonremains legacy-safe. - [x] Add a review-only default route candidate diff package. The
scripts/test/iam-profile-default-candidate-diff.shhelper generatescandidate-routes.json,candidate-routes.diff, andsummary.jsonfor the two currently eligible read-only IAM routes from the service-DNS native route table. It fails ifdeploy/gateway/routes.jsonalready 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.shreuses the auth route live smoke against a prepared candidate table, checks the gateway route headers forauth-google-configandauth-me, and verifies all blocked auth/profile/KYC routes remain inactive while broadauth,admin, andfallbackstaylegacy_proxy. Local candidate proof was captured underoutput/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.shruns the auth route Playwright smoke withAUTH_ROUTE_BROWSER_EXPECT_ROUTE_SET=candidate-readonly, so the default candidate table may contain onlyauth-google-configandauth-mebefore broadauth/legacy_proxy. The wrapper requiresapi-gateway, recordsdefaultRouteTableModified=false, and keeps blocked auth/profile/KYC routes out of the candidate browser proof. Local candidate browser proof was captured underoutput/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.shrequires the generated candidate route table, validates that onlyauth-google-configandauth-meare active, then reuses the IAM/Profile rollback rehearsal againstdeploy/gateway/routes.jsonthroughapi-gateway. It recordsdefaultRouteTableModified=falseand proves broadauth,admin, andfallbackreturn tolegacy_proxy. Local candidate rollback proof was captured underoutput/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/, andoutput/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 defaultauth,admin, andfallbackaslegacy_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-isolatedto 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 recordstargetProvenance=disposable-populated,defaultRouteTableModified=false, androutePromotionApproved=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, authenticatedme, refresh-token rotation, old-refresh rejection, session restoration after refresh, logout, and refresh-after-logout rejection throughapi-gateway. Local proof was captured underoutput/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 attachedpostload-reconciliationevidence must show every item matched, zero issues, zero rejected rows, source/target hashes, non-empty target rows, completedmigration_runs, and clean owner-local orphan checks. Current blocker snapshot: the latest local bundle atoutput/qa/iam-profile-default-cutover-proof-bundle-20260710-083035/ismode=self-test/targetProvenance=fixture_onlyand is intentionally rejected byIAM_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.shruns 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. Itssummary.jsonrecordsroutePromotionApproved=falseanddefaultRouteTableModified=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.shvalidates an already captured bundle fromIAM_PROFILE_DEFAULT_CUTOVER_PROOF_BUNDLE_ARTIFACT_DIR, rejects fixture/self-test summaries, requiresmode=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, andmake test-iam-profile-uuid-primary-key-promotionwith 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-rollbackagainst the rollback table and record how to restoredeploy/gateway/routes.jsonto 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.mdwith 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-servicetask 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-gatewayor BFF URLs only; no frontend route callsiam-serviceorprofile-servicedirectly. - Default-route promotion is tied to production-like populated validation with
IAM_PROFILE_LIVE_VALIDATION_RUN_REPORT=/path/to/migrator-run.jsonandIAM_PROFILE_LIVE_VALIDATION_REQUIRE_RUN_REPORT=1; fixture-only evidence is insufficient and must be rejected bymake 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-routesmake test-iam-profile-default-cutover-candidatesmake test-iam-profile-default-candidate-diffIAM_PROFILE_DEFAULT_CANDIDATE_LIVE_CONFIRM=auth-candidate GATEWAY_BASE_URL=http://localhost:<port> make test-iam-profile-default-candidate-liveIAM_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-browserIAM_PROFILE_DEFAULT_CANDIDATE_ROLLBACK_CONFIRM=auth-candidate-rollback GATEWAY_BASE_URL=http://localhost:<gateway-port> make test-iam-profile-default-candidate-rollbackIAM_PROFILE_DEFAULT_CANDIDATE_ISOLATED_CONFIRM=disposable-populated make test-iam-profile-default-candidate-isolatedAUTH_ROUTE_LIVE_CONFIRM=auth-native make test-auth-routes-liveAUTH_ROUTE_BROWSER_CONFIRM=auth-native make test-auth-routes-browserAUTH_SESSION_BROWSER_CONFIRM=auth-session make test-auth-routes-session-browserPROFILE_ROUTE_LIVE_CONFIRM=profile-native PROFILE_ROUTE_LIVE_SEED_CONFIRM=seed-profile make test-profile-routes-livePROFILE_ROUTE_BROWSER_CONFIRM=profile-native PROFILE_ROUTE_BROWSER_SEED_CONFIRM=seed-profile make test-profile-routes-browserIAM_PROFILE_ROUTE_ROLLBACK_CONFIRM=default-legacy make test-iam-profile-route-rollbackIAM_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-validationIAM_PROFILE_UUID_PK_READINESS_CONFIRM=uuid-primary-key-readiness IAM_DATABASE_URL=postgres://... PROFILE_DATABASE_URL=postgres://... make test-iam-profile-uuid-primary-key-readinessIAM_PROFILE_UUID_FK_VALIDATION_CONFIRM=uuid-foreign-key-validation IAM_DATABASE_URL=postgres://... PROFILE_DATABASE_URL=postgres://... make test-iam-profile-uuid-foreign-key-validationIAM_PROFILE_UUID_PK_PROMOTION_CONFIRM=uuid-primary-key-promotion IAM_DATABASE_URL=postgres://... PROFILE_DATABASE_URL=postgres://... make test-iam-profile-uuid-primary-key-promotionIAM_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-bundleIAM_PROFILE_DEFAULT_CUTOVER_PROOF_BUNDLE_ARTIFACT_DIR=output/qa/iam-profile-default-cutover-proof-bundle-<timestamp> make test-iam-profile-default-cutover-review-artifactmake test-service-task-packspnpm docs:build