-
-
Notifications
You must be signed in to change notification settings - Fork 0
feat(action): composite GitHub Action + Marketplace positioning (gen-1) #43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| # SPDX-License-Identifier: MPL-2.0 | ||
| # SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk> | ||
| # | ||
| # OikosBot composite action — ecological & economic code analysis with | ||
| # Pareto verdicts. Runs the published CLI container (ENTRYPOINT oikosbot), | ||
| # so consumers need no Rust toolchain. See examples/oikosbot-ci.yml for a | ||
| # full workflow and docs/ for interpretation guidance. | ||
| name: 'OikosBot Sustainability Analysis' | ||
| description: >- | ||
| Ecological & economic code analysis: carbon/energy estimates, Pareto | ||
| verdicts on pull requests (improvement / regression / trade-off), and | ||
| SARIF output for GitHub code scanning. Honors the repo's .oikos.yml. | ||
| author: 'Jonathan D.A. Jewell' | ||
| branding: | ||
| icon: 'trending-down' | ||
| color: 'green' | ||
|
|
||
| inputs: | ||
| mode: | ||
| description: 'Subcommand: report (SARIF, default), check (threshold gate), compare (Pareto verdict vs base)' | ||
| required: false | ||
| default: 'report' | ||
| path: | ||
| description: 'Directory to analyze (or head directory for compare)' | ||
| required: false | ||
| default: '.' | ||
| base: | ||
| description: 'Base directory for compare mode (e.g. a checkout of the target branch)' | ||
| required: false | ||
| default: '' | ||
| format: | ||
| description: 'Output format: sarif | json | text' | ||
| required: false | ||
| default: 'sarif' | ||
| output: | ||
| description: 'Output file path (empty = stdout)' | ||
| required: false | ||
| default: 'results.sarif' | ||
| config: | ||
| description: 'Path to .oikos.yml (empty = auto-discover in path)' | ||
| required: false | ||
| default: '' | ||
| eco-threshold: | ||
| description: 'Eco-score floor 0-100 (empty = config value, else 50)' | ||
| required: false | ||
| default: '' | ||
| pr-body: | ||
| description: 'File with the PR description, for the Pareto trade-off documentation check (compare mode)' | ||
| required: false | ||
| default: '' | ||
| check: | ||
| description: 'compare mode: fail on an undocumented, measured Pareto regression/trade-off (true/false)' | ||
| required: false | ||
| default: 'false' | ||
| image: | ||
| description: 'Container image to run' | ||
| required: false | ||
| default: 'ghcr.io/hyperpolymath/oikos:latest' | ||
|
|
||
| outputs: | ||
| output-file: | ||
| description: 'Path of the written output file (when output is set)' | ||
| value: ${{ inputs.output }} | ||
|
hyperpolymath marked this conversation as resolved.
|
||
|
|
||
| runs: | ||
| using: 'composite' | ||
| steps: | ||
| - name: Run oikosbot | ||
| shell: bash | ||
| env: | ||
| MODE: ${{ inputs.mode }} | ||
| TARGET: ${{ inputs.path }} | ||
| BASE: ${{ inputs.base }} | ||
| FORMAT: ${{ inputs.format }} | ||
| OUTFILE: ${{ inputs.output }} | ||
| CONFIG: ${{ inputs.config }} | ||
| THRESHOLD: ${{ inputs.eco-threshold }} | ||
| PR_BODY: ${{ inputs.pr-body }} | ||
| DO_CHECK: ${{ inputs.check }} | ||
| IMAGE: ${{ inputs.image }} | ||
| run: | | ||
| set -euo pipefail | ||
| args=("$MODE") | ||
| case "$MODE" in | ||
| compare) | ||
| [ -n "$BASE" ] || { echo "::error::compare mode requires the 'base' input"; exit 1; } | ||
| args+=("$BASE" "$TARGET") | ||
| [ "$DO_CHECK" = "true" ] && args+=(--check) | ||
| [ -n "$PR_BODY" ] && args+=(--pr-body "$PR_BODY") | ||
| [ "$FORMAT" = "json" ] && args+=(--format json) | ||
| ;; | ||
| report|check) | ||
| args+=("$TARGET" --format "$FORMAT") | ||
| ;; | ||
| *) | ||
| echo "::error::unknown mode '$MODE' (report | check | compare)"; exit 1 | ||
| ;; | ||
| esac | ||
| [ -n "$OUTFILE" ] && args+=(--output "$OUTFILE") | ||
| [ -n "$CONFIG" ] && args+=(--config "$CONFIG") | ||
|
hyperpolymath marked this conversation as resolved.
|
||
| [ -n "$THRESHOLD" ] && args+=(--eco-threshold "$THRESHOLD") | ||
| docker run --rm \ | ||
| --user "$(id -u):$(id -g)" \ | ||
| -v "$GITHUB_WORKSPACE:$GITHUB_WORKSPACE" \ | ||
| -w "$GITHUB_WORKSPACE" \ | ||
| "$IMAGE" "${args[@]}" | ||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| // SPDX-License-Identifier: CC-BY-SA-4.0 | ||
| // SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk> | ||
| = OikosBot vs Climate Warrior: positioning | ||
| :toc: macro | ||
| :icons: font | ||
|
|
||
| _A point-in-time comparison (2026-07-28) against | ||
| https://github.com/marketplace/climate-warrior-official[Climate Warrior Official], | ||
| the closest sustainability-branded product on the GitHub Marketplace. Facts | ||
| about Climate Warrior are taken from its Marketplace listing and | ||
| https://github.com/rollthecloudinc/climatewarrior/wiki/Github-App-Docs[App docs] | ||
| as of that date; corrections welcome._ | ||
|
|
||
| toc::[] | ||
|
|
||
| == Short version | ||
|
|
||
| The two products share the Software Carbon Intensity (SCI) vocabulary and | ||
| almost nothing else. **Climate Warrior is a storage product with carbon | ||
| telemetry** — a GitHub App (category: API Management) that turns repositories | ||
| into versioned JSON document stores ("energy-efficient databases") and records | ||
| SCI for its own operations, mainly lambda executions. **OikosBot is a code | ||
| analyzer with an economics engine** — it reads your source, estimates | ||
| per-function carbon/energy/time/memory, and renders a *Pareto verdict* on | ||
| every change: improvement, regression, or a trade-off that must be documented. | ||
|
|
||
| They are not substitutes. A team could run both without overlap: Climate | ||
| Warrior to store documents with an SCI ledger, OikosBot to review code. | ||
|
|
||
| == Matrix | ||
|
|
||
| [cols="1,2,2",options="header"] | ||
| |=== | ||
| | Dimension | OikosBot | Climate Warrior | ||
|
|
||
| | What it is | ||
| | Code-analysis CLI + GitHub Action (GitHub App planned; AffineScript | ||
| receiver in flight) | ||
| | GitHub App | ||
|
|
||
| | Marketplace category fit | ||
| | Code quality / code scanning (SARIF into the Security tab) | ||
| | API Management (its actual listing category) | ||
|
|
||
| | Unit of analysis | ||
| | Functions and files in your source (tree-sitter AST; Rust, JavaScript, | ||
| Python today) | ||
| | Its own storage/API operations (JSON documents, lambda executions) | ||
|
|
||
| | Metrics | ||
| | Per-function energy (J), carbon (gCO2e), time (ms), memory (bytes); | ||
| Eco/Econ/Quality scores; composite health index | ||
| | Software Carbon Intensity of service operations; historical SCI | ||
|
|
||
| | The economics layer | ||
| | **Pareto engine**: ε-tolerant dominance over weighted, normalized | ||
| objectives; frontier membership + ParetoScore per unit; base-vs-head | ||
| verdicts (improvement / regression / trade-off / neutral); | ||
| EconScore = 0.5·Pareto + 0.3·allocation (shadow prices) + 0.2·debt | ||
| | None (no notion of trade-offs or optimality) | ||
|
|
||
| | PR workflow | ||
| | Verdict per change; trade-offs and regressions ask for a documented | ||
| justification (`Pareto-Trade-off:` trailer, machine-checked); advisor by | ||
| default, regulator opt-in per repo | ||
| | None (not a review tool) | ||
|
|
||
| | Output formats | ||
| | SARIF 2.1.0 (GitHub code scanning, with `pareto_*` properties), JSON, text | ||
| | App-internal; repository documents | ||
|
|
||
| | Configuration | ||
| | `.oikos.yml` per repo: mode, thresholds, excludes, languages | ||
| | App installation settings | ||
|
|
||
| | Methodology transparency | ||
| | Open source (MPL-2.0); estimation model in-tree and SCI-spec-referenced | ||
| (ISO/IEC 21031:2024); every figure carries a confidence label | ||
| (Measured / Calibrated / Estimated / Unknown), and heuristic figures are | ||
| barred from blocking decisions by construction | ||
| | Not disclosed on the listing | ||
|
|
||
| | Pricing / maturity | ||
| | Free, open source, v0.1.x (pre-1.0; App mode not yet live) | ||
| | Free tier ("Squire"); ~16 installs at time of writing | ||
| |=== | ||
|
|
||
| == What OikosBot does not do (honesty section) | ||
|
|
||
| * Estimates are **static heuristics** today (`Confidence::Estimated`), not | ||
| measurements. Runtime calibration and the VeriSimDB-backed praxis loop are | ||
| roadmap items. This is exactly why the confidence gate exists: heuristics | ||
| advise; only measured or calibrated figures may ever block a merge. | ||
| * The GitHub **App** (webhook, PR comments without CI) is not yet live — CI | ||
| Action mode is the generation-1 surface. The App is gated on upstream | ||
| AffineScript stdlib work by deliberate ruling (no interim listener). | ||
| * Language coverage is Rust / JavaScript / Python; listed-but-unsupported | ||
| languages in `.oikos.yml` are ignored loudly, never silently. | ||
| * Climate Warrior's document-storage use case is entirely out of scope: | ||
| OikosBot stores nothing about your repository (until the optional | ||
| VeriSimDB layer lands, and then only where configured). | ||
|
|
||
| == Positioning takeaway | ||
|
|
||
| If a Marketplace listing is pursued, OikosBot belongs in **code quality / | ||
| security (code scanning)** next to linters and SAST tools — not in the | ||
| sustainability-storage niche where Climate Warrior sits. Its differentiator | ||
| is not "we mention carbon" but the **economics**: making every PR answer | ||
| "did this change move us toward or away from the efficient frontier, and if | ||
| it traded something away, did the author say so?" |
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.