# MEGA™ Municipal Risk Management — test and readiness report

**Release:** 1.1 candidate — 24 October 2026  
**Target:** Afrihost Linux shared hosting, PHP 8.2+, MySQL/MariaDB  
**Outcome:** Code-level checks PASS; end-to-end workshop and production readiness NOT VERIFIED.

## 1. What was inspected

Inspected: `public/index.php`, `app/bootstrap.php`, `app/schema.sql`, `install.php`, `tests/checks.php`, deployment guide, and 587-row taxonomy CSV. Reviewed workflow for IDP/SDBIP entry, department selection, workshop voting, inherent risk scoring, initial and revised control effectiveness, treatment, evidence, approvals and consolidation.

## 2. Updates made in 1.1

1. Action implementation now requires *action-linked* implementation evidence before the `implemented` status is accepted; progress changes require explanatory notes, stored in the new `action_updates` audit table.
2. Evidence attachments cannot claim an action from another risk. Upload types are checked against the expected evidence kinds.
3. Risk approval now requires preceding submission and nonempty control descriptions, rather than allowing direct approval of incomplete drafts.
4. Initial controls cannot be overwritten after submission/approval, and changed effectiveness factors on approved risks must use the evidence-supported review path.
5. Cannot open a second active voting round for the same risk; workshop cannot close with open rounds.
6. Validated workshop state, objective level and operational objective parent type.
7. Action updates and evidence uploads require an appropriate staff role rather than any logged-in viewer.
8. Added administrator creation of staff accounts via `?p=users`; individual staff accounts are needed for separate approval credentials.
9. Logout now requires POST with CSRF protection.
10. Added `app/migrate_1_1.sql` for existing installations and updated install-time schema.

## 3. Executed checks

| Check | Result | Notes |
|---|---|---|
| PHP syntax: installer | PASS | `php -l install.php` |
| PHP syntax: bootstrap | PASS | `php -l app/bootstrap.php` |
| PHP syntax: main application | PASS | `php -l public/index.php` |
| Taxonomy records | PASS | 587 rows present |
| Residual arithmetic | PASS | 20×0.8=16; 13×0.65=8.45; 25×1=25 |
| SQL schema live application | NOT RUN | No local MySQL/MariaDB service or PDO-MySQL extension available |
| Fresh installer on target Afrihost plan | NOT RUN | Requires user's hosting environment |
| Voting concurrency and race conditions | NOT RUN | Requires a running database and concurrent HTTP clients |
| Anonymous ballot integrity under hostile conditions | NOT CERTIFIED | A browser cookie is not a reliable identity or one-person-one-vote control |
| Approval, evidence, snapshots end-to-end | NOT RUN | Requires configured live MySQL and authenticated test accounts |
| Performance/load test, security assessment, accessibility | NOT RUN | Separate tests are required |

## 4. Open issues / release blockers

- Anonymous vote participation remains limited by one browser cookie and a shared link, not verified against a registered workshop attendee list. Multiple devices can circumvent the one-vote rule. For a consequential workshop, use controlled attendance and an independent facilitator cross-check; a robust single-use per-attendee voting mechanism is still required.
- No independent signed-off departmental approval aggregation; approvals are per risk. Consolidated output includes approved risk records but does not certify completeness of all departments.
- Consolidated snapshot stores a limited set of fields, not the full risk register; complete immutable report versions, including causes/controls/actions and approved assessment metadata, are not yet implemented.
- Controls have no independently authenticated testing or verified external SDBIP/KPI feed. Evidence and values are recorded and evaluated by the Risk Officer; the application does not prove their authenticity.
- Roles are coarse and record-level/department-specific permissions are incomplete. Action-owner role is not tied to individual action ownership because action owners are manual text entries.
- No secure invitation/password change/reset lifecycle or MFA; administration creates an initial password manually. Credentials need a safer provisioning workflow before real deployment.
- No automated database backups, restore exercise, hardened file scanning, rate limiting, monitoring, automated notification, offline support or fully formatted XLSX output.
- Current register UI does not match every original workbook column or fully implement all Excel-scale methodologies and departmental sign-offs.
- No independent penetration testing, POPIA/records-retention analysis, legal review or load certification.

**Readiness judgement:** Improved *restricted demonstration candidate* with **fictional/test data only**. NOT a complete, audited, production-ready municipal risk system. Do not place confidential real municipal risk evidence or real personal information on a public installation yet.

## 5. Required Afrihost acceptance run

1. Verify HTTPS, PHP >=8.2, extensions `pdo_mysql` and `fileinfo`, Apache access restrictions, and MySQL/MariaDB version.
2. Install to a new database; remove `install.php`; confirm configuration cannot be fetched over HTTP.
3. Sign in as admin; create separate Risk Officer and Manager accounts. Verify viewer cannot update actions.
4. Create strategic IDP objective, related operational SDBIP objective, department and workshop.
5. Set workshop live, register a taxonomy risk, open a voting round; use 5 distinct devices/browsers, record 1–5 impact and likelihood. Confirm average-impact × average-likelihood value.
6. Confirm an empty round cannot close, a second round cannot open for the same risk, and closed workshop cannot accept votes.
7. Record controls and first factor; assert residual = inherent × factor. Attempt factor changes without evidence: should be rejected.
8. Add action, attempt implemented without linked evidence (must fail), upload evidence and record a progress note, then mark implemented.
9. Submit the risk. Confirm a Manager can approve the completed submitted risk; attempt approve an unsubmitted or incomplete risk (must fail).
10. Upload separate effectiveness evidence, record KPI before/after and rationale, approve change via Risk Officer, verify residual recalculates and audit event appears.
11. Repeat across two departments. Confirm only approved risks enter consolidated CSV; create/download snapshot; ensure no draft leaks into exports.
12. Test workshop load, session expiration, backup restoration, HTTPS access and mobile phones before the real event.

## 6. Upgrade instructions

**For existing pilot installations only:** back up files and database first, then execute `app/migrate_1_1.sql` in your MySQL admin tool and deploy updated `public/index.php`. For fresh installations use the whole new package and **do not run** the migration separately. Never execute the full schema on an existing live database as an upgrade mechanism.
