--- title: "1.15.13 — The nginx map wedge heals itself; capacity resize + batch plans; MojoSec authoritative cases" description: "Heals the nginx WebSocket-map wedge introduced by 1.15.10 end to end: a wedged node repairs itself on its first deploy of this release, edge generations adapt to whichever side of the node's graph declares the map, and a live generation can never again be rewritten in place. Also ships capacity resi…" date: "2026-08-21" tags: ["release"] canonical: "https://django-mojo.sitesmojo.com/changelog/1-15-13/" --- Heals the nginx WebSocket-map wedge introduced by 1.15.10 end to end: a wedged node repairs itself on its first deploy of this release, edge generations adapt to whichever side of the node's graph declares the map, and a live generation can never again be rewritten in place. Also ships capacity resize actions with a two-phase batch plan/apply API, and MojoSec's opt-in authoritative mode that summarizes web/FIM evidence into cases instead of per-receipt events. ### Added - Capacity: `resize_cache` and `resize_database` actions on the existing apply contract — curated size ladders from the capacity report's new `sizes` block; database resizes are per named instance with the failover promotion tier riding in the same call. - Capacity: two-phase batch plan/apply — `POST /api/aws/capacity/plan` validates, orders, words and prices an ordered set of capacity actions (an unpriced type is an honest `null` plus a warning, never a silent $0); `POST /api/aws/capacity/plan/apply` confirms by `plan_id` behind a structural fleet fingerprint (409 `plan_stale`) and a single-use lock (409 `plan_already_applied`); `GET /api/aws/capacity/status` now takes `operation` XOR `batch`. Both new endpoints carry apply's full permission gate — a plan leaks intent and cost. - MojoSec: an opt-in authoritative enrollment mode routes policy-bound web observations and trusted expected-change FIM straight to summarized cases — no per-receipt event, the contribution owns the ack. Trusted deployment FIM coalesces into one case per sensor and deployment per UTC day, settling after a quiet window (new `settle_mojosec_cases` cron); promotions into high/critical project exactly one event per urgency step. - MojoSec: the case list gains `settled`/`family`/`deployment_id` filters and rows carry deployment identity; case detail adds the breakdown, `settled_at` and the projection ratchet; case metrics report settled cases and suppressed per-receipt events. - Admin fleet page: the Redis and database size dropdowns go live from the report's ladder, and the page renders the server's plan — wording, ordering and pricing all come from the server. ### Changed - Edge generation ids include the framework version, so a renderer change always stages into a fresh directory and passes the full validate → swap → revert gate. - `terminate_node` of a node a completed drain removed from every group no longer 409s `not_registered`: fresh EC2 facts must prove it a tagged fleet member — an exact project+env identity match against a registered member, or the capacity clone stamp; a generic ownership tag alone never suffices, so one environment's portal cannot terminate another environment's box. - When a MojoSec sensor is enrolled, deploy-owned writes into host config directories are journaled together with their parent directories, so routine deploy writes stop surfacing as unexplained FIM changes. ### Fixed - The nginx WebSocket-map wedge from 1.15.10: a node whose bootstrap predates the bootstrap-owned `$connection_upgrade` contract now self-heals — the deploy's nginx runtime fragment carries the map whenever nothing else in the graph declares it (and yields to any declaration elsewhere), and an edge generation probes the real `nginx -t` verdict to carry the map itself when that node needs it, flipping back automatically if the bootstrap later declares one. A node already wedged — every `nginx -T` failing, deploys and rollbacks dying at `worker user; got []` — is repaired by its first deploy of this release. - Deploy convergence failures quote nginx's own `[emerg]` line instead of the bare `got []`. - A live edge generation can no longer be rewritten in place: identical re-stages are skipped and changed bytes are refused loudly. Previously a pending retry could silently rewrite the serving directory's config — the node broke on disk with no swap to revert while nginx kept serving from memory. - The MojoSec case list 500ed on any non-empty page; datetimes nested in list payloads now serialize. ### Upgrade notes - One database migration (incident app) — the routine `migrate` on deploy covers it. - On the first upgrade, every edge node re-stages its generation once (the framework version now moves the id), and a pre-contract node may gain the `$connection_upgrade` map in the deploy-owned nginx fragment — both are one-time, validated convergences. - A node wedged by the 1.15.10 map move heals on its first deploy of this release; until that deploy lands, its rollback targets remain broken (older releases carry the same failing check).