# Release gate — private staging only

These are required acceptance checks, not claims of tests already passed.
Use synthetic candidates and an email test inbox. Make two branches A/B, managers MA/MB and employees EA/EB. Use two different browser profiles to avoid shared sessions.

| Check | Expected |
|---|---|
| Run `tools/validate.php` with PHP 8+ | No helper or PHP syntax errors |
| Existing admin, employee and candidate logins | All still work; original dashboards load |
| MA lists employees/applications/candidates/resumes/enrollments | A records only; unassigned and B absent |
| MA changes URL/edit ID or POST ID to a B record | Rejected; B database row unchanged |
| MA submits `act=member`, `permissions`, `assign`, `branch` | Rejected even with a valid manager CSRF token |
| MA creates employee and forges role/admin/branch fields | Ordinary employee in A only; no admin/manager privileges |
| MA posts save without View or Add/Edit permission | Rejected; row unchanged |
| Remove MA permissions or deactivate employee/branch | Next workspace request loses access immediately |
| CSV export, unauthorized branch filter | A only; no hashes/tokens; denied without Export permission |
| Manager uses direct `/admin/jobs.php`, `/admin old/jobs.php`, alternate employee global-module URL | No admin/global records accessible |
| Employee self-service | Own CRM/invoice/payment/report/tasks still work; another employee's ID is rejected |
| Candidate and program enrollment | Enroll A candidate into assigned A program; reject B reference; candidate dashboard shows assigned class/resource |
| Before start / at start / exact end / after end / Cancelled | Join denied / allowed / denied / denied / denied; timezone IST |
| Leave class, close tab, long offline gap, repeated heartbeat | Time does not continue beyond end or count long gaps; totals do not exceed duration |
| Candidate attendance / Manager A report / Admin report | Same candidate, class and seconds; MB cannot access A attendance |
| Candidate dashboard today's completed class | Included in denominator after refresh; no stale Join button |
| Resume list and View Resume | Compact contact details and email-matched applied job; full details only on View |
| Poster preview + expired/scheduled/inactive popup | Preview works; public popup only during Active schedule; close/frequency/mobile/reduced motion work |
| 10 MB MP4 resource + 10 MB MP4 review | Saved, playback works, record points to real file |
| Above PHP/server size limit and unsupported file extension | Clear failure; no misleading success/empty video record |
| Original public job apply and training apply | Submission saved once; original email arrives in staging inbox; no admin-login wall |
| Original invoice + candidate creation | Invoice totals/status and onboarding email still correct |
| Existing website pages, mobile menu, admin links | No PHP warnings, 403 regressions or broken layout |
| Main Admin full overview | A and B visible, manager-created employee count and audit entries correct |

Check server/PHP error logs after tests. Keep actual outcomes/date/tester in your deployment record. Stop rollout on any failed access control, database or email test.
