OViq Hotel ERP — Phase 8 HR/payroll pending-feature implementation Executed verification: 2026-10-22 Runtime: PHP 8.3.6, MySQL 8.0.46, Node.js 22.23.3 and headless Chromium. PHP syntax checks: 105 files passed. JavaScript syntax checks passed. Source targets PHP >=8.2. PHP8.2 itself and non-Chromium browsers were not executed locally. CI matrix is supplied but not remotely activated/executed. TOTAL: 497 reported assertions/checks across the layers below. These are checks, not 497 distinct features or a production/security certification. IMPLEMENTED THIS BATCH Employee directory; optional same-property linked user; compensation controls split from HR-only administration; shift templates; overnight roster intervals and saved paid-duration snapshots; manual attendance and approval/correction; DST-safe UTC conversions; monthly contract salary proration; allowances; configured fixed/percentage deductions; approved roster-based overtime; draft regeneration; source fingerprints and stale-edit guards; completed-month approval; sensitive payroll reauthentication through current password/fresh enrolled second factor; manual external salary-payment reference; frozen printable payslips; protected approved/paid work-date months; user/payload-bound request-key replay; audited transactional mutations; resumable migration and legacy-data readiness checks. NEW CORRECTNESS COVERAGE - Integer payroll formula: 3000 base + 100 allowance + 40 overtime - 160 deductions = 2980 net; partial-month calendar-day proration. - Open/pending attendance cannot be silently paid as overtime; roster/attendance exceptions block approval; changed sources require regenerated review. - Changing current compensation does not rewrite an approved historical snapshot. - HR-only account lacks salary controls and receives 403 for payroll and payslip routes; foreign payslip receives 404. - Password confirmation enforced in browser payroll approval; enrolled-factor enforcement reuses the existing identity service whose replay/recovery tests also pass. - Property mutex serializes simultaneous roster writes, identical draft requests, approval-versus-new-attendance and payment markers; revoked session version rejected inside mutation. - Test-only failing audit INSERT proves HR row/request rollback. That test used an isolated DBA connection to create its fault-injection trigger; application does not require that privilege. - Actual Phase7 ZIP schema upgrades, replays metadata safely after simulated interrupted migration, preserves unknown legacy ownership and settled amounts, and does not invent approval or payroll provenance. BROWSER / UI EVIDENCE Chromium completes employee registration, shift creation, roster assignment, approved attendance, salary draft, password-confirmed approval, manual paid recording and immutable payslip rendering. Mobile employee layout tested at 390px; print styles hide navigation; print button invokes browser printing. No uncaught JavaScript errors; salary pages are not persisted by the service worker. Preview PNGs in tests/previews contain SYNTHETIC TEST DATA ONLY. Browser/HTTP harnesses were run in disposable fixtures; console output is included below. Portable PHP suites ship in tests/. Test databases must end in _test. No real gateway/device/provider calls or money transfers were made. DEPLOYMENT / ACCEPTANCE LIMITS Use public/ as document root. Preserve database settings, encryption key, uploads and installed.lock when upgrading; back up and restore-drill first; maintenance mode before php bin/migrate.php. Existing DBA audit guards remain required. Review DEPLOYMENT.txt and RELEASE-STATUS.txt. Unknown legacy employee end dates, global/shared shift ownership, unverified roster snapshots and settled payroll without provenance block readiness pending DBA/payroll-owner reconciliation. This is configurable monthly-contract payroll, NOT statutory tax/payroll compliance. No automatic absence deduction, weekly/holiday overtime rules, biometric device adapter, salary bank transfer, server-side PDF mailer, self-service portal, four-eyes approval rule, approved-payroll reversal or automatic salary GL posting. Payroll periods follow local attendance work dates with no overnight month-end splitting. No load test, HA test, pentest or production acceptance certification was performed. ===== Existing integration and route regression ===== PASS Authenticated property context resolves assigned property PASS Super-admin permission gate succeeds PASS Housekeeper denied CRM permission PASS Forged CSRF token rejected PASS Issued CSRF token accepted PASS Lead created at version zero PASS Lead stage persists PASS Stale lead update rejected PASS Unknown pipeline stage rejected PASS Cross-property lead update denied PASS Invalid calendar date rejected PASS Blank lead title rejected PASS Work assigned to technician PASS Asset retirement blocked while work outstanding PASS Work lifecycle reaches closed PASS Closed work cannot advance PASS Due maintenance produces one work order PASS Repeated due generation creates no duplicate PASS Retired assets cannot reactivate PASS Event quote equals two hours times hall rate PASS Overlapping event rejected PASS Back-to-back hall booking accepted PASS Hall capacity enforced PASS Completed event cannot reopen PASS Event cancellation persists PASS Cross-property hall booking denied PASS Pricing defaults disabled PASS Disabled pricing engine rejects generation PASS Pricing toggle persists PASS Pricing generates two daily recommendations PASS Regeneration uses unique date/type records PASS No duplicate recommendations PASS Approved recommendation stored as date override PASS Reapplying recommendation rejected PASS Base room-type rate unchanged PASS High-occupancy pricing formula verified PASS Low-occupancy pricing formula verified PASS Audit and mutation transaction rolls back together PASS Workflow audit records written PASS Controller renders crm PASS Controller renders maintenance PASS Controller renders events PASS Controller renders pricing PASS Controller renders reports PASS Date-rate API rejects missing inputs PASS Date-rate API returns approved override PASS Route handler exists /login PASS Route handler exists / PASS Route handler exists /dashboard PASS Route handler exists /pms/calendar PASS Route handler exists /pms/calendar-data PASS Route handler exists /pms/available-rooms PASS Route handler exists /pms/reservations PASS Route handler exists /pms/reservations/create PASS Route handler exists /pms/reservations/{id} PASS Route handler exists /pms/rooms PASS Route handler exists /pms/guests PASS Route handler exists /pms/guests/{id} PASS Route handler exists /pms/night-audit PASS Route handler exists /front-office PASS Route handler exists /pos PASS Route handler exists /pos/orders/{id} PASS Route handler exists /pos/kitchen PASS Route handler exists /housekeeping PASS Route handler exists /inventory PASS Route handler exists /inventory/purchase-orders PASS Route handler exists /inventory/purchase-orders/{id} PASS Route handler exists /accounting PASS Route handler exists /crm PASS Route handler exists /maintenance PASS Route handler exists /events PASS Route handler exists /pricing PASS Route handler exists /reports PASS Route handler exists /reports/export PASS Route handler exists /pms/date-rate PASS Route handler exists /login/verify PASS Route handler exists /security PASS Route handler exists /admin/access PASS Route handler exists /hr PASS Route handler exists /hr/schedule PASS Route handler exists /hr/attendance PASS Route handler exists /hr/payroll PASS Route handler exists /hr/payroll/{id} PASS Route handler exists /login PASS Route handler exists /logout PASS Route handler exists /pms/reservations PASS Route handler exists /pms/reservations/{id}/checkin PASS Route handler exists /pms/reservations/{id}/checkout PASS Route handler exists /pms/reservations/{id}/transition/{action} PASS Route handler exists /pms/reservations/{id}/charges PASS Route handler exists /pms/reservations/{id}/payments PASS Route handler exists /pms/room-types PASS Route handler exists /pms/rooms PASS Route handler exists /pms/rooms/{id}/status PASS Route handler exists /pms/guests PASS Route handler exists /pms/guests/{id} PASS Route handler exists /pms/night-audit/run PASS Route handler exists /front-office/wakeup PASS Route handler exists /front-office/wakeup/{id}/complete PASS Route handler exists /pos/outlets PASS Route handler exists /pos/tables PASS Route handler exists /pos/categories PASS Route handler exists /pos/items PASS Route handler exists /pos/orders PASS Route handler exists /pos/orders/{id}/items PASS Route handler exists /pos/orders/{id}/items/{item_id}/void PASS Route handler exists /pos/orders/{id}/items/{item_id}/split PASS Route handler exists /pos/orders/{id}/send-kitchen PASS Route handler exists /pos/orders/{id}/pay PASS Route handler exists /pos/orders/{id}/room-charge PASS Route handler exists /pos/kitchen/{item_id}/advance PASS Route handler exists /housekeeping/tasks PASS Route handler exists /housekeeping/tasks/{id}/assign PASS Route handler exists /housekeeping/tasks/{id}/advance PASS Route handler exists /housekeeping/laundry PASS Route handler exists /housekeeping/laundry/{id}/move PASS Route handler exists /housekeeping/lost-found PASS Route handler exists /housekeeping/lost-found/{id}/claim PASS Route handler exists /inventory/items PASS Route handler exists /inventory/stores PASS Route handler exists /inventory/adjust PASS Route handler exists /inventory/purchase-orders PASS Route handler exists /inventory/purchase-orders/{id}/approve PASS Route handler exists /inventory/purchase-orders/{id}/receive PASS Route handler exists /accounting/journal PASS Route handler exists /accounting/expenses PASS Route handler exists /ops/{module}/{action} PASS Route handler exists /login/verify PASS Route handler exists /security/{action} PASS Route handler exists /admin/access/{action} PASS Route handler exists /hr/{module}/{action} TOTAL 131 assertions passed; 85 registered routes. ===== Financial, tenant and concurrent booking hardening ===== PASS Property context established PASS Decimal money addition uses exact minor units PASS Fractional line rounds half up PASS Negative monetary input rejected PASS Excess decimal places rejected PASS Cross-property guest rejected by reservation service PASS Room maximum occupancy enforced PASS Concurrent same-room booking: exactly one writer succeeds PASS Concurrent booking creates only one reservation PASS Unassigned reservations cannot oversell room-type inventory PASS Dirty/cleaning room cannot be checked in PASS Unpaid folio cannot check out PASS Folio includes room tax and extra charges exactly once PASS Identical folio payment replay is idempotent PASS Payment key reuse with changed amount rejected PASS Folio overpayment rejected PASS Paid checkout sends room to cleaning PASS Checkout generates one cleaning task PASS Closed folio rejects charges PASS Occupied restaurant table cannot be reopened PASS Split tax totals use exact minor units PASS POS partial-payment replay creates no duplicate PASS Split payment cannot exceed remaining balance PASS Cannot redistribute partially-paid lines PASS Fully-paid split rejects additional payment PASS All splits settled marks order paid PASS Settled order frees table PASS Settled order cannot be voided PASS Concurrent identical payment requests both resolve successfully PASS Concurrent payment replay persists only one receipt PASS Still-open current business date cannot be closed PASS Concurrent night audit closes date once PASS Night audit posts exactly one room charge per business date PASS Night audit does not double count quoted room amount PASS Opening stock adjustment persists PASS Negative inventory stock rejected PASS Cross-property stock adjustment rejected PASS Partial GRN advances PO state PASS Cumulative GRN over-receipt rejected PASS Weighted-average cost includes stock in both stores PASS Receipt leaves other store quantity unchanged PASS Receiving store gets exact received quantity PASS Fully-received PO closes PASS Double-entry journal balances exactly PASS Journal uses property currency, not hardcoded USD PASS Unbalanced journal rejected PASS Expense cannot post to an asset account PASS Rejected expense leaves no partial record PASS Expense journal preserves expense date PASS Database rejects audit update PASS Database rejects audit deletion PASS Login attempt bucket updated 1 PASS Login attempt bucket updated 2 PASS Login attempt bucket updated 3 PASS Login attempt bucket updated 4 PASS Login attempt bucket updated 5 PASS New session does not bypass database login throttle PASS Native DI resolves typed dependencies PASS Named routes encode path parameters PASS Dynamic SQL identifiers validated TOTAL 60 Phase 6 hardening assertions passed. ===== Identity, access and ledger replay regression ===== PASS RFC 6238 published vector 59 PASS RFC 6238 published vector 1111111109 PASS RFC 6238 published vector 1111111111 PASS RFC 6238 published vector 1234567890 PASS RFC 6238 published vector 2000000000 PASS RFC 6238 published vector 20000000000 PASS Generated TOTP secret has 160-bit base32 form PASS Current TOTP matches PASS Used counter cannot match again PASS Non-numeric TOTP rejected PASS Out-of-window TOTP rejected PASS TOTP secret round-trips through authenticated encryption PASS Tampered encrypted secret is rejected PASS Enrollment requires the current password PASS Enrollment issues a local authenticator URI PASS Enrollment issues ten unique recovery codes PASS Enrollment stores encrypted secret and removes plaintext slot PASS Enrollment revokes older sessions and upgrades current session PASS Database stores only hashes of recovery codes PASS Password alone grants no authenticated session for enrolled user PASS Fresh TOTP completes password sign-in PASS Verified sign-in TOTP cannot be replayed PASS Repeated password login returns challenge PASS Unused recovery code completes sign-in PASS Recovery code works once only PASS Enrolled settings administrator can enforce property 2FA policy PASS Required policy prevents disabling 2FA PASS Custom role belongs to current property PASS Staff account is assigned selected custom role PASS Permission update revokes sessions of assigned users PASS Stale role version rejected PASS System role templates are immutable through administration PASS Delegated role administrator cannot grant unheld financial permission PASS Non-super administrator cannot assign super-admin PASS Delegated administrator cannot alter super administrator PASS Administrator cannot edit own assigned role PASS Foreign-property role cannot be assigned PASS Administrator cannot disable own account PASS Cross-property user edits rejected PASS Authorized staff deactivation persists PASS Stale user version rejected PASS Property policy sends unenrolled password-valid user to enrollment PASS Recovery regeneration issues ten replacement codes PASS Regeneration invalidates every old recovery code PASS 2FA disable removes encrypted secret and recovery codes PASS Non-required unenrolled account can use password sign-in PASS Manual journal requires a replay key PASS Identical journal replay returns original entry PASS Changed journal payload cannot reuse a key PASS Identical expense replay returns original expense PASS Expense replay creates only one balanced journal PASS Changed expense payload cannot reuse a key PASS Expense request key cannot be reused for a journal PASS Security audit events written without secrets PASS Audit payloads do not contain authenticator secret TOTAL 55 identity/access/ledger assertions passed. ===== Independent-process identity races ===== PASS Concurrent identical TOTP submissions produce one accepted verification PASS TOTP replay counter is advanced exactly once PASS Concurrent identical recovery codes produce one accepted verification PASS Recovery-code used marker persists once PASS Concurrent identical ledger submissions return the same entry PASS Concurrent ledger replay persists a single balanced entry PASS Concurrent role edits reject the stale version PASS Custom-role version advances once TOTAL 8 Phase 7 multi-process assertions passed. ===== New HR and monthly payroll service/view assertions ===== PASS Invalid payroll month rejected PASS Unsupported payroll year rejected PASS Unknown HR mutation rejected PASS Missing request key rejected PASS Employee creation retry returns the original employee PASS Changed employee payload cannot reuse request key PASS Employee number includes property and unique identity PASS Employee directory supports staff without login accounts PASS Invalid employee email rejected PASS Negative contract salary rejected PASS Cross-property linked account rejected PASS A login account cannot link to two employees PASS Stale employee write rejected PASS Overnight shift is derived from end-before-start PASS Zero-length shift rejected PASS Shift operational duration limit enforced PASS Invalid clock time rejected PASS Break cannot consume the entire shift PASS Roster stores explicit UTC boundaries PASS Duplicate employee/date assignment rejected PASS Overnight roster ends on the next calendar day PASS Overnight roster overlap rejected across work dates PASS Changing shift templates preserves existing roster snapshots PASS Stale shift edit rejected PASS Attendance subtracts unpaid breaks in integer minutes PASS Duplicate attendance rejected PASS Check-in must match the property-local work date PASS Reverse attendance interval rejected PASS Future/mismatched attendance rejected PASS Open attendance cannot be approved PASS Open attendance prevents overlapping subsequent entries PASS Stale attendance edit rejected PASS Draft displays pending-attendance and roster exceptions PASS Payroll approval blocks unresolved attendance PASS Approved attendance is protected from direct editing PASS Roster for approved attendance cannot change PASS Roster with attendance cannot be removed PASS Changed attendance invalidates the previous payroll source hash PASS Draft regeneration updates the same monthly slip PASS Resolved attendance yields an exception-free payroll draft PASS Overtime pays only actual minutes beyond snapshotted scheduled paid minutes PASS Integer payroll computes base, allowance, overtime, percentage and fixed deductions exactly PASS Stale payroll regeneration rejected PASS Payroll requires explicit local-review acknowledgement PASS Draft payroll cannot be marked paid PASS Payroll approval retry is idempotent PASS Approved payroll cannot be regenerated PASS Approved payroll freezes source attendance PASS Approved payroll freezes new roster records in its month PASS Approved payroll freezes new attendance in its month PASS Compensation changes do not rewrite approved historical payslips PASS External salary payment reference is mandatory PASS Repeated salary payment mark has one result PASS Manual payment marker follows draft/approved/paid lifecycle PASS Paid payroll cannot be marked paid again with another key PASS Partial-month base salary uses rounded integer calendar-day proration PASS Deductions exceeding gross are rejected PASS Invalid percentage deduction rejected PASS Current/incomplete month cannot be approved PASS Unused non-frozen roster can be removed PASS Attendance reopening requires an audit reason PASS Unfrozen approved attendance supports audited correction PASS Foreign employee lookup rejected PASS Foreign shift assignment rejected PASS Foreign employee payroll generation rejected PASS Foreign payslip lookup rejected PASS HR-only operator cannot generate payroll PASS HR-only operator cannot read salary slips PASS HR-only operator cannot set compensation PASS HR-only employee registration defaults compensation without exposing it PASS Non-payroll directory rendering omits salary controls PASS Employee names are HTML-escaped PASS Directory listing excludes foreign property employee data PASS HR controller renders index inside existing shell PASS HR controller renders schedule inside existing shell PASS HR controller renders attendance inside existing shell PASS HR controller renders payroll inside existing shell PASS Printable paid slip uses immutable payroll amounts and manual receipt reference PASS Nonexistent spring-forward wall time rejected PASS Ambiguous fall-back wall time rejected PASS Unambiguous DST property-local input converts to UTC PASS Audit insertion failure aborts HR mutation PASS HR row and request key roll back together with audit failure PASS Payroll manual payment markers do not silently post general-ledger entries PASS HR workflows emit transactional audit events TOTAL 85 HR/payroll assertions passed. ===== New independent-process HR/payroll races ===== PASS Concurrent duplicate roster writes produce one successful assignment PASS Concurrent roster requests persist one row PASS Simultaneous identical payroll-generation requests return one draft identity PASS Concurrent payroll generation persists one monthly payslip PASS Payroll approval and attendance creation serialize; exactly one wins PASS Approval never commits a stale snapshot alongside new pending attendance PASS Concurrent identical salary-payment markers resolve idempotently PASS Concurrent salary-payment replay creates one payment audit event PASS Session revocation is rechecked inside the HR mutation transaction TOTAL 9 HR concurrency assertions passed. ===== Fresh installer and HTTP deployment regression ===== PASS Uninstalled application routes to public installer PASS Installer rejects missing CSRF PASS Installer database configuration succeeds PASS Installer builds all tables and seeds identity catalog PASS Installer creates administrator and completes lock step PASS Installation lock written PASS Installed wizard cannot be reopened PASS Login rejects missing CSRF PASS Login authenticates and dashboard renders PASS Authenticated route /crm renders PASS Authenticated route /maintenance renders PASS Authenticated route /events renders PASS Authenticated route /pricing renders PASS Authenticated route /reports renders PASS Authenticated route /pms/calendar renders PASS Authenticated route /pms/rooms renders PASS Authenticated route /pos renders PASS Authenticated route /accounting renders PASS Nested-page base URL anchored at application root PASS CRM mutation rejects missing CSRF PASS Lead creation escapes stored HTML when rendered PASS AJAX lead movement persists PASS AJAX stale version returns conflict PASS Invalid report date returns 422 PASS Report CSV export responds PASS Unregistered route returns 404 without fatal error PASS Service worker excludes authenticated page persistence PASS CLI migration runner handles fresh install and rerun PASS Phase 4-style database receives Phase 5 additions PASS Non-CRM role denied CRM page PASS Housekeeper denied pricing page TOTAL 31 HTTP/deployment checks passed. ===== New Chromium employee-to-paid-payslip and HTTP acceptance ===== PASS HR directory renders in the existing navy/gold application shell PASS Employee registration form writes a property-scoped staff record PASS Employee directory persistence verified independently in MySQL PASS Shift creation form saves local shift and unpaid break PASS Roster submission retains its historical schedule filter PASS Attendance submission retains the recorded payroll month PASS Attendance approval form commits its reviewed status PASS Payroll draft form generates exact monthly net pay with overtime PASS Generated payslip is explicitly a draft until reviewed PASS Payroll approval rejects incorrect reauthentication without changing its status PASS Reviewed payroll approval requires and accepts the current password PASS Manual salary-payment recording produces a frozen paid payslip PASS Payslip print stylesheet hides navigation and retains the document PASS Print/Save PDF control invokes browser printing PASS HR mutation rejects missing CSRF token PASS Invalid payroll-period query returns HTTP 422 without a fatal error PASS HTTP attendance correction cannot alter a paid payroll period PASS Cross-property payslip URL returns HTTP 404 PASS HR directory does not expose foreign-property employees PASS Role change revokes the browser session before HR access PASS HR-only account does not receive salary input fields PASS HR-only account is denied the payroll screen PASS HR-only account is denied printable payslips PASS HR-only account cannot invoke payroll-generation POST directly PASS Employee page fits a mobile viewport without horizontal overflow PASS HR workflows produce no uncaught browser JavaScript errors PASS Service worker does not persist authenticated HR or salary pages TOTAL 27 HR browser/HTTP checks passed. ===== Prior PMS, CRM, mobile and offline Chromium acceptance ===== PASS Desktop sidebar renders PASS Room type setup submits successfully PASS Room setup creates clean room tile PASS Guest registration reaches profile PASS Walk-in guest checked in through real browser form PASS Folio receipt records through idempotent payment form PASS Paid browser checkout succeeds PASS Tape chart JavaScript renders fourteen-day grid PASS Drag-and-drop CRM movement persists after reload PASS Accessible CRM selector persists stage change PASS Browser route renders /maintenance PASS Browser route renders /events PASS Browser route renders /pricing PASS Browser route renders /reports PASS Browser route renders /accounting PASS Browser route renders /housekeeping PASS Browser route renders /pos PASS Mobile sidebar toggle works at 390px PASS Mobile dashboard avoids document-level horizontal overflow PASS Browser cache contains no authenticated HTML pages PASS Offline navigation displays static fallback, not guest data PASS No uncaught browser JavaScript errors PASS No external asset requests needed for application rendering TOTAL 23 browser checks passed. ===== Prior identity and access Chromium acceptance ===== PASS Browser creates property-owned role with selected permissions PASS Browser creates staff account assigned to custom role PASS Custom-role staff can open granted CRM module PASS Custom-role staff cannot open access administration PASS Role edit revokes the existing staff session PASS Reauthenticated staff loses revoked CRM permission PASS Enrollment renders local QR payload and manual setup key PASS Confirmed enrollment displays ten one-use recovery codes PASS Enabling two-factor revokes previously active browser session PASS Recovery codes disappear after their one-time display PASS Enrolled password sign-in requires a second-factor challenge PASS Incomplete challenge cannot reach dashboard PASS Current authenticator code completes browser sign-in PASS One-use recovery code completes browser sign-in PASS Used recovery code cannot be replayed in the browser PASS Settings administrator enforces property-wide enrollment policy PASS Required policy restricts unenrolled staff to enrollment page PASS Enrolled administrator retains access administration PASS Repeated journal form submission creates one journal entry PASS Repeated expense form submission creates one expense row PASS Authenticator and recovery pages are never cached by service worker PASS No uncaught JavaScript errors in identity workflows PASS QR and identity screens make no external asset requests TOTAL 23 Phase 7 browser checks passed. ===== Property-isolation and security HTTP regression ===== PASS Foreign guest detail denied PASS Foreign reservation detail denied PASS Foreign POS order detail denied PASS Foreign outlet detail denied PASS Property-isolated collection /pms/guests PASS Property-isolated collection /pms/reservations PASS Property-isolated collection /pms/reservations/create PASS Property-isolated collection /inventory PASS Property-isolated collection /front-office PASS Property-isolated collection /dashboard PASS Cross-property checkout denied before mutation PASS Foreign inventory input cannot cross resource boundary PASS Unsupported JSON mutation fails closed PASS Disabled account loses existing session access PASS 2FA-marked account cannot bypass the second-factor challenge PASS HTTP login throttle survives six fresh cookie jars TOTAL 16 security HTTP checks passed. ===== Earlier archived upgrade, SQL backup and restore drill ===== PASS Archived Phase6 database upgrades through Phase7 PASS Actual upgrade migration rerun is idempotent PASS Unknown legacy inventory ownership is preserved for manual reconciliation PASS Preflight blocks unresolved legacy inventory PASS Preflight reports missing DBA audit guards PASS DBA audit-guard installer succeeds and can be rerun PASS CLI backup produces a checksum-verified SQL dump PASS Backup tool refuses to overwrite an existing file PASS Backup restores matching table and fixture record counts into another database PASS Restore includes both append-only audit triggers TOTAL 10 upgrade/backup checks passed. ===== Application-key and emergency recovery regression ===== PASS Key provisioning creates once and never silently rotates an existing key PASS Provisioned application key is owner-readable only PASS Emergency recovery refuses missing confirmation and replacement password PASS Confirmed operator recovery completes through shipped CLI PASS Recovery resets enrollment, revokes sessions and replaces password atomically PASS Emergency recovery records a DBA audit event TOTAL 6 key/recovery operator checks passed. ===== Actual archived Phase7-to-Phase8 HR migration ===== PASS Actual archived Phase7 schema upgrades through Phase8 PASS Phase8 upgrade rerun is idempotent PASS Legacy linked employee names backfill only from matching-property accounts PASS Unknown legacy staff identity and end dates are preserved for reconciliation PASS Legacy shift ownership inferred from unambiguous single-property roster usage PASS Shared and unused legacy shifts remain unassigned rather than guessing ownership PASS Migration never silently approves historical attendance PASS Historical settled payroll is preserved without inventing calculation provenance PASS Readiness preflight blocks Legacy employee identity and employment-end dates reconciled PASS Readiness preflight blocks Legacy shift ownership reconciled PASS Readiness preflight blocks Legacy roster property and schedule snapshots reconciled PASS Readiness preflight blocks Legacy settled payroll has reviewed snapshot provenance PASS Interrupted-migration replay reuses metadata without duplicate columns or lost staff TOTAL 13 HR upgrade checks passed.