Modh
AboutServicesWorkPlaybookResourcesBook a call
Book a call
Agent Skills/Backend / Infrastructure/Write Criticality Classification
Backend / Infrastructureintermediate5 min

shield-check Write Criticality Classification

Classify database writes by durability requirement (tracking vs critical) to eliminate false-positive data-loss alarms. Use when adding error handling for DB writes, Sentry alerting for failed operations, or designing retry logic. Prevents noisy alerts from fire-and-forget writes while ensuring real data loss is caught and retried.

Install this skill

git submodule add https://github.com/modh-labs/playbook.git .playbook

One submodule installs all 17 skills. Reference .playbook/skills/write-criticality/SKILL.md from your AGENTS.md.


Write Criticality

When This Skill Activates

  • Adding error handling around database writes
  • Deciding whether a failed write should trigger a Sentry alarm
  • Adding retry logic to write operations
  • Reviewing code that captures "data lost" exceptions
  • Auditing alerting noise from transient infrastructure errors

The Core Principle

Alarm severity must match durability requirement, not payload content.

A write that carries user data is NOT necessarily critical — it depends on whether another write path captures the same data downstream.

WRONG:  if (payload has data && write failed) → alarm "DATA LOST"
RIGHT:  if (write is last chance to save data && write failed) → alarm "DATA LOST"

Decision Tree — "Is This Write Critical?"

Write failed. Should I alarm?

1. Is there a downstream write that captures the same data?
   YES → This is a TRACKING write. Log warning + breadcrumb. No alarm.
   NO  → Go to 2.

2. Can the user retry the operation (form still open, request can be resent)?
   YES → This is a RETRIABLE write. Return error to user. No alarm.
   NO  → Go to 3.

3. Will the upstream system retry (webhook provider, queue, cron)?
   YES → This is an IDEMPOTENT write. Log warning. No alarm.
   NO  → This is a CRITICAL write. Retry once + alarm on final failure.

The Three Tiers

Tier 1: Tracking Writes (default)

Definition: Analytics, funnel tracking, stage progression — data that is also captured by a downstream critical write.

On failure:

  • logger.warn() with structured context
  • Sentry breadcrumb (visible if a later error occurs in the same request)
  • Metric counter with write_criticality: "tracking" tag

Do NOT:

  • Fire captureException()
  • Log at error level
  • Trigger PagerDuty or alert channels

Example: Updating an intent call's stage as the user fills a form — save-form-data captures the complete data later.

Tier 2: Retriable Writes

Definition: User-facing operations where the client can retry — form submissions, API calls, checkout flows.

On failure:

  • Return { success: false, error: "..." } to the caller
  • logger.error() for server-side visibility
  • Sentry breadcrumb (not exception — the user will retry)

Example: Lead creation from a public form — the user's browser still has the form state and can resubmit.

Tier 3: Critical Writes

Definition: The last chance to persist data. No downstream write, no user retry, no webhook re-delivery.

On failure:

  • Retry once with 1s backoff (transient errors only)
  • If still fails: captureException() with write_criticality: "critical" tag
  • logger.error() with full context
  • Metric counter for dashboards

Example: Final form data persistence to the database after the user has moved past the form step.


Implementation Pattern

Add a critical flag to write functions

interface WriteParams {
  // ... existing params ...
  /**
   * When true, failures fire Sentry alarms ("DATA LOST").
   * When false (default), failures log warnings only —
   * data is expected to be captured by a downstream critical write.
   */
  critical?: boolean;
}

Error handling branching

if (error) {
  const isCritical = params.critical === true;

  if (isCritical && hasData) {
    logger.error({ error, ...context }, "Write failed — DATA LOST");
    captureException(new Error(`${operation} failed: ${error.message}`), {
      tags: { write_criticality: "critical" },
    });
  } else {
    logger.warn({ error, ...context }, "Write failed (tracking, non-critical)");
    addBreadcrumb({
      category: module,
      message: `${operation} tracking write failed: ${error.message}`,
      level: "warning",
    });
  }
}

Transient error detection

function isTransientFetchError(error: unknown): boolean {
  if (error && typeof error === "object" && "message" in error) {
    const msg = String((error as { message: string }).message);
    return msg.includes("fetch failed") || msg.includes("ECONNRESET");
  }
  return false;
}

Common transient error signatures:

ErrorCause
TypeError: fetch failed + UND_ERR_SOCKETTCP connection closed by server (keep-alive timeout)
TypeError: fetch failed + UND_ERR_CONNECT_TIMEOUTDNS or connection timeout
ECONNRESETNetwork reset mid-request
certificate has expiredTLS cert issue on upstream

Retry wrapper for critical writes

async function withTransientRetry<
  T extends { error: { message: string } | null }
>(operation: () => PromiseLike<T>, label: string): Promise<T> {
  const result = await operation();
  if (result.error && isTransientFetchError(result.error)) {
    logger.warn({ error: result.error, label },
      `Transient error on ${label} — retrying once after 1s`);
    await new Promise((resolve) => setTimeout(resolve, 1000));
    return operation();
  }
  return result;
}

Rules for retry:

  • Only retry transport-level errors (fetch failed, socket closed)
  • Never retry application errors (constraint violation, RLS denial, validation)
  • Maximum 1 retry with 1s backoff (not exponential — this is a single-shot recovery)
  • The retry must be idempotent (same data, same where clause)

Sentry Queryability

Tag all write failure metrics with write_criticality:

metrics.count("write.failed", 1, {
  attributes: {
    write_criticality: isCritical ? "critical" : "tracking",
    module: "...",
  },
});

This enables dashboard filters:

  • write_criticality:critical → real data loss events (alert on these)
  • write_criticality:tracking → noise (monitor volume, don't alert)

Anti-Patterns

1. Alarming on payload presence

// WRONG — triggers false alarms for tracking writes
if (hasFormDataContent(params.formData)) {
  captureException(new Error("FORM DATA LOST"));
}

The data being present in the payload doesn't mean it's lost — it may be saved by a downstream write.

2. All writes treated equally

// WRONG — every failed write fires the same alarm
if (error) {
  captureException(error);
}

A funnel analytics write and a payment confirmation write have vastly different severity.

3. Retry everything

// WRONG — retrying a constraint violation wastes time
if (error) {
  await sleep(1000);
  return operation(); // Will fail with the same error
}

Only retry transient transport errors. Application errors need different handling.

4. Silencing everything

// WRONG — real data loss goes undetected
try { await write(); } catch { /* swallow */ }

Fire-and-forget is fine for tracking writes, but critical writes MUST alarm on failure.


Audit Checklist

When reviewing a codebase for write criticality issues:

  • Are there captureException calls triggered by hasData && error? (likely false alarms)
  • Do fire-and-forget writes pass data that's also saved elsewhere? (tracking, not critical)
  • Is the critical durability boundary identified? (the ONE place where data must persist)
  • Does the critical write have retry logic for transient errors?
  • Are Sentry alarms tagged with write_criticality for filterability?
  • Can you answer: "If write X fails, where else is the data captured?"

Related Skills

activity

Structured Logging & Observability

Enforce structured logging, Sentry integration, and distributed tracing patterns. Use when adding logging, error tracking, Sentry tags, custom spans, metrics, webhook observability, or debugging production issues. Prevents console.log usage and ensures trace correlation.

Backend / Infrastructure
shield-question

Prove Your Telemetry

Instrumentation fails silently, and its failure looks exactly like good news. An absent field reads as "nothing to report", a quiet dashboard reads as "nothing is wrong", a low issue count reads as "we fixed it". Before trusting any of those, read a real emitted event and confirm it carries what you think. Use when adding or changing logging/error capture, when an error report has no useful detail, when a metric or dashboard is suspiciously quiet, when an error "stopped happening" on its own, or when a shipped fix cannot be confirmed.

Universal
heart-pulse

Weekly Infra Health Review

Stand up a recurring agent that READS your infra telemetry, DIFFS it against last week, and posts a short week-over-week digest ending in 1-3 prioritized "areas of improvement". A dashboard shows numbers but never says what CHANGED or what to DO — an interpreted weekly digest (signals -> recommended actions) is the difference between "we collect telemetry" and "we understand our system". Use when telemetry exists but nobody reads it, when "is our infra healthy?" has no one-glance answer, when costs/perf drift unnoticed until they break, or when standing up a scheduled health/cost review for any stack (Postgres advisors, connection capacity, telemetry quotas, deploy/config drift, web vitals, tracked-ticket movement).

Workflow / Process

Related Playbook Chapters

  • →05 Observability/error Tracking
←Back to Agent Skills