# 17 — Phase 1 Checklist & Status

Working tracker for [13 — Implementation Plan, Phase 1](13-implementation-plan.md).
Engineering items are DONE in this repository; three items are **external actions** that
only the business can complete — instruments for all three are ready in `tools/`.

Status date: **2026-08-05**.

---

## Exit criteria (doc 13)

| Criterion | Status | Evidence |
|---|---|---|
| Kernel API frozen and documented | ✅ Done | [16 — Kernel API](16-kernel-api.md); suite `tests/Kernel/` green |
| CI green on both dialects | ✅ Done (local + workflow) | 130 tests / SQLite + MySQL 8.0; `.github/workflows/ci.yml` runs on every PR once the repo is pushed to GitHub |
| Backup restore-tested once | ✅ Done (dev rehearsal) · 🔲 repeat on real host | See drill log below; `BackupRestoreTest` re-rehearses on every PR |
| Hosting confirmed | 🔲 **External** | Run `tools/hosting-check.php` on the candidate host — steps below |
| Arabic receipt printed from real hardware | ⛔ **Superseded by D17** (2026-08-05) | Hardware is out of our scope — the client installs the PWA on their own devices ([14 §13 D17](14-conventions.md)). Receipts render through the OS print dialog (D23); Arabic rendering is verified in the browser print preview, not on owned hardware |

Remaining Phase 1 work item: business answers ([00 §6](00-business-context.md)) — question
sheet below. Doc 13: none block starting Phase 2, but **VAT and legal invoice format must
be answered before Phase 3 ships receipts** and before Phase 6 ships invoices.

---

## 1. Hosting verification (doc 12 §12 item 1) — owner: whoever holds the hosting account

1. Upload the single file `tools/hosting-check.php` to the host (any path under the web
   root works). Edit its `HC_*` constants: a random `HC_TOKEN`, the host's MySQL
   credentials.
2. Add the cron entry in the hosting panel: `*/5 * * * * php /path/to/hosting-check.php cron`
3. Immediately: open `https://…/hosting-check.php?token=…` — PHP version, extensions,
   `mysqldump`, DB/utf8mb4, outbound HTTPS results are instant.
4. After **at least 2 days**: re-open the report — the cron heartbeat section now scores
   cron reliability (fired-late percentage, max gap).
5. Record the results here (engine + exact version matters — CI must mirror it):

| Check | Result | Date |
|---|---|---|
| PHP version | _pending_ | |
| MySQL/MariaDB engine + version | _pending_ | |
| mysqldump reachable from cron | _pending_ | |
| Outbound HTTPS (off-host push possible) | _pending_ | |
| Cron reliability over ≥ 2 days | _pending_ | |

**Doc 13 rule: if PHP < 8.2 or cron cannot dump, change the hosting plan NOW.**
Delete the file from the host when done (it reports server internals).

## 2. Hardware verification (doc 12 §12 item 2, doc 10 §9) — ⛔ SUPERSEDED

> **Superseded by decision [D17](14-conventions.md) (2026-08-05):** we have nothing to do
> with hardware. The client installs the PWA on devices of their own choosing; printing
> goes through the OS print dialog (D23). H1–H7 below are retained for reference only —
> `tools/hardware/arabic-print-test.php` stays available if a client asks about ESC/POS
> printers. Decision P3 (encryption at rest) now reads: local data protection inherits
> the client device's OS storage encryption.

Original protocol (no longer ours to run) — buy **one** full set before committing to
five: Windows PC, 80 mm thermal printer (ESC/POS), printer-driven cash drawer, UPS.

Spec notes from the docs:
- **UPS is not optional in Iraq** (doc 10 §9) — it is part of the deployment.
- **Windows edition: 10/11 Home is the supported baseline.** Nothing in the stack needs
  Pro or any specific edition, and the client UI stays a platform-free browser app
  (doc 12 C7/§3). Doc 10 §7 still requires the local database encrypted at rest —
  satisfied on Home per decision P3 below; verify it on the candidate PC (H7) before
  buying five.

Protocol (record each):

| # | Test | How | Result |
|---|---|---|---|
| H1 | Arabic text mode (firmware shaping) | `php tools/hardware/arabic-print-test.php --connector=windows:<printer> --mode=text` — try `--table` values from the printer manual | _pending_ |
| H2 | Arabic image mode (production fallback) | `--mode=image --font="C:\Windows\Fonts\arial.ttf"` (or Amiri/Noto Naskh) | _pending_ |
| H3 | Checklist on paper | joined letters, RTL order, Arabic-Indic digits, mixed AR/EN | _pending_ |
| H4 | Drawer kick | `--drawer` — drawer physically opens | _pending_ |
| H5 | Print speed | tool prints elapsed ms; end-to-end order target < 3 s (doc 10 §8) | _pending_ |
| H6 | Power-cut behaviour | print + write to a WAL SQLite file, pull mains with UPS active: PC and printer stay up; DB intact | _pending_ |
| H7 | Encryption at rest on Win Home | Settings → Privacy & Security → **Device encryption** present and ON (needs TPM 2.0 + a Microsoft account for recovery-key escrow — common on Win 11 Home). If absent: enable **VeraCrypt** system encryption and time the boot-password step against the morning-open flow | _pending_ |

**Buy the remaining four sets only after H1–H7 pass** (image mode passing is sufficient
for H1/H2 — firmware shaping is a bonus, not a requirement).

## 3. Business questions ([00 §6](00-business-context.md)) — owner: the owner

Send as one sheet; record answers here and update doc 00.

| # | Question | Why it matters / what it blocks |
|---|---|---|
| Q1 | Is the cafe operator the **same company** as the workspace operator? | If yes, tenant master data can be imported instead of re-entered (Phase 2 onboarding). |
| Q2 | Is a **printed/stamped invoice** legally required for tenant billing, in Arabic? | Invoice print design + stamping workflow (Phase 6); statement delivery defaults. |
| Q3 | Does any branch need **VAT / sales tax** on receipts? | `tax_class` on items (doc 02 §2), `tax_total` on orders, receipt layout (Phase 3) and invoice layout (Phase 6). **Most urgent.** |
| Q4 | Are salaries paid **monthly on a fixed date** for everyone, or per-employee schedules? | Payroll run grid (Phase 9). |
| Q5 | Is an owner-declared closure a **paid day** for staff? | Default already assumed **yes, configurable per closure** (doc 08 §4) — confirm. |

| # | Answer | Date | Doc updated |
|---|---|---|---|
| Q1 | _pending_ | | |
| Q2 | _pending_ | | |
| Q3 | **No — no VAT / sales tax at any branch** | 2026-08-05 | doc 00 §6 answered; `tax_class`/`tax_total` stay dormant (0); receipts and invoices carry no tax line |
| Q4 | _pending_ | | |
| Q5 | _pending_ | | |

## 4. Small platform decisions still open

| # | Decision | Options / recommendation | Status |
|---|---|---|---|
| P1 | Dead-man's-switch monitor for `DEADMAN_PING_URL` | A heartbeat-monitor service (e.g. Healthchecks.io free tier, UptimeRobot heartbeat) — must be **external to the host** | Open |
| P2 | Off-host backup destination | FTPS to a second, unrelated provider, or object storage with an HTTPS ingest endpoint; both wired in `BackupJob` | Open |
| P3 | Branch DB encryption at rest (doc 10 §7) on **Win 10/11 Home** | **Policy: OS-level encryption, zero code impact.** In order: (1) Windows **Device encryption** where the hardware supports it — Win 11 Home commonly does, TPM 2.0 being mandatory there; (2) **VeraCrypt** system encryption where it does not; (3) a Pro upgrade only if both fail on the chosen PC. SQLCipher stays avoided (custom PHP build). H7 verifies the choice on the candidate PC before buying five. | Policy set — verify via H7 |
| P4 | Branch update mechanism (doc 12 §12 item 3) | **Decided: manual install per release** until Phase 10's self-update (doc 13) | Recorded |

## 5. Engineering deliverables (all in this repo)

- ✅ Kernel: Db, Migrator, Money/CashRounding/Fx, Uuid, BusinessDay, Validator,
  Router/Request/Response, Auth/Session/RBAC/Capabilities, Audit — [16](16-kernel-api.md)
- ✅ Baseline migrations, both dialects (`migrations/central`, `migrations/branch`)
- ✅ Dual-dialect test suite; MySQL skip = failure in CI
- ✅ Sync contract v1 frozen — [15](15-sync-contract.md)
- ✅ Conventions + decision log — [14](14-conventions.md)
- ✅ CI workflow (`.github/workflows/ci.yml`) — activates on push to GitHub; branch
  protection on `main` must be enabled there (rule 11 in doc 14)
- ✅ Release pipeline: `build/release.sh` (vendor bundled) + `build/deploy-ftps.sh`
  (FTPS mirror + remote migrate + health check)
- ✅ Centre entrypoint: `GET /health`, `POST /admin/migrate` (token)
- ✅ Cron dispatcher `cron/run.php` with `backup:dump`, `migrate`
- ✅ Backup job: mysqldump → PHP-PDO fallback, retention, off-host push (FTPS/HTTPS),
  dead-man ping only on full success
- ✅ Restore drill tool `tools/restore-test.php`

## 6. Restore drill log (doc 10 §7: monthly — doc 13 cross-phase)

| Date | Dump | Method | Restored into | Result |
|---|---|---|---|---|
| 2026-08-05 | cafe-central-20260805-060620.sql.gz (1,767 B) | mysqldump via `cron/run.php backup:dump` | `cafe_restore_test` (dev MySQL 8.0.42) | ✅ 4 tables, 56 statements, row counts + Arabic content verified |

Next drill due: **2026-09-05** — against the real host once hosting is confirmed.
