Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
daceea7
feat(seed): adapt the methodology's dimensions to the Dominican context
mrivas00 Aug 21, 2026
5cc0238
feat(api): reject a capture line that omits a required comment
mrivas00 Aug 21, 2026
0e2514c
feat(web): enforce and surface the mandatory comment
mrivas00 Aug 21, 2026
6322d9d
docs(seed): describe the Dominican dimension options in the explanations
mrivas00 Aug 21, 2026
d2835f4
test(api): cover the mandatory comment on escape-hatch values
mrivas00 Aug 21, 2026
2350fb9
docs: record where the Dominican factors come from
mrivas00 Aug 21, 2026
b40eeb1
docs(openspec): mark the methodology tasks complete
mrivas00 Aug 21, 2026
b7d90f4
fix(seed): name the electricity factor source `SENI`
mrivas00 Aug 25, 2026
86e5370
fix(seed): ship the cable car as an option with no factor
mrivas00 Aug 25, 2026
3c55021
fix: drop the mandatory comment on `Otro`
mrivas00 Aug 25, 2026
fa0003f
fix(seed): ship the new dimension values without factors
mrivas00 Aug 25, 2026
165ac4a
fix(web): drop what the comment requirement left behind
mrivas00 Aug 26, 2026
713de34
fix(seed): put the cable car in the transport order
mrivas00 Aug 26, 2026
607304d
docs(seed): send the motoconcho to Moto, not to the taxi option
mrivas00 Aug 26, 2026
42fd278
docs: repin the acceptance fixture to the SENI grid factor
mrivas00 Aug 26, 2026
c46b15b
docs(openspec): correct what the factor decision left standing
mrivas00 Aug 26, 2026
c4dcc85
docs(openspec): close the tasks a database was blocking
mrivas00 Aug 26, 2026
8e68341
fix(seed): set the SENI grid factor to 0.53495
mrivas00 Aug 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions docs/development/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,14 @@ Everything a developer needs to work on the Huella Latam codebase: environment s

## Configuration and operations

| Document | Description |
| --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| [System Parameters Reference](./system-parameters.md) | Database-backed configuration parameters and their effects on platform behaviour |
| [Country Onboarding Guide](./country-onboarding.md) | How to deploy the platform in a new country: seed data, methodology, Entra ID, and infrastructure |
| [RD Activity Catalog Sources](./rd-activity-catalog-sources.md) | Where the Dominican activity catalog comes from, how far it was checked against the official classifier, and what is still ours |
| [RD Territorial Catalog Sources](./rd-territories-sources.md) | Where the Dominican territorial hierarchy comes from, which levels are loaded, and why two are deliberately empty |
| [Internationalization Plan](./i18n-plan.md) | Forward-looking plan for adding i18n (not yet implemented) |
| Document | Description |
| --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| [System Parameters Reference](./system-parameters.md) | Database-backed configuration parameters and their effects on platform behaviour |
| [Country Onboarding Guide](./country-onboarding.md) | How to deploy the platform in a new country: seed data, methodology, Entra ID, and infrastructure |
| [RD Activity Catalog Sources](./rd-activity-catalog-sources.md) | Where the Dominican activity catalog comes from, how far it was checked against the official classifier, and what is still ours |
| [RD Territorial Catalog Sources](./rd-territories-sources.md) | Where the Dominican territorial hierarchy comes from, which levels are loaded, and why two are deliberately empty |
| [RD Methodology Factors](./rd-methodology-factors.md) | Where the Dominican dimension values and emission factors come from, what each was derived from, and what still needs MMARN's confirmation |
| [Internationalization Plan](./i18n-plan.md) | Forward-looking plan for adding i18n (not yet implemented) |

## Quality and CI

Expand Down
11 changes: 10 additions & 1 deletion docs/development/country-onboarding.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,8 @@ Standard GHG Protocol categories:
"isRequired": false,
"values": [
{ "name": "Caldera", "parentValue": null },
{ "name": "Generador", "parentValue": null }
{ "name": "Generador", "parentValue": null },
{ "name": "Otro", "parentValue": null }
]
}
],
Expand All @@ -255,7 +256,15 @@ Standard GHG Protocol categories:

**Emission factors** associate a numeric value with a specific combination of dimension values, a measurement unit, and a source citation.

Give a catch-all value such as `Otro` a factor too, the most conservative of its
dimension, so the escape hatch never understates. The line's comment is where a
registrant says what the emission actually was; it is optional, like every other
comment, so an inventory that leans on the catch-all is worth reviewing rather
than trusting.

> **Important:** Emission factor values must be sourced from the country's official environmental authority or an internationally recognized standard (GHG Protocol, IPCC, IEA). Document the source and year in the `source` field.
>
> All active factors of a subcategory must share one `source` string — the maintainer API enforces it — so a subcategory that mixes bases states them together in that one string.

---

Expand Down
34 changes: 17 additions & 17 deletions docs/development/manual-testing-emission-capture.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ Quantities below are written exactly as they must be typed — no thousand separ

| Sistema eléctrico | Unidad | Cantidad |
| ----------------- | -------------- | -------- |
| Sistema nacional | megawatts hora | 1850 |
| SENI | megawatts hora | 1850 |

**Productos comprados**

Expand Down Expand Up @@ -206,7 +206,7 @@ Quantities below are written exactly as they must be typed — no thousand separ
| Combustiones móviles | Camioneta / Gasolina-Nafta | 4600 | litros | 2.339 | kg/L | DEFRA 2025 | 2,339 | 10 759.4 | **10,76** |
| Emisiones fugitivas | HFC-134a | 45 | kilógramos | 1 300 | kg/kg | DEFRA 2025 | 1.300 | 58 500 | **58,5** |
| Emisiones fugitivas | HFC-32 | 18 | kilógramos | 677 | kg/kg | DEFRA 2025 | 677 | 12 186 | **12,19** |
| Electricidad | Sistema nacional | 1850 | megawatts hora | 177 | kg/MWh | DEFRA 2025 | 177 | 327 450 | **327,45** |
| Electricidad | SENI | 1850 | megawatts hora | 534.95 | kg/MWh | SENI | 534,95 | 989 657.5 | **989,66** |
| Productos comprados | Plástico / Primera mano | 85 | toneladas | 3 172 | kg/ton | DEFRA 2025 | 3.172 | 269 620 | **269,62** |
| Productos comprados | Papel y cartón / Con material reciclado | 140 | toneladas | 1 068 | kg/ton | DEFRA 2025 | 1.068 | 149 520 | **149,52** |
| Disposición de residuos | Residuos comerciales o industriales / Relleno sanitario | 62 | toneladas | 520.5327 | kg/ton | DEFRA 2025 | 520,53 ⓘ | 32 273.0274 | **32,27** |
Expand All @@ -226,12 +226,12 @@ Quantities below are written exactly as they must be typed — no thousand separ

The four factors that require conversion:

| Stored factor | Unit picked | Applied factor | Derivation |
| ------------------------------ | -------------- | ----------------- | ------------------------- |
| Diésel · 2 570 `kg/m3` | litros | **2.57** `kg/L` | 2 570 × 1 / 1 000 |
| Gasolina/Nafta · 2 339 `kg/m3` | litros | **2.339** `kg/L` | 2 339 × 1 / 1 000 |
| GLP · 2 939 `kg/ton` | kilógramos | **2.939** `kg/kg` | 2 939 × 1 000 / 1 000 000 |
| Electricidad · 0.177 `kg/kWh` | megawatts hora | **177** `kg/MWh` | 0.177 × 1 000 / 1 |
| Stored factor | Unit picked | Applied factor | Derivation |
| ------------------------------- | -------------- | ------------------- | ------------------------- |
| Diésel · 2 570 `kg/m3` | litros | **2.57** `kg/L` | 2 570 × 1 / 1 000 |
| Gasolina/Nafta · 2 339 `kg/m3` | litros | **2.339** `kg/L` | 2 339 × 1 / 1 000 |
| GLP · 2 939 `kg/ton` | kilógramos | **2.939** `kg/kg` | 2 939 × 1 000 / 1 000 000 |
| Electricidad · 0.53495 `kg/kWh` | megawatts hora | **534.95** `kg/MWh` | 0.53495 × 1 000 / 1 |

### Per subcategory

Expand All @@ -242,7 +242,7 @@ Shown in each subcategory header.
| Combustiones estacionarias | 41 529.8 | 41.5298 | **41,53 tCO₂e** |
| Combustiones móviles (flota propia) | 83 747.4 | 83.7474 | **83,75 tCO₂e** |
| Emisiones fugitivas | 70 686 | 70.686 | **70,69 tCO₂e** |
| Electricidad | 327 450 | 327.45 | **327,45 tCO₂e** |
| Electricidad | 989 657.5 | 989.6575 | **989,66 tCO₂e** |
| Productos comprados | 419 140 | 419.14 | **419,14 tCO₂e** |
| Disposición de residuos sólidos | 32 357.36964 | 32.35736964 | **32,36 tCO₂e** |
| Consumo de agua y tratamiento de aguas residuales | 15 293.24 | 15.29324 | **15,29 tCO₂e** |
Expand All @@ -258,11 +258,11 @@ Category totals appear in the `Total …` card at the top of each category tab.
| Category | kg CO₂e | t CO₂e (exact) | Card shows |
| ------------------------------------------------ | ------------------- | ------------------ | ------------------ |
| 1 — Emisiones directas | 195 963.2 | 195.9632 | **195,96 tCO₂e** |
| 2 — Emisiones indirectas por energías importadas | 327 450 | 327.45 | **327,45 tCO₂e** |
| 2 — Emisiones indirectas por energías importadas | 989 657.5 | 989.6575 | **989,66 tCO₂e** |
| 3 — Otras emisiones indirectas | 572 894.80964 | 572.89480964 | **572,89 tCO₂e** |
| **TOTAL** (step 4 / step 5) | **1 096 308.00964** | **1 096.30800964** | **1.096,31 tCO₂e** |
| **TOTAL** (step 4 / step 5) | **1 758 515.50964** | **1 758.51550964** | **1.758,52 tCO₂e** |

Cross-checks: scope split ≈ 17.9 % / 29.9 % / 52.3 %; main-activity equivalence `1 096.30800964 / 18 500 000` = `0.00005925989…` tCO₂e per litre, which the adaptive mass unit renders as **59,26 gCO₂e/litros producidos** — in the step-4 caption and in the equivalence card of step 5 and the home screen. The raw tonne figure (`0,000059`) is never displayed; see [Display Precision](../architecture/emission-calculation.md#display-precision).
Cross-checks: scope split ≈ 11.1 % / 56.3 % / 32.6 %; main-activity equivalence `1 758.51550964 / 18 500 000` = `0.00009505489…` tCO₂e per litre, which the adaptive mass unit renders as **95,05 gCO₂e/litros producidos** — in the step-4 caption and in the equivalence card of step 5 and the home screen. The raw tonne figure (`0,000095`) is never displayed; see [Display Precision](../architecture/emission-calculation.md#display-precision).

---

Expand Down Expand Up @@ -328,14 +328,14 @@ Step 3, per subcategory:
Step 3, category cards:

- [ ] Total emisiones directas = **195,96 tCO₂e**
- [ ] Total emisiones indirectas por energías importadas = **327,45 tCO₂e**
- [ ] Total emisiones indirectas por energías importadas = **989,66 tCO₂e**
- [ ] Total otras emisiones indirectas = **572,89 tCO₂e**

Steps 4 and 5:

- [ ] Inventory total = **1.096,31 tCO₂e**
- [ ] Scope split ≈ 17.9 % / 29.9 % / 52.3 %
- [ ] The step-4 caption and the step-5 equivalence card both read **59,26 gCO₂e/litros producidos** — a `0,000059 tCO₂e/…` here means the adaptive mass unit did not apply.
- [ ] Inventory total = **1.758,52 tCO₂e**
- [ ] Scope split ≈ 11.1 % / 56.3 % / 32.6 %
- [ ] The step-4 caption and the step-5 equivalence card both read **95,05 gCO₂e/litros producidos** — a `0,000095 tCO₂e/…` here means the adaptive mass unit did not apply.
- [ ] The _Factores utilizados_ table of step 4 carries the same ⓘ affordance as the capture grid; its per-gas breakdown lines inherit the precision but deliberately not the affordance.

Robustness:
Expand Down Expand Up @@ -367,7 +367,7 @@ Expected:
| cat | kg | ton |
| --- | ------------------ | ------------ |
| 1 | 195 963.2000000000 | 195.96320000 |
| 2 | 327 450.0000000000 | 327.45000000 |
| 2 | 989 657.5000000000 | 989.65750000 |
| 3 | 572 894.8096400000 | 572.89480964 |

To inspect line by line (quantity, applied factor, rate unit, result):
Expand Down
101 changes: 101 additions & 0 deletions docs/development/rd-methodology-factors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# RD Methodology Factors

What the Dominican methodology changed in
`tools/seed/src/data/base/methodologies.json`, and which of those changes carry a
number.

**The branch adds options, not factors.** The observations asked for dimension
values the country actually has — dumps rather than only sanitary landfills, a
cable car, isolated grids — and those values ship. Pricing them is MMARN's:
Dominican factors come from the Dominican authority, and a number derived here
would be a foreign estimate wearing a national badge. Every value this branch
adds is therefore an option with **no seeded factor**, with one exception.

## The exception: the SENI grid factor

`0.53495 kgCO₂e/kWh` replaces `0.177`, a UK figure inherited from the demo dataset
that understated Dominican grid emissions roughly threefold. It is the one factor
the branch changes, because it prices Scope 2 for every organization in the
country and leaving a UK number there is worse than replacing it with an
order-of-magnitude-correct national one.

It is still not an official figure. **Confirm it against what the CNE / MEM
publishes before the first reporting cycle closes.**

## What happens to an option with no factor

The capture line finds nothing seeded, so **Fuente factor** offers only `Otro`,
where the registrant enters the value they hold — the operator's, the ministry's,
their own metering — and it is stored with the line. The option is usable and the
gap is visible, which is the point: an empty factor reads as a question, and a
plausible-looking derived number does not.

Every one of these becomes a data change the day MMARN supplies the figure. No
code is involved.

## Scope 2 — Electricidad

| Value | Factor | Note |
| --------------- | -------------- | --------------------------------------------------------------------------------------------- |
| SENI | 0.53495 kg/kWh | The one replacement — see above |
| Sistema aislado | none | Typically diesel generation, so above the interconnected grid — by how much is MMARN's to say |
| Otro | none | Escape hatch |

The demo dataset's single `Sistema nacional` value is gone: the country has an
interconnected grid and isolated systems, and the observation asks for both.

## Scope 3 — Disposición de residuos sólidos

The `Destino` dimension gains `Vertedero a cielo abierto`, `Vertedero controlado`
and `Otro`, alongside the `Relleno sanitario`, `Incineración` and `Reciclaje` the
platform already carried. **The three pre-existing destinations keep the
platform's DEFRA 2025 factors, unchanged. The three new ones carry none.**

A first pass derived them, scaling the landfill factor per material by the IPCC
2006 Vol. 5 Ch. 3 methane correction factor for the site type. It was dropped —
and the reason is worth keeping, because it is the question MMARN has to answer
before any number goes in: that derivation treats the DEFRA landfill figure as
the MCF = 1.0 reference, and DEFRA's figure is net of the landfill-gas capture
typical of a managed UK site. Model the _absence_ of capture at unmanaged
Dominican sites instead and the ranking inverts — dumps come out **above** the
sanitary landfill rather than below it.

**Is the disposal-route ranking driven by methane generation, or by net emissions
after capture?** Until that is answered, a derived multiplier is a coin flip
dressed as a factor.

## Scope 3 — Desplazamiento diario de empleados

| Change | Basis |
| ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Teleférico` added, **no factor** | The option the observation asks for — see below |
| `Tren cercanías` and `Tren larga distancia` removed | The country has no passenger rail network; the Santo Domingo metro stays as `Metro` |
| `Taxi/Ride-share` → `Taxi/vehículo de transporte individual` | One value, not two: taxi and platform vehicles are split only once their factors differ. The motoconcho is not one of them — it is a motorcycle, and `Moto` already prices it |
| `Bici` → `Bicicleta` | Wording |

Both renames keep the platform's existing factors: the numbers are the same rows
under new names, not new values.

**The cable car.** A figure was drafted — 0.04 kWh per passenger-kilometre times
the SENI factor, on the reasoning that the traction is electric — and dropped:
0.04 kWh is a plausible mid-range for an urban aerial cableway anywhere, not a
measured value for the Santo Domingo system. Ask the operator for the consumption
per passenger-kilometre.

## What `Otro` carries, and what it does not

Nothing. `Otro` is an option with no factor, like every other value this branch
adds, and its comment is optional like every other comment in capture.

Two drafts tried to make the escape hatch self-defending — a mandatory comment,
and the highest factor of its dimension so it could never understate — and both
are gone. The mandatory comment matched values by name, so it could not be scoped
to one dimension without becoming a per-dimension rule, and two `Otro` options
behaving unlike every other value cost more in explanation than the traceability
bought. The conservative factor went with the rest of the derived numbers.

What is left is honest rather than protective: selecting `Otro` obliges the
registrant to supply a factor, because there is none to fall back on. Observations
4 and 6 say _especifique_, and the subcategory explanations ask for the comment;
neither is enforced. An inventory leaning on `Otro` is worth reviewing rather than
trusting.
Loading