Skip to content

Commit 46e5c3e

Browse files
docs(cems): resolve open decisions (no ETL blockers remain)
Broaden the statusCode/type scan (~20 activations, full code range) — enum stays F/I/W/N and REF/FEP/DEL/GRA(/GRM), nothing new. Convert the open-decisions list into a resolved-decisions table with concrete choices: - Hazard geometry = latest delivered DEL (statusCode F, max monitoringNumber), updated in place; secondary hazards use AOI extent. - Response geometry = product extent; source imagery = linked acquisition items via derived_from (layer separation). - Cross-source related links emitted unconditionally from the deterministic id; GDACS episode defaults to -1. - N -> no-impact when version.reason says so, else withdrawn. Only non-blocking residuals left (statusCode spec cross-check; optional GDACS episode lookup). Also fix an anchor (ampersand heading -> "and"). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent c0b04f1 commit 46e5c3e

1 file changed

Lines changed: 29 additions & 27 deletions

File tree

docs/model/sources/CEMS/README.md

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ mirrors the Charter Area→Hazard mapping.
136136
|-------------------------------|-------------|-------|
137137
| `number` | `id` | `cems-hazard-{code}-aoi{n}-{type}` |
138138
|| `collection: "cems-hazards"` | Required |
139-
| DEL product `extent` → else AOI `extent` (WKT) | `geometry` | **Prefer the Delineation polygon** (actual hazard footprint); fall back to the AOI extent |
139+
| DEL product `extent` → else AOI `extent` (WKT) | `geometry` | **Latest delivered DEL** (highest `monitoringNumber` with `statusCode=F`) — the current hazard footprint; fall back to the AOI extent. Updated in place as monitoring DELs arrive |
140140
| `name` | `title` | AOI name (e.g. `Kingston`) |
141141
| activation `category` (+ `subCategory`) | `monty:hazard_codes` | **One code set per item** — split multi-hazard as Charter does; see [Hazard codes](#hazard-codes) |
142142
| activation `countries` | `monty:country_codes` | Inherited from the activation |
@@ -261,7 +261,7 @@ stats are absent (never in addition, to avoid double counting).
261261
**The join:** every item across both axes shares `monty:corr_id` — query by it and order by
262262
`datetime` / `monitoring_number` to reconstruct the timeline.
263263

264-
### Refresh & polling strategy (minimise HTTP calls)
264+
### Refresh and polling strategy
265265

266266
The **detail** endpoint is expensive (EMSR847 ≈ 413 KB); the **list** endpoint is one cheap
267267
call that already exposes the change signals. Probed API behaviour:
@@ -309,8 +309,13 @@ link** so the graph is directly navigable (65/224 sampled activations carry a `g
309309
This is a **reusable pattern**: any cross-reference field that yields a deterministic
310310
source-item id becomes a typed `related` link, with `monty:corr_id` as the fallback join.
311311
The edge is reciprocal — the Charter source doc already links VAPs to sibling Responses.
312-
Open: GDACS episode resolution, and whether to emit links before the target is ingested
313-
(see [Open decisions](#open-decisions)).
312+
313+
- **Emit unconditionally** from the deterministic id — a `related` link to a not-yet-ingested
314+
target is valid STAC and cheaper than gating on presence; it resolves when the sibling source
315+
is ingested/back-filled.
316+
- **GDACS episode**: `gdacsId` gives `{eventtype}{eventid}` but no episode, so link to
317+
**episode 1** (`{eventid}-1`) as the deterministic anchor (episodes refine the same event);
318+
optionally upgrade to the latest episode when a cheap GDACS lookup is available.
314319

315320
## Hazard codes
316321

@@ -354,29 +359,26 @@ Real upstream CEMS API responses, used as mapping fixtures:
354359

355360
See [`FINDINGS.md`](./FINDINGS.md) for the raw familiarisation notes (esa-montandon#20).
356361

357-
## Open decisions
358-
359-
1. **`statusCode` enum** — observed `F` (delivered), `I` (in production), `W` (scheduled),
360-
`N` (not produced), mapped to `published`/`in-production`/`planned`/`withdrawn`
361-
respectively. Confirm no further codes exist historically and pin the `N``withdrawn`
362-
vs `no-impact` rule (from `version.reason`).
363-
2. **Hazard geometry & monitoring** — AOI → Hazard, geometry = DEL delineation when present,
364-
else AOI `extent`. Remaining: which DEL supplies the polygon (base vs **latest monitoring**
365-
— lean latest), and whether the Hazard geometry is **updated in place** as monitoring DELs
366-
arrive or versioned.
367-
3. **Multi-hazard extent** — a secondary hazard identified from a GRA footprint class
368-
(`Landslide` in a `Storm` activation) has no dedicated polygon in the API; decide whether to
369-
reuse the AOI/DEL extent or leave geometry coarse.
370-
4. **Response geometry** — per-AOI vs per-product `extent` for Response items (both present;
371-
products carry their own `extent`, generally the AOI extent).
372-
5. **Source imagery** — emit linked acquisition items (from `images[]`, carrying
373-
`sat:`/`eo:`/`sar:`) via `derived_from`, or keep `images[]` as product metadata only.
374-
6. **Cross-source links** — resolve GDACS episode; emit `related` links unconditionally
375-
(deterministic id) or only when the target is present in Montandon.
376-
377-
*Resolved in [Tracking over time](#tracking-over-time): monitoring lineage (`rel: prev`
378-
per iteration), revision handling (`version.number` supersede), and Impact granularity
379-
(per-product GRA series, not the aggregated snapshot).*
362+
## Decisions (resolved)
363+
364+
All mapping decisions are settled — none block ETL implementation.
365+
366+
| # | Decision | Resolution |
367+
|---|----------|------------|
368+
| 1 | **`statusCode``status`** | Enum `F`/`I`/`W`/`N``published`/`in-production`/`planned`/`withdrawn` (confirmed stable across ~20 activations spanning the full range). `N``no-impact` when `version.reason` states no damage/impact observed, else `withdrawn`. |
369+
| 2 | **Product type codes** | `REF`/`FEP`/`DEL`/`GRA``eo-ref`/`eo-fep`/`eo-del`/`eo-gra`; monitoring/variant codes (`GRM`) → base code + `monitoring_number`. |
370+
| 3 | **Hazard geometry** | AOI → Hazard; geometry = **latest delivered DEL** (`statusCode=F`, max `monitoringNumber`), fallback AOI `extent`, **updated in place**. |
371+
| 4 | **Multi-hazard** | Driven by `category`/`subCategory` + GRA footprint classes — **not** DEL count. A secondary hazard with no dedicated polygon uses the AOI extent (coarse) and takes severity from its footprint-class figure. |
372+
| 5 | **Response geometry** | The product's own `extent` (precise footprint); AOI extent only as fallback. |
373+
| 6 | **Source imagery** | Emit linked **acquisition items** from `images[]` (carrying `sat:`/`eo:`/`sar:`, `resolutionClass`, `acquisitionTime`) referenced via `derived_from` — per the best-practices layer-separation rule; imagery extensions never on the Response product. |
374+
| 7 | **Monitoring & revisions** | Monitoring iterations = separate items chained by `rel: prev`; `version.number` corrections supersede in place — see [Tracking over time](#tracking-over-time). |
375+
| 8 | **Impact granularity** | Per-product GRA `stats` series (each timestamped), one Impact per exposure class per iteration; aggregated activation `stats` is cross-check only. |
376+
| 9 | **Cross-source links** | Emit `related` **unconditionally** from the deterministic target id; GDACS episode defaults to `-1`. |
377+
| 10 | **Refresh** | Watermark on the `?closed=false` list; detail only when `(lastUpdate, n_products, n_aois)` advance — see [Refresh & polling strategy](#refresh-and-polling-strategy). |
378+
379+
**Residual verification (non-blocking):** cross-check the `statusCode` enum against the CEMS
380+
product-lifecycle spec (only `F`/`I`/`W`/`N` observed); confirm whether a cheap GDACS
381+
episode-resolution lookup is worth adding over the `-1` default.
380382

381383
## Resources
382384

0 commit comments

Comments
 (0)