Young's Mind
Implementation

Features to add, functions to build, and the prod server prep

Young's rulings carried: Oracle ARM 4 vCPU · 24 GB · 200 GB (this changes my earlier estimate — see sizing below) · POS payments + offline are gaps to extend · EVE beta, "we will make it work for our business" · prices in AUD.

Features to add, functions to build, and the prod server prep

Young's rulings carried: Oracle ARM 4 vCPU · 24 GB · 200 GB (this changes my earlier estimate — see sizing below) · POS payments + offline are gaps to extend · EVE beta, "we will make it work for our business" · prices in AUD.

Part 1 — What we already have vs what must be built

Tam's studies are the inventory. Nothing below is invented; each row names its source.

CapabilityStateSource
Medusa backend (server + worker, Postgres, Redis)exists — compose + shared image pipeline speccedhosting-docker-study
Next.js storefront, useEveAgent() chat UIexists (pattern verified in EVE docs)eve-integration-study
Per-tenant EVE agent: instructions.md · tools/ · connections/medusa.ts · skills/existseve-integration-study
HIL workflow gating (refund, bulk-pricing)exists as designeve-integration-study
POS: staff auth, setup wizard, barcode scan, cart → draft order, order historyexists in the Agilo forknextjs-commerce-study
POS: unified stock via sales-channel + inventory modulesexistsnextjs-commerce-study
POS paymentsGAP — must buildnextjs-commerce-study §MVP gaps
POS offline modeGAP must extend (cached browse only today)nextjs-commerce-study §MVP gaps
Tenant provisioning + tenant-key-or-metered AI overageGAP — new (Mira's pricing guardrail)business-plan

Total: 3 build items, and they are exactly the ones Young named. Everything else is assembly.

Part 2 — Feature spec: POS payments

The constraint: the Agilo POS talks to Medusa's Admin REST API over HTTPS only — no backend changes. So a payment path that FITS is needed, not a rebuilt POS.

Design: a Medusa Payment Provider, not POS surgery.

A Medusa payment module (medusa-payment-*) is a swappable provider slot — the commerce module layer integrates providers exactly as Stripe is integrated today. The POS cart already creates draft orders; adding a payment session and capturing against it is a provider module, and the POS needs only to mark the draft paid.

Scope:

  1. Payment provider module (AU-first: Stripe, later a second processor). Cart → draft order → payment session → capture. Draft-order payment is the extension point — it already exists in Medusa.
  2. Cash + EFTPOS manual path — shipped FIRST, deliberately. Agilo has "no integrated payment processing yet"; the honest MVP is tendered amount recorded against the draft order, settled outside the system, reconciled by a daily totals job. This is sellable day one and needs no gateway contract.
  3. Card, second phase. Stripe domestic; terminal integration (the Agilo roadmap item) is phase 3 and needs our own hardware decision.
  4. Reconciliation function (the part that makes it trustworthy): daily job comparing Medusa order totals vs payment captures, reporting per tenant. Without this the gap just moves from "no payments" to "unknown payments".

Aud note: Mira's plan passes card fees through (Stripe 2.9% + $0.30) at AUD pricing — so the provider must expose processor fees per transaction in the reconciliation, not buried in a payout.

Part 3 — Feature spec: POS offline mode

The constraint: Agilo is cached browse only today, and the Admin API is HTTPS-only (no API reachable without network). Offline cannot mean "full POS offline" — it means degraded POS that never loses a sale.

Design: an offline queue with a deliberate ceiling.

  1. What works offline: scanning, carting, tender recording, and a held-sale receipt with a local receipt number.
  2. What syncs: a queue in local storage (SQLite on device), replayed when the network returns, in order, idempotent on the local receipt number (an idempotency key is the difference between offline-sync and double-charging).
  3. Stock, honestly: reads come from the last successful cache; stock is marked stale in the UI with the cache timestamp. A till must not promise availability it can't check — that is a support call, not a feature.
  4. The ceiling we ship with: offline supports held sales only — they sync and complete when the network returns. It does not attempt offline payment capture. A card capture requires the network; claiming offline card payments would be a false feature.

Why a ceiling is a design decision: the failure mode here is a shop taking cash all weekend on a cached catalogue, syncing on Monday, and discovering Saturday's stock sold twice. Marking stock stale and holding sales is what makes that impossible.

Part 4 — Functions to build (engineering backlog)

#FunctionPriority
F1Tenant provisioning: compose → seed → keys → EVE agent config → health checkfirst
F2Tenant backup + restore drill, per tenant, DR tested not declaredhigh
F3AI conversation metering + per-tenant overage switch (Mira's guardrail)high
F4Manual payment path + daily reconciliation jobhigh
F5Offline queue + idempotent replay in Agilomedium
F6EVE version pin per tenant + upgrade pathhigh (EVE is beta)
F7HIL gate as a provable control — provisioning must be able to show it is armedhigh
F8Alerting: per-tenant health (/health + /eve/v1/health), failed pods, stale stockmedium
F9Connection-pooling + resource ceiling per tenant compose (noisy neighbour)medium

F7 is the one I will not compromise. HIL gating is what keeps an AI-staff tier sellable — a convention here is V2's built-never-wired defect all over again. It gets a control, a probe, and a MUST-FAIL test, or it does not ship.

Part 4b — Security functions (Echo, 2026-10-18)

The three-layer identity model ([2fa-and-account-management](2fa-and-account-management), [authelia-optimization](authelia-optimization)) adds these to the backlog. All A$0 software — the work is wiring, not licences.

#FunctionPriority
S1Enable Medusa core MFA — set AUTH_MFA_ENCRYPTION_KEY per tenant, disable_policy: challengefirst (one env var)
S2requireMfa: {maxAgeSeconds} on elevated writes — refunds, bulk-pricing (strengthens F7)high
S3Provisioning creates an invite, not a user — Medusa has no "create user with password"high
S4Authelia L1 gate: tenant private KB / staging portalshigh (Ace, ~30 min)
S5Do NOT forward-auth the tenant Medusa Admin — avoids a double MFA promptrule, not a task
S62FA enrolment + recovery-code UX (Nova's lane)medium

Two things this spec must NOT promise

  1. Staff roles / permissions. RBAC is a paid Medusa Enterprise feature, not MIT core — Medusa's ENTERPRISE-LICENSE.md lists the RBAC module, its admin APIs and its dashboard routes as proprietary. A tenant needing role separation is a licence line item for Mira, not a build task. The pilot ships with all admin users as full admins.
  2. A confirmed audit log. The 2FA doc asserted "Audit log (Medusa built-in)"; I could not find that feature in the MIT docs. Treat as unverified until someone locates the page. Authelia gives audit for L1 only.

One correction to Part 5 item 5

The firewall note says the current 8442–8448 / 9903–9906 listeners "are LAB-style loopback and must not be reachable from the public interface". That is right — but I verified on prod that no SMTP listener exists either (25/587/465 all closed), which matters because Medusa's default notification provider is Local: it logs the email and sends nothing. A tenant left on the default completes orders and silently sends no confirmation ever.

Add to the prep list: an email-delivery probe in the onboarding gate. /health and /eve/v1/health both pass while email is dead — the failure is invisible by construction. (Provider choice is Sol's; see [medusa-cloud-engineering-verification](medusa-cloud-engineering-verification) §2.)

Part 5 — Production server prep

Measured on 161.33.71.67 (Young's node), not assumed:

SurfaceMeasured
CPU / arch4 vCPU, aarch64 — ARM64 confirmed, so every image must be linux/arm64
Memory23 Gi total, ~21 Gi available
Disk193 GB, 14 GB used, 179 GB free
OS / PythonUbuntu, Python 3.12.3
DockerDocker Compose v5.4.0; docker running, no containers
edge_tts7.3.0 already installed on prod (Eva's fix's third surface is done)
Servicesnginx + pulse-site.service running
Listening8442–8448 (V3 A2A), 9903–9906, 9222, 8765

Ruling carried — sizing corrected: Young confirmed 4 vCPU / 24 GB / 200 GB. My architecture note guessed 24 GB from a study and flagged it as unmeasured. The measurement is now the authority. Per-tenant ≈ 3 GB of the 24 GB → 8 tenants on the node before any scaling decision, not 2–3.

Prep tasks:

  1. ARM64 image policy — the compose must build/pull arm64. This is the single most likely silent failure (an amd64 image on ARM fails late, looking like a config bug).
  2. Reverse proxy — nginx is live with pulse-site; add per-tenant vhosts (t<id>.ourdomain) and TLS. Routing per tenant is the front door.
  3. Resource ceilings in every compose: cpus + mem_limit per tenant so one tenant cannot eat the node (F9).
  4. Storage layout — /srv/tenants/<id>/{compose,data,bind-mounts}, Postgres volumes pinned. Backups to the 179 GB free.
  5. Firewall — only 80/443 (and 22 to our admin path) exposed; the current 8442–8448/9903–9906 listeners are LAB-style loopback and must not be reachable from the public interface on a shared commerce node.
  6. Secrets layout — per-tenant .env mode 0600, never in images or the repo (the vault's own discipline).
  7. /home/ubuntu/pulse-site stays untouched. Prod hosts Pulse today; the commerce stack lands alongside, not over.

One measured risk stated plainly: the same node hosts Pulse (prod) and would host the commerce tenants. That is one noisy neighbour away from a Pulse outage — same class of defect as V2's fleet. Pulse gets a resource ceiling and an alert before tenant #1 is provisioned.

Copyright © 2026