observabilitylisted
Install: claude install-skill Mark-Life/agent-task-manager
# Observability
**Record what happened to this request, not what the code is doing.** One
canonical record per unit of work, carrying every dimension you would want to
group by later. Run each section's **Check** before calling the instrumentation
done.
## One wide event per unit of work
**A request, job, or run emits exactly one rich record — a wide event, or
canonical log line.** Capture the immutable facts before the work starts,
accumulate the outcome into a mutable record as it runs, emit where every path
converges. In imperative code that is `finally`, over an accumulator declared
beside the frozen context (`telegram-claude`, `src/bot.ts`):
```ts
// Wide-event context captured up front so every return path emits once.
const meta: RunEventMeta = { runId: crypto.randomUUID(), userId, provider,
project, promptChars: prompt.length, queueDepth: state.queue.length };
const rec: RunRecord = { outcome: "done", costUsd: null, turns: null,
totalTokens: null, durationMs: null, sessionId: sessionId ?? null };
try {
/* … the work, folding results into `rec` … */
} catch (e) {
rec.outcome = "errored";
rec.errorClass =
(e as { _tag?: string })?._tag ?? (e as Error)?.name ?? "ProviderCrashed";
rec.errorMessage = clipError(String((e as Error)?.message ?? e));
} finally {
await emitRunEvent(rec, meta);
}
```
In Effect, `Effect.onExit` is the equivalent and covers interrupts too, reading
the accumulated Refs so a SIGINT still emits a complete row (`factory`,
`packa