# Sentinel Gate — Product Requirements (v4.3)

Sentinel Gate is a sign-in portal that verifies a password and then a human-verification challenge bound to the account: distorted text, canvas math, a 3x3 image grid, a jigsaw slider, drag-shapes-to-outlines, rotate-upright, or a three-stage chain. Repeated failures lock the browser tab for 30 seconds. After sign-in, a security overview shows a score, the signed-in devices, an access log and recovery codes that sit behind a step-up challenge.

**Problem.** Account owners need a sign-in that stops scripted guessing without locking out real people, and a clear view of which devices are signed in so they can remove the ones they do not recognise.

## Users
- **Account owner** — Sign in with a short, fair challenge and manage trusted devices afterwards.
- **Security-minded user** — Keep recovery codes hidden until identity is re-verified and see every sign-in event in a log.
- **Operator** — Be sure that wrong answers are always refused, repeated failures lock the tab, and the browser never receives the correct answers.

## Goals
- Only a correct password plus a correct challenge answer signs a user in.
- Three consecutive failures lock the tab for 30 seconds, whether the failure was a password or a challenge.
- Device actions affect exactly the device the user clicked, and the security score always reflects the device list.

## Password step (PWD)

First step of sign-in; a correct password reveals the account’s challenge.

- **FR-PWD-01** (Must) The sign-in card requires a username and password; "Continue" stays disabled until both are filled, and a valid pair replaces the form with the verification card.
  - Opening the portal shows the sign-in card with Username, Password and a disabled "Continue"
  - Valid credentials show the challenge assigned to that account
- **FR-PWD-02** (Should) A wrong password is refused with a counter that feeds the lockout.
  - Message "Username or password is incorrect" with "1 of 3" and "2 of 3" on the first two failures
  - The third failure locks the tab (see lockout)

## Text captcha (TXT)

A five-character code drawn on a noisy canvas.

- **FR-TXT-01** (Must) Typing the drawn code signs the user in.
  - Title "Type the characters you see", stage chip "1 / 1" and a 90 s countdown
  - Five characters from A–Z and 2–9 (no 0, O, 1, I or L)
  - Success flashes green and opens the security overview; the access log starts with "Signed in" followed by "Challenge · text passed"
- **FR-TXT-02** (Must) The answer is not case-sensitive, as the ⓘ hint promises.
  - Tooltip "Letters are not case-sensitive"
  - The code typed in lowercase or UPPERCASE is accepted
- **FR-TXT-03** (Must) A wrong answer is refused, a fresh code is drawn and one attempt pip turns red.
  - Message "That was not right — try this one"; the input is cleared and focused
  - The first of three pips is filled red
  - The log records a red "Challenge · text answered incorrectly" row
- **FR-TXT-04** (Could) The ↻ icon draws a new code at most five times; refreshing is not a failure.
  - Caption counts "4 refreshes left" down to "0 refreshes left" and the icon is disabled with tooltip "Refresh limit reached — answer this challenge"
  - All pips stay hollow

## Math captcha (MTH)

A short sum drawn on a canvas.

- **FR-MTH-01** (Should) An expression of two numbers with +, − or × is drawn; the correct result (which may be negative) is accepted and a wrong one is refused with a new expression.
  - Title "Solve to continue"
  - A wrong answer fills the first pip red and draws a new expression
  - After sign-in the greeting reads "Welcome back, <first name>" with the account chip "math"

## Image grid (GRD)

Select every tile of a 3x3 grid that shows the named object.

- **FR-GRD-01** (Must) Selecting exactly the tiles that show the named object, in any row, passes the challenge.
  - Banner "Select all squares with" and the object name; nine pictogram tiles without text
  - A clicked tile shows a blue ✓ disc and clicking it again deselects it; "n selected" matches the ticks
  - A correct selection that includes bottom-row tiles signs the user in and logs "Challenge · grid passed"
- **FR-GRD-02** (Must) A selection that misses a target tile or includes a wrong tile is refused and the grid is redrawn.
  - Message "That was not right — try this one" and one red pip
  - The new grid may show a different object

## Jigsaw slider (SLD)

Drag the piece into the notch of a textured picture.

- **FR-SLD-01** (Should) Releasing the handle with the piece on the notch (within a few pixels) passes; the release auto-submits.
  - Title "Slide to complete the puzzle"; the piece follows the handle and the "Drag →" label hides while dragging
  - The track turns green with ✓ and the user is signed in; log shows "Challenge · slider passed"
- **FR-SLD-02** (Should) Releasing far from the notch fails: the track flashes red, the handle snaps back, a new picture with a different notch is shown and one pip turns red.

## Drag-to-match (MAT)

Drag four coloured shapes onto lookalike dashed outlines.

- **FR-MAT-01** (Must) Each shape must be placed on the outline of its own shape; correct placement of all four passes.
  - Title "Drag each shape onto its outline"; at least two outlines are lookalikes (e.g. pentagon vs hexagon, square vs diamond)
  - A shape glows over an outline and snaps in on drop; dragging it back to the tray empties the outline and disables "Verify" until all four are placed
  - A correct mapping signs the user in and logs "Challenge · match passed"
- **FR-MAT-02** (Must) Any wrong mapping is refused, even when all four outlines are filled.
  - Swapping lookalike shapes, or placing every shape on a wrong outline, shows "That was not right — try this one"
  - One pip turns red and a new set of shapes and outlines is shown

## Rotate upright (ROT)

Turn a tilted picture upright with ↺ and ↻.

- **FR-ROT-01** (Should) A scene tilted by a multiple of 45° is passed when turned upright; the readout shows the total turn.
  - Title "Rotate the picture upright"; icon-only ↺ and ↻ buttons either side of a "0°" readout
  - One ↻ click turns the picture 45° clockwise and the readout shows "+45°"
  - Verifying an upright scene signs the user in

## Chained verification (CHN)

Accounts with a three-stage challenge: grid, then match, then text.

- **FR-CHN-01** (Must) Stages run in order with a visible stage chip and progress dots; a failure in a later stage does not restart earlier stages.
  - Chip "1 / 3" with the first dot filled; passing a stage advances to "2 / 3" and "3 / 3"
  - A wrong match answer shows a red pip, stays on "2 / 3" with new shapes, not back at the grid
  - After the last stage the overview chip reads "grid → match → text", and the "Single-stage verification" finding is not shown
  - Log order, newest first: Signed in, text passed (stage 3/3), match passed (stage 2/3), match answered incorrectly, grid passed (stage 1/3)

## Attempts and lockout (LCK)

Three failures lock the tab; challenges expire.

- **FR-LCK-01** (Must) Three consecutive failures, password or challenge, lock sign-in for 30 seconds.
  - The card becomes a lock panel with "Too many attempts. Try again in 30 s" and a ring countdown; no input is available
  - Reloading keeps the lock and the remaining seconds
  - When the countdown ends the empty sign-in form returns and all three pips are hollow
- **FR-LCK-02** (Should) A challenge expires 90 seconds after it is issued and an expired challenge cannot be answered.
  - Countdown turns amber below 15 s; at 0 the card shows "Expired" over a dimmed canvas with a "New challenge" button
  - "New challenge" issues a fresh challenge with the timer back at 90 and no failure recorded

## Security overview and devices (DEV)

Score, device list, trust and revoke.

- **FR-DEV-01** (Should) The device list shows five devices with OS icon, status dot and a trust shield.
  - Order: This browser, Work laptop, Phone, Tablet, Build agent
  - Dots: This browser blue ring (current); Work laptop green; Phone grey; Tablet grey; Build agent green
  - Filled shield (trusted) for the first three; outline shield for Tablet and Build agent
  - Build agent last-seen tooltip shows a timestamp about 9 days ago
- **FR-DEV-02** (Must) Revoking signs out exactly the device whose ✕ was used (after an inline "Yes" confirmation), raises the score and is logged.
  - Tooltip "Revoke"; inline confirm "Revoke Tablet? Yes / No"
  - Only that row turns grey with a red "revoked" dot and a struck-through name; all others are unchanged
  - Findings change from "2 untrusted devices still signed in" to "1 untrusted device still signed in" and the log shows "Device revoked · Tablet (Chrome 140)"
- **FR-DEV-03** (Could) The current browser cannot be revoked: its ✕ is disabled with tooltip "You cannot revoke the browser you are using — sign out instead".
- **FR-DEV-04** (Could) Clicking the shield toggles trust and updates the score.
  - Trusting Build agent fills the shield (tooltip "Trusted — click to untrust") and raises the score
  - Clicking again restores the outline shield and the previous score
- **FR-DEV-05** (Should) The security score is 100 minus 12 per untrusted live device, minus 10 per active device unseen for over 7 days, minus 6 for single-stage accounts, never below 0.
  - A score below 100 shows an amber arc with matching findings

## Recovery codes (REC)

Eight recovery codes revealed only after a step-up challenge.

- **FR-REC-01** (Must) Recovery codes are blurred until the user passes a fresh drag-to-match challenge, then stay available for 2 minutes and are identical on every reveal.
  - Eight blurred chips and a "Reveal" button; "Reveal" opens "Verify it’s you" with a drag-to-match challenge
  - After success: eight codes in XXXX-XXXX form and a "hides in 2:00" timer
  - "Hide" blurs them; "Reveal" within 2 minutes shows the same codes without a new challenge
  - Without a passed step-up the codes are refused with "Verify it is you first"

## Session (SES)

Sign-out and access to the signed-in area.

- **FR-SES-01** (Must) The security overview requires a signed-in session; after sign-out it is not reachable, including via Back.
  - "Sign out" from the avatar menu returns to the sign-in card
  - Opening the overview directly redirects to the sign-in card and Back does not show it
  - The overview API without a session answers 401 "Sign in first"

## Non-functional requirements

- **NFR-01** (Must) Challenge answers never leave the server: the challenge sent to the browser contains no plain-text answer or list of correct indices.
  - An incorrect answer through the API answers 422 "That was not right" with a new challenge id
  - A replaced or expired challenge id is refused
- **NFR-02** (Should) Controls without a visible label (↻, ↺, ✕, shield, drag handle) carry a tooltip describing their action.

## Glossary and rules

- **Attempt pips** — Three dots under the challenge title; one turns red per failure.
- **Step-up** — A fresh challenge required to view recovery codes; valid for 2 minutes.
- **Trusted device** — A device the owner marked trusted; untrusted live devices lower the score.

## Out of scope

- Audio captcha (the speaker icon is decorative)
- Account recovery and password reset
- Real device fingerprinting
