Problem reporting boundary
Daemon problem reporting boundary
Problem reporting is a core-owned licensing transport because customers do not install the
operator's licensing plugin. Its contract is src/licence/contract.ts: codes follow the open
subsystem.event grammar (PROBLEM_CODE_RE) rather than a closed enum, so a newer core with new codes
never has its batches rejected by an older licensing server; the server describes the codes it knows
and shows any other code verbatim. Core still emits only code-defined identifiers. Core-side emitters are checked against the closed PROBLEM_CODES catalog (src/licence/contract.ts:90, src/problems/service.ts:17-18), and the wire grammar also admits unclassified for batches from older cores (src/licence/contract.ts:206-208).
The operator plugin owns the receiver, three additive migration-4 tables, receipt-day aggregation,
catalog identity projection and 14-day retention. Core declares that window as PROBLEM_LIMITS.retentionMs (src/licence/contract.ts:211), but no core code reads it; the receiver enforces it.
Core sends the active licence token as a Bearer credential, read at send time through the live licence state (src/daemon/bootstrap.ts:264-269), in one request with a 15-second deadline and no redirects (src/licence/reports.ts:8-10). Core verifies the licence offline with its embedded public key (src/daemon/main.ts:113); checking the report credential is the receiver's job.
Only redacted daemon warning/error samples enter this path. Only the daemon installs the log sink (src/daemon/bootstrap.ts:150), so no agent, runner or web log text does.
Elowen is a TypeScript daemon with a Next.js web application. The daemon owns the brain, persistence, plugin registry, platform adapters, and authorization decisions. The web process presents those capabilities and proxies browser requests; it is not a second brain.
The live-emitter catalog PROBLEM_CODES is separate from the open report wire grammar. Producers use it through typed logger metadata, for example logger.warn('Retry exhausted', undefined, { code: 'provider.retry_exhausted', reporting: 'code-only' }). When reporting is enabled, ProblemService.observe validates new warning/error metadata against this catalog before aggregation; missing or undeclared codes become runtime.reporting_invalid or plugin.reporting_invalid without a text sample. Reporting disabled or local-only metadata collects nothing. This bounded validation uses the existing catalog and introduces no additional storage or transport. provider.search_replay_refused and alert.render_failed are retired only from live classification. Persisted batches still validate against PROBLEM_CODE_RE and replay their original codes and samples; licensing retains their historical cs/sk/en descriptions. The disputed subagent.continuation_failed entry and the skills.* vocabulary remain declared. A real consumer is ProblemService.project in src/problems/service.ts.