--- title: "1.3.0 — The edge app, and per-checkout test isolation" description: "Adds `mojo.apps.edge` — nginx vhosts as structured rows with a node-side installer that validates against the real config before an atomic swap — and `testit.testenv`, which derives a database, Redis index and port from the checkout path so two working copies can run their suites concurrently. Minor…" date: "2026-08-06" tags: ["release"] canonical: "https://django-mojo.sitesmojo.com/changelog/1-3-0/" --- Adds `mojo.apps.edge` — nginx vhosts as structured rows with a node-side installer that validates against the real config before an atomic swap — and `testit.testenv`, which derives a database, Redis index and port from the checkout path so two working copies can run their suites concurrently. Minor rather than patch because it adds an installable app and a new module. ### Added - **`mojo.apps.edge`** — a new installable app. Vhosts and upstreams are rows, not free-text nginx snippets. - Node-side installer stages a complete generation, pre-filters it, then validates against the real nginx config before an atomic swap. The previous generation is retained, so a bad release reverts by moving a symlink. - Web app releases: register, promote, roll back. A rollback is a pointer change, not a re-download. - New REST surface and one new protected permission, `edge_node`. - **`testit.testenv`** — per-checkout test isolation. Database name, Redis index and dev-server port are derived from the checkout's path. - aws-check: load-balancer discovery, certificate-expiry alarming fed by a dnsman publisher, and a DNS section for dnsman bootstrap. - GuardDuty findings ingested from SNS into incident events, with a lifecycle model. - Permission-safe metrics discovery, with a documented catalog. - Tenant ACME delegation and a downstream ACME hub client. - fileman: AWS credential masking with AssumeRole support. ### Changed - Two worktrees can now run test suites at the same time without truncating and flushing each other. Verified with two full suites overlapping for 131 seconds, both green. - Hardened S3 bucket operations; bootstrap now sets the bucket region and preserves mutation evidence. ### Upgrade notes Each worktree needs its own setup, and a deleted worktree should be pruned so its Redis index returns to the pool — indexes are a scarce, machine-wide resource. Ninety-two changes since 1.2.71.