C6 Carbon Model
C6 Carbon Model — Canonical Metric Catalog
Date: 2026-05-07
Purpose: Define the C6-native carbon model. Every methodology (Verra legacy, VM0048, VM0047, ART TREES, Plan Vivo, Gold Standard, CDM, IPCC) maps onto this catalog as a projection — a subset of metrics with methodology-specific transforms. C6 owns the data model; methodologies are configurations on top.
Pairs with: methodology-inputs-comparison.md (the upstream input survey) and app/units/registry.py (the canonical-unit enforcement layer).
Design principle: if a metric appears in ≥2 methodologies it is core and lives directly in farm_metrics. If it appears in only one methodology and is high-cardinality (per-tree, per-plot, per-pixel), it lives in a side table (carbon_measurements, plot_measurements, etc.) and is aggregated into a farm_metric row at compute time.
1. Metric layers
Three layers, top to bottom:
| Layer | Where stored | Cardinality | Example |
|---|
| L0 — Raw observation | carbon_measurements, plot_measurements, satellite raster cache | high (per tree, per plot, per pixel × year) | DBH=42 cm, plot SOC core 0–30 cm |
| L1 — Farm metric (canonical) | farm_metrics | medium (per farm × code × vintage) | agb = 78.4 tC/ha (2024) |
| L2 — Methodology output | vintage_ledger rows + project_computation | low (per project × vintage) | VM0048 baseline = 12,400 tCO₂e/yr |
This catalog is the L1 list — what every farm should carry to feed any methodology. L0 sources and L2 transforms are referenced but not enumerated here.
2. Canonical metric catalog
Columns:
- code —
farm_metrics.metric_type.code (matches app/units/registry.py where applicable)
- canonical unit — what
value_canonical carries (matches REGISTRY[code].canonical)
- accepts — input units the converter accepts (raw side)
- pool / class — IPCC pool, LULC class, or driver category
- methodologies — which standards consume it (V7=VM0007, V15=VM0015, V48=VM0048, V47=VM0047, V9=VM0009, ART=ART TREES 2.0, PV=Plan Vivo, GS=Gold Standard, CDM=CDM A/R)
- C6 status —
live (in DB today), partial (live but missing fields), gap (need to add)
- L0 source — where raw data comes from
Pool codes: AGB = above-ground biomass; BGB = below-ground; DW = dead wood; L = litter; SOC = soil organic carbon; HWP = harvested wood products. Carbon fraction (CF) and 44/12 stoichiometry applied at engine layer, not storage.
2.1 Geometry & area
| code | canonical | accepts | class | methodologies | C6 | L0 source |
|---|
total_area_ha | ha | ha, km², m², acres | farm gross | all | live | KML/shapefile + PostGIS ST_Area |
net_usable_area_ha | ha | ha | farm net (post-overlay deductions) | all | live | total − protected − indigenous − water |
aud_area_ha | ha | ha | REDD-AUD project area | V7,V9,V15,V48,ART | live | farm geometry × forest mask |
apd_area_ha | ha | ha | REDD-APD planned-deforestation area | V7,V15 | live | concession docs + farm geometry |
arr_eligible_area_ha | ha | ha | ARR area (10-yr non-forest test) | V47,GS,CDM,PV | gap | Hansen GFC ≥10 yr non-forest mask + geometry |
degraded_forest_area_ha | ha | ha | ARR-on-degraded-forest area (V47 v1.1) | V47 | gap | RS biomass below threshold + farm geometry |
leakage_belt_area_ha | ha | ha | activity-shift leakage belt | V7,V15,V48,V47 | gap | configurable buffer (10–20 km) around AUD |
discounted_overlap_ha | ha | ha | total overlay deductions | all | live | sum of overlay overlap |
protected_area_overlap_ha | ha | ha | WDPA overlay | all | live | overlay runner |
indigenous_land_overlap_ha | ha | ha | FUNAI/ANT/INEI overlay | all | live | overlay runner |
2.2 Forest cover & stratification
| code | canonical | accepts | class | methodologies | C6 | L0 source |
|---|
forest_cover_ha | ha | ha | current forest extent | all | live | MapBiomas / PRODES |
forest_cover_pct | % | %, ha (with denom) | derived | all | live | forest_cover_ha / total_area_ha |
forest_type_class | enum | text | stratification | all | gap | MapBiomas Collection 10 forest subtype |
disturbance_class | enum | text | undisturbed / logged / secondary | V7,V47,V48,ART | gap | RS time-series + biomass |
forest_age_years | yr | yr | stand age (ARR/IFM) | V47,GS,CDM | gap | planting records or RS regrowth detection |
stratum_id | int | int | stratum FK | all | gap | C6 stratification table (forest type × disturbance × age) |
2.3 Carbon pools — per-stratum density
| code | canonical | accepts | pool | methodologies | C6 | L0 source |
|---|
agb | tC/ha | tDM/ha, tC/ha, Mg/ha | AGB | all | live | field plots + Chave 2014; or GEDI L4A/B; or vendor PDFs (Canopy, C2050, ClearBlue) |
agb_density_mg_ha | Mg/ha | Mg/ha | AGB (raw remote-sensing) | all | live | GEDI L4A AGBD, ESA CCI Biomass |
bgb | tC/ha | tDM/ha, tC/ha | BGB | all | live | AGB × root-shoot ratio (Mokany 2006) or field excavation |
bgb_density_mg_ha | Mg/ha | Mg/ha | BGB (raw) | all | live | derived from AGB |
dw_density | tC/ha | tDM/ha, tC/ha | dead wood | V7,V9,V15,V47,ART,GS | gap | line-intersect sampling for lying DW; plot for standing DW |
litter_density | tC/ha | tDM/ha, tC/ha | litter | V7,V9,V47,ART,GS | gap | 0.25 m² destructive plot sampling |
soc | tC/ha | tC/ha, g/kg×depth | SOC 0–30 cm | V7-peat,V9,V47,ART,PV | live | SoilGrids 250 m or core (0–30 cm + bulk density + %C) |
soc_method | enum | text | tier1_default / tier2_regional / tier3_measured | all SOC users | gap | provenance — drives uncertainty |
hwp_carbon | tC | tC | HWP retention pool | V7-IFM,GS | gap | mill records + IPCC Winjum 1998 retention factors |
non_woody_biomass | tC/ha | tDM/ha, tC/ha | herbaceous (V47 conditional) | V47 | gap | plot harvest sampling |
These live at L0 (plot_measurements) and aggregate up. Listed here for completeness — C6 must store these to defend its own AGB numbers.
| code | canonical | accepts | class | methodologies | C6 | L0 source |
|---|
plot_dbh | cm | cm, mm | per-tree DBH | all forest | gap | field plot |
plot_height | m | m, cm | per-tree height | all forest | gap | field plot (clinometer / hypsometer) |
plot_species | enum | text | per-tree species code | all forest | gap | field botanist |
wood_density_t_m3 | t/m³ | g/cm³, t/m³ | ρ per species | all forest | gap | Global Wood Density Database (Zanne 2009) |
carbon_fraction | dimensionless | unitless | CF (default 0.47) | all | gap (in code, not table) | IPCC default or measured; lives in app.methodologies.params today |
root_shoot_ratio | dimensionless | unitless | R per biome | all forest | gap (in code) | IPCC 2006 Table 4.4; in params today |
bef | dimensionless | unitless | biomass expansion factor | volume-based inventories | gap | IPCC Vol. 4 Table 4.5 |
allometric_equation_id | enum | text | which equation used | all forest | gap | C6 lookup (Chave 2014 pantropical, regional…) |
plot_area_ha | ha | m², ha | plot footprint | all forest | gap | survey records |
plot_geom | PostGIS Point/Poly | — | plot location | all forest | gap | GPS |
2.5 Activity data — historical & projected deforestation
| code | canonical | accepts | class | methodologies | C6 | L0 source |
|---|
historical_deforestation_rate | %/yr | %/yr, ha/yr | reference-period rate | V7,V15,V9,GS | live | PRODES 10-yr trend |
aud_annual_deforest_pct | %/yr | %/yr | AUD baseline rate | V7,V15,V48,ART | live | reference region trend or jurisdictional allocation |
apd_annual_deforest_pct | %/yr | %/yr | APD planned rate | V7,V15 | live | concession plan |
aud_annual_avoided_deforest_ha | ha/yr | ha/yr | derived AD output | V7,V15,V48,ART | live | rate × area |
defor_primary_ha | ha | ha | per-vintage primary loss | V7,V15,V48,ART,V9 | live | MapBiomas Alerta + PRODES |
defor_secondary_ha | ha | ha | per-vintage secondary loss | V7,V15,V48 | live | MapBiomas |
defor_recurrent_ha | ha | ha | recurrent on previously-cleared | V48,ART | live | MapBiomas |
defor_total_ha | ha | ha | total per vintage | all REDD | live | sum |
defor_cumulative_ha | ha | ha | windowed sum | all REDD | live | derived |
degradation_ha | ha | ha | degradation per vintage (future V48 module) | V48 (future), ART | gap | Sentinel-1 / GEDI / DETER |
forest_gain_ha | ha | ha | regrowth per vintage | ART, V47 | gap | MapBiomas, Hansen |
jurisdictional_jad_tco2e | tCO₂e | tCO₂e, ktCO₂e, MtCO₂e | Verra-supplied JAD | V48 | gap | VMD0055 jurisdictional file |
allocated_baseline_tco2e_yr | tCO₂e/yr | tCO₂e/yr | risk-allocated to project pixels | V48 | gap | Verra risk map × project geometry |
fcbm_forest_ha_t1 / t2 / t3 | ha | ha | Forest Cover Benchmark Map at 3 timepoints | V48 | gap | VMD0055 jurisdictional file |
baseline_source | enum | text | discriminator: historical_projected / jurisdictionally_allocated / dynamic_control_matched / community_PRA / national_NFMS | all | gap | project config |
2.6 LULC class areas (current state)
Already live as lulc_*_ha. These feed stratification + leakage analysis.
| code | canonical | class | C6 |
|---|
lulc_native_nonforest_ha | ha | wetland/grassland | live |
lulc_pasture_ha | ha | pasture | live |
lulc_agriculture_ha | ha | annual + perennial crops | live |
lulc_forest_plantation_ha | ha | plantation | live |
lulc_urban_ha | ha | urban | live |
lulc_mining_ha | ha | mining | live |
lulc_water_ha | ha | water | live |
lulc_other_ha | ha | beach/bare/unobserved | live |
2.7 Driver / risk layers
| code | canonical | accepts | class | methodologies | C6 | L0 source |
|---|
dist_to_road_m | m | m, km | driver | V15,V48 | gap | OSM roads + farm centroid / nearest pixel |
dist_to_settlement_m | m | m, km | driver | V15,V48 | gap | gridded population (GHSL, WorldPop) |
dist_to_river_m | m | m, km | driver | V15 | gap | HydroRIVERS / RAISG |
dist_to_prior_clearing_m | m | m, km | driver | V15,V48 | gap | MapBiomas annual |
slope_pct | % | %, deg | driver | V15,V48 | gap | SRTM 30 m |
elevation_m | m | m | driver | V15,V48 | gap | SRTM |
tenure_class | enum | text | private / public / reserve / undefined | V15,V48,PV | gap | SIGEF/CAR (Brazil), ANT (Colombia), COFOPRI (Peru) |
2.8 ARR-specific (V47, GS, CDM, PV)
| code | canonical | accepts | class | methodologies | C6 | L0 source |
|---|
pre_project_land_use_class | enum | text | cropland / pasture / barren / degraded forest | V47,GS,CDM,PV | gap | MapBiomas + farm survey |
pre_project_land_use_years | yr | yr | length of pre-project state (V47 ≥10 yr) | V47,GS | gap | MapBiomas time series |
stocking_index | dimensionless | unitless | V47 biomass-based SI | V47 | gap | RS biomass product (GEDI L4B / Chloris / Kanop / Planet) |
matched_control_plot_id | text | — | k-NN matched control reference | V47 | gap | C6 matching algorithm + donor pool |
matched_control_si_delta | dimensionless | — | annual ΔSI (project − control) | V47 | gap | derived per verification |
common_practice_pct | % | % | adoption rate of activity in jurisdiction | V47,GS | gap | sub/national land-use statistics |
species_planted | enum | text | planted species mix | V47,GS,CDM,PV | gap | project planting plan |
survival_rate_pct | % | %, count_ratio | tree survival (PV indicator) | PV,GS | gap | annual count |
tree_count | count | count | census-based ARR tree count | V47-census | gap | GPS field census |
mean_height_m | m | m | stand height (≥2 m forest test for GS) | GS,CDM | gap | field / LiDAR |
crediting_period_years | yr | yr | project lifetime | V47,GS,CDM,PV | live (project-level) | project setting |
2.9 Site-prep & non-CO₂ emissions
| code | canonical | accepts | class | methodologies | C6 | L0 source |
|---|
fertilizer_n_kg_ha | kg N/ha | kg/ha | direct N | V47,GS,CDM | gap | project records |
n2o_emission_factor | dimensionless | unitless | EF1 (IPCC default 0.01) | V47,GS,CDM | gap (in params) | IPCC 2006 Vol. 4 Ch. 11 |
biomass_burning_ha | ha | ha | site-prep / fire-prep area | V47,GS,V7,V48 | partial (fire metrics live) | active-fire products + records |
combustion_completeness | dimensionless | unitless | CC factor | V7,V47,GS | gap (params) | IPCC 2006 Vol. 4 Table 2.6 |
ch4_emission_factor | dimensionless | unitless | g CH₄ / kg dry matter burned | V7,V47,GS | gap (params) | IPCC 2006 Vol. 4 Table 2.5 |
fossil_fuel_co2_t | tCO₂e | tCO₂e, kg | machinery + transport | V47,GS,CDM | gap | project records |
2.10 Fire & disturbance history
| code | canonical | accepts | class | methodologies | C6 | L0 source |
|---|
fire_cumulative_burned_ha | ha | ha | window total | all | live | MapBiomas Fogo |
fire_affected_pct | % | % | derived | all | live | derived |
fire_max_frequency | count | count | per-pixel max event count | all | live | MapBiomas Fogo |
2.11 Leakage
| code | canonical | accepts | class | methodologies | C6 | L0 source |
|---|
leakage_belt_defor_ha_yr | ha/yr | ha/yr | activity-shift detection | V7,V15,V48,V47 | gap | MapBiomas inside leakage belt |
market_leakage_factor_pct | % | % | commodity-shift discount | V7,V48,V47 | gap | VMD0011 default tables or modelled |
pre_project_production_t_yr | t/yr | t/yr, kg/yr | commodity production displaced (ARR) | V47,GS,CDM | gap | farm + statistics |
displaced_production_t_yr | t/yr | t/yr | actual displacement observed | V47 | gap | post-start surveys |
new_forest_cleared_for_displacement_ha | ha | ha | 5-yr post-start leakage area | V47 | gap | satellite of leakage area |
2.12 Uncertainty & QA per pool
| code | canonical | accepts | class | methodologies | C6 | L0 source |
|---|
agb_uncertainty_pct_ci95 | % | % | 95% CI half-width | all | gap | plot variance + RS error |
bgb_uncertainty_pct_ci95 | % | % | 95% CI | all | gap | propagated from AGB or root data |
dw_uncertainty_pct_ci95 | % | % | 95% CI | V7,V47,ART,GS | gap | line-intersect variance |
litter_uncertainty_pct_ci95 | % | % | 95% CI | V7,V47,ART,GS | gap | plot variance |
soc_uncertainty_pct_ci95 | % | % | 95% CI | V7-peat,ART | gap | core variance |
activity_data_uncertainty_pct_ci95 | % | % | RS classification accuracy | V48,ART | gap | confusion-matrix-based |
combined_uncertainty_pct_ci95 | % | % | aggregated | V48,ART | gap | propagation per VMD0017 / TREES |
uncertainty_deduction_pct | % | % | conservativeness deduction applied | V48,ART | gap | derived |
2.13 Buffer / permanence / risk
| code | canonical | accepts | class | methodologies | C6 | L0 source |
|---|
buffer_pct | % | % | non-permanence buffer | all | live (project-level) | risk tool output |
buffer_risk_score | score 0–100 | score | risk tool composite | all | partial (risk_score exists) | VCS Buffer Risk Tool, ART risk tool |
permanence_horizon_years | yr | yr | minimum monitoring period | all | gap (in static dossier) | methodology-specific |
reversal_event_ha | ha | ha | post-start observed reversal | all | gap | satellite + field |
2.14 ART TREES jurisdictional (mostly project-level, but some farm contributes)
| code | canonical | accepts | class | methodologies | C6 | L0 source |
|---|
hfld_score | dimensionless | unitless | forest cover × deforest rate | ART | gap | jurisdictional NFMS |
nfms_emission_factor_tco2e_ha | tCO₂e/ha | tCO₂e/ha, tC/ha | per-stratum NFMS-derived EF | ART | gap | National Forest Inventory |
accounting_area_jurisdiction | text | — | jurisdiction code | ART | gap | project config |
2.15 Plan Vivo non-carbon indicators
Required for issuance under PV. Not “carbon” but blocks credits if missing.
| code | canonical | accepts | class | methodologies | C6 | L0 source |
|---|
livelihood_indicator_score | score 0–100 | score | PV §4.3 | PV | gap | household surveys |
ecosystem_indicator_score | score 0–100 | score | PV §4.4 (biodiversity) | PV | gap | field + RS |
pra_baseline_id | text | — | participatory rural appraisal anchor | PV | gap | community workshops |
2.16 Project-level financial / output (already L2)
These belong in project_computation / vintage_ledger, listed for completeness — they should not be stored as farm_metrics (output, not input).
| code | canonical | C6 | notes |
|---|
gross_capacity_tco2e_yr | tCO₂e/yr | live | methodology output |
net_issuable_tco2e_yr | tCO₂e/yr | live | post leakage + buffer |
lifetime_tco2e | tCO₂e | live | net × crediting period |
headline_price_usd_tco2e | USD/tCO₂e | live | from forecast curve |
annual_credits_kt | kt CO₂e/yr | live | display unit |
aud_annual_credits_kt | kt CO₂e/yr | live | AUD slice |
apd_annual_credits_kt | kt CO₂e/yr | live | APD slice |
3. Coverage matrix — methodologies vs C6 metrics
How complete is C6 today, by methodology?
| Methodology | Total inputs needed | Live in C6 | Partial | Gap | Coverage |
|---|
| VM0007 legacy REDD+ MF | ~25 | 11 | 1 | 13 | 44% |
| VM0009 avoided ecosystem conversion | ~15 | 7 | 1 | 7 | 47% |
| VM0015 AUD legacy | ~20 | 8 | 1 | 11 | 40% |
| VM0048 + VMD0055 new REDD | ~18 | 7 | 0 | 11 | 39% |
| VM0047 ARR | ~22 | 4 | 0 | 18 | 18% |
| ART TREES 2.0 jurisdictional | ~16 | 6 | 1 | 9 | 38% |
| Plan Vivo PV Climate | ~14 | 4 | 0 | 10 | 29% |
| Gold Standard A/R | ~17 | 4 | 0 | 13 | 24% |
| CDM AR-AMS0007 | ~12 | 3 | 0 | 9 | 25% |
REDD coverage is the strongest area (40–47%). ARR and Plan Vivo are weakest (18–29%) — C6 has barely the framework for ARR-only projects today.
4. Gaps prioritized
The big rocks, in order of impact:
P0 — blocks current methodology accuracy
- Carbon pools beyond AGB/BGB/SOC: add
dw_density, litter_density, hwp_carbon. VM0007/V47/ART/GS all need at least DW + litter or a documented de-minimis exclusion. Without these the engine silently under-estimates and mis-applies the conservativeness deduction.
- Allometric provenance:
wood_density_t_m3, allometric_equation_id, carbon_fraction (today buried in app/methodologies/params). Audit defensibility requires per-row traceability to the equation + ρ used.
- Per-pool uncertainty (95% CI):
*_uncertainty_pct_ci95 for AGB, BGB, DW, L, SOC, AD. VM0048 and ART TREES apply quantitative uncertainty deductions at issuance — not having these means engine cannot legitimately deduct.
baseline_source discriminator: enum on the methodology-protocol level. Without this the engine cannot tell “VM0007 historical projection” from “VM0048 jurisdictionally allocated” and mixing logic produces silent errors.
- Stratification table:
stratum_id + forest_type_class + disturbance_class. Today agb is one number per farm; methodologies require per-stratum EFs.
P1 — unlocks ARR / V47
arr_eligible_area_ha, pre_project_land_use_class, pre_project_land_use_years — V47 eligibility.
stocking_index, matched_control_plot_id, matched_control_si_delta — V47 dynamic baseline. New paradigm; not currently representable.
forest_gain_ha per vintage — ART TREES enhancement category + V47 monitoring.
species_planted, survival_rate_pct, tree_count, forest_age_years — ARR project monitoring.
P2 — VM0048 jurisdictional ingestion
jurisdictional_jad_tco2e, allocated_baseline_tco2e_yr, fcbm_forest_ha_t1/t2/t3 — ingest VMD0055 jurisdictional files. Today engine fakes baseline from project rate; under V48 it must be jurisdictional.
- Driver layer ingest:
dist_to_road_m, dist_to_settlement_m, slope_pct, elevation_m — needed even under V48 because EF stratification depends on them.
P3 — Leakage + non-CO₂
leakage_belt_area_ha + leakage_belt_defor_ha_yr + market_leakage_factor_pct — currently project-level compliance_leakage_pct is a hand-set scalar; methodology requires per-belt monitoring.
fertilizer_n_kg_ha, fossil_fuel_co2_t, combustion_completeness, ch4_emission_factor — non-CO₂ project emissions required by V47/GS/CDM.
P4 — Plan Vivo path (only if pursuing PV registry)
livelihood_indicator_score, ecosystem_indicator_score, pra_baseline_id — non-carbon indicators required for PV issuance.
5. Recommended schema changes
5.1 New farm_metrics codes (P0–P3)
Codes to add to lookup_metric_type + app/units/registry.py:
# Pools
dw_density tC/ha
litter_density tC/ha
hwp_carbon tC
non_woody_biomass tC/ha
# Allometric provenance (per-plot side table; only summary on farm)
agb_method enum: field_plot / gedi / vendor / ipcc_default
soc_method enum: tier1 / tier2 / tier3_measured
# Stratification
forest_type_class enum
disturbance_class enum
forest_age_years yr
# ARR
arr_eligible_area_ha ha
degraded_forest_area_ha ha
pre_project_land_use_class enum
pre_project_land_use_years yr
stocking_index dimensionless
species_planted text (multi)
survival_rate_pct %
tree_count count
mean_height_m m
# Activity data extensions
degradation_ha ha
forest_gain_ha ha
jurisdictional_jad_tco2e tCO₂e
allocated_baseline_tco2e_yr tCO₂e/yr
fcbm_forest_ha_t1, _t2, _t3 ha
# Drivers
dist_to_road_m m
dist_to_settlement_m m
dist_to_river_m m
dist_to_prior_clearing_m m
slope_pct %
elevation_m m
tenure_class enum
# Leakage
leakage_belt_area_ha ha
leakage_belt_defor_ha_yr ha/yr
market_leakage_factor_pct %
# Non-CO₂
fertilizer_n_kg_ha kg N/ha
biomass_burning_ha ha
fossil_fuel_co2_t tCO₂e
# Uncertainty (per-pool)
agb_uncertainty_pct_ci95 %
bgb_uncertainty_pct_ci95 %
dw_uncertainty_pct_ci95 %
litter_uncertainty_pct_ci95 %
soc_uncertainty_pct_ci95 %
activity_data_uncertainty_pct_ci95 %
combined_uncertainty_pct_ci95 %
# ART
hfld_score dimensionless
nfms_emission_factor_tco2e_ha tCO₂e/ha
# Plan Vivo
livelihood_indicator_score score 0–100
ecosystem_indicator_score score 0–100
5.2 New side tables (L0 raw observations)
plot_measurements — per-tree DBH, height, species, ρ, plot_id, geom. Used for AGB/BGB derivation. Today AGB lands directly in farm_metrics with no traceability to plots.
plot_definitions — plot polygon, area, sampling protocol, allometric equation used.
stratum — forest type × disturbance × age class. FK from farm_metrics for per-stratum EFs.
leakage_belt — belt geometry per project (separate from project geometry).
control_plot_match — V47 k-NN matched control plot reference + multivariate distance + match date.
jurisdictional_data_file — VMD0055 / ART NFMS files: jurisdiction, file hash, vintage, JAD, FCBM, risk map blob.
5.3 New project-level fields
baseline_source enum on project_methodology_history (or project): historical_projected | jurisdictionally_allocated | dynamic_control_matched | community_PRA | national_NFMS.
accounting_area_jurisdiction text — required when baseline_source = jurisdictional_allocated or national_NFMS.
6. Engine-side principles
- Engine never reads
value_raw. Always reads value_canonical via read_canonical_value(). Already enforced.
- Pool list is methodology-config, not engine-hardcoded.
MethodologyDef.required_inputs already does this; extend it with optional_with_de_minimis_test to model V48’s stricter rules.
- Carbon fraction (CF) and 44/12 stoichiometry happen in the engine when projecting tC → tCO₂e. Storage stays in tC/ha. Already true in the registry — preserve this invariant.
- Uncertainty deductions are explicit. Add a
uncertainty_deduction_tco2e row to vintage_ledger so the receipt shows it. Today the ledger has gross → leakage → buffer → issuable; insert uncertainty between buffer and issuable.
- Leakage and buffer are distinct — never collapse.
vintage_ledger already has both rows; preserve.
baseline_source selects which calculation path the engine takes. Don’t try to unify legacy + jurisdictional in one function.
7. Open questions for the team
- Is C6 doing field plots itself, or always consuming vendor PDFs (Canopy, ClearBlue, C2050)? If always vendor,
plot_measurements becomes ingest of vendor’s plot data; if both, schema needs to support mixed.
- Will C6 ever pursue VM0047 (ARR) or only stay on REDD? P1 gaps are big.
- Is Plan Vivo on the roadmap? P4 work is otherwise wasted.
- For VM0048: does C6 have the relationship with Verra to ingest jurisdictional files directly, or will it consume them via a partner (e.g. Everland, Wildlife Works)?
- Carbon fraction default: today
app/methodologies/params likely uses 0.47 — confirm vs 0.5 (older IPCC default still common in vendor reports).
8. Sources cross-reference
This catalog is a synthesis of:
methodology-inputs-comparison.md (the 112-row methodology survey, sibling file)
app/units/registry.py (canonical-unit invariants)
app/methodologies/{vm0007,vm0048,art_trees,verra_old}.py (current REQUIRED_INPUTS)
migrations/versions/{868f5ac927ad,d8e1c4a3b9f2,d6a3e9b1c4f7}.py (seed data for current 48 metric_types)
docs/needs/units-design.md (the dual-write design)
- IPCC 2006 GL Vol. 4 + 2019 Refinement
- Verra VM0007 v1.8, VM0009 v3.0, VM0015 v1.2, VM0047 v1.1, VM0048 v1.0
- ART TREES 2.0 standard
- Plan Vivo PV Climate Methodology Requirements 1.0
- Gold Standard LUF A/R v2.0
The existing 48 lookup_metric_type rows already cover the REDD baseline well. The biggest single-decision lever is whether C6 commits to ARR + Plan Vivo paths — that determines whether ~30 of the 60 gaps get worked.