feat(carbon): add carbon footprint tracking as core capability#5
Merged
Conversation
Knowledge & skill files:
- CARBON_KNOWLEDGE.md — agent-readable reference table (EcoLogits 2026-03)
gCO₂eq rates for 11 models + DEFAULT, formula, analogies, framework
efficiency table, output format spec, honest caveats
- CARBON_SKILL.md — transversal skill definition: carbon_tracker v0.1.0
inputs/outputs schema, 5-step execution, comparison sub-skill
packages/carbon (new):
- src/index.ts — zero-dependency TypeScript calculator
· RATE_TABLE with 11 models + DEFAULT (EcoLogits 2026-03)
· resolveModelKey(): substring matching, priority-ordered
· calculateCO2(): formula, range bands, per-100k normalisation
· getAnalogy(): human-readable CO₂ comparisons
· CarbonSession: accumulator for multi-call tracking
· compareFrameworks(): sorts by efficiency, savings %, baseline detection
- src/__tests__/carbon.test.ts — 55 tests across all exported functions
· RATE_TABLE structure, completeness, output/input ratio
· resolveModelKey: all models, priority order, case-insensitive, DEFAULT
· calculateCO2: worked example, zero tokens, all models, range bands
· getAnalogy: all scale boundaries, edge cases
· CarbonSession: accumulation, reset, multi-call consistency
· compareFrameworks: sorting, savings, baseline detection, edge cases
site/index.html:
- New "Carbon Footprint" section with responsive two-column layout
(single column on ≤1024px / mobile)
- Live carbon panel: model selector, per-100k metric, session estimate,
framework comparison bar chart, analogy, caveats
- Framework savings table (4D / Linear / Cyclic vs baseline)
- Nav + footer links for #carbon
- window.fluentlySetCarbonModel / fluentlyUpdateCarbonTokens hooks
for future wiring to the Try It runner
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
❌ Test Suite Failed — PR cannot be mergedWhat failedThe test suite did not pass on Node.js Test output (first 4000 characters)How to fix
|
Contributor
❌ Test Suite Failed — PR cannot be mergedWhat failedThe test suite did not pass on Node.js Test output (first 4000 characters)How to fix
|
…Registry
Replace hardcoded RateTableProvider with a pluggable provider architecture:
EmissionsProvider (interface)
- Contract every calculation method must satisfy
- calculate() returns null for unsupported models — registry falls through
RateTableProvider (class, implements EmissionsProvider)
- Existing EcoLogits bottom-up calculation, now encapsulated
- Accepts a custom rateTable in constructor: no subclassing needed
- providerId stamped on every CarbonResult
EmissionsRegistry (class)
- Holds named providers in registration order
- First provider returning non-null wins; falls back to default
- register/unregister/setDefault/get/list API
- calculate() accepts optional providerId for explicit routing
defaultRegistry (module-level singleton)
- Pre-loaded with RateTableProvider as default
- Consumer registers new providers once; all call sites pick them up:
defaultRegistry.register(new AnthropicSDKProvider(), true)
calculateCO2 / CarbonSession / compareFrameworks
- Optional provider parameter at every level
- Omit for global default; inject for per-call or per-session override
CarbonResult now carries providerId field.
ComparisonResult now carries providerId field.
Tests: 72 tests (was 55), covering:
- EmissionsRegistry: register, unregister, default, order, fallback, errors
- RateTableProvider: custom rate table injection, all models
- calculateCO2 / CarbonSession / compareFrameworks with injected providers
- Custom provider end-to-end: model-specific routing, confidence preference
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
❌ Test Suite Failed — PR cannot be mergedWhat failedThe test suite did not pass on Node.js Test output (first 4000 characters)How to fix
|
Contributor
❌ Test Suite Failed — PR cannot be mergedWhat failedThe test suite did not pass on Node.js Test output (first 4000 characters)How to fix
|
- Add packages/carbon/vitest.config.ts (mirrors scorer config) to resolve CJS/ESM conflict when vitest processes carbon tests - Fix "output rate is 5× input rate" test: use toBeCloseTo(5, 10) instead of toBe(5) — floating-point division (e.g. 0.000005/0.000001) produces 5.000000000000001 due to IEEE 754 representation All 202 tests passing locally on Node 20. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
CARBON_KNOWLEDGE.mdandCARBON_SKILL.md— agent-readable reference files for zero-code CO₂ calculationpackages/carbonworkspace with full TypeScript calculator (resolveModelKey,calculateCO2,getAnalogy,CarbonSession,compareFrameworks)site/index.htmlwith live model selector, framework comparison bars, and EcoLogits attributionTest plan
tsc --noEmitclean onpackages/carbon🤖 Generated with Claude Code