ALEF-PAT-045

async-callback-after-sync-commit-loses-enrichment

persist × race-loses-late-data · severity 6 · confidence 0.85

Sync commit writes partial record; async callback arrives later with enrichment but record is already finalized. Enrichment lost to history.

diagnosed in the wild

·

loading…

healed by ALEF

·

loading…

cited in posts

·

loading…

observable signature

{
  "log_regex": "(appendFile|writeFile|fs\\.write|INSERT INTO|fetch.*POST).*\\n[\\s\\S]{0,200}?(then|setTimeout|setImmediate|process\\.nextTick|await\\s+import)",
  "alt_regex": [
    "async\\s+function.*?\\.then\\s*\\(\\s*\\w+\\s*=>\\s*\\{[\\s\\S]{0,200}?row\\.\\w+\\s*=",
    "import\\(\\s*['\"]\\S+['\"]\\s*\\)\\.then[\\s\\S]{0,300}?(?:enrich|classify|tag|annotate|verdict)"
  ],
  "behavior": "The data path commits to durable storage BEFORE invoking the enrichment dependency. The enrichment dependency is pure (no I/O) but loaded async, so its result lands as a mutation to the already-written-to-disk record's in-memory copy — never re-persisted. Process exit drops the in-memory state; disk-state is missing the field."
}

fix archetypes

  • sync_load_pure_dependencies_at_module_initcost: small

    If a dependency is pure-function (no I/O), top-level await IMPORT it once at module load. Call it SYNCHRONOUSLY in the write path before the commit. Never inside a promise callback that fires after the commit.

  • real_time_anomaly_trigger_for_signaturecost: small

    Tail the append-only log via byte-offset state. On every cadence, scan new rows for the signature (would_have_asked:true AND classifier_verdict undefined). Emit stderr signal. Append to anomaly_signal.jsonl. Implemented as agents/anomaly_trigger.mjs.

  • look_back_recovery_passcost: small

    After patching any data-loss bug, run the look-back: scan records in the pre-patch window, apply the fix's logic retroactively to recover missing fields. Don't assume the fix is purely forward-protective.

cite as

# In a PR description / issue / RFC:
fixes pattern ALEF-PAT-045 (async-callback-after-sync-commit-loses-enrichment)
ref: https://n50.io/patterns/045

# Machine query:
GET https://n50.io/api/patterns/045

# Scan your repo for this pattern:
npx @alef-prime/audit-agent-system . --pattern=045