Tracy evaluation
Outcome
Do not adopt Tracy. The current stack remains because Tracy would overlap with Whoops and PHPDebugBar, would not replace Clockwork/Monolog/GlitchTip, and registers competing global handlers. ADR 0006 records the decision.
Current responsibility inventory
| Component | Authoritative responsibility | Hook and production state |
|---|---|---|
| Symfony ErrorHandler | PHP error bootstrap | Registered first; debug/production selected by APP_DEBUG |
| Laminas Stratigility ErrorHandler | Outermost PSR-15 HTTP exception boundary | Produces safe HTML or Problem+JSON and incident IDs |
| Whoops | Development exception visualization only | Called by ErrorResponseGenerator; never registered globally |
| PHPDebugBar | In-page HTML bar and AJAX/JSON debug headers | Debug-only middleware; receives sanitized lifecycle snapshots |
| Clockwork | Persisted request timeline, Monolog, DBAL queries, browser tooling | Debug-only PSR-15 middleware and bridge |
| Monolog | Persistent structured application/worker logs | Active independently from browser tooling |
| GlitchTip | Sanitized remote production error reporting | Process-env opt-in; no default PII/request body |
Application code writes through DebugLogger and HttpDebugTracer, not through
a vendor collector. Header/cookie/body snapshots have bounded depth and length;
known authorization, cookie, password, token, API-key, and secret keys are
redacted centrally.
Disposable spike
Tracy 2.12.0 was installed only under /tmp with its own lock/vendor directory;
the project manifest and lock were not modified. Reproduce with any disposable
Tracy autoloader:
php tools/benchmarks/tracy-spike.php /tmp/tracy-spike/vendor/autoload.php
Environment and five-run result on 2026-08-21:
| Probe | Result |
|---|---|
| PHP / Tracy | 8.5.9 / 2.12.0 |
Live memory delta after Debugger::enable(Production) |
1,302,376 bytes |
| Peak memory delta | 1,413,840 bytes |
| Registers global error handler | Yes (Closure) |
Configured keysToHide dump redaction |
Synthetic secret hidden |
Default structured Debugger::log() redaction |
Synthetic secret remained |
| Root dependency/bootstrap after spike | Absent |
The memory number is a narrow initialization measurement, not a full request benchmark, and is not the rejection reason by itself. Handler ownership, feature replacement, and privacy parity are the controlling gates.
Scenario comparison
| Scenario | Current stack | Tracy 2.12.0 | Finding |
|---|---|---|---|
| HTML exception | Safe production page; Whoops detail in debug; incident correlation | BlueScreen/development detail and production strategy | Could replace Whoops, but not the PSR-15 incident contract |
| AJAX/JSON | RFC 7807 response plus opt-in DebugBar headers and Clockwork record | AJAX-aware diagnostics | Needs a new PSR-7/Problem+JSON adapter; no measured gain |
| Handled exception | Laminas listener logs, traces, reports and preserves response semantics | Global exception strategy | Competes with the authoritative HTTP boundary |
| CLI exception | Symfony Console rendering, Monolog; GlitchTip bootstrap present | CLI-friendly text/BlueScreen logging | Better local presentation alone does not close the known remote CLI-capture hook gap |
| database query | Clockwork DBAL datasource, including cached test connections | Core Tracy has no project DBAL collector; addons/integration required | Does not replace current coverage |
| Sensitive-value redaction | Central recursive/bounded HTTP and GlitchTip sanitizers | Dump keys configurable; default log spike retained the synthetic value | Weaker safe default for current usage |
| Streaming/async | Debug middleware is gated and can be bypassed; workers log without HTML injection | Bar/BlueScreen depend on global process/output behavior | No improvement; long-lived workers need explicit reset semantics |
| Production monitoring | Monolog + remote GlitchTip release/environment/incident IDs | Local production log/error strategy | Does not replace remote monitoring |
| Windows | Existing browser tools and Whoops are pure PHP; worker signal caveat documented | PHP 8.2–8.5 supported, pure PHP | Compatible, no differentiating benefit |
| CSP | Current delivery still needs a complete future policy | Tracy documents nonce/strict-dynamic and requires inline styles |
Not a path to a stricter policy |
Validation
The comparison reused the current HTML, AJAX/JSON, exception, lifecycle, redaction, and production reporter unit suites. The architecture contract proves that rejected Tracy code leaves neither a dependency nor a bootstrap reference. There is exactly one global error-handler owner; do not enable Tracy beside it.