# Architecture Regex Tools is a static browser application with framework-neutral regex boundaries. ```text React workbench ├─ Pattern SyntaxSupervisor → syntax.worker │ ├─ Regexpp ECMAScript provider → normalized AST │ └─ PCRE2 lexical provider → partial normalized structure ├─ Replacement SyntaxSupervisor → syntax.worker → typed replacement tokens ├─ EngineSupervisor │ ├─ ecmascript.worker → native RegExp → match DTOs │ └─ pcre2.worker → PCRE2 10.47 WASM ABI → match DTOs ├─ Pcre2TraceSupervisor → pcre2-trace.worker │ └─ separate ABI-v3 PCRE2_AUTO_CALLOUT operation → bounded trace DTOs ├─ AnalysisPanel │ ├─ normalized-AST ECMAScript static heuristics │ └─ AnalysisSupervisor → analysis.worker → native RegExp benchmark/growth probes ├─ ComparisonOrchestrator │ ├─ two exact syntax snapshots + independently killable engine workers │ └─ normalized UTF-16 match/capture alignment + explicit incomplete states ├─ PCRE2 C17 generator → validated snapshot → exact UTF-8 byte-array source ├─ SubjectMinimizer │ ├─ fixed syntax snapshots + exact real-engine failure or comparison oracle │ └─ deterministic Unicode-scalar reducer → bounded local-minimal result ├─ CaseGenerationOrchestrator │ ├─ generation.worker → deterministic bounded ECMAScript AST candidates │ └─ EngineSupervisor → selected actual-engine label verification ├─ ECMAScript literal/control formatter │ ├─ exact regexpp literal-token ranges → idempotent candidate preview │ └─ PatternFormatValidator → paired syntax + actual-engine workers and exact tests ├─ Corpus EngineSupervisor → sequential bounded document jobs → summaries/outputs ├─ Test SyntaxSupervisor + EngineSupervisor → isolated cancellable test runs └─ project validator / serializer / IndexedDB persistence ``` Provider AST objects never cross the worker boundary. The syntax worker emits application-owned nodes, tokens, diagnostics, capture definitions and explicit provenance. React never imports or traverses regexpp's cyclic AST. Every engine request carries a protocol version, monotonically increasing request ID and worker generation. A supervisor allows one active request, rejects stale responses, terminates on timeout/crash/cancel, and lazily creates a new generation. Timeout is a distinct error state. PCRE2 tracing is not an `EngineSupervisor` match or replacement operation. Its own worker compiles with `PCRE2_AUTO_CALLOUT`, copies only complete fixed records and bounded mark bytes, and stops natively at either trace cap. Reported callout fields retain byte positions; movement classifications are a separate derived UI layer. Normal execution, corpus, tests and benchmarks never run through the trace operation. Static analysis traverses the normalized ECMAScript tree on the UI side under node/finding caps. Timing and generated-input growth probes use the independent analysis worker. Timeout, cancellation or crash discards that worker; no trace mode is benchmarked. Comparison is a separate orchestration layer, not an `EngineSupervisor` operation. It runs explicit ECMAScript and PCRE2 syntax/execution snapshots, retains each engine identity and native range model, and aligns only normalized editor ranges. Timeout, cancellation, compile rejection and truncation remain distinct non-comparable outcomes. Shared patterns are sent unchanged; per-flavour ports are user-owned variants. The PCRE2 C generator is application-owned and never implements browser execution. It validates one exact PCRE2 snapshot, emits user strings as independent UTF-8 byte arrays, and states the host-level mappings that the PCRE2 API cannot express directly. Its advertised C17 target is protected by deterministic golden identities and an exact PCRE2 10.47 compile/execute gate. Subject minimization is a main-thread bounded reducer whose expensive predicate checks stay in independently terminable engine workers. Fixed pattern syntax is parsed once for capture metadata. The baseline and every accepted candidate retain the exact target and engine identity. Timeout, crash, cancellation, worker failure and incomplete output are separate outcomes. Deterministic ddmin deletion is followed by a fixed-point local sweep over Unicode-scalar deletion and lower-rank canonical replacement; only completion of that sweep permits a transform-local minimality claim. Generated-case synthesis and verification are separate trust boundaries. The dedicated generation worker receives only a validated, complete ECMAScript normalized tree plus explicit settings and seed. The main-thread orchestrator then sends each bounded candidate to `EngineSupervisor`; only the selected real adapter can establish a `should-match` or `should-not-match` label. Worker timeout, crash, cancellation, compile rejection, wrong outcome and ordinary failure stay distinct. Settings/results are ephemeral, while explicitly added unit tests retain field-validated generator provenance. Formatting is not an engine operation and never rewrites from heuristic text alone. The ECMAScript formatter consumes an exact accepted regexpp snapshot and changes only parser-reported literal/control token ranges. Its validator reparses source and candidate separately, preserves capture shape, runs both in separate actual-engine workers against the current replacement snapshot, then replays every enabled test tied to the exact active pattern/version/flags/options. Any difference, incomplete output, one-sided timeout, identity change or inconclusive worker outcome blocks apply. The preview and observations are ephemeral, and user confirmation is required even after all bounded gates pass. Pattern and replacement syntax use independent supervisors. A pattern snapshot is bound to its exact pattern, ordered flags and revision; execution cannot use acceptance or capture metadata from an earlier input. Replacement output is built while the native engine produces the same bounded authoritative match sequence that is returned to the UI. Per-match replacement ranges and token contributions are deterministic mappings over those actual matches, the complete replacement-token model and the bounded output. They execute no replacement callback or user code and have separate presentation and token-evaluation limits. Corpus documents are ephemeral React session state, not project state. A dedicated engine supervisor processes one document at a time and is terminated on cancellation, timeout or workspace exit. Batch orchestration retains only per-document summaries and, for apply runs, bounded outputs. It enforces document-count, per-document byte, aggregate input byte, aggregate match, aggregate output and batch wall-time limits. Exact-output export is unavailable if any document is partial, failed, cancelled or not run. Whole-document mode sends each document to the engine once. Independent-line mode segments CRLF, CR, LF, U+2028 and U+2029 without discarding them, executes each logical line as its own subject, and reattaches the exact original separator during apply. This makes anchor and cross-line behavior deliberately different rather than silently rewriting the pattern. Match DTOs are reduced to bounded per-group participation counts and samples before the next document. Native ranges are retained in the engine's declared unit. PCRE2 always uses UTF/UCP and exposes UTF-8 byte ranges; its ABI copies scalar records and names out of WebAssembly before returning and retains no code pointer. Browser editor ranges are half-open UTF-16 code-unit ranges. Reusable converters cover UTF-8 byte and Unicode code-point offsets, including invalid-boundary rejection and lone-surrogate detection. The release boundary is `dist/` plus checked-in legal/source documents. The Portal consumes the resulting immutable ZIP and never imports React source.