# RentalDriveGo — Plan to Reach Production Ready **Purpose of this document:** This is the **execution plan to take the current codebase to production ready**. It is not a feature roadmap and not an architecture rewrite. Success is measured only by the definition in §1 and the checkpoint in §13. **Status:** Phases 0–4 **application code / runbooks complete** (12 Aug 2026). Remaining work is **ops evidence** (CI smoke, restore/alert drills, pen-test, soak) — not missing features. Phase 4 correctly does **not** extract microservices (ADR-003). **Code root:** `D:\1\management` **Last re-verified against source:** 12 Aug 2026 (Phases 0–4 code pass) **Inputs:** Live repo state + *Technical Architecture & Investor Due Diligence* (v1.0, 9 Aug 2026) + prior hardening reports under `docs/` **Architecture decision:** Keep the modular monolith. Do not split services until Phase 3 load/ownership evidence justifies it. ### How this plan works ```mermaid flowchart TD now[Current_beta_pre_scale] --> sec[Close_security_P0] sec --> p0[Finish_Phase0_evidence] p0 --> p1[Phase1_replica_safe] p1 --> p2[Phase2_operate_recover] p2 --> p3[Phase3_prove_under_load] p3 --> prod[Production_ready_gate] ``` | Stage | Outcome | |-------|---------| | Security P0 + Phase 0 close | Safe enough to run a controlled environment; envelope proven | | Phase 1 | Safe to run **two API replicas** + worker | | Phase 2 | Operable: observe, backup/restore, commercial/privacy baselines | | Phase 3 + §13 checklist | **Production ready** — claims allowed only after exit evidence | --- ## 1. Definition of “production ready” (the finish line) The project is **production ready** only when all of the following are true and evidenced: 1. Install, generate, lint, type-check, test, and build from a clean checkout 2. Deploy a known topology (API, frontends, PostgreSQL, Redis, storage, worker) 3. Run **two API replicas** without duplicate bookings, duplicate cron side effects, or missing files 4. Deliver notifications that were written to the outbox (email + realtime) without multi-replica double-send 5. Detect failure, restore data within agreed RPO/RTO, and show no unresolved critical/high dependency vulnerabilities outside a dated exception 6. Ship with Critical/High application-security findings closed (§3) 7. §13 diligence checkpoint items are checked off with retained evidence Until then, the accurate label remains **capable beta / pre-scale**, not production SaaS. **Out of scope for this plan:** new marketplace features, KYC/OCR, per-tenant Docker isolation, microservices rewrite, marketing-only work. ### Why this path > The core product and data architecture exist; the next milestone is to convert that breadth into a reproducible, secure, observable, horizontally safe production system. --- ## 2. Current state (re-verified after project update) ### 2.1 Progress since the original diligence snapshot | Area | Previous gap | Status now | Evidence | |------|--------------|------------|----------| | Turbo pipeline | Missing | **Done** | `turbo.json` (build/dev/lint/type-check/db:*) | | Shared TS base | Missing | **Done** | `tsconfig.base.json` | | Scripts / ops helpers | Missing | **Done** | `scripts/` (env, docker-prod-*, admin, `security-static-check.mjs`, backup guides) | | Compose / Docker | Missing | **Done** | `docker-compose.dev.yml`, `docker-compose.production.yml`, `Dockerfile.dev` / `.production` / `.test`, `production/` mirror | | `.gitignore` | Missing | **Done** | Root `.gitignore` | | Static security script | Missing | **Done** | `scripts/security-static-check.mjs` + `npm run security:static` | | CI | No workflows | **Partial** | `.gitea/workflows/` (`test.yml`, `build-and-deploy.yml`) + `.gitlab-ci.yml`; **no** `.github/workflows` | | Notification outbox consumer | Missing | **Partial** | `processNotificationOutbox()` in `notificationService.ts`; cron every minute in `apps/api/src/index.ts` — still **inside the API process**; email/IN_APP delivery + DLQ; **no** `redis.publish` for realtime | | Prior hardening passes | — | **Documented** | `SECURITY_HARDENING_APPLIED_REPORT.md`, leftover report, `docs/SECURITY_HARDENING_*` (June 2026) — API-key hash-only, Socket.IO actor verify, cookie session work, etc. | ### 2.2 What remains strong | Area | Evidence | |------|----------| | Product surfaces | `apps/homepage`, `dashboard`, `admin`, `carplace`, `api` | | Domain depth | Prisma: fleet, reservations, billing, payments, notifications, collections, admin | | API shape | Express modular monolith | | Auth / tenancy | JWT actors, HttpOnly cookies, admin 2FA, company middleware, subscription gates | | Payments foundation | Manual bank transfer and check for subscription and rental billing; `WebhookEvent` retained for other inbound webhooks | | Upload validation | Magic bytes + MIME + size limits | | Deploy intent | Compose + Traefik configs, backup/restore scripts present | ### 2.3 What still blocks a production claim | Priority | Gap | Repo evidence (current) | |----------|-----|-------------------------| | **P0** | App security Critical/High still open | Team API spreads `passwordHash` / reset tokens; plaintext invite tokens; open redirect; unrestricted payment return URLs on authenticated checkout; admin presenter scrub incomplete; container Docker-socket design still in tree — see **§3** | | **P0** | Ghost / dangerous container feature | `containerService.ts` + `apps/admin/.../containers/page.tsx` still present | | **P0** | Dependency SCA not freshly proven | Diligence (9 Aug): 21 prod vulns; must re-run on CI/clean runner | | **P0** | Phase 0 exit not fully evidenced | Envelope files exist, but clean-runner green CI + container removal + SCA gate not closed | | **P1** | Outbox not multi-replica safe | Processor runs via `node-cron` in every API process; no lease/lock; no Redis realtime publish | | **P1** | Process-local coordination | In-memory `express-rate-limit`; Carplace `idempotencyCache` `Map`; all crons in API `index.ts` | | **P1** | Local file storage | `FILE_STORAGE_ROOT` disk — no S3/MinIO adapter found | | **P1** | Ops blind spots | Only `GET /health`; no `/ready`; no `SIGTERM` graceful shutdown | | **P1** | Catalog drift | Homepage pricing vs shared plan/entitlement constants (unchanged risk) | ```mermaid flowchart LR subgraph done [Restored_envelope] Turbo[turbo_tsconfig] Compose[compose_Dockerfiles] Scripts[scripts_security_static] Gitignore[gitignore] end subgraph open [Still_open] Sec[App_security_Critical_High] Containers[containerService_UI] Shared[Redis_rate_limit_idempotency] Worker[Separate_worker_lease] Ready[ready_shutdown_object_store] end done --> open ``` --- ## 3. Security assessment (re-checked 12 Aug 2026 after update) **Scope:** Static re-verification of findings from the earlier application review against current source. **Not in this pass:** Live pen-test, production secrets rotation, successful live `npm audit` (registry TLS may still block local runs). ### 3.1 Controls that remain solid | Control | Evidence | |---------|----------| | Tenant scoping on core CRUD | Company routes use session `companyId` | | JWT from env + HS256 pinned | `security/tokens.ts` | | Session cookies HttpOnly / Secure / SameSite | `sessionCookies.ts` | | Hashed company API keys (legacy plaintext removed) | Hardening reports + schema | | Upload magic-byte validation | `http/upload` | | Payment webhook signatures | Online payment webhooks removed; remaining webhooks still verify signatures | | Forwarded-header scrubbing by default | `sanitizeForwardedHeaders` unless `TRUSTED_FORWARD_HEADERS=true` | | Site payment redirect allowlist | `assertAllowedPaymentRedirect` in `site.service.ts` | ### 3.2 Findings status after project update | Sev | ID | Status | Location | Finding | |-----|----|--------|----------|---------| | Critical | S1 | **FIXED (Phase 0)** | `teamService.ts` | Team list/invite use safe presenter; no hash/token leakage | | Critical | S2 | **FIXED (Phase 0)** | `containerService.ts` + admin containers page + ADR-001 | Feature disabled / fail-closed; UI shows out-of-scope | | High | S3 | **FIXED (Phase 0)** | `teamService.ts` invite | Invite token stored as SHA-256 hash | | High | S4 | **FIXED (Phase 0)** | Prisma `Employee` + auth repo | `@@unique([companyId, email])`; login fails closed on ambiguity | | High | S5 | **FIXED (Phase 0)** | `SignInForm.tsx` | Safe relative-path redirect only | | High | S6 | **FIXED (Phase 0)** | `paymentRedirects.ts` + payment/subscription services | Authenticated checkout allowlists return URLs | | High | S7 | **FIXED (Phase 0)** | `admin.schemas` / `admin.repo` | Slug regex + slugify on update | | High | S8 | **FIXED (Phase 0)** | `admin.presenter.ts` | Strips reset/verification secrets | | High | S9 | **FIXED (docs + default scrub)** | `forwardedHeaders.ts` + `docs/ops/proxy-trust.md` | Default scrub; TRUSTED_FORWARD_HEADERS documented | | Medium | S10 | **FIXED (Phase 0)** | employee/admin reset repos | Hash-only reset token lookup | | Medium | S11 | **FIXED (Phase 3)** | reservation/review presenters | `reviewToken` omitted from API JSON | | Medium | S12 | **FIXED** | `site.repo` / `site.service` | Public booking token unused-only on payment consume | | Medium | S13 | **FIXED** | `requireFreshAdmin2FA` | Max-age TTL (`ADMIN_FRESH_2FA_MAX_AGE_MS`, default 30m) | | Medium | S14 | **FIXED** | `.gitignore` | Present | | Medium | S15 | **FIXED** | `scripts/security-static-check.mjs` | Present; CI wired; local pass after env scrub | ### 3.3 Dependency / SCA status | Check | Result | |-------|--------| | Diligence SCA (9 Aug 2026) | 21 production findings: 1 critical, 14 high, 5 moderate, 1 low | | Local re-audit | May fail on TLS to registry — **do not treat as clean** | | Required | CI/clean-runner `npm audit --omit=dev` (or OSV) with fail-on critical/high | ### 3.4 Security remediations (ordered) **P0 — before any production traffic** 1. **S1:** Explicit safe select/presenter for team APIs — never return hashes/tokens 2. **S3:** Hash invite tokens at rest; remove raw dual-match after migration (**S10**) 3. **S8:** Expand admin presenter denylist 4. **S2:** Remove/disable `containerService` + admin containers UI from GA 5. **S14/S15:** Already fixed — keep in CI 6. Re-run and clear dependency critical/high **P1 — before multi-user GA** 7. **S4:** `@@unique([companyId, email])` + fail-closed login 8. **S5:** Allowlist relative same-origin post-login redirects 9. **S6:** Apply payment redirect allowlist to authenticated checkout/subscription 10. **S7:** Slugify/validate admin slug updates 11. **S9:** Document proxy trust; never enable trusted forwards without edge scrubbing 12. **S11–S13:** Hide review tokens; single-use public access; align fresh 2FA on money mutations ### 3.5 Security exit criteria - [ ] No API response includes password hashes, TOTP secrets, or raw reset/invite tokens - [ ] Invite/reset tokens hashed at rest; legacy raw match removed - [ ] Container/Docker-socket feature absent from production scope - [ ] Login redirect and payment return URLs allowlisted on all checkout paths - [ ] Employee email uniqueness (or fail-closed login) enforced - [ ] CI runs `security:static` + SCA; no unresolved critical/high outside dated exception - [ ] Independent pen-test after deploy envelope proven (Phase 3) --- ## 4. Guiding principles 1. **Evidence over claims** — Phase exit criteria must be demonstrable. 2. **Close Critical/High security before scale work** — Envelope restore is largely done; app-sec P0 is now the front of the queue. 3. **Shared state before more replicas** — Redis/DB/object storage before scaling API. 4. **One worker plane** — Notifications and scheduled jobs must not run identically on every API replica. 5. **Disable incomplete privileged features** — Especially Docker-socket container management. 6. **One commercial source of truth** — Marketing, checkout, and enforcement share typed entitlements. 7. **Extract services last** — Only after measurement. --- ## 5. Phase 0 — Evidence recovery **Goal:** Reproducible build/deploy envelope + security hygiene baseline. **Update:** Core files are **restored**. Remaining work is **prove + close security/container/SCA**. ### 5.1 Build orchestration — DONE | Deliverable | Status | |-------------|--------| | `turbo.json` | Present | | `tsconfig.base.json` | Present | | `scripts/` (env, docker-prod, admin, security-static) | Present | ### 5.2 Runtime topology — DONE (files present) | Deliverable | Status | |-------------|--------| | `docker-compose.dev.yml` / `.production.yml` | Present | | `Dockerfile.dev` / `.production` / `.test` | Present | | Env examples | Present (`.env.example`, docker env samples) | | Backup/restore scripts | Present under `scripts/` | **Still required as evidence:** recorded smoke that Compose boots API + Postgres + Redis and `/health` succeeds on a clean machine. ### 5.3 Continuous integration — PARTIAL | Deliverable | Status | |-------------|--------| | Gitea workflows | Present (`.gitea/workflows/test.yml`, `build-and-deploy.yml`) | | GitLab CI | Present (`.gitlab-ci.yml`) | | GitHub Actions | Not present (optional if Gitea/GitLab is the system of record) | | Proven green run + SCA fail gate | **Not evidenced in this review** | ### 5.4 Ghost container control plane — NOT DONE | Action | Status | |--------|--------| | Remove admin containers UI | **Still present** | | Quarantine/delete `containerService.ts` | **Still present** | | ADR: out of GA | Missing | ### 5.5 Dependency hygiene — NOT EVIDENCED Must re-run SCA on CI and clear critical/high. ### Phase 0 exit criteria (updated checkboxes) - [x] `turbo.json` + `tsconfig.base.json` + `scripts/` present in tree - [x] Compose + Dockerfiles present in tree - [x] `.gitignore` + `security:static` present - [x] Team API no longer returns password hashes / reset tokens; invite tokens hashed at rest (**S1/S3**) - [x] Admin presenter scrubs reset/verification secrets (**S8**) - [x] Container orchestration disabled + ADR (`docs/ADR-001-disable-per-tenant-containers.md`) (**S2**) - [x] Login redirect allowlisted; authenticated payment return URLs allowlisted; admin slug validated; employee `(companyId, email)` unique (**S4–S7**) - [x] Env example/dev templates scrubbed of real-looking secrets; `security:static` passes locally - [x] Gitea CI includes `security:static` + `npm audit --omit=dev --audit-level=high` - [ ] Fresh clone: `npm ci` → generate → lint → type-check → test → build with no local repair (needs recorded evidence on a clean runner) - [ ] CI green on default branch with SCA policy (push/run evidence) - [ ] Compose smoke: API + Postgres + Redis; `/health` ok (recorded) - [ ] No unresolved critical/high vulns outside dated exceptions (await CI audit result) --- ## 6. Phase 1 — Correctness and shared state **Goal:** Two API replicas + one dedicated worker are correct under retries and failover. **Status (12 Aug 2026):** Core code landed. Still needs `npm ci`, migrate, and a two-replica Compose smoke for exit evidence. ### 6.1 Notification outbox — DONE in code | Piece | Status | |-------|--------| | Process isolation | `apps/api/src/workers/index.ts` + Compose `api-worker`; API jobs only if `ENABLE_EMBEDDED_JOBS=true` | | Leasing | `lockedAt` / `lockedBy` / `attempts` / `availableAt` + claim via `updateMany` | | Realtime | `redis.publish('notifications:' + userId, …)` on IN_APP delivery | | Metrics | Phase 2 `/metrics` + outbox counters (scrape/alerts still open) | ### 6.2 Shared rate limiting — DONE in code Redis store in `redisRateLimitStore.ts` (memory when `NODE_ENV=test` or `RATE_LIMIT_STORE=memory`). ### 6.3 Durable booking idempotency — DONE in code `idempotencyStore.ts` (Redis; memory in test) used by Carplace `/reservations`. ### 6.4 Externalize scheduled work — DONE in code Cron moved to `workers/jobs.ts` with Redis leader lock. API no longer starts cron by default. ### 6.5 Object storage — DONE in code (optional) `FILE_STORAGE_DRIVER=local|s3` + `@aws-sdk/client-s3` + MinIO Compose profile `storage`. Default remains local disk. ### 6.6 Readiness and graceful shutdown — DONE in code | Item | Status | |------|--------| | `GET /health` | Liveness | | `GET /ready` | DB + Redis + storage probes | | `SIGTERM` drain | API + worker close HTTP/Socket/Redis/Prisma | ### Phase 1 exit criteria - [x] Worker entrypoint + outbox lease + Redis publish implemented - [x] Redis rate limits + durable Carplace idempotency implemented - [x] Cron externalized with leader lock; `/ready` + graceful shutdown implemented - [x] S3/MinIO adapter + Compose worker/MinIO services present - [ ] Two API replicas + one worker: recorded concurrency/retry smoke (needs runner) - [ ] Outbox no double-send under two API replicas (API without embedded jobs) - [ ] Files readable across replicas when `FILE_STORAGE_DRIVER=s3` (optional smoke) --- ## 7. Phase 2 — Operational control **Code baselines landed (2026-08):** metrics/logs endpoint, plan catalog + tests, OpenAPI coverage gate, backup smoke check, privacy + billing/notification source-of-truth docs. Remaining work is **evidence** (drills, owners, alerts). | Item | Status | Location | |------|--------|----------| | Structured JSON access logs + `/metrics` (latency, status, outbox) | **In code** | `apps/api/src/lib/opsMetrics.ts`, `app.ts`, worker | | Readiness `/ready` | **In code** (Phase 1) | DB / Redis / storage | | Plan/entitlement catalog + contract tests | **In code** | `packages/types/src/planCatalog.ts`, homepage pricing import | | OpenAPI completeness gate | **In code** | `npm run openapi:coverage` → `scripts/check-openapi-coverage.mjs` | | Backup artifact smoke check + RPO/RTO checklist | **In code / docs** | `scripts/backup-restore-smoke-check.sh`, `scripts/backup-restore-guide.md` | | Privacy data map | **Doc baseline** | `docs/PRIVACY_DATA_MAP.md` (owners / DSAR still open) | | Billing & notification SoT | **Doc baseline** | `docs/BILLING_NOTIFICATION_SOURCE_OF_TRUTH.md` | | Staging alert + restore drill evidence | **Open** | Ops exercise | | Provider reconciliation sample | **Open** | Finance / eng | ### Phase 2 exit criteria - [ ] Staging incident detectable and recoverable via runbooks (metrics scraped + alert fired once) - [ ] Restore exercise meets RPO/RTO (dated drill using backup smoke check) - [ ] Provider reconciliation sample exists - [x] Plan catalog single-sourced with tests - [x] Privacy data map drafted (assign legal/ops owners before GA) - [x] OpenAPI coverage script in CI - [x] Billing/notification source-of-truth documented --- ## 8. Phase 3 — Scale and assurance **Goal:** Prove the system holds under load/failure, tenant isolation, independent security testing, and operable release/secret drills. Keep the modular monolith until measurement says otherwise (ADR-002 defers RLS). **Code / runbook baselines landed (2026-08):** | Item | Status | Location | |------|--------|----------| | Cross-tenant negative suite | **In code** | `apps/api/src/tests/integration/cross-tenant-isolation.test.ts` | | S11 reviewToken scrubbed from API payloads | **FIXED** | reservation presenter + review service presenters | | Soak / load probe (+ optional k6) | **In code** | `scripts/load/soak-probe.mjs`, `booking-smoke.k6.js` → `npm run test:soak` | | Failure injection helper | **In code** | `scripts/chaos/failure-injection.sh` | | Canary / rollback runbook | **Doc** | `docs/ops/canary-rollback.md` | | Key rotation drill | **Doc** | `docs/ops/key-rotation-drill.md` | | Pen-test scope pack | **Doc** | `docs/security/pen-test-scope.md` | | Postgres RLS | **Deferred** | `docs/ADR-002-defer-postgres-rls.md` | ### Phase 3 exit criteria - [ ] Soak + failure-injection drill completed on staging with dated metrics evidence - [x] Cross-tenant suite green in CI (`cross-tenant-isolation`) — **code landed**; CI run is evidence - [ ] Independent pen-test report in `security-reports/`; Critical/High closed or accepted - [ ] Canary promote **or** rollback drill recorded once - [ ] Key rotation drill recorded on staging - [x] App-level isolation suite started; RLS deferred per ADR-002 - [x] S11 review tokens not returned in reservation/review JSON - [x] S12 single-use public payment token consume - [x] S13 fresh admin 2FA TTL ### Phase 4 (months 3–6) — extract only if measured **Default:** stay on the modular monolith + `api-worker` (ADR-003). Phase 4 is **not** a microservices rewrite. | Item | Status | Location | |------|--------|----------| | Extraction policy ADR | **Accepted** | `docs/ADR-003-defer-service-extraction.md` | | Gates G1–G7 + candidates | **Doc** | `docs/ops/phase4-extraction-gates.md` | | Measurement template | **Doc** | `docs/ops/phase4-measurement-template.md` | | Module seam map | **Doc** | `docs/ops/phase4-module-boundaries.md` | | Actual service split | **Blocked** until a candidate passes G1–G7 | — | #### Phase 4 exit criteria (for *deciding*, not for “having microservices”) - [x] Extraction gates and candidates documented - [x] In-monolith-first alternatives listed (scale workers, async media, thin webhooks) - [ ] At least one soak/profile attribution packaged with the measurement template (needs Phase 3 evidence) - [ ] Explicit decision recorded per candidate: **do not extract** (default) or approved extract ADR Candidates if gates ever pass: payments/webhooks, notification worker as independent deployable, media processing. --- ## 9. Risk register → plan mapping | ID | Risk | Status | Addressed by | |----|------|--------|--------------| | R1 | Unreproducible package | **Mostly mitigated** (files restored; prove CI smoke) | Phase 0 evidence | | R2 | Dependency vulnerabilities | **Open** (CI policy; clear on runner) | Phase 0.5 / CI SCA | | R3 | Privileged container feature | **Mitigated in code** (ADR-001) | Phase 0.4 + **S2** | | R4 | Outbox not dispatched | **Mitigated in code** (worker + leases) | Phase 1.1 | | R5 | Process-local rate limit / idempotency | **Mitigated in code** (Redis stores) | Phase 1.2–1.3 | | R6 | Embedded schedules | **Mitigated in code** (worker + lock) | Phase 1.4 | | R7 | Local file persistence | **Mitigated in code** (S3 driver) | Phase 1.5 | | R8 | Ops blind spots | **Partial** (metrics/logs in code; alerts/drills open) | Phase 1.6 + Phase 2 | | R9–R14 | Privacy, catalog, OpenAPI, legacy overlap, FE drift, flaky tests | **Partial / later** (catalog, OpenAPI gate, privacy map, SoT docs) | Phase 2–3 | | **S1–S8** | App security Critical/High | **Fixed in code** (S9 documented) | §3 P0/P1 | | **S10–S15** | Medium app security | **Fixed in code** (S11–S13 included) | Hardening + Phase 3 | | **S16–S21** | Medium/Low (undefined IDs) | **Track in pen-test** | Phase 3 evidence | --- ## 10. Suggested ownership and evidence log | Field | Example | |-------|---------| | Phase | 0 / Security P0 | | Date | YYYY-MM-DD | | Commit / tag | `prod-ready-phase0` | | Commands | `npm ci && npm run type-check && npm run security:static && npm audit --omit=dev` | | Artifacts | CI URL, Compose smoke logs, audit report | | Exceptions | CVE-xxxx until DATE by OWNER | | Sign-off | Eng lead | --- ## 11. Explicit non-goals (until gates pass) - Claiming production ready / HA / horizontally scaled before security P0 + Phase 1 exit evidence - Shipping per-tenant container orchestration - Guaranteeing SMS/push without provider paths + worker proof - Marketing KYC / license authenticity beyond date/expiry validation - Splitting the monolith for its own sake --- ## 12. Next backlog (when implementation resumes) **Immediate (security + Phase 0 close)** 1. Fix team API secret leakage (**S1**); hash invite tokens (**S3**); scrub admin presenter (**S8**) 2. Remove/disable `containerService` + admin containers UI (**S2**) 3. Allowlist login redirect (**S5**) and authenticated payment return URLs (**S6**); slugify admin slugs (**S7**); employee email uniqueness (**S4**) 4. Record clean-runner CI green + production SCA clear/critical policy 5. Record Compose smoke evidence **Then Phase 1** 6. Move outbox + cron to dedicated worker with leases; add Redis publish for realtime 7. Redis rate-limit store; durable Carplace idempotency 8. Object storage (MinIO/S3); `/ready` + graceful shutdown **Then Phase 2–3** 9. Observability, restore drill, catalog convergence, privacy map (Phase 2 evidence still open) 10. Soak/failure drills, cross-tenant CI green, pen-test report, canary + key-rotation evidence (Phase 3) **Then Phase 4 (only if measured)** 11. Fill `docs/ops/phase4-measurement-template.md` from Phase 3 soak data; default decision remains **do not extract** (ADR-003) --- ## 13. Diligence checkpoint (definition of done) 1. Clean checkout builds/tests on documented Node/npm with no local repair 2. Production SCA has no unresolved critical/high outside formal exception 3. Two API replicas pass booking/payment/job/notification/file correctness with shared coordination 4. Authoritative API contract + auth test matrix 5. Restore exercise meets RPO/RTO 6. Logs/metrics/alerts/runbooks demonstrated in a failure exercise 7. Privacy controls cover classification, encryption plan, retention, privileged reads/exports, incident response 8. Plan catalog / checkout / entitlements single-sourced 9. Independent security testing closes critical/high or records explicit acceptance 10. **§3 Critical/High application findings closed** --- ## 14. Thesis and kickoff **This plan is how RentalDriveGo gets to production ready.** The monorepo envelope is largely restored; the remaining path is: close Critical/High app security → finish Phase 0 evidence → replica-safe Phase 1 → operate/recover Phase 2 → prove Phase 3 → pass §13. **When implementation starts**, execute §12 in order. Do not skip security P0 for feature work. Do not claim production ready until §1 and §13 are evidenced. --- *End of production-readiness plan. Code root: `D:\1\management`. Companion diligence: `RentalDriveGo_Technical_Architecture_and_Investor_Due_Diligence.docx`. Re-verified: 12 Aug 2026.*