name: firms-fire
version: "0.1"
category: events-hazards
themes: [hazards]
family: active-fire-nrt-hotspot-detection
answers_verb: alert                       # notifies when a new fire is detected in an AOI
description: >
  Pilot alert layer (ALERTS.md §10.1): wrap the NASA FIRMS NRT active-fire feed
  and deliver detections through Folia's full delivery surface — webhook, MCP
  push, signed receipt — rather than FIRMS's email-only alerts. The detection is
  not novel (FIRMS already does it); the value is the delivery fabric + an
  inspectable firing that carries the FIRMS source row that drove it.

  Source = @nasa/firms/active-fire (feed-poll, ~3h NRT global; RT 20-30min
  US/Canada; URT <60s at direct-readout overpass moments). A subscription
  declares which latency tier(s) it accepts and a confidence floor.

# ── Alert layer (ALERTS §2 — cell-indexed, thresholdable score) ─────────────

alert_layer: alerts/firms-fire
type: computed
geo: { cell_system: h3, resolution: 8 }

# metadata → sensible subscription defaults (ALERTS §2)
cooldown_default: 6h
min_confidence: 0.5

# User-supplied via subscription (ALERTS §2.2 parameterized layers).
params:
  min_confidence:
    type: number
    default: 0.5
    description: Normalized-confidence floor [0,1]. VIIRS l/n/h → 0.2/0.6/0.9; MODIS pct/100.
  accept_tiers:
    type: enum-list
    enum: [URT, RT, NRT]
    default: [NRT]
    description: >
      Latency tier(s) accepted. Accepting NRT also accepts fresher RT/URT rows;
      accepting only URT rejects anything slower. Tier is derived per row from
      observed age against the pinned floors (URT<60s / RT<30m / NRT<3h).
  source:
    type: string
    default: VIIRS_SNPP_NRT
    description: FIRMS area-API product (VIIRS_SNPP_NRT, VIIRS_NOAA20_NRT, MODIS_NRT, ...).

inputs:
  firms:
    dataset: "@nasa/firms/active-fire"       # feed-poll source; distribution declares freshness
    connector: connectors.firms.adapter      # area-CSV fetch + parse/normalize
    params:
      source: ${params.source}
      day_range: 1

# ── Compute (passthrough with thresholdable confidence, ALERTS §10.1) ───────
#
# No new op: FIRMS is a point feed. The connector parses/normalizes the CSV into
# detections; the alert layer thresholds normalized confidence + accepted tier
# per cell. Each fired cell commits its FIRMS source row (ALERTS §4).
compute:
  op: feed_threshold                         # connector-side; not a raster op (ADR-0029)
  inputs:
    detections: { input: firms }
  params:
    value: confidence_norm
    threshold: ${params.min_confidence}
    accept_tiers: ${params.accept_tiers}
    commit_source_row: true                  # firing.inputs = the FIRMS row

outputs:
  primary:
    - alerts/firms-fire                      # cell-indexed alert layer (score = confidence)
  show_your_work:
    - firms                                  # the raw FIRMS detections behind each firing

license:
  recipe: Apache-2.0
  output_dataset: public-domain
  upstream_data:
    - { source: "@nasa/firms/active-fire", license: public-domain }

# ── Source-freshness seam (research/source-freshness/README.md) ─────────────
# The distribution's freshness block (kind: feed-poll, poll_interval: 30m,
# debounce: 15m) drives the ad-hoc poll in connectors/firms/adapter.py today.
# alerts-v1/11's dispatcher retrofits it: it owns the D1 source_state table +
# scheduling; the resolver-diff primitive (adapter.diff_new) is unchanged.
freshness_source: "@nasa/firms/active-fire#nasa-firms"
