Skip to content

chore(deps): bump esbuild and vite in /landing-website#25

Merged
ahmetabdullahgultekin merged 1 commit into
masterfrom
dependabot/npm_and_yarn/landing-website/multi-5f24edee58
Mar 28, 2026
Merged

chore(deps): bump esbuild and vite in /landing-website#25
ahmetabdullahgultekin merged 1 commit into
masterfrom
dependabot/npm_and_yarn/landing-website/multi-5f24edee58

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Mar 19, 2026

Copy link
Copy Markdown
Contributor

Removes esbuild. It's no longer used after updating ancestor dependency vite. These dependencies need to be updated together.

Removes esbuild

Updates vite from 5.4.21 to 8.0.1

Release notes

Sourced from vite's releases.

create-vite@8.0.1

Please refer to CHANGELOG.md for details.

v8.0.1

Please refer to CHANGELOG.md for details.

create-vite@8.0.0

Please refer to CHANGELOG.md for details.

plugin-legacy@8.0.0

Please refer to CHANGELOG.md for details.

v8.0.0

Please refer to CHANGELOG.md for details.

v8.0.0-beta.18

Please refer to CHANGELOG.md for details.

v8.0.0-beta.17

Please refer to CHANGELOG.md for details.

v8.0.0-beta.16

Please refer to CHANGELOG.md for details.

v8.0.0-beta.15

Please refer to CHANGELOG.md for details.

v8.0.0-beta.14

Please refer to CHANGELOG.md for details.

v8.0.0-beta.13

Please refer to CHANGELOG.md for details.

v8.0.0-beta.12

Please refer to CHANGELOG.md for details.

v8.0.0-beta.11

Please refer to CHANGELOG.md for details.

v8.0.0-beta.10

Please refer to CHANGELOG.md for details.

v8.0.0-beta.9

Please refer to CHANGELOG.md for details.

v8.0.0-beta.8

Please refer to CHANGELOG.md for details.

v8.0.0-beta.7

Please refer to CHANGELOG.md for details.

... (truncated)

Changelog

Sourced from vite's changelog.

8.0.1 (2026-03-19)

Features

Bug Fixes

  • bundled-dev: properly disable inlineConst optimization (#21865) (6d97142)
  • css: lightningcss minify failed when build.target: 'es6' (#21933) (5fcce46)
  • deps: update all non-major dependencies (#21878) (6dbbd7f)
  • dev: always use ESM Oxc runtime (#21829) (d323ed7)
  • dev: handle concurrent restarts in _createServer (#21810) (40bc729)
  • handle + symbol in package subpath exports during dep optimization (#21886) (86db93d)
  • improve no-cors request block error (#21902) (5ba688b)
  • use precise regexes for transform filter to avoid backtracking (#21800) (dbe41bd)
  • worker: require(json) result should not be wrapped (#21847) (0672fd2)
  • worker: make worker output consistent with client and SSR (#21871) (69454d7)

Miscellaneous Chores

8.0.0 (2026-03-12)

Vite 8 is here!

Today, we're thrilled to announce the release of the next Vite major:

⚠ BREAKING CHANGES

  • remove import.meta.hot.accept resolution fallback (#21382)
  • update default browser target (#21193)
  • the epic rolldown-vite merge (#21189)

Features

... (truncated)

Commits
  • ea68a88 chore(deps): update rolldown-related dependencies (#20810)
  • 693d255 release: v7.1.7
  • 98a3484 fix(hmr): wait for import.meta.hot.prune callbacks to complete before runni...
  • 9f32b1d fix(hmr): trigger prune event when import is removed from non hmr module (#20...
  • 9f2247c fix(deps): update all non-major dependencies (#20811)
  • 105abe8 fix(glob): handle glob imports from folders starting with dot (#20800)
  • 4c4583c fix(build): fix ssr environment emitAssets: true when `sharedConfigBuild: t...
  • 9bc9d12 fix(client): use CSP nonce when rendering error overlay (#20791)
  • 54377f7 release: v7.1.6
  • 88af2ae fix(deps): update all non-major dependencies (#20773)
  • Additional commits viewable in compare view

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    You can disable automated security fix PRs for this repo from the Security Alerts page.

Removes [esbuild](https://github.com/evanw/esbuild). It's no longer used after updating ancestor dependency [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite). These dependencies need to be updated together.


Removes `esbuild`

Updates `vite` from 5.4.21 to 8.0.1
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/create-vite@8.0.1/packages/vite)

---
updated-dependencies:
- dependency-name: esbuild
  dependency-version: 
  dependency-type: indirect
- dependency-name: vite
  dependency-version: 8.0.1
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code labels Mar 19, 2026
@ahmetabdullahgultekin ahmetabdullahgultekin merged commit 8d700f2 into master Mar 28, 2026
1 check passed
@dependabot dependabot Bot deleted the dependabot/npm_and_yarn/landing-website/multi-5f24edee58 branch March 28, 2026 08:26
ahmetabdullahgultekin added a commit that referenced this pull request Apr 25, 2026
…-04-25)

Pointer bump for the 4 PRs that landed on identity-core-api/main today:
  efb8228  feat(rbac): V45 TENANT_ADMIN permission baseline (#27)
  4794595  fix(auth): session cancel + dead-end prevention + method switch (#25)
  9e2df8e  feat(tenants): multi email-domain support (V44 + entity foundation) (#26)
  4bee6d7  feat(register): resolve tenant by email-domain via tenant_email_domains (V44 wire-up) (#28)

V44 + V45 migrations both ship in this bump. Next prod boot
(\`docker compose up -d identity-core-api\`) will apply them.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ahmetabdullahgultekin added a commit that referenced this pull request Apr 25, 2026
identity-core-api → 12e8010 (PR #30 V47 enrollment scores + PR #31 auth-sessions admin list)
biometric-processor → 8c5423f (PR #53 demographics router gating, ~400 MB savings)
web-app → b59005c (PR #44 auth-sessions admin page wiring)
client-apps → f4bdc40 (PR #33 MFA PR #25 endpoints — DELETE cancel + switch-method + NEEDS_ENROLLMENT)

Prod deploys:
- identity-core-api rebuilt + restarted with V47 → live, GET /auth/sessions verified
- biometric-api rebuilt + restarted with demographics gating → ~400 MB freed
ahmetabdullahgultekin added a commit that referenced this pull request May 1, 2026
api 2fe3f03..04b44bf:
  PR #46 — chore: address Copilot post-merge findings on PR #43+#44 (round 3)
    V52__shedlock_timestamps_tz.sql — ALTER lock_until/locked_at to
      TIMESTAMP WITH TIME ZONE so shedlock matches the rest of the
      schema's TZ-aware convention (rest of identity_core uses TIMESTAMPTZ).
      Picked V52 because MigrationChainContiguityTest requires no gap;
      V54 would have failed.
    VerifiableSmsService.java — closed unclosed Javadoc <p> tag (doclint).
    TwilioVerifySmsService.java — log.warn now passes the exception so
      SLF4J emits the stack trace (was string-only before).
    OtpController.java — switches on VerifyResult so the summary log
      says "SMS OTP provider error" on PROVIDER_ERROR vs "SMS OTP
      mismatch" on INVALID_CODE.
    OtpControllerTest.java — Logback ListAppender attached, asserts
      both WARN reason branches plus negative regression guard.

web f2930ca..e90aa35:
  PR #56 — chore: address Copilot post-merge findings on PR #53 (round 3)
    QrCodePuzzle.tsx — onError moved into useEffect so it no longer
      fires during render (kills "Cannot update a component while
      rendering a different component" warning).
    EmailOtpPuzzle.tsx — header comment fixed (OTP sent on click,
      not on mount).
    useTestVerifyApi.ts — JSDoc paths standardised on apiBase-relative
      form to match AuthSessionRepository.generateQrToken; file header
      documents the convention.
    AuthMethodMode.tsx — docblock rewritten to use the actual
      AuthMethodModeKind values (real | test | stub) instead of the
      stale "live" reference.

Test verification (per agent):
  api  — mvn -Dtest=OtpControllerTest,MigrationChainContiguityTest → 17/17
  web  — npx vitest run src/features/auth-methods-testing → 47/47
         npm run lint → 0 errors / 2 pre-existing warnings (cap 90)

23 PRs merged this session total. Round 3 closes the Copilot review
backlog. Operator container rebuild (Task #25) still required for the
server-side fixes to land in prod.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ahmetabdullahgultekin added a commit that referenced this pull request May 1, 2026
…landed (PR #47)

PR #47 — feat(db): V53 BEFORE DELETE trigger on users + tenants
  RAISE EXCEPTION on hard DELETE; bypass via SET LOCAL
  app.allow_hard_delete='on' for legitimate GDPR Art. 17 purge.
  SoftDeletePurgeJob.purgeBatch now sets the GUC inside the TX so the
  trigger lets the row delete proceed. Trigger is idempotent
  (CREATE OR REPLACE FUNCTION + DROP TRIGGER IF EXISTS).
  Closes the residual hard-delete vector flagged in DB review #1
  (DB_REVIEW_2026-04-30.md) and codifies feedback_no_hard_delete_users.md
  at the database layer.

  Renumbered to V53 because V51 = ShedLock (PR #43) and V52 = ShedLock
  TIMESTAMPTZ alignment (PR #46) merged first.

  Ahabgu incident regression (2026-04-28 careless `DELETE FROM users`
  cascading across 13 FK children) is now engine-level impossible.

  3 commits: migration SQL + purge bypass + Testcontainers integration
  test (RUN_INTEGRATION=true gate, CI exercises).

  Effective on next container rebuild (Task #25).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ahmetabdullahgultekin added a commit that referenced this pull request May 1, 2026
…/10)

api 8c7f6d2..6bb853f:
  PR #49 — fix(admin): SUPER_ADMIN cross-tenant + missing default-flow
           transition + verification stats aggregates
    Bug A — Guest endpoints route through TenantScopeResolver so
            SUPER_ADMIN sees platform-wide invitations; cross-tenant repo
            methods added; IllegalStateException → 409 in
            GlobalExceptionHandler (was generic 500).
    Bug B — ManageAuthFlowService.updateFlow now dethrones the prior
            default flow in the same TX when isDefault=true.
    Bug C — AuthSessionController + DeviceController accept null tenantId
            for SUPER_ADMIN as platform-wide. Paged repo methods
            findAllByStatusIn / findAllByUserId added; listAllDevices()
            use-case.
    Bug D — VerificationController /stats now computes
            completionRate, failureRate, avgTimeMinutes,
            statusDistribution, last-30-days dailyVerifications,
            top-10 failureReasons (was returning {total, completed, …}
            while FE rendered a different shape — every tile = "Veri yok").
            Verification flows kept distinct from auth flows
            (flow_type=VERIFICATION subset, KYC/KYB/AML).

web b0c9888:
  PR #59 — fix(admin): wire Star/StarBorder default-flow toggle, surface
           SUPER_ADMIN cross-tenant flag, replace hardcoded English in
           DevicesPage with t() (new devices.* keys EN+TR), pipe Guest
           toast through formatApiError.
    AuthSessionsPage + DevicesPage send empty tenantId when current
    user is SUPER_ADMIN; banner explains the cross-tenant view.
    AuthFlowsPage gets a Star icon button + confirmation dialog
    that calls updateFlow({isDefault: true}).
    GuestsPage error path now humans-readable.
    useVerification refactored to read the new dashboard shape.
    702/702 web vitest pass; 3 backend tests updated to reflect the
    "null tenantId = platform-wide for SUPER_ADMIN" contract.

USER-BUG-8 / 9 / 10 all closed. Effective on next container rebuild
(Task #25) for backend; web auto-deploys via Hostinger CI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ahmetabdullahgultekin added a commit that referenced this pull request May 1, 2026
…findings)

api 19d76ff..cb3ea1a:
  PR #51 — chore: address Copilot post-merge findings on PR #49 (round 5)
    7 findings:
    - UserController guest-invite: SUPER_ADMIN no longer falls back to
      currentUser.tenant; missing tenantId now hard-errors 400.
    - Guest list / device list platform-wide paths capped at
      MAX_PLATFORM_WIDE_GUESTS / DEVICES = 1000 rows.
    - AuthSessionQueryService javadoc documents the tenantId=null
      SUPER_ADMIN platform-wide contract.
    - GlobalExceptionHandler: new DomainStateConflictException narrows
      409 handler; 15 domain throws migrated; 9 test assertions
      updated. IllegalStateException no longer silently demoted to 409.
    - ManageVerificationService.getStats: N+1 step-result fetch
      replaced with findAllBySessionIdInOrderBySessionIdAscStepNumberAsc
      batched query.

bio 16a03b2..41c85db:
  PR #64 — chore: address Copilot post-merge findings on PR #63 (round 5)
    4 findings:
    - container.py: liveness warm-up now runs
      UniFaceLivenessDetector.warm_model_sync() on the cached detector
      instance (was a throw-away MiniFASNet() that didn't actually warm
      the production code path).
    - container.py: explicit info-log when liveness backend skips warm-up.
    - container.py: generic exception handler uses exc_info=True.
    - check_liveness.py: renamed mid-flow timing to
      total_until_liveness; added true end-to-end total on completion log.

web b0c9888..0bc801f:
  PR #60 — chore: address Copilot post-merge findings on PR #57+#58+#59 (round 5)
    15 findings:
    - AuthService.ts comment now references real i18n keys
      (errors.invalidCredentials, errors.mfaRequired).
    - formatApiError.test.ts test descriptions renamed to match.
    - index.html: MediaPipe CDN pinned to @0.10.18 (matches package.json).
    - index.html: prefetches now use as="fetch" + crossorigin.
    - LoginPage warm-up comment clarified (timing optimization, not
      chunk split).
    - BiometricEngine.initialize() single-flight via shared _initPromise
      (kills duplicate-init race between LoginPage + LoginMfaFlow).
    - useAuthSessionsList: test exercises crossTenant=true with empty
      tenantId.
    - AuthFlowsPage: success auto-clear timer in ref, cleared on
      unmount + before re-scheduling.
    - AuthFlowsPage: Star IconButton aria-label toggles between
      setAsDefault / alreadyDefault.
    - DeviceRepository / VerificationRepository: signatures require
      explicit { crossTenant?: boolean } flag for empty tenantId; throws
      otherwise.
    - useVerification: derives isSuperAdmin; non-super-admin callers
      wait for tenantId instead of falling through.
    - AuthFlowsPage Set-default Dialog onClose ignores backdrop/Escape
      while request is in flight.
    - tr.json grammar fix: "...ayarlansın mı?" → "...ayarlamak ister misiniz?".

35 PRs merged this session total. Round 5 closes the Copilot review backlog
on the last 5 user-bug PRs. Operator container rebuild (Task #25) still
required for server-side fixes to land in prod.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ahmetabdullahgultekin added a commit that referenced this pull request May 1, 2026
…w docs

SESSION_STATUS_2026-05-01.md: canonical session-state doc. 39 PRs merged
across 4 repos this session; all 10 user-reported bugs closed end-to-end;
7 rounds of Copilot post-merge cleanup; 9 senior reviewers deployed
(5 delivered 2026-04-30, 4 in flight 2026-05-01).

Operator container rebuild (Task #25) is the gating step — server-side
work is on main but not running in prod.

Adds the 4 lens reviews from 2026-04-30 morning that were left untracked:
- BACKEND_REVIEW_2026-04-30.md (Senior BE)
- ENGINEERING_REVIEW_2026-04-30.md (Chief Engineer)
- FRONTEND_REVIEW_2026-04-30.md (Senior FE — static lens; superseded by
  the in-flight 2026-05-01 redrive that explicitly covers working-feature
  dimension after user feedback that USER-BUG-6/7/8/9/10 weren't caught)
- PRODUCT_REVIEW_2026-04-30.md (Product Owner)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ahmetabdullahgultekin added a commit that referenced this pull request May 11, 2026
…52)

* chore(deps-dev): bump vite from 6.4.1 to 6.4.2 in /landing-website (#28)

Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 6.4.1 to 6.4.2.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v6.4.2/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v6.4.2/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 6.4.2
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* docs(changelog): 2026-04-24 evening — 12 more PRs merged, puzzle-page split, dashboard 403/500/422 remediation

* docs(changelog): PR #38 — frontend RBAC gating (Rules 2+3) live on app.fivucsas.com

* chore(submodule): bump identity-core-api → 4bee6d7 (4 PRs landed 2026-04-25)

Pointer bump for the 4 PRs that landed on identity-core-api/main today:
  efb8228  feat(rbac): V45 TENANT_ADMIN permission baseline (#27)
  4794595  fix(auth): session cancel + dead-end prevention + method switch (#25)
  9e2df8e  feat(tenants): multi email-domain support (V44 + entity foundation) (#26)
  4bee6d7  feat(register): resolve tenant by email-domain via tenant_email_domains (V44 wire-up) (#28)

V44 + V45 migrations both ship in this bump. Next prod boot
(\`docker compose up -d identity-core-api\`) will apply them.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): bump web-app → 1689177 (PR #39 biometric-puzzles)

Pointer bump for the always-succeed bug fix:
  1689177  feat(biometric-puzzles): real per-challenge face + hand detection (#39)

14 face puzzles now run pinned ChallengeType through the BiometricPuzzle
engine. 9 hand puzzles use the new HandLandmarker + per-challenge
detector module. Regression guard ensures every registry entry
references a unique component (prevents the bug-pattern from recurring).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): bump biometric-processor → 4a9383d (PR #36 anti-spoof core)

PR #36 (liveness_score) — rPPG analyzer + temporal consistency + light
challenge service. ~1 KLOC of additive anti-spoof analysis, 3 new
test files, no rewiring of existing code paths.

Note: the broader liveness_capture branch (Aysenur's 6-commit superset
with demo-ui artifacts + dev OpenCV tool) was NOT merged — 12 KLOC,
7 real conflicts in central wiring; needs cleanup.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): bump web-app → 9d7f0c2 (PR #40 lint sweep, 78→17 warnings)

* chore(submodule): bump client-apps → acd395d (PRs #27/#28/#29 — Android CI fix, iOS CoreFoundation, APK i18n)

* chore(submodule): bump client-apps → 2af501f (PR #30 V16 i18n — 12 login screens)

* chore(submodule): bump biometric-processor → ee1e870 (PR #51 anti-spoof pipeline integration, Aysenur)

* chore(submodule): bump web-app → 07f34d0 (PR #41 CI fix unblocks #39+#40 deploy)

* chore(submodule): bump biometric-processor → bdd8203 (PR #52 config validator)

* chore(submodules): bump for today's afternoon-evening wave

identity-core-api → 2adfa90 (PR #29 audit_logs.tenant_id fix + V46 backfill)
biometric-processor → bdd8203 (PR #52 config validator)
client-apps → e840de0 (PR #31 MFA dispatch + PR #32 polish v2)

Plus prod deploy of identity-core-api with V46 backfill applied:
829 NULL-tenant audit rows → 0; 104 anonymous failed-login rows
correctly stay NULL by design.

* chore(submodule): bump identity-core-api → 07b6bcf (PR #30 V47 enrollment scores)

* chore(submodules): bump for next wave (4 more PRs landed + 2 deploys)

identity-core-api → 12e8010 (PR #30 V47 enrollment scores + PR #31 auth-sessions admin list)
biometric-processor → 8c5423f (PR #53 demographics router gating, ~400 MB savings)
web-app → b59005c (PR #44 auth-sessions admin page wiring)
client-apps → f4bdc40 (PR #33 MFA PR #25 endpoints — DELETE cancel + switch-method + NEEDS_ENROLLMENT)

Prod deploys:
- identity-core-api rebuilt + restarted with V47 → live, GET /auth/sessions verified
- biometric-api rebuilt + restarted with demographics gating → ~400 MB freed

* chore(submodules): bump for 3 Dependabot security/patch merges (web #42 postcss XSS, bp #48 dotenv, bp #46 next-demo)

* chore(submodule): bump biometric-processor → f6c6fcb (PR #55 gesture Phase 1, supersedes #50)

* chore(submodules): bump client-apps + biometric-processor (post-PR-#34 + bp #54)

- client-apps → 5e756d8 (PR #34: KMP LoginScreen reads active auth flow + dynamic primary step)
- biometric-processor → a29812d (PR #54: dependabot uuid removal + @sentry/webpack-plugin 5.1.1→5.2.0)
- docs/practice-and-test pointer refresh (no-op in tree)
- .env.example: BE-H1 RS256 JWT signing config (carried over from prior wave)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): bump web-app → 0c61076 (PR #31 GestureLivenessStep + i18n)

PR #31 — gesture Phase 2 web (landmarks-only client-side detection).
Closes the deferred-draft items: liveness.gesture.* keys (17 × en/tr)
landed; build + lint green.

* chore(submodule): bump client-apps → 0104d15 (PR #35 polish: i18n + UX sweep)

PR #35 — TR translation refinements (HW_TOKEN_*, MRZ_BACK_OF_ID_OVERLAY),
22 new i18n keys (OTP countdown + a11y + Profile sweep), TOTP auto-submit
on 6 digits, Email/SMS OTP 30s resend countdown, ProfileScreen +
EditProfileScreen full i18n. 447/447 desktopTest still green.

* docs: strip iOS/macOS from forward roadmap (out of scope, no Apple hardware) (#36)

* chore(submodule): bump client-apps → 0104d15 (PR #35 polish: i18n + UX sweep)

PR #35 — TR translation refinements (HW_TOKEN_*, MRZ_BACK_OF_ID_OVERLAY),
22 new i18n keys (OTP countdown + a11y + Profile sweep), TOTP auto-submit
on 6 digits, Email/SMS OTP 30s resend countdown, ProfileScreen +
EditProfileScreen full i18n. 447/447 desktopTest still green.

* docs: strip iOS/macOS from forward roadmap (out of scope, no Apple hardware)

Apple platforms (iOS / iPadOS / macOS) are permanently out of scope as of
2026-04-26 — the product owner has no Apple hardware available for
development, signing, or testing. Android APK + Windows + Linux desktop
cover the demonstration target. Apple-platform users are served via the
hosted login page (verify.fivucsas.com) in their system browser.

KMP `iosMain` source directory remains in the codebase as part of the
Kotlin Multiplatform compile structure but receives no further
engineering work. This is a docs-only PR, no source code is touched.

Files touched in this repo:
- ROADMAP.md: scope-note banner at top.
- ROADMAP_V2.md: scope-note banner; Phase 7 retitled "Desktop"
  (iOS bullets dropped); Phase summary table row 7 updated; WebAuthn
  browser-OS support table iOS/macOS rows flagged "n/a — native app
  out of scope (browser support remains for hosted-login users on
  Apple devices)"; ASCII core-design diagram updated to remove
  "NFC on iOS/unsupported" phrasing.
- MASTER_PLAN.md: scope-note banner at top; INTEGRATION PATH 4 SDK
  callout drops Swift Package, keeps Android AAR.
- PLATFORM_STATUS.md: scope-note banner at top; KMP source-structure
  bullet updated to keep `iosMain` listed but flagged as out of scope
  (in-tree for compile structure only).
- MOBILE_APP_COMPREHENSIVE_REDESIGN.md: scope-note banner at top.
  Architectural diagrams referencing `iosMain`/`iosApp`/`IosTokenStorage`
  preserved as KMP architectural reference (not engineered against).
- CHANGELOG.md: single Unreleased entry under a new ### Docs heading.

Submodule bumps (forward to docs-branch tips of each submodule's
companion PR):
- web-app → a84f9791 (PR #46)
- identity-core-api → 2af82343 (PR #34)
- biometric-processor → 65d2ea50 (PR #56)
- docs → a3c012e9 (PR #11 — substantive rewrite of CLIENT_APPS_PARITY.md
  and PATH_TO_20_20.md)

`client-apps` submodule deliberately NOT bumped — concurrent agent active
in that repo and per cleanup plan, that submodule was excluded from this
sweep. Its iOS-related docs (ROADMAP_CLIENT_APPS.md, CHANGELOG.md, README)
will be cleaned up separately.

History preserved: any CHANGELOG entries that mention past iOS work are
left as-is. Only forward-looking content is updated. Pre-pivot Appendix A
in CLIENT_APPS_PARITY.md is also preserved as historical reference.

* chore(submodules): bump pointers to post-merge mains (post doc-strip)

Sub-repos' doc-strip branches squash-merged; bump parent pointers to the
new main SHAs so this parent PR lands a coherent tree:
- web-app → main (PR #46 + PR #47)
- identity-core-api → main (PR #33 + PR #34)
- biometric-processor → main (PR #56)
- docs → main (PR #11)

* docs: refresh CLAUDE.md + add login surfaces comparison + close-out scope

- CLAUDE.md: stale rollingcatsoftware.com URLs → fivucsas.com domains;
  CX33 → CX43 (16 GB); add verify.fivucsas.com + demo.fivucsas.com to
  subdomain table; refresh "Last verified" to 2026-04-26.
- docs submodule bump: new LOGIN_SURFACES_COMPARISON_2026-04-26.md (3-way
  compare of app.fivucsas/login, verify.fivucsas/login, verify.fivucsas/widget)
- FIVUCSAS_INCOMPLETE_2026-04-26.md: refreshed with 8 PRs shipped,
  iOS/macOS DROPPED, V42/V43 audit-finding correction

* chore(submodule): bump identity-core-api → 82b3a48 (V48 drop biometric_data)

PR #35 — biometric_data table removed (V48 migration applied live on
Hetzner; flyway_schema_history rank 48 = success). 9 files of dead code
deleted: BiometricData entity + 2 repository declarations + legacy
service.BiometricService + 4 application service callers + EnrollmentController
references. Net -390 / +97 LOC. Zero data loss (table empty since 2026-04 pivot).

* chore(submodule): bump web-app → $(git -C web-app rev-parse --short HEAD) (PR #48 perf: MUI vendor split)

PR #48 — Phase E2 MUI vendor chunk split. mui-vendor 555 KB → mui-core
517 KB + mui-icons 37 KB. E1 Recharts lazy was already in place. 678/678
tests still green; lint 0/0; single file change (vite.config.ts).

* chore(submodule): bump identity-core-api → 462c062 (PR #36 PKCE D5a/b)

PR #36 — Phase D5a/b shipped + DEPLOYED. New AuditAction.PKCE_FAILURE +
PkceFailureReason enum + PkceVerificationException + per-clientId
Bucket4j (30 failures / 5 min) + Retry-After on exhaustion. Audit row
written even when rate-limited (full attack pattern visibility for SOC).
+3 net tests (929→932 passing).

* chore(biometric): bump submodules + roadmap docs

- biometric-processor: Faz 1-3 — centerface/.env.prod, liveness wired
  into /enroll+/verify, pose quality fields, adaptive threshold config
- web-app: FaceLandmarker primary detector, passive liveness pre-filter,
  enrollment renewal UX, i18n keys added (678/678 tests pass)
- BIOMETRIC_PIPELINE_AUDIT_2026-04-28.md: full audit doc
- BIOMETRIC_ROADMAP_2026-04-28.md: fix roadmap
- CLAUDE.md: biometric pipeline section updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(submodule): bump biometric-processor (compose centerface+anti-spoof+liveness)

* chore(submodule): bump biometric-processor (mtcnn fix)

* chore(submodule): bump web-app (CI env fix + FaceLandmarker + passive liveness)

* docs(2026-04-28): refresh CLAUDE.md + add session roadmap and client-apps plan

- CLAUDE.md: replace stale "biometric pipeline aging" note with verified
  post-fix prod state (Facenet512, mtcnn, anti-spoof on, UniFace passive
  liveness, MediaPipe FaceLandmarker, adaptive threshold). Refresh
  Last verified line and Next Steps to point at today's branches and
  the V42/V43 missing-migration P0.
- ROADMAP_2026-04-28.md: canonical record of today's findings (8 user-
  found bugs C1-C11), 6 morning fixes verified live, and a final-state
  table for the 4 afternoon teams.
- CLIENT_APPS_PARITY_PLAN_2026-04-28.md: research-only plan for Team D
  (Compose UI parity + APK release workflow). Ready for user review;
  needs keystore + 4 GitHub secrets before action.

Companion memory updates (in ~/.claude/projects memory):
  feedback_no_hard_delete_users.md
  feedback_readonly_rootfs_cache_dirs.md
  feedback_liveness_hybrid_vs_passive.md
  project_session_20260428.md (READ FIRST ON RESUME)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodules): bump web-app + identity-core-api + biometric-processor (2026-04-28 wave)

web-app 47f7077:
- fix(sidebar): exact-route highlight (no prefix collision)
- fix(enrollment): TOTP/EMAIL_OTP/SMS_OTP/QR_CODE correctness sweep
- fix(web): rescue stashed agent work (biometric tools network error,
  puzzles polish, MFA double-step defense)

identity-core-api 8ba4ee7:
- fix(enrollment): drop SMS_OTP/QR_CODE/EMAIL_OTP from AUTO_COMPLETE_TYPES
- fix(enrollment): auto-create ENROLLED EMAIL_OTP+QR_CODE rows on first list
- fix(mfa): exclude completed methods from next step's available list

biometric-processor 9444018:
- fix(prod): give UniFace MiniFASNet a writable model cache (HOME=/tmp,
  UNIFACE_CACHE_DIR=/app/uniface-cache, named volume biometric_uniface)
- fix(liveness): use passive UniFace only — hybrid mode vetoed every login

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): bump identity-core-api → c25b731 (users-list lastLogin fix)

Wrong audit action constant ('USER_AUTHENTICATED') made the Users
list always show "Never" for Last Login. Switch to 'USER_LOGIN' and
fall back to User.lastLoginAt when audit is empty.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): bump identity-core-api → 5446d57 (V42 + tenant-lock)

Two changes:
- Restore Flyway V42 (TOTP secret encrypted-at-rest CHECK
  constraint) from the security/phase-1-auth-hardening branch,
  applied manually to prod since out-of-order=false.
- fix(auth): tenant-lock OAuth-initiated logins to the client's
  tenant. demo.fivucsas.com (marmara-bys-demo OAuth client) now
  rejects users from other tenants.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs: multi-email / multi-tenant identity design note

Captures the architectural answer to the 2026-04-28 question:
"I have ahabgu@gmail.com on Fivucsas and ahmet.abdullah@marun.edu.tr
should be on Marmara — same person, two emails, two tenants."

Today's reality:
- The schema already supports two distinct user rows in two
  tenants. tenant_email_domains (V44) auto-routes registration by
  email domain (marmara.edu.tr → Marmara). Today's tenant-lock at
  OAuth login (commit 5446d57) enforces "right account at right
  surface."
- glsm's 2-row situation explained — soft-delete + new tenant
  registration. No 500 risk after morning's findByEmail filter; do
  not hard-delete the soft-deleted row (FK cascade lesson).

Three architecture options laid out:
- A. Status quo — works for today's use case
- B. Identities + memberships — week-long, true human-centric model
- C. Email aliases on user row — cheap, partial

Recommendation: A now. B if/when concrete business need surfaces.
Phone-as-primary-login folded into B at that point.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(archive): move 16 superseded reports into archive/2026-04-pre-roadmap-2028/

Top-level was carrying 22 markdown files, most pre-dating the
2026-04-28 production hardening day. Canonical "current state"
docs now sit at root:

  CHANGELOG.md
  CLAUDE.md
  README.md
  ROADMAP_2026-04-28.md
  CLIENT_APPS_PARITY_PLAN_2026-04-28.md
  MULTI_EMAIL_TENANT_DESIGN_2026-04-28.md

Archived (preserved with full git history via git mv):
  API_EDGE_CASE_AUDIT.md
  ARCHITECTURE_ANALYSIS.md
  BIOMETRIC_PIPELINE_AUDIT_2026-04-28.md   (morning audit, items shipped same day)
  BIOMETRIC_ROADMAP_2026-04-28.md          (morning roadmap, items shipped same day)
  CLIENT_SIDE_ML_REPORT.md
  FIVUCSAS_INCOMPLETE_2026-04-26.md
  FRONTEND_COMPARISON_REPORT.md
  INFRA_REVIEW.md
  MASTER_PLAN.md
  MOBILE_APP_COMPREHENSIVE_REDESIGN.md
  NFC_READER_REDESIGN.md
  PERFORMANCE_AUDIT.md
  PLATFORM_STATUS.md
  ROADMAP.md
  ROADMAP_V2.md
  TODO.md

Each of these is referenced from archive/2026-04-pre-roadmap-2028/README.md
with a one-line "why archived" rationale.

Also unignore /archive/ — it was previously gitignored which would
have silently swallowed this commit. Future archive waves can keep
this same shape (wave-name folder + README index).

README.md updated with version 4.0.0 + pointer to ROADMAP_2026-04-28.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(2026-04-28-evening): 4 audit reports + bump submodules

Audit reports captured at root:
  AUDIT_2026-04-28_BASIC.md     — design correctness on happy paths
  AUDIT_2026-04-28_EDGE.md      — race / extreme inputs / FK cascades
  AUDIT_2026-04-28_SECURITY.md  — authn / authz / OAuth / secrets / transport
  AUDIT_2026-04-28_OPS.md       — backups / containers / network / DR

Bumps:
  identity-core-api → 24d3784:
    - V42 TOTP encrypted-at-rest CHECK (restored from unmerged branch)
    - users-list lastLoginAt fix (action 'USER_LOGIN', not 'USER_AUTHENTICATED')
    - OAuth tenant-lock (commit 5446d57 — refuses cross-tenant logins)
    - MFA double-consume race fix (PESSIMISTIC_WRITE on session lookup)
    - Cross-tenant by-id user access fix (enforceTenantScope guard)

  biometric-processor → 9d4481f:
    - Strip bio.fivucsas.com public Traefik router. Internal-only via
      backend docker network (per CLAUDE.md design intent).

P0 audit findings closed today (5):
  ops-P0a  bio.fivucsas exposed       → 9d4481f
  ops-P0b  disk 91%                   → docker builder prune (-23 GB)
  edge-P0a MFA double-consume race    → 24d3784
  edge-P0b cross-tenant user by-id    → 24d3784
  basic-P0 demo creds in prod bundle  → false positive (already DEV-gated)

P0 findings deferred (need coordinated rotation / SPA refactor):
  sec-P0a  secrets in git history      → TODO Phase C1a-f
  sec-P0b  VITE_BIOMETRIC_API_KEY in   → expand today's useFaceSearch
            SPA bundle for non-search     reroute to all biometric callsites

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(audit): 2026-04-29 ops follow-up — closes 2 P0 + 2 P1 from yesterday

P0 closed yesterday (verified today):
  1. bio.fivucsas.com publicly exposed → router stripped (9d4481f)
  2. Disk 91% → 86% via builder prune (-23 GB)

P1 documentation shipped today:
  3. Observability runbook → infra/observability/RUNBOOK_OBSERVABILITY.md
  4. DR runbook → infra/RUNBOOK_DR.md (first drill instructions inside)

P1/P2 still open: WAL/PITR, password rotation, image SHA pinning,
shared_buffers tuning, PgBouncer, offsite long-term retention.

Top 3 next actions for the user:
- Run the first DR drill (validates RTO/RPO + the runbook itself)
- Bring up observability (~5 min once Grafana password chosen)
- Move postgres password out of backup.sh into .env (chmod 600)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): bump web-app → eef1657 (Sec-P0b — biometric API key out of bundle)

Closes the second of yesterday's audit-security P0s. SPA no longer
ships VITE_BIOMETRIC_API_KEY; all biometric calls now route through
identity-core-api with the user's Bearer JWT.

Bundle re-verified post-merge:
  X-API-Key            0 hits
  VITE_BIOMETRIC_API   0 hits
  bio.fivucsas.com     1 hit (cosmetic help-text)

Combined with yesterday's biometric-processor public-router strip
(commit 9d4481f on the bp side, parent submodule pointer 5199952),
bio.fivucsas.com is now fully internal — no public DNS reach, no
public credential leaked in any browser bundle.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): bump identity-core-api → d4c4d43 (5 P1 carryovers + 9 tests)

Closes 5 P1s from yesterday's audits:
  EDGE-P1 #3  startEnrollment race → 500
  EDGE-P1 #4  /audit-logs unbounded size param
  EDGE-P1 #8  V43 migration version gap
  SEC-P1 #4  /auth/mfa/step missing rate-limit bucket
  SEC-P1 #3  JWT default-algo locked to RS256 on prod profile

V43 row pre-inserted into prod flyway_schema_history before rebuild
(out-of-order=false in prod), mirroring yesterday's V42 pattern.

9 new tests across 5 suites (mvn -DskipTests package green):
  ManageEnrollmentServiceTest        +2 (race + winner-vanishes)
  AuditLogControllerTest             +3 (size 0/100/10000000)
  MigrationChainContiguityTest       +2 (V43 reservation + chain)
  RateLimitInterceptorMfaStepTest    +3 (30/min, 31st 429, IP isolation)
  JwtServiceProdAlgoLockTest         +4 (prod+HS512 throws, etc.)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): bump web-app → c641d4e (basic-audit P1 sweep)

Closes 9 P1 + 2 P2 from AUDIT_2026-04-28_BASIC.md:
- 23 Turkish translations for biometricPuzzle hints (full tr/en parity)
- document.title localized via pageTitles namespace
- 6 raw err.message sites routed through formatApiError
- TOTP enrollment hardcoded English (3 sites) + QR alt text localized
- UserService / AuthService re-throw ZodError; formatApiError
  extended to map ZodError → t('errors.validation')

63 new keys per language, +5 KB bundle, 678 vitest pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodules): bump api → 69bfa09 + web-app → c580822 (5-team wave)

API (69bfa09) consolidates Teams A + B + C:
  A — fix/test-mocks-2026-04-29 (dcf50d6)
      7 mock failures from yesterday's 24d3784 fixed.
      946→966 tests, 0 failures.
  B — fix/biometric-adapter-tenant-and-embedding-forward (70e3e4d)
      BiometricServicePort gains 5-arg overloads forwarding
      tenant_id + D2 client_embedding(s) to bio. Backward-compat
      via default methods. 6 new adapter tests.
  C — fix/tenant-soft-delete-and-totp-convert (69bfa09)
      Tenant @SQLDelete + @SQLRestriction (Edge-P1 #5: tenant
      hard-delete trap closed). User.two_factor_secret @Convert
      (Edge-P1 #7: defense-in-depth for V42 CHECK). V49 idempotent
      reverse index applied to prod. 14 new tests.

Full suite: 966 tests, 0 failures, 0 errors.

Web-app (c580822):
  E — fix/loginpage-face-tile-cleanup
      Removed dead face-tile state from LoginPage (broken pre-auth
      since SPA reroute; tile was already invisible). +3/-32.
      Deployed to Hostinger.

Production deployed at 04:48 UTC: api rebuilt + restarted,
V49 in flyway_schema_history, smoke-tests green (login OK,
cross-tenant client_id still rejected at the marmara-bys-demo
gate).

Team D (ops P2) committed to /opt/projects local repo (no remote);
Sec-P0a runbook at /opt/projects/infra/RUNBOOK_SECRET_ROTATION.md
captures the operator-coordinated history rewrite + secret
rotation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(deploy): tag :latest images with :sha-<short> after build (Ops-P2 #7)

Mirror the rollback-friendly tagging pattern from /opt/projects/infra/deploy.sh
(commit e3e9056) into the FIVUCSAS dev-driven deploy scripts. After the remote
`docker compose up -d --build`, the script now SSHs back in to walk
`docker compose images`, find each repo carrying `:latest`, and re-tag it as
`:sha-<short>` derived from the local identity-core-api git HEAD. This lets a
broken deploy roll back to the previously-built image without rebuilding.

- deploy-identity-core-hetzner.sh: new step 4b
- deploy-identity-core-hetzner.ps1: new step 3b (mirrors bash via ssh heredoc)
- header comments cite the audit (Ops-P2 #7) and the reference SHA

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(audit): close DRAFT audit PRs api#32 + web#45 as superseded

Both audit PRs were authored 2026-04-26 and contained only an .md report
file (no code to merge). Today's hardening wave closes the substantive
findings; the reports remain in the working tree for history.

api#32 closed-via-comment: V42 restored (bad7262), V43 slot reserved
(29aa007), test compile fixed (dcf50d6, be30dc7), JWT RS256 lock
(65415f3), MFA-step rate limit + Retry-After (3670932).

web#45 closed-via-comment: i18n sweep (c641d4e), biometric API key
elimination (fc79de6, 5ac4a97, 2a3820b), CI .env.production write
(15aab67), face-tile login removal (c580822).

Closing comments on each PR list closed vs. deferred items with SHAs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(changelog): add 2026-04-28 + 2026-04-29 hardening wave entries

Single comprehensive entry per day covering:
- 2026-04-28: 6 morning fixes (LoginPage 401 i18n, UserRepo soft-delete,
  optional MFA-step skip, Fivucsas tenant contact_email, UniFace passive
  liveness, useQualityAssessment bbox fallback); enrollment correctness
  sweep across TOTP/EMAIL_OTP/SMS_OTP/QR_CODE; fingerprint-twice MFA fix;
  4 audit reports; FK-cascade incident note.
- 2026-04-29: Sec-P0b biometric API key elimination from SPA bundle
  (fc79de6, 5ac4a97, 2a3820b); biometric adapter telemetry forwarding
  (6ad1d91); JWT RS256 lock on prod profile (65415f3); MFA-step
  rate-limit + Retry-After (3670932); audit-log size cap (8075c11);
  Tenant @SQLDelete + TOTP @Convert (2e05457); V42 restore (bad7262)
  + V43 reserve (29aa007); test compile fix (dcf50d6, be30dc7); Ops-P2
  image-SHA tagging in scripts/deploy/*; 5 runbooks; audit DRAFT PRs
  api#32 + web#45 closed.

Each line cites the specific commit SHA that landed the fix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: bump submodules — bio→22563fd (file-size guard), web→5b8f876 (face demo)

biometric-processor: MAX_FILE_SIZE guard wired before API-key auth (Z3).
web-app: public /face-demo page showcasing 7 face capabilities (Z5).
ROADMAP_2026-04-28: add Round 2/3 + doc archive notes.

Closes the Z-wave (post-AUDIT_2026-04-28 follow-up). Z1/Z2 still open
pending Anthropic rate-limit reset.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodules): bump api → 30371e8 (Z1) + web-app → 9e151bf (Z2)

api: refresh-token rotation family revocation (Sec-P2 #6) + OAuth2
HostedAuthorizeCompleteRequest @Valid (Sec-P2 #7) + MFA expiresAt
boundary alignment (Edge-P2 #6).

web-app: VitePWA navigateFallback + cleanupOutdatedCaches (Edge-P2
#9) — kills stale-shell 404s after Hostinger deploys.

Closes the post-AUDIT_2026-04-28 Z-wave. Sec-P2 #8 (audit-log HTML
escape) deferred — log-file-only today, only relevant if a future
UI renders details unescaped.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(claude): refresh status to 2026-04-29 — Z-wave shipped

Last-verified line, In Progress section, and Next Steps order
all reset to today's reality. The post-AUDIT_2026-04-28 Z-wave
(Z1 refresh-token family revocation + OAuth2 @Valid + MFA
boundary, Z2 VitePWA navigateFallback, Z3 bio MAX_FILE_SIZE,
Z4 ops housekeeping, Z5 /face-demo) is closed. Operator-only
items (Sec-P0a rotation, DR drill, observability bring-up,
V50 prod apply) remain.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): bump web-app → 9231f4d (Z2 vitest exclude)

Adds .claude/** + archive/** to vitest test.exclude so the baseline
reflects real source (678 passing, 0 failing) instead of stale
agent-worktree drafts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: bump docs+bio submodules + ignore verify-widget/html build artifacts

- docs: import AUDIT_2026-04-19 + PRECOMMIT_HOOKS reference
- biometric-processor: import AUDIT_2026-04-26 read-only verification
- .gitignore: verify-widget/html/ is build staging, not source

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodules): bump api+web to ship gitleaks CI

- identity-core-api da9b7c4: add gitleaks workflow (Sec-P0a §8)
- web-app 0256e58: add gitleaks workflow (Sec-P0a §8)

Pairs with GitHub-side secret-scanning + push-protection now enabled
on both repos via API.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodules): bump api+web — gitleaks CLI fix + allowlist

- identity-core-api 8b5fdde: switch to gitleaks CLI (no paid license) + allowlist 10 known test/doc false positives — CI green.
- web-app 4566b19: switch to gitleaks CLI — CI green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(claude): mark all reachable Z-wave + ops follow-ups as completed 2026-04-30

V50 applied + api recreated, observability live, DR drill OK, gitleaks CI on both repos, secret scanning + push protection enabled. Sec-P0a actual rotation + DNS A record + Grafana contact point remain operator-only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(claude): record biometric-API-key rotation + Grafana ops-email + finding that .env.gcp leaked GCP creds, not Hetzner

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): web-app 7365003 — CI SKIP_MODEL_FETCH

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): web-app c791923 — fix dashboard/profile mismatches

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): web-app 91b1b6e — face mesh + hand skeleton overlays on puzzles

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): web-app 0654b27 — close P3 session-count UX

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(claude): record late-day profile UX polish + puzzle landmark overlays

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* refactor(landing): strip Marmara University from buyer-facing copy (P2.5) (#37)

* refactor(landing): strip Marmara University buyer-facing branding — keep in /about + README (P2.5)

The hero badge and footer on fivucsas.com lead with "Marmara University -
Engineering Project" / "2026 FIVUCSAS. Marmara University.", which signals
"student demo" to prospective tenants and undercuts the SaaS positioning.

Strip the academic framing from the two buyer-facing surfaces:
- Hero badge → "Multi-Tenant Biometric Identity Platform"
- Footer → "2026 FIVUCSAS. All rights reserved."

Marmara University attribution is preserved verbatim in the Project Team
section (lines 423 + 471 — Project Team subtitle and Supervisor row), which
is the academic-history equivalent of an /about page. README.md is also
untouched.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(landing): strip Marmara from meta keywords for SEO consistency (Copilot review)

Refs FIVUCSAS#37

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodules): bump api+bio+web — 7 PRs landed (Phase 1+2 + Copilot)

api 8b5fdde..20cc504:
  PR #37 — validate-on-migrate + statement_timeout + MDC + Maven cache
           + Copilot fixes: CORS expose, X-Request-Id validation, constants
  PR #38 — Tx/Async correctness (readOnly defaults, REQUIRES_NEW, proxy-bypass,
           bounded pool), JPA equals/hashCode, audit-log HTML escape
           + Copilot fixes: TenantContext across @Async (RLS-safe),
           userAgentV2 escape, AuditEscapeTest + AuditLogAdapterTest escape
  PR #39 — fingerprint placeholder removed (legacy biometric path deleted;
           WebAuthn FingerprintAuthHandler retained)

bio 6e6ee88..f0d997c:
  PR #57 — asyncio.to_thread on UniFace + QualityAssessor + cv2.imread
           (event-loop unblock, P2.11)
  PR #58 — fingerprint placeholder hash_embedder removed

web f649ef3..7dae2c9:
  PR #49 — central dateFnsLocale helper across 9 list pages (P3.2)
           + Copilot fix: locale-aware skeletons P/PP/PPP/p/pp instead of
           literal MMM dd, yyyy / HH:mm:ss patterns

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(triage): USER_BUGS_2026-04-30 — face-no-gate / YOLO wrong class / puzzles broken

Three direct user reports surfaced 2026-04-30 16:50 (TR):

1. Face enrollment auto-advances even when no face is in view; failure
   surfaces only at server save. Front-end has the detection signal but
   does not gate progression on it. Branch fix/face-enrollment-no-face-gate.

2. YOLO card-type classifier picks the wrong TR ID variant. Likely
   label-order / preprocessing / no confidence floor. Defensive fix
   even if model is the root cause: ≥0.6 floor + manual-select fallback.
   Branch fix/card-type-yolo-classification.

3. Math + shape-drawing biometric puzzles silently broken. Likely
   string/number validation, missing onSolve wiring, pointer-event /
   canvas-size races. Branch fix/biometric-puzzles-math-shape.

Each has a separate background fix branch + Vitest. This file is the
canonical triage doc; supersedes ad-hoc TODO entries.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodules): bump api+bio+web — USER-BUG-1 + 3, JVM heap, post-merge Copilot

api 20cc504..9973ee2:
  PR #40 — perf(jvm): drop -Xmx512m silent override, MaxRAMPercentage=75
           (PERF #1; ~1.5 GB heap on 2 GiB container; 40-80 ms p99 saving)
  PR #41 — chore: align FINGERPRINT delete log with PR #39 removal
           (Copilot post-merge; FACE/VOICE arms keep the info-log,
           FINGERPRINT explicit no-op with debug-only)

bio f0d997c..b1fe294:
  PR #59 — fix: 4 Copilot post-merge findings on PR #57 / #58
           A. _model typed via TYPE_CHECKING uniface.spoofing.MiniFASNet
           B. _ensure_model_loaded → asyncio.Lock + double-checked locking
           C. asyncio.to_thread → get_thread_pool().run_blocking()
              so ML_THREAD_POOL_SIZE is honored
           D. README Voice line corrected — Resemblyzer GE2E still in prod
              (numba conflict resolved by librosa==0.9.2 pin, not removal)

web 7dae2c9..6ce1f7d:
  PR #50 — fix(face): hard-stop face enrollment when no face is detected
           (USER-BUG-1; useFaceChallenge.ts hard-timeout removed,
           center-crop-fallback removed, early gate on detection.detected,
           en/tr i18n, 33/33 vitest)
  PR #51 — fix(puzzles): smooth finger-count + index-extended check
           (USER-BUG-3; HAND_MATH / HAND_FINGER_COUNT / HAND_SHAPE_TRACE /
           HAND_TRACE_TEMPLATE were jittered out by strict count===target
           comparator on noisy MediaPipe output; FingerCountSmoother
           500ms dominance ≥60% + isIndexExtended TIP-above-PIP;
           21/21 hand-challenge + 27/27 puzzle suite pass)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodules): bump api+bio+web — USER-BUG-2 closed (server+client) + USER-BUG-4 SMS OTP

api 9973ee2..cc8ed23:
  PR #42 — fix(sms-otp): branch on VerifiableSmsService for Twilio Verify;
           prod uses SMS_PROVIDER=twilio-verify but OtpController was
           unconditionally going through local Redis OtpService. Fix:
           skip otpService.generate when smsService instanceof
           VerifiableSmsService; verify via verifiable.verifyCode.
           Plus normalizeCode (NFKC + ZWSP/LRM/RLM/BOM strip + trim)
           applied to email + SMS verify input.
           5 new test cases including "sendShouldNotGenerateLocalCode"
           that would have caught the original bug; 13/13 pass.
           USER-BUG-4. Needs identity-core-api container rebuild.

bio b1fe294..de5584e:
  PR #60 — fix(card-type): server-side defensive tightening on
           YOLOCardTypeDetector. Confidence threshold 0.5 → 0.65;
           OCR validation now runs on every detection (not only the
           two confusable pairs); borderline calls (conf in [0.65,
           0.75) AND OCR no_evidence) return detected=False rather
           than committing to a guess. _ocr_validate returns
           (chosen_class, evidence) for diagnostic logging.
           akademisyen_karti added to supported_card_types (model
           class was present, list was missing it).
           Companion to web-app PR #52 (client defense-in-depth).
           USER-BUG-2 server-side, the user-visible path.

web 6ce1f7d..8ea8186:
  PR #52 — fix(card-type): client CardDetector labels.json (canonical
           training-time class order) + FALLBACK_CLASS_NAMES corrected;
           CARD_HIGH_CONFIDENCE=0.7 gate; i18n cardDetection.classLabels
           so CardDetectionPage no longer leaks raw slugs; vitest pinning
           order against alphabetical regression.
           USER-BUG-2 client defense-in-depth.

USER_BUGS_2026-04-30.md status table updated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(user-bugs): all four closed; operator rebuild + E.164 phone follow-up noted

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): identity-core-api → 567ce25 — ShedLock for SoftDeletePurgeJob (P2.9, PR #43)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodules): bump api+web — auth-methods-testing real APIs (USER-BUG-5) + V51 renumber

api 567ce25..8165311:
  PR #45 — chore(db): renumber V53__shedlock to V51 to fix
           MigrationChainContiguityTest after PR #43 left a gap
           (V51/V52 reserved on feat/v51-forbid-hard-delete-p1-7).

web a1f1adb..bb30a4a:
  PR #53 — fix(auth-methods-testing): server-mediated puzzles call real APIs
           (USER-BUG-5 part 1). Deleted StubAuthRepository entirely.
           EmailOtp/Sms/Totp/QrCode now hit real /auth/2fa/* endpoints
           against the admin's own session, surface real errors.
           Password puzzle was never a discrete second factor — left
           excluded from registry by design.
  PR #54 — fix(auth-methods-testing): biometric/WebAuthn puzzles wrap
           production step components (USER-BUG-5 part 2). Face/Voice/
           Fingerprint/NFC/HardwareKey now hit real biometric +
           webauthn endpoints, auto-enroll on 404, every onSuccess
           gated on server-confirmed verdict. setTimeout fakes removed.

USER-BUG-5 (auth-methods-testing page mocks) fully closed. Total this
session: 18 PRs merged across api/bio/web/root.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodules): bump api+bio — Copilot post-merge round 2 fixes (round 2 of 3)

api 8165311..2fe3f03:
  PR #44 — chore: address Copilot findings on PR #42, PR #40
           OtpController: PROVIDER_REJECTED label clarified, normalizeCode
           docs aligned with NFKC, .strip() instead of .trim() to handle
           U+3000-class whitespace, verifySmsOtp UserNotFound now consistent
           across both modes. Dockerfile: ENTRYPOINT now uses exec for
           SIGTERM forwarding.

bio de5584e..9b81a39:
  PR #61 — fix: address Copilot findings on PR #59, PR #60
           Combined yolo_card_type + uniface + quality_assessor fixes
           (borderline-reject + ocr_unavailable, _ocr_validate confidence
           arg removed, _CONFUSABLE_PAIRS dead code removed, docstring
           sync, ThreadPool injected via constructor instead of static
           import to break infra→container coupling, _model type
           narrowed via local cast, ImportError guidance aligned with
           uniface>=3.0.0 pin, async-lock concurrency test added).

Web-app post-merge fixes round 2 still pending — single agent in flight.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(user-bugs): USER-BUG-5 (auth-methods-testing mocks) closed; status table updated

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): web-app → f2930ca — Copilot post-merge round 2 (PR #55)

PR #55 — fix: address Copilot findings on PR #50, #51, #52
  CardDetector: __dirname → import.meta.url for ESM; smoothing-buffer
    impl/comment alignment; JSDoc shape 5+C → 4+C; UNRECOGNISED_CONFIDENCE_THRESHOLD
    extracted to remove the 0.6-duplicated-3x smell.
  useFaceChallenge: cropFace-null path now also resets stageStartRef
    so the stage-timer race is closed end-to-end (not just hold-timer).
  handChallenges: HAND_FINGER_COUNT target<0 short-circuit; FingerCountSmoother
    "immediately" docstring corrected; HAND_FINGER_COUNT-specific jitter
    regression test added; "4 fingers" comment aligned with twoFingerFrame.

Test verification (per agent): vitest 5/5 + 23/23 on touched specs; eslint 0 errors.

Closes Copilot post-merge round 2 (web-app). All 22 findings across the
3 repos addressed (api #44 + bio #61 + web #55).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodules): bump api+web — Copilot post-merge round 3

api 2fe3f03..04b44bf:
  PR #46 — chore: address Copilot post-merge findings on PR #43+#44 (round 3)
    V52__shedlock_timestamps_tz.sql — ALTER lock_until/locked_at to
      TIMESTAMP WITH TIME ZONE so shedlock matches the rest of the
      schema's TZ-aware convention (rest of identity_core uses TIMESTAMPTZ).
      Picked V52 because MigrationChainContiguityTest requires no gap;
      V54 would have failed.
    VerifiableSmsService.java — closed unclosed Javadoc <p> tag (doclint).
    TwilioVerifySmsService.java — log.warn now passes the exception so
      SLF4J emits the stack trace (was string-only before).
    OtpController.java — switches on VerifyResult so the summary log
      says "SMS OTP provider error" on PROVIDER_ERROR vs "SMS OTP
      mismatch" on INVALID_CODE.
    OtpControllerTest.java — Logback ListAppender attached, asserts
      both WARN reason branches plus negative regression guard.

web f2930ca..e90aa35:
  PR #56 — chore: address Copilot post-merge findings on PR #53 (round 3)
    QrCodePuzzle.tsx — onError moved into useEffect so it no longer
      fires during render (kills "Cannot update a component while
      rendering a different component" warning).
    EmailOtpPuzzle.tsx — header comment fixed (OTP sent on click,
      not on mount).
    useTestVerifyApi.ts — JSDoc paths standardised on apiBase-relative
      form to match AuthSessionRepository.generateQrToken; file header
      documents the convention.
    AuthMethodMode.tsx — docblock rewritten to use the actual
      AuthMethodModeKind values (real | test | stub) instead of the
      stale "live" reference.

Test verification (per agent):
  api  — mvn -Dtest=OtpControllerTest,MigrationChainContiguityTest → 17/17
  web  — npx vitest run src/features/auth-methods-testing → 47/47
         npm run lint → 0 errors / 2 pre-existing warnings (cap 90)

23 PRs merged this session total. Round 3 closes the Copilot review
backlog. Operator container rebuild (Task #25) still required for the
server-side fixes to land in prod.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): biometric-processor — Copilot post-merge round 4 (PR #62)

I-prefix for IThreadPoolExecutorPort, dead test helpers removed, asyncio.sleep
event-loop smell fixed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): identity-core-api → V53 forbid hard-delete trigger landed (PR #47)

PR #47 — feat(db): V53 BEFORE DELETE trigger on users + tenants
  RAISE EXCEPTION on hard DELETE; bypass via SET LOCAL
  app.allow_hard_delete='on' for legitimate GDPR Art. 17 purge.
  SoftDeletePurgeJob.purgeBatch now sets the GUC inside the TX so the
  trigger lets the row delete proceed. Trigger is idempotent
  (CREATE OR REPLACE FUNCTION + DROP TRIGGER IF EXISTS).
  Closes the residual hard-delete vector flagged in DB review #1
  (DB_REVIEW_2026-04-30.md) and codifies feedback_no_hard_delete_users.md
  at the database layer.

  Renumbered to V53 because V51 = ShedLock (PR #43) and V52 = ShedLock
  TIMESTAMPTZ alignment (PR #46) merged first.

  Ahabgu incident regression (2026-04-28 careless `DELETE FROM users`
  cascading across 13 FK children) is now engine-level impossible.

  3 commits: migration SQL + purge bypass + Testcontainers integration
  test (RUN_INTEGRATION=true gate, CI exercises).

  Effective on next container rebuild (Task #25).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): web-app — wrong-password error fix (USER-BUG-6, PR #57)

PR #57 — fix(login): show 'invalid credentials' on wrong password
  Root cause: AuthService.login() was wrapping the axios 401 in
  UnauthorizedError, stripping response.status/data, so formatApiError
  fell through every branch to errors.unknown.
  Fix: re-throw axios error untouched; formatApiError now reads
  backend errorCode (INVALID_CREDENTIALS, NEEDS_ENROLLMENT, MFA_REQUIRED)
  and routes to distinct i18n keys; 401 on /auth/login returns
  errors.invalidCredentials not the misleading errors.unauthorized
  (session-expired) message.
  720/720 vitest pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodules): bump web+bio — face login cold-start (USER-BUG-7)

web-app PR #58 — perf(face-login): preload MediaPipe + idle-time engine warmup
  index.html — preconnect to cdn.jsdelivr.net + storage.googleapis.com,
    prefetch vision_bundle.mjs + vision_wasm_internal.wasm +
    face_landmarker.task. Browser warms DNS/TLS/cache while React parses.
  LoginPage.tsx + verify-app/LoginMfaFlow.tsx — BiometricEngine.initialize()
    fires inside requestIdleCallback while user types email/password.
    By MFA-dispatch the FaceLandmarker is loaded; "MediaPipe (CDN)" badge
    shows immediately and detection runs on the first frame.
  vite.config.ts — mediapipe-vendor manualChunk so the npm fallback path
    isn't in the main login bundle.
  Estimated 1.5–2s shaved off "land on login → face badge visible".

bio PR #63 — perf(bio): warm UniFace at startup + per-stage timing logs
  container.py — UniFace MiniFASNet constructed inside
    initialize_dependencies() (was first-request lazy, costing 1–2s for
    every end-user after every restart). Failures non-fatal.
  verify_face.py + check_liveness.py — per-stage timing logs:
    "face/verify: decode=… detect=… quality=… embed=… fetch=… total=…ms".
    Future debugging will show which stage dominates.
  First /verify after deploy: ~3–4s → ~700–900ms.

Remaining bottleneck (per agent): DeepFace Facenet512.represent + mtcnn
inside _extractor.extract() costs ~250–400ms on CX43 CPU. New timing logs
will quantify. Further gains require ONNX export of Facenet512 or a model
swap (out of scope for this perf pass).

Effective on next container rebuild + Hostinger deploy (web auto via CI).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodules): bump api+web — admin-pages bug sweep (USER-BUG-8/9/10)

api 8c7f6d2..6bb853f:
  PR #49 — fix(admin): SUPER_ADMIN cross-tenant + missing default-flow
           transition + verification stats aggregates
    Bug A — Guest endpoints route through TenantScopeResolver so
            SUPER_ADMIN sees platform-wide invitations; cross-tenant repo
            methods added; IllegalStateException → 409 in
            GlobalExceptionHandler (was generic 500).
    Bug B — ManageAuthFlowService.updateFlow now dethrones the prior
            default flow in the same TX when isDefault=true.
    Bug C — AuthSessionController + DeviceController accept null tenantId
            for SUPER_ADMIN as platform-wide. Paged repo methods
            findAllByStatusIn / findAllByUserId added; listAllDevices()
            use-case.
    Bug D — VerificationController /stats now computes
            completionRate, failureRate, avgTimeMinutes,
            statusDistribution, last-30-days dailyVerifications,
            top-10 failureReasons (was returning {total, completed, …}
            while FE rendered a different shape — every tile = "Veri yok").
            Verification flows kept distinct from auth flows
            (flow_type=VERIFICATION subset, KYC/KYB/AML).

web b0c9888:
  PR #59 — fix(admin): wire Star/StarBorder default-flow toggle, surface
           SUPER_ADMIN cross-tenant flag, replace hardcoded English in
           DevicesPage with t() (new devices.* keys EN+TR), pipe Guest
           toast through formatApiError.
    AuthSessionsPage + DevicesPage send empty tenantId when current
    user is SUPER_ADMIN; banner explains the cross-tenant view.
    AuthFlowsPage gets a Star icon button + confirmation dialog
    that calls updateFlow({isDefault: true}).
    GuestsPage error path now humans-readable.
    useVerification refactored to read the new dashboard shape.
    702/702 web vitest pass; 3 backend tests updated to reflect the
    "null tenantId = platform-wide for SUPER_ADMIN" contract.

USER-BUG-8 / 9 / 10 all closed. Effective on next container rebuild
(Task #25) for backend; web auto-deploys via Hostinger CI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): identity-core-api → V54 E.164 phone validation (PR #48)

PR #48 merged: @Pattern E.164 on CreateUserRequest + UpdateUserRequest;
V54__users_phone_number_e164.sql backfills existing non-E.164 rows + adds
CHECK constraint. Renumbered V53 → V54 after rebase to avoid collision
with V53 forbid-hard-delete trigger (PR #47).

Web-side auto-prefix +90 + strip-non-digits deferred (Task #46) —
agent rate-limited before reaching the FE form work.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): identity-core-api → AuthController.verifyMfaStep extraction (PR #50, P2.9 second half)

PR #50 — refactor(auth): extract verifyMfaStep into VerifyMfaStepService
strategy. AuthController.java 1526L → 1162L (-364, -24%); verifyMfaStep
itself 380L → 25L pure HTTP shim.

New under application/service/mfa/:
  VerifyMfaStepHandler (interface), MfaStepResult, VerifyMfaStepRequest,
  VerifyMfaStepResponse, VerifyMfaStepService (orchestrator, 390L).
New under .../mfa/handler/:
  10 @Component handlers (one per AuthMethodType: PASSWORD, EMAIL_OTP,
  SMS_OTP, TOTP, FACE, VOICE, FINGERPRINT, HARDWARE_KEY, QR_CODE,
  NFC_DOCUMENT) + WebAuthnVerifySupport shared by FINGERPRINT/HARDWARE_KEY.

Tests: 1050 → 1053 (zero regressions, 18 new VerifyMfaStepServiceTest).
Wire contract preserved: request/response shape, status codes,
audit keys (MFA_STEP_COMPLETED/FAILED/COMPLETE), RFC 8176 amr ordering,
pessimistic-lock (findBySessionTokenForUpdate + @Transactional), WebAuthn
challenge two-phase flow.

Pure refactor, no production rebuild needed. Closes master-roadmap P2.9
second half.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodules): bump api+web+bio — Copilot post-merge round 5 (26 findings)

api 19d76ff..cb3ea1a:
  PR #51 — chore: address Copilot post-merge findings on PR #49 (round 5)
    7 findings:
    - UserController guest-invite: SUPER_ADMIN no longer falls back to
      currentUser.tenant; missing tenantId now hard-errors 400.
    - Guest list / device list platform-wide paths capped at
      MAX_PLATFORM_WIDE_GUESTS / DEVICES = 1000 rows.
    - AuthSessionQueryService javadoc documents the tenantId=null
      SUPER_ADMIN platform-wide contract.
    - GlobalExceptionHandler: new DomainStateConflictException narrows
      409 handler; 15 domain throws migrated; 9 test assertions
      updated. IllegalStateException no longer silently demoted to 409.
    - ManageVerificationService.getStats: N+1 step-result fetch
      replaced with findAllBySessionIdInOrderBySessionIdAscStepNumberAsc
      batched query.

bio 16a03b2..41c85db:
  PR #64 — chore: address Copilot post-merge findings on PR #63 (round 5)
    4 findings:
    - container.py: liveness warm-up now runs
      UniFaceLivenessDetector.warm_model_sync() on the cached detector
      instance (was a throw-away MiniFASNet() that didn't actually warm
      the production code path).
    - container.py: explicit info-log when liveness backend skips warm-up.
    - container.py: generic exception handler uses exc_info=True.
    - check_liveness.py: renamed mid-flow timing to
      total_until_liveness; added true end-to-end total on completion log.

web b0c9888..0bc801f:
  PR #60 — chore: address Copilot post-merge findings on PR #57+#58+#59 (round 5)
    15 findings:
    - AuthService.ts comment now references real i18n keys
      (errors.invalidCredentials, errors.mfaRequired).
    - formatApiError.test.ts test descriptions renamed to match.
    - index.html: MediaPipe CDN pinned to @0.10.18 (matches package.json).
    - index.html: prefetches now use as="fetch" + crossorigin.
    - LoginPage warm-up comment clarified (timing optimization, not
      chunk split).
    - BiometricEngine.initialize() single-flight via shared _initPromise
      (kills duplicate-init race between LoginPage + LoginMfaFlow).
    - useAuthSessionsList: test exercises crossTenant=true with empty
      tenantId.
    - AuthFlowsPage: success auto-clear timer in ref, cleared on
      unmount + before re-scheduling.
    - AuthFlowsPage: Star IconButton aria-label toggles between
      setAsDefault / alreadyDefault.
    - DeviceRepository / VerificationRepository: signatures require
      explicit { crossTenant?: boolean } flag for empty tenantId; throws
      otherwise.
    - useVerification: derives isSuperAdmin; non-super-admin callers
      wait for tenantId instead of falling through.
    - AuthFlowsPage Set-default Dialog onClose ignores backdrop/Escape
      while request is in flight.
    - tr.json grammar fix: "...ayarlansın mı?" → "...ayarlamak ister misiniz?".

35 PRs merged this session total. Round 5 closes the Copilot review backlog
on the last 5 user-bug PRs. Operator container rebuild (Task #25) still
required for server-side fixes to land in prod.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): identity-core-api → Copilot round 6 on PR #50 (PR #52)

PR #52 merged: WebAuthn action=challenge short-circuits substitution guard;
completeMfa/advanceToNextStep wrapped (AuthFlow lookup or token-mint
failures emit MFA_STEP_FAILED orchestration-error, not 500);
VerifyMfaStepHandler javadoc reflects actual wiring (List → EnumMap).
15/15 VerifyMfaStepServiceTest green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): web-app — phone E.164 auto-prefix (USER-BUG-4 part 2, PR #61)

PR #61 merged. New web-app/src/utils/phoneNumber.ts utility:
  normalizePhoneInputE164 strips non-digits, auto-prepends +90,
  preserves typed +CC, dedupes accidental 905... prefixes;
  isValidE164 matches backend Pattern ^\+[1-9]\d{7,14}$.

Wired into SettingsPage profile-form phone field and EnrollmentPage
SMS-OTP phone-prompt dialog. Replaces legacy length<10 check. Submit
payload uses normalized form. en/tr i18n key phoneNumber.e164Required.
26 new tests; 747/747 vitest pass.

USER-BUG-4 fully closed end-to-end: server PR #48 rejects non-E.164
with 422; client PR #61 prevents that 422 from reaching the user by
normalizing on input.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): identity-core-api → Copilot round 7 on PR #52 (PR #53)

PR #53 merged: challenge action double-call fixed (contract violation
surfaced as 400 instead of re-invoking handler); e.getMessage() removed
from user-facing strings + audit reasons (e.getClass().getSimpleName()
only — full exception still in server log); RuntimeException catch +
containsInterrupted(Throwable) cause-chain walk re-sets
Thread.currentThread().interrupt() so cooperative cancellation isn't
lost when an HTTP client wraps InterruptedException as RuntimeException.

15/15 VerifyMfaStepServiceTest green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(session): 2026-05-01 status snapshot + 4 historical 4-lens review docs

SESSION_STATUS_2026-05-01.md: canonical session-state doc. 39 PRs merged
across 4 repos this session; all 10 user-reported bugs closed end-to-end;
7 rounds of Copilot post-merge cleanup; 9 senior reviewers deployed
(5 delivered 2026-04-30, 4 in flight 2026-05-01).

Operator container rebuild (Task #25) is the gating step — server-side
work is on main but not running in prod.

Adds the 4 lens reviews from 2026-04-30 morning that were left untracked:
- BACKEND_REVIEW_2026-04-30.md (Senior BE)
- ENGINEERING_REVIEW_2026-04-30.md (Chief Engineer)
- FRONTEND_REVIEW_2026-04-30.md (Senior FE — static lens; superseded by
  the in-flight 2026-05-01 redrive that explicitly covers working-feature
  dimension after user feedback that USER-BUG-6/7/8/9/10 weren't caught)
- PRODUCT_REVIEW_2026-04-30.md (Product Owner)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): identity-core-api → P0 cross-tenant breach fixed (PR #54)

PR #54: TenantBindFromAuthFilter binds TenantContext to JWT-derived
tenantId after JwtAuthenticationFilter populates SecurityContextHolder.
Forged X-Tenant-ID headers from non-SUPER_ADMIN users are now overwritten
with the authenticated user's true tenantId + AUDIT-logged for SIEM.
SUPER_ADMIN keeps the legitimate cross-tenant override.

Closes SECURITY_REVIEW_2026-05-01.md §P0-1 (Task #57). Application-layer
half of multi-tenant isolation; DB-layer half is Task #27 (FORCE ROW
LEVEL SECURITY + non-superuser app role).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(api-submodule): bump to security wave 2026-05-02 (P0-SEC-2/4 + P1-1)

- 7aee607 OAuth2 confidential client_secret + RoleController tenantId ownership (#55)
- 8d03566 hash refresh-token secret on write, dual-read legacy plaintext (#56)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(2026-05-02): session status + proctoring/amispoof.com design memo

SESSION_STATUS_2026-05-02.md — 8 P0/P1 from senior reviews shipped in 5 PRs
across 2 repos. Operator-only residuals (rebuild + env vars +
JWT_SECRET decision + GDPR fixture force-push) listed in strict order.

RESEARCH_PROCTORING_AMISPOOF_2026-05-02.md — design memo on extracting
proctoring work into its own submodule + standing up amispoof.com as
public demo + research data flywheel. Recommends option B (extract now,
defer demo). User picks A/B/C. No code in that direction yet.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(api-submodule): bump to WebAuthn fix wave (PR #57)

cf398b9 — WebAuthn origin allowlist (registration + assertion paths),
clientDataJSON required, sign-counter validated.

Operator must set WEBAUTHN_ALLOWED_ORIGINS in .env.prod before rebuild.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(2026-05-02): api bump + optimized roadmap

api submodule bumped to 9cf4367 — includes #58 backend security batch
(JJWT alg/kid bind + iss/aud + HS512 gated + PKCE hard-reject + audit
escape + MfaSession Jackson), #59 test coverage backfill (F4 RLS + F5
refresh-token family revoke + F9 ShedLock concurrency), and #60
P0-critical CustomUserDetails wiring fix.

ROADMAP_OPTIMIZED_2026-05-02.md replaces stale ROADMAP_2026-04-28.md +
sprawling Phase-A–L tracker. Single source of truth for what's open:
T1 operator-only urgent, T2 awaiting user decisions, T3 in flight,
T4 leverage-ranked open work, T5 long-running scheduled.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(session-status): record CustomUserDetails blast-radius + upgrade rebuild to P0 URGENT

PR #60 surfaced that the broken principal-type wiring in
CustomUserDetailsService had been silently nullifying — for at least
8 days — not just PR #54's cross-tenant filter, but also 5 methods on
AuthorizationService and AuditLoggingAspect's user/tenant attribution.

Operator container rebuild is now P0 URGENT.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodules): bump web-app + biometric-processor to 2026-05-02 main

- web-app: e02c32f — PR #61 phone E.164 + PR #62 VITE_API_BASE_URL +
  PR #63 ErrorHandler/useVerification i18n + Redux removal +
  PR #64 round-8 MediaPipe CDN centralization + BiometricEngine dispose race.
- biometric-processor: 9f0999f — PR #66 round-8 UniFace warm-up cache +
  audit-doc import + Traefik public-router strip + MAX_UPLOAD_SIZE guard.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): web-app → F3 Playwright tags + nightly cron (PR #65)

Default Playwright run no longer mutates PROD.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): web-app → P1-FE error-surfacing batch (PR #66)

Mutation hooks now setState({error}) before re-throw across 5 features.
DeveloperPortalPage setTimeout leak fixed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodule): identity-core-api → backend quality + YAML hotfix (#61, #62)

PR #61 — P1-Q5/Q6/Q9 dead helpers + adapter cleanup + controller @Transactional move.
PR #62 — hotfix dup `app:` block in application-prod.yml (boot blocker).

Live state post-deploy 2026-05-02 17:58 UTC:
  api  HEAD 27d7423 + hotfix c53ce53 baked locally; main is now d8a4d33.
  bio  HEAD 9f0999f + manual schema/backfill applied (Alembic 0005 not in container yet).
  Soak window: APP_SECURITY_JWT_ALLOW_HS512=true, iss/aud empty, until ~2026-06-01.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(2026-05-02): rebuild executed + JWT/User analysis + soak plan

- SESSION_STATUS: late-session rebuild section, two-retry post-mortem,
  follow-up Tasks #80/81/82.
- ANALYSIS_2026-05-02_USER_DOMAIN_AND_JWT_ROTATION: deep-dive professional
  recommendations on (a) Hexagonal User-domain bifurcation — gradual
  migration with ArchUnit guard rather than delete-or-park; (b) JWT_SECRET
  defence-in-depth via kid-based key registry rather than hard rotation.
- ROADMAP_OPTIMIZED: late-session adds line.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(submodules): land PR-#63/#64/#67/#68 — backend/bio quality batch (2026-05-04)

- identity-core-api #63: ArchUnit user-domain-boundary guard (P0-Q3)
- identity-core-api #64: JWT kid-based key registry (T3.C)
- biometric-processor #67: F2 + F10 CI hygiene (drop pytest swallow + remove stale tests)
- biometric-processor #68: alembic in runtime image + backfill async-iter fix (Task #81)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(web-submodule): T-FRONTEND-HYGIENE P3 batch

Bumps web-app to 319b457 (PR #67):
- index.html title brand-neutralized
- 9 setTimeout cleanups (TOTP/WebAuthn/NFC/StepUp/FaceVerify/etc.)
- NotificationPanel polling pauses on hidden tab
- CSP comment drift fixed in vite.config.ts
- tfhub.dev / kaggle.com stripped from connect-src (post-MobileFaceNet)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(2026-05-04): roadmap refresh + CHANGELOG entry for Wave 1

- ROADMAP_OPTIMIZED_2026-05-02.md: post-deploy refresh (operator rebuild
  EXECUTED 2026-05-02 17:50–17:58 UTC; T2.1 proctoring direction = B;
  T2.2 user-domain decision = ArchUnit guard).
- SESSION_STATUS_2026-05-02.md: T3.C kid-registry rollout instructions
  added to §5 (operator post-merge env steps).
- CHANGELOG.md: Wave 1 batch — api PR #63/#64, bio PR #67/#68, web PR #67,
  CI/CD status, Copilot post-merge nit on NfcStep.tsx:96 queued.

T-LOGIN-EDGE and T-SEC-TAIL still in flight; submodule pointer for api
deliberately not bumped here.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(api-submodule): T-SEC-TAIL DeviceController boundary + P2 cleanup

Bumps identity-core-api 2d958c5 -> 19366c0:

  * fix(security): route WebAuthn credential writes through service
    boundary (T-SEC-TAIL §T4.4) (#66)
  * fix(security): reject ID-token replay against /oauth2/userinfo
    (SECURITY_REVIEW_2026-05-01) (#67)
  * feat(db): V57 — hand audit_logs partition lifecycle to pg_partman
    (concurrent agent's work, included in fast-forward)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(review): senior UI/UX designer review of verify + app — 2026-05-04

Comprehensive design review covering app.fivucsas.com (admin dashboard),
verify.fivucsas.com (hosted login + embeddable widget), demo.fivucsas.com
(Marmara BYS showcase), and fivucsas.com (brand cohesion). 35 prioritized
findings (1 P0, 4 P1, 20 P2, 11 P3) with file paths, effort sizing, and
agent-actionable flags. Verified against HEAD 319b457 to avoid restating
items already shipped (Profile date-i18n, tenant hardcode, dead Redux,
PWA navigateFallback, USER-BUG-1..10).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(review): senior DB engineer deep review — 2026-05-04

Comprehensive storage-tier review covering schema design, indexes,
relations, views, functions, performance, backup, security, migration
hygiene. 30 findings prioritised P0–P3.

Headline P0s:
- V57 on disk without V56 will brick Flyway on next deploy
- User entity still missin…
ahmetabdullahgultekin added a commit that referenced this pull request May 16, 2026
… normalization

Submodule spoof-detector dae24c8..4f601e7 (3 PRs, all merged to main):
  #25 fix(session): remove verdictLockedSpoof latch — live faces wrongly
       verdicted as SPOOF on slow-fps cameras (Chrome/Brave mobile @ ~9 fps).
       Wires LivenessProver into SessionEngine. Adds 7 regression tests on
       a previously-untested engine. 126 → 133 vitest green.
  #26 fix(amispoof): normalize displayed confidence to [0, 100] — engine
       confidence is structurally capped at 0.88, normalized at the display
       layer so a clearly-live face reads as 92% instead of 81%. Engine
       v.summary untouched (SDK consumers keep the raw scale).
  #27 fix(amispoof): also normalize on-screen verdict-text line — extracts
       a single displaySummary(v) helper so badge, on-screen text, and
       copy-to-clipboard all read the same number.

Verified live at https://fivucsas.com/amispoof/ at 2026-05-16 16:04 UTC.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant