case-studies · 24 Oct 2026

Formatloom: a small interface with serious engineering boundaries

How browser-local processing, explicit parser limits, testing and a documented deployment path shape Formatloom.

Formatloom is a public workbench for formatting and validating JSON, converting JSON and YAML, and showing when a conversion may lose meaning. The interface is small. The engineering is not reduced to a textarea and a button because the input may contain configuration or API data that should stay close to the person using it.

This case study documents decisions evidenced by the live product and published Mirtilo IO technical notes. The implementation repository is private, so this page does not present source-code inspection as public evidence. It does not claim user growth, revenue, client outcomes or high-scale operational history.

The working method behind these boundaries is described in AI-assisted engineering: evidence over output.

Problem

Online formatters are convenient until the document contains something private or operationally sensitive. Sending that document to an unknown processing service changes the risk model before the user has received any value.

The product needed to make structured-data work quick while keeping the document in the browser. It also needed to make conversion loss visible. A tool that silently removes comments, aliases or numeric precision can produce output that looks valid while changing its meaning.

Constraints

The boundary was written before the implementation:

  • JSON/YAML processing stays in the browser.
  • There is no account system, application database, saved workspace, upload endpoint or processing API.
  • Input is limited to 1 MiB, measured again in UTF-8 before processing.
  • JSON is strict. YAML is limited to one ordinary safe document.
  • Warnings must be visible when a conversion can lose source information.
  • Analytics may receive only an allowlisted operation and outcome envelope, never document content.
  • The product must work in English and Brazilian Portuguese, across desktop, tablet and mobile layouts.

These constraints kept the first product narrow. They also made privacy, parser behaviour and release verification part of the product instead of later polish.

Architecture

Rails 8.1 provides the server-rendered shell, public routes, page metadata, privacy copy and the /up health endpoint. Turbo handles navigation and Stimulus manages the page lifecycle. TypeScript, bundled with esbuild, owns the browser behaviour and the worker protocol. Tailwind CSS 4 and Propshaft handle styles and assets.

The TypeScript Web Worker is the processing boundary. It validates the requested operation and input size, parses the document, and returns a bounded structured response with success, warning or error status. The worker does not read the DOM, storage, cookies or network state. It also ignores stale responses after a reset or navigation so an older calculation cannot overwrite newer page state.

The Rails layer remains a shell rather than a data-processing backend. There is no application database to migrate, back up or involve in document handling. Copy and download use browser APIs, and the current document remains in browser memory.

Privacy boundary

The privacy promise is visible in the interface and enforced by the contracts:

  • input, output, diagnostics and warnings stay in the current browser session;
  • the worker does not fetch, submit, store or forward the document;
  • the application does not persist the document or create a saved workspace;
  • theme and language preferences are the only values that may remain in local storage;
  • the content security policy restricts scripts, connections, workers and frames.

The result is a browser-local workbench, not a hosted document-processing service. If the optional analytics service is blocked or unavailable, the workbench keeps working.

Parser and fidelity decisions

Formatloom treats JSON as strict JSON. It rejects empty input, malformed syntax, comments and trailing commas instead of silently accepting a dialect that the output may not preserve.

YAML is deliberately narrower: one ordinary safe document. The conversion path surfaces parser diagnostics and warns about comments, anchors, aliases, duplicate keys, ordering, unsafe numbers and other features that may not survive conversion to JSON.

A warning still returns usable output. An error leaves the original input available for correction. This distinction gives the user a chance to inspect the trade-off instead of mistaking a successful parse for a faithful conversion.

Tests and verification

The repository records product specifications and contracts for the worker, data model, workbench UI and analytics envelope before the implementation details.

The automated checks cover parser behaviour, YAML fidelity warnings, worker validation, stale requests, analytics filtering, themes and localisation. Rails tests cover route and privacy boundaries. Browser system tests exercise the workflow, keyboard access, responsive layouts, reload behaviour, branding and network requests. CI also runs asset builds, RuboCop, Brakeman and Bundler Audit.

The quickstart includes a manual Network-panel check: only static assets and the configured analytics host should receive requests. That check matters because a passing unit test cannot by itself prove that a browser did not send the document elsewhere.

Accessibility

Accessibility is part of the workbench contract. Controls have accessible names, focus remains visible, status changes are announced, warnings are readable and navigable, and the workflow is usable with a keyboard. The layout is tested across desktop, tablet and mobile bands and remains usable without a wide screen.

The same constraints that protect the data also shape the interface: the user needs to understand where processing happens, what the result means and what a warning is asking them to review.

Analytics boundary

Umami is optional operational telemetry, not a second processing path. Events can describe an operation and outcome such as success, warning or error, copy or download. The adapter validates an allowlist and excludes input, output, document names, content hashes, byte lengths, session recordings, user identifiers and local correlation tokens.

The analytics contract is intentionally small. Blocking the script must not change a workbench state transition, and diagnostics and warning messages remain local.

Docker and Dokploy deployment

The production application is packaged as a multi-stage Docker image. The image compiles browser assets, starts Thruster and Puma, and runs as a non-root user. The application exposes /up as its health endpoint and does not require a database service.

The live service runs at formatloom.mirtilo.io on a VPS managed through Dokploy. The image is published to GitHub Container Registry and deployed behind an HTTPS proxy. The repository also contains a Kamal configuration for the same Docker/VPS shape; the active deployment uses Dokploy.

This is a small deployment shape by design: one application container, no document-processing service and no application database. The operational boundary stays proportional to the product.

Limitations and next decisions

Formatloom has no accounts, saved workspaces, batch processing, public processing API or team features. The product is free. JSON-to-CSV conversion and structured diff are possible next directions, but they are hypotheses, not committed scope.

There is no evidence here for user count, revenue, client impact, high-scale incident management, SLOs, advanced observability or executed production rollback exercises. Those claims need separate records and will not be inferred from a live URL or a green test suite.

The next decision is therefore demand-led: keep the boundary stable, inspect verified usage and release evidence, and add only a workflow that justifies its new privacy and maintenance cost.

Sources