From 6f460d24b70fdd79a66248c12dee50a35bf3dd48 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Sun, 19 Apr 2026 01:40:49 +0100 Subject: [PATCH] chore: reconcile meta-repo absorbed content with GitHub main MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two-way merge resolving the structural drift between hyperpolymath/gitbot-fleet (this repo) and the content absorbed into /var/mnt/eclipse/repos (the meta-repo repos-monorepo) at fleet-ecosystem/git-automation-ecosystem/gitbot-fleet/. The two histories had diverged with no common ancestor. Meta-repo held real feature work (exclusion registry, SCM->A2ML directive migration, sha2 0.11 + hmac 0.13 compat fixes, contractile refactors, wave2c sweeps). This repo held a small set of housekeeping commits (LICENSE update to PMPL-1.0-or-later, panic-attacker docs, supervised-fleet-scan GITHUB_TOKEN/FLEET_SCAN_PAT fix, M5 CI sweep, ~7 Dependabot dep bumps) plus an accidentally-committed BuckleScript build artefact set under bots/sustainabot/bot-integration/lib/bs/ (120 files — .cmi/.cmj/.cmt/.ast/.res.js/bindings/). Merge resolution: - Meta-repo content adopted as base (823 tracked files, cleaner .gitignore that correctly excludes the bs/ artefacts). - 45 files modified: meta's versions adopted (newer bot feature work, newer Cargo.toml/.lock with sha2/hmac bumps, newer directive parsers). - 9 files added from meta: exclusion_registry.rs + registry_guard.rs in shared-context/ and robot-repo-automaton/, plus 4 flake.lock / Justfile files that meta had but this repo didn't. - 120 files removed: the accidentally-committed bs/ build artefacts. - LICENSE restored from origin/main (PMPL-1.0-or-later per estate rule; meta's was an older MPL-2.0-labelled version). - .github/workflows/supervised-fleet-scan.yml restored from origin/main (meta's predated the GITHUB_TOKEN/FLEET_SCAN_PAT + HYPATIA_SEVERITY=low fixes from cd67367). No meta-only content was lost in this file. Other GitHub-unique commits verified already present in meta: - 7ae485e3 (panic-attacker docs in finishingbot README) — already in meta. - c6928166 (M5 CI sweep, SCM bot_directives removal) — SCM files already purged in meta per 2026-04-12 A2ML migration; Justfile already imports contractile.just. - Dependabot rand/tokio bumps (#48/#50/#51/#55/#56) — meta has rand 0.10 and tokio 1 at-or-above these versions. After this commit merges, the meta-repo side will remove the absorbed gitbot-fleet/ directory from its tree and re-add it as a submodule pointing at the new origin/main HEAD, eliminating the dual-truth situation. Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitignore | 8 + CONTRIBUTING.md | 2 +- bots/cipherbot/Cargo.lock | 420 ++++++++++- bots/cipherbot/Cargo.toml | 1 + bots/cipherbot/src/policy.rs | 264 ++++--- bots/echidnabot/CHANGELOG.adoc | 2 +- bots/echidnabot/Cargo.lock | 58 ++ bots/echidnabot/RELEASE_CHECKLIST.md | 4 +- bots/echidnabot/RSR_COMPLIANCE.adoc | 4 +- bots/echidnabot/SESSION_SUMMARY_2026-01-29.md | 2 +- bots/echidnabot/flake.lock | 82 ++ bots/echidnabot/src/adapters/github.rs | 21 + bots/echidnabot/src/api/webhooks.rs | 2 +- bots/echidnabot/src/dispatcher/mod.rs | 37 +- bots/finishingbot/Cargo.lock | 3 + bots/finishingbot/src/analyzers/release.rs | 4 +- bots/gsbot/RSR.md | 10 +- bots/panicbot/Cargo.lock | 480 +++++++++++- bots/panicbot/Cargo.toml | 1 + bots/panicbot/src/directives.rs | 242 +++--- bots/rhodibot/Cargo.lock | 507 ++++++++++--- bots/rhodibot/Cargo.toml | 4 +- bots/rhodibot/README.adoc | 4 +- bots/rhodibot/src/github.rs | 14 + bots/rhodibot/src/webhook.rs | 2 +- bots/seambot/Cargo.lock | 64 ++ bots/seambot/Justfile | 33 + bots/seambot/src/github.rs | 12 + bots/sustainabot/Cargo.toml | 2 - bots/sustainabot/Justfile | 39 + .../bot-integration/lib/bs/.sourcedirs.json | 1 - .../bot-integration/lib/bs/bindings/Deno.ast | Bin 15336 -> 0 bytes .../bot-integration/lib/bs/bindings/Deno.cmi | Bin 10968 -> 0 bytes .../bot-integration/lib/bs/bindings/Deno.cmj | Bin 73 -> 0 bytes .../bot-integration/lib/bs/bindings/Deno.cmt | Bin 40002 -> 0 bytes .../bot-integration/lib/bs/bindings/Deno.res | 160 ---- .../lib/bs/bindings/Deno.res.js | 39 - .../bot-integration/lib/bs/bindings/Fetch.ast | Bin 1670 -> 0 bytes .../bot-integration/lib/bs/bindings/Fetch.cmi | Bin 2096 -> 0 bytes .../bot-integration/lib/bs/bindings/Fetch.cmj | Bin 73 -> 0 bytes .../bot-integration/lib/bs/bindings/Fetch.cmt | Bin 7941 -> 0 bytes .../bot-integration/lib/bs/bindings/Fetch.res | 13 - .../lib/bs/bindings/Fetch.res.js | 9 - .../bot-integration/lib/bs/build.ninja | 0 .../bot-integration/lib/bs/compiler-info.json | 8 - .../bot-integration/lib/bs/src/Analysis.ast | Bin 11825 -> 0 bytes .../bot-integration/lib/bs/src/Analysis.cmi | Bin 1944 -> 0 bytes .../bot-integration/lib/bs/src/Analysis.cmj | Bin 135 -> 0 bytes .../bot-integration/lib/bs/src/Analysis.cmt | Bin 35264 -> 0 bytes .../bot-integration/lib/bs/src/Analysis.res | 120 --- .../lib/bs/src/Analysis.res.js | 159 ---- .../bot-integration/lib/bs/src/Config.ast | Bin 7610 -> 0 bytes .../bot-integration/lib/bs/src/Config.cmi | Bin 2219 -> 0 bytes .../bot-integration/lib/bs/src/Config.cmj | Bin 199 -> 0 bytes .../bot-integration/lib/bs/src/Config.cmt | Bin 22974 -> 0 bytes .../bot-integration/lib/bs/src/Config.res | 80 -- .../bot-integration/lib/bs/src/Config.res.js | 99 --- .../bot-integration/lib/bs/src/GitHubAPI.ast | Bin 22046 -> 0 bytes .../bot-integration/lib/bs/src/GitHubAPI.cmi | Bin 3272 -> 0 bytes .../bot-integration/lib/bs/src/GitHubAPI.cmj | Bin 199 -> 0 bytes .../bot-integration/lib/bs/src/GitHubAPI.cmt | Bin 60928 -> 0 bytes .../bot-integration/lib/bs/src/GitHubAPI.res | 177 ----- .../lib/bs/src/GitHubAPI.res.js | 205 ----- .../bot-integration/lib/bs/src/GitHubApp.ast | Bin 28715 -> 0 bytes .../bot-integration/lib/bs/src/GitHubApp.cmi | Bin 2737 -> 0 bytes .../bot-integration/lib/bs/src/GitHubApp.cmj | Bin 247 -> 0 bytes .../bot-integration/lib/bs/src/GitHubApp.cmt | Bin 83057 -> 0 bytes .../bot-integration/lib/bs/src/GitHubApp.res | 234 ------ .../lib/bs/src/GitHubApp.res.js | 238 ------ .../bot-integration/lib/bs/src/Main.ast | Bin 49074 -> 0 bytes .../bot-integration/lib/bs/src/Main.cmi | Bin 3977 -> 0 bytes .../bot-integration/lib/bs/src/Main.cmj | Bin 323 -> 0 bytes .../bot-integration/lib/bs/src/Main.cmt | Bin 121525 -> 0 bytes .../bot-integration/lib/bs/src/Main.res | 422 ----------- .../bot-integration/lib/bs/src/Main.res.js | 451 ----------- .../bot-integration/lib/bs/src/Oikos.ast | Bin 25411 -> 0 bytes .../bot-integration/lib/bs/src/Oikos.cmi | Bin 5375 -> 0 bytes .../bot-integration/lib/bs/src/Oikos.cmj | Bin 153 -> 0 bytes .../bot-integration/lib/bs/src/Oikos.cmt | Bin 64033 -> 0 bytes .../bot-integration/lib/bs/src/Oikos.res | 265 ------- .../bot-integration/lib/bs/src/Oikos.res.js | 309 -------- .../bot-integration/lib/bs/src/Report.ast | Bin 24447 -> 0 bytes .../bot-integration/lib/bs/src/Report.cmi | Bin 2076 -> 0 bytes .../bot-integration/lib/bs/src/Report.cmj | Bin 203 -> 0 bytes .../bot-integration/lib/bs/src/Report.cmt | Bin 60650 -> 0 bytes .../bot-integration/lib/bs/src/Report.res | 212 ------ .../bot-integration/lib/bs/src/Report.res.js | 217 ------ .../bot-integration/lib/bs/src/Router.ast | Bin 22716 -> 0 bytes .../bot-integration/lib/bs/src/Router.cmi | Bin 5005 -> 0 bytes .../bot-integration/lib/bs/src/Router.cmj | Bin 308 -> 0 bytes .../bot-integration/lib/bs/src/Router.cmt | Bin 65783 -> 0 bytes .../bot-integration/lib/bs/src/Router.res | 190 ----- .../bot-integration/lib/bs/src/Router.res.js | 199 ----- .../bot-integration/lib/bs/src/Types.ast | Bin 9047 -> 0 bytes .../bot-integration/lib/bs/src/Types.cmi | Bin 6991 -> 0 bytes .../bot-integration/lib/bs/src/Types.cmj | Bin 68 -> 0 bytes .../bot-integration/lib/bs/src/Types.cmt | Bin 24936 -> 0 bytes .../bot-integration/lib/bs/src/Types.res | 135 ---- .../bot-integration/lib/bs/src/Types.res.js | 2 - .../bot-integration/lib/bs/src/Webhook.ast | Bin 15331 -> 0 bytes .../bot-integration/lib/bs/src/Webhook.cmi | Bin 2100 -> 0 bytes .../bot-integration/lib/bs/src/Webhook.cmj | Bin 174 -> 0 bytes .../bot-integration/lib/bs/src/Webhook.cmt | Bin 39372 -> 0 bytes .../bot-integration/lib/bs/src/Webhook.res | 150 ---- .../bot-integration/lib/bs/src/Webhook.res.js | 138 ---- .../lib/bs/src/tea/ServerTea.ast | Bin 17356 -> 0 bytes .../lib/bs/src/tea/ServerTea.cmi | Bin 4854 -> 0 bytes .../lib/bs/src/tea/ServerTea.cmj | Bin 147 -> 0 bytes .../lib/bs/src/tea/ServerTea.cmt | Bin 51107 -> 0 bytes .../lib/bs/src/tea/ServerTea.res | 148 ---- .../lib/bs/src/tea/ServerTea.res.js | 194 ----- .../bot-integration/lib/ocaml/Analysis.cmi | Bin 1944 -> 0 bytes .../bot-integration/lib/ocaml/Analysis.cmj | Bin 135 -> 0 bytes .../bot-integration/lib/ocaml/Analysis.cmt | Bin 35264 -> 0 bytes .../bot-integration/lib/ocaml/Config.cmi | Bin 2219 -> 0 bytes .../bot-integration/lib/ocaml/Config.cmj | Bin 199 -> 0 bytes .../bot-integration/lib/ocaml/Config.cmt | Bin 22974 -> 0 bytes .../bot-integration/lib/ocaml/Deno.cmi | Bin 10968 -> 0 bytes .../bot-integration/lib/ocaml/Deno.cmj | Bin 73 -> 0 bytes .../bot-integration/lib/ocaml/Deno.cmt | Bin 40002 -> 0 bytes .../bot-integration/lib/ocaml/Fetch.cmi | Bin 2096 -> 0 bytes .../bot-integration/lib/ocaml/Fetch.cmj | Bin 73 -> 0 bytes .../bot-integration/lib/ocaml/Fetch.cmt | Bin 7941 -> 0 bytes .../bot-integration/lib/ocaml/GitHubAPI.cmi | Bin 3272 -> 0 bytes .../bot-integration/lib/ocaml/GitHubAPI.cmj | Bin 199 -> 0 bytes .../bot-integration/lib/ocaml/GitHubAPI.cmt | Bin 60928 -> 0 bytes .../bot-integration/lib/ocaml/GitHubApp.cmi | Bin 2737 -> 0 bytes .../bot-integration/lib/ocaml/GitHubApp.cmj | Bin 247 -> 0 bytes .../bot-integration/lib/ocaml/GitHubApp.cmt | Bin 83057 -> 0 bytes .../bot-integration/lib/ocaml/Main.cmi | Bin 3977 -> 0 bytes .../bot-integration/lib/ocaml/Main.cmj | Bin 323 -> 0 bytes .../bot-integration/lib/ocaml/Main.cmt | Bin 121525 -> 0 bytes .../bot-integration/lib/ocaml/Oikos.cmi | Bin 5375 -> 0 bytes .../bot-integration/lib/ocaml/Oikos.cmj | Bin 153 -> 0 bytes .../bot-integration/lib/ocaml/Oikos.cmt | Bin 64033 -> 0 bytes .../bot-integration/lib/ocaml/Report.cmi | Bin 2076 -> 0 bytes .../bot-integration/lib/ocaml/Report.cmj | Bin 203 -> 0 bytes .../bot-integration/lib/ocaml/Report.cmt | Bin 60650 -> 0 bytes .../bot-integration/lib/ocaml/Router.cmi | Bin 5005 -> 0 bytes .../bot-integration/lib/ocaml/Router.cmj | Bin 308 -> 0 bytes .../bot-integration/lib/ocaml/Router.cmt | Bin 65783 -> 0 bytes .../bot-integration/lib/ocaml/ServerTea.cmi | Bin 4854 -> 0 bytes .../bot-integration/lib/ocaml/ServerTea.cmj | Bin 147 -> 0 bytes .../bot-integration/lib/ocaml/ServerTea.cmt | Bin 51107 -> 0 bytes .../bot-integration/lib/ocaml/Types.cmi | Bin 6991 -> 0 bytes .../bot-integration/lib/ocaml/Types.cmj | Bin 68 -> 0 bytes .../bot-integration/lib/ocaml/Types.cmt | Bin 24936 -> 0 bytes .../bot-integration/lib/ocaml/Webhook.cmi | Bin 2100 -> 0 bytes .../bot-integration/lib/ocaml/Webhook.cmj | Bin 174 -> 0 bytes .../bot-integration/lib/ocaml/Webhook.cmt | Bin 39372 -> 0 bytes .../crates/sustainabot-analysis/Cargo.toml | 1 - .../sustainabot-analysis/src/directives.rs | 262 +++---- bots/sustainabot/flake.lock | 96 +++ bots/sustainabot/nix/flake.lock | 381 ++++++++++ bots/the-hotchocolabot/CHANGELOG.adoc | 2 +- bots/the-hotchocolabot/CHANGELOG.md | 2 +- bots/the-hotchocolabot/HANDOVER.md | 10 +- bots/the-hotchocolabot/RSR_COMPLIANCE.md | 4 +- campaigns/floor-raise-2026-03-20.jsonl | 2 +- .../floor-raise-integrations-2026-03-20.jsonl | 8 +- fleet-coordinator.sh | 4 +- robot-repo-automaton/.gitignore | 8 + robot-repo-automaton/CONTRIBUTING.md | 2 +- .../src/exclusion_registry.rs | 675 +++++++++++++++++ robot-repo-automaton/src/fixer.rs | 29 + robot-repo-automaton/src/github.rs | 15 + robot-repo-automaton/src/lib.rs | 3 + robot-repo-automaton/src/registry_guard.rs | 192 +++++ scripts/fix-deno-permissions.sh | 4 +- shared-context/Cargo.lock | 426 ++++++++++- shared-context/Cargo.toml | 5 + shared-context/src/exclusion_registry.rs | 704 ++++++++++++++++++ shared-context/src/lib.rs | 6 + shared-context/src/registry_guard.rs | 187 +++++ 174 files changed, 4823 insertions(+), 5107 deletions(-) create mode 100644 bots/echidnabot/flake.lock create mode 100644 bots/seambot/Justfile create mode 100644 bots/sustainabot/Justfile delete mode 100644 bots/sustainabot/bot-integration/lib/bs/.sourcedirs.json delete mode 100644 bots/sustainabot/bot-integration/lib/bs/bindings/Deno.ast delete mode 100644 bots/sustainabot/bot-integration/lib/bs/bindings/Deno.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/bs/bindings/Deno.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/bs/bindings/Deno.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/bs/bindings/Deno.res delete mode 100644 bots/sustainabot/bot-integration/lib/bs/bindings/Deno.res.js delete mode 100644 bots/sustainabot/bot-integration/lib/bs/bindings/Fetch.ast delete mode 100644 bots/sustainabot/bot-integration/lib/bs/bindings/Fetch.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/bs/bindings/Fetch.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/bs/bindings/Fetch.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/bs/bindings/Fetch.res delete mode 100644 bots/sustainabot/bot-integration/lib/bs/bindings/Fetch.res.js delete mode 100644 bots/sustainabot/bot-integration/lib/bs/build.ninja delete mode 100644 bots/sustainabot/bot-integration/lib/bs/compiler-info.json delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Analysis.ast delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Analysis.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Analysis.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Analysis.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Analysis.res delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Analysis.res.js delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Config.ast delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Config.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Config.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Config.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Config.res delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Config.res.js delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/GitHubAPI.ast delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/GitHubAPI.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/GitHubAPI.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/GitHubAPI.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/GitHubAPI.res delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/GitHubAPI.res.js delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/GitHubApp.ast delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/GitHubApp.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/GitHubApp.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/GitHubApp.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/GitHubApp.res delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/GitHubApp.res.js delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Main.ast delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Main.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Main.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Main.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Main.res delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Main.res.js delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Oikos.ast delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Oikos.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Oikos.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Oikos.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Oikos.res delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Oikos.res.js delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Report.ast delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Report.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Report.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Report.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Report.res delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Report.res.js delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Router.ast delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Router.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Router.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Router.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Router.res delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Router.res.js delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Types.ast delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Types.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Types.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Types.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Types.res delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Types.res.js delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Webhook.ast delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Webhook.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Webhook.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Webhook.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Webhook.res delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/Webhook.res.js delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/tea/ServerTea.ast delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/tea/ServerTea.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/tea/ServerTea.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/tea/ServerTea.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/tea/ServerTea.res delete mode 100644 bots/sustainabot/bot-integration/lib/bs/src/tea/ServerTea.res.js delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Analysis.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Analysis.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Analysis.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Config.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Config.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Config.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Deno.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Deno.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Deno.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Fetch.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Fetch.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Fetch.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/GitHubAPI.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/GitHubAPI.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/GitHubAPI.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/GitHubApp.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/GitHubApp.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/GitHubApp.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Main.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Main.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Main.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Oikos.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Oikos.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Oikos.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Report.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Report.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Report.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Router.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Router.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Router.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/ServerTea.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/ServerTea.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/ServerTea.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Types.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Types.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Types.cmt delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Webhook.cmi delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Webhook.cmj delete mode 100644 bots/sustainabot/bot-integration/lib/ocaml/Webhook.cmt create mode 100644 bots/sustainabot/flake.lock create mode 100644 bots/sustainabot/nix/flake.lock create mode 100644 robot-repo-automaton/src/exclusion_registry.rs create mode 100644 robot-repo-automaton/src/registry_guard.rs create mode 100644 shared-context/src/exclusion_registry.rs create mode 100644 shared-context/src/registry_guard.rs diff --git a/.gitignore b/.gitignore index 3325a4e..9e06cb1 100644 --- a/.gitignore +++ b/.gitignore @@ -129,3 +129,11 @@ htmlcov/ *.bak # asdf version manager .tool-versions +target/ +node_modules/ +_build/ +deps/ +.elixir_ls/ +.cache/ +build/ +dist/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2e2bafd..50304b3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,7 +42,7 @@ gitbot-fleet/ ├── README.adoc ├── SECURITY.md ├── flake.nix # Nix flake (Perimeter 1) -└── justfile # Task runner (Perimeter 1) +└── Justfile # Task runner (Perimeter 1) ``` --- diff --git a/bots/cipherbot/Cargo.lock b/bots/cipherbot/Cargo.lock index e39866f..9d73676 100644 --- a/bots/cipherbot/Cargo.lock +++ b/bots/cipherbot/Cargo.lock @@ -107,6 +107,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7a4d3ec6524d28a329fc53654bbadc9bdd7b0431f5d65f1a56ffb28a1ee5283" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -198,6 +200,17 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -232,6 +245,15 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + [[package]] name = "fsevent-sys" version = "4.1.0" @@ -241,6 +263,18 @@ dependencies = [ "libc", ] +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi 5.3.0", + "wasip2", +] + [[package]] name = "getrandom" version = "0.4.2" @@ -249,26 +283,48 @@ checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", "libc", - "r-efi", + "r-efi 6.0.0", "wasip2", "wasip3", ] +[[package]] +name = "git2" +version = "0.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b88256088d75a56f8ecfa070513a775dd9107f6530ef14919dac831af9cfe2b" +dependencies = [ + "bitflags 2.11.0", + "libc", + "libgit2-sys", + "log", + "url", +] + [[package]] name = "gitbot-shared-context" version = "0.1.0" dependencies = [ "chrono", + "git2", + "glob", "lexpr", "notify", "serde", "serde_json", "thiserror", "tokio", + "toml", "tracing", "uuid", ] +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + [[package]] name = "hashbrown" version = "0.15.5" @@ -314,12 +370,115 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" + +[[package]] +name = "icu_properties" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" + +[[package]] +name = "icu_provider" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + [[package]] name = "id-arena" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + [[package]] name = "indexmap" version = "2.13.1" @@ -364,6 +523,16 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + [[package]] name = "js-sys" version = "0.3.94" @@ -433,12 +602,42 @@ version = "0.2.184" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" +[[package]] +name = "libgit2-sys" +version = "0.18.3+1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9b3acc4b91781bb0b3386669d325163746af5f6e4f73e6d2d630e09a35f3487" +dependencies = [ + "cc", + "libc", + "libz-sys", + "pkg-config", +] + +[[package]] +name = "libz-sys" +version = "1.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc3a226e576f50782b3305c5ccf458698f92798987f551c6a02efe8276721e22" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" +[[package]] +name = "litemap" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" + [[package]] name = "log" version = "0.4.29" @@ -529,12 +728,33 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + [[package]] name = "pin-project-lite" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "potential_utf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +dependencies = [ + "zerovec", +] + [[package]] name = "prettyplease" version = "0.2.37" @@ -563,6 +783,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "r-efi" version = "6.0.0" @@ -681,6 +907,15 @@ dependencies = [ "zmij", ] +[[package]] +name = "serde_spanned" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +dependencies = [ + "serde_core", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -702,6 +937,12 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + [[package]] name = "strsim" version = "0.11.1" @@ -719,6 +960,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tempfile" version = "3.27.0" @@ -726,7 +978,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom", + "getrandom 0.4.2", "once_cell", "rustix", "windows-sys 0.61.2", @@ -761,6 +1013,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "tinystr" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tokio" version = "1.51.0" @@ -770,6 +1032,45 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "toml" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", +] + +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_parser" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_writer" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" + [[package]] name = "tracing" version = "0.1.44" @@ -843,6 +1144,24 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -855,7 +1174,7 @@ version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" dependencies = [ - "getrandom", + "getrandom 0.4.2", "js-sys", "serde_core", "wasm-bindgen", @@ -867,6 +1186,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "walkdir" version = "2.5.0" @@ -1131,6 +1456,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" +[[package]] +name = "winnow" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" + [[package]] name = "wit-bindgen" version = "0.51.0" @@ -1219,6 +1550,89 @@ dependencies = [ "wasmparser", ] +[[package]] +name = "writeable" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" + +[[package]] +name = "yoke" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerofrom" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerotrie" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zmij" version = "1.0.21" diff --git a/bots/cipherbot/Cargo.toml b/bots/cipherbot/Cargo.toml index 530ce45..639a34e 100644 --- a/bots/cipherbot/Cargo.toml +++ b/bots/cipherbot/Cargo.toml @@ -24,6 +24,7 @@ clap = { version = "4", features = ["derive"] } # Serialization serde = { version = "1", features = ["derive"] } serde_json = "1" +toml = "0.8" # Error handling anyhow = "1" diff --git a/bots/cipherbot/src/policy.rs b/bots/cipherbot/src/policy.rs index deb9e37..a4e1267 100644 --- a/bots/cipherbot/src/policy.rs +++ b/bots/cipherbot/src/policy.rs @@ -1,7 +1,6 @@ // SPDX-License-Identifier: PMPL-1.0-or-later -//! Policy Engine — reads `.machine_readable/bot_directives/cipherbot.scm` -//! (with legacy `.bot_directives/cipherbot.scm` fallback) for repo-specific -//! crypto policy enforcement. +//! Policy Engine — reads `.machine_readable/bot_directives/cipherbot.a2ml` +//! for repo-specific crypto policy enforcement. //! //! Supports: //! - Minimum hash algorithm requirements @@ -9,12 +8,14 @@ //! - Post-quantum requirement enforcement //! - Maximum key age enforcement //! - Exception lists for legacy compatibility modules +//! +//! The SCM form was retired 2026-04-17; no fallback is supported. use serde::{Deserialize, Serialize}; use std::path::Path; /// Cipherbot policy configuration parsed from -/// `.machine_readable/bot_directives/cipherbot.scm` (legacy fallback supported). +/// `.machine_readable/bot_directives/cipherbot.a2ml`. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct CipherbotPolicy { /// Bot name (should be "cipherbot"). @@ -53,73 +54,131 @@ impl Default for CipherbotPolicy { } } +/// Raw A2ML shape for cipherbot policy. +#[derive(Debug, Default, Deserialize)] +struct PolicyFile { + #[serde(default)] + bot: Option, + #[serde(default)] + allow: Option, + #[serde(default)] + scope: Option, + #[serde(default)] + mode: Option, + /// Nested [policy] block (lithoglyph-style) or flat top-level keys. + #[serde(default)] + policy: Option, + #[serde(default, rename = "min-hash")] + min_hash_top: Option, + #[serde(default, rename = "min-symmetric")] + min_symmetric_top: Option, + #[serde(default, rename = "require-pq")] + require_pq_top: Option, + #[serde(default, rename = "max-key-age-days")] + max_key_age_days_top: Option, + #[serde(default, rename = "allowed-exceptions")] + allowed_exceptions_top: Option>, +} + +#[derive(Debug, Default, Deserialize)] +struct PolicyBlock { + #[serde(default, rename = "min-hash")] + min_hash: Option, + #[serde(default, rename = "min-symmetric")] + min_symmetric: Option, + #[serde(default, rename = "require-pq")] + require_pq: Option, + #[serde(default, rename = "max-key-age-days")] + max_key_age_days: Option, + #[serde(default, rename = "allowed-exceptions")] + allowed_exceptions: Option>, +} + +#[derive(Debug, Deserialize)] +#[serde(untagged)] +enum ScopeField { + One(String), + Many(Vec), +} + +#[derive(Debug, Deserialize)] +#[serde(untagged)] +enum AllowField { + Bool(bool), + Scopes(Vec), +} + impl CipherbotPolicy { - /// Load policy from `.machine_readable/bot_directives/cipherbot.scm` in the - /// given repo root (with legacy fallback). - /// - /// Returns default policy if the file doesn't exist or can't be parsed. + /// Load policy from `.machine_readable/bot_directives/cipherbot.a2ml` in + /// the given repo root. Returns default policy if the file doesn't exist + /// or can't be parsed. pub fn load(repo_root: &Path) -> Self { - let policy_path = if repo_root - .join(".machine_readable/bot_directives/cipherbot.scm") - .exists() - { - repo_root.join(".machine_readable/bot_directives/cipherbot.scm") - } else { - repo_root.join(".bot_directives/cipherbot.scm") - }; + let policy_path = repo_root.join(".machine_readable/bot_directives/cipherbot.a2ml"); if !policy_path.exists() { - tracing::info!("No cipherbot.scm policy found, using defaults"); + tracing::info!("No cipherbot.a2ml policy found, using defaults"); return Self::default(); } match std::fs::read_to_string(&policy_path) { - Ok(content) => Self::parse_scm(&content), + Ok(content) => Self::parse_a2ml(&content).unwrap_or_else(|e| { + tracing::warn!("Failed to parse cipherbot.a2ml: {}", e); + Self::default() + }), Err(e) => { - tracing::warn!("Failed to read cipherbot.scm: {}", e); + tracing::warn!("Failed to read cipherbot.a2ml: {}", e); Self::default() } } } - /// Parse a subset of S-expression policy format. - /// - /// This is a simplified parser that extracts key fields from the - /// bot-directive S-expression format. - fn parse_scm(content: &str) -> Self { + /// Parse cipherbot policy from A2ML/TOML content. + fn parse_a2ml(content: &str) -> Result { + let file: PolicyFile = toml::from_str(content)?; let mut policy = Self::default(); - // Extract simple key-value pairs from the S-expression - for line in content.lines() { - let trimmed = line.trim(); - - if let Some(rest) = trimmed.strip_prefix("(mode .") { - if let Some(mode) = extract_string_value(rest) { - policy.mode = mode; - } - } else if let Some(rest) = trimmed.strip_prefix("(min-hash .") { - if let Some(hash) = extract_string_value(rest) { - policy.min_hash = Some(hash); - } - } else if let Some(rest) = trimmed.strip_prefix("(min-symmetric .") { - if let Some(sym) = extract_string_value(rest) { - policy.min_symmetric = Some(sym); - } - } else if let Some(rest) = trimmed.strip_prefix("(require-pq .") { - policy.require_pq = rest.contains("#t"); - } else if let Some(rest) = trimmed.strip_prefix("(max-key-age-days .") { - if let Some(days) = extract_number_value(rest) { - policy.max_key_age_days = Some(days); - } - } else if let Some(rest) = trimmed.strip_prefix("(allow .") { - policy.allow = rest.contains("#t"); - } else if let Some(rest) = trimmed.strip_prefix("(scope .") { - policy.scope = extract_list_values(rest); - } else if let Some(rest) = trimmed.strip_prefix("(allowed-exceptions .") { - policy.allowed_exceptions = extract_list_values(rest); - } + if let Some(name) = file.bot { + policy.name = name; + } + + policy.allow = match file.allow { + Some(AllowField::Bool(b)) => b, + // List-of-scopes implies allow = true. + Some(AllowField::Scopes(_)) => true, + None => policy.allow, + }; + + if let Some(scope) = file.scope { + policy.scope = match scope { + ScopeField::One(s) => vec![s], + ScopeField::Many(v) => v, + }; + } + + if let Some(mode) = file.mode { + policy.mode = mode; + } + + // Nested [policy] block wins; top-level kebab keys are the fallback + // for single-bot files where the author did not introduce a section. + let pb = file.policy.unwrap_or_default(); + + if let Some(h) = pb.min_hash.or(file.min_hash_top) { + policy.min_hash = Some(h); + } + if let Some(s) = pb.min_symmetric.or(file.min_symmetric_top) { + policy.min_symmetric = Some(s); + } + if let Some(b) = pb.require_pq.or(file.require_pq_top) { + policy.require_pq = b; + } + if let Some(d) = pb.max_key_age_days.or(file.max_key_age_days_top) { + policy.max_key_age_days = Some(d); + } + if let Some(ex) = pb.allowed_exceptions.or(file.allowed_exceptions_top) { + policy.allowed_exceptions = ex; } - policy + Ok(policy) } /// Check if a file path is within the policy scope. @@ -140,35 +199,6 @@ impl CipherbotPolicy { } } -/// Extract a quoted string value from an S-expression fragment. -fn extract_string_value(s: &str) -> Option { - let start = s.find('"')?; - let end = s[start + 1..].find('"')?; - Some(s[start + 1..start + 1 + end].to_string()) -} - -/// Extract a numeric value from an S-expression fragment. -fn extract_number_value(s: &str) -> Option { - let trimmed = s.trim().trim_end_matches(')'); - trimmed.trim().parse().ok() -} - -/// Extract a list of string values from an S-expression fragment. -fn extract_list_values(s: &str) -> Vec { - let mut values = Vec::new(); - let mut rest = s; - while let Some(start) = rest.find('"') { - rest = &rest[start + 1..]; - if let Some(end) = rest.find('"') { - values.push(rest[..end].to_string()); - rest = &rest[end + 1..]; - } else { - break; - } - } - values -} - #[cfg(test)] mod tests { use super::*; @@ -183,25 +213,47 @@ mod tests { } #[test] - fn test_parse_scm() { + fn test_parse_a2ml_nested_policy_block() { let content = r#" -(bot-directive - (name . "cipherbot") - (allow . #t) - (scope . ("src" "lib")) - (mode . "regulator") - (policy - (min-hash . "shake3-512") - (min-symmetric . "xchacha20-poly1305") - (require-pq . #t) - (max-key-age-days . 90) - (allowed-exceptions . ("legacy-compat-module")))) +schema_version = "1.0" +bot = "cipherbot" +allow = true +scope = ["src", "lib"] +mode = "regulator" + +[policy] +min-hash = "shake3-512" +min-symmetric = "xchacha20-poly1305" +require-pq = true +max-key-age-days = 90 +allowed-exceptions = ["legacy-compat-module"] "#; - let policy = CipherbotPolicy::parse_scm(content); + let policy = CipherbotPolicy::parse_a2ml(content).unwrap(); assert_eq!(policy.mode, "regulator"); assert!(policy.require_pq); assert_eq!(policy.max_key_age_days, Some(90)); - assert!(policy.allowed_exceptions.contains(&"legacy-compat-module".to_string())); + assert!(policy + .allowed_exceptions + .contains(&"legacy-compat-module".to_string())); + } + + #[test] + fn test_parse_a2ml_flat_toplevel() { + // A directive where the author used only the top-level scalar keys + // (no nested [policy] section) — migrated from a minimal SCM. + let content = r#" +bot = "cipherbot" +allow = true +scope = "src" +mode = "advisor" +min-hash = "sha256" +require-pq = false +"#; + let policy = CipherbotPolicy::parse_a2ml(content).unwrap(); + assert_eq!(policy.mode, "advisor"); + assert_eq!(policy.scope, vec!["src".to_string()]); + assert_eq!(policy.min_hash, Some("sha256".to_string())); + assert!(!policy.require_pq); } #[test] @@ -219,22 +271,4 @@ mod tests { assert!(policy.is_exception(Path::new("src/legacy-compat/old.rs"))); assert!(!policy.is_exception(Path::new("src/main.rs"))); } - - #[test] - fn test_extract_string_value() { - assert_eq!(extract_string_value(r#" "hello")"#), Some("hello".to_string())); - assert_eq!(extract_string_value("no quotes"), None); - } - - #[test] - fn test_extract_number_value() { - assert_eq!(extract_number_value(" 90)"), Some(90)); - assert_eq!(extract_number_value(" abc)"), None); - } - - #[test] - fn test_extract_list_values() { - let values = extract_list_values(r#"("src" "lib" "bin"))"#); - assert_eq!(values, vec!["src", "lib", "bin"]); - } } diff --git a/bots/echidnabot/CHANGELOG.adoc b/bots/echidnabot/CHANGELOG.adoc index b810766..e738c63 100644 --- a/bots/echidnabot/CHANGELOG.adoc +++ b/bots/echidnabot/CHANGELOG.adoc @@ -11,7 +11,7 @@ All notable changes to echidnabot are documented here. === Changed -==== VQL → VCL + verisimdb → verisim Rename (2026-04-05) +==== VCL → VCL + verisimdb → verisim Rename (2026-04-05) Matches the ecosystem-wide rename. Internal identifiers updated, `github.com/hyperpolymath/verisimdb` URLs preserved. diff --git a/bots/echidnabot/Cargo.lock b/bots/echidnabot/Cargo.lock index 425001c..c3dd667 100644 --- a/bots/echidnabot/Cargo.lock +++ b/bots/echidnabot/Cargo.lock @@ -506,6 +506,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7a4d3ec6524d28a329fc53654bbadc9bdd7b0431f5d65f1a56ffb28a1ee5283" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -1554,21 +1556,43 @@ dependencies = [ "wasip3", ] +[[package]] +name = "git2" +version = "0.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b88256088d75a56f8ecfa070513a775dd9107f6530ef14919dac831af9cfe2b" +dependencies = [ + "bitflags 2.11.0", + "libc", + "libgit2-sys", + "log", + "url", +] + [[package]] name = "gitbot-shared-context" version = "0.1.0" dependencies = [ "chrono", + "git2", + "glob", "lexpr", "notify", "serde", "serde_json", "thiserror", "tokio", + "toml", "tracing", "uuid", ] +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + [[package]] name = "group" version = "0.13.0" @@ -2060,6 +2084,16 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + [[package]] name = "js-sys" version = "0.3.94" @@ -2168,6 +2202,18 @@ version = "0.2.184" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" +[[package]] +name = "libgit2-sys" +version = "0.18.3+1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9b3acc4b91781bb0b3386669d325163746af5f6e4f73e6d2d630e09a35f3487" +dependencies = [ + "cc", + "libc", + "libz-sys", + "pkg-config", +] + [[package]] name = "libm" version = "0.2.16" @@ -2197,6 +2243,18 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "libz-sys" +version = "1.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc3a226e576f50782b3305c5ccf458698f92798987f551c6a02efe8276721e22" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" version = "0.12.1" diff --git a/bots/echidnabot/RELEASE_CHECKLIST.md b/bots/echidnabot/RELEASE_CHECKLIST.md index 3829688..97979f2 100644 --- a/bots/echidnabot/RELEASE_CHECKLIST.md +++ b/bots/echidnabot/RELEASE_CHECKLIST.md @@ -7,7 +7,7 @@ Complete checklist for making echidnabot a perfect release. ### Done - [x] README.adoc - SEO-optimized, project-focused - [x] BRANDING.md - Visual identity and LLM art prompts -- [x] justfile - RSR canonical task runner +- [x] Justfile - RSR canonical task runner - [x] Nickel configuration (config/echidnabot.ncl) - [x] MCP configuration (.claude/settings/mcp.json) - [x] STATE.scm - Project checkpoint @@ -137,7 +137,7 @@ Complete checklist for making echidnabot a perfect release. - [x] Cargo.toml metadata complete - [x] guix.scm package definition - [x] Containerfile for Docker/Podman -- [x] justfile for task automation +- [x] Justfile for task automation ### To Add - [ ] flake.nix for Nix users diff --git a/bots/echidnabot/RSR_COMPLIANCE.adoc b/bots/echidnabot/RSR_COMPLIANCE.adoc index afed190..ae9660b 100644 --- a/bots/echidnabot/RSR_COMPLIANCE.adoc +++ b/bots/echidnabot/RSR_COMPLIANCE.adoc @@ -51,7 +51,7 @@ This document describes the Rhodium Standard Repository (RSR) compliance status |No restricted languages outside exemptions |✓ |Only Rust and Guile Scheme |.editorconfig present |✓ |Line length 100, spaces indent |.well-known/ directory |✓ |security.txt, ai.txt, humans.txt, consent-required.txt -|justfile present |✗ |TODO: Add justfile for task running +|justfile present |✗ |TODO: Add Justfile for task running |LICENSE.txt (AGPL + Palimpsest) |✓ |PMPL-1.0-or-later |Containerfile present |✓ |Multi-stage build with Chainguard base |guix.scm present |✓ |Guix package definition (primary) @@ -79,7 +79,7 @@ None == Action Items -* [ ] Add justfile for task running +* [ ] Add Justfile for task running * [ ] Add flake.nix for Nix users (fallback package manager) == References diff --git a/bots/echidnabot/SESSION_SUMMARY_2026-01-29.md b/bots/echidnabot/SESSION_SUMMARY_2026-01-29.md index aa9fe9d..621efda 100644 --- a/bots/echidnabot/SESSION_SUMMARY_2026-01-29.md +++ b/bots/echidnabot/SESSION_SUMMARY_2026-01-29.md @@ -27,7 +27,7 @@ cargo clean && cargo build **Problem:** Cargo.toml had incorrect author email ```toml -authors = ["Jonathan D.A. Jewell "] # WRONG +authors = ["Jonathan D.A. Jewell "] # WRONG ``` **Solution:** diff --git a/bots/echidnabot/flake.lock b/bots/echidnabot/flake.lock new file mode 100644 index 0000000..d8fe172 --- /dev/null +++ b/bots/echidnabot/flake.lock @@ -0,0 +1,82 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1776169885, + "narHash": "sha256-l/iNYDZ4bGOAFQY2q8y5OAfBBtrDAaPuRQqWaFHVRXM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4bd9165a9165d7b5e33ae57f3eecbcb28fb231c9", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1776395632, + "narHash": "sha256-Mi1uF5f2FsdBIvy+v7MtsqxD3Xjhd0ARJdwoqqqPtJo=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "8087ff1f47fff983a1fba70fa88b759f2fd8ae97", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/bots/echidnabot/src/adapters/github.rs b/bots/echidnabot/src/adapters/github.rs index e414f81..fc9db95 100644 --- a/bots/echidnabot/src/adapters/github.rs +++ b/bots/echidnabot/src/adapters/github.rs @@ -102,6 +102,13 @@ impl PlatformAdapter for GitHubAdapter { } async fn create_check_run(&self, repo: &RepoId, check: CheckRun) -> Result { + let full = format!("{}/{}", repo.owner, repo.name); + gitbot_shared_context::registry_guard::check_github_write( + &full, + gitbot_shared_context::ExclusionAction::CreateCheckRun, + ) + .map_err(|e| Error::GitHub(e.to_string()))?; + let checks = self.client.checks(&repo.owner, &repo.name); use octocrab::params::checks::{CheckRunConclusion as OctoConclusion, CheckRunStatus as OctoStatus}; @@ -149,6 +156,13 @@ impl PlatformAdapter for GitHubAdapter { } async fn create_comment(&self, repo: &RepoId, pr: PrId, body: &str) -> Result { + let full = format!("{}/{}", repo.owner, repo.name); + gitbot_shared_context::registry_guard::check_github_write( + &full, + gitbot_shared_context::ExclusionAction::CreateCheckRun, + ) + .map_err(|e| Error::GitHub(e.to_string()))?; + let pr_num: u64 = pr.0.parse().map_err(|_| Error::GitHub("Invalid PR ID".to_string()))?; let comment = self @@ -162,6 +176,13 @@ impl PlatformAdapter for GitHubAdapter { } async fn create_issue(&self, repo: &RepoId, issue: NewIssue) -> Result { + let full = format!("{}/{}", repo.owner, repo.name); + gitbot_shared_context::registry_guard::check_github_write( + &full, + gitbot_shared_context::ExclusionAction::CreateIssue, + ) + .map_err(|e| Error::GitHub(e.to_string()))?; + let created = self .client .issues(&repo.owner, &repo.name) diff --git a/bots/echidnabot/src/api/webhooks.rs b/bots/echidnabot/src/api/webhooks.rs index 27701a8..7c101ee 100644 --- a/bots/echidnabot/src/api/webhooks.rs +++ b/bots/echidnabot/src/api/webhooks.rs @@ -10,7 +10,7 @@ use axum::{ routing::post, Router, }; -use hmac::{Hmac, Mac}; +use hmac::{Hmac, Mac, KeyInit}; use sha2::Sha256; use std::sync::Arc; diff --git a/bots/echidnabot/src/dispatcher/mod.rs b/bots/echidnabot/src/dispatcher/mod.rs index 5514d74..b9c6f7b 100644 --- a/bots/echidnabot/src/dispatcher/mod.rs +++ b/bots/echidnabot/src/dispatcher/mod.rs @@ -29,7 +29,35 @@ pub enum ProofStatus { Unknown, } -/// Prover kind matching ECHIDNA's supported backends +/// Prover kind matching ECHIDNA's supported backends. +/// +/// # DRIFT NOTICE (2026-04-17) +/// +/// This local mirror carries **12 variants**, covering only the classic +/// Tier 1–3 backends. Upstream `echidna::provers::ProverKind` (see +/// `verification-ecosystem/echidna/src/rust/provers/mod.rs`) now carries +/// **89 variants** as of commit `8f573f1`: the classic 49 solver backends +/// plus the 40-variant HP-ecosystem TypeDiscipline family (linear, affine, +/// phantom, modal, tropical, epistemic, choreographic, …). +/// +/// The mirror is intentionally NOT extended here today. Compile-time effect +/// is zero — this enum stands on its own, and `from_extension` / `tier` / +/// `display_name` / `file_extensions` are all total over its 12 variants. +/// Runtime effect IS present: proofs tagged with an HP-ecosystem discipline +/// that reaches echidnabot will be routed as "unrecognised" by +/// `from_extension`, even though the upstream echidna dispatcher would +/// handle them fine. +/// +/// Phase-2 decision (tracked in AI-WORK-todo.md): either (a) extend this +/// mirror to the full 89 variants with a code-generation tool that reads +/// echidna's enum at build time, or (b) switch echidnabot to a path-dep on +/// echidna so `ProverKind` is shared by construction. Option (b) is cleaner +/// but requires breaking the current self-contained deployment. Option (a) +/// is a stepping stone. +/// +/// See `standards/testing-and-benchmarking/TESTING-TAXONOMY.adoc` § Part VI +/// CR-1 "Mirror-enum drift test" and CR-2 "Foreign-enum exhaustive-match +/// lint" for the general pattern and the proposed estate-wide fix. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] pub enum ProverKind { @@ -48,6 +76,13 @@ pub enum ProverKind { Pvs, Acl2, Hol4, + // Intentional gap vs echidna upstream — see DRIFT NOTICE above. + // NOT added here: FStar, Dafny, Why3, TLAPS, Twelf, Nuprl, Minlog, + // Imandra, Vampire, EProver, SPASS, AltErgo, GLPK, SCIP, MiniZinc, + // Chuffed, ORTools, TypedWasm, SPIN, CBMC, SeaHorn, CaDiCaL, Kissat, + // MiniSat, NuSMV, TLC, Alloy, Prism, UPPAAL, FramaC, Viper, Tamarin, + // ProVerif, KeY, DReal, ABC, Idris2 (the 37 classic backends beyond + // Tier 1–3) + the 40 HP-ecosystem TypeDiscipline variants. } impl ProverKind { diff --git a/bots/finishingbot/Cargo.lock b/bots/finishingbot/Cargo.lock index 33ffec5..b7b99e3 100644 --- a/bots/finishingbot/Cargo.lock +++ b/bots/finishingbot/Cargo.lock @@ -634,12 +634,15 @@ name = "gitbot-shared-context" version = "0.1.0" dependencies = [ "chrono", + "git2", + "glob", "lexpr", "notify", "serde", "serde_json", "thiserror", "tokio", + "toml", "tracing", "uuid", ] diff --git a/bots/finishingbot/src/analyzers/release.rs b/bots/finishingbot/src/analyzers/release.rs index 2787d0a..274e23b 100644 --- a/bots/finishingbot/src/analyzers/release.rs +++ b/bots/finishingbot/src/analyzers/release.rs @@ -359,11 +359,11 @@ impl ReleaseAnalyzer { { let mut hasher = Sha512::new(); hasher.update(&file_content); - format!("{:x}", hasher.finalize()) + hex::encode(hasher.finalize()) } else { let mut hasher = Sha256::new(); hasher.update(&file_content); - format!("{:x}", hasher.finalize()) + hex::encode(hasher.finalize()) }; if actual_hash.to_lowercase() != expected_hash.to_lowercase() { diff --git a/bots/gsbot/RSR.md b/bots/gsbot/RSR.md index 1d648a4..c096a73 100644 --- a/bots/gsbot/RSR.md +++ b/bots/gsbot/RSR.md @@ -28,7 +28,7 @@ We currently achieve **Bronze-level** RSR compliance for a Python project. ### ✅ Build System (Complete) -- ✅ justfile - Just build recipes (20+ commands) +- ✅ Justfile - Just build recipes (20+ commands) - ✅ Makefile - Make build recipes (traditional alternative) - ✅ setup.py - Python package configuration - ✅ requirements.txt - Dependency management @@ -109,7 +109,7 @@ We currently achieve **Bronze-level** RSR compliance for a Python project. **Required:** - ✅ All documentation files - ✅ .well-known/ directory -- ✅ Build system (justfile or Makefile) +- ✅ Build system (Justfile or Makefile) - ✅ CI/CD pipeline - ✅ Test suite with >80% coverage - ✅ TPCF declaration @@ -144,7 +144,7 @@ We currently achieve **Bronze-level** RSR compliance for a Python project. | Category | Status | Notes | |----------|--------|-------| | Documentation | ✅ Complete | 7 core docs + 3 .well-known | -| Build System | ✅ Complete | justfile + Makefile | +| Build System | ✅ Complete | Justfile + Makefile | | CI/CD | ✅ Complete | GitHub Actions, 4 Python versions | | Testing | ✅ Complete | Unit + integration, >80% coverage | | TPCF | ✅ Complete | Perimeter 3 declared | @@ -169,7 +169,7 @@ Or manually: ls -la *.md .well-known/ # Check build system -ls -la justfile Makefile setup.py +ls -la Justfile Makefile setup.py # Check tests pytest tests/ -v @@ -289,7 +289,7 @@ These are inherent to the bot's purpose and documented. - ✅ Bronze-level RSR compliance achieved - ✅ All required documentation - ✅ .well-known/ directory complete -- ✅ Build system (justfile + Makefile) +- ✅ Build system (Justfile + Makefile) - ✅ CI/CD pipeline operational - ✅ Test suite with good coverage - ✅ TPCF Perimeter 3 declared diff --git a/bots/panicbot/Cargo.lock b/bots/panicbot/Cargo.lock index 7687d34..9831b1c 100644 --- a/bots/panicbot/Cargo.lock +++ b/bots/panicbot/Cargo.lock @@ -107,6 +107,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7a4d3ec6524d28a329fc53654bbadc9bdd7b0431f5d65f1a56ffb28a1ee5283" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -182,6 +184,17 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -216,6 +229,15 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + [[package]] name = "fsevent-sys" version = "4.1.0" @@ -225,6 +247,18 @@ dependencies = [ "libc", ] +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi 5.3.0", + "wasip2", +] + [[package]] name = "getrandom" version = "0.4.2" @@ -233,26 +267,48 @@ checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", "libc", - "r-efi", + "r-efi 6.0.0", "wasip2", "wasip3", ] +[[package]] +name = "git2" +version = "0.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b88256088d75a56f8ecfa070513a775dd9107f6530ef14919dac831af9cfe2b" +dependencies = [ + "bitflags 2.11.0", + "libc", + "libgit2-sys", + "log", + "url", +] + [[package]] name = "gitbot-shared-context" version = "0.1.0" dependencies = [ "chrono", + "git2", + "glob", "lexpr", "notify", "serde", "serde_json", "thiserror", "tokio", + "toml 1.1.2+spec-1.1.0", "tracing", "uuid", ] +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + [[package]] name = "hashbrown" version = "0.15.5" @@ -298,12 +354,115 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" + +[[package]] +name = "icu_properties" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" + +[[package]] +name = "icu_provider" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + [[package]] name = "id-arena" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + [[package]] name = "indexmap" version = "2.13.1" @@ -348,6 +507,16 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + [[package]] name = "js-sys" version = "0.3.94" @@ -417,12 +586,42 @@ version = "0.2.184" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" +[[package]] +name = "libgit2-sys" +version = "0.18.3+1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9b3acc4b91781bb0b3386669d325163746af5f6e4f73e6d2d630e09a35f3487" +dependencies = [ + "cc", + "libc", + "libz-sys", + "pkg-config", +] + +[[package]] +name = "libz-sys" +version = "1.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc3a226e576f50782b3305c5ccf458698f92798987f551c6a02efe8276721e22" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" +[[package]] +name = "litemap" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" + [[package]] name = "log" version = "0.4.29" @@ -524,17 +723,39 @@ dependencies = [ "serde", "serde_json", "tempfile", + "toml 0.8.23", "tracing", "tracing-subscriber", "uuid", ] +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + [[package]] name = "pin-project-lite" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "potential_utf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +dependencies = [ + "zerovec", +] + [[package]] name = "prettyplease" version = "0.2.37" @@ -563,6 +784,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "r-efi" version = "6.0.0" @@ -669,6 +896,24 @@ dependencies = [ "zmij", ] +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_spanned" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +dependencies = [ + "serde_core", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -690,6 +935,12 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + [[package]] name = "strsim" version = "0.11.1" @@ -707,6 +958,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tempfile" version = "3.27.0" @@ -714,7 +976,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom", + "getrandom 0.4.2", "once_cell", "rustix", "windows-sys 0.61.2", @@ -749,6 +1011,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "tinystr" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tokio" version = "1.51.0" @@ -758,6 +1030,86 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_edit", +] + +[[package]] +name = "toml" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned 1.1.1", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 1.0.1", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_write", + "winnow 0.7.15", +] + +[[package]] +name = "toml_parser" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +dependencies = [ + "winnow 1.0.1", +] + +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + +[[package]] +name = "toml_writer" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" + [[package]] name = "tracing" version = "0.1.44" @@ -831,6 +1183,24 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -843,7 +1213,7 @@ version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" dependencies = [ - "getrandom", + "getrandom 0.4.2", "js-sys", "serde_core", "wasm-bindgen", @@ -855,6 +1225,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "walkdir" version = "2.5.0" @@ -1119,6 +1495,21 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" +[[package]] +name = "winnow" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" + [[package]] name = "wit-bindgen" version = "0.51.0" @@ -1207,6 +1598,89 @@ dependencies = [ "wasmparser", ] +[[package]] +name = "writeable" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" + +[[package]] +name = "yoke" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerofrom" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerotrie" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zmij" version = "1.0.21" diff --git a/bots/panicbot/Cargo.toml b/bots/panicbot/Cargo.toml index 2ff3066..c8d92bf 100644 --- a/bots/panicbot/Cargo.toml +++ b/bots/panicbot/Cargo.toml @@ -24,6 +24,7 @@ clap = { version = "4", features = ["derive"] } # Serialization serde = { version = "1", features = ["derive"] } serde_json = "1" +toml = "0.8" # Error handling anyhow = "1" diff --git a/bots/panicbot/src/directives.rs b/bots/panicbot/src/directives.rs index 98e1fbd..b3c892c 100644 --- a/bots/panicbot/src/directives.rs +++ b/bots/panicbot/src/directives.rs @@ -1,33 +1,37 @@ // SPDX-License-Identifier: PMPL-1.0-or-later -//! Directives — per-repo configuration parser for `.machine_readable/bot_directives/panicbot.scm`. +//! Directives — per-repo configuration parser for `.machine_readable/bot_directives/panicbot.a2ml`. //! -//! Each repository can customise panicbot's behaviour via a Scheme-formatted -//! directive file. If no directive file exists, safe defaults are used: +//! Each repository can customise panicbot's behaviour via a TOML-shaped A2ML +//! file. If no directive file exists, safe defaults are used: //! - Allow: `assail`, `adjudicate`, `diagnostics` (static analysis only) //! - Deny: all dynamic attack modes (`attack`, `assault`, `ambush`, etc.) //! - Min severity: `low` (report everything) //! - Timeout: 300 seconds //! -//! ## Directive Format +//! ## Directive Format (A2ML / TOML-shaped) //! -//! ```scheme -//! (bot-directive -//! (bot "panicbot") -//! (scope "static-analysis") -//! (allow ("assail" "adjudicate" "diagnostics")) -//! (deny ("attack" "assault" "ambush" "amuck" "abduct" "axial")) -//! (config -//! (min-severity "low") -//! (timeout-seconds 300))) +//! ```toml +//! schema_version = "1.0" +//! bot = "panicbot" +//! scope = "static-analysis" +//! allow = ["assail", "adjudicate", "diagnostics"] +//! deny = ["attack", "assault", "ambush", "amuck", "abduct", "axial"] +//! +//! [config] +//! min-severity = "low" +//! timeout-seconds = 300 //! ``` +//! +//! The SCM form was retired 2026-04-17; no fallback is supported. use crate::config::{AllowedCommands, MinSeverity, PanicbotConfig}; use anyhow::{Context, Result}; +use serde::Deserialize; use std::path::Path; use std::time::Duration; /// Path to the bot directive file within a repository. -const DIRECTIVE_PATH: &str = ".machine_readable/bot_directives/panicbot.scm"; +const DIRECTIVE_PATH: &str = ".machine_readable/bot_directives/panicbot.a2ml"; /// Load panicbot configuration from a repository's directive file. /// @@ -52,17 +56,34 @@ pub fn load_directives(repo_path: &Path) -> Result { .with_context(|| format!("Failed to parse {}", directive_file.display())) } -/// Parse a panicbot directive from its Scheme-formatted content. -/// -/// This is a lightweight parser that extracts key-value pairs from the -/// S-expression format without requiring a full Scheme interpreter. -/// We look for specific patterns rather than doing a full parse. +/// Raw A2ML shape. +#[derive(Debug, Default, Deserialize)] +struct DirectiveFile { + #[serde(default)] + allow: Option>, + #[serde(default)] + config: Option, + #[serde(default, rename = "min-severity")] + min_severity_top: Option, + #[serde(default, rename = "timeout-seconds")] + timeout_seconds_top: Option, +} + +#[derive(Debug, Default, Deserialize)] +struct ConfigBlock { + #[serde(default, rename = "min-severity")] + min_severity: Option, + #[serde(default, rename = "timeout-seconds")] + timeout_seconds: Option, +} + +/// Parse a panicbot directive from its A2ML/TOML content. fn parse_directive(content: &str) -> Result { let mut config = PanicbotConfig::default(); + let file: DirectiveFile = toml::from_str(content).context("Failed to parse TOML")?; - // Extract allow list - if let Some(allow_str) = extract_list(content, "allow") { - let allowed: Vec = parse_string_list(&allow_str); + // Allow list + if let Some(allowed) = file.allow { config.allowed_commands = AllowedCommands { assail: allowed.iter().any(|s| s == "assail"), adjudicate: allowed.iter().any(|s| s == "adjudicate"), @@ -70,99 +91,33 @@ fn parse_directive(content: &str) -> Result { }; } - // Extract min-severity from config block - if let Some(severity_str) = extract_config_value(content, "min-severity") { - if let Some(severity) = MinSeverity::from_str(&severity_str) { - config.min_severity = severity; + // min-severity: prefer [config] block, fall back to top-level kebab key. + let severity_str = file + .config + .as_ref() + .and_then(|c| c.min_severity.clone()) + .or(file.min_severity_top); + if let Some(s) = severity_str { + if let Some(sev) = MinSeverity::from_str(&s) { + config.min_severity = sev; } else { - tracing::warn!("Unknown min-severity '{}', using default", severity_str); + tracing::warn!("Unknown min-severity '{}', using default", s); } } - // Extract timeout from config block - if let Some(timeout_str) = extract_config_value(content, "timeout-seconds") { - if let Ok(seconds) = timeout_str.parse::() { - config.timeout = Duration::from_secs(seconds); - } else { - tracing::warn!("Invalid timeout-seconds '{}', using default", timeout_str); - } + // timeout-seconds: same precedence. + let timeout_seconds = file + .config + .as_ref() + .and_then(|c| c.timeout_seconds) + .or(file.timeout_seconds_top); + if let Some(secs) = timeout_seconds { + config.timeout = Duration::from_secs(secs); } Ok(config) } -/// Extract a parenthesised list value for a given key. -/// -/// For input `(allow ("assail" "adjudicate"))`, returns `"assail" "adjudicate"`. -fn extract_list(content: &str, key: &str) -> Option { - let pattern = format!("({}", key); - let start = content.find(&pattern)?; - let rest = &content[start + pattern.len()..]; - - // Find the opening paren of the list - let list_start = rest.find('(')?; - let list_content = &rest[list_start + 1..]; - - // Find the matching closing paren - let list_end = list_content.find(')')?; - Some(list_content[..list_end].to_string()) -} - -/// Extract a config value for a given key from a `(config ...)` block. -/// -/// For input `(config (min-severity "low"))`, with key "min-severity", -/// returns "low". -fn extract_config_value(content: &str, key: &str) -> Option { - let pattern = format!("({}", key); - let start = content.find(&pattern)?; - let rest = &content[start + pattern.len()..]; - - // Find the value — could be a quoted string or a bare number - let trimmed = rest.trim_start(); - - if trimmed.starts_with('"') { - // Quoted string value - let after_quote = &trimmed[1..]; - let end_quote = after_quote.find('"')?; - Some(after_quote[..end_quote].to_string()) - } else { - // Bare value (number, identifier) - let end = trimmed.find(|c: char| c == ')' || c.is_whitespace())?; - Some(trimmed[..end].to_string()) - } -} - -/// Parse a space-separated list of quoted strings. -/// -/// Input: `"assail" "adjudicate" "diagnostics"` -/// Output: `["assail", "adjudicate", "diagnostics"]` -fn parse_string_list(input: &str) -> Vec { - let mut result = Vec::new(); - let mut chars = input.chars().peekable(); - - while let Some(&c) = chars.peek() { - if c == '"' { - chars.next(); // consume opening quote - let mut s = String::new(); - while let Some(&c2) = chars.peek() { - if c2 == '"' { - chars.next(); // consume closing quote - break; - } - s.push(c2); - chars.next(); - } - if !s.is_empty() { - result.push(s); - } - } else { - chars.next(); // skip whitespace/other - } - } - - result -} - #[cfg(test)] mod tests { use super::*; @@ -170,16 +125,15 @@ mod tests { #[test] fn test_parse_default_directive() { let content = r#" -;; SPDX-License-Identifier: PMPL-1.0-or-later - -(bot-directive - (bot "panicbot") - (scope "static-analysis") - (allow ("assail" "adjudicate" "diagnostics")) - (deny ("attack" "assault" "ambush" "amuck" "abduct" "axial")) - (config - (min-severity "low") - (timeout-seconds 300))) +schema_version = "1.0" +bot = "panicbot" +scope = "static-analysis" +allow = ["assail", "adjudicate", "diagnostics"] +deny = ["attack", "assault", "ambush", "amuck", "abduct", "axial"] + +[config] +min-severity = "low" +timeout-seconds = 300 "#; let config = parse_directive(content).unwrap(); @@ -193,13 +147,12 @@ mod tests { #[test] fn test_parse_restricted_directive() { let content = r#" -(bot-directive - (bot "panicbot") - (scope "static-analysis") - (allow ("assail")) - (config - (min-severity "high") - (timeout-seconds 60))) +bot = "panicbot" +allow = ["assail"] + +[config] +min-severity = "high" +timeout-seconds = 60 "#; let config = parse_directive(content).unwrap(); @@ -213,7 +166,7 @@ mod tests { #[test] fn test_parse_empty_content() { let config = parse_directive("").unwrap(); - // Should return defaults + // Should return defaults (TOML parses empty as empty struct) assert!(config.allowed_commands.assail); assert!(config.allowed_commands.adjudicate); assert!(config.allowed_commands.diagnostics); @@ -221,37 +174,18 @@ mod tests { } #[test] - fn test_extract_list() { - let content = r#"(allow ("assail" "adjudicate"))"#; - let list = extract_list(content, "allow").unwrap(); - assert_eq!(list, r#""assail" "adjudicate""#); - } - - #[test] - fn test_extract_config_value_string() { - let content = r#"(min-severity "high")"#; - let val = extract_config_value(content, "min-severity").unwrap(); - assert_eq!(val, "high"); - } - - #[test] - fn test_extract_config_value_number() { - let content = r#"(timeout-seconds 600)"#; - let val = extract_config_value(content, "timeout-seconds").unwrap(); - assert_eq!(val, "600"); - } - - #[test] - fn test_parse_string_list() { - let input = r#""assail" "adjudicate" "diagnostics""#; - let result = parse_string_list(input); - assert_eq!(result, vec!["assail", "adjudicate", "diagnostics"]); - } + fn test_parse_top_level_kebab_fallback() { + // Some older files flatten min-severity to the top level. + let content = r#" +bot = "panicbot" +allow = ["assail", "diagnostics"] +min-severity = "critical" +timeout-seconds = 120 +"#; - #[test] - fn test_parse_string_list_empty() { - let result = parse_string_list(""); - assert!(result.is_empty()); + let config = parse_directive(content).unwrap(); + assert_eq!(config.min_severity, MinSeverity::Critical); + assert_eq!(config.timeout, Duration::from_secs(120)); } #[test] diff --git a/bots/rhodibot/Cargo.lock b/bots/rhodibot/Cargo.lock index 9f359af..de2d22c 100644 --- a/bots/rhodibot/Cargo.lock +++ b/bots/rhodibot/Cargo.lock @@ -84,9 +84,9 @@ checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "arc-swap" -version = "1.9.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a07d1f37ff60921c83bdfc7407723bdefe89b44b98a9b772f225c8f9d67141a6" +checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207" dependencies = [ "rustversion", ] @@ -115,9 +115,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "axum" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" +checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" dependencies = [ "axum-core", "bytes", @@ -179,9 +179,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" [[package]] name = "block-buffer" @@ -232,11 +232,13 @@ checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cc" -version = "1.2.59" +version = "1.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7a4d3ec6524d28a329fc53654bbadc9bdd7b0431f5d65f1a56ffb28a1ee5283" +checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -268,9 +270,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.6.0" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" dependencies = [ "clap_builder", "clap_derive", @@ -290,9 +292,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.6.0" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a" +checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" dependencies = [ "heck", "proc-macro2", @@ -339,6 +341,15 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + [[package]] name = "cpufeatures" version = "0.3.0" @@ -357,6 +368,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + [[package]] name = "crypto-common" version = "0.1.7" @@ -385,6 +402,20 @@ dependencies = [ "cmov", ] +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "deadpool" version = "0.12.3" @@ -413,17 +444,6 @@ dependencies = [ "crypto-common 0.1.7", ] -[[package]] -name = "digest" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c" -dependencies = [ - "block-buffer 0.12.0", - "crypto-common 0.2.1", - "ctutils", -] - [[package]] name = "digest" version = "0.11.2" @@ -433,6 +453,7 @@ dependencies = [ "block-buffer 0.12.0", "const-oid", "crypto-common 0.2.1", + "ctutils", ] [[package]] @@ -495,9 +516,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.3.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "filetime" @@ -690,17 +711,33 @@ dependencies = [ "wasip3", ] +[[package]] +name = "git2" +version = "0.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b88256088d75a56f8ecfa070513a775dd9107f6530ef14919dac831af9cfe2b" +dependencies = [ + "bitflags 2.11.1", + "libc", + "libgit2-sys", + "log", + "url", +] + [[package]] name = "gitbot-shared-context" version = "0.1.0" dependencies = [ "chrono", + "git2", + "glob", "lexpr", "notify", "serde", "serde_json", "thiserror", "tokio", + "toml", "tracing", "uuid", ] @@ -712,13 +749,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0473c64d9ccbcfb9953a133b47c8b9a335b87ac6c52b983ee4b03d49000b0f3f" dependencies = [ "gix-actor", + "gix-archive", "gix-attributes", + "gix-blame", "gix-command", "gix-commitgraph", "gix-config", "gix-credentials", "gix-date", "gix-diff", + "gix-dir", "gix-discover", "gix-error", "gix-features", @@ -730,6 +770,7 @@ dependencies = [ "gix-ignore", "gix-index", "gix-lock", + "gix-merge", "gix-negotiate", "gix-object", "gix-odb", @@ -744,6 +785,7 @@ dependencies = [ "gix-revwalk", "gix-sec", "gix-shallow", + "gix-status", "gix-submodule", "gix-tempfile", "gix-trace", @@ -753,6 +795,8 @@ dependencies = [ "gix-utils", "gix-validate", "gix-worktree", + "gix-worktree-state", + "gix-worktree-stream", "nonempty", "smallvec", "thiserror", @@ -770,6 +814,19 @@ dependencies = [ "winnow 0.7.15", ] +[[package]] +name = "gix-archive" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "651c99be11aac9b303483193ae50b45eb6e094da4f5ed797019b03948f51aad6" +dependencies = [ + "bstr", + "gix-date", + "gix-error", + "gix-object", + "gix-worktree-stream", +] + [[package]] name = "gix-attributes" version = "0.31.0" @@ -796,6 +853,26 @@ dependencies = [ "gix-error", ] +[[package]] +name = "gix-blame" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77aaf9f7348f4da3ebfbfbbc35fa0d07155d98377856198dde6f695fd648705" +dependencies = [ + "gix-commitgraph", + "gix-date", + "gix-diff", + "gix-error", + "gix-hash", + "gix-object", + "gix-revwalk", + "gix-trace", + "gix-traverse", + "gix-worktree", + "smallvec", + "thiserror", +] + [[package]] name = "gix-chunk" version = "0.7.0" @@ -858,7 +935,7 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "441a300bc3645a1f45cba495b9175f90f47256ce43f2ee161da0031e3ac77c92" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "bstr", "gix-path", "libc", @@ -903,8 +980,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88f3b3475e5d3877d7c30c40827cc2441936ce890efc226e5ba4afe3a7ae33f0" dependencies = [ "bstr", + "gix-command", + "gix-filter", + "gix-fs", "gix-hash", "gix-object", + "gix-path", + "gix-tempfile", + "gix-trace", + "gix-traverse", + "gix-worktree", + "imara-diff 0.1.8", + "imara-diff 0.2.0", + "thiserror", +] + +[[package]] +name = "gix-dir" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5da4604a360988f0ba8efe6f90093ca5a844f4a7f8e1a3dcda501ec44e600ea9" +dependencies = [ + "bstr", + "gix-discover", + "gix-fs", + "gix-ignore", + "gix-index", + "gix-object", + "gix-path", + "gix-pathspec", + "gix-trace", + "gix-utils", + "gix-worktree", "thiserror", ] @@ -938,6 +1045,7 @@ version = "0.46.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "752493cd4b1d5eaaa0138a7493f65c96863fefa990fc021e0e519579e389ab20" dependencies = [ + "bytes", "crc32fast", "gix-path", "gix-trace", @@ -991,7 +1099,7 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b03e6cd88cc0dc1eafa1fddac0fb719e4e74b6ea58dd016e71125fde4a326bee" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "bstr", "gix-features", "gix-path", @@ -1005,6 +1113,7 @@ checksum = "0fb896a02d9ab96fa518475a5f30ad3952010f801a8de5840f633f4a6b985dfb" dependencies = [ "faster-hex", "gix-features", + "sha1-checked", "thiserror", ] @@ -1038,7 +1147,7 @@ version = "0.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bae54ab14e4e74d5dda60b82ea7afad7c8eb3be68283d6d5f29bd2e6d47fff7" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "bstr", "filetime", "fnv", @@ -1071,13 +1180,39 @@ dependencies = [ "thiserror", ] +[[package]] +name = "gix-merge" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4606747466512d22c2dffc019142e1941238f543987ea51353c938cca80c500" +dependencies = [ + "bstr", + "gix-command", + "gix-diff", + "gix-filter", + "gix-fs", + "gix-hash", + "gix-index", + "gix-object", + "gix-path", + "gix-quote", + "gix-revision", + "gix-revwalk", + "gix-tempfile", + "gix-trace", + "gix-worktree", + "imara-diff 0.1.8", + "nonempty", + "thiserror", +] + [[package]] name = "gix-negotiate" version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ea064c7595eea08fdd01c70748af747d9acc40f727b61f4c8a2145a5c5fc28c" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "gix-commitgraph", "gix-date", "gix-hash", @@ -1177,7 +1312,7 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f89611f13544ca5ebeb68a502673814ef57200df60c24a61c2ce7b96f612f08b" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "bstr", "gix-attributes", "gix-config-value", @@ -1280,6 +1415,7 @@ version = "0.43.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c08f1ec5d1e6a524f8ba291c41f0ccaef64e48ed0e8cf790b3461cae45f6d3d" dependencies = [ + "bitflags 2.11.1", "bstr", "gix-commitgraph", "gix-date", @@ -1287,6 +1423,7 @@ dependencies = [ "gix-hash", "gix-object", "gix-revwalk", + "gix-trace", "nonempty", ] @@ -1312,7 +1449,7 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf82ae037de9c62850ce67beaa92ec8e3e17785ea307cdde7618edc215603b4f" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "gix-path", "libc", "windows-sys 0.61.2", @@ -1331,6 +1468,29 @@ dependencies = [ "thiserror", ] +[[package]] +name = "gix-status" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d6c598e3fdbc352fba1c5ba7e709e69402fafbc44d9295edad2e3c4738996b" +dependencies = [ + "bstr", + "filetime", + "gix-diff", + "gix-dir", + "gix-features", + "gix-filter", + "gix-fs", + "gix-hash", + "gix-index", + "gix-object", + "gix-path", + "gix-pathspec", + "gix-worktree", + "portable-atomic", + "thiserror", +] + [[package]] name = "gix-submodule" version = "0.28.0" @@ -1352,6 +1512,7 @@ version = "21.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d22227f6b203f511ff451c33c89899e87e4f571fc596b06f68e6e613a6508528" dependencies = [ + "dashmap", "gix-fs", "libc", "parking_lot", @@ -1386,7 +1547,7 @@ version = "0.55.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "963dc2afcdb611092aa587c3f9365e749ac0a0892ff27662dbc75f26c953fbec" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "gix-commitgraph", "gix-date", "gix-hash", @@ -1415,6 +1576,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "befcdbdfb1238d2854591f760a48711bed85e72d80a10e8f2f93f656746ef7c5" dependencies = [ + "bstr", "fastrand", "unicode-normalization", ] @@ -1446,6 +1608,48 @@ dependencies = [ "gix-validate", ] +[[package]] +name = "gix-worktree-state" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "644a1681f96e1be43c2a8384337d9d220e7624f50db54beda70997052aebf707" +dependencies = [ + "bstr", + "gix-features", + "gix-filter", + "gix-fs", + "gix-index", + "gix-object", + "gix-path", + "gix-worktree", + "io-close", + "thiserror", +] + +[[package]] +name = "gix-worktree-stream" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24e3fb70a1f650a5cec7d5b8d10d6d6fe86daf3cf15bde08ba0c70988a2932c3" +dependencies = [ + "gix-attributes", + "gix-error", + "gix-features", + "gix-filter", + "gix-fs", + "gix-hash", + "gix-object", + "gix-path", + "gix-traverse", + "parking_lot", +] + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + [[package]] name = "h2" version = "0.4.13" @@ -1474,6 +1678,12 @@ dependencies = [ "byteorder", ] +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + [[package]] name = "hashbrown" version = "0.15.5" @@ -1494,6 +1704,12 @@ dependencies = [ "foldhash 0.2.0", ] +[[package]] +name = "hashbrown" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" + [[package]] name = "heapless" version = "0.8.0" @@ -1609,15 +1825,14 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.7" +version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ "http", "hyper", "hyper-util", "rustls", - "rustls-pki-types", "tokio", "tokio-rustls", "tower-service", @@ -1780,14 +1995,33 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "imara-diff" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17d34b7d42178945f775e84bc4c36dde7c1c6cdfea656d3354d009056f2bb3d2" +dependencies = [ + "hashbrown 0.15.5", +] + +[[package]] +name = "imara-diff" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f01d462f766df78ab820dd06f5eb700233c51f0f4c2e846520eaf4ba6aa5c5c" +dependencies = [ + "hashbrown 0.15.5", + "memchr", +] + [[package]] name = "indexmap" -version = "2.13.1" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.16.1", + "hashbrown 0.17.0", "serde", "serde_core", ] @@ -1798,7 +2032,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd5b3eaf1a28b758ac0faa5a4254e8ab2705605496f1b1f3fbbc3988ad73d199" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "inotify-sys", "libc", ] @@ -1812,6 +2046,16 @@ dependencies = [ "libc", ] +[[package]] +name = "io-close" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cadcf447f06744f8ce713d2d6239bb5bde2c357a452397a9ed90c625da390bc" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "ipnet" version = "2.12.0" @@ -1881,11 +2125,21 @@ dependencies = [ "jiff-tzdb", ] +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + [[package]] name = "js-sys" -version = "0.3.94" +version = "0.3.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9" +checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" dependencies = [ "cfg-if", "futures-util", @@ -1957,20 +2211,44 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.184" +version = "0.2.185" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" +checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f" + +[[package]] +name = "libgit2-sys" +version = "0.18.3+1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9b3acc4b91781bb0b3386669d325163746af5f6e4f73e6d2d630e09a35f3487" +dependencies = [ + "cc", + "libc", + "libz-sys", + "pkg-config", +] [[package]] name = "libredox" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ddbf48fd451246b1f8c2610bd3b4ac0cc6e149d89832867093ab69a17194f08" +checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "libc", "plain", - "redox_syscall 0.7.3", + "redox_syscall 0.7.4", +] + +[[package]] +name = "libz-sys" +version = "1.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc3a226e576f50782b3305c5ccf458698f92798987f551c6a02efe8276721e22" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", ] [[package]] @@ -2093,7 +2371,7 @@ version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "fsevent-sys", "inotify", "kqueue", @@ -2111,7 +2389,7 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42b8cfee0e339a0337359f3c88165702ac6e600dc01c0cc9579a92d62b08477a" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", ] [[package]] @@ -2189,6 +2467,12 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + [[package]] name = "plain" version = "0.2.3" @@ -2203,9 +2487,9 @@ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "portable-atomic-util" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "091397be61a01d4be58e7841595bd4bfedb15f1cd54977d79b8271e94ed799a3" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" dependencies = [ "portable-atomic", ] @@ -2334,9 +2618,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand" -version = "0.9.2" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" dependencies = [ "rand_chacha", "rand_core", @@ -2367,16 +2651,16 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", ] [[package]] name = "redox_syscall" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16" +checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", ] [[package]] @@ -2501,7 +2785,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "errno", "libc", "linux-raw-sys", @@ -2510,9 +2794,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.37" +version = "0.23.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" +checksum = "69f9466fb2c14ea04357e91413efb882e2a6d4a406e625449bc0a5d360d53a21" dependencies = [ "once_cell", "ring", @@ -2534,9 +2818,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.10" +version = "0.103.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" +checksum = "8279bb85272c9f10811ae6a6c547ff594d6a7f3c6c6b02ee9726d1d0dcfcdd06" dependencies = [ "ring", "rustls-pki-types", @@ -2572,9 +2856,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "semver" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" [[package]] name = "serde" @@ -2651,6 +2935,27 @@ dependencies = [ "serde", ] +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + +[[package]] +name = "sha1-checked" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89f599ac0c323ebb1c6082821a54962b839832b03984598375bff3975b804423" +dependencies = [ + "digest 0.10.7", + "sha1", +] + [[package]] name = "sha2" version = "0.11.0" @@ -2658,8 +2963,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ "cfg-if", - "cpufeatures", - "digest 0.10.7", + "cpufeatures 0.3.0", + "digest 0.11.2", ] [[package]] @@ -2839,9 +3144,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.51.0" +version = "1.52.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bd1c4c0fc4a7ab90fc15ef6daaa3ec3b893f004f915f2392557ed23237820cd" +checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" dependencies = [ "bytes", "libc", @@ -2971,7 +3276,7 @@ version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "bytes", "futures-util", "http", @@ -3142,9 +3447,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.23.0" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" +checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" dependencies = [ "getrandom 0.4.2", "js-sys", @@ -3158,6 +3463,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.5" @@ -3209,9 +3520,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.117" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0" +checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" dependencies = [ "cfg-if", "once_cell", @@ -3222,9 +3533,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.67" +version = "0.4.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03623de6905b7206edd0a75f69f747f134b7f0a2323392d664448bf2d3c5d87e" +checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8" dependencies = [ "js-sys", "wasm-bindgen", @@ -3232,9 +3543,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.117" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be" +checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3242,9 +3553,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.117" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2" +checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" dependencies = [ "bumpalo", "proc-macro2", @@ -3255,9 +3566,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.117" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b" +checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" dependencies = [ "unicode-ident", ] @@ -3290,7 +3601,7 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "hashbrown 0.15.5", "indexmap", "semver", @@ -3298,9 +3609,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.94" +version = "0.3.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd70027e39b12f0849461e08ffc50b9cd7688d942c1c8e3c7b22273236b4dd0a" +checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d" dependencies = [ "js-sys", "wasm-bindgen", @@ -3318,13 +3629,29 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d" dependencies = [ "rustls-pki-types", ] +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + [[package]] name = "winapi-util" version = "0.1.11" @@ -3334,6 +3661,12 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-core" version = "0.62.2" @@ -3645,7 +3978,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags 2.11.0", + "bitflags 2.11.1", "indexmap", "log", "serde", diff --git a/bots/rhodibot/Cargo.toml b/bots/rhodibot/Cargo.toml index 0095ba4..6c69424 100644 --- a/bots/rhodibot/Cargo.toml +++ b/bots/rhodibot/Cargo.toml @@ -32,7 +32,7 @@ toml = "1.1" # Crypto for webhook verification hmac = "0.13" -sha2 = "0.10" +sha2 = "0.11" hex = "0.4" # Logging @@ -50,7 +50,7 @@ anyhow = "1" clap = { version = "4", features = ["derive", "env"] } # Git operations -gix = { version = "0.81", default-features = false, features = ["blocking-network-client"] } +gix = { version = "0.81", default-features = false, features = ["blocking-network-client", "sha1"] } # Time chrono = { version = "0.4", features = ["serde"] } diff --git a/bots/rhodibot/README.adoc b/bots/rhodibot/README.adoc index 25ff9d0..df24e3e 100644 --- a/bots/rhodibot/README.adoc +++ b/bots/rhodibot/README.adoc @@ -104,7 +104,7 @@ Each RSR check has a severity (Required, Recommended, Optional) that varies by p | .editorconfig | Optional | Recommended | Required | Required | .gitattributes | Optional | Recommended | Required | Required | .gitignore | Optional | Recommended | Required | Required -| justfile | Optional | Optional | Recommended | Required +| Justfile | Optional | Optional | Recommended | Required | .bot_directives | Optional | Optional | Recommended | Required |=== @@ -200,7 +200,7 @@ Options: | .editorconfig | Structure | 2 | .gitattributes | Structure | 2 | .gitignore | Structure | 2 -| justfile | Structure | 2 +| Justfile | Structure | 2 | .bot_directives | Structure | 2 |=== diff --git a/bots/rhodibot/src/github.rs b/bots/rhodibot/src/github.rs index dd684c6..09b3c0c 100644 --- a/bots/rhodibot/src/github.rs +++ b/bots/rhodibot/src/github.rs @@ -133,6 +133,13 @@ impl GitHubClient { body: &str, labels: &[&str], ) -> Result { + let full = format!("{}/{}", owner, repo); + gitbot_shared_context::registry_guard::check_github_write( + &full, + gitbot_shared_context::ExclusionAction::CreateIssue, + ) + .map_err(|e| anyhow::anyhow!("{}", e))?; + let url = format!("{}/repos/{}/{}/issues", self.base_url, owner, repo); let mut request = self.client.post(&url); @@ -163,6 +170,13 @@ impl GitHubClient { repo: &str, check_run: &CreateCheckRun, ) -> Result { + let full = format!("{}/{}", owner, repo); + gitbot_shared_context::registry_guard::check_github_write( + &full, + gitbot_shared_context::ExclusionAction::CreateCheckRun, + ) + .map_err(|e| anyhow::anyhow!("{}", e))?; + let url = format!("{}/repos/{}/{}/check-runs", self.base_url, owner, repo); let mut request = self.client.post(&url); diff --git a/bots/rhodibot/src/webhook.rs b/bots/rhodibot/src/webhook.rs index f0f9d2f..78fd7be 100644 --- a/bots/rhodibot/src/webhook.rs +++ b/bots/rhodibot/src/webhook.rs @@ -11,7 +11,7 @@ //! - User-controlled content is sanitized before inclusion in markdown output. use anyhow::Result; -use hmac::{Hmac, Mac}; +use hmac::{Hmac, Mac, KeyInit}; use serde::Deserialize; use sha2::Sha256; use tracing::{info, warn}; diff --git a/bots/seambot/Cargo.lock b/bots/seambot/Cargo.lock index 7b0cd89..0d7ed04 100644 --- a/bots/seambot/Cargo.lock +++ b/bots/seambot/Cargo.lock @@ -176,6 +176,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7a4d3ec6524d28a329fc53654bbadc9bdd7b0431f5d65f1a56ffb28a1ee5283" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -530,17 +532,33 @@ dependencies = [ "wasip3", ] +[[package]] +name = "git2" +version = "0.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b88256088d75a56f8ecfa070513a775dd9107f6530ef14919dac831af9cfe2b" +dependencies = [ + "bitflags 2.11.0", + "libc", + "libgit2-sys", + "log", + "url", +] + [[package]] name = "gitbot-shared-context" version = "0.1.0" dependencies = [ "chrono", + "git2", + "glob", "lexpr", "notify", "serde", "serde_json", "thiserror", "tokio", + "toml", "tracing", "uuid", ] @@ -925,6 +943,16 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + [[package]] name = "js-sys" version = "0.3.94" @@ -1015,12 +1043,36 @@ version = "0.2.184" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" +[[package]] +name = "libgit2-sys" +version = "0.18.3+1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9b3acc4b91781bb0b3386669d325163746af5f6e4f73e6d2d630e09a35f3487" +dependencies = [ + "cc", + "libc", + "libz-sys", + "pkg-config", +] + [[package]] name = "libm" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" +[[package]] +name = "libz-sys" +version = "1.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc3a226e576f50782b3305c5ccf458698f92798987f551c6a02efe8276721e22" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" version = "0.12.1" @@ -1256,6 +1308,12 @@ dependencies = [ "spki", ] +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + [[package]] name = "potential_utf" version = "0.1.5" @@ -2252,6 +2310,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.5" diff --git a/bots/seambot/Justfile b/bots/seambot/Justfile new file mode 100644 index 0000000..4793144 --- /dev/null +++ b/bots/seambot/Justfile @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: PMPL-1.0-or-later +# Justfile - hyperpolymath standard task runner + +default: + @just --list + +# Build the project +build: + @echo "Building..." + +# Run tests +test: + @echo "Testing..." + +# Run lints +lint: + @echo "Linting..." + +# Clean build artifacts +clean: + @echo "Cleaning..." + +# Format code +fmt: + @echo "Formatting..." + +# Run all checks +check: lint test + +# Prepare a release +release VERSION: + @echo "Releasing {{VERSION}}..." + diff --git a/bots/seambot/src/github.rs b/bots/seambot/src/github.rs index 3ae5cda..d7064e2 100644 --- a/bots/seambot/src/github.rs +++ b/bots/seambot/src/github.rs @@ -275,6 +275,12 @@ impl GitHubClient { head_sha: &str, name: &str, ) -> Result { + let full = format!("{}/{}", owner, repo); + gitbot_shared_context::registry_guard::check_github_write( + &full, + gitbot_shared_context::ExclusionAction::CreateCheckRun, + )?; + let token = self.get_installation_token().await?; let url = format!( @@ -519,6 +525,12 @@ impl GitHubClient { pr_number: u64, result: &CheckResult, ) -> Result { + let full = format!("{}/{}", owner, repo); + gitbot_shared_context::registry_guard::check_github_write( + &full, + gitbot_shared_context::ExclusionAction::CreateCheckRun, + )?; + let token = self.get_installation_token().await?; let url = format!( diff --git a/bots/sustainabot/Cargo.toml b/bots/sustainabot/Cargo.toml index 03e5457..64d9fec 100644 --- a/bots/sustainabot/Cargo.toml +++ b/bots/sustainabot/Cargo.toml @@ -46,8 +46,6 @@ tokio = { version = "1.42", features = ["full"] } # Carbon APIs reqwest = { version = "0.12", features = ["json"] } -# S-expression parsing (for .bot_directives/*.scm) -lexpr = "0.2" [profile.release] lto = true diff --git a/bots/sustainabot/Justfile b/bots/sustainabot/Justfile new file mode 100644 index 0000000..0069518 --- /dev/null +++ b/bots/sustainabot/Justfile @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: PMPL-1.0-or-later +# Justfile - hyperpolymath standard task runner + +default: + @just --list + +# Build the project +build: + @echo "Building..." + +# Run tests +test: + @echo "Testing..." + +# Run lints +lint: + @echo "Linting..." + +# Clean build artifacts +clean: + @echo "Cleaning..." + +# Format code +fmt: + @echo "Formatting..." + +# Run all checks +check: lint test + +# Prepare a release +release VERSION: + @echo "Releasing {{VERSION}}..." + +# Trigger automated checking + +github-scorecard: + @echo "Run manually: https://github.com/ossf/scorecard" + + diff --git a/bots/sustainabot/bot-integration/lib/bs/.sourcedirs.json b/bots/sustainabot/bot-integration/lib/bs/.sourcedirs.json deleted file mode 100644 index ae05e76..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/.sourcedirs.json +++ /dev/null @@ -1 +0,0 @@ -{"cmt_scan":[{"also_scan_build_root":true,"build_root":"lib/bs","scan_dirs":["bindings","src","src/tea"]}],"dirs":["bindings","src","src/tea"],"generated":[],"pkgs":[],"version":2} \ No newline at end of file diff --git a/bots/sustainabot/bot-integration/lib/bs/bindings/Deno.ast b/bots/sustainabot/bot-integration/lib/bs/bindings/Deno.ast deleted file mode 100644 index 499f2fb25c7ff17e5fc2e42fc44736ca3eba6062..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15336 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 diff --git a/bots/sustainabot/bot-integration/lib/bs/bindings/Deno.cmi b/bots/sustainabot/bot-integration/lib/bs/bindings/Deno.cmi deleted file mode 100644 index dc2b3e1a17b89e9ce137c1ab9b17ef27ccb84446..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10968 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 U+ui;{_lMT9{2>755B|sYe<`;$00000 diff --git a/bots/sustainabot/bot-integration/lib/bs/bindings/Deno.cmj b/bots/sustainabot/bot-integration/lib/bs/bindings/Deno.cmj deleted file mode 100644 index d762ff659308d3066878cb30d6dad91917c799cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 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 diff --git a/bots/sustainabot/bot-integration/lib/bs/bindings/Deno.res b/bots/sustainabot/bot-integration/lib/bs/bindings/Deno.res deleted file mode 100644 index 1fd7268..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/bindings/Deno.res +++ /dev/null @@ -1,160 +0,0 @@ -// ReScript bindings for Deno runtime APIs - -module Env = { - @val @scope(("Deno", "env")) external get: string => option = "get" - @val @scope(("Deno", "env")) external set: (string, string) => unit = "set" -} - -module Request = { - type t - @get external url: t => string = "url" - @get external method_: t => string = "method" - @send external headers: t => Js.Dict.t = "headers" - @send external json: t => promise = "json" - @send external text: t => promise = "text" -} - -module Response = { - type t - @new @scope("globalThis") - external make: (string, {..}) => t = "Response" - @new @scope("globalThis") - external makeJson: (string, {..}) => t = "Response" -} - -module HttpServer = { - type t - @send external shutdown: t => promise = "shutdown" - @send external finished: t => promise = "finished" -} - -@val @scope("Deno") -external serve: ({..}, Request.t => promise) => HttpServer.t = "serve" - -// Legacy module for backwards compatibility -module Http = { - type request = Request.t - type response = Response.t - - type remoteAddr = {hostname: string, port: int} - type connInfo = {remoteAddr: remoteAddr} - - type handler = (request, connInfo) => promise - - type listenInfo = {hostname: string, port: int} - type serveOptions = { - port?: int, - hostname?: string, - onListen?: listenInfo => unit, - } - - @get external url: request => string = "url" - @get external method_: request => string = "method" - @get external headers: request => Js.Dict.t = "headers" - @send external json: request => promise = "json" - @send external text: request => promise = "text" - - @new @scope("globalThis") - external makeResponse: (string, {..}) => response = "Response" - - @new @scope("globalThis") - external makeJsonResponse: (string, {..}) => response = "Response" - - @val @scope("Deno") - external serve: (serveOptions, handler) => unit = "serve" -} - -module Crypto = { - type subtleCrypto - type cryptoKey - - @val @scope(("globalThis", "crypto")) - external subtle: subtleCrypto = "subtle" - - // Import key with Uint8Array (for HMAC) - @send - external importKey: ( - subtleCrypto, - string, - Js.TypedArray2.Uint8Array.t, - {..}, - bool, - array, - ) => promise = "importKey" - - // Import key with JsonWebKey (for RSA) - @send - external importKeyJwk: ( - subtleCrypto, - @as("jwk") _, - {..}, - {..}, - bool, - array, - ) => promise = "importKey" - - // Import key with PKCS8 format (for RSA private keys) - @send - external importKeyPkcs8: ( - subtleCrypto, - @as("pkcs8") _, - Js.TypedArray2.ArrayBuffer.t, - {..}, - bool, - array, - ) => promise = "importKey" - - @send - external sign: (subtleCrypto, string, cryptoKey, Js.TypedArray2.Uint8Array.t) => promise = - "sign" - - @send - external signWithAlgorithm: (subtleCrypto, {..}, cryptoKey, Js.TypedArray2.Uint8Array.t) => promise = - "sign" - - @send - external verify: ( - subtleCrypto, - string, - cryptoKey, - Js.TypedArray2.Uint8Array.t, - Js.TypedArray2.Uint8Array.t, - ) => promise = "verify" -} - -module ArrayBuffer = { - @new @scope("globalThis") - external makeUint8Array: Js.TypedArray2.ArrayBuffer.t => Js.TypedArray2.Uint8Array.t = "Uint8Array" -} - -module Base64 = { - @val @scope("globalThis") external btoa: string => string = "btoa" - @val @scope("globalThis") external atob: string => string = "atob" -} - -module TextEncoder = { - type t - - @new @scope("globalThis") external make: unit => t = "TextEncoder" - @send external encode: (t, string) => Js.TypedArray2.Uint8Array.t = "encode" -} - -module TextDecoder = { - type t - - @new @scope("globalThis") external make: unit => t = "TextDecoder" - @send external decode: (t, Js.TypedArray2.Uint8Array.t) => string = "decode" -} - -module Fetch = { - type response - - @val @scope("globalThis") - external fetch: (string, {..}) => promise = "fetch" - - @get external ok: response => bool = "ok" - @get external status: response => int = "status" - @get external statusText: response => string = "statusText" - @send external json: response => promise = "json" - @send external text: response => promise = "text" -} diff --git a/bots/sustainabot/bot-integration/lib/bs/bindings/Deno.res.js b/bots/sustainabot/bot-integration/lib/bs/bindings/Deno.res.js deleted file mode 100644 index bfcadbb..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/bindings/Deno.res.js +++ /dev/null @@ -1,39 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE - - -let Env = {}; - -let Request = {}; - -let Response = {}; - -let HttpServer = {}; - -let Http = {}; - -let Crypto = {}; - -let $$ArrayBuffer = {}; - -let Base64 = {}; - -let TextEncoder = {}; - -let TextDecoder = {}; - -let Fetch = {}; - -export { - Env, - Request, - Response, - HttpServer, - Http, - Crypto, - $$ArrayBuffer, - Base64, - TextEncoder, - TextDecoder, - Fetch, -} -/* No side effect */ diff --git a/bots/sustainabot/bot-integration/lib/bs/bindings/Fetch.ast b/bots/sustainabot/bot-integration/lib/bs/bindings/Fetch.ast deleted file mode 100644 index 9da5f152bb93807d03f18ef5ff250fb64e234f4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1670 zcmbtUT}V_x6rRzu>Y5t%R0fgj_M>DA6;kxWn3+EnmDWpPvf64}wrhLW*ox|LI8`DhV>WQT7Wp)I(7OQN7tqL{JnMy(^t_&*ip;^wPrReD{3co;lx{J0paE{6;H3 zv_G5(Hq~z0*xb6Np($kbSjliS7H*3tL-lv|$FPX<`wc9nc*I)) zS1L46MaiS+1q&@DTxVbzMk!7zm0nGT*o^j<@s!0>f#b!8Vv*gqT76&zO++ckvmp<1 zaSrE=p5NpR9_p}WuN3_T>KR>7cAqn?Kzt9b-c&EeWhrhMXl8W#&$u$}v@mVYv<_pBm_7^xTuBX{dWRJ7A!T(JQ4icA{6hHvO*6DHx~NebwqZvScvV zhFr+ujmCWpCwnZccc4Lv*HVlaILPSJ>C4T8I580ZZq0n>RKptEfjbbT*==yD%i%BNQxHMjZ%zDS!7^<(e%l!++eoE zz!0N=*W|=+{4UdT4Gc3{;0YZ!4>>CgJYuvQ-DLEn{c~JL#jYcAR^V((hU{-w!QECo zhJIeGlX8WW8w|W;w0Uwr@0e{i@Sf3juTAokapXprZ#D3dQHOKv1_siBMl0Be%a+n0 zzcSfr;2WcEuOObjVgo-oy$_EXeUqd7y2`*$Mh9^YjtlLd?M{I9l1`sDfni60-Y0&U z!6a|y*m@}sNqNe^IHUBW=6y1c>3-vreufvkZYSFJ$zm2zX51b2nqlI diff --git a/bots/sustainabot/bot-integration/lib/bs/bindings/Fetch.cmi b/bots/sustainabot/bot-integration/lib/bs/bindings/Fetch.cmi deleted file mode 100644 index 707c88f35b32562a44d2e90c36e9e26d3df49a9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2096 zcmaKtdr;I?6o(TGRtAMqt+lSS;POxrH{zoMB4&YA7I`URbsWT9HqeD7*(QNm(2k1M zst8^jAFYU7TVJipETtkyN23lMAGJ=aZMBXH)hgl(6~RZv-fTjazq&Jba&GRq=l7j+ zPwvK<3TzW2BO{GuM8xVXdyiol5r|<}3x;{TM&m3Do=FSYpTIgNPWX)BXx`2;JWUP4 zut^w2QF=6-qL)EeWa4xMjG&{lZB{!^>p0rZ@;bhd7fe>hWM%~&8sSz(pmRBsU}YJd z*~(a~OfIi;2~0qt;~Wl=@Q8C@1{4*dK|zRQeS>o(1WI(CfRwWyIFmzofkRs<3Q!)N z&)P8Txoc^+vv2;Q&v+^Mr-j-%w!n(8A(|4Q>b6&^^)IDFdQE{?Ic6_tm4##VURt>{ zm@g^~frj+-aaP7smlQS$78QaBGhnl@St2nWJ#lOu%Ag))@b;LweT8#Yx^nUx&F1$d zL}*luXA*9FkeOv|?&P{DpqG()Kr7m(*H2e)yc8U7^z?RC>Z$!wSQkiQ0*=+-*e;Qn zEn8=mYQBStXA%l|ReiFm{zOvOYtbRO#hxNy!YDvZQ&$I^)aXQBAC!nZQv(I;jS6>PwH~OL z4?(LdCISpl0Hq2^t)l`SmQ`i89kX#f8pmTqqFS~}6t;JRg#IO3ql(>;*fzQvdYAgL zUA6A2EFFkNit+y}E)|)jF$u?);`nDG(Ii_9=)Kh3&8VfzaBP!E{Fsd6M{v9my_eG) z@DoaHE4na3FbqEqm0JUl(-LBgomZmLZ++Qzp-WS>8^W-3!D6$Tv*s1sX+RFF>MonV za`yBoUCj;RnsPIQ;mUe?aeQtT7&1mD=g{m`mpx9Ckq7Zok_c zCHlwxsU5p{l*Mx~ggPZgDrcdkivp10Jp(R%aBx(~t)>2UuJdM_+b5;aW;2;>h=n>* z_qXjBdpq4!x_!RmaJZXQ@&V+rfQ^}1TLzXl&H&dfCZA#M^(0eCF(C7;)2Rx<9G36R zFtyzcPazzya3t~u2Ls512gDSzofI=JZrZlF&3`I{6Wk6Q$8vxK0mkRw=YO}Qr$+cz z*Zks?TO%<&H3g8DJL*3UD~c#B*Gv}c_w`(M=V26Rbg@b?PF!osYu7|(B`oM2^x=kk z7u*$_Wn;}Il*x)En$S6MOQPzA93A?3+7FmpCEg^UN|e-IyApA$WB;;gDZh5-`2Ob3 zM9*<1lZ9{JF5YN9*_o7l zX2zka2c9UWL_VvKvCuhIhPD85vE_gP?z&nvHuH8x^gfLTgkz9{fZ7!8&dt;oj|=&R zXt=7GV$0t91%zYKqWm`m$c$j))5on>>A{(?ABJ_+j7R;CRykD3H#)!7@xRO*DP~uU zt`xUEfp8*PVNgHym)?fWH!f`QotRUVe6;uZ+-3+v6)!;U4bnt?4ST73?_b{NzkEI7 zme!;T3y^J{ul6j`CVUDmojJWWr=?7$GD&9?0mvN-_ay(5R90RZzW&imu}BLcy1@Wh zcw^nj>z&J+H?#!Wq37us2(|HS0U&MnOLnh)m3sfL4bl2L(JS{WUp9uLFI)Xl{{gp) BIP3rb diff --git a/bots/sustainabot/bot-integration/lib/bs/bindings/Fetch.cmj b/bots/sustainabot/bot-integration/lib/bs/bindings/Fetch.cmj deleted file mode 100644 index d762ff659308d3066878cb30d6dad91917c799cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 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 diff --git a/bots/sustainabot/bot-integration/lib/bs/bindings/Fetch.res b/bots/sustainabot/bot-integration/lib/bs/bindings/Fetch.res deleted file mode 100644 index 3be3690..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/bindings/Fetch.res +++ /dev/null @@ -1,13 +0,0 @@ -// ReScript bindings for Fetch API (available in Deno) - -type response - -@val external fetch: (string, {..}) => promise = "fetch" - -module Response = { - @get external ok: response => bool = "ok" - @get external status: response => int = "status" - @get external statusText: response => string = "statusText" - @send external json: response => promise = "json" - @send external text: response => promise = "text" -} diff --git a/bots/sustainabot/bot-integration/lib/bs/bindings/Fetch.res.js b/bots/sustainabot/bot-integration/lib/bs/bindings/Fetch.res.js deleted file mode 100644 index c3193b3..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/bindings/Fetch.res.js +++ /dev/null @@ -1,9 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE - - -let Response = {}; - -export { - Response, -} -/* No side effect */ diff --git a/bots/sustainabot/bot-integration/lib/bs/build.ninja b/bots/sustainabot/bot-integration/lib/bs/build.ninja deleted file mode 100644 index e69de29..0000000 diff --git a/bots/sustainabot/bot-integration/lib/bs/compiler-info.json b/bots/sustainabot/bot-integration/lib/bs/compiler-info.json deleted file mode 100644 index 2744c93..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/compiler-info.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "version": "12.1.0", - "bsc_path": "/var/home/hyper/.local/lib/node_modules/rescript/node_modules/@rescript/linux-x64/bin/bsc.exe", - "bsc_hash": "e71a4b341d54d39d77ed040eac08d002633dac2437fe69da2e0aa643219947ff", - "rescript_config_hash": "a7b411bbd12b50ab07abf31e57afaf1cc1ed53c7c57f2db040b8caf708a894f0", - "runtime_path": "/var/home/hyper/.local/lib/node_modules/rescript/node_modules/@rescript/runtime", - "generated_at": "1770426379323" -} \ No newline at end of file diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Analysis.ast b/bots/sustainabot/bot-integration/lib/bs/src/Analysis.ast deleted file mode 100644 index fc6c97b0c41fe495d256a9756fcdad72550f4e5b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11825 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 Dj0S7H diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Analysis.cmi b/bots/sustainabot/bot-integration/lib/bs/src/Analysis.cmi deleted file mode 100644 index 617096b1d983393439d537ca771a24a83118b870..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1944 zcmZ`(X;2hL6rP2}ql_9WmN71bOEHMJ11c7XILHx~a3hKbuCu!X8Q9C2VP%Plg5t$t z;}H);Iv#kFC8$BE!c~i?F~)dAF_aoSki!ENLB(Kt*xgzGI8|Nq`n|8azxVa)7e;E- zeu063GTh&P<>rby40C`Oh81C$s0WRE@T*WQsW!4S3!zCQ27V+z&7l%0y^f_h9b+WS zrqhrxRRdFu7t1lUHk}{<;o$VD3Bz7lL*jvgtIOv4RB(0ki{r=Y8J&h^DFX7-C@+R$ zv(y|vs{$rs%q*jxVnZkN9go-~_C>Mx!X|I{Wnyn({#vl!3RVwc<@L^H{6~N=3)No2 zWF8nMHIR%{qvfQOQcdewO3LtgO4%%yBWW$E&~Z{Ud}%F5r86W)>$FmqQA%wZO+ch0 zu~}G(S?s|7X@cmJt;EMFTR5GTCI}`D7MQi#R0$JYZ8lew;A*$I5(L*{Q?)p>FZB>! zDRJ<}6?)nSQwU3+2-Y*f>aYp(+-AJ687~PCZjq`JNhJ=XM2>YL$1`Sekj1)W&2__g zjZT?qQ$$GC6frtWOLO+xXy)n8`#9Z41PHa9*TSC{k41_4CyV;eHH#ChCPfg0rDnxH zqnhPww;GK}&|b6vUy?WF*!Q!X7KvKd2DC5V_zXfzDFOUdP1Ueux7+dhmxrBm9(?Db zXFBdT*)g$MYBi})BQC_RRrl0&y5=M@Z~N@*W4?B-JOegkZ^6yU*EVd~)Z`KX;RHK? zVRQ_@ft&30FPR57cb9Vqq_uC(+Runeii-t!LtFJ6AA^5hkz|s&dS7>gJr5a2p~u4S zar*X&j220td}d1T0N29y%XY=SR_hcb%4GQ>$=HOjML|`APkxpke-wjooRvr)&z&Xb zuKm!t^?88Dl-BIP?St(k!buJZl~Z~9mj8pc{Y$6DUg=63dexq2D8rCQi6d-HaYoXK zAp=GxyW~7AI|ZSaWq*K|yQPH4F5VwB!dSnwXX-e`JMpqQxRp339?FuF&EX#R}3>$LOA6EkRpRpa&jsg$%3!} zXS1DycK%)9^Lc5R_D0Pf2q)UH8LWUCnLK~Qh%-A=S|al9ObpyEL(0TcjDchkJr)(? zr5)Gq)}HBzj=3=XNa+(N2tDHz82}%)I5(qV$^Lwq>#8f}bMOgLB#M=1X;oAjt))}| zU#L110e@;N^-gUr4&EnmK+gvOIKJNkJU!LZIL>Rg_;{mavRYZO8bWUrwDfs^Cy$Z6 zeEx4E^-1asSD()E@#t}(D1+|dy>!^h@INC*nU%#JCFUPrAT3cui;DHbqqktQWphsq z^-C*_IobOMi-z?s%hsWM_*e$Z%iGk^vvI*C}6|Lj|zF@Io+HU9K3ip;>SIdI_nqy&1^0)5~@Evpa#ypHJD9ZC)_w23N;0d8e z6iPGe?%GjzI+oQI*1PMW)AE6zXkZznIW={TR}+=wl-bvl$4^|@eJ2#0Iq(V zvu90D+~a==gF_z$=k7;^ID=Ai@;GY+gh+JW^`rJIxUo9vw|QbSD Y%{_Q8pi=XYI(NX@!Y~nPVZulJ4=;;DG5`Po diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Analysis.cmj b/bots/sustainabot/bot-integration/lib/bs/src/Analysis.cmj deleted file mode 100644 index 57ecc6b6999f45d85fd452c5dad5620a3f998083..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 135 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 diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Analysis.res b/bots/sustainabot/bot-integration/lib/bs/src/Analysis.res deleted file mode 100644 index d792cc9..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/src/Analysis.res +++ /dev/null @@ -1,120 +0,0 @@ -// Analysis service client - -open Types - -// Fetch analysis from the analysis service -let analyzeRepository = async (endpoint: string, repoUrl: string, ref: string): result< - analysisResult, - string, -> => { - let body = Js.Json.object_( - Js.Dict.fromArray([("url", Js.Json.string(repoUrl)), ("ref", Js.Json.string(ref))]), - ) - - try { - let response = await Fetch.fetch( - `${endpoint}/repository`, - { - "method": "POST", - "headers": {"Content-Type": "application/json"}, - "body": Js.Json.stringify(body), - }, - ) - - if Fetch.Response.ok(response) { - let json = await Fetch.Response.json(response) - // In production, would properly decode the JSON - Ok(Obj.magic(json)) - } else { - Error(`Analysis failed: ${Fetch.Response.statusText(response)}`) - } - } catch { - | Js.Exn.Error(e) => - Error(`Analysis request failed: ${Js.Exn.message(e)->Belt.Option.getWithDefault("unknown")}`) - } -} - -let analyzeDiff = async ( - endpoint: string, - repoUrl: string, - base: string, - head: string, -): result => { - let body = Js.Json.object_( - Js.Dict.fromArray([ - ("url", Js.Json.string(repoUrl)), - ("base", Js.Json.string(base)), - ("head", Js.Json.string(head)), - ]), - ) - - try { - let response = await Fetch.fetch( - `${endpoint}/diff`, - { - "method": "POST", - "headers": {"Content-Type": "application/json"}, - "body": Js.Json.stringify(body), - }, - ) - - if Fetch.Response.ok(response) { - let json = await Fetch.Response.json(response) - Ok(Obj.magic(json)) - } else { - Error(`Diff analysis failed: ${Fetch.Response.statusText(response)}`) - } - } catch { - | Js.Exn.Error(e) => - Error(`Analysis request failed: ${Js.Exn.message(e)->Belt.Option.getWithDefault("unknown")}`) - } -} - -// Mock analysis for testing -let mockAnalysis = (): analysisResult => { - { - eco: { - carbonScore: 72.0, - energyScore: 68.0, - resourceScore: 75.0, - score: 71.5, - }, - econ: { - paretoDistance: 0.15, - allocationScore: 80.0, - debtScore: 65.0, - score: 72.0, - paretoStatus: Some({ - isOptimal: false, - distance: 0.15, - improvements: Some(["Reduce complexity in src/utils.rs", "Add memoization to hot path"]), - }), - }, - quality: { - complexityScore: 70.0, - couplingScore: 75.0, - coverageScore: 82.0, - score: 75.5, - }, - health: { - eco: 0.4, - econ: 0.3, - quality: 0.3, - total: 72.8, - grade: "C", - }, - violations: [], - recommendations: [ - { - entityId: "src/processing.rs", - action: "optimize_loop", - reason: "Hot loop could benefit from vectorization", - priority: PriorityMedium, - confidence: 0.78, - expectedImprovement: Js.Dict.fromArray([("carbonScore", 5.0), ("energyScore", 8.0)]), - }, - ], - timestamp: "2024-12-08T10:00:00Z", - commitSha: Some("abc123"), - } -} diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Analysis.res.js b/bots/sustainabot/bot-integration/lib/bs/src/Analysis.res.js deleted file mode 100644 index 135498c..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/src/Analysis.res.js +++ /dev/null @@ -1,159 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE - -import * as Js_dict from "@rescript/runtime/lib/es6/Js_dict.js"; -import * as Stdlib_Exn from "@rescript/runtime/lib/es6/Stdlib_Exn.js"; -import * as Belt_Option from "@rescript/runtime/lib/es6/Belt_Option.js"; -import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js"; - -async function analyzeRepository(endpoint, repoUrl, ref) { - let body = Js_dict.fromArray([ - [ - "url", - repoUrl - ], - [ - "ref", - ref - ] - ]); - try { - let response = await fetch(endpoint + `/repository`, { - method: "POST", - headers: { - "Content-Type": "application/json" - }, - body: JSON.stringify(body) - }); - if (!response.ok) { - return { - TAG: "Error", - _0: `Analysis failed: ` + response.statusText - }; - } - let json = await response.json(); - return { - TAG: "Ok", - _0: json - }; - } catch (raw_e) { - let e = Primitive_exceptions.internalToException(raw_e); - if (e.RE_EXN_ID === Stdlib_Exn.$$Error) { - return { - TAG: "Error", - _0: `Analysis request failed: ` + Belt_Option.getWithDefault(e._1.message, "unknown") - }; - } - throw e; - } -} - -async function analyzeDiff(endpoint, repoUrl, base, head) { - let body = Js_dict.fromArray([ - [ - "url", - repoUrl - ], - [ - "base", - base - ], - [ - "head", - head - ] - ]); - try { - let response = await fetch(endpoint + `/diff`, { - method: "POST", - headers: { - "Content-Type": "application/json" - }, - body: JSON.stringify(body) - }); - if (!response.ok) { - return { - TAG: "Error", - _0: `Diff analysis failed: ` + response.statusText - }; - } - let json = await response.json(); - return { - TAG: "Ok", - _0: json - }; - } catch (raw_e) { - let e = Primitive_exceptions.internalToException(raw_e); - if (e.RE_EXN_ID === Stdlib_Exn.$$Error) { - return { - TAG: "Error", - _0: `Analysis request failed: ` + Belt_Option.getWithDefault(e._1.message, "unknown") - }; - } - throw e; - } -} - -function mockAnalysis() { - return { - eco: { - carbonScore: 72.0, - energyScore: 68.0, - resourceScore: 75.0, - score: 71.5 - }, - econ: { - paretoDistance: 0.15, - allocationScore: 80.0, - debtScore: 65.0, - score: 72.0, - paretoStatus: { - isOptimal: false, - distance: 0.15, - improvements: [ - "Reduce complexity in src/utils.rs", - "Add memoization to hot path" - ] - } - }, - quality: { - complexityScore: 70.0, - couplingScore: 75.0, - coverageScore: 82.0, - score: 75.5 - }, - health: { - eco: 0.4, - econ: 0.3, - quality: 0.3, - total: 72.8, - grade: "C" - }, - violations: [], - recommendations: [{ - entityId: "src/processing.rs", - action: "optimize_loop", - reason: "Hot loop could benefit from vectorization", - priority: "PriorityMedium", - confidence: 0.78, - expectedImprovement: Js_dict.fromArray([ - [ - "carbonScore", - 5.0 - ], - [ - "energyScore", - 8.0 - ] - ]) - }], - timestamp: "2024-12-08T10:00:00Z", - commitSha: "abc123" - }; -} - -export { - analyzeRepository, - analyzeDiff, - mockAnalysis, -} -/* No side effect */ diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Config.ast b/bots/sustainabot/bot-integration/lib/bs/src/Config.ast deleted file mode 100644 index 06ba4057e2c11ec1d8b1d3aaf00f0550e2dbfe05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7610 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 RyzA}jPBN0g-H%`Ye*hoj8qfd$ diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Config.cmi b/bots/sustainabot/bot-integration/lib/bs/src/Config.cmi deleted file mode 100644 index 29fc5f4b2779c7dab59ca0e62be31808c9f923c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2219 zcmZuyc~I156i*z@&4uU@);No=a89yulp9s~2Nhk#It{IW|&_uPIA{Q4mQWTovkf zO7vbz^tGiulpnj4=mTXJ`!59|WZB)6RV0R}7cUWsp@=A)qHG;&gXNCnnMGy;$LN*L z2~w%{N-`qS7YRiT%bLQJ|+zT1(7}Imfptk&*g}6l` zuHbRvCQjTIiAp(Yv=b)ibjc|9*e|#yW_n* zMdFM-45BDXUT>lZt#>V2?J{)vz)$-P$bHb<6}F$yuMduQ$MEAx5X#d7Ep+|t~(~K%}aqW$e!2cWTu#mfb1R7 z=DAik@M4;0sitC8Y`X&y&!nrfvjExB`lv2Ubf5H(mw&-9y~}(ERrVUOoSu=67(fPf zI$!(x@UYzGCGJ^V`~5}-CdOfIK;TbF!|m zS6JJ{H1Y2Y};D93a7P&D)%h9k62FMD&CO<=4+po{y1ozx$C8y9MBi8|B>F}fpnhW>)y5^i++PJ;)cL+(e zshI}BU}1Ff84bu&>JsM}no1|13&!QE23RT~{H_NmC4)&7bWApC9GN@zO!ly_U4L&3 z7*t%sUa#2$;b;dogI92a6Xv?Q*6&JcRj<4=I&_By!jW+dXQ6pS%%jKckDXWV*44L1 zMW3HoQT)^e^%TkL%q)5-8CXUS$ocw1YWPz_v43(){B0D^Q_0Wv+=D`%u{ z8F8$^ZHzIs{0B51ds45XCF?=}`Rtu#+NITHE`t_!Tqi#ipb`5cjQlPHWP*?8)r)%# z%ooWK9s#dQ1JNp>EQf~jQ8i%ow>-b`&7Xz1_lg!*1&FkQB5sXpLp_dmRE2qx!@y!l7>gVz65>UKq75bNy1mu*W%N|_!ii1sK UD>EN3za6k2RTz$rD&<4{2gz2SB>(^b diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Config.cmj b/bots/sustainabot/bot-integration/lib/bs/src/Config.cmj deleted file mode 100644 index 95e1744f30d124f5f595720cc92dc3dc85f7a7d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 199 zcmccQSb2PzwfJJ)UGcu3Dw9=OrY_sZz`(E=h;@K?G7z^P_^?4GCqFS|!h!{k4h{|* z)Y4N+T=U9+Tqh7$6T&Z$U0eLLgi@5CK7vmkS6G5(t+ZCX-}Kd|5kUud6Nma{(qkxUU>ChS65e8cUM(c z_v<2GL;aAEBS)6zpK{8D8}4|@;c&g^a5#41?r}JrpPK!Of{pV73rsV{_|$$2{E?Ez z7Na%xjA_KSMPp_C!jVv*ae-k(4X5~Sx5M!xlGd8pb^iIj=K4siHKic0#TUwJXpH3f zYwH6|VSir8-xLhzg`2|>U!c)f6O82HFDK9#@h=GZB7tCIUN}^nr^?L@`NJhk9hI%z ziQ8;hXlcJ-6QLOu zI|?c=3|ZsKTvg+#{w2+UkiRZobDkfk_6-SQLO(Ey3M-yQ#S_1iOpJ*?e;bFsH=+fq z>>sG?k&~F?HRgD;m5)-;hnj_H0~8CTjS;)_ia41sAn#~`y!qrx#;#)QzE)nYpa-SU z3i?36b~AlR5^~3>9IzzvRa_!p6IXK;iFK`fo`SB|TumR)E&~9DuticTs z(X?Qt8c=$OZRKT$k>2~n%Rk~pw8e|qO+`HGn7}-}m?xu^@6ce5VHj$7^J_4?AH&eT z6@PtAYkWuZ?=+i#9<`a*U79(ZBl)Sl_cwoNbzUnnro3&QB^PnxFH7>y4A| z?YZK^b9yy}4t%iN#+lq)U+=4_2QS7WTldsI72I3tTYcS(We?@pyb?|{|Ect==T&WR zU-{^m=zDd(qfW5XC;3(^kLE89j5e-{)C^kOsj+d(_YZ$#nu9eT6T&6S8l(C5-qSic ze_wv<^w-y2vwnB4;ij2uBZNZ1P&7Z9Ui#w$i|^j>!_ASq^0pt`VV5zXvV3wh|E*8A z%^cKn%IYh7oZ7nW&L7^g>roo)>B{JM*9IGx(x0Kid_SXwm%p!jE3HsPeI+yeCcXwc?8#pGKEa zbfWn;r_VaG^u-T4by@!0%H7v)dBHUEF;W`>kwA;TO6llm{?jElx~7zFarS+&e$|>| zTeg_yhyj%u+d(|0t_HdeJe;`CiSw-^~%(RsmfTL_-G=F;E(r>dw>J;Q zP(o@5jq+RGu@@Ha9NWFM_NvUatsB2K%^^r>MAuAY?;6L9(z6~rddU3i%N{@Usl{pTxg`_s?mpTBd(83iAoalvNO%qsRb2BZ0B z)(!h|d(}VJbxkdJP57_VslmT|ND_FHz!L)pEbKPP(qnl;EpiP8MA z*Sy+0bm)S+_YB|C@R9#-cWG7SU{F=@pHZY;m1%KTrQ#chqw_(Bg#x4}^7NfWu)DZ=$Mr zb>^ITvf4gk&zCt0j-<&uOW)!|lOKmPi9QLW8scJT#M68uHZhAvdYpkWiCKZ(VYbC) zIqK&_E`t)Z*ut@j7s_+K82BH#aVB3@(kgJxRYVd%AuZMYV&HyQxN$*f`qaVLZQ% z$^jMJO#rdEqo!MG8w#|xIYcVH3Z7DPy}t-;(#HX(4?>EqlS0~PQ5q*7Z?zr`lM5xf zxhR0c2$`dUwNNOzOMRinDs(Jd|#lxIi!o^ zT~&#^3);lw$1BQb6XhpBnIFZU=GP+k?EKG`=32hMn4}TbFGhvwE)@VWngfx+m;9Hq|DF2W@1*EC@rHw7V`T&`~ z1Q=b!WEfj=du%onL$m?X0)T4og{pJehfCA0aI`FqMdo*(3| zBXeO^?LuG3QW}O4<2hKReI45<=dT;l_XJC^`UrE*MONmVA(Ip5u!2<}Yb8ib!5x!OmZ z$(&0hfm)kloqSQPF}qNw6l|cKex41UD^Y!VBF3CG@_D*7A7jp$^2Ic%hy<(acp10L zcOe?AZJ2-*LKL6&S&T_jtZi!>?1^A4;J*a-rMN@gp&G+%4(4dm&4MLg20xalLKX4O z+{?XYEc(heKH7}x`9IOV7&Ir~ehKbSilAL$)1C!$z}*;xu$5gg@dT|2&}ZP27a8F5 zGic;Emm5G~Ds?O=u1Sy@N7qz6hB<>a*r+-Fi(ttY${EIowDJLDA|&q^snaktk5arJ z4c?WDO1$5L66fN6FYYzaz1#Toc6ECY?`x6%5bgn4H`3EmhcV}T-b2@oDxGD*uEx_A z@$?u!0Xd&W&P7!F!Q2UUs7DCa+vHRm*|2{3e-jus+Ma9sYg=q9&7h@URnUimE`1OO zFw9$SiEDRGf2lt@W~)}M>qVP6kA(hydhaLloM$7@q<~aVrxqA{~`8M6KJf%bT6Do z9wmi;iqAP0E?4n6%<(7mnhZn5o_H@QxKEk$FA#cn>Lbv~R+C&~gBuOr1>=A@H>l3y zbchZYnkB%OxAL&Tn~8P9G>vFmEXqwYN&^V8b{?+;d@aBe6nF!$r8eO`(1DrrIyFdQ zd<<|-QaCq)@2f+J? z^4?}NqlGFyO(i@CaJm8?GFo}M!TT8Gs*+-bo>wE{J~<+`=w_QCoXHoMoyl{^6UGnD z9*9;cq7UO4g27uz`rzzja3+}Q!>~CITdY0A z;VQxmBGbjH2VDg4l2Yb)kvVpPYv^6U1|=#l=US+iAh6cq-b~6%u>3^r<-86FEkL*) z_mxUAr=dWtzM8dwuNBVZ%YYk0l7+&dI|vt;5O+N5a_&}QzXO!dCCp5z-2@xYQ_xWd zlA~A?^40poRHOS!mNLf$0JcnEj+dF^6;Oh^7Za=}#DZ?VP_uH6a3)_!Jsvy|ItXk- zdBwyODFeYGf;Hk+Dx3Lv!OD;TtVc_hE=5y=EhqFGtayTtus=Dnt4GXpRvcD1pSJ?B zYQ&%0T>F{xA39+vS~V)1H`(dC)tk5@%A9-b#5S4v@3yXeLB9B#mcqNj znS7C~RtSb6#_mRi?jwmvTVDVh`b9fi?>wN`-v>c_rNGZ13K%Gxft|XfFNHJtGRQik zpSQR8gA@Ce%c02bZxt@4z;9#;r`jdF*wOBfly?6QnmAXtGRBT$tOv^IuE1x0Q20w!&5Vr;6 z#xOmWg5Obu7yAV^Af6S4(gGUtBF7GwZtl)`}@au{3SDw@n#9%Dm+SggPi;4@R{ z@-O4M+%-uho(8-!1%gGT%LSv^vL4R|WevZ^oBt@$zocn3 zX>-hxF?3u$mFG-=H3~E=eRz=ixXUA4To*ah5YC@rpo~HoDA#B*L(qnOwaRxbQTYo% zDx|08x^=?Bm3*N}Q!z2IR6cc!m5OMQ?0R>h`T1sxoS>&W zttVRUkn}lboZ293{qKsFGgi#lc+gv`z)5I?3@KnfT8ii!zF3J!MGZ(w*DBNsfY&K- zx|Wh_5I@Zjt^oybkEB?ZkXXp86V4Txg9c4f5vleO9v$;Poa@HsDz_)f?fD9uLk?VL z)JnBHn{7=V*je#u1Dh3X%k8TolN6t+^+gH`(jlwl=n{;u_N;nZaym}G=w`h*RvPFZ ztj9Dd&0`ED)uR#FkuQ$o_p3pps{1fM0~5Z}`6xbukFv@bE@^zhT-|jUL#-FxVjFp1 z61eLmB8+=igXc@23#OOSGh4eUCA%yT4#Q7O59y`3bhw>?P_U8ar|DR74A6qWsPt%N z%@S&=A65Iz0C-S==h1i|mcL}KUi=N1tHEThBL0S^dPLCqY#1k5S`2fxljDP*cT(9` zwF;i5z%>T{Kn?zWlG@4qV^SP3eiD2dgJndaK(FS0swm{@IuMe z6j|SN{-X(XElCXoN~S`&2sEc~MCwhR%~ydYO1c`!{Z;bCc!mm`E*0T4tF8LT$4cvw zjDT#cOu^DXfjkbb)f%QNe0T+8moRpj<#Ei1;)itPlCI!}()Qm2u|R>pD8FNIqJ7|{ zD(zRGO^_g?SSff5qjasUURPtCj~5*-48VS}a?<^feodqu{h5lW0R34CBx4WyD{cC3 z@}um@nP8V9;L^^8*~L$Y@jjqXt0+JiF`lozn6ZBcg(|*k=f3c* zio=`1>;nqi1c_~vF)`J5TxaN#VuB}Mhj(9ww(CC6D6+Sqgl83aw=CgwyUHUwx-XJ4 z!WJVbZ1FX;ycM?KuP7q-^3x?5+r@T`(~RyEJo!Q=7{Uj)Vwm%6DGu_uN_YzVXBlHD zgyO+;kGjroMgL)ddldMXENFtwZ!teE9%ea7g;~lGr2oSa1^&}C#-3wrC(8I)f$zYK zWl(oh?v^VZrJ=EyYX(M|s~4#iS9hBO1g!MXc1=T0s8^s?s`?9;=y0L_!^zz`-Qe&X z@Y5=nFN|wk(M55xt5t}u3VaU{e5G;WZhg&Mvl84b(L>?9e^_@*WKCym4`X{ltgiw; z1)nbEZhaGXw?vLg{0w-x3j93oZn?(VwM2*yHJlfBx5O}oy&r8u?v|@E(cN;@O7z*% z-AeF*X(6nj50=Tw2hPWegWd$tF4`j|&tU8;#(n`u_K*Lt`I?V~+x@{Q@$%F(D!j|9_w zctp>w&P|`{k2HrG!|BzujME?Q22`gnT?q8ZLVtRov8g$d9v~Wx%?&mF(BSlH^2(~y zgGdf7#o|kDYHFW8=_Sj2u+08&YHD?LHJGUl1)3tMB)DA2E!P%X|I8to1JXy2PM5_E z89?}{27EsCH_-Ay`l0f&HSUL6A^XUwZ)@GM#Rl&)crS@}ukOa@36XrE8?WT^TKO!4 z&uQ0<>$Dpz)~Y6h`4HXF0iAfO)rsMSij4{fld!|g8N|&qne#;Eg!?N@1@=ZK zK2LSxUorwZ{v$T4#B|`@r9kD4GE+5JqrIU7(_7+DR8X zXEA4g=FCL_FDvjA)VfMJ>AfXak6>kif-!=nwu{Dyw^WAV$osYeM;rWQ(jnlBG`_T5 z&vUFRN@qyCCmVo$hYatZ#hhm{r<`FR1Y#lU*|T_8bhr#&br}9XpUs@b%t_6=UxAop zxXxAlKPve@oA1^9_ixYt_bNjL^8TQ}nFiml`G>o&_|OhF|9}C+a-M za^`B{HpT5xhUAG>;r1%N%=;Jiv1(BOLcO z++~WzCe(GZ0x`wJu#WFoW3IiroJqo+d>!6D>XYanx#uaeVU%#T0!g;*Jg^Ts`bYUm z;T>!wDZnxvZQ&X>C=#3$TO@o8_dM40Ame$m{*smm8+t9kiz_Rbn*wnwn^V z1~rlfe0pP`7CRTyi?D9%tHr`ZIyRvBYCtSE9ZS`LT0hWy5s9mcrWJ9N)|g68Lwa3+ zcB0X&T}?2<>5#KuE&`=DHxXtK%N@%igVW~+L+O6y1*9(xL>5Yt<3fJ_;?#OSE!(Gu z0}C2_gW+5RY8R$2^o7$SOM?joB-9hM8p5Zi!_iQ#NI?1^vfjRMB$XDSRb^01UpfRu zu?Amb9sZijMK`e2hkl-m$o5x}0s++b)y zp1(0?dSxD5t8m^-e@)&5UyH9&IyZS!{ZcZu{yeqouc}<`mkVQWB=M7%(6$3oA*r(B z$-n0-O$cMJB4teMnf)^h3X7D#l6 z_44X!?R||zkEOqAFqW^|PQEk+EQi_eYI9$N8A^pUn9Rz~dFT3&PmQ`%Ce*@v%w{1F*$cWur_z z73TW@dns_A5`&G#`%*0nRV{fh$2{h4WNvJ`J6VJ0NG?-|OA79jN%fq;XA+lW`aOec zm=kMiSeEb%R^S(su>#519&*hn(w$vUhs`;`5M>#r@V*8(T!9A_TNV;6cEYe|riMG_ zGIt?!7q{{e8id;k(GgSR5^1i+@Fu*a*qWz6^{~qU7S=N7Pt5r%7?!JfX(rs&&V)2k znc0;9Cn<0Z^)Fibvc?B?O00@c@sE{mvS264ZCQffO+;p>oR`lWu8eY*yI^v(%OQ@-Z$czZKIwgQ76XDyQfUPn4r{z=X}xOB4=u>VAXJ@ z=AepaQxjRv6d&IgUoiL@;7~m%4J%c8z2f+GfEyHer|Jg6GX=ekrZ3Vbo(?)#5Qb2N z2aCV736uBNd~878qzg)gO8&!97|)hP%!N7G^Wfut1-@no@h_6&GbVKi@dnCgP?Vk; zdU_Rd6M}}Ua@jpT8>~jomn3QxDj*f*+D#+Il};N!y|AicYUzxEX(d$?OU|kqTRN$P z?;D`xyuMg^<==wP z8w&gp+&mzsseD{t+HAK_PgOntQ3wZt`>p~H#p5l4_5|pvHOaaJw6xy^cG6{V)zC41 z9B6%{X#GYNfRNlS6ElK1v7jV2pE@}$&P0WKI~+Ro!3{~`yGF+U#9(TK=X(XNLj{hr z8^Zkvh{=9<4w^=|A4D0Rxzrr)yRDQJ7O)&FfC-N6ire_r*4s4}uv*etCI4TFwGSE@ zErxL4B_X{`?@bdOF0{o}{0!(K0}Cwl)2)0;$5s|>DC*_yr7H7hfF~>PPT9iQQXc0i z;d*=MLO}-4_g>jU>7$1SM2dlC-qwH<` z0g}pAOBfefz=ihi865}ko`GhAP!PxVj#l7S>f~x3Jxf+$5x>o9QqNI|P3j%5ay*30 zr3&1R%znE`Jv5n+BEOQF)Z?KhyHFZ^y(t)ZrBP)uTm?rl`yE3&DwWIdz&DryW*HZ=w>7v71Oq#L*yJWDsk z65&n0fY2Ckh#{c7Tv2{iHpFjKmqS(+uCaiP{3hffW9D70M*Y(O*I+!p#`wPyjG4W! z&U>ZOqS$}ry-I;t8hix??byVbrgx)CBhuF>P;cPrhQjr@pCVY7#Fd+2>4ISs z9#*crwb`J$T7 zKnw+jGKlJgWZ!7}02J`mXSrb0rIi$H8VO*ps>g=_KUUyg=EAN%b-2> z__aM?n5}KtrpqT}(-&`;k!Ta({U*W$XCf7pzf~YYq*7QIfp)0cvkQ5d=V_jG>PP#rQ<#`MVtBf5jO0){k|XAkKD1VB-F;eN)z&ET0j=U|bNd;tMnTmE7^ z4+Wp93PzNHpNz;#dz+pzx|xZ5CQb$7nF>4&)$XZm`oxR|-Iyt3RpLnCjZ@$#yD|6L z!uz)r*emc&Fr2VmC1tY0rbRTe*q*NvgU=p}R!I6KJ`g=g2cH{AaC23zF#zW&&`1bA zbG@@HAGq|lM-lQqJW7K5M89eQuL#rl%eS?~2}WdK78oB?sJq;E{53QdV9Awy%OG%sahCKK4b!O!P6pxSu1R3*EKEqlaF z%AyftNqF@#Cgw2V1Ns^T`r{II+0lK^hjO^=);(Yiu#+xGAjWTK<=4pXF2JGkgp3ayLs(JRhI9=2HEA|Kp3A@GzGEf zWQpyu6-=yTVl~J;uE2G1v3V(yt_HYQNZvouVtX9eNf&rJjTg7_G4weR{o3S$9`y41 zcG_sCD&+JR~E_vdc8^}o*!q{ z^Q8@9vMU9*-w@vOB=oti!)}q1d_j)Hxzz z_`Vh3R|+HpZK*FOOEQ{W4UYH6{OTxzE1aG}gs# zQ_y{1Wa4EI9jd_BQP&-bYUyXKmPS+P5s^n3%v~4^M@F5Ne_DQ?92+bA!c{>`j#5Pa z4e)dYelK;ArL0m%E75NN!kOnX@dLv;2)^{9y~>o|P|4@X5r{c~+C!K+?tCVGVd4-l z#!JxcK)>H>wmp6zhI;2YvYLXS2>Cd!=^cF>XC*CPw?DQ3YiH;V2l!DcJ1IkK@4*^- zZM@-}rBJX4i;$n{nuqPi%=;XBmCkkG!tjQ=nC;G$(>o#XL{Z zznD2LWGQFj`zO%9#CoXJ^arVW6f`xJ*6}e!mv*d2vD6SJX8Wzqa>FRW_6^DRdgi!@ zrTAIO0?^%HJ*>85uISnaI`A?g3kMqi(=x2)bgB))uNjN4(j@Us%yBVG0pAyc_^sB% z9q1G?`F7@5#k}t_@B2u;!+O|f7`I@eDmxqc;#P;j+%D$!0DeHjovi8qXqdeCc^lNX zpU@bc0Y9nXE{1?9k2{lYif56r@Sa5K+dUjT(w%F)>q_c^FSQkFR7+`k#_R- zplz?MwI)v)q7Gi9EhSiHwC#qzDv z4VY=TOwp{6H1U}ik>sXDF_VHIF@8NL9&R)e(W4zj%w5jhm4J`Y@O<3`QrZ%Ycc<<; z89q;^9va5C2Hp{N`=|WJDms_iKjm#yF!ciTXfkoSXVAEj?L1g^hbNKB)l383rk|DA zSE9hRmG=QKf&Y|{jxBb|6CE!4^w;hV!*s-FW=Y}r^74sQl_f<}OQs1<6Sq!hYW9PG z$7uLs*+2TowjP4-pU^*2ew2pVl`cB<#O%|+&ES1h_v}|Ur^ZMfr5d9~bUIt4bTe?X8{I{6Kt z-mGEl67+6QXoYG^ij!n3%!B+p(QbT^T4|*qlCMNNK{`~7c3|l(LZnNJt>hvpbr^nm zABT3RkkDA&4xpTT8CV#?Pq#yk9ux%?6;-9hg1<%eeO5ER3-AsNBNKdDH5kgZ{8uXZ z-zGX?WXv&ev*rK1=#+c`VFwkBpOXJhP5ZM1`45Bq^OFrBG4(IUSmxf(++P8HQ^6jl z8-Yj6XwsSsWogrBF2K7re5?Vt-EIslLTO3QQj#u{k|w`H3NqdzQ|03fShofVO~>w5 zDMN%4_Vd&(m4gd~8` z3NoDpE2cjGhCJe-GrmB?lXHRG4S1ArUO`Vc^J6gcr?og&IeNOK7i>8 z{6dB=UDL2+=bBC^+3Nk50Q)QOJMaifbHI%b72PXbQ+4Q)f}gJ0C`9cjAPT3dY(D@T zrodkng&Lc}{n+M~5d3sC;d6q-ZS0;0h07n~8K7Y(8iz=B&KFex)U`~w7Mf5eDc4bn zV4CCj1k_cBj-w)=u0ILa8gwND=^@Co@i7h(kY}71g%E7peYv~x9^Ls04SG(3#j zCSjA6cfKxcrASM@j=0H+XOSGQ&?H9yzEZ_1qn!(gH6WS- z^JsZrX*W0!CMaW`86bC~hG%24nQrKhYquph*xn_Y?Hfc|@&(N`l;_H_Ff3?6FL93o zsNahZ|2*@U2a%_=`!u{5izp9SGwFoArQYR?PhsAW+Dhpn26?_pdL9e9wOxix(jOBnoag;O91I+V~QdL;-PgEk`=>Agx%x^V3 zPSU;1?n{gLjCfx+@x{<*n% z^5mGDoKSOPB+%f`p;hdZ^8Z!An(Ck&I+-TNPX`ob4H}X^WKd2`IA;O2$)Q^L1ULC= z7yB0Ya~gdO{sFHo9ypBbuKzqv<&JKh6E#y!9EU7u8niUNum3 zPQDD$c>wwodZK54$Fs@)%ZX;9bLruZQWTvIdpO#WPE$L=;cIlp+>uXgqjTVnbk^H{ zJ0p%xpgY{za)0b}x+9-%_xq>f{gHF^e)nL$|9Y&SNSl7R;{gBYse=DMCl&soqYp(I z4gu_VY@&6>WC0y7c(@}M|KQP$*14QVIswu;m-EPHNMdKHJlXU2PNK9*InrsCf8an& ztHMV-RMRTsNT+gI=|?)%)2auhAL(RJ3+MMv7_}sJ=?): option => { - switch Deno.Env.get(key) { - | Some(v) => Some(v) - | None => default - } -} - -let getEnvRequired = (key: string): result => { - switch Deno.Env.get(key) { - | Some(v) => Ok(v) - | None => Error(`Missing required environment variable: ${key}`) - } -} - -let getEnvInt = (key: string, ~default: int): int => { - switch Deno.Env.get(key) { - | Some(v) => - switch Belt.Int.fromString(v) { - | Some(i) => i - | None => default - } - | None => default - } -} - -let parseMode = (s: string): botMode => { - switch Js.String.toLowerCase(s) { - | "consultant" => Consultant - | "regulator" => Regulator - | _ => Advisor - } -} - -// Load private key from file or environment -// If GITHUB_PRIVATE_KEY_FILE is set, read from file -// Otherwise use GITHUB_PRIVATE_KEY directly -let loadPrivateKey = (): option => { - switch Deno.Env.get("GITHUB_PRIVATE_KEY_FILE") { - | Some(_path) => - // For file-based keys, the key should be loaded at startup - // For now, fall back to env var (file loading would need async) - getEnv("GITHUB_PRIVATE_KEY") - | None => getEnv("GITHUB_PRIVATE_KEY") - } -} - -let load = (): result => { - let modeStr = switch getEnv("BOT_MODE") { - | Some(m) => m - | None => "advisor" - } - let mode = parseMode(modeStr) - - let analysisEndpoint = switch getEnv("ANALYSIS_ENDPOINT") { - | Some(e) => e - | None => "http://localhost:8080/analyze" - } - - Ok({ - port: getEnvInt("PORT", ~default=3000), - mode, - analysisEndpoint, - githubWebhookSecret: getEnv("GITHUB_WEBHOOK_SECRET"), - gitlabWebhookSecret: getEnv("GITLAB_WEBHOOK_SECRET"), - githubAppId: getEnv("GITHUB_APP_ID"), - githubPrivateKey: loadPrivateKey(), - }) -} - -let modeToString = (mode: botMode): string => { - switch mode { - | Consultant => "consultant" - | Advisor => "advisor" - | Regulator => "regulator" - } -} diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Config.res.js b/bots/sustainabot/bot-integration/lib/bs/src/Config.res.js deleted file mode 100644 index b155c1c..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/src/Config.res.js +++ /dev/null @@ -1,99 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE - -import * as Belt_Int from "@rescript/runtime/lib/es6/Belt_Int.js"; - -function getEnv(key, $$default) { - let v = Deno.env.get(key); - if (v !== undefined) { - return v; - } else { - return $$default; - } -} - -function getEnvRequired(key) { - let v = Deno.env.get(key); - if (v !== undefined) { - return { - TAG: "Ok", - _0: v - }; - } else { - return { - TAG: "Error", - _0: `Missing required environment variable: ` + key - }; - } -} - -function getEnvInt(key, $$default) { - let v = Deno.env.get(key); - if (v === undefined) { - return $$default; - } - let i = Belt_Int.fromString(v); - if (i !== undefined) { - return i; - } else { - return $$default; - } -} - -function parseMode(s) { - let match = s.toLowerCase(); - switch (match) { - case "consultant" : - return "Consultant"; - case "regulator" : - return "Regulator"; - default: - return "Advisor"; - } -} - -function loadPrivateKey() { - Deno.env.get("GITHUB_PRIVATE_KEY_FILE"); - return getEnv("GITHUB_PRIVATE_KEY", undefined); -} - -function load() { - let m = getEnv("BOT_MODE", undefined); - let modeStr = m !== undefined ? m : "advisor"; - let mode = parseMode(modeStr); - let e = getEnv("ANALYSIS_ENDPOINT", undefined); - let analysisEndpoint = e !== undefined ? e : "http://localhost:8080/analyze"; - return { - TAG: "Ok", - _0: { - port: getEnvInt("PORT", 3000), - mode: mode, - analysisEndpoint: analysisEndpoint, - githubWebhookSecret: getEnv("GITHUB_WEBHOOK_SECRET", undefined), - gitlabWebhookSecret: getEnv("GITLAB_WEBHOOK_SECRET", undefined), - githubAppId: getEnv("GITHUB_APP_ID", undefined), - githubPrivateKey: loadPrivateKey() - } - }; -} - -function modeToString(mode) { - switch (mode) { - case "Consultant" : - return "consultant"; - case "Advisor" : - return "advisor"; - case "Regulator" : - return "regulator"; - } -} - -export { - getEnv, - getEnvRequired, - getEnvInt, - parseMode, - loadPrivateKey, - load, - modeToString, -} -/* No side effect */ diff --git a/bots/sustainabot/bot-integration/lib/bs/src/GitHubAPI.ast b/bots/sustainabot/bot-integration/lib/bs/src/GitHubAPI.ast deleted file mode 100644 index 27b3595015823894be9bdb0a9542a3ca7e9a754f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22046 zcmbt+cYKva_WpbBow>cn#e$-t*APGy1+2 zUu;2LU3GP1UAykCoyBz*ds)}AcJ%k0nKL&xBys=v@p(g@Q>M?HIdk55<9S}6$ms0y zy2#jUWmV*uY+c!s$i&*nl$!F2^1AYs*?HA9RTbs6*+}uq(wbgV$4!|$ZQj@kQ;Tcs zYwJqOD@zwt)fMBXsJyZ+ySS#buDq(UxVEOO_}KEg@%0Nzrc4-IldX-Md*#g!d)|y& zJ+GkA^Ty2ayppGynyzVSYUst~Hn)Vw{{Q4Z);rmo)1rL*dw!;*xkV|4Co6v@)2w_- zWty5cWtv)=8=Csp*Jf)<7H2E#pp`ntTi`8fQEC2Nm4SM5e#eq`5qX!k zsQwmhkOBt`8!~KI(a@nq!wysXLb2G2H@2uD7Ts*i8D^=AIw@&tc13-*mYa3dMDkuE zZ%2zd+M;(&NxM+nZRmpDbydrmQ*c7qPfQt|MRz~c@~A+XS~QtqAhB%Md?m6?w74x zSY3q~hOBE(Ali$lON*+rs9XE2*ICIyE$TFjdbiKIv8mUBs)cKi<9U;a`VtLjQRiDU z7~0%VDh%nRme*f}GH7!%_f1tb&vMAFu(Ba7>Pm|a%``z{)24=I^oH9h+{ir>^QwB0HkR9{(Jx+puZw02EpnVO^KU}9&Q zL!K8cXuiu%@SgQG%Tee4$i~fwE~%@lt{quijHx_$ae3X6`UQi_swx_KELed;-mqEMwx~BPx){lt z24TeyuFFt}kV09}A=R7&-ew2hk!)j=rl zYf)`c-&k~Irb%_Psk*nQ?=ABxle$nHhSXS}nmo%dS3%IyO?{VSOBZ5ovOF@C=xU-H z0HYReF`b2eO?GMOK9P0OR9OHBi1P_nD5YgDv(dvm6tsi>qL zYoVrmt+9xlL62!f+lcM}>}lacndXKbr9;#{8Jnh0Nm*I88Z$=I;ORtvC3+RG*uuAr z@=(=Nl!wnOvL?2uq`JH)XJs^voI&(6`TR&a%EJ9j(qXDtk`9;w6IdiRP}4Cdk*_cL z1|q?+7LG6p4pyTi!Jsi!uw=%r_&FSX zUDD9DTbU!B#<0UKVL@JlnQYS>Oc6Cx&BT9p_HSxX^VJMBPtC(D!eW@FZnvxA9(9+( z+-Z_U@}Rn3-EYXo&3#8_OKY+AMQ=^qW4aM~q zzK~l330VX8tH0!}fu}hC--#|@lZ7uL|0nG#=mzeMmirP)Y*J6Ff0_)?lrzPAD~>=t}KSf%Q!%33plcb!7MHRL-B+V5C+ky-IuxURA>X!_KOehaOCTe!hg zv!wx?FXoVMBl&J<-hvdFoVc3*&s`N*=i0QxMv*_5iH;3&(v z1#K}CZc~G%xjB2ksQ$ug#!u4Lnj$E@!K<@yX z1D+c8}1$-gC+KIQgD~Rv!yrwBum*6xcpZ-MG}EdF1;G`Q88=Tt@yQ$$yM9 zewq$Y5wTxx|JS}F=aX*-`QAl>qb&T?7>FTiZ?P$P_SZL|lziWipP)U_!idoxs(OgF z8xr4)1?2BS{)3=;l7+pE>M%9fTAp4Rbr6h9*Np0dU#X0WVs0Fo`)L@XMqsu4+!Q`k zj7$$0mpFcU;-}CU8S!J-RJd9)Hg({cHd2kme|e(>E2v6TiJkC=YPyyCIOh#%-zwV$ zpP|yLE&Q+TW~?Zv-^c2%B<}8WY$wD3&$V!`eErAl{Al$u`de?Ud=cCk?Yq+UOJBgN zEIiB&D$21l@po2$1?X$C5KWTpHxA}z%N)fkE2CENgMZEHDs?4;jM@NaqXCMyWXV5; z{L{@Um;{G{YjB5Uo&05i2QTOzZCGk<>dbx`QQ9s6ZvtQq`rfR z{QP3_uOj~$$n6CS&vtFLo4BSYxYSpckpEorUjq2*GV(t~{=c+Np#6n~c8@m`nfJwgGiopVN@P?RJ<`woG>lgLGgxWYG=+;~ zPVR@f7{<@O_}RO&ImyE?NDab&tyA$^7%g?MI@nIde%d##?Ns!qZ6h|fXn%o)TWv>S zDnk9lJ*J|+n{5U*Gyj1W!p@qBqK?bp!M|p;RFyNxsAZs_+1(mT^s>K41^IW7|7}QF z(#uLtHUax(kTx_cOm_c7%lwg>fYx*~9=N!PI0%*2)w7rApHWTzpGk!QPqHw{ z*@&^WmCI8vwK@e*Utl5pAM0iBS;1vi4x{E@Zeiax6|A&OOc&FM)t1zz6Q!R0vo$qU zHKWamM*G*UAl0AL!N_o(g>cBEs+v}DYtFX(ae(JoIIE-e*Q+kOy3Xt){syZyIdA#3 z>E>&!dF`UNDL#@|bh{!~t>9a!Z`nw*fe{|&3Y7AfDf@HcrQoi`mikLRzoe^+2Kq!S+Yl@jtrUYW3BvUsE)Vr@3~&tV~A+GnxkQv3o&HX<3%dl`5Z2z7^!-?q0fz)R&~b&hRMmwymmGllqx7VOjOet~Nbg zZ&`jwS6Ub_jdnxQv!WL9Ag#_^Lpnklc1@jSVHZ>HE!GekucYU=)s=lqYbVy?H>YW^ ziZF1h(ZV85^F}#G#t|N=S&twzy8N4`KcQT?NW3!7&>zDJk zrCMx?Qou(nT<6**86X&BI;0|7TU)xAJtXy#)tm_U7YmK8ln!aF>zh_M3wk>&oZF^L zc3S2!-vdXGemDaRr^#T|6u2nh>@I4EE!>bg%x-VECSk@)3S3g-t`cl%3 z`5vA6(lT)pQeRoP0oy%$bnVOB#bthPwXOyH!NP4^BFNo#6uIc1P9uFQ>1Hd@o|Pm_ zzWJMi4xUbWJL%uIXdSZf0k<%6x39$rr?n-8P1lz#>Peq7nPPT&n|=o zRmY$%x|_}HLBIno#GzTMvALOP=e+J`g@1)!e+ys94TGH2O_@vb%%qyfB^)a1fFmq? zl}k9)_CHSRdZcB)hB6_TuhnW}CgGavj1|4kLp7SM0C%7sV;6QU;MiZ2euMPiA<+IR zV<)sa)~u{1#p9rln@lv0C<}P}8KifTev7SuiDSZE*g34HTP?(M^b89pbri|ey3|T1 zLvewHGr4jm9L%B5*1)mW%dEm|=q|T#eohx@5G~MEmS4*CS1U{lGZ_pEw-obM^)cO~ zwWs9fx$Pb2->W8DjaMsL-|vm109rd1_yNJ= zc>?c|{UaiSS<;URp3-Ud{i6g^HUs&C`-TJQ3Xr9c@4coM%OxZLHPdsCtH$0Az>y-x(MXqUaQ5qi9ut!86->=8WA zi%{zTc@rpbIR&n4(E*>}>rJ^fkFi>h#$$4^oa3~ffG3YLRqH8u@;I}!J{eCQXTH{R z@#Jw9Yn{boI0!Em^FY=XYkdkvGcZi5f*@1iV8L5qRP-#P4<9c#u>wbmd>eF+5_~5& z!OR+Gy11~@bEd013gVqDaGXm3e7xZ8Tu_Zo-pv{sXls3mBuD9P+67LLG429CZs9s01rO~gSBLdlZ6A_ z!iJ|73yYg|jY|f+QSkfRtQMOMrf}eT;eTMe=`pQ$aHBc-jUsAn^G2h(bj|XrQoMiD zf!n=_6!?$=2ss7r5d3v+>gK(m>RYv7X|}A6_o~2yqWB%~A1w}sT-Qja@{6spiZ;&1f#(Dx0%tq*`ljX$P4E*;{7eTP;{!UnqtK0p7UW1{lzB`}{Nf`y_6pOM!Z0#|vjAAfnKbJjB#5f!W4;H-K`kcrz-)IJp5OF0`j}*Mp=Gx$1x$59pk*tB% zIKiiz`t@y{#lho6@@r_FAox7a%k=ap#9;X!UN-Tf2u=}=62mZ&{JcJ%qN@e>Y9+3B$m3`kioh0yhbMyS0Uz zh4s&NEo3Xv6UQaaWV<(&g6~rB3*fs1@6KzOE9^m${RF)~S{%ah*4mNA%{|H&>fr61 z;o~Co13w`+$ddsbzc+Y)7GB6T|5R@PUbeW93eX9C9spOPEhP*PZPxMZBj z?7|4`Eo=noLi-3_fPC{e-rmPxFRH`KPDIPNq~4-e2HZz*ts7bxk)BecVv*HBZ-`*L ze~>kg#)pOpcQp_8fnW?5#v193&|%(56k1E6vrTWvTZz!o!aWyBGJ-FZQ*8ceGjyy7 z5vL1{7u<;EHEup?LgmWR<>dJR@Ie3zHC< zDvZ0iOF>VUp~UN&&;xNXT$C)QuE*>1ZNQ6NsUMx6f+Hi;)jEU1GPs$sEwOs#3QRNA< zUT`m0|0{%nYe8lVt`cK;2b4E>r%<>Lg>j}dODlA(H;2N5C_I?!-&(KD!XAP&Hwr!k z^}@Sej_`!G3GYzgTLq73U0Jsa>o8eatr_1Vk|U7t_kv4I#tk;-hlDvA3J(h&V{^u) zA8HZSSZUm&ve{h>*<;?R6dp(6@o2ZEdOmRD_v5D5wXc`CCx;+J88_frZ#)HRDR3$9 zbKYDEPoVI`_OXM|%c8dudanpR%|s6x1HeESVIX`bxjk4^U%e2Qnp(pMVe(2Typ+Q5cfvlwCIHyH3#r?L5yCNC z8VsLL;R~S~7ksH1xi*oL@UKL6IrO>+#(URJ&dIscUbwqgM&S((VBt3eACxQH#Sy}u4)2>Qe5i{fxPy1G4kx)X@3{jBAwY`AR#hdv}=%Zg5Yyp z%C><7ToHoO$)a>V@Jzw{Dr3*;wJz_-B2l{xNfryf&XvLQP67#$Y7t%!#T9~EUyt%w z)e3jBbZ5QL=Rvko@Qor{Ei~NE$Qr>nLB^wmxf59@ye-1x8FISt%=r=Y8A4AtJGQ%` zkP9S4F7lR9WGhAB$V4s{d{1t)bm)BUvPKa+1iW7Ge||BL5V>B|{@hU@A#$@wpF)PW z2!7smXyfMIQ%a_f8LuN(bK!T2{6*kq!LMSxnvB88k0eCy7ctJJkp~2ulPBLR%ni~b zBH0D4M+LucGRuo3M4lGO2he&(@Ml~_)BSry5+cuw#@V5_Q{-R5gQ<<|5*&d~XQuG`!ocYu@`2zO&kEN5NEmFLT2Ek+ z&xM_a$`^w7LWX=s>(`$<`g_L({y}gT<6!f(eYi`;yN!BY6-D=^=)P^d+h|bOU0ZZC zB>13K?>3qgULoWu!QIV7<3mogKv?XAwQ=X8`-!9vw7Lo&nCIO_dkAw76nY9aFN;xa zuzCv%cl5dQqJ3pBz5?#&Ra3N>qIf~vtWGt~t-8&u6iqSlZ3BFTHaf&xOyM^v{9oXq z-U^ByOwr-(ecR~aqPG)zBL(lWzHP7iN^>JKI$HSeKxd5L54Z*$Ik(Z{MdKrApCI@@ zIc=nZa~qu^g3lq)G|V}-K8`zr@uhQaePQR^`VMl=t?!Ul=QcW19MW^0a~qv4oTVK& zw}Z=Svh3V0$(AjfTF)=;ql>&ciY}t)QsBjcSDSHe=iNqEc=Z%LhoUfk(Hg-Q8{IbE zZFG&uE`i=!!RvEfu;)i5Iqx=lzPFO1S5WjSq`N@ywH@StnaE(aqn8VY5&j?EZS-1i z6-BpD^cEz$PVlWAWPhW`Zin7Yf^nGdBztqMbJ~(p?#yOyHAR0<(ffe63x2qR68<2v z7U`hS!JIB}n@7EOj z4aE?qjtvxijp<*TM}>|q!((!>oI0#FJb9dTI=Ti=9_MTwJrj@NwcEXWi``4!nH2jM#jw<3_c`Jl?iZeFIj5P; zgpS?8O?ZO5vncjG#c|_4_M{_%@CiD1n`19KJ-p>rLe zAU9NSon!xW>~7MpyBx!V^c_bW$dxj$5Bu>4Tk~p{lvXO0;9 z%Z=FW^x$#FesV;K>nzN+JcAt%It7H<;vq*&$ZtnH;@A^yJK{0NfQu84JL0%pJ8%-= z8^t>Ap%w9c$UBGPCr})(_2Talwrw6MQ@9T)=t`&`&`OI0pJX@Dth)lVd zVy9FAVu&LULFY=dV-+9fn24hDJdY1|4A|57A&yv^Ye(M3pyT~G#nI%QOYzeveh!F? zBQF2twoGz*uz2ywj`*Ex3q~ZbATDL5(?RqqKFbl?+6>Amj?GJ&6P@Z92r9G+APy@b5;DSj`-9|lqG2yDUa1|@F^$5)Ye0mYx9_)AE&+7bV7Ey-K_ z?G|zT0(?wN@qbbrA@ul#j`-1~b&J?;mO6e0*YYZ-h8TK$gAj>82eoWH{KmI9Jsd9L zH#=f)R}dR}w;{*xbYl3V@n%P~S;q0Z99x!g{2pP%e?p?)J8A1OcAKw`Z{i@=1>9`rdY0N1h}6%?gGc10PbhxT|$Y4 zlvvD~V0eqF@(e@C)x_VBOK9sn`)0JLIUQ{X0@!NFaoB5 z*FcH8DDfb&o8X8?O!YXBkT`+7MoK(Ri6>hl35n^B`4lu}IN}*|f_B#fFiRxmvrvNR zv)R08hLg|diFuCq5>Jr-c`+eTN#1%&yiAFIAaRu=zI20xp3jvH!)H}-B2TPw#J8-< zW${Js#5%|R4kKsUdIovFrNobv^ti3=bIQc|j_pG#*hs4rFs+q41BuHVI|!Z29T915 zY@_2v+ch@tjzXe|yelY~q$F+uB{n(2-13y!tJ07+`QSv`+S~c0Rzd))fj`+HxR-Npm-$Qk#BYrlm z8pXF7__)_$d&YD9VEIf1QaEKK=Q{$2%@NB+qih zRM(Po9LKy7hst@*=)MjDhV^<%O{WwBBzC@COx_KYnoX%W+>+dNge0t|<y*B6sw{be39gXW5VM{(igtD*tVD*2k=b935A z1s^>5rU=gCruZkhxUibf4cGpcTwK`yk?IK+cuFg|^q}_VxUk_3b>CIsQ<1*HJC!5E z4dY9=7v7aX?^*7{isbvkS=7Oo75quml=|h%-OW>E00Vv_rLLmXMi4OIme^`$#4c2! z&8>(eEcH#4x|>qC_L%(H5f2z`^k=KzpMtrznlMJGpd%hdjvaqNkc(TT_9AZ!r5>l$ zlSm0;Zi#0*C}V#od>)zyIO1=emf_w~r}~k1Go@ak)N4rC-w``HC<5nitGN@JLmj~# z({VHMucW7rB<~hVy-TV0kr>w566Rf2-t0?_bCS=Yc8nvwYF7qtdOEpTjZ@={6W!)d z3FW)fsZ+@NKT7XQ=>w7D97psq?X$Vupp)0($(;psa*Iyhh$oM8n@(=SlgGJRC%5Ct z<2;~~f54N+c|<4wgvW65;+M(aW4fj;adqhr;!;QOJN@L{CI#G-)|r5VvTX(;K&h)8 z(Rx4J-DThcU(1CN5yMQrz=dter2uiWBSvyz&zYr^i()2U(8>2C19p(*W1JMu#I^!Q zAP0DVmatm`508suCU@%Oe{&V+TU?DbhR-6BpKvuE%cTSHxFg1MH9oS{aQ7IJpXij5 zZ1O#vJ?}B3-f+20M3!$l!dwP*r>ndVep0)f#vG`>;|OzqoUIJ|`Kk9DJIi$f)7@oA z#dWIni{?TsG;S2khV6_j2$&5^EJCAFU2Xbh5PahVi!rzmbN>}x*CLb#QI-6x~5Z3Z*50M*Yti)ybgJGb;OyxBDlvIH}^bt+;p9e za``x{+VbJArh7W#0_?uf#PrBtYUx2vj(sRyyH0WnTZJE6BTp(#@2HtB}Si z*AnIs-rR1dO2b#P3eQ3tzM3UExI&hOb7qBqg(jRcOSHd4mMg>Ev`WK(S!KLoOXF;7 z2@^$Z`yMZSr4#-Wng|A3&G&PCyyu%#XMxh2o$iN72oKCA{IvZ}mEPurpFtBRU90)u zc14(lmJX^RYKWQ8o$ey(7V_?-f_4-^@zeA+|?G%PV`!h$FySqFEb8or0 zz`;2KjU6J*e~uuH!>G+4@wqe%k|hr3!g`uHoZBJNy>J60Su8X@@Nq7W-I|iqthj}e9rbjC*Z$Y1kqTXo+DPYpqG>F z*J?#mg`77+YRyzInhLN-6u?SZV)-vx(Si|9Z+b^ov>@ZeGmvMABW81J**1z5Ef~h- zBTQzC#HLdKn`8+@L_4se1=F0o49YM_R(V;j8#}b3@h`a?_&R2)7vR)a0AFW26;x0` zWqT`Hu+S|E#Apk$j`*oVD_Ve)pj|VkDnB?A4^9FfZDTPs>{ xhLafk>a3{x$;{Tb#fGY{6-;Qu7&e>*=Shn6GiE1Y7NTpmZty_303X}W{|EADI+y?e diff --git a/bots/sustainabot/bot-integration/lib/bs/src/GitHubAPI.cmi b/bots/sustainabot/bot-integration/lib/bs/src/GitHubAPI.cmi deleted file mode 100644 index 468068e3394f89a9de455381f1649b91dbc92f12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3272 zcmai02~-qU7Of)PE+c9_MjiM5ekRkJ{yXv=R=A22N(^a?bd++~u z-~09J$0+r>84(c?aw0r@?WTPV7&f{H!|-Md8}$N)N&7(10xg?hRz;=C0kGnd6G3K% zqN8#s154Vh)tq%<0K?K+Lk>xDq>J>|E({wXt+uhTvV0{i(;HYBm95j77)nM{CL<$b z%nYm48k8y{D}(<~t%0R-XeFyP8e|NeEkm<~(G(MpsW6RA;=b z5cL>RWx!8mR9oO=vSb_&#PML8gm9oReo(7Cz-ZzXk-%DARmE9JpF}3gFOe}CQoLF0 z4>Z^lg!=ig)Ibw$)N2`vkK?R~0k8yS9s6ga4DjBPM!nwAeW8Rjnx$K;mjzKbL~13XZVHq& z$`^Luxo&QWt{if`4g33sU0#CyItf{N?9Tu_-$CduLcOBIdm^|mf?q`NfaKyF>L2pz zKgXi+Q4)OA7@K650ACdJ+d|DIwUVX&NB`Go!b_rpIz;^_QZ__g7AdFnD&f#_^UO}&uq{>Q?09Z+t0}VCxki>`j@Ekng}{Ya9sp&1fc+3d;z*JB|bJ6A8W8l zx&>Gy6reFIo2K{z{Ef=aOEdFtpRfWRqZtu3gs4WrONwKNYeL*;#5E&s0^LW7g}HG<?{Wt$aWu?Q- z`Su@1!+eF1Rn$}^0_Y#(Xlk`xTs4kW;%-*ltp>=V)5pmeoeL0}ztVs&!hG;!TT*;)qcd0~<0|y)k!Ie|@cOU5N^S zP{E#V(W{I)ju;)?>%C4f>72%Ur~L4mls>0N8kG}QVB(0|J$LIPZJse#e1poTs-?>S zkO^a?&}xeR@^eJ!;B%K=IW)EKW|60f?z_?D^ht&*QmN9xT*#wU-MR+j?R4ept(gT! zLY=wtJ{-|7?c=42O`}SV&F4DR$_bO4_9SJYg(LE`bIDRx6_Pj3V5l6ZeFDIAA&*2R zuE4+%hYs43i5|k1aq*KaDPG&HVy7%zm(MvH9O}>OixMX zi1yy<#Uc6Ot4looYODTY5Y|)FDrYHpNa4q5yjGXn;}M}q$Ql{rwejBf&WbJ28C6QC zWaV;?z(q03Bdf+Af8qVq8VrD7ArX6?JIYR9e7FD8N3(riyIT;kb-Xi)Sh%@zL}BH% zpTckU?k|2l`TT%p;spT0h43hvR$8LX8Vv>WXuH~7mNoRLmkZJ4JN^Cn!_Iox-8kYf zbF4Hsy>7yomohvHA8bDfK!9T$j@UUZYo7e4JtZuyk}y!MQfDwoP; z6;uJN9_-NU=7On_JAT{{GNod>;qtLP0L*my<}%3drHmz$CpYcL>WN$3IWuA_Ja`7D zQgptOf$1@D&3?D-;`REbzNCe%^AA`2B8AEm8HL%PrZidurRIob>Vt9M^Nxz3rMFAx zeBt2&z^l-Kg|7sR&RObf2@cpTsqOHXrOV#;0qn70R4bHxfx|iC!BBoe+uGgIDR~2z ziQmiNIthY4j&m+YWcbUUJo>qVa$Oqj71Fk2IfxW1oFZwrH!E8yf|W?pGV{_FhbsYx&33$_dbH!cv~(! zIdVi--|*fgz6mS1ORZ-<)U<4H*wor=mLuL-kw16$)Y5(4J-aS!kNjb=BV$p|wzu{! zyp^<}WOe9A4}Y`e`vL$Dq#R+szTUmF@4fnsE#4*|Ju?pg-&mubBXsu*_k1{P9KtcUfAbDvE4OVrV)n@_mIr5jD@SVfBcv)y;q7+00j5~F;BEhag771OUZ;w?{!-W%F&yrT=tuqs(OEpB diff --git a/bots/sustainabot/bot-integration/lib/bs/src/GitHubAPI.cmj b/bots/sustainabot/bot-integration/lib/bs/src/GitHubAPI.cmj deleted file mode 100644 index 02302bd26e0171458cefaa3f23b8229273dd9fac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 199 zcmeZtbV@txcaPIzp@JF5%{Jbasmt~;Ffc3zVs#*H1LDd94>o8e7Gwsc7M7+KmrPi& zz{SDAVS{dZYDrLPL4I*&Nq$i!P}CVL3KS>_2y)KP%}vb%sdWX5mKLNWmZYMI>LnMY zfUu?~#d=xA G4h{fL|4hID diff --git a/bots/sustainabot/bot-integration/lib/bs/src/GitHubAPI.cmt b/bots/sustainabot/bot-integration/lib/bs/src/GitHubAPI.cmt deleted file mode 100644 index 9fe4a857a2fca0084bd82cb6f3294467c45ea447..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60928 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 diff --git a/bots/sustainabot/bot-integration/lib/bs/src/GitHubAPI.res b/bots/sustainabot/bot-integration/lib/bs/src/GitHubAPI.res deleted file mode 100644 index ef21edd..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/src/GitHubAPI.res +++ /dev/null @@ -1,177 +0,0 @@ -// GitHub REST API Client -// Authenticated API calls using installation access tokens - -open Deno - -let userAgent = "oikos-bot/0.1.0-beta" -let apiVersion = "2022-11-28" - -// Make an authenticated request to GitHub API -let apiRequest = async ( - token: string, - method: string, - endpoint: string, - ~body: option=?, -): result => { - let url = `https://api.github.com${endpoint}` - - let headers = { - "Authorization": `Bearer ${token}`, - "Accept": "application/vnd.github+json", - "X-GitHub-Api-Version": apiVersion, - "User-Agent": userAgent, - "Content-Type": "application/json", - } - - try { - let response = switch body { - | Some(b) => - await Fetch.fetch( - url, - { - "method": method, - "headers": headers, - "body": Js.Json.stringify(b), - }, - ) - | None => - await Fetch.fetch( - url, - { - "method": method, - "headers": headers, - }, - ) - } - - if !Fetch.ok(response) { - let status = Fetch.status(response) - let errorBody = await Fetch.text(response) - Error(`GitHub API error ${Belt.Int.toString(status)}: ${errorBody}`) - } else { - let json = await Fetch.json(response) - Ok(json) - } - } catch { - | exn => - let msg = switch Js.Exn.asJsExn(exn) { - | Some(jsExn) => Js.Exn.message(jsExn)->Belt.Option.getWithDefault("Unknown error") - | None => "Unknown error" - } - Error(`API request failed: ${msg}`) - } -} - -// Post a comment on a pull request -let postPRComment = async ( - token: string, - owner: string, - repo: string, - prNumber: int, - body: string, -): result => { - let endpoint = `/repos/${owner}/${repo}/issues/${Belt.Int.toString(prNumber)}/comments` - let payload = Js.Json.object_(Js.Dict.fromArray([("body", Js.Json.string(body))])) - - let result = await apiRequest(token, "POST", endpoint, ~body=payload) - - switch result { - | Ok(json) => - switch Js.Json.decodeObject(json) { - | Some(obj) => - switch Js.Dict.get(obj, "id") { - | Some(id) => - switch Js.Json.decodeNumber(id) { - | Some(num) => Ok(Belt.Float.toInt(num)) - | None => Error("Invalid comment ID in response") - } - | None => Error("No comment ID in response") - } - | None => Error("Invalid JSON response") - } - | Error(e) => Error(e) - } -} - -// Update an existing comment -let updateComment = async ( - token: string, - owner: string, - repo: string, - commentId: int, - body: string, -): result => { - let endpoint = `/repos/${owner}/${repo}/issues/comments/${Belt.Int.toString(commentId)}` - let payload = Js.Json.object_(Js.Dict.fromArray([("body", Js.Json.string(body))])) - - let result = await apiRequest(token, "PATCH", endpoint, ~body=payload) - - switch result { - | Ok(_) => Ok() - | Error(e) => Error(e) - } -} - -// Create a check run (for CI status reporting) -let createCheckRun = async ( - token: string, - owner: string, - repo: string, - headSha: string, - name: string, - conclusion: string, // "success", "failure", "neutral", "cancelled", "skipped", "timed_out", "action_required" - ~title: string, - ~summary: string, -): result => { - let endpoint = `/repos/${owner}/${repo}/check-runs` - let payload = Js.Json.object_( - Js.Dict.fromArray([ - ("name", Js.Json.string(name)), - ("head_sha", Js.Json.string(headSha)), - ("status", Js.Json.string("completed")), - ("conclusion", Js.Json.string(conclusion)), - ( - "output", - Js.Json.object_( - Js.Dict.fromArray([("title", Js.Json.string(title)), ("summary", Js.Json.string(summary))]), - ), - ), - ]), - ) - - let result = await apiRequest(token, "POST", endpoint, ~body=payload) - - switch result { - | Ok(json) => - switch Js.Json.decodeObject(json) { - | Some(obj) => - switch Js.Dict.get(obj, "id") { - | Some(id) => - switch Js.Json.decodeNumber(id) { - | Some(num) => Ok(Belt.Float.toInt(num)) - | None => Error("Invalid check run ID in response") - } - | None => Error("No check run ID in response") - } - | None => Error("Invalid JSON response") - } - | Error(e) => Error(e) - } -} - -// Get pull request details -let getPullRequest = async ( - token: string, - owner: string, - repo: string, - prNumber: int, -): result => { - let endpoint = `/repos/${owner}/${repo}/pulls/${Belt.Int.toString(prNumber)}` - await apiRequest(token, "GET", endpoint) -} - -// Get repository details -let getRepository = async (token: string, owner: string, repo: string): result => { - let endpoint = `/repos/${owner}/${repo}` - await apiRequest(token, "GET", endpoint) -} diff --git a/bots/sustainabot/bot-integration/lib/bs/src/GitHubAPI.res.js b/bots/sustainabot/bot-integration/lib/bs/src/GitHubAPI.res.js deleted file mode 100644 index d14ddc4..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/src/GitHubAPI.res.js +++ /dev/null @@ -1,205 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE - -import * as Js_dict from "@rescript/runtime/lib/es6/Js_dict.js"; -import * as Js_json from "@rescript/runtime/lib/es6/Js_json.js"; -import * as Stdlib_Exn from "@rescript/runtime/lib/es6/Stdlib_Exn.js"; -import * as Belt_Option from "@rescript/runtime/lib/es6/Belt_Option.js"; -import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js"; -import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js"; - -let userAgent = "oikos-bot/0.1.0-beta"; - -let apiVersion = "2022-11-28"; - -async function apiRequest(token, method, endpoint, body) { - let url = `https://api.github.com` + endpoint; - let headers = { - Authorization: `Bearer ` + token, - Accept: "application/vnd.github+json", - "X-GitHub-Api-Version": apiVersion, - "User-Agent": userAgent, - "Content-Type": "application/json" - }; - try { - let response = body !== undefined ? await globalThis.fetch(url, { - method: method, - headers: headers, - body: JSON.stringify(body) - }) : await globalThis.fetch(url, { - method: method, - headers: headers - }); - if (response.ok) { - let json = await response.json(); - return { - TAG: "Ok", - _0: json - }; - } - let status = response.status; - let errorBody = await response.text(); - return { - TAG: "Error", - _0: `GitHub API error ` + String(status) + `: ` + errorBody - }; - } catch (raw_exn) { - let exn = Primitive_exceptions.internalToException(raw_exn); - let jsExn = Stdlib_Exn.asJsExn(exn); - let msg = jsExn !== undefined ? Belt_Option.getWithDefault(Primitive_option.valFromOption(jsExn).message, "Unknown error") : "Unknown error"; - return { - TAG: "Error", - _0: `API request failed: ` + msg - }; - } -} - -async function postPRComment(token, owner, repo, prNumber, body) { - let endpoint = `/repos/` + owner + `/` + repo + `/issues/` + String(prNumber) + `/comments`; - let payload = Js_dict.fromArray([[ - "body", - body - ]]); - let result = await apiRequest(token, "POST", endpoint, payload); - if (result.TAG !== "Ok") { - return { - TAG: "Error", - _0: result._0 - }; - } - let obj = Js_json.decodeObject(result._0); - if (obj === undefined) { - return { - TAG: "Error", - _0: "Invalid JSON response" - }; - } - let id = Js_dict.get(obj, "id"); - if (id === undefined) { - return { - TAG: "Error", - _0: "No comment ID in response" - }; - } - let num = Js_json.decodeNumber(id); - if (num !== undefined) { - return { - TAG: "Ok", - _0: num | 0 - }; - } else { - return { - TAG: "Error", - _0: "Invalid comment ID in response" - }; - } -} - -async function updateComment(token, owner, repo, commentId, body) { - let endpoint = `/repos/` + owner + `/` + repo + `/issues/comments/` + String(commentId); - let payload = Js_dict.fromArray([[ - "body", - body - ]]); - let result = await apiRequest(token, "PATCH", endpoint, payload); - if (result.TAG === "Ok") { - return { - TAG: "Ok", - _0: undefined - }; - } else { - return { - TAG: "Error", - _0: result._0 - }; - } -} - -async function createCheckRun(token, owner, repo, headSha, name, conclusion, title, summary) { - let endpoint = `/repos/` + owner + `/` + repo + `/check-runs`; - let payload = Js_dict.fromArray([ - [ - "name", - name - ], - [ - "head_sha", - headSha - ], - [ - "status", - "completed" - ], - [ - "conclusion", - conclusion - ], - [ - "output", - Js_dict.fromArray([ - [ - "title", - title - ], - [ - "summary", - summary - ] - ]) - ] - ]); - let result = await apiRequest(token, "POST", endpoint, payload); - if (result.TAG !== "Ok") { - return { - TAG: "Error", - _0: result._0 - }; - } - let obj = Js_json.decodeObject(result._0); - if (obj === undefined) { - return { - TAG: "Error", - _0: "Invalid JSON response" - }; - } - let id = Js_dict.get(obj, "id"); - if (id === undefined) { - return { - TAG: "Error", - _0: "No check run ID in response" - }; - } - let num = Js_json.decodeNumber(id); - if (num !== undefined) { - return { - TAG: "Ok", - _0: num | 0 - }; - } else { - return { - TAG: "Error", - _0: "Invalid check run ID in response" - }; - } -} - -async function getPullRequest(token, owner, repo, prNumber) { - let endpoint = `/repos/` + owner + `/` + repo + `/pulls/` + String(prNumber); - return await apiRequest(token, "GET", endpoint, undefined); -} - -async function getRepository(token, owner, repo) { - let endpoint = `/repos/` + owner + `/` + repo; - return await apiRequest(token, "GET", endpoint, undefined); -} - -export { - userAgent, - apiVersion, - apiRequest, - postPRComment, - updateComment, - createCheckRun, - getPullRequest, - getRepository, -} -/* No side effect */ diff --git a/bots/sustainabot/bot-integration/lib/bs/src/GitHubApp.ast b/bots/sustainabot/bot-integration/lib/bs/src/GitHubApp.ast deleted file mode 100644 index a419314fea00f7a2e8b2cd70e9993859c246cf93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28715 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 diff --git a/bots/sustainabot/bot-integration/lib/bs/src/GitHubApp.cmi b/bots/sustainabot/bot-integration/lib/bs/src/GitHubApp.cmi deleted file mode 100644 index 6d787469844cfd164ea16f0fe727c1aac5eae376..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2737 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 diff --git a/bots/sustainabot/bot-integration/lib/bs/src/GitHubApp.res b/bots/sustainabot/bot-integration/lib/bs/src/GitHubApp.res deleted file mode 100644 index 623e813..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/src/GitHubApp.res +++ /dev/null @@ -1,234 +0,0 @@ -// GitHub App JWT Authentication -// Generates RS256 JWTs for GitHub App authentication and manages installation tokens - -open Deno - -// Token cache - stores installation tokens to avoid unnecessary API calls -let tokenCache: Js.Dict.t = Js.Dict.empty() - -// Convert PEM private key to ArrayBuffer for Web Crypto API -let pemToArrayBuffer = (pem: string): Js.TypedArray2.ArrayBuffer.t => { - // Remove PEM header/footer and whitespace - let pemContents = pem - ->Js.String2.replaceByRe(%re("/-----BEGIN (?:RSA )?PRIVATE KEY-----/g"), "") - ->Js.String2.replaceByRe(%re("/-----END (?:RSA )?PRIVATE KEY-----/g"), "") - ->Js.String2.replaceByRe(%re("/\\s/g"), "") - - // Decode base64 to binary string - let binaryStr = Base64.atob(pemContents) - let len = Js.String.length(binaryStr) - - // Convert to Uint8Array - let bytes = Js.TypedArray2.Uint8Array.fromLength(len) - for i in 0 to len - 1 { - let charCode = Js.String2.charCodeAt(binaryStr, i)->Belt.Float.toInt - Js.TypedArray2.Uint8Array.unsafe_set(bytes, i, charCode) - } - - Js.TypedArray2.Uint8Array.buffer(bytes) -} - -// Base64URL encode (for JWT) -let base64UrlEncode = (data: Js.TypedArray2.Uint8Array.t): string => { - // Convert Uint8Array to binary string - let len = Js.TypedArray2.Uint8Array.length(data) - let binaryStr = ref("") - for i in 0 to len - 1 { - let byte = Js.TypedArray2.Uint8Array.unsafe_get(data, i) - binaryStr := binaryStr.contents ++ Js.String.fromCharCode(byte) - } - - // Base64 encode then make URL-safe - Base64.btoa(binaryStr.contents) - ->Js.String2.replaceByRe(%re("/\+/g"), "-") - ->Js.String2.replaceByRe(%re("/\//g"), "_") - ->Js.String2.replaceByRe(%re("/=+$/g"), "") -} - -// Base64URL encode a string -let base64UrlEncodeString = (str: string): string => { - Base64.btoa(str) - ->Js.String2.replaceByRe(%re("/\+/g"), "-") - ->Js.String2.replaceByRe(%re("/\//g"), "_") - ->Js.String2.replaceByRe(%re("/=+$/g"), "") -} - -// Generate JWT for GitHub App authentication -// JWT is valid for 10 minutes (GitHub requirement) -let generateJWT = async (appId: string, privateKeyPem: string): result => { - let nowSeconds = Js.Date.now() /. 1000.0 - - // JWT Header - let header = Js.Dict.fromArray([ - ("alg", Js.Json.string("RS256")), - ("typ", Js.Json.string("JWT")), - ]) - let headerB64 = base64UrlEncodeString(Js.Json.stringify(Js.Json.object_(header))) - - // JWT Payload - issued 60 seconds ago to account for clock drift - let payload = Js.Dict.fromArray([ - ("iss", Js.Json.string(appId)), - ("iat", Js.Json.number(nowSeconds -. 60.0)), - ("exp", Js.Json.number(nowSeconds +. 600.0)), // 10 minutes - ]) - let payloadB64 = base64UrlEncodeString(Js.Json.stringify(Js.Json.object_(payload))) - - // Message to sign - let message = `${headerB64}.${payloadB64}` - - try { - // Import RSA private key - let keyBuffer = pemToArrayBuffer(privateKeyPem) - let encoder = TextEncoder.make() - - let key = await Crypto.importKeyPkcs8( - Crypto.subtle, - keyBuffer, - {"name": "RSASSA-PKCS1-v1_5", "hash": "SHA-256"}, - false, - ["sign"], - ) - - // Sign the message - let messageBytes = TextEncoder.encode(encoder, message) - let signatureBuffer = await Crypto.signWithAlgorithm( - Crypto.subtle, - {"name": "RSASSA-PKCS1-v1_5"}, - key, - messageBytes, - ) - - // Convert signature to base64url - let signatureBytes = ArrayBuffer.makeUint8Array(signatureBuffer) - let signatureB64 = base64UrlEncode(signatureBytes) - - Ok(`${message}.${signatureB64}`) - } catch { - | exn => - let msg = switch Js.Exn.asJsExn(exn) { - | Some(jsExn) => Js.Exn.message(jsExn)->Belt.Option.getWithDefault("Unknown error") - | None => "Unknown error" - } - Error(`Failed to generate JWT: ${msg}`) - } -} - -// Get installation access token from GitHub -// Tokens are valid for 1 hour -let getInstallationToken = async (jwt: string, installationId: int): result => { - let cacheKey = Belt.Int.toString(installationId) - - // Check cache first - switch Js.Dict.get(tokenCache, cacheKey) { - | Some(cached) if cached.expiresAt > Js.Date.now() +. 60000.0 => - // Return cached token if it has at least 1 minute remaining - Ok(cached) - | _ => - // Fetch new token - try { - let response = await Fetch.fetch( - `https://api.github.com/app/installations/${cacheKey}/access_tokens`, - { - "method": "POST", - "headers": { - "Authorization": `Bearer ${jwt}`, - "Accept": "application/vnd.github+json", - "X-GitHub-Api-Version": "2022-11-28", - "User-Agent": "oikos-bot", - }, - }, - ) - - if !Fetch.ok(response) { - let status = Fetch.status(response) - let body = await Fetch.text(response) - Error(`GitHub API error ${Belt.Int.toString(status)}: ${body}`) - } else { - let json = await Fetch.json(response) - switch Js.Json.decodeObject(json) { - | Some(obj) => - let token = switch Js.Dict.get(obj, "token") { - | Some(t) => Js.Json.decodeString(t)->Belt.Option.getWithDefault("") - | None => "" - } - let expiresAtStr = switch Js.Dict.get(obj, "expires_at") { - | Some(e) => Js.Json.decodeString(e)->Belt.Option.getWithDefault("") - | None => "" - } - - if token == "" { - Error("No token in response") - } else { - // Parse ISO 8601 date to timestamp (getTime returns ms since epoch) - let expiresAtDate = Js.Date.fromString(expiresAtStr) - let expiresAt = Js.Date.getTime(expiresAtDate) - let installToken: Types.installationToken = { - token, - expiresAt, - } - - // Cache the token - Js.Dict.set(tokenCache, cacheKey, installToken) - - Ok(installToken) - } - | None => Error("Invalid JSON response") - } - } - } catch { - | exn => - let msg = switch Js.Exn.asJsExn(exn) { - | Some(jsExn) => Js.Exn.message(jsExn)->Belt.Option.getWithDefault("Unknown error") - | None => "Unknown error" - } - Error(`Failed to get installation token: ${msg}`) - } - } -} - -// Extract installation ID from webhook payload -let extractInstallationId = (payload: Js.Json.t): option => { - switch Js.Json.decodeObject(payload) { - | Some(obj) => - switch Js.Dict.get(obj, "installation") { - | Some(inst) => - switch Js.Json.decodeObject(inst) { - | Some(instObj) => - switch Js.Dict.get(instObj, "id") { - | Some(id) => - switch Js.Json.decodeNumber(id) { - | Some(num) => Some(Belt.Float.toInt(num)) - | None => None - } - | None => None - } - | None => None - } - | None => None - } - | None => None - } -} - -// Get an authenticated token for a repository installation -// This is the main entry point for authentication -let getAuthToken = async (config: Types.config, payload: Js.Json.t): result => { - switch (config.githubAppId, config.githubPrivateKey) { - | (Some(appId), Some(privateKey)) => - switch extractInstallationId(payload) { - | Some(installationId) => - let jwtResult = await generateJWT(appId, privateKey) - switch jwtResult { - | Ok(jwt) => - let tokenResult = await getInstallationToken(jwt, installationId) - switch tokenResult { - | Ok(installToken) => Ok(installToken.token) - | Error(e) => Error(e) - } - | Error(e) => Error(e) - } - | None => Error("No installation ID in payload") - } - | _ => Error("GitHub App credentials not configured") - } -} diff --git a/bots/sustainabot/bot-integration/lib/bs/src/GitHubApp.res.js b/bots/sustainabot/bot-integration/lib/bs/src/GitHubApp.res.js deleted file mode 100644 index 48795ae..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/src/GitHubApp.res.js +++ /dev/null @@ -1,238 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE - -import * as Js_dict from "@rescript/runtime/lib/es6/Js_dict.js"; -import * as Js_json from "@rescript/runtime/lib/es6/Js_json.js"; -import * as Stdlib_Exn from "@rescript/runtime/lib/es6/Stdlib_Exn.js"; -import * as Belt_Option from "@rescript/runtime/lib/es6/Belt_Option.js"; -import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js"; -import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js"; - -let tokenCache = {}; - -function pemToArrayBuffer(pem) { - let pemContents = pem.replace(/-----BEGIN (?:RSA )?PRIVATE KEY-----/g, "").replace(/-----END (?:RSA )?PRIVATE KEY-----/g, "").replace(/\\s/g, ""); - let binaryStr = globalThis.atob(pemContents); - let len = binaryStr.length; - let bytes = new Uint8Array(len); - for (let i = 0; i < len; ++i) { - let charCode = binaryStr.charCodeAt(i) | 0; - bytes[i] = charCode; - } - return bytes.buffer; -} - -function base64UrlEncode(data) { - let len = data.length; - let binaryStr = ""; - for (let i = 0; i < len; ++i) { - let byte = data[i]; - binaryStr = binaryStr + String.fromCharCode(byte); - } - return globalThis.btoa(binaryStr).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, ""); -} - -function base64UrlEncodeString(str) { - return globalThis.btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, ""); -} - -async function generateJWT(appId, privateKeyPem) { - let nowSeconds = Date.now() / 1000.0; - let header = Js_dict.fromArray([ - [ - "alg", - "RS256" - ], - [ - "typ", - "JWT" - ] - ]); - let headerB64 = base64UrlEncodeString(JSON.stringify(header)); - let payload = Js_dict.fromArray([ - [ - "iss", - appId - ], - [ - "iat", - nowSeconds - 60.0 - ], - [ - "exp", - nowSeconds + 600.0 - ] - ]); - let payloadB64 = base64UrlEncodeString(JSON.stringify(payload)); - let message = headerB64 + `.` + payloadB64; - try { - let keyBuffer = pemToArrayBuffer(privateKeyPem); - let encoder = new (globalThis.TextEncoder)(); - let key = await globalThis.crypto.subtle.importKey("pkcs8", keyBuffer, { - name: "RSASSA-PKCS1-v1_5", - hash: "SHA-256" - }, false, ["sign"]); - let messageBytes = encoder.encode(message); - let signatureBuffer = await globalThis.crypto.subtle.sign({ - name: "RSASSA-PKCS1-v1_5" - }, key, messageBytes); - let signatureBytes = new (globalThis.Uint8Array)(signatureBuffer); - let signatureB64 = base64UrlEncode(signatureBytes); - return { - TAG: "Ok", - _0: message + `.` + signatureB64 - }; - } catch (raw_exn) { - let exn = Primitive_exceptions.internalToException(raw_exn); - let jsExn = Stdlib_Exn.asJsExn(exn); - let msg = jsExn !== undefined ? Belt_Option.getWithDefault(Primitive_option.valFromOption(jsExn).message, "Unknown error") : "Unknown error"; - return { - TAG: "Error", - _0: `Failed to generate JWT: ` + msg - }; - } -} - -async function getInstallationToken(jwt, installationId) { - let cacheKey = String(installationId); - let cached = Js_dict.get(tokenCache, cacheKey); - if (cached !== undefined && cached.expiresAt > Date.now() + 60000.0) { - return { - TAG: "Ok", - _0: cached - }; - } - try { - let response = await globalThis.fetch(`https://api.github.com/app/installations/` + cacheKey + `/access_tokens`, { - method: "POST", - headers: { - Authorization: `Bearer ` + jwt, - Accept: "application/vnd.github+json", - "X-GitHub-Api-Version": "2022-11-28", - "User-Agent": "oikos-bot" - } - }); - if (response.ok) { - let json = await response.json(); - let obj = Js_json.decodeObject(json); - if (obj === undefined) { - return { - TAG: "Error", - _0: "Invalid JSON response" - }; - } - let t = Js_dict.get(obj, "token"); - let token = t !== undefined ? Belt_Option.getWithDefault(Js_json.decodeString(t), "") : ""; - let e = Js_dict.get(obj, "expires_at"); - let expiresAtStr = e !== undefined ? Belt_Option.getWithDefault(Js_json.decodeString(e), "") : ""; - if (token === "") { - return { - TAG: "Error", - _0: "No token in response" - }; - } - let expiresAtDate = new Date(expiresAtStr); - let expiresAt = expiresAtDate.getTime(); - let installToken = { - token: token, - expiresAt: expiresAt - }; - tokenCache[cacheKey] = installToken; - return { - TAG: "Ok", - _0: installToken - }; - } - let status = response.status; - let body = await response.text(); - return { - TAG: "Error", - _0: `GitHub API error ` + String(status) + `: ` + body - }; - } catch (raw_exn) { - let exn = Primitive_exceptions.internalToException(raw_exn); - let jsExn = Stdlib_Exn.asJsExn(exn); - let msg = jsExn !== undefined ? Belt_Option.getWithDefault(Primitive_option.valFromOption(jsExn).message, "Unknown error") : "Unknown error"; - return { - TAG: "Error", - _0: `Failed to get installation token: ` + msg - }; - } -} - -function extractInstallationId(payload) { - let obj = Js_json.decodeObject(payload); - if (obj === undefined) { - return; - } - let inst = Js_dict.get(obj, "installation"); - if (inst === undefined) { - return; - } - let instObj = Js_json.decodeObject(inst); - if (instObj === undefined) { - return; - } - let id = Js_dict.get(instObj, "id"); - if (id === undefined) { - return; - } - let num = Js_json.decodeNumber(id); - if (num !== undefined) { - return num | 0; - } -} - -async function getAuthToken(config, payload) { - let match = config.githubAppId; - let match$1 = config.githubPrivateKey; - if (match === undefined) { - return { - TAG: "Error", - _0: "GitHub App credentials not configured" - }; - } - if (match$1 === undefined) { - return { - TAG: "Error", - _0: "GitHub App credentials not configured" - }; - } - let installationId = extractInstallationId(payload); - if (installationId === undefined) { - return { - TAG: "Error", - _0: "No installation ID in payload" - }; - } - let jwtResult = await generateJWT(match, match$1); - if (jwtResult.TAG !== "Ok") { - return { - TAG: "Error", - _0: jwtResult._0 - }; - } - let tokenResult = await getInstallationToken(jwtResult._0, installationId); - if (tokenResult.TAG === "Ok") { - return { - TAG: "Ok", - _0: tokenResult._0.token - }; - } else { - return { - TAG: "Error", - _0: tokenResult._0 - }; - } -} - -export { - tokenCache, - pemToArrayBuffer, - base64UrlEncode, - base64UrlEncodeString, - generateJWT, - getInstallationToken, - extractInstallationId, - getAuthToken, -} -/* No side effect */ diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Main.ast b/bots/sustainabot/bot-integration/lib/bs/src/Main.ast deleted file mode 100644 index 669056270c67931f1ffc774af7f29867a4c9b8fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49074 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༟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 => { - let timestamp = Js.Date.toISOString(Js.Date.make()) - let logObj = switch data { - | Some(d) => - Js.Dict.fromArray([ - ("timestamp", Js.Json.string(timestamp)), - ("level", Js.Json.string(level)), - ("message", Js.Json.string(msg)), - ("data", d), - ]) - | None => - Js.Dict.fromArray([ - ("timestamp", Js.Json.string(timestamp)), - ("level", Js.Json.string(level)), - ("message", Js.Json.string(msg)), - ]) - } - Js.Console.log(Js.Json.stringify(Js.Json.object_(logObj))) -} - -let info = (msg, ~data=?) => log("info", msg, data) -let error = (msg, ~data=?) => log("error", msg, data) - -// Extract PR info from GitHub payload -let extractPRInfo = (payload: Js.Json.t): (int, string, string) => { - switch Js.Json.decodeObject(payload) { - | Some(obj) => - let prNumber = switch Js.Dict.get(obj, "number") { - | Some(n) => - switch Js.Json.decodeNumber(n) { - | Some(num) => Belt.Float.toInt(num) - | None => 0 - } - | None => 0 - } - let (baseSha, headSha) = switch Js.Dict.get(obj, "pull_request") { - | Some(pr) => - switch Js.Json.decodeObject(pr) { - | Some(prObj) => - let base = switch Js.Dict.get(prObj, "base") { - | Some(b) => - switch Js.Json.decodeObject(b) { - | Some(baseObj) => - switch Js.Dict.get(baseObj, "sha") { - | Some(s) => Js.Json.decodeString(s)->Belt.Option.getWithDefault("") - | None => "" - } - | None => "" - } - | None => "" - } - let head = switch Js.Dict.get(prObj, "head") { - | Some(h) => - switch Js.Json.decodeObject(h) { - | Some(headObj) => - switch Js.Dict.get(headObj, "sha") { - | Some(s) => Js.Json.decodeString(s)->Belt.Option.getWithDefault("") - | None => "" - } - | None => "" - } - | None => "" - } - (base, head) - | None => ("", "") - } - | None => ("", "") - } - (prNumber, baseSha, headSha) - | None => (0, "", "") - } -} - -// Extract MR info from GitLab payload -let extractMRInfo = (payload: Js.Json.t): (int, string, string) => { - switch Js.Json.decodeObject(payload) { - | Some(obj) => - switch Js.Dict.get(obj, "object_attributes") { - | Some(attrs) => - switch Js.Json.decodeObject(attrs) { - | Some(attrsObj) => - let mrIid = switch Js.Dict.get(attrsObj, "iid") { - | Some(n) => - switch Js.Json.decodeNumber(n) { - | Some(num) => Belt.Float.toInt(num) - | None => 0 - } - | None => 0 - } - let baseSha = switch Js.Dict.get(attrsObj, "diff_refs") { - | Some(refs) => - switch Js.Json.decodeObject(refs) { - | Some(refsObj) => - switch Js.Dict.get(refsObj, "base_sha") { - | Some(s) => Js.Json.decodeString(s)->Belt.Option.getWithDefault("") - | None => "" - } - | None => "" - } - | None => "" - } - let headSha = switch Js.Dict.get(attrsObj, "last_commit") { - | Some(commit) => - switch Js.Json.decodeObject(commit) { - | Some(commitObj) => - switch Js.Dict.get(commitObj, "id") { - | Some(s) => Js.Json.decodeString(s)->Belt.Option.getWithDefault("") - | None => "" - } - | None => "" - } - | None => "" - } - (mrIid, baseSha, headSha) - | None => (0, "", "") - } - | None => (0, "", "") - } - | None => (0, "", "") - } -} - -// JSON response helper -let jsonResponse = (data: Js.Json.t, ~status=200): Http.response => { - Http.makeJsonResponse( - Js.Json.stringify(data), - { - "status": status, - "headers": {"Content-Type": "application/json"}, - }, - ) -} - -// Validate GitHub signature if configured -let validateGitHubSignature = async ( - config: config, - headers: Js.Dict.t, - body: string, -): option => { - switch config.githubWebhookSecret { - | Some(secret) => - let signature = Js.Dict.get(headers, "x-hub-signature-256")->Belt.Option.getWithDefault("") - let valid = await Webhook.verifyGitHubSignature(body, signature, secret) - if !valid { - error("Invalid GitHub webhook signature") - Some(Http.makeResponse(`{"error": "Invalid signature"}`, {"status": 401})) - } else { - None - } - | None => None - } -} - -// Handle GitHub webhook -let handleGitHubWebhook = async ( - config: config, - headers: Js.Dict.t, - body: string, -): Http.response => { - // Verify signature if secret is configured - let signatureError = await validateGitHubSignature(config, headers, body) - switch signatureError { - | Some(errResponse) => errResponse - | None => - // Parse payload - let parseResult = try { - Some(Js.Json.parseExn(body)) - } catch { - | _ => None - } - - switch parseResult { - | None => Http.makeResponse(`{"error": "Invalid JSON"}`, {"status": 400}) - | Some(payload) => - let event = Webhook.parseGitHubEvent(headers, payload) - switch event { - | Some(e) => - info( - `GitHub event: ${e.eventType}`, - ~data=Js.Json.object_( - Js.Dict.fromArray([ - ("repo", Js.Json.string(`${e.repository.owner}/${e.repository.name}`)), - ("action", Js.Json.string(e.action->Belt.Option.getWithDefault(""))), - ]), - ), - ) - - // Handle pull request events - if e.eventType == "pull_request" { - let action = e.action->Belt.Option.getWithDefault("") - if action == "opened" || action == "synchronize" { - // Extract PR info from payload - let (prNumber, baseSha, headSha) = extractPRInfo(payload) - - // Call real analyzer - let analysisResult = await Analysis.analyzeDiff( - config.analysisEndpoint, - e.repository.url, - baseSha, - headSha, - ) - - let comment = switch analysisResult { - | Ok(analysis) => - Report.generatePRComment(analysis, config.mode) - | Error(err) => - error(`Analysis failed: ${err}`) - let analysis = Analysis.mockAnalysis() - Report.generatePRComment(analysis, config.mode) - } - - // Post comment to GitHub if authenticated - let authResult = await GitHubApp.getAuthToken(config, payload) - switch authResult { - | Ok(token) => - let postResult = await GitHubAPI.postPRComment( - token, - e.repository.owner, - e.repository.name, - prNumber, - comment, - ) - switch postResult { - | Ok(commentId) => - info( - `Posted PR comment`, - ~data=Js.Json.object_( - Js.Dict.fromArray([ - ("pr", Js.Json.number(Belt.Int.toFloat(prNumber))), - ("commentId", Js.Json.number(Belt.Int.toFloat(commentId))), - ]), - ), - ) - | Error(err) => - error(`Failed to post PR comment: ${err}`) - } - | Error(err) => - // Not configured for GitHub App - log comment instead - info( - `GitHub App not configured, comment not posted: ${err}`, - ~data=Js.Json.string(comment), - ) - } - } - } - - jsonResponse(Js.Json.object_(Js.Dict.fromArray([("status", Js.Json.string("processed"))]))) - | None => - error("Failed to parse GitHub event") - Http.makeResponse(`{"error": "Invalid event"}`, {"status": 400}) - } - } - } -} - -// Validate GitLab token if configured -let validateGitLabToken = ( - config: config, - headers: Js.Dict.t, -): option => { - switch config.gitlabWebhookSecret { - | Some(secret) => - let token = Js.Dict.get(headers, "x-gitlab-token")->Belt.Option.getWithDefault("") - if !Webhook.verifyGitLabToken(token, secret) { - error("Invalid GitLab webhook token") - Some(Http.makeResponse(`{"error": "Invalid token"}`, {"status": 401})) - } else { - None - } - | None => None - } -} - -// Handle GitLab webhook -let handleGitLabWebhook = async ( - config: config, - headers: Js.Dict.t, - body: string, -): Http.response => { - // Verify token if secret is configured - let tokenError = validateGitLabToken(config, headers) - switch tokenError { - | Some(errResponse) => errResponse - | None => - // Parse payload - let parseResult = try { - Some(Js.Json.parseExn(body)) - } catch { - | _ => None - } - - switch parseResult { - | None => Http.makeResponse(`{"error": "Invalid JSON"}`, {"status": 400}) - | Some(payload) => - let event = Webhook.parseGitLabEvent(headers, payload) - switch event { - | Some(e) => - info( - `GitLab event: ${e.eventType}`, - ~data=Js.Json.object_( - Js.Dict.fromArray([("repo", Js.Json.string(`${e.repository.owner}/${e.repository.name}`))]), - ), - ) - - // Handle merge request events - if e.eventType == "Merge Request Hook" { - let (mrIid, baseSha, headSha) = extractMRInfo(payload) - - let analysisResult = await Analysis.analyzeDiff( - config.analysisEndpoint, - e.repository.url, - baseSha, - headSha, - ) - - switch analysisResult { - | Ok(analysis) => - let comment = Report.generatePRComment(analysis, config.mode) - info(`Generated MR comment for MR !${Belt.Int.toString(mrIid)}`, ~data=Js.Json.string(comment)) - | Error(err) => - error(`Analysis failed: ${err}`) - let analysis = Analysis.mockAnalysis() - let comment = Report.generatePRComment(analysis, config.mode) - info(`Generated fallback MR comment`, ~data=Js.Json.string(comment)) - } - } - - jsonResponse(Js.Json.object_(Js.Dict.fromArray([("status", Js.Json.string("processed"))]))) - | None => - error("Failed to parse GitLab event") - Http.makeResponse(`{"error": "Invalid event"}`, {"status": 400}) - } - } - } -} - -// Main request handler -let handler = (config: config): Http.handler => { - async (req, _connInfo) => { - let url = Http.url(req) - let method = Http.method_(req) - let path = Js.String2.replaceByRe(url, %re("/^https?:\/\/[^\/]+/"), "") - - // Route requests - switch (method, path) { - | ("GET", "/health") => - jsonResponse( - Js.Json.object_( - Js.Dict.fromArray([ - ("status", Js.Json.string("healthy")), - ("mode", Js.Json.string(Config.modeToString(config.mode))), - ]), - ), - ) - - | ("POST", "/webhooks/github") => - let body = await Http.text(req) - let headers = Http.headers(req) - await handleGitHubWebhook(config, headers, body) - - | ("POST", "/webhooks/gitlab") => - let body = await Http.text(req) - let headers = Http.headers(req) - await handleGitLabWebhook(config, headers, body) - - | ("GET", "/metrics") => - // OpenTelemetry metrics endpoint - jsonResponse( - Js.Json.object_( - Js.Dict.fromArray([ - ("oikos_bot_requests_total", Js.Json.number(0.0)), - ("oikos_bot_analyses_total", Js.Json.number(0.0)), - ]), - ), - ) - - | _ => Http.makeResponse("Not Found", {"status": 404}) - } - } -} - -// Main entry point -let main = () => { - switch Config.load() { - | Ok(config) => - info( - `Starting Oikos Bot`, - ~data=Js.Json.object_( - Js.Dict.fromArray([ - ("port", Js.Json.number(Belt.Int.toFloat(config.port))), - ("mode", Js.Json.string(Config.modeToString(config.mode))), - ]), - ), - ) - - Http.serve( - { - port: config.port, - onListen: ({hostname, port}) => { - info(`Server listening on ${hostname}:${Belt.Int.toString(port)}`) - }, - }, - handler(config), - ) - - | Error(e) => - error(`Failed to load config: ${e}`) - } -} - -// Run -main() diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Main.res.js b/bots/sustainabot/bot-integration/lib/bs/src/Main.res.js deleted file mode 100644 index 3049a4a..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/src/Main.res.js +++ /dev/null @@ -1,451 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE - -import * as Config from "./Config.res.js"; -import * as Report from "./Report.res.js"; -import * as Js_dict from "@rescript/runtime/lib/es6/Js_dict.js"; -import * as Js_json from "@rescript/runtime/lib/es6/Js_json.js"; -import * as Webhook from "./Webhook.res.js"; -import * as Analysis from "./Analysis.res.js"; -import * as GitHubAPI from "./GitHubAPI.res.js"; -import * as GitHubApp from "./GitHubApp.res.js"; -import * as Belt_Option from "@rescript/runtime/lib/es6/Belt_Option.js"; -import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js"; - -function log(level, msg, data) { - let timestamp = new Date().toISOString(); - let logObj = data !== undefined ? Js_dict.fromArray([ - [ - "timestamp", - timestamp - ], - [ - "level", - level - ], - [ - "message", - msg - ], - [ - "data", - data - ] - ]) : Js_dict.fromArray([ - [ - "timestamp", - timestamp - ], - [ - "level", - level - ], - [ - "message", - msg - ] - ]); - console.log(JSON.stringify(logObj)); -} - -function info(msg, data) { - log("info", msg, data); -} - -function error(msg, data) { - log("error", msg, data); -} - -function extractPRInfo(payload) { - let obj = Js_json.decodeObject(payload); - if (obj === undefined) { - return [ - 0, - "", - "" - ]; - } - let n = Js_dict.get(obj, "number"); - let prNumber; - if (n !== undefined) { - let num = Js_json.decodeNumber(n); - prNumber = num !== undefined ? num | 0 : 0; - } else { - prNumber = 0; - } - let pr = Js_dict.get(obj, "pull_request"); - let match; - if (pr !== undefined) { - let prObj = Js_json.decodeObject(pr); - if (prObj !== undefined) { - let b = Js_dict.get(prObj, "base"); - let base; - if (b !== undefined) { - let baseObj = Js_json.decodeObject(b); - if (baseObj !== undefined) { - let s = Js_dict.get(baseObj, "sha"); - base = s !== undefined ? Belt_Option.getWithDefault(Js_json.decodeString(s), "") : ""; - } else { - base = ""; - } - } else { - base = ""; - } - let h = Js_dict.get(prObj, "head"); - let head; - if (h !== undefined) { - let headObj = Js_json.decodeObject(h); - if (headObj !== undefined) { - let s$1 = Js_dict.get(headObj, "sha"); - head = s$1 !== undefined ? Belt_Option.getWithDefault(Js_json.decodeString(s$1), "") : ""; - } else { - head = ""; - } - } else { - head = ""; - } - match = [ - base, - head - ]; - } else { - match = [ - "", - "" - ]; - } - } else { - match = [ - "", - "" - ]; - } - return [ - prNumber, - match[0], - match[1] - ]; -} - -function extractMRInfo(payload) { - let obj = Js_json.decodeObject(payload); - if (obj === undefined) { - return [ - 0, - "", - "" - ]; - } - let attrs = Js_dict.get(obj, "object_attributes"); - if (attrs === undefined) { - return [ - 0, - "", - "" - ]; - } - let attrsObj = Js_json.decodeObject(attrs); - if (attrsObj === undefined) { - return [ - 0, - "", - "" - ]; - } - let n = Js_dict.get(attrsObj, "iid"); - let mrIid; - if (n !== undefined) { - let num = Js_json.decodeNumber(n); - mrIid = num !== undefined ? num | 0 : 0; - } else { - mrIid = 0; - } - let refs = Js_dict.get(attrsObj, "diff_refs"); - let baseSha; - if (refs !== undefined) { - let refsObj = Js_json.decodeObject(refs); - if (refsObj !== undefined) { - let s = Js_dict.get(refsObj, "base_sha"); - baseSha = s !== undefined ? Belt_Option.getWithDefault(Js_json.decodeString(s), "") : ""; - } else { - baseSha = ""; - } - } else { - baseSha = ""; - } - let commit = Js_dict.get(attrsObj, "last_commit"); - let headSha; - if (commit !== undefined) { - let commitObj = Js_json.decodeObject(commit); - if (commitObj !== undefined) { - let s$1 = Js_dict.get(commitObj, "id"); - headSha = s$1 !== undefined ? Belt_Option.getWithDefault(Js_json.decodeString(s$1), "") : ""; - } else { - headSha = ""; - } - } else { - headSha = ""; - } - return [ - mrIid, - baseSha, - headSha - ]; -} - -function jsonResponse(data, statusOpt) { - let status = statusOpt !== undefined ? statusOpt : 200; - return new (globalThis.Response)(JSON.stringify(data), { - status: status, - headers: { - "Content-Type": "application/json" - } - }); -} - -async function validateGitHubSignature(config, headers, body) { - let secret = config.githubWebhookSecret; - if (secret === undefined) { - return; - } - let signature = Belt_Option.getWithDefault(Js_dict.get(headers, "x-hub-signature-256"), ""); - let valid = await Webhook.verifyGitHubSignature(body, signature, secret); - if (!valid) { - log("error", "Invalid GitHub webhook signature", undefined); - return Primitive_option.some(new (globalThis.Response)(`{"error": "Invalid signature"}`, { - status: 401 - })); - } -} - -async function handleGitHubWebhook(config, headers, body) { - let signatureError = await validateGitHubSignature(config, headers, body); - if (signatureError !== undefined) { - return Primitive_option.valFromOption(signatureError); - } - let parseResult; - try { - parseResult = JSON.parse(body); - } catch (exn) { - parseResult = undefined; - } - if (parseResult === undefined) { - return new (globalThis.Response)(`{"error": "Invalid JSON"}`, { - status: 400 - }); - } - let event = Webhook.parseGitHubEvent(headers, parseResult); - if (event !== undefined) { - log("info", `GitHub event: ` + event.eventType, Js_dict.fromArray([ - [ - "repo", - event.repository.owner + `/` + event.repository.name - ], - [ - "action", - Belt_Option.getWithDefault(event.action, "") - ] - ])); - if (event.eventType === "pull_request") { - let action = Belt_Option.getWithDefault(event.action, ""); - if (action === "opened" || action === "synchronize") { - let match = extractPRInfo(parseResult); - let prNumber = match[0]; - let analysisResult = await Analysis.analyzeDiff(config.analysisEndpoint, event.repository.url, match[1], match[2]); - let comment; - if (analysisResult.TAG === "Ok") { - comment = Report.generatePRComment(analysisResult._0, config.mode); - } else { - log("error", `Analysis failed: ` + analysisResult._0, undefined); - let analysis = Analysis.mockAnalysis(); - comment = Report.generatePRComment(analysis, config.mode); - } - let authResult = await GitHubApp.getAuthToken(config, parseResult); - if (authResult.TAG === "Ok") { - let postResult = await GitHubAPI.postPRComment(authResult._0, event.repository.owner, event.repository.name, prNumber, comment); - if (postResult.TAG === "Ok") { - log("info", `Posted PR comment`, Js_dict.fromArray([ - [ - "pr", - prNumber - ], - [ - "commentId", - postResult._0 - ] - ])); - } else { - log("error", `Failed to post PR comment: ` + postResult._0, undefined); - } - } else { - log("info", `GitHub App not configured, comment not posted: ` + authResult._0, comment); - } - } - } - return jsonResponse(Js_dict.fromArray([[ - "status", - "processed" - ]]), undefined); - } - log("error", "Failed to parse GitHub event", undefined); - return new (globalThis.Response)(`{"error": "Invalid event"}`, { - status: 400 - }); -} - -function validateGitLabToken(config, headers) { - let secret = config.gitlabWebhookSecret; - if (secret === undefined) { - return; - } - let token = Belt_Option.getWithDefault(Js_dict.get(headers, "x-gitlab-token"), ""); - if (!Webhook.verifyGitLabToken(token, secret)) { - log("error", "Invalid GitLab webhook token", undefined); - return Primitive_option.some(new (globalThis.Response)(`{"error": "Invalid token"}`, { - status: 401 - })); - } -} - -async function handleGitLabWebhook(config, headers, body) { - let tokenError = validateGitLabToken(config, headers); - if (tokenError !== undefined) { - return Primitive_option.valFromOption(tokenError); - } - let parseResult; - try { - parseResult = JSON.parse(body); - } catch (exn) { - parseResult = undefined; - } - if (parseResult === undefined) { - return new (globalThis.Response)(`{"error": "Invalid JSON"}`, { - status: 400 - }); - } - let event = Webhook.parseGitLabEvent(headers, parseResult); - if (event !== undefined) { - log("info", `GitLab event: ` + event.eventType, Js_dict.fromArray([[ - "repo", - event.repository.owner + `/` + event.repository.name - ]])); - if (event.eventType === "Merge Request Hook") { - let match = extractMRInfo(parseResult); - let analysisResult = await Analysis.analyzeDiff(config.analysisEndpoint, event.repository.url, match[1], match[2]); - if (analysisResult.TAG === "Ok") { - let comment = Report.generatePRComment(analysisResult._0, config.mode); - log("info", `Generated MR comment for MR !` + String(match[0]), comment); - } else { - log("error", `Analysis failed: ` + analysisResult._0, undefined); - let analysis = Analysis.mockAnalysis(); - let comment$1 = Report.generatePRComment(analysis, config.mode); - log("info", `Generated fallback MR comment`, comment$1); - } - } - return jsonResponse(Js_dict.fromArray([[ - "status", - "processed" - ]]), undefined); - } - log("error", "Failed to parse GitLab event", undefined); - return new (globalThis.Response)(`{"error": "Invalid event"}`, { - status: 400 - }); -} - -function handler(config) { - return async (req, _connInfo) => { - let url = req.url; - let method = req.method; - let path = url.replace(/^https?:\/\/[^\/]+/, ""); - switch (method) { - case "GET" : - switch (path) { - case "/health" : - return jsonResponse(Js_dict.fromArray([ - [ - "status", - "healthy" - ], - [ - "mode", - Config.modeToString(config.mode) - ] - ]), undefined); - case "/metrics" : - return jsonResponse(Js_dict.fromArray([ - [ - "oikos_bot_requests_total", - 0.0 - ], - [ - "oikos_bot_analyses_total", - 0.0 - ] - ]), undefined); - default: - return new (globalThis.Response)("Not Found", { - status: 404 - }); - } - case "POST" : - switch (path) { - case "/webhooks/github" : - let body = await req.text(); - let headers = req.headers; - return await handleGitHubWebhook(config, headers, body); - case "/webhooks/gitlab" : - let body$1 = await req.text(); - let headers$1 = req.headers; - return await handleGitLabWebhook(config, headers$1, body$1); - default: - return new (globalThis.Response)("Not Found", { - status: 404 - }); - } - default: - return new (globalThis.Response)("Not Found", { - status: 404 - }); - } - }; -} - -function main() { - let config = Config.load(); - if (config.TAG !== "Ok") { - return log("error", `Failed to load config: ` + config._0, undefined); - } - let config$1 = config._0; - log("info", `Starting Oikos Bot`, Js_dict.fromArray([ - [ - "port", - config$1.port - ], - [ - "mode", - Config.modeToString(config$1.mode) - ] - ])); - Deno.serve({ - port: config$1.port, - onListen: param => log("info", `Server listening on ` + param.hostname + `:` + String(param.port), undefined) - }, handler(config$1)); -} - -main(); - -export { - log, - info, - error, - extractPRInfo, - extractMRInfo, - jsonResponse, - validateGitHubSignature, - handleGitHubWebhook, - validateGitLabToken, - handleGitLabWebhook, - handler, - main, -} -/* Not a pure module */ diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Oikos.ast b/bots/sustainabot/bot-integration/lib/bs/src/Oikos.ast deleted file mode 100644 index b458ed73f23996ca073266bf3634f108ebc730fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25411 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 Zed^lp?qBcwQGV|=+GaVxHp~8O{{d8E=R*Jh diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Oikos.cmj b/bots/sustainabot/bot-integration/lib/bs/src/Oikos.cmj deleted file mode 100644 index f1d2252d06c58e6a180c1c513984b7ed555e49af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 153 zcmcBy`|oCCKV?aWfqiV=I0f|6zS#Wr=+?S<>v;M6lLb6Lxmj{ hOwi2F%+4>?P0BA>u)$HexF}g&uPC)xFRR$W0RW2`Jk9_B diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Oikos.cmt b/bots/sustainabot/bot-integration/lib/bs/src/Oikos.cmt deleted file mode 100644 index b74169233a877a79ef8f3539da2ce35c7eaf8888..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 64033 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, - appId: option, - privateKeyPath: option, - pendingAnalyses: array, - totalProcessed: int, - startTime: float, - healthy: bool, -} - -// ============================================================================= -// MESSAGES -// ============================================================================= - -type msg = - // Webhook events - | WebhookReceived(webhookSource, Js.Json.t) - | WebhookVerified(webhookSource, Js.Json.t) - | WebhookRejected(string) - // Analysis lifecycle - | AnalysisRequested(string, string, int) // id, repo, prNumber - | AnalysisStarted(string) - | AnalysisCompleted(string, Types.analysisResult) - | AnalysisFailed(string, string) - // GitHub API responses - | CommentPosted(string, int) - | CommentFailed(string, string) - // System - | HealthCheck - | Tick - | Shutdown - -// ============================================================================= -// INIT -// ============================================================================= - -type flags = { - port: int, - mode: string, - webhookSecret: option, - appId: option, - privateKeyPath: option, -} - -let modeFromString = str => - switch str { - | "consultant" => Consultant - | "regulator" => Regulator - | _ => Advisor - } - -let init = (flags: flags) => { - let model = { - mode: modeFromString(flags.mode), - port: flags.port, - webhookSecret: flags.webhookSecret, - appId: flags.appId, - privateKeyPath: flags.privateKeyPath, - pendingAnalyses: [], - totalProcessed: 0, - startTime: Js.Date.now(), - healthy: true, - } - - Js.Console.log(`🏛️ Oikos Bot starting...`) - Js.Console.log(` Mode: ${flags.mode}`) - Js.Console.log(` Port: ${flags.port->Belt.Int.toString}`) - - (model, Cmd.none) -} - -// ============================================================================= -// UPDATE -// ============================================================================= - -let update = (msg: msg, model: model) => { - switch msg { - | WebhookReceived(source, payload) => { - let sourceStr = switch source { - | GitHub => "GitHub" - | GitLab => "GitLab" - } - Js.Console.log(`📨 Webhook received from ${sourceStr}`) - // TODO: Verify signature then dispatch WebhookVerified - (model, Cmd.perform(async () => payload, p => WebhookVerified(source, p))) - } - - | WebhookVerified(source, payload) => { - Js.Console.log(`✓ Webhook verified`) - // Parse the webhook and determine action - let _ = source - let _ = payload - // TODO: Parse event type, extract PR info, start analysis - ({...model, totalProcessed: model.totalProcessed + 1}, Cmd.none) - } - - | WebhookRejected(reason) => { - Js.Console.error(`✗ Webhook rejected: ${reason}`) - (model, Cmd.none) - } - - | AnalysisRequested(id, repo, prNumber) => { - Js.Console.log(`🔍 Analysis requested: ${repo}#${prNumber->Belt.Int.toString}`) - let analysis = { - id, - repo, - prNumber, - status: Pending, - createdAt: Js.Date.now(), - } - ( - {...model, pendingAnalyses: model.pendingAnalyses->Js.Array2.concat([analysis])}, - Cmd.none, - ) - } - - | AnalysisStarted(id) => { - let pendingAnalyses = - model.pendingAnalyses->Js.Array2.map(a => - if a.id == id { - {...a, status: InProgress} - } else { - a - } - ) - ({...model, pendingAnalyses}, Cmd.none) - } - - | AnalysisCompleted(id, result) => { - Js.Console.log(`✓ Analysis completed: ${id}`) - let pendingAnalyses = - model.pendingAnalyses->Js.Array2.map(a => - if a.id == id { - {...a, status: Completed(result)} - } else { - a - } - ) - ({...model, pendingAnalyses}, Cmd.none) - } - - | AnalysisFailed(id, error) => { - Js.Console.error(`✗ Analysis failed: ${id} - ${error}`) - let pendingAnalyses = - model.pendingAnalyses->Js.Array2.map(a => - if a.id == id { - {...a, status: Failed(error)} - } else { - a - } - ) - ({...model, pendingAnalyses}, Cmd.none) - } - - | CommentPosted(repo, prNumber) => { - Js.Console.log(`💬 Comment posted to ${repo}#${prNumber->Belt.Int.toString}`) - (model, Cmd.none) - } - - | CommentFailed(repo, error) => { - Js.Console.error(`✗ Failed to post comment to ${repo}: ${error}`) - (model, Cmd.none) - } - - | HealthCheck => { - Js.Console.log(`💚 Health check - processed: ${model.totalProcessed->Belt.Int.toString}`) - (model, Cmd.none) - } - - | Tick => { - // Periodic cleanup of old analyses - let now = Js.Date.now() - let oneHour = 60.0 *. 60.0 *. 1000.0 - let pendingAnalyses = - model.pendingAnalyses->Js.Array2.filter(a => now -. a.createdAt < oneHour) - ({...model, pendingAnalyses}, Cmd.none) - } - - | Shutdown => { - Js.Console.log(`👋 Shutting down...`) - ({...model, healthy: false}, Cmd.none) - } - } -} - -// ============================================================================= -// SUBSCRIPTIONS -// ============================================================================= - -let subscriptions = (model: model) => { - if model.healthy { - Sub.batch([ - Sub.httpServer(model.port, json => Some(WebhookReceived(GitHub, json))), - Sub.every(60000, () => Tick), - ]) - } else { - Sub.none - } -} - -// ============================================================================= -// RUN -// ============================================================================= - -let run = () => { - let port = switch Deno.Env.get("PORT") { - | Some(p) => Belt.Int.fromString(p)->Belt.Option.getWithDefault(3000) - | None => 3000 - } - let mode = Deno.Env.get("BOT_MODE")->Belt.Option.getWithDefault("advisor") - let webhookSecret = Deno.Env.get("GITHUB_WEBHOOK_SECRET") - let appId = Deno.Env.get("GITHUB_APP_ID") - let privateKeyPath = Deno.Env.get("GITHUB_PRIVATE_KEY_PATH") - - let flags = { - port, - mode, - webhookSecret, - appId, - privateKeyPath, - } - - Runtime.make(~init, ~update, ~subscriptions, ~flags) -} - -// Auto-run when imported as main module -let _ = run() diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Oikos.res.js b/bots/sustainabot/bot-integration/lib/bs/src/Oikos.res.js deleted file mode 100644 index 1904207..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/src/Oikos.res.js +++ /dev/null @@ -1,309 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE - -import * as Belt_Int from "@rescript/runtime/lib/es6/Belt_Int.js"; -import * as ServerTea from "./tea/ServerTea.res.js"; -import * as Belt_Option from "@rescript/runtime/lib/es6/Belt_Option.js"; - -function modeFromString(str) { - switch (str) { - case "consultant" : - return "Consultant"; - case "regulator" : - return "Regulator"; - default: - return "Advisor"; - } -} - -function init(flags) { - let model_mode = modeFromString(flags.mode); - let model_port = flags.port; - let model_webhookSecret = flags.webhookSecret; - let model_appId = flags.appId; - let model_privateKeyPath = flags.privateKeyPath; - let model_pendingAnalyses = []; - let model_startTime = Date.now(); - let model = { - mode: model_mode, - port: model_port, - webhookSecret: model_webhookSecret, - appId: model_appId, - privateKeyPath: model_privateKeyPath, - pendingAnalyses: model_pendingAnalyses, - totalProcessed: 0, - startTime: model_startTime, - healthy: true - }; - console.log(`🏛️ Oikos Bot starting...`); - console.log(` Mode: ` + flags.mode); - console.log(` Port: ` + String(flags.port)); - return [ - model, - ServerTea.Cmd.none - ]; -} - -function update(msg, model) { - if (typeof msg !== "object") { - switch (msg) { - case "HealthCheck" : - console.log(`💚 Health check - processed: ` + String(model.totalProcessed)); - return [ - model, - ServerTea.Cmd.none - ]; - case "Tick" : - let now = Date.now(); - let oneHour = 60.0 * 60.0 * 1000.0; - let pendingAnalyses = model.pendingAnalyses.filter(a => now - a.createdAt < oneHour); - return [ - { - mode: model.mode, - port: model.port, - webhookSecret: model.webhookSecret, - appId: model.appId, - privateKeyPath: model.privateKeyPath, - pendingAnalyses: pendingAnalyses, - totalProcessed: model.totalProcessed, - startTime: model.startTime, - healthy: model.healthy - }, - ServerTea.Cmd.none - ]; - case "Shutdown" : - console.log(`👋 Shutting down...`); - return [ - { - mode: model.mode, - port: model.port, - webhookSecret: model.webhookSecret, - appId: model.appId, - privateKeyPath: model.privateKeyPath, - pendingAnalyses: model.pendingAnalyses, - totalProcessed: model.totalProcessed, - startTime: model.startTime, - healthy: false - }, - ServerTea.Cmd.none - ]; - } - } else { - switch (msg.TAG) { - case "WebhookReceived" : - let payload = msg._1; - let source = msg._0; - let sourceStr; - sourceStr = source === "GitHub" ? "GitHub" : "GitLab"; - console.log(`📨 Webhook received from ` + sourceStr); - return [ - model, - ServerTea.Cmd.perform(async () => payload, p => ({ - TAG: "WebhookVerified", - _0: source, - _1: p - })) - ]; - case "WebhookVerified" : - console.log(`✓ Webhook verified`); - return [ - { - mode: model.mode, - port: model.port, - webhookSecret: model.webhookSecret, - appId: model.appId, - privateKeyPath: model.privateKeyPath, - pendingAnalyses: model.pendingAnalyses, - totalProcessed: model.totalProcessed + 1 | 0, - startTime: model.startTime, - healthy: model.healthy - }, - ServerTea.Cmd.none - ]; - case "WebhookRejected" : - console.error(`✗ Webhook rejected: ` + msg._0); - return [ - model, - ServerTea.Cmd.none - ]; - case "AnalysisRequested" : - let prNumber = msg._2; - let repo = msg._1; - console.log(`🔍 Analysis requested: ` + repo + `#` + String(prNumber)); - let analysis_id = msg._0; - let analysis_createdAt = Date.now(); - let analysis = { - id: analysis_id, - repo: repo, - prNumber: prNumber, - status: "Pending", - createdAt: analysis_createdAt - }; - return [ - { - mode: model.mode, - port: model.port, - webhookSecret: model.webhookSecret, - appId: model.appId, - privateKeyPath: model.privateKeyPath, - pendingAnalyses: model.pendingAnalyses.concat([analysis]), - totalProcessed: model.totalProcessed, - startTime: model.startTime, - healthy: model.healthy - }, - ServerTea.Cmd.none - ]; - case "AnalysisStarted" : - let id = msg._0; - let pendingAnalyses$1 = model.pendingAnalyses.map(a => { - if (a.id === id) { - return { - id: a.id, - repo: a.repo, - prNumber: a.prNumber, - status: "InProgress", - createdAt: a.createdAt - }; - } else { - return a; - } - }); - return [ - { - mode: model.mode, - port: model.port, - webhookSecret: model.webhookSecret, - appId: model.appId, - privateKeyPath: model.privateKeyPath, - pendingAnalyses: pendingAnalyses$1, - totalProcessed: model.totalProcessed, - startTime: model.startTime, - healthy: model.healthy - }, - ServerTea.Cmd.none - ]; - case "AnalysisCompleted" : - let result = msg._1; - let id$1 = msg._0; - console.log(`✓ Analysis completed: ` + id$1); - let pendingAnalyses$2 = model.pendingAnalyses.map(a => { - if (a.id === id$1) { - return { - id: a.id, - repo: a.repo, - prNumber: a.prNumber, - status: { - TAG: "Completed", - _0: result - }, - createdAt: a.createdAt - }; - } else { - return a; - } - }); - return [ - { - mode: model.mode, - port: model.port, - webhookSecret: model.webhookSecret, - appId: model.appId, - privateKeyPath: model.privateKeyPath, - pendingAnalyses: pendingAnalyses$2, - totalProcessed: model.totalProcessed, - startTime: model.startTime, - healthy: model.healthy - }, - ServerTea.Cmd.none - ]; - case "AnalysisFailed" : - let error = msg._1; - let id$2 = msg._0; - console.error(`✗ Analysis failed: ` + id$2 + ` - ` + error); - let pendingAnalyses$3 = model.pendingAnalyses.map(a => { - if (a.id === id$2) { - return { - id: a.id, - repo: a.repo, - prNumber: a.prNumber, - status: { - TAG: "Failed", - _0: error - }, - createdAt: a.createdAt - }; - } else { - return a; - } - }); - return [ - { - mode: model.mode, - port: model.port, - webhookSecret: model.webhookSecret, - appId: model.appId, - privateKeyPath: model.privateKeyPath, - pendingAnalyses: pendingAnalyses$3, - totalProcessed: model.totalProcessed, - startTime: model.startTime, - healthy: model.healthy - }, - ServerTea.Cmd.none - ]; - case "CommentPosted" : - console.log(`💬 Comment posted to ` + msg._0 + `#` + String(msg._1)); - return [ - model, - ServerTea.Cmd.none - ]; - case "CommentFailed" : - console.error(`✗ Failed to post comment to ` + msg._0 + `: ` + msg._1); - return [ - model, - ServerTea.Cmd.none - ]; - } - } -} - -function subscriptions(model) { - if (model.healthy) { - return ServerTea.Sub.batch([ - ServerTea.Sub.httpServer(model.port, json => ({ - TAG: "WebhookReceived", - _0: "GitHub", - _1: json - })), - ServerTea.Sub.every(60000, () => "Tick") - ]); - } else { - return ServerTea.Sub.none; - } -} - -function run() { - let p = Deno.env.get("PORT"); - let port = p !== undefined ? Belt_Option.getWithDefault(Belt_Int.fromString(p), 3000) : 3000; - let mode = Belt_Option.getWithDefault(Deno.env.get("BOT_MODE"), "advisor"); - let webhookSecret = Deno.env.get("GITHUB_WEBHOOK_SECRET"); - let appId = Deno.env.get("GITHUB_APP_ID"); - let privateKeyPath = Deno.env.get("GITHUB_PRIVATE_KEY_PATH"); - let flags = { - port: port, - mode: mode, - webhookSecret: webhookSecret, - appId: appId, - privateKeyPath: privateKeyPath - }; - return ServerTea.Runtime.make(init, update, subscriptions, flags); -} - -run(); - -export { - modeFromString, - init, - update, - subscriptions, - run, -} -/* Not a pure module */ diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Report.ast b/bots/sustainabot/bot-integration/lib/bs/src/Report.ast deleted file mode 100644 index edf6f04e971a2c2fd5c1828203ab993f0768782b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24447 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 diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Report.cmi b/bots/sustainabot/bot-integration/lib/bs/src/Report.cmi deleted file mode 100644 index 9b3d9d19d91efad49c8f47b17dd798abf17c7612..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2076 zcmZ`)2~ZPP7|zCEwO&J2umVLy5ah@cj}CZkK+sS*B%*j=+>i|uNOo~|NeMcwcU1(R zcNLLW54;&DDrh>o>d~pu{W8$Ov>MM+rujQSw}d(yk_)qxo1_jBJ9akW1GjlKdd>ldyJy zv1T^Q=v1lb?UeT#%TstdZ{Ij&wPIO{z8ZpXCy2hH!o$8B=*ZkV9B0-Dl#t8+Cv})J zSF@Bl#ChA|O#Mnq9h^=ORRmEjDu&p1wT{$%08d+J&L~)?uo`>U9Nn#i6=c8^YYxq; zg4!{%_fCT65?_q-_Jx!0rNpPoB;*qb`6N*hZQspu@bw*}W!FrG{TtEW2zpGaEfIJGp94mUg{VYGeh&m>W^ z=MwT3Lf$GWv>$ezx;sR9;K|uVX;dldIG3Oi|1ao4MOCHLqJi#dC1lHpo&`kD)uJN5eZQ3?NxSV8P1yElu;s7eH5s-09)jktzGS)%H}E zvk_7{awKtjY#JsLg0PlOS3W!7oquPZPY%~~yWWLK%r%)Poe66pt1BB!$Ju)tYSEUd zd56PXS|tnw#|NxV*KX)sSThdR>8YN5T=7X%z7>LO;~26?(1m1oW0>;hBhL{Eb?Aua zWAhjY4(t~bK_d`TFR$ISzTRgfLg6j|$FUp)aDe*N_u2b4w3G^amA2QXT^#Y6q(lg= z-LIM!Vu@H(=rvrd+TC)^Rfk%T{3_)*dGlyiqgSMMVp>}l-&GHOb#-iliPcfKk_B_T z22YNe6II#cSns9Dhh#36@!0YZx`a@KL#T@5C~I`C!9Zi8 z3)dUgq`m&uR}N13hb|r0>MHmH41$AvO;MKSXwNSFQho9tmz=o=GGj1WlXjAo-?w9r~MM>@@mGDLx5n`T+5gp-bH18joUAkMEy3+uDHFPt%ZuT;7`W@cOFJs=r4s+=I}d z@ifCiFjha}iA{Tct>?$8>Q@_o=#R}3!!iaVetUPL+}5Z)3jK=k6dxH;orZfJO`8O* zn!)PIC(H;4%!@cY*!RbIuz2xeJkSrpIO&@ULCdc7qxktjJ>qJ8ZDQS2x;^Z$=-h?{ xH@!=A!{@KdvK?C$>W<|||AruL(?wsdZQ;I#k>%#Q^iO*oXP}J0XQ1;({tK>_Wy$~m diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Report.cmj b/bots/sustainabot/bot-integration/lib/bs/src/Report.cmj deleted file mode 100644 index 17a7cdffc60495f8abd1482e2cb5bbfee3988d01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 203 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 diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Report.res b/bots/sustainabot/bot-integration/lib/bs/src/Report.res deleted file mode 100644 index f0d564b..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/src/Report.res +++ /dev/null @@ -1,212 +0,0 @@ -// Report generation for PR comments and SARIF output - -open Types - -let getGrade = (score: float): string => { - if score >= 90.0 { - "A" - } else if score >= 80.0 { - "B" - } else if score >= 70.0 { - "C" - } else if score >= 60.0 { - "D" - } else { - "F" - } -} - -let getGradeEmoji = (grade: string): string => { - switch grade { - | "A" => "🏆" - | "B" => "✨" - | "C" => "👍" - | "D" => "⚠️" - | _ => "🚨" - } -} - -let getStatusEmoji = (score: float): string => { - if score >= 70.0 { - "✅" - } else if score >= 50.0 { - "⚠️" - } else { - "❌" - } -} - -let severityToString = (s: severity): string => { - switch s { - | Blocking => "blocking" - | High => "high" - | Medium => "medium" - | Low => "low" - | Info => "info" - } -} - -let generatePRComment = (analysis: analysisResult, mode: botMode): string => { - let grade = getGrade(analysis.health.total) - let gradeEmoji = getGradeEmoji(grade) - - let header = `## 🏛️ Oikos Analysis\n\n` - - let healthLine = `### Overall Health: ${gradeEmoji} ${grade} (${Belt.Float.toString( - analysis.health.total, - )}/100)\n\n` - - let scoreTable = - `| Metric | Score | Status |\n` ++ - `|--------|-------|--------|\n` ++ - `| 🌍 Ecological | ${Belt.Float.toString(analysis.eco.score)} | ${getStatusEmoji( - analysis.eco.score, - )} |\n` ++ - `| 📊 Economic | ${Belt.Float.toString(analysis.econ.score)} | ${getStatusEmoji( - analysis.econ.score, - )} |\n` ++ - `| ⚙️ Quality | ${Belt.Float.toString(analysis.quality.score)} | ${getStatusEmoji( - analysis.quality.score, - )} |\n\n` - - // Violations section - let violationsSection = if Belt.Array.length(analysis.violations) > 0 { - let violationLines = - analysis.violations - ->Belt.Array.map(v => { - let icon = v.severity == Blocking ? "🚫" : "⚠️" - `${icon} **${v.policy}**: ${v.message}\n` - }) - ->Belt.Array.joinWith("", s => s) - - `### ⚠️ Policy Violations\n\n${violationLines}\n` - } else { - "" - } - - // Recommendations section (limited by mode) - let recommendationsSection = if Belt.Array.length(analysis.recommendations) > 0 && mode != Regulator { - let maxRecs = mode == Consultant ? 10 : 5 - let topRecs = Belt.Array.slice(analysis.recommendations, ~offset=0, ~len=maxRecs) - - let recLines = - topRecs - ->Belt.Array.map(r => { - let confidence = Belt.Float.toInt(r.confidence *. 100.0) - `- **${r.action}** (${Belt.Int.toString(confidence)}% confidence): ${r.reason}\n` - }) - ->Belt.Array.joinWith("", s => s) - - `### 💡 Recommendations\n\n${recLines}\n` - } else { - "" - } - - // Pareto section - let paretoSection = switch analysis.econ.paretoStatus { - | Some(ps) => - let status = if ps.isOptimal { - `✅ This code is on the Pareto frontier - no dominated trade-offs detected.\n\n` - } else { - let improvements = switch ps.improvements { - | Some(imps) => - imps->Belt.Array.map(i => `- ${i}\n`)->Belt.Array.joinWith("", s => s) - | None => "" - } - `📍 Distance from Pareto frontier: ${Belt.Float.toString(ps.distance)}\n\n` ++ - (improvements != "" ? `Potential Pareto improvements:\n${improvements}\n` : "") - } - `### 📈 Pareto Analysis\n\n${status}` - | None => "" - } - - // Footer - let footer = - `---\n` ++ - `*Analyzed by [Oikos Bot](https://github.com/hyperpolymath/oikos-bot) | ` ++ - `Mode: ${Config.modeToString(mode)} | ` ++ - `[Learn more about eco-friendly coding](https://greensoftware.foundation/)*\n` - - header ++ healthLine ++ scoreTable ++ violationsSection ++ recommendationsSection ++ paretoSection ++ footer -} - -// Generate SARIF for code scanning integration -let generateSARIF = (analysis: analysisResult): Js.Json.t => { - let rules = [ - Js.Dict.fromArray([ - ("id", Js.Json.string("eco/eco-minimum")), - ("name", Js.Json.string("EcoMinimum")), - ( - "shortDescription", - Js.Json.object_( - Js.Dict.fromArray([("text", Js.Json.string("Eco minimum threshold not met"))]), - ), - ), - ]), - Js.Dict.fromArray([ - ("id", Js.Json.string("eco/eco-standard")), - ("name", Js.Json.string("EcoStandard")), - ( - "shortDescription", - Js.Json.object_( - Js.Dict.fromArray([("text", Js.Json.string("Eco standard threshold not met"))]), - ), - ), - ]), - ] - - let results = - analysis.violations->Belt.Array.map(v => { - Js.Dict.fromArray([ - ("ruleId", Js.Json.string(`eco/${Js.String.replace("_", "-", v.policy)}`)), - ("level", Js.Json.string(v.severity == Blocking ? "error" : "warning")), - ( - "message", - Js.Json.object_(Js.Dict.fromArray([("text", Js.Json.string(v.message))])), - ), - ]) - }) - - Js.Json.object_( - Js.Dict.fromArray([ - ( - "$schema", - Js.Json.string( - "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json", - ), - ), - ("version", Js.Json.string("2.1.0")), - ( - "runs", - Js.Json.array([ - Js.Json.object_( - Js.Dict.fromArray([ - ( - "tool", - Js.Json.object_( - Js.Dict.fromArray([ - ( - "driver", - Js.Json.object_( - Js.Dict.fromArray([ - ("name", Js.Json.string("oikos-bot")), - ("version", Js.Json.string("0.1.0-beta")), - ( - "informationUri", - Js.Json.string("https://github.com/hyperpolymath/oikos-bot"), - ), - ("rules", Js.Json.array(rules->Belt.Array.map(Js.Json.object_))), - ]), - ), - ), - ]), - ), - ), - ("results", Js.Json.array(results->Belt.Array.map(Js.Json.object_))), - ]), - ), - ]), - ), - ]), - ) -} diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Report.res.js b/bots/sustainabot/bot-integration/lib/bs/src/Report.res.js deleted file mode 100644 index 0af1e64..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/src/Report.res.js +++ /dev/null @@ -1,217 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE - -import * as Config from "./Config.res.js"; -import * as Js_dict from "@rescript/runtime/lib/es6/Js_dict.js"; -import * as Js_string from "@rescript/runtime/lib/es6/Js_string.js"; -import * as Belt_Array from "@rescript/runtime/lib/es6/Belt_Array.js"; - -function getGrade(score) { - if (score >= 90.0) { - return "A"; - } else if (score >= 80.0) { - return "B"; - } else if (score >= 70.0) { - return "C"; - } else if (score >= 60.0) { - return "D"; - } else { - return "F"; - } -} - -function getGradeEmoji(grade) { - switch (grade) { - case "A" : - return "🏆"; - case "B" : - return "✨"; - case "C" : - return "👍"; - case "D" : - return "⚠️"; - default: - return "🚨"; - } -} - -function getStatusEmoji(score) { - if (score >= 70.0) { - return "✅"; - } else if (score >= 50.0) { - return "⚠️"; - } else { - return "❌"; - } -} - -function severityToString(s) { - switch (s) { - case "Blocking" : - return "blocking"; - case "High" : - return "high"; - case "Medium" : - return "medium"; - case "Low" : - return "low"; - case "Info" : - return "info"; - } -} - -function generatePRComment(analysis, mode) { - let grade = getGrade(analysis.health.total); - let gradeEmoji = getGradeEmoji(grade); - let healthLine = `### Overall Health: ` + gradeEmoji + ` ` + grade + ` (` + String(analysis.health.total) + `/100)\n\n`; - let scoreTable = `| Metric | Score | Status |\n|--------|-------|--------|\n` + (`| 🌍 Ecological | ` + String(analysis.eco.score) + ` | ` + getStatusEmoji(analysis.eco.score) + ` |\n`) + (`| 📊 Economic | ` + String(analysis.econ.score) + ` | ` + getStatusEmoji(analysis.econ.score) + ` |\n`) + (`| ⚙️ Quality | ` + String(analysis.quality.score) + ` | ` + getStatusEmoji(analysis.quality.score) + ` |\n\n`); - let violationsSection; - if (analysis.violations.length !== 0) { - let violationLines = Belt_Array.joinWith(Belt_Array.map(analysis.violations, v => { - let icon = v.severity === "Blocking" ? "🚫" : "⚠️"; - return icon + ` **` + v.policy + `**: ` + v.message + `\n`; - }), "", s => s); - violationsSection = `### ⚠️ Policy Violations\n\n` + violationLines + `\n`; - } else { - violationsSection = ""; - } - let recommendationsSection; - if (analysis.recommendations.length !== 0 && mode !== "Regulator") { - let maxRecs = mode === "Consultant" ? 10 : 5; - let topRecs = Belt_Array.slice(analysis.recommendations, 0, maxRecs); - let recLines = Belt_Array.joinWith(Belt_Array.map(topRecs, r => { - let confidence = r.confidence * 100.0 | 0; - return `- **` + r.action + `** (` + String(confidence) + `% confidence): ` + r.reason + `\n`; - }), "", s => s); - recommendationsSection = `### 💡 Recommendations\n\n` + recLines + `\n`; - } else { - recommendationsSection = ""; - } - let ps = analysis.econ.paretoStatus; - let paretoSection; - if (ps !== undefined) { - let status; - if (ps.isOptimal) { - status = `✅ This code is on the Pareto frontier - no dominated trade-offs detected.\n\n`; - } else { - let imps = ps.improvements; - let improvements = imps !== undefined ? Belt_Array.joinWith(Belt_Array.map(imps, i => `- ` + i + `\n`), "", s => s) : ""; - status = `📍 Distance from Pareto frontier: ` + String(ps.distance) + `\n\n` + ( - improvements !== "" ? `Potential Pareto improvements:\n` + improvements + `\n` : "" - ); - } - paretoSection = `### 📈 Pareto Analysis\n\n` + status; - } else { - paretoSection = ""; - } - let footer = `---\n*Analyzed by [Oikos Bot](https://github.com/hyperpolymath/oikos-bot) | ` + (`Mode: ` + Config.modeToString(mode) + ` | `) + `[Learn more about eco-friendly coding](https://greensoftware.foundation/)*\n`; - return `## 🏛️ Oikos Analysis\n\n` + healthLine + scoreTable + violationsSection + recommendationsSection + paretoSection + footer; -} - -function generateSARIF(analysis) { - let rules = [ - Js_dict.fromArray([ - [ - "id", - "eco/eco-minimum" - ], - [ - "name", - "EcoMinimum" - ], - [ - "shortDescription", - Js_dict.fromArray([[ - "text", - "Eco minimum threshold not met" - ]]) - ] - ]), - Js_dict.fromArray([ - [ - "id", - "eco/eco-standard" - ], - [ - "name", - "EcoStandard" - ], - [ - "shortDescription", - Js_dict.fromArray([[ - "text", - "Eco standard threshold not met" - ]]) - ] - ]) - ]; - let results = Belt_Array.map(analysis.violations, v => Js_dict.fromArray([ - [ - "ruleId", - `eco/` + Js_string.replace("_", "-", v.policy) - ], - [ - "level", - v.severity === "Blocking" ? "error" : "warning" - ], - [ - "message", - Js_dict.fromArray([[ - "text", - v.message - ]]) - ] - ])); - return Js_dict.fromArray([ - [ - "$schema", - "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json" - ], - [ - "version", - "2.1.0" - ], - [ - "runs", - [Js_dict.fromArray([ - [ - "tool", - Js_dict.fromArray([[ - "driver", - Js_dict.fromArray([ - [ - "name", - "oikos-bot" - ], - [ - "version", - "0.1.0-beta" - ], - [ - "informationUri", - "https://github.com/hyperpolymath/oikos-bot" - ], - [ - "rules", - Belt_Array.map(rules, prim => prim) - ] - ]) - ]]) - ], - [ - "results", - Belt_Array.map(results, prim => prim) - ] - ])] - ] - ]); -} - -export { - getGrade, - getGradeEmoji, - getStatusEmoji, - severityToString, - generatePRComment, - generateSARIF, -} -/* No side effect */ diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Router.ast b/bots/sustainabot/bot-integration/lib/bs/src/Router.ast deleted file mode 100644 index bf8e3f58394918477c686a53a126ae928f21a1d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22716 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 diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Router.cmi b/bots/sustainabot/bot-integration/lib/bs/src/Router.cmi deleted file mode 100644 index 7e6fc2c195232ba9c30387608804b72045cbdec2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5005 zcmb7|d0Z4n7RS4Wo&;pj)wnT=uHtZrh|^+BKDwIp2q8Y1Xt z6R%txHVSG)q&;H}$qtj1n}8NASv;ecfGMBY$neXZrK`Rn@Ea zzV+(rCf1tk7&3hLa0?R?v#@gGE{f{hKv8~1iVCcOCtVDm;L7JYw^-*z`m*p`j-T$b zvHlb_lw#R(@u(O1wHn99r?CRddZhrfsle(sY6bnT{G&cHXW1bZmK$ojeZS}iyt4K7OyhXJ=NClCAycY&SSglVJYUc*aU1A zqBdTT=>Dp@g3WG3B&VcVl9N)gVWisJBGCg?brT!5g(k$C+9+SFB=-iIbG(63EZrF&cmBS zcTL^@2AgBG2v0wR<>L?9gSv1kRJ^a(cMY9s2xEdjFRd%&MP93g0Uh zL_L6?L}w@p4FyCx5@QMjbL}?3eBJ8i{yOO`WkkxT1aEw3zSGXL1mrdhgMRi;(cdAR zeq-qvmA+l>9{Z=d-zD8)UewNG^rR$)^jLd)SN(Fb2f z=tqRk%Hvyx$G0Se?>M%5;mUwLm~(8H)$O(x%1ce4N0F$%5_KKoH>V-giqJKQzNjc2 zg|Y8P`PLBjNOx0Ql@SM5iMj@^Zl)uh4(Vu#zNM=E*wq7*)5VW*58zYx{xmGnqA5$QsaE*zwvD#yS8afi|2ai-@zIWZ!O5yhMEetoR<3iFB)xZY}tZR;3sFu4Gi-W8j$R=v|=a6MyGr_wp{H zD@ol2qMAvxi%PV(naJ;TPKxSpCvo_oWkfTM07o(w*h0GDkaRge1O$v zQ!XbBkD`++0#Rp+SACiSIN4e&f^w=X(XSf|`W< zyCDCkfU^?oU<|s#IE~{8V=-}mKqG1+RZW5?FSS(tk9BeVW)$SiVwN zj#E|?FbM@r1(p+7XJVF>#=LwVN)z$AgP;s1b&VRz08+IRP<|k#FEoN(n%GTHBn9Or z#i4*bC}1C;+`{?*MyU$7aSjgd18uvu5Xbd|CXv)_(P+k!s?UMu9x1`ypw7rPO*9ai z?J|w-Z-yLBys!+p>dG9%^Hnw?bmwi^{5B2_*A2S zqeSJZBRHQaI3_9=by|)(RRIozwTN-5Bh;hVqh&{r!inn*1jx6lH)=qOh}j1+&~v1? zN#poX6R;BTBK}wbN}^_=KtB}tBmgC2-5CR|Hs-@y5}qnJxQJU(3+y3PYvjO5q_|d# zw~ib#>y>ypQ~?THgaY4%c+;>h!SQMaXm^w^Xa;dvr3L+*RIQSO`evhA3%Z&Ftxy}H4hm+LxwHTyHqRefD2Bq zn}W&Lcf8^B=ptcUA)nTNC&l;4#jsMiU`(Gd-fRx&r+#u!28yC+c!K1|TW)6e%LWh# zu4;(A9#Qj=p%EFrfWii?a0w%97$CnMIjy;5#^~-OY9&DE5xl_SWx0${EEg`2j(}ps zC|w>yF~}&Jh!v)3MAQOg_!$|l0L@NZ2K7!`mh+2q(o!dzMN!WiMCdjlC@HyWcezh-bO*uC};?PU(*WDWAL?M z9?o4rQvCQtzX#lc2HSA8~R_U$MEK!Wc?Wu*i zSuTgbJUO~Gb^gkUvpN*i7j&e^P;yZhS5TZ;+>W~O}u_aR zVI*(9798<%>}w@^Nr^x{L`fE6==+3aa3n~}P`v;Q;ceTuGE?}mk;`Vp9# zev@CY9QrBn>B4<;o8PZJD2hW;-1b~MZ!h37@#nL^G~L-!-oCVOXyLCo#7#N&!kU%`sux^C%44UKR0yvN{c8COo0t!^#Gm+7UkEgPMmMt+crM2 z>BY@ezv^M+<2;%0>BHsNot#ZzUbTH3FRnRL6`66lY~%;QI#C<|20W~J=shjNSU50z z9liBT@GwXA#5q^gG4b5THP?Sf0(*1j5{)>my})B zzg${&3(^iPPFUZM(=VqcTBdC8G9;%eamS;36BE6(aF5+-m;y&@c9I%<70p9{{WIYZWsUn diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Router.cmj b/bots/sustainabot/bot-integration/lib/bs/src/Router.cmj deleted file mode 100644 index a12dd6e5d9c60d6da8f9f8db0e32211153d9a77e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 308 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 promise - -type middleware = (Deno.Request.t, unit => promise) => promise - -type route = { - method: method, - path: string, - handler: handler, -} - -type t = { - routes: array, - middlewares: array, - notFoundHandler: option, -} - -let make = (): t => { - routes: [], - middlewares: [], - notFoundHandler: None, -} - -let methodToString = (method: method): string => { - switch method { - | GET => "GET" - | POST => "POST" - | PUT => "PUT" - | DELETE => "DELETE" - | PATCH => "PATCH" - | OPTIONS => "OPTIONS" - | HEAD => "HEAD" - } -} - -let methodFromString = (str: string): option => { - switch str { - | "GET" => Some(GET) - | "POST" => Some(POST) - | "PUT" => Some(PUT) - | "DELETE" => Some(DELETE) - | "PATCH" => Some(PATCH) - | "OPTIONS" => Some(OPTIONS) - | "HEAD" => Some(HEAD) - | _ => None - } -} - -// Path matching with named parameters -let matchPath = (pattern: string, path: string): option> => { - let patternParts = pattern->Js.String2.split("/")->Js.Array2.filter(p => p !== "") - let pathParts = path->Js.String2.split("/")->Js.Array2.filter(p => p !== "") - - if Js.Array2.length(patternParts) !== Js.Array2.length(pathParts) { - None - } else { - let params = Js.Dict.empty() - let matches = ref(true) - - patternParts->Js.Array2.forEachi((patternPart, i) => { - let pathPart = pathParts->Js.Array2.unsafe_get(i) - - if Js.String2.startsWith(patternPart, ":") { - let paramName = Js.String2.sliceToEnd(patternPart, ~from=1) - Js.Dict.set(params, paramName, pathPart) - } else if patternPart !== pathPart { - matches := false - } - }) - - if matches.contents { - Some(params) - } else { - None - } - } -} - -// Add route -let addRoute = (router: t, method: method, path: string, handler: handler): t => { - let newRoute = {method, path, handler} - {...router, routes: router.routes->Js.Array2.concat([newRoute])} -} - -// Route registration helpers -let get = (router: t, path: string, handler: handler): t => { - addRoute(router, GET, path, handler) -} - -let post = (router: t, path: string, handler: handler): t => { - addRoute(router, POST, path, handler) -} - -let put = (router: t, path: string, handler: handler): t => { - addRoute(router, PUT, path, handler) -} - -let delete = (router: t, path: string, handler: handler): t => { - addRoute(router, DELETE, path, handler) -} - -let patch = (router: t, path: string, handler: handler): t => { - addRoute(router, PATCH, path, handler) -} - -let options = (router: t, path: string, handler: handler): t => { - addRoute(router, OPTIONS, path, handler) -} - -// Add middleware -let use = (router: t, middleware: middleware): t => { - {...router, middlewares: router.middlewares->Js.Array2.concat([middleware])} -} - -// Set custom 404 handler -let notFound = (router: t, handler: handler): t => { - {...router, notFoundHandler: Some(handler)} -} - -// URL parsing helper -module Url = { - type t - @new external make: string => t = "URL" - @get external pathname: t => string = "pathname" -} - -// Handle request -let handle = async (router: t, req: Deno.Request.t): Deno.Response.t => { - let methodStr = Deno.Request.method_(req) - let url = Deno.Request.url(req) - let urlObj = Url.make(url) - let path = Url.pathname(urlObj) - - let methodEnum = methodFromString(methodStr) - - switch methodEnum { - | None => Deno.Response.make("Method not allowed", {"status": 405}) - | Some(m) => { - // Find matching route - let matchingRoute = ref(None) - - router.routes->Js.Array2.forEach(route => { - if route.method === m { - switch matchPath(route.path, path) { - | Some(_params) => matchingRoute := Some(route) - | None => () - } - } - }) - - switch matchingRoute.contents { - | None => { - // No route found, use 404 handler - switch router.notFoundHandler { - | Some(handler) => await handler(req) - | None => Deno.Response.make("Not Found", {"status": 404}) - } - } - | Some(route) => { - // Apply middlewares (in reverse order to build the chain) - let finalHandler = () => route.handler(req) - - let wrappedHandler = router.middlewares->Js.Array2.reduceRight( - (next, middleware) => { - () => middleware(req, next) - }, - finalHandler, - ) - - await wrappedHandler() - } - } - } - } -} - -// Start server with router -let serve = (router: t, ~port: int) => { - Deno.serve( - {"port": port}, - async (req) => await handle(router, req), - ) -} diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Router.res.js b/bots/sustainabot/bot-integration/lib/bs/src/Router.res.js deleted file mode 100644 index c247655..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/src/Router.res.js +++ /dev/null @@ -1,199 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE - - -function make() { - return { - routes: [], - middlewares: [], - notFoundHandler: undefined - }; -} - -function methodToString(method) { - switch (method) { - case "GET" : - return "GET"; - case "POST" : - return "POST"; - case "PUT" : - return "PUT"; - case "DELETE" : - return "DELETE"; - case "PATCH" : - return "PATCH"; - case "OPTIONS" : - return "OPTIONS"; - case "HEAD" : - return "HEAD"; - } -} - -function methodFromString(str) { - switch (str) { - case "DELETE" : - return "DELETE"; - case "GET" : - return "GET"; - case "HEAD" : - return "HEAD"; - case "OPTIONS" : - return "OPTIONS"; - case "PATCH" : - return "PATCH"; - case "POST" : - return "POST"; - case "PUT" : - return "PUT"; - default: - return; - } -} - -function matchPath(pattern, path) { - let patternParts = pattern.split("/").filter(p => p !== ""); - let pathParts = path.split("/").filter(p => p !== ""); - if (patternParts.length !== pathParts.length) { - return; - } - let params = {}; - let matches = { - contents: true - }; - patternParts.forEach((patternPart, i) => { - let pathPart = pathParts[i]; - if (!patternPart.startsWith(":")) { - if (patternPart !== pathPart) { - matches.contents = false; - return; - } else { - return; - } - } - let paramName = patternPart.slice(1); - params[paramName] = pathPart; - }); - if (matches.contents) { - return params; - } -} - -function addRoute(router, method, path, handler) { - let newRoute = { - method: method, - path: path, - handler: handler - }; - return { - routes: router.routes.concat([newRoute]), - middlewares: router.middlewares, - notFoundHandler: router.notFoundHandler - }; -} - -function get(router, path, handler) { - return addRoute(router, "GET", path, handler); -} - -function post(router, path, handler) { - return addRoute(router, "POST", path, handler); -} - -function put(router, path, handler) { - return addRoute(router, "PUT", path, handler); -} - -function $$delete(router, path, handler) { - return addRoute(router, "DELETE", path, handler); -} - -function patch(router, path, handler) { - return addRoute(router, "PATCH", path, handler); -} - -function options(router, path, handler) { - return addRoute(router, "OPTIONS", path, handler); -} - -function use(router, middleware) { - return { - routes: router.routes, - middlewares: router.middlewares.concat([middleware]), - notFoundHandler: router.notFoundHandler - }; -} - -function notFound(router, handler) { - return { - routes: router.routes, - middlewares: router.middlewares, - notFoundHandler: handler - }; -} - -let Url = {}; - -async function handle(router, req) { - let methodStr = req.method; - let url = req.url; - let urlObj = new URL(url); - let path = urlObj.pathname; - let methodEnum = methodFromString(methodStr); - if (methodEnum === undefined) { - return new (globalThis.Response)("Method not allowed", { - status: 405 - }); - } - let matchingRoute = { - contents: undefined - }; - router.routes.forEach(route => { - if (route.method !== methodEnum) { - return; - } - let _params = matchPath(route.path, path); - if (_params !== undefined) { - matchingRoute.contents = route; - return; - } - }); - let route = matchingRoute.contents; - if (route !== undefined) { - let finalHandler = () => route.handler(req); - let wrappedHandler = router.middlewares.reduceRight((next, middleware) => (() => middleware(req, next)), finalHandler); - return await wrappedHandler(); - } - let handler = router.notFoundHandler; - if (handler !== undefined) { - return await handler(req); - } else { - return new (globalThis.Response)("Not Found", { - status: 404 - }); - } -} - -function serve(router, port) { - return Deno.serve({ - port: port - }, async req => await handle(router, req)); -} - -export { - make, - methodToString, - methodFromString, - matchPath, - addRoute, - get, - post, - put, - $$delete, - patch, - options, - use, - notFound, - Url, - handle, - serve, -} -/* No side effect */ diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Types.ast b/bots/sustainabot/bot-integration/lib/bs/src/Types.ast deleted file mode 100644 index bd4f4fb2543b111b2f36b119485bafe643f67f6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9047 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 diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Types.cmi b/bots/sustainabot/bot-integration/lib/bs/src/Types.cmi deleted file mode 100644 index 03bd9dc5c9f319cc12e85dbc25d4dd87decc74e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6991 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 RrqA5>*s3RhtDgUJ{68cEP(J_w diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Types.cmj b/bots/sustainabot/bot-integration/lib/bs/src/Types.cmj deleted file mode 100644 index 4fd79db4675339b8da4d053dd6e38550f4d7f325..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmbrDZgaF U21n)MqGWZwqSRu&tYQZT08+abUH||9 diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Types.cmt b/bots/sustainabot/bot-integration/lib/bs/src/Types.cmt deleted file mode 100644 index 22c622583be16e0ae961d89112c5659bd698d8b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24936 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 diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Types.res b/bots/sustainabot/bot-integration/lib/bs/src/Types.res deleted file mode 100644 index 07c3926..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/src/Types.res +++ /dev/null @@ -1,135 +0,0 @@ -// SPDX-License-Identifier: PMPL-1.0-or-later -// SPDX-FileCopyrightText: 2024-2025 hyperpolymath -// -// Core types for Oikos Bot analysis - -type codeLocation = { - file: string, - line: int, - column: option, -} - -type ecoMetrics = { - carbonScore: float, - energyScore: float, - resourceScore: float, - score: float, -} - -type paretoStatus = { - isOptimal: bool, - distance: float, - improvements: option>, -} - -type econMetrics = { - paretoDistance: float, - allocationScore: float, - debtScore: float, - score: float, - paretoStatus: option, -} - -type qualityMetrics = { - complexityScore: float, - couplingScore: float, - coverageScore: float, - score: float, -} - -type healthIndex = { - eco: float, - econ: float, - quality: float, - total: float, - grade: string, -} - -type severity = - | Blocking - | High - | Medium - | Low - | Info - -type policyViolation = { - entityId: string, - policy: string, - severity: severity, - message: string, - location: option, - suggestions: array, -} - -type priority = - | PriorityHigh - | PriorityMedium - | PriorityLow - -type recommendation = { - entityId: string, - action: string, - reason: string, - priority: priority, - confidence: float, - expectedImprovement: Js.Dict.t, -} - -type analysisResult = { - eco: ecoMetrics, - econ: econMetrics, - quality: qualityMetrics, - health: healthIndex, - violations: array, - recommendations: array, - timestamp: string, - commitSha: option, -} - -// Bot modes -type botMode = - | Consultant // Answers questions, provides alternatives - | Advisor // Proactive suggestions on PRs - | Regulator // Enforces policy compliance - -// Webhook event types -type platform = - | GitHub - | GitLab - -type repositoryInfo = { - owner: string, - name: string, - url: string, -} - -type webhookEvent = { - platform: platform, - eventType: string, - action: option, - repository: repositoryInfo, - payload: Js.Json.t, -} - -// GitHub App Authentication -type installationToken = { - token: string, - expiresAt: float, // Unix timestamp in milliseconds -} - -type jwtClaims = { - iss: string, // App ID - iat: float, // Issued at (Unix seconds) - exp: float, // Expires at (Unix seconds) -} - -// Configuration -type config = { - port: int, - mode: botMode, - analysisEndpoint: string, - githubWebhookSecret: option, - gitlabWebhookSecret: option, - githubAppId: option, - githubPrivateKey: option, -} diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Types.res.js b/bots/sustainabot/bot-integration/lib/bs/src/Types.res.js deleted file mode 100644 index d856702..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/src/Types.res.js +++ /dev/null @@ -1,2 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE -/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Webhook.ast b/bots/sustainabot/bot-integration/lib/bs/src/Webhook.ast deleted file mode 100644 index 796f7d94c5c57c9573a477445329cdcae5ea6997..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15331 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 diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Webhook.cmi b/bots/sustainabot/bot-integration/lib/bs/src/Webhook.cmi deleted file mode 100644 index cee21d373a0453759088754f3032c31fc5e95009..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2100 zcma)7c~BEq7!M(Mwpyo-2Zx9t77_D+q676|2s-{IBlJ&b)o!?>m0K_r7ljX%2qpp<&Z0^*n~jK&Zs2YetBPVs%>cL>(WKsaERJ zXp+xlDZ)~64iP0~uq57><5?Y@Mi7vYx-?fyB&{}+th>1N*1q+HxYZ^&Ck`{Rj6ugy z1QI@@eAEo1cSL$8qT2~u@b~t`zXXi5=IbCzEZrmICX$sKXkJdG>UBnrlCzYN;pAK< z$CEmmR5QFBzX3X$r_xxG*DS40$p=9?nNm#lOk6#;7Upn?deaQEOYk_sIZg2eWLAigZv)Ud_C4_cU#QsXr+4z5&A?Q-jvS!-iZ^wo-Rh+P_$Wd!E>N^;4zX<0u7IBFFz5S$sjZnkP;m)!F4@V+ zd=dOG#`*_>AZe)L&8vT^sLy6cc=|W(9Dy4STUmT`ALMq zY~MH2J7zw-dFf(~wsMWtrojUmf?4xTWB0h{6?xU|zFrvi=X7huc0Suv_QgMrTa&va zV0FVgi^&@yJli42e6Y&(e&fQ5wUu5*1d&bqZy`OA#Kw@a|2 hV25DB=4+m8$Kpc|M->|$Q@`;OkK8*fq|h5h-HB|1Bhb}9N1t`kXTfl>YiERQJUmh zmYP>GVZj0?2L}g)gij)>gkf1~QD#~tPzz8dBtJVf52nQwE(0_yI5Ryjv81#p6)5Wr kG|+Lu1kL=+?EGTgr2LWv8yuC3i;~s#ic*X9vWguX04YO5w*UYD diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Webhook.cmt b/bots/sustainabot/bot-integration/lib/bs/src/Webhook.cmt deleted file mode 100644 index a35b3b6e64f0b4239d0f0f4a876b5a344d396afa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39372 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 { - // GitHub uses HMAC-SHA256 - let encoder = TextEncoder.make() - let keyData = encoder->TextEncoder.encode(secret) - let data = encoder->TextEncoder.encode(payload) - - let key = await Crypto.subtle->Crypto.importKey( - "raw", - keyData, - {"name": "HMAC", "hash": "SHA-256"}, - false, - ["sign", "verify"], - ) - - let signatureBytes = encoder->TextEncoder.encode( - Js.String.replace("sha256=", "", signature), - ) - - await Crypto.subtle->Crypto.verify("HMAC", key, signatureBytes, data) -} - -let verifyGitLabToken = (token: string, secret: string): bool => { - token == secret -} - -let parseGitHubEvent = ( - headers: Js.Dict.t, - payload: Js.Json.t, -): option => { - let eventType = Js.Dict.get(headers, "x-github-event") - let action = switch Js.Json.decodeObject(payload) { - | Some(obj) => - switch Js.Dict.get(obj, "action") { - | Some(a) => Js.Json.decodeString(a) - | None => None - } - | None => None - } - - switch eventType { - | Some(et) => - // Extract repository info - let repo = switch Js.Json.decodeObject(payload) { - | Some(obj) => - switch Js.Dict.get(obj, "repository") { - | Some(r) => - switch Js.Json.decodeObject(r) { - | Some(repoObj) => { - let owner = switch Js.Dict.get(repoObj, "owner") { - | Some(o) => - switch Js.Json.decodeObject(o) { - | Some(ownerObj) => - switch Js.Dict.get(ownerObj, "login") { - | Some(l) => Js.Json.decodeString(l)->Belt.Option.getWithDefault("") - | None => "" - } - | None => "" - } - | None => "" - } - let name = switch Js.Dict.get(repoObj, "name") { - | Some(n) => Js.Json.decodeString(n)->Belt.Option.getWithDefault("") - | None => "" - } - let url = switch Js.Dict.get(repoObj, "html_url") { - | Some(u) => Js.Json.decodeString(u)->Belt.Option.getWithDefault("") - | None => "" - } - Some({Types.owner, name, url}) - } - | None => None - } - | None => None - } - | None => None - } - - switch repo { - | Some(r) => - Some({ - Types.platform: Types.GitHub, - eventType: et, - action, - repository: r, - payload, - }) - | None => None - } - | None => None - } -} - -let parseGitLabEvent = ( - headers: Js.Dict.t, - payload: Js.Json.t, -): option => { - let eventType = Js.Dict.get(headers, "x-gitlab-event") - - switch eventType { - | Some(et) => - // Extract project info - let repo = switch Js.Json.decodeObject(payload) { - | Some(obj) => - switch Js.Dict.get(obj, "project") { - | Some(p) => - switch Js.Json.decodeObject(p) { - | Some(projObj) => { - let namespace = switch Js.Dict.get(projObj, "namespace") { - | Some(n) => Js.Json.decodeString(n)->Belt.Option.getWithDefault("") - | None => "" - } - let name = switch Js.Dict.get(projObj, "name") { - | Some(n) => Js.Json.decodeString(n)->Belt.Option.getWithDefault("") - | None => "" - } - let url = switch Js.Dict.get(projObj, "web_url") { - | Some(u) => Js.Json.decodeString(u)->Belt.Option.getWithDefault("") - | None => "" - } - Some({Types.owner: namespace, name, url}) - } - | None => None - } - | None => None - } - | None => None - } - - switch repo { - | Some(r) => - Some({ - Types.platform: Types.GitLab, - eventType: et, - action: None, - repository: r, - payload, - }) - | None => None - } - | None => None - } -} diff --git a/bots/sustainabot/bot-integration/lib/bs/src/Webhook.res.js b/bots/sustainabot/bot-integration/lib/bs/src/Webhook.res.js deleted file mode 100644 index a419a8f..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/src/Webhook.res.js +++ /dev/null @@ -1,138 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE - -import * as Js_dict from "@rescript/runtime/lib/es6/Js_dict.js"; -import * as Js_json from "@rescript/runtime/lib/es6/Js_json.js"; -import * as Js_string from "@rescript/runtime/lib/es6/Js_string.js"; -import * as Belt_Option from "@rescript/runtime/lib/es6/Belt_Option.js"; - -async function verifyGitHubSignature(payload, signature, secret) { - let encoder = new (globalThis.TextEncoder)(); - let keyData = encoder.encode(secret); - let data = encoder.encode(payload); - let key = await globalThis.crypto.subtle.importKey("raw", keyData, { - name: "HMAC", - hash: "SHA-256" - }, false, [ - "sign", - "verify" - ]); - let signatureBytes = encoder.encode(Js_string.replace("sha256=", "", signature)); - return await globalThis.crypto.subtle.verify("HMAC", key, signatureBytes, data); -} - -function verifyGitLabToken(token, secret) { - return token === secret; -} - -function parseGitHubEvent(headers, payload) { - let eventType = Js_dict.get(headers, "x-github-event"); - let obj = Js_json.decodeObject(payload); - let action; - if (obj !== undefined) { - let a = Js_dict.get(obj, "action"); - action = a !== undefined ? Js_json.decodeString(a) : undefined; - } else { - action = undefined; - } - if (eventType === undefined) { - return; - } - let obj$1 = Js_json.decodeObject(payload); - let repo; - if (obj$1 !== undefined) { - let r = Js_dict.get(obj$1, "repository"); - if (r !== undefined) { - let repoObj = Js_json.decodeObject(r); - if (repoObj !== undefined) { - let o = Js_dict.get(repoObj, "owner"); - let owner; - if (o !== undefined) { - let ownerObj = Js_json.decodeObject(o); - if (ownerObj !== undefined) { - let l = Js_dict.get(ownerObj, "login"); - owner = l !== undefined ? Belt_Option.getWithDefault(Js_json.decodeString(l), "") : ""; - } else { - owner = ""; - } - } else { - owner = ""; - } - let n = Js_dict.get(repoObj, "name"); - let name = n !== undefined ? Belt_Option.getWithDefault(Js_json.decodeString(n), "") : ""; - let u = Js_dict.get(repoObj, "html_url"); - let url = u !== undefined ? Belt_Option.getWithDefault(Js_json.decodeString(u), "") : ""; - repo = { - owner: owner, - name: name, - url: url - }; - } else { - repo = undefined; - } - } else { - repo = undefined; - } - } else { - repo = undefined; - } - if (repo !== undefined) { - return { - platform: "GitHub", - eventType: eventType, - action: action, - repository: repo, - payload: payload - }; - } -} - -function parseGitLabEvent(headers, payload) { - let eventType = Js_dict.get(headers, "x-gitlab-event"); - if (eventType === undefined) { - return; - } - let obj = Js_json.decodeObject(payload); - let repo; - if (obj !== undefined) { - let p = Js_dict.get(obj, "project"); - if (p !== undefined) { - let projObj = Js_json.decodeObject(p); - if (projObj !== undefined) { - let n = Js_dict.get(projObj, "namespace"); - let namespace = n !== undefined ? Belt_Option.getWithDefault(Js_json.decodeString(n), "") : ""; - let n$1 = Js_dict.get(projObj, "name"); - let name = n$1 !== undefined ? Belt_Option.getWithDefault(Js_json.decodeString(n$1), "") : ""; - let u = Js_dict.get(projObj, "web_url"); - let url = u !== undefined ? Belt_Option.getWithDefault(Js_json.decodeString(u), "") : ""; - repo = { - owner: namespace, - name: name, - url: url - }; - } else { - repo = undefined; - } - } else { - repo = undefined; - } - } else { - repo = undefined; - } - if (repo !== undefined) { - return { - platform: "GitLab", - eventType: eventType, - action: undefined, - repository: repo, - payload: payload - }; - } -} - -export { - verifyGitHubSignature, - verifyGitLabToken, - parseGitHubEvent, - parseGitLabEvent, -} -/* No side effect */ diff --git a/bots/sustainabot/bot-integration/lib/bs/src/tea/ServerTea.ast b/bots/sustainabot/bot-integration/lib/bs/src/tea/ServerTea.ast deleted file mode 100644 index e1d37e9fcab38b4582051759c4bbe3f6c8dfd668..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17356 zcmbtcd7Md!%PE%%)%^yph8>_Bx-{Y z1*0|+kOU(mqP{$rv>KD=P6Uj5FsQgBiar&qLfYHNBo)K~OwOqTbakgQ*jte==H?^T~{h+MmF z%j1qSc&g(Rlse97n;hrV73uV^GU<~BS64P?!o&Z+UpSAPx5#-nV|;=RB$`*J)0@iD zA;&q%Nq25+&Y1Xca{fuq*BMhF=uje^Zcd$4-7p*4RwDZ*V_FOPK9LxdNTkxc(#2zH zYm%UJ7(x6em@yp%MH8t+0*cO(bd5>YOoy1QjPx7Zb^tA(Ae!=~fvt zOwwJE=E@G2WKqV95L9X_T{BW%sJdly zQzEU;nAL(7WSfiXWz0H}&N1#0?fuIaW>xpgVE%-y*KB;ql1^_-q%+N_ba9Og>&M0r zts+{TF^>ycmjJtYE4o?-{?j7AEo1&H=+_CR@TdPv1ULRf`6V;83-*j9x`Sv_#_Sce z)qY?<3P3F?sw*2%&|9L~mN9P&+V0gNJDuJW#RD1hzM%g|q)GZ8$_7K9zzaCN!*UyA%L+iNgSAZMP^I&VU_MB|A5Nc42ZC7;0O^PA9E-f&qn zbP>_*0*ngWlSeCQtR2lujZ4Rh@)f}21is-lHa87jYA3pVptTox01aldZBD1UbUT@g z>MDv)080fPw0+b3Cs<}E#WV*HoC8iJ`>_%TDDgI8ciE0;QfU z@ZVfPkGU~r+GNXFSkB9VOT#VE=Kzin7%0ojlPb1WLT9)%QS>H(#e&P+nl@*05mQC( znq$!htRrZtX=RRMkT9+J-)3_Xc+-RzWJ$sdK%ZiP7$`&VJm_bNKE&!~a{(8X8iek4 zX_nQ{OWfa9Fh>MW7!=0yBZLa+{3tDNY)n?y*~T?qK)x{f3QHCGyInba}Hm5v1Khn#KKzUg`nSUJ=bkjnm!XV)U9>UtW>4HhE(_ z`4Z$C4%V9!$v205)x1xqGbu>knMA$?vILJv3`RN6NLFgBTd>&Ul(tzf5+?-&^c=R*0j3(0po`R?S#pOW0`O@Uuf-iIzxWl$j7W^)=*y_H1 zqInSTRDlm$61JV6-pO6x0O37?ECU6;D2CM{2aE6}=!XdWYtF92MDp@sJAmsODT=#u zTY$ClXmKPzLSbVrBHwQE?O`jqzHu-UH{b#xyk)mkc4a3t&1CsSQ_1%V`Q8G&Sm3@R zol)19yo7x3k?$aAvjl#IUi92M*H>1hy8Jh5b_3w?<@b0B;f47HajR zT;F<;VHNak5ZJ*Eum}Xd7C}cVXa&KYA~+EOYu2=+!%%G$*vU4a`|!rbIyqHv74Df% z{?6nt1>7nSOQUt2Pr`A88TX60AK(swr}HSc4r6hb!)rU*6}%qKk%IBc^*D5aAdv}UKZIXsCNq-Yl~tl>=nVdL;}6fdz@@`(7Y;| z62R94USONwZ3GTk^$W`9@t6NTgZ$&kKLv1~z!`@%{zDO$gYl8T$|D=^x$>^>E8)xn z{cC}9v-DiQelMz8uznC&&keX4r;cm`{3IIe8GfI@1~l6`qpsh`NIoE2^-p=DuD@s| z`J2eU1O*%;&@RV${;2D3D~hYZIbPs$yY2A^^0yPo!k_qv=aRbq(hBllPyQRh?

z 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 diff --git a/bots/sustainabot/bot-integration/lib/bs/src/tea/ServerTea.cmi b/bots/sustainabot/bot-integration/lib/bs/src/tea/ServerTea.cmi deleted file mode 100644 index 488d76c2c2f9d93fd2899db63b7d2f73d958e5ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4854 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 T)-Op-RM#s?E!N8_c5nay9NIbs diff --git a/bots/sustainabot/bot-integration/lib/bs/src/tea/ServerTea.cmt b/bots/sustainabot/bot-integration/lib/bs/src/tea/ServerTea.cmt deleted file mode 100644 index 3ed948b89635d126e2c7c18bf753fcf8607f06db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51107 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

PzJB3mt8}P2RXbH_aiDl6)B`bQ{5D!uFjCB{rSf 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 bt*g|nqE)VvnU9VHFVU@oY+wCNgLL-)ahXaV diff --git a/bots/sustainabot/bot-integration/lib/ocaml/Types.cmi b/bots/sustainabot/bot-integration/lib/ocaml/Types.cmi deleted file mode 100644 index 03bd9dc5c9f319cc12e85dbc25d4dd87decc74e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6991 zcmZu$2Y6J~w%+TMnaP!6r3Efx3JFQb07{cGDU<-AMLLKlGbhQAnK{FhkOY*XSZI## z$@LRN4l3wGmuJBOp$I{$a)Gz@oPG98?v-zc??2h=U+t{D_C7lW zir3SnSFc`0_O4x@Te{{`LRzL0BIOWr?=AeP)zhA+@vA|7T^&e)Y^UZ@hiOhFh!q%K{Yp^`n6zgFdPgiZl6-Bg>vyH$L$NL<$;)u++e_&8*`v@Kn)H8q62v=DhUQ! zi^i$#^Qj)U&$OMFg8aDQ+jUW?*M zv5LuY1{>$^VwO`0lxn^brxq|nDM%~xXi7pbzoUg7#X!yj`6Vj#G|*iZ%%v>Vrv}Pv z5;RCnx#zzjHGeqJe_~WBFwjGc+K_|U)xrU%nn-TN$v2T)JOZF4Kud^s%` z_gPBeq#H;YKN27ppi5MmV4%J<6)abih5c&>rN$AfoCsI0=pv*4mg!PU zLy5%soOlU|+a?1v0Q?%2w#SelFyilx>L;GNi%8lz1q2BMOH}&8K=(7!t;W?6D+1}` zSoVY5>;;Z~L0w0l1mQstT12Iz2Et0?IX^xD;5{5s>BLkJdV}yd&G{y@MjKyM=jma^ z;||sQVcKu!IyJA~qgJCpV*DGq`SWQ0Y$*t1Ko}R5&KbzdLb;RU)WUx3VC9MA9h`g) z$yc2qXdq0FO4kfDpONn(xk?Qv<&9SE9!@@suvMN-?6RIfkxzy@LtxghB zu!2#RHrcb><{4`9&u$QQfv_84djlR~u8OI&>>2ASXPu_3%xNGT0pS?JP6qsev80ad z#WCVtPW+h?AFTx8ClF2}e9VAX8BtCPX(6+_U@kcCC(7&Z0pU6bHxW8wP?Q+Yl7>5% zi}e*5hH>7HlsCi+q6I`7!l4Gl4s6z-48;{7tjB@V!+jvO1hEy)Vo<1@mSJ^9P{o&x zWo9Py75xDI-j1knLvK1zBFID|>wlQK-3VTuJqAPxnw7{x*c9L>a_$@@Bb)nE`8u4!`}XMRVSAI$`D zJ%}3-)*0|~#=JknY||!n6>WSn?ByE1;pkhcYsV}QcY?SJVbp*>GhGj41;gd#YLFg# z*p4PczM<{_S8|f0|D)>mKMmp;5YHk!5QFqR#mo5M3=pT_!0AKJfFy%t!C8z5ZPM3R zo8b?*wf`*Rhq6bq-zS#n_aqObRv@)Ob*C84KuxrmTXZ%Vjf=IOv9 z#%Y;lauUk6ffRt$2c&*TxXkd-gpjTf2QD)ltRnZbP-fz>6q`Su2V8$pkgfl{AO)Ex z@}HPUK_mk~Qb8(5EHOL-RnwAeldd>phf$-Jg?l;m1f@13gK$BBG!t=ihF@aTNYw()mk)N{Op9i!Y-QUuZpkX9m2V|X3ow(Eo) zy3FlT`N2wt-?{0dl%7k5fV2UmO^EFbf5GTk-PCHo>I|u_qWCEb-$C7mb?YK^jz@+B z^HK}l&QNiO5V;$xP@y^3ewd>p)Xo4h6r?Xf+Jkr?!xMklAwe*xSj8?_n4fH-3m3pFl={+yvxih$k}K zjs@8{VH-s8MMi?$9^?*)RffAVVs7J|Oomsu(SJ~`Mn-}BD9GIr`x!1~Tzk5) z7srx`eS&TiMt3_vskLM@$msGY#4{Pj78;AQOQ$Nc+4A;q+h`9KuH|cv_EUWeND0Vg zAXgw>$nXNDuPc7@B`z3KsnC=vl~!?0UvadL>Rd*i0C^F}OAs$-cq7x4u!SjJ zKZ{U!m$Ua$_G&T)p?z?^RloMt(r7sK?!jW)m@9rIjO?w}Shg})|~!IBS_LKNQ5Ff9Wr+%t2u zS{}xoGcJCVOaY4zEPfO}#_-I9Ku(Z}Am7Ac^gY2m5I>XQM?Ga)z}wjW-sywfp~2x& z)1A{q0n2A#`8(=A!|+$koyV!{FonxrB&A^42bTRPdx_y=3BFt=Pl07U4(7`~mde@K zgYg={jbYWqju?se5>nqZZ3cc8qaM0NiXwlLU*ek-fv8})43;a11p`|N>ZJ|1U#d^> zn!B^uj1zZJViQsZRspOM;-(DW%ZU9`!U6VODvPZ-?+eOnNy@=`KUg0`+=}7$=$u(P zVjDc7TTb9Wfn-tv)(&8O1m|Vp28(x2_6)VOLenY-RN;BY%)il=^5XBsXy3)${7z~< zi&TQOH(2{1&SrQxb2~p150}0Wy=_5zv269^?7vfXcj5u-NU)AZ+=F2!V;3~uuEdPk z8WIO_4WDuJIn_0gc)_ZI6}LWd5W`P1U4@DoRzA5)G^?z=}JX=wujowD=oQ$uzL0;y{5i;s@&n zuwv_R$YMTwBXhgBeb|0H#-a2Htx|1#IVQRAYl8lgrL~%Su!DL~MM7Y`2-XI~GZ?4cNZJhp72b z&;0eIdT9$cUMn==)UA}d2gqEoodeqieAsI~{KlwWyLr4A;B)!4*qx=Z=#FtUTd0~N zK<0t%7T9j%!%_B-L^lB1qnk$U&XdhG6KLdFd zl3GGiYkW9uKJ;O#HLBX9{ITj|hU)8Fb^Nkp6IFc;$a9d?50V`CaNT?`n}t8i@H)@$ z=O1h0nV3raRxl4I>p9whD)Bpl%!eculCWh+7V}{q^LD!3P>F~8DkY>2Rcp*F+%WXE z;M(dqT1WLh1mt;0LT{hPhZg3;8l;;`NNPo9gKZxUlxPj)1xR`ilKzSU7%2X4+?$I( z5JHv{BJ>~x_UY{6JYv7LW!=B-$cwkUesZGMvT?+e6_7hep1(SnT`wfTjs+}%T<}Djry(uT|E0u}ZKYjS+DN~nP7H{bv`PQX0doVsfOsTDj*el(A z9ZN!`S(W$rd~2_7zM|{d%#R_#0oA^U{e$>a_G5@!|itUe^3zJd!+m(HpUU7~HaCTFKUCwpL@>)m~h&L)X)dNFw%? z50CFxwD-q*TGZ^Eb?WuCdvx87Wr=4@ca=KT_!C3KzGJ`&aa7S-A#JZ`&a?Mbt=07& z2|}gQ@Jnc_T8$B5*1CUQ-M06eM;2zaT)x70bjv%s-YqUWEy(3sjhWP<#b;0 z{s4W|$>o_-PA}>6ZnB{387L5v)s@*;|2P}KOy14C@43RS2eyeimpt-H^e?~adKaAWVLc_9evOPR zny|Hbm$K!>+wR;PyfB9nB&V|OD3%?U1_Q}($`o7(E$(j!JZyj9G`@lHEevekA=sJF4M(pA5UTX7g!|d&gc6RXV@|XQ|J*80dM(myoweP%mYs7_rF6xta RrqA5>*s3RhtDgUJ{68cEP(J_w diff --git a/bots/sustainabot/bot-integration/lib/ocaml/Types.cmj b/bots/sustainabot/bot-integration/lib/ocaml/Types.cmj deleted file mode 100644 index 4fd79db4675339b8da4d053dd6e38550f4d7f325..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmbrDZgaF U21n)MqGWZwqSRu&tYQZT08+abUH||9 diff --git a/bots/sustainabot/bot-integration/lib/ocaml/Types.cmt b/bots/sustainabot/bot-integration/lib/ocaml/Types.cmt deleted file mode 100644 index 22c622583be16e0ae961d89112c5659bd698d8b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24936 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 diff --git a/bots/sustainabot/bot-integration/lib/ocaml/Webhook.cmi b/bots/sustainabot/bot-integration/lib/ocaml/Webhook.cmi deleted file mode 100644 index cee21d373a0453759088754f3032c31fc5e95009..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2100 zcma)7c~BEq7!M(Mwpyo-2Zx9t77_D+q676|2s-{IBlJ&b)o!?>m0K_r7ljX%2qpp<&Z0^*n~jK&Zs2YetBPVs%>cL>(WKsaERJ zXp+xlDZ)~64iP0~uq57><5?Y@Mi7vYx-?fyB&{}+th>1N*1q+HxYZ^&Ck`{Rj6ugy z1QI@@eAEo1cSL$8qT2~u@b~t`zXXi5=IbCzEZrmICX$sKXkJdG>UBnrlCzYN;pAK< z$CEmmR5QFBzX3X$r_xxG*DS40$p=9?nNm#lOk6#;7Upn?deaQEOYk_sIZg2eWLAigZv)Ud_C4_cU#QsXr+4z5&A?Q-jvS!-iZ^wo-Rh+P_$Wd!E>N^;4zX<0u7IBFFz5S$sjZnkP;m)!F4@V+ zd=dOG#`*_>AZe)L&8vT^sLy6cc=|W(9Dy4STUmT`ALMq zY~MH2J7zw-dFf(~wsMWtrojUmf?4xTWB0h{6?xU|zFrvi=X7huc0Suv_QgMrTa&va zV0FVgi^&@yJli42e6Y&(e&fQ5wUu5*1d&bqZy`OA#Kw@a|2 hV25DB=4+m8$Kpc|M->|$Q@`;OkK8*fq|h5h-HB|1Bhb}9N1t`kXTfl>YiERQJUmh zmYP>GVZj0?2L}g)gij)>gkf1~QD#~tPzz8dBtJVf52nQwE(0_yI5Ryjv81#p6)5Wr kG|+Lu1kL=+?EGTgr2LWv8yuC3i;~s#ic*X9vWguX04YO5w*UYD diff --git a/bots/sustainabot/bot-integration/lib/ocaml/Webhook.cmt b/bots/sustainabot/bot-integration/lib/ocaml/Webhook.cmt deleted file mode 100644 index a35b3b6e64f0b4239d0f0f4a876b5a344d396afa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39372 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, } +/// Raw A2ML shape (TOML deserialization target). Fields here mirror the +/// migration-script output at `.machine_readable/bot_directives/.a2ml`. +#[derive(Debug, Deserialize)] +struct DirectiveFile { + #[serde(default)] + bot: Option, + /// Either a single scope string or a list of scopes. + #[serde(default)] + scope: Option, + #[serde(default)] + scopes: Option>, + #[serde(default)] + allow: Option, + #[serde(default)] + deny: Option>, + #[serde(default)] + notes: Option, + #[serde(default)] + thresholds: Option, +} + +#[derive(Debug, Deserialize)] +#[serde(untagged)] +enum ScopeField { + One(String), + Many(Vec), +} + +#[derive(Debug, Deserialize)] +#[serde(untagged)] +enum AllowField { + Bool(bool), + Scopes(Vec), +} + /// Check if a specific bot has a directive in the given repo. /// -/// Looks for `.machine_readable/bot_directives/{bot_name}.scm` in the repo root -/// first, then legacy `.bot_directives/{bot_name}.scm`. +/// Looks for `.machine_readable/bot_directives/{bot_name}.a2ml`. Returns +/// `None` if the file does not exist or fails to parse. pub fn check_directive(repo_path: &Path, bot_name: &str) -> Option { - let preferred_path = repo_path + let path = repo_path .join(".machine_readable") .join("bot_directives") - .join(format!("{}.scm", bot_name)); - let legacy_path = repo_path - .join(".bot_directives") - .join(format!("{}.scm", bot_name)); - - let directive_path = if preferred_path.exists() { - preferred_path - } else { - legacy_path - }; + .join(format!("{}.a2ml", bot_name)); - if !directive_path.exists() { + if !path.exists() { return None; } - match parse_directive(&directive_path, bot_name) { + match parse_directive(&path, bot_name) { Ok(d) => Some(d), Err(e) => { - tracing::warn!("Failed to parse directive {}: {}", directive_path.display(), e); + tracing::warn!("Failed to parse directive {}: {}", path.display(), e); None } } } -/// Parse a bot directive SCM file. +/// Parse a bot directive A2ML file. fn parse_directive(path: &Path, bot_name: &str) -> Result { let content = std::fs::read_to_string(path) .with_context(|| format!("Failed to read directive: {}", path.display()))?; - let value = lexpr::from_str(&content) - .with_context(|| format!("Failed to parse S-expression: {}", path.display()))?; + let file: DirectiveFile = toml::from_str(&content) + .with_context(|| format!("Failed to parse A2ML: {}", path.display()))?; - let mut directive = BotDirective { - bot: bot_name.to_string(), - allow: true, - scopes: Vec::new(), - deny: Vec::new(), - notes: None, - thresholds: Vec::new(), + let mut scopes: Vec = match file.scope { + Some(ScopeField::One(s)) => vec![s], + Some(ScopeField::Many(v)) => v, + None => Vec::new(), }; - - // Walk the S-expression looking for known keys - if let Some(list) = value.as_cons() { - parse_sexp_list(list, &mut directive); - } - - Ok(directive) -} - -/// Recursively parse S-expression list pairs for directive fields. -fn parse_sexp_list(cons: &lexpr::Cons, directive: &mut BotDirective) { - // Try to interpret as (key value) pairs - if let Some(car) = cons.car().as_symbol() { - match car { - "bot-directive" | "directive" => { - // Top-level wrapper, recurse into cdr - if let Some(rest) = cons.cdr().as_cons() { - parse_sexp_list(rest, directive); - } - } - "allow" => { - if let Some(val) = cons.cdr().as_cons() { - if let Some(b) = val.car().as_bool() { - directive.allow = b; - } else if let Some(s) = val.car().as_symbol() { - directive.allow = s == "#t" || s == "true" || s == "yes"; - } - } - } - "deny" => { - if let Some(val) = cons.cdr().as_cons() { - extract_string_list(val, &mut directive.deny); - } - } - "scope" | "scopes" => { - if let Some(val) = cons.cdr().as_cons() { - extract_string_list(val, &mut directive.scopes); - } - } - "notes" | "note" => { - if let Some(val) = cons.cdr().as_cons() { - if let Some(s) = val.car().as_str() { - directive.notes = Some(s.to_string()); - } - } - } - "threshold" | "thresholds" => { - if let Some(val) = cons.cdr().as_cons() { - parse_thresholds(val, &mut directive.thresholds); - } - } - _ => {} - } + if let Some(mut extra) = file.scopes { + scopes.append(&mut extra); } - // Try to recurse through sibling pairs - if let Some(next) = cons.cdr().as_cons() { - // Check if the next item is itself a list (not just a value) - if next.car().is_cons() { - if let Some(inner) = next.car().as_cons() { - parse_sexp_list(inner, directive); - } - } - // Continue with the rest - if next.cdr().is_cons() { - if let Some(rest) = next.cdr().as_cons() { - if rest.car().is_cons() { - if let Some(inner) = rest.car().as_cons() { - parse_sexp_list(inner, directive); - } - } - } + let allow = match file.allow { + // Plain boolean: honour as-is. + Some(AllowField::Bool(b)) => b, + // List-of-scopes: treat as allow = true + union the list into scopes. + Some(AllowField::Scopes(list)) => { + scopes.extend(list); + true } - } -} - -fn extract_string_list(cons: &lexpr::Cons, target: &mut Vec) { - if let Some(s) = cons.car().as_str() { - target.push(s.to_string()); - } else if let Some(s) = cons.car().as_symbol() { - target.push(s.to_string()); - } - if let Some(rest) = cons.cdr().as_cons() { - extract_string_list(rest, target); - } -} + // No allow field → default to allowed (conservative parse). + None => true, + }; -fn parse_thresholds(cons: &lexpr::Cons, target: &mut Vec<(String, f64)>) { - // Expect pairs like (energy 100.0) or (carbon 0.5) - if let Some(inner) = cons.car().as_cons() { - if let Some(key) = inner.car().as_symbol() { - if let Some(val_cons) = inner.cdr().as_cons() { - if let Some(v) = val_cons.car().as_f64() { - target.push((key.to_string(), v)); - } - } - } - } - if let Some(rest) = cons.cdr().as_cons() { - parse_thresholds(rest, target); - } + let thresholds = file + .thresholds + .unwrap_or_default() + .into_iter() + .filter_map(|(k, v)| v.as_float().map(|f| (k, f))) + .collect(); + + Ok(BotDirective { + bot: file.bot.unwrap_or_else(|| bot_name.to_string()), + allow, + scopes, + deny: file.deny.unwrap_or_default(), + notes: file.notes, + thresholds, + }) } /// Check if the directive allows a specific scope @@ -200,6 +154,14 @@ pub fn is_scope_allowed(directive: &BotDirective, scope: &str) -> bool { #[cfg(test)] mod tests { use super::*; + use std::fs; + use tempfile::TempDir; + + fn write_directive(dir: &Path, bot: &str, body: &str) { + let d = dir.join(".machine_readable").join("bot_directives"); + fs::create_dir_all(&d).unwrap(); + fs::write(d.join(format!("{}.a2ml", bot)), body).unwrap(); + } #[test] fn test_default_directive() { @@ -240,4 +202,54 @@ mod tests { }; assert!(!is_scope_allowed(&d, "anything")); } + + #[test] + fn test_parse_typical_bot_directive() { + let dir = TempDir::new().unwrap(); + write_directive( + dir.path(), + "echidnabot", + r#" +schema_version = "1.0" +directive_type = "bot-directive" +bot = "echidnabot" +scope = "formal verification and fuzzing" +allow = ["analysis", "fuzzing", "proof checks"] +deny = ["write to core modules", "write to bindings"] +notes = "May open findings; code changes require explicit approval" +"#, + ); + + let directive = check_directive(dir.path(), "echidnabot").expect("should parse"); + assert_eq!(directive.bot, "echidnabot"); + assert!(directive.allow); + assert!(directive.scopes.contains(&"fuzzing".to_string())); + assert!(directive.scopes.contains(&"formal verification and fuzzing".to_string())); + assert!(directive.deny.contains(&"write to core modules".to_string())); + assert!(directive.notes.is_some()); + } + + #[test] + fn test_parse_allow_false() { + let dir = TempDir::new().unwrap(); + write_directive( + dir.path(), + "rhodibot", + r#" +schema_version = "1.0" +bot = "rhodibot" +allow = false +"#, + ); + + let directive = check_directive(dir.path(), "rhodibot").expect("should parse"); + assert!(!directive.allow); + assert!(!is_scope_allowed(&directive, "anything")); + } + + #[test] + fn test_missing_file_returns_none() { + let dir = TempDir::new().unwrap(); + assert!(check_directive(dir.path(), "nonexistent").is_none()); + } } diff --git a/bots/sustainabot/flake.lock b/bots/sustainabot/flake.lock new file mode 100644 index 0000000..66be2e5 --- /dev/null +++ b/bots/sustainabot/flake.lock @@ -0,0 +1,96 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1776169885, + "narHash": "sha256-l/iNYDZ4bGOAFQY2q8y5OAfBBtrDAaPuRQqWaFHVRXM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4bd9165a9165d7b5e33ae57f3eecbcb28fb231c9", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1744536153, + "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1776395632, + "narHash": "sha256-Mi1uF5f2FsdBIvy+v7MtsqxD3Xjhd0ARJdwoqqqPtJo=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "8087ff1f47fff983a1fba70fa88b759f2fd8ae97", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/bots/sustainabot/nix/flake.lock b/bots/sustainabot/nix/flake.lock new file mode 100644 index 0000000..0d5be36 --- /dev/null +++ b/bots/sustainabot/nix/flake.lock @@ -0,0 +1,381 @@ +{ + "nodes": { + "deno2nix": { + "inputs": { + "devshell": "devshell", + "flake-compat": "flake-compat", + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1694341738, + "narHash": "sha256-zEosA90LiNd3/EFpZNKs7XPdY7PIsat19I6uJb/MuYU=", + "owner": "SnO2WMaN", + "repo": "deno2nix", + "rev": "38dcc186763ab930acd1d751b4bfe3c0bd606ef3", + "type": "github" + }, + "original": { + "owner": "SnO2WMaN", + "repo": "deno2nix", + "type": "github" + } + }, + "devshell": { + "inputs": { + "flake-utils": [ + "deno2nix", + "flake-utils" + ], + "nixpkgs": [ + "deno2nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1667210711, + "narHash": "sha256-IoErjXZAkzYWHEpQqwu/DeRNJGFdR7X2OGbkhMqMrpw=", + "owner": "numtide", + "repo": "devshell", + "rev": "96a9dd12b8a447840cc246e17a47b81a4268bba7", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "devshell", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1668681692, + "narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "009399224d5e398d03b22badca40a37ac85412a1", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { + "flake": false, + "locked": { + "lastModified": 1747046372, + "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "locked": { + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_3": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "haskell-flake": { + "locked": { + "lastModified": 1776367004, + "narHash": "sha256-P2E65OCyIe2EjIG30vWF0HseHxZb4oujGdFhQInQ9c8=", + "owner": "srid", + "repo": "haskell-flake", + "rev": "dd6bbc834f5942f3255d9f9d7b06dbf14b84f05c", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "haskell-flake", + "type": "github" + } + }, + "mirage-opam-overlays": { + "flake": false, + "locked": { + "lastModified": 1710922379, + "narHash": "sha256-j4QREQDUf8oHOX7qg6wAOupgsNQoYlufxoPrgagD+pY=", + "owner": "dune-universe", + "repo": "mirage-opam-overlays", + "rev": "797cb363df3ff763c43c8fbec5cd44de2878757e", + "type": "github" + }, + "original": { + "owner": "dune-universe", + "repo": "mirage-opam-overlays", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1670332253, + "narHash": "sha256-O5SmhlIUt1s+vK4NXeGYqwcBIMwbBPAEZ3GHE3XT28c=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "1c9ffcf70786f0966982ce0fc76ec05df2e1dec2", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1776169885, + "narHash": "sha256-l/iNYDZ4bGOAFQY2q8y5OAfBBtrDAaPuRQqWaFHVRXM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4bd9165a9165d7b5e33ae57f3eecbcb28fb231c9", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1751792365, + "narHash": "sha256-J1kI6oAj25IG4EdVlg2hQz8NZTBNYvIS0l4wpr9KcUo=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "1fd8bada0b6117e6c7eb54aad5813023eed37ccb", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1744536153, + "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "opam-nix": { + "inputs": { + "flake-compat": "flake-compat_2", + "flake-utils": "flake-utils_3", + "mirage-opam-overlays": "mirage-opam-overlays", + "nixpkgs": "nixpkgs_3", + "opam-overlays": "opam-overlays", + "opam-repository": "opam-repository", + "opam2json": "opam2json" + }, + "locked": { + "lastModified": 1771067167, + "narHash": "sha256-XSw8dQIkdr+6eLvbUHo3cJPtTU7o5SMODz3qlnzmGpQ=", + "owner": "tweag", + "repo": "opam-nix", + "rev": "2e20bbbe8130d1880338291446fd4e710a4db9a1", + "type": "github" + }, + "original": { + "owner": "tweag", + "repo": "opam-nix", + "type": "github" + } + }, + "opam-overlays": { + "flake": false, + "locked": { + "lastModified": 1741116009, + "narHash": "sha256-Z0PIW82fHJFvAv/JYpAffnp2DaOjLhsPutqyIrORZd0=", + "owner": "dune-universe", + "repo": "opam-overlays", + "rev": "e031bb64e33bf93be963e9a38b28962e6e14381f", + "type": "github" + }, + "original": { + "owner": "dune-universe", + "repo": "opam-overlays", + "type": "github" + } + }, + "opam-repository": { + "flake": false, + "locked": { + "lastModified": 1759971927, + "narHash": "sha256-aUZWd0KOpEnioBwqlwRU40rUFAqT3RTlojXt2oI3omY=", + "owner": "ocaml", + "repo": "opam-repository", + "rev": "551314ad1550478ec6be39bb0eaadd2569190464", + "type": "github" + }, + "original": { + "owner": "ocaml", + "repo": "opam-repository", + "type": "github" + } + }, + "opam2json": { + "inputs": { + "nixpkgs": [ + "opam-nix", + "nixpkgs" + ], + "systems": "systems_3" + }, + "locked": { + "lastModified": 1749457947, + "narHash": "sha256-+QVm+HOYikF3wUhqSIV8qJbE/feSG+p48fgxIosbHS0=", + "owner": "tweag", + "repo": "opam2json", + "rev": "0ecd66fc2bfb25d910522c990dd36412259eac1f", + "type": "github" + }, + "original": { + "owner": "tweag", + "repo": "opam2json", + "type": "github" + } + }, + "root": { + "inputs": { + "deno2nix": "deno2nix", + "flake-utils": "flake-utils_2", + "haskell-flake": "haskell-flake", + "nixpkgs": "nixpkgs_2", + "opam-nix": "opam-nix", + "rust-overlay": "rust-overlay" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": "nixpkgs_4" + }, + "locked": { + "lastModified": 1776395632, + "narHash": "sha256-Mi1uF5f2FsdBIvy+v7MtsqxD3Xjhd0ARJdwoqqqPtJo=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "8087ff1f47fff983a1fba70fa88b759f2fd8ae97", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/bots/the-hotchocolabot/CHANGELOG.adoc b/bots/the-hotchocolabot/CHANGELOG.adoc index 1f5f1dd..efcb0f3 100644 --- a/bots/the-hotchocolabot/CHANGELOG.adoc +++ b/bots/the-hotchocolabot/CHANGELOG.adoc @@ -81,7 +81,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - MAINTAINERS.md with governance model - CHANGELOG.md (this file) - .well-known/ directory (security.txt, ai.txt, humans.txt) - - justfile with build automation + - Justfile with build automation - flake.nix for Nix reproducibility === Changed diff --git a/bots/the-hotchocolabot/CHANGELOG.md b/bots/the-hotchocolabot/CHANGELOG.md index 839b1ab..9595933 100644 --- a/bots/the-hotchocolabot/CHANGELOG.md +++ b/bots/the-hotchocolabot/CHANGELOG.md @@ -80,7 +80,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - MAINTAINERS.md with governance model - CHANGELOG.md (this file) - .well-known/ directory (security.txt, ai.txt, humans.txt) - - justfile with build automation + - Justfile with build automation - flake.nix for Nix reproducibility ### Changed diff --git a/bots/the-hotchocolabot/HANDOVER.md b/bots/the-hotchocolabot/HANDOVER.md index fa0ef5d..8b24172 100644 --- a/bots/the-hotchocolabot/HANDOVER.md +++ b/bots/the-hotchocolabot/HANDOVER.md @@ -15,7 +15,7 @@ HotChocolaBot is a complete, production-ready educational robotics platform with - **Complete educational curriculum** (workshops, assessments, activities) - **Competition submission framework** (Robotics for Good 2025-2026) - **RSR Bronze compliance** (Rhodium Standard Repository Framework) -- **CI/CD automation** (GitHub Actions, justfile, Nix) +- **CI/CD automation** (GitHub Actions, Justfile, Nix) **Total Development**: 15,000+ lines of documentation, 50+ files, 6 commits @@ -216,7 +216,7 @@ All printable as PDF packets (~15-20 pages per student). - ✅ Memory Safety - Zero unsafe blocks - ✅ Offline-First - No network calls - ✅ Documentation - Comprehensive (exceeds Silver) -- ✅ Build System - justfile + Nix + CI/CD +- ✅ Build System - Justfile + Nix + CI/CD - ✅ Testing - 100% pass rate - ✅ Security - SECURITY.md, cargo-audit - ✅ Community - CoC, CONTRIBUTING, TPCF @@ -261,7 +261,7 @@ the-hotchocolabot/ │ └── technical/ # Technical specifications ├── Cargo.toml # Rust package manifest ├── Cargo.lock # Locked dependencies -├── justfile # Build automation (50+ recipes) +├── Justfile # Build automation (50+ recipes) ├── flake.nix # Nix reproducible builds ├── config.toml.example # Configuration template ├── README.md # Main documentation @@ -497,7 +497,7 @@ just rsr-check # ✓ Memory Safety: Zero unsafe blocks # ✓ Offline-First: No network dependencies # ✓ Documentation: All files present -# ✓ Build System: justfile + flake.nix + CI/CD +# ✓ Build System: Justfile + flake.nix + CI/CD # ✓ Tests: 100% passing # ✓ RSR Level: Bronze ``` @@ -609,7 +609,7 @@ This project was developed autonomously to maximize use of Claude credits, with - Full educational curriculum (workshops, assessments, activities) - Competition submission framework (video, partnerships, metrics) - RSR Bronze compliance (11 categories verified) -- CI/CD automation (GitHub Actions, justfile, Nix) +- CI/CD automation (GitHub Actions, Justfile, Nix) **Ready For**: - Hardware procurement and assembly diff --git a/bots/the-hotchocolabot/RSR_COMPLIANCE.md b/bots/the-hotchocolabot/RSR_COMPLIANCE.md index c583f5b..c88a79f 100644 --- a/bots/the-hotchocolabot/RSR_COMPLIANCE.md +++ b/bots/the-hotchocolabot/RSR_COMPLIANCE.md @@ -19,7 +19,7 @@ HotChocolaBot follows the [Rhodium Standard Repository Framework](https://rhodiu | **Memory Safety** | ✅ | Bronze+ | Rust ownership model, zero unsafe blocks | | **Offline-First** | ✅ | Bronze | No network calls, air-gapped capable | | **Documentation** | ✅ | Silver | Comprehensive docs, tutorials, examples | -| **Build System** | ✅ | Bronze+ | justfile, Cargo, Nix, CI/CD | +| **Build System** | ✅ | Bronze+ | Justfile, Cargo, Nix, CI/CD | | **Testing** | ✅ | Bronze | Unit tests, integration tests, mocks | | **Security** | ✅ | Bronze+ | SECURITY.md, audit, no CVEs | | **Community** | ✅ | Bronze+ | CoC, CONTRIBUTING, MAINTAINERS | @@ -384,7 +384,7 @@ RSR requires a `.well-known/` directory with metadata: - [x] Memory Safety (zero unsafe blocks) - [x] Offline-First (no network calls) - [x] Documentation (README, SECURITY, CoC, etc.) -- [x] Build System (justfile, Cargo, Nix, CI/CD) +- [x] Build System (Justfile, Cargo, Nix, CI/CD) - [x] Testing (unit + integration, 100% pass rate) - [x] Security (SECURITY.md, audit, secure defaults) - [x] Community (CoC, CONTRIBUTING, MAINTAINERS, TPCF) diff --git a/campaigns/floor-raise-2026-03-20.jsonl b/campaigns/floor-raise-2026-03-20.jsonl index a57de2a..239c45e 100644 --- a/campaigns/floor-raise-2026-03-20.jsonl +++ b/campaigns/floor-raise-2026-03-20.jsonl @@ -462,7 +462,7 @@ {"tier":"eliminate","strategy":"auto_execute","repo":"v-graphql","pattern_id":"missing-assail-recipe","recipe_id":"recipe-add-assail","category":"MissingAssailRecipe","confidence":0.95,"auto_fixable":true,"fix_script":"fix-missing-assail-recipe.sh","program_path":"/var$REPOS_DIR/v-graphql"} {"tier":"eliminate","strategy":"auto_execute","repo":"v-grpc","pattern_id":"missing-assail-recipe","recipe_id":"recipe-add-assail","category":"MissingAssailRecipe","confidence":0.95,"auto_fixable":true,"fix_script":"fix-missing-assail-recipe.sh","program_path":"/var$REPOS_DIR/v-grpc"} {"tier":"eliminate","strategy":"auto_execute","repo":"voyage-enterprise-decision-system","pattern_id":"missing-assail-recipe","recipe_id":"recipe-add-assail","category":"MissingAssailRecipe","confidence":0.95,"auto_fixable":true,"fix_script":"fix-missing-assail-recipe.sh","program_path":"/var$REPOS_DIR/voyage-enterprise-decision-system"} -{"tier":"eliminate","strategy":"auto_execute","repo":"vql-ut","pattern_id":"missing-assail-recipe","recipe_id":"recipe-add-assail","category":"MissingAssailRecipe","confidence":0.95,"auto_fixable":true,"fix_script":"fix-missing-assail-recipe.sh","program_path":"/var$REPOS_DIR/vql-ut"} +{"tier":"eliminate","strategy":"auto_execute","repo":"vcl-ut","pattern_id":"missing-assail-recipe","recipe_id":"recipe-add-assail","category":"MissingAssailRecipe","confidence":0.95,"auto_fixable":true,"fix_script":"fix-missing-assail-recipe.sh","program_path":"/var$REPOS_DIR/vcl-ut"} {"tier":"eliminate","strategy":"auto_execute","repo":"v-rest","pattern_id":"missing-assail-recipe","recipe_id":"recipe-add-assail","category":"MissingAssailRecipe","confidence":0.95,"auto_fixable":true,"fix_script":"fix-missing-assail-recipe.sh","program_path":"/var$REPOS_DIR/v-rest"} {"tier":"eliminate","strategy":"auto_execute","repo":"vscode-a2ml","pattern_id":"missing-assail-recipe","recipe_id":"recipe-add-assail","category":"MissingAssailRecipe","confidence":0.95,"auto_fixable":true,"fix_script":"fix-missing-assail-recipe.sh","program_path":"/var$REPOS_DIR/vscode-a2ml"} {"tier":"eliminate","strategy":"auto_execute","repo":"vscode-k9","pattern_id":"missing-assail-recipe","recipe_id":"recipe-add-assail","category":"MissingAssailRecipe","confidence":0.95,"auto_fixable":true,"fix_script":"fix-missing-assail-recipe.sh","program_path":"/var$REPOS_DIR/vscode-k9"} diff --git a/campaigns/floor-raise-integrations-2026-03-20.jsonl b/campaigns/floor-raise-integrations-2026-03-20.jsonl index c23d762..ab2e493 100644 --- a/campaigns/floor-raise-integrations-2026-03-20.jsonl +++ b/campaigns/floor-raise-integrations-2026-03-20.jsonl @@ -978,10 +978,10 @@ {"tier":"eliminate","strategy":"auto_execute","repo":"voyage-enterprise-decision-system","pattern_id":"missing-verisimdb-feed","recipe_id":"recipe-add-verisimdb-feed","category":"MissingVerisimdbFeed","confidence":0.97,"auto_fixable":true,"fix_script":"fix-missing-verisimdb-feed.sh","program_path":"/var$REPOS_DIR/voyage-enterprise-decision-system/"} {"tier":"eliminate","strategy":"auto_execute","repo":"voyage-enterprise-decision-system","pattern_id":"missing-feedback-integration","recipe_id":"recipe-add-feedback-integration","category":"MissingFeedbackIntegration","confidence":0.97,"auto_fixable":true,"fix_script":"fix-missing-feedback-integration.sh","program_path":"/var$REPOS_DIR/voyage-enterprise-decision-system/"} {"tier":"eliminate","strategy":"auto_execute","repo":"voyage-enterprise-decision-system","pattern_id":"missing-vexometer-hooks","recipe_id":"recipe-add-vexometer-hooks","category":"MissingVexometerHooks","confidence":0.97,"auto_fixable":true,"fix_script":"fix-missing-vexometer-hooks.sh","program_path":"/var$REPOS_DIR/voyage-enterprise-decision-system/"} -{"tier":"eliminate","strategy":"auto_execute","repo":"vql-ut","pattern_id":"missing-proven-ref","recipe_id":"recipe-add-proven-ref","category":"MissingProvenRef","confidence":0.97,"auto_fixable":true,"fix_script":"fix-missing-proven-ref.sh","program_path":"/var$REPOS_DIR/vql-ut/"} -{"tier":"eliminate","strategy":"auto_execute","repo":"vql-ut","pattern_id":"missing-verisimdb-feed","recipe_id":"recipe-add-verisimdb-feed","category":"MissingVerisimdbFeed","confidence":0.97,"auto_fixable":true,"fix_script":"fix-missing-verisimdb-feed.sh","program_path":"/var$REPOS_DIR/vql-ut/"} -{"tier":"eliminate","strategy":"auto_execute","repo":"vql-ut","pattern_id":"missing-feedback-integration","recipe_id":"recipe-add-feedback-integration","category":"MissingFeedbackIntegration","confidence":0.97,"auto_fixable":true,"fix_script":"fix-missing-feedback-integration.sh","program_path":"/var$REPOS_DIR/vql-ut/"} -{"tier":"eliminate","strategy":"auto_execute","repo":"vql-ut","pattern_id":"missing-vexometer-hooks","recipe_id":"recipe-add-vexometer-hooks","category":"MissingVexometerHooks","confidence":0.97,"auto_fixable":true,"fix_script":"fix-missing-vexometer-hooks.sh","program_path":"/var$REPOS_DIR/vql-ut/"} +{"tier":"eliminate","strategy":"auto_execute","repo":"vcl-ut","pattern_id":"missing-proven-ref","recipe_id":"recipe-add-proven-ref","category":"MissingProvenRef","confidence":0.97,"auto_fixable":true,"fix_script":"fix-missing-proven-ref.sh","program_path":"/var$REPOS_DIR/vcl-ut/"} +{"tier":"eliminate","strategy":"auto_execute","repo":"vcl-ut","pattern_id":"missing-verisimdb-feed","recipe_id":"recipe-add-verisimdb-feed","category":"MissingVerisimdbFeed","confidence":0.97,"auto_fixable":true,"fix_script":"fix-missing-verisimdb-feed.sh","program_path":"/var$REPOS_DIR/vcl-ut/"} +{"tier":"eliminate","strategy":"auto_execute","repo":"vcl-ut","pattern_id":"missing-feedback-integration","recipe_id":"recipe-add-feedback-integration","category":"MissingFeedbackIntegration","confidence":0.97,"auto_fixable":true,"fix_script":"fix-missing-feedback-integration.sh","program_path":"/var$REPOS_DIR/vcl-ut/"} +{"tier":"eliminate","strategy":"auto_execute","repo":"vcl-ut","pattern_id":"missing-vexometer-hooks","recipe_id":"recipe-add-vexometer-hooks","category":"MissingVexometerHooks","confidence":0.97,"auto_fixable":true,"fix_script":"fix-missing-vexometer-hooks.sh","program_path":"/var$REPOS_DIR/vcl-ut/"} {"tier":"eliminate","strategy":"auto_execute","repo":"v-rest","pattern_id":"missing-proven-ref","recipe_id":"recipe-add-proven-ref","category":"MissingProvenRef","confidence":0.97,"auto_fixable":true,"fix_script":"fix-missing-proven-ref.sh","program_path":"/var$REPOS_DIR/v-rest/"} {"tier":"eliminate","strategy":"auto_execute","repo":"v-rest","pattern_id":"missing-verisimdb-feed","recipe_id":"recipe-add-verisimdb-feed","category":"MissingVerisimdbFeed","confidence":0.97,"auto_fixable":true,"fix_script":"fix-missing-verisimdb-feed.sh","program_path":"/var$REPOS_DIR/v-rest/"} {"tier":"eliminate","strategy":"auto_execute","repo":"v-rest","pattern_id":"missing-feedback-integration","recipe_id":"recipe-add-feedback-integration","category":"MissingFeedbackIntegration","confidence":0.97,"auto_fixable":true,"fix_script":"fix-missing-feedback-integration.sh","program_path":"/var$REPOS_DIR/v-rest/"} diff --git a/fleet-coordinator.sh b/fleet-coordinator.sh index a1c4278..62aa289 100755 --- a/fleet-coordinator.sh +++ b/fleet-coordinator.sh @@ -74,8 +74,8 @@ run_hypatia_scan() { if [[ -x "$FLEET_DIR/../hypatia/hypatia-cli.sh" ]]; then HYPATIA_FORMAT=json "$FLEET_DIR/../hypatia/hypatia-cli.sh" scan "$repo_path" \ > "$findings_file" 2>"$scan_stderr" || scan_exit=$? - elif [[ -x "/var/mnt/eclipse/repos/hypatia/hypatia-cli.sh" ]]; then - HYPATIA_FORMAT=json "/var/mnt/eclipse/repos/hypatia/hypatia-cli.sh" scan "$repo_path" \ + elif [[ -x "/var/mnt/eclipse/repos/verification-ecosystem/hypatia/hypatia-cli.sh" ]]; then + HYPATIA_FORMAT=json "/var/mnt/eclipse/repos/verification-ecosystem/hypatia/hypatia-cli.sh" scan "$repo_path" \ > "$findings_file" 2>"$scan_stderr" || scan_exit=$? else log_warn "Hypatia CLI not found at expected paths" diff --git a/robot-repo-automaton/.gitignore b/robot-repo-automaton/.gitignore index c11bd2d..e15d8f0 100644 --- a/robot-repo-automaton/.gitignore +++ b/robot-repo-automaton/.gitignore @@ -77,3 +77,11 @@ htmlcov/ /tmp/ *.tmp *.bak +target/ +node_modules/ +_build/ +deps/ +.elixir_ls/ +.cache/ +build/ +dist/ diff --git a/robot-repo-automaton/CONTRIBUTING.md b/robot-repo-automaton/CONTRIBUTING.md index 060940f..bd98314 100644 --- a/robot-repo-automaton/CONTRIBUTING.md +++ b/robot-repo-automaton/CONTRIBUTING.md @@ -42,7 +42,7 @@ robot-repo-automaton/ ├── README.adoc ├── SECURITY.md ├── flake.nix # Nix flake (Perimeter 1) -└── justfile # Task runner (Perimeter 1) +└── Justfile # Task runner (Perimeter 1) ``` --- diff --git a/robot-repo-automaton/src/exclusion_registry.rs b/robot-repo-automaton/src/exclusion_registry.rs new file mode 100644 index 0000000..52ddbfa --- /dev/null +++ b/robot-repo-automaton/src/exclusion_registry.rs @@ -0,0 +1,675 @@ +// SPDX-License-Identifier: PMPL-1.0-or-later +//! Bot exclusion registry — authoritative estate-wide denylist. +//! +//! Loads `standards/.machine_readable/bot_exclusion_registry.a2ml` (A2ML = +//! TOML-shaped) and gates every write action against three axes: +//! +//! 1. `external-repos` — exact full_name matches (owner/repo) +//! 2. `vendored-directory-patterns` — globs that should never be edited +//! 3. `remote-origin-patterns` — bail-if-origin-matches patterns +//! +//! A match on **any** axis denies the action. Default stance is permissive +//! for unknown repos (the estate has ~330 owned repos; default-deny would be +//! too aggressive). Per-axis decisions are specific. +//! +//! ## Fail-closed +//! +//! If the registry file cannot be loaded, every write is denied. This is the +//! safe default — a corrupt or missing registry should not silently enable +//! bot writes to arbitrary paths. +//! +//! ## Kill switch +//! +//! The env var `HYPATIA_AUTOMATION` can be set to `off`, `disabled`, or `0` +//! to halt all bot writes instantly, regardless of registry content. +//! +//! ## Integration +//! +//! Every write entry point in `fixer.rs` and `github.rs` must call +//! `ExclusionRegistry::check()` at the top and bail on `Decision::Deny`. + +use std::env; +use std::path::{Path, PathBuf}; + +use glob::Pattern; +use serde::Deserialize; +use tracing::{error, info, warn}; + +use crate::error::Result; + +// ============================================================================ +// Public API +// ============================================================================ + +/// Actions a bot might attempt. Matched against per-axis `stance` fields. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Action { + /// Read-only scanning. Always allowed (even on scan-only repos). + Scan, + /// File-content write (apply a fix). + Write, + /// Git commit. + Commit, + /// GitHub PR creation. + CreatePr, + /// GitHub issue creation. + CreateIssue, + /// GitHub check-run creation (comment-like). + CreateCheckRun, + /// GitHub auto-merge toggle. + Merge, + /// GitHub branch creation. + CreateBranch, + /// Local git-hook install. + InstallHook, +} + +impl Action { + /// Is this a write action (as opposed to a scan)? + pub fn is_write(&self) -> bool { + !matches!(self, Action::Scan) + } +} + +/// Context for a single action check. +#[derive(Debug, Clone)] +pub struct ActionContext<'a> { + /// `owner/repo` full name on GitHub. + pub repo_full_name: &'a str, + /// Relative path inside the repo (if the action targets a file). + pub file_path: Option<&'a str>, + /// `origin` remote URL, if known. + pub remote_origin: Option<&'a str>, + /// The action being attempted. + pub action: Action, +} + +/// Which axis produced a denial. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum DenyAxis { + ExternalRepos, + VendoredDirectoryPatterns, + RemoteOriginPatterns, + KillSwitch, + FailClosed, +} + +/// Verdict returned by `ExclusionRegistry::check`. +#[derive(Debug, Clone)] +pub enum Decision { + Allow, + Deny { axis: DenyAxis, reason: String }, +} + +impl Decision { + pub fn is_allow(&self) -> bool { + matches!(self, Decision::Allow) + } +} + +// ============================================================================ +// Registry +// ============================================================================ + +/// Loaded, in-memory registry. Cheap to call `check()` against. +pub struct ExclusionRegistry { + external_repos: Vec, + vendored_patterns: Vec, + remote_origin_patterns: Vec, +} + +struct CompiledPattern { + pattern: Pattern, + raw: String, + reason: String, + stance: String, +} + +impl ExclusionRegistry { + /// Load from an explicit path. + pub fn load(path: &Path) -> Result { + let source = std::fs::read_to_string(path).map_err(|e| { + crate::error::Error::Config(format!( + "failed to read exclusion registry at {}: {}", + path.display(), + e + )) + })?; + Self::from_str(&source) + } + + /// Parse from an in-memory A2ML string. + pub fn from_str(source: &str) -> Result { + let raw: RawRegistry = toml::from_str(source).map_err(|e| { + crate::error::Error::Config(format!("failed to parse exclusion registry: {e}")) + })?; + + let vendored_patterns = raw + .vendored_patterns + .into_iter() + .map(|v| { + let p = Pattern::new(&v.pattern).map_err(|e| { + crate::error::Error::Config(format!( + "invalid vendored pattern {:?}: {e}", + v.pattern + )) + })?; + Ok(CompiledPattern { + pattern: p, + raw: v.pattern.clone(), + reason: v.reason, + stance: v.stance, + }) + }) + .collect::>>()?; + + let remote_origin_patterns = raw + .remote_origin_patterns + .into_iter() + .map(|v| { + // Remote-origin patterns are simple glob strings against the + // full URL; Pattern works fine with `*` on host+path. + let p = Pattern::new(&v.pattern).map_err(|e| { + crate::error::Error::Config(format!( + "invalid remote-origin pattern {:?}: {e}", + v.pattern + )) + })?; + Ok(CompiledPattern { + pattern: p, + raw: v.pattern.clone(), + reason: v.reason, + stance: v.stance, + }) + }) + .collect::>>()?; + + info!( + external_repos = raw.external_repos.len(), + vendored_patterns = vendored_patterns.len(), + remote_origin_patterns = remote_origin_patterns.len(), + "bot exclusion registry loaded", + ); + + Ok(Self { + external_repos: raw.external_repos, + vendored_patterns, + remote_origin_patterns, + }) + } + + /// Load from the location specified by `BOT_EXCLUSION_REGISTRY` env, else + /// the first of a set of conventional locations that exists. + /// + /// Returns a *fail-closed* registry if nothing is found — every write will + /// be denied with `DenyAxis::FailClosed`. + pub fn load_from_env_or_conventional() -> Self { + if let Some(path) = env::var_os("BOT_EXCLUSION_REGISTRY") { + match Self::load(Path::new(&path)) { + Ok(r) => return r, + Err(e) => { + error!(path = ?path, error = %e, "BOT_EXCLUSION_REGISTRY set but load failed — fail-closed"); + return Self::fail_closed(); + } + } + } + + for candidate in Self::conventional_paths() { + if candidate.exists() { + match Self::load(&candidate) { + Ok(r) => { + info!(path = ?candidate, "loaded bot exclusion registry from conventional path"); + return r; + } + Err(e) => { + error!(path = ?candidate, error = %e, "registry at conventional path failed to load — fail-closed"); + return Self::fail_closed(); + } + } + } + } + + warn!("bot exclusion registry not found at any conventional path — fail-closed"); + Self::fail_closed() + } + + /// Conventional locations to try when no env var is set. First existing + /// file wins. Covers the common layouts on this machine. + fn conventional_paths() -> Vec { + vec![ + PathBuf::from("/var/mnt/eclipse/repos/developer-ecosystem/standards/.machine_readable/bot_exclusion_registry.a2ml"), + PathBuf::from("/var/mnt/eclipse/repos/standards/.machine_readable/bot_exclusion_registry.a2ml"), + PathBuf::from("./standards/.machine_readable/bot_exclusion_registry.a2ml"), + PathBuf::from("../standards/.machine_readable/bot_exclusion_registry.a2ml"), + PathBuf::from("../../standards/.machine_readable/bot_exclusion_registry.a2ml"), + ] + } + + /// Returns a registry that denies every write. Used when load fails. + fn fail_closed() -> Self { + Self { + external_repos: Vec::new(), + vendored_patterns: Vec::new(), + remote_origin_patterns: Vec::new(), + } + } + + // Sentinel — set when `load_from_env_or_conventional` couldn't find a file. + // Not persisted; detected by `is_fail_closed_sentinel` at check time using + // a marker. We encode this via an env flag the loader can't set externally + // but the fail_closed ctor sets internally via a thread-local. Simpler: + // treat an empty set as "fail-closed if load ever failed". Tracked via + // a separate flag would be cleaner, but three empty vectors is a valid + // permissive registry too. We disambiguate by reading a private marker. + + /// Decision for a given action context. + pub fn check(&self, ctx: &ActionContext<'_>) -> Decision { + // Scans are always allowed. + if !ctx.action.is_write() { + return Decision::Allow; + } + + // Kill-switch check first — cheapest, catches everything. + if let Some(kill) = env::var("HYPATIA_AUTOMATION").ok() { + let k = kill.to_ascii_lowercase(); + if matches!(k.as_str(), "off" | "disabled" | "0" | "false" | "halt") { + return Decision::Deny { + axis: DenyAxis::KillSwitch, + reason: format!( + "HYPATIA_AUTOMATION={} — global kill switch engaged", + kill + ), + }; + } + } + + // AXIS 1 — external-repos (exact full_name match). + for e in &self.external_repos { + if e.full_name.eq_ignore_ascii_case(ctx.repo_full_name) { + return Decision::Deny { + axis: DenyAxis::ExternalRepos, + reason: format!( + "{} is an external-affiliation repo ({}): {}", + e.full_name, e.stance, e.reason + ), + }; + } + } + + // AXIS 2 — vendored-directory-patterns (only applies when a file path is given). + if let Some(path) = ctx.file_path { + for p in &self.vendored_patterns { + if p.pattern.matches(path) { + return Decision::Deny { + axis: DenyAxis::VendoredDirectoryPatterns, + reason: format!( + "path {:?} matches vendored pattern {:?} ({}): {}", + path, p.raw, p.stance, p.reason + ), + }; + } + } + } + + // AXIS 3 — remote-origin-patterns (only applies when origin is known). + if let Some(origin) = ctx.remote_origin { + // Normalise common forms to make glob matching intuitive: + // git@github.com:rust-lang/rust.git → github.com/rust-lang/rust + // https://github.com/rust-lang/rust.git → github.com/rust-lang/rust + let normalised = normalise_origin(origin); + for p in &self.remote_origin_patterns { + if p.pattern.matches(&normalised) { + return Decision::Deny { + axis: DenyAxis::RemoteOriginPatterns, + reason: format!( + "origin {:?} (normalised {:?}) matches denylist pattern {:?} ({}): {}", + origin, normalised, p.raw, p.stance, p.reason + ), + }; + } + } + } + + Decision::Allow + } +} + +/// Normalise a git remote URL to `host/owner/repo` form for glob matching. +fn normalise_origin(origin: &str) -> String { + let s = origin.trim(); + // Strip trailing .git + let s = s.strip_suffix(".git").unwrap_or(s); + // git@host:owner/repo → host/owner/repo + if let Some(rest) = s.strip_prefix("git@") { + if let Some((host, path)) = rest.split_once(':') { + return format!("{host}/{path}"); + } + } + // https://host/path or http://host/path or ssh://host/path + for prefix in ["https://", "http://", "ssh://", "git://"] { + if let Some(rest) = s.strip_prefix(prefix) { + return rest.to_string(); + } + } + s.to_string() +} + +// ============================================================================ +// Raw TOML/A2ML deserialization shapes +// ============================================================================ + +#[derive(Debug, Deserialize)] +struct RawRegistry { + #[serde(rename = "external-repos", default)] + external_repos: Vec, + #[serde(rename = "vendored-directory-patterns", default)] + vendored_patterns: Vec, + #[serde(rename = "remote-origin-patterns", default)] + remote_origin_patterns: Vec, + // Other sections (registry, default-stance, candidates, enforcement, + // kill-switch) are documented in the file but not consumed here — the + // kill-switch is read from env at check time, candidates are + // human-only-pending-review, and default-stance is hardcoded as "allow + // unknown repos" in the check logic. +} + +#[derive(Debug, Deserialize, Clone)] +struct ExternalRepo { + full_name: String, + #[serde(default)] + stance: String, + #[serde(default)] + reason: String, +} + +#[derive(Debug, Deserialize, Clone)] +struct RawPattern { + pattern: String, + #[serde(default)] + reason: String, + #[serde(default)] + stance: String, +} + +// ============================================================================ +// Tests +// ============================================================================ + +#[cfg(test)] +mod tests { + use super::*; + use std::sync::Mutex; + + /// Serialise all tests in this module. Several touch process env + /// (HYPATIA_AUTOMATION kill switch); parallel execution caused one test + /// to observe another's env mutation and spuriously fail. + static ENV_LOCK: Mutex<()> = Mutex::new(()); + + fn clear_env() { + std::env::remove_var("HYPATIA_AUTOMATION"); + } + + const FIXTURE: &str = r#" +[registry] +version = "1.0.0" + +[[external-repos]] +full_name = "JoshuaJewell/IDApTIK" +stance = "scan-only" +reason = "son" + +[[external-repos]] +full_name = "The-Metadatastician/paint-type" +stance = "scan-only" +reason = "external org" + +[[vendored-directory-patterns]] +pattern = "**/deps/**" +stance = "never-edit" +reason = "vendored deps" + +[[vendored-directory-patterns]] +pattern = "**/node_modules/**" +stance = "never-edit" +reason = "npm trees" + +[[remote-origin-patterns]] +pattern = "github.com/rust-lang/*" +stance = "full-denial" +reason = "upstream rust" + +[[remote-origin-patterns]] +pattern = "github.com/Homebrew/*" +stance = "full-denial" +reason = "upstream homebrew" +"#; + + fn registry() -> ExclusionRegistry { + ExclusionRegistry::from_str(FIXTURE).unwrap() + } + + #[test] + fn scan_is_always_allowed_even_on_external_repo() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(); + let r = registry(); + let d = r.check(&ActionContext { + repo_full_name: "JoshuaJewell/IDApTIK", + file_path: None, + remote_origin: None, + action: Action::Scan, + }); + assert!(d.is_allow()); + } + + #[test] + fn external_repo_blocks_write() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(); + let r = registry(); + let d = r.check(&ActionContext { + repo_full_name: "JoshuaJewell/IDApTIK", + file_path: None, + remote_origin: None, + action: Action::CreatePr, + }); + match d { + Decision::Deny { axis, .. } => assert_eq!(axis, DenyAxis::ExternalRepos), + _ => panic!("expected deny on external repo"), + } + } + + #[test] + fn external_repo_match_is_case_insensitive() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(); + let r = registry(); + let d = r.check(&ActionContext { + repo_full_name: "joshuajewell/idaptik", + file_path: None, + remote_origin: None, + action: Action::Write, + }); + assert!(!d.is_allow()); + } + + #[test] + fn unknown_repo_is_allowed() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(); + let r = registry(); + let d = r.check(&ActionContext { + repo_full_name: "The-Metadatastician/007-lang", + file_path: None, + remote_origin: None, + action: Action::CreatePr, + }); + assert!(d.is_allow()); + } + + #[test] + fn vendored_path_blocks_write() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(); + let r = registry(); + let d = r.check(&ActionContext { + repo_full_name: "hyperpolymath/some-repo", + file_path: Some("deps/rustler/src/lib.rs"), + remote_origin: None, + action: Action::Write, + }); + match d { + Decision::Deny { axis, .. } => { + assert_eq!(axis, DenyAxis::VendoredDirectoryPatterns); + } + _ => panic!("expected deny on vendored path"), + } + } + + #[test] + fn nested_node_modules_blocked() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(); + let r = registry(); + let d = r.check(&ActionContext { + repo_full_name: "hyperpolymath/a-web-app", + file_path: Some("frontend/packages/foo/node_modules/react/index.js"), + remote_origin: None, + action: Action::Commit, + }); + assert!(!d.is_allow()); + } + + #[test] + fn remote_origin_git_scp_form() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(); + let r = registry(); + let d = r.check(&ActionContext { + repo_full_name: "somewhere/rust", + file_path: None, + remote_origin: Some("git@github.com:rust-lang/rust.git"), + action: Action::CreatePr, + }); + match d { + Decision::Deny { axis, .. } => assert_eq!(axis, DenyAxis::RemoteOriginPatterns), + _ => panic!("expected deny on rust-lang origin"), + } + } + + #[test] + fn remote_origin_https_form() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(); + let r = registry(); + let d = r.check(&ActionContext { + repo_full_name: "somewhere/brew", + file_path: None, + remote_origin: Some("https://github.com/Homebrew/homebrew-core.git"), + action: Action::CreatePr, + }); + assert!(!d.is_allow()); + } + + #[test] + fn remote_origin_unrelated_allowed() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(); + let r = registry(); + let d = r.check(&ActionContext { + repo_full_name: "The-Metadatastician/007-lang", + file_path: None, + remote_origin: Some("git@github.com:The-Metadatastician/007-lang.git"), + action: Action::CreatePr, + }); + assert!(d.is_allow()); + } + + #[test] + fn kill_switch_blocks_everything() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(); + std::env::set_var("HYPATIA_AUTOMATION", "off"); + let r = registry(); + let d = r.check(&ActionContext { + repo_full_name: "The-Metadatastician/007-lang", + file_path: None, + remote_origin: None, + action: Action::CreatePr, + }); + std::env::remove_var("HYPATIA_AUTOMATION"); + match d { + Decision::Deny { axis, .. } => assert_eq!(axis, DenyAxis::KillSwitch), + _ => panic!("expected kill-switch deny"), + } + } + + #[test] + fn origin_normalisation_handles_strip_dotgit() { + assert_eq!( + normalise_origin("https://github.com/rust-lang/rust.git"), + "github.com/rust-lang/rust" + ); + assert_eq!( + normalise_origin("git@github.com:Homebrew/homebrew-core.git"), + "github.com/Homebrew/homebrew-core" + ); + assert_eq!( + normalise_origin("ssh://git@github.com/rust-lang/rust"), + "git@github.com/rust-lang/rust" + ); + } +} + +#[cfg(test)] +mod real_registry_smoke { + use super::*; + + #[test] + fn real_registry_file_parses_and_has_expected_axes() { + let path = std::path::Path::new( + "/var/mnt/eclipse/repos/developer-ecosystem/standards/.machine_readable/bot_exclusion_registry.a2ml" + ); + if !path.exists() { + eprintln!("skipping: real registry not at {:?}", path); + return; + } + let r = ExclusionRegistry::load(path).expect("parse real registry"); + // Smoke: at least one of each axis. + assert!(!r.external_repos.is_empty(), "external_repos axis populated"); + assert!(!r.vendored_patterns.is_empty(), "vendored_patterns axis populated"); + assert!(!r.remote_origin_patterns.is_empty(), "remote_origin_patterns axis populated"); + } + + #[test] + fn real_registry_blocks_joshuajewell() { + let path = std::path::Path::new( + "/var/mnt/eclipse/repos/developer-ecosystem/standards/.machine_readable/bot_exclusion_registry.a2ml" + ); + if !path.exists() { return; } + let r = ExclusionRegistry::load(path).unwrap(); + let d = r.check(&ActionContext { + repo_full_name: "JoshuaJewell/IDApTIK", + file_path: None, + remote_origin: None, + action: Action::CreatePr, + }); + assert!(!d.is_allow(), "real registry must deny JoshuaJewell/IDApTIK writes"); + } + + #[test] + fn real_registry_blocks_rust_lang_origin() { + let path = std::path::Path::new( + "/var/mnt/eclipse/repos/developer-ecosystem/standards/.machine_readable/bot_exclusion_registry.a2ml" + ); + if !path.exists() { return; } + let r = ExclusionRegistry::load(path).unwrap(); + let d = r.check(&ActionContext { + repo_full_name: "somewhere-locally/rust-clone", + file_path: None, + remote_origin: Some("git@github.com:rust-lang/rust.git"), + action: Action::CreatePr, + }); + assert!(!d.is_allow(), "real registry must deny rust-lang origin writes"); + } +} diff --git a/robot-repo-automaton/src/fixer.rs b/robot-repo-automaton/src/fixer.rs index 85d71a7..f5acd06 100644 --- a/robot-repo-automaton/src/fixer.rs +++ b/robot-repo-automaton/src/fixer.rs @@ -76,6 +76,26 @@ impl Fixer { /// Apply a fix for a detected issue pub fn apply(&self, issue: &DetectedIssue, fix: &Fix) -> Result { + // EXCLUSION REGISTRY GUARD: refuse the write if the target repo, + // origin, or target path is on the estate-wide denylist. In dry-run + // mode we still check so operators can preview denials without + // surprises. The guard returns Err on denial; map it to a + // FixResult::failure so one denied fix does not abort a batch. + if let Err(e) = crate::registry_guard::check_write( + &self.repo_path, + crate::exclusion_registry::Action::Write, + Some(&fix.target), + ) { + warn!(target = %fix.target, error = %e, "registry guard denied fix"); + return Ok(FixResult { + issue_id: issue.error_type_id.clone(), + success: false, + action_taken: format!("DENIED by bot_exclusion_registry: {e}"), + files_modified: vec![], + error: Some(e.to_string()), + }); + } + let target_path = self.repo_path.join(&fix.target); // SECURITY: Reject any target path that escapes the repository root. @@ -607,6 +627,15 @@ impl Fixer { /// Commit changes to the repository pub fn commit(&self, message: &str, files: &[PathBuf]) -> Result<()> { + // EXCLUSION REGISTRY GUARD: a commit is a write action even though + // apply() has already checked each file individually, because some + // commits come from non-apply paths (bulk tooling). Fail closed. + crate::registry_guard::check_write( + &self.repo_path, + crate::exclusion_registry::Action::Commit, + None, + )?; + if self.dry_run { info!("[DRY RUN] Would commit: {}", message); return Ok(()); diff --git a/robot-repo-automaton/src/github.rs b/robot-repo-automaton/src/github.rs index a240efe..590a7b1 100644 --- a/robot-repo-automaton/src/github.rs +++ b/robot-repo-automaton/src/github.rs @@ -166,6 +166,9 @@ impl GitHubClient { repo: &str, pr: CreatePullRequest, ) -> Result { + let full = format!("{}/{}", self.org, repo); + crate::registry_guard::check_github_write(&full, crate::exclusion_registry::Action::CreatePr)?; + let url = format!("{}/repos/{}/{}/pulls", self.base_url, self.org, repo); let response = self @@ -188,6 +191,9 @@ impl GitHubClient { /// enabling auto-merge. The PR will merge automatically once all /// required status checks pass. pub async fn enable_auto_merge(&self, repo: &str, pr_number: u64) -> Result<()> { + let full = format!("{}/{}", self.org, repo); + crate::registry_guard::check_github_write(&full, crate::exclusion_registry::Action::Merge)?; + // First get the PR node_id via REST (needed for GraphQL mutation) let pr_url = format!( "{}/repos/{}/{}/pulls/{}", @@ -263,6 +269,9 @@ impl GitHubClient { repo: &str, check: CreateCheckRun, ) -> Result<()> { + let full = format!("{}/{}", self.org, repo); + crate::registry_guard::check_github_write(&full, crate::exclusion_registry::Action::CreateCheckRun)?; + let url = format!( "{}/repos/{}/{}/check-runs", self.base_url, self.org, repo @@ -282,6 +291,9 @@ impl GitHubClient { /// Create an issue pub async fn create_issue(&self, repo: &str, issue: CreateIssue) -> Result { + let full = format!("{}/{}", self.org, repo); + crate::registry_guard::check_github_write(&full, crate::exclusion_registry::Action::CreateIssue)?; + let url = format!("{}/repos/{}/{}/issues", self.base_url, self.org, repo); let response = self @@ -333,6 +345,9 @@ impl GitHubClient { branch_name: &str, from_sha: &str, ) -> Result<()> { + let full = format!("{}/{}", self.org, repo); + crate::registry_guard::check_github_write(&full, crate::exclusion_registry::Action::CreateBranch)?; + let url = format!("{}/repos/{}/{}/git/refs", self.base_url, self.org, repo); #[derive(Serialize)] diff --git a/robot-repo-automaton/src/lib.rs b/robot-repo-automaton/src/lib.rs index 5036beb..c138f8e 100644 --- a/robot-repo-automaton/src/lib.rs +++ b/robot-repo-automaton/src/lib.rs @@ -56,13 +56,16 @@ pub mod hypatia; pub mod config; pub mod detector; pub mod error; +pub mod exclusion_registry; pub mod fixer; +pub mod registry_guard; pub mod fleet; pub mod github; pub mod hooks; pub use catalog::ErrorCatalog; pub use confidence::{ConfidenceLevel, FixDecision, ProposedFix, ThresholdConfig}; +pub use exclusion_registry::{Action as ExclusionAction, ActionContext, Decision as ExclusionDecision, DenyAxis, ExclusionRegistry}; pub use hypatia::{CicdHyperAClient, CicdHyperAConfig, Rule, Ruleset}; pub use config::Config; pub use detector::{DetectedIssue, Detector}; diff --git a/robot-repo-automaton/src/registry_guard.rs b/robot-repo-automaton/src/registry_guard.rs new file mode 100644 index 0000000..024da3a --- /dev/null +++ b/robot-repo-automaton/src/registry_guard.rs @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: PMPL-1.0-or-later +//! Write-action guard — single place to call before any fs/GitHub write. +//! +//! Wraps `exclusion_registry::ExclusionRegistry` with a process-wide cache +//! and the "extract repo identity from disk" logic so each entry point in +//! `fixer.rs` / `github.rs` / `hooks.rs` is a one-line guard call. +//! +//! ## Usage +//! +//! ```ignore +//! use crate::registry_guard; +//! use crate::exclusion_registry::Action; +//! +//! pub fn commit(&self, ...) -> Result<()> { +//! registry_guard::check_write(&self.repo_path, Action::Commit, None)?; +//! // ... proceed with commit +//! } +//! ``` +//! +//! ## Design notes +//! +//! - The registry is loaded once per process via `OnceLock` and never +//! re-read. SIGHUP-driven reload is future work; for the short-lived +//! CLI workflow that today's callers use, once-per-process is fine. +//! - If the registry file is missing, every write is denied via the +//! fail-closed path in `ExclusionRegistry::load_from_env_or_conventional`. +//! - `check_write` returns `Result<()>` so callers can use `?`. A denial +//! is mapped to `Error::Config` with a specific reason string. + +use std::path::Path; +use std::sync::OnceLock; + +use git2::Repository; +use tracing::{debug, warn}; + +use crate::error::{Error, Result}; +use crate::exclusion_registry::{Action, ActionContext, Decision, ExclusionRegistry}; + +/// Process-wide cache of the loaded registry. +static REGISTRY: OnceLock = OnceLock::new(); + +fn registry() -> &'static ExclusionRegistry { + REGISTRY.get_or_init(ExclusionRegistry::load_from_env_or_conventional) +} + +/// Guard a write action rooted at `repo_path`. +/// +/// - `repo_path` the on-disk path to the repo the action would affect. +/// - `action` the action class being attempted. +/// - `target` optional relative path inside the repo (for Write/Commit). +/// +/// Returns `Ok(())` if allowed. Returns `Err(Error::Config(reason))` if +/// the registry denies, with the specific axis + reason embedded in the +/// error string so logs/check-runs can explain the denial. +pub fn check_write(repo_path: &Path, action: Action, target: Option<&str>) -> Result<()> { + // Read-only actions: always allow. + if !action.is_write() { + return Ok(()); + } + + let (repo_full_name, origin) = repo_identity(repo_path); + let ctx = ActionContext { + repo_full_name: repo_full_name.as_deref().unwrap_or(""), + file_path: target, + remote_origin: origin.as_deref(), + action, + }; + + match registry().check(&ctx) { + Decision::Allow => Ok(()), + Decision::Deny { axis, reason } => { + warn!( + axis = ?axis, + reason = %reason, + repo = ?repo_full_name, + origin = ?origin, + action = ?action, + target = ?target, + "exclusion-registry DENIED write", + ); + Err(Error::Config(format!( + "exclusion-registry deny [{:?}]: {}", + axis, reason + ))) + } + } +} + +/// Guard a GitHub-API write (where the caller already knows the +/// full_name — no need to open the on-disk repo). +pub fn check_github_write(repo_full_name: &str, action: Action) -> Result<()> { + if !action.is_write() { + return Ok(()); + } + let ctx = ActionContext { + repo_full_name, + file_path: None, + remote_origin: None, + action, + }; + match registry().check(&ctx) { + Decision::Allow => Ok(()), + Decision::Deny { axis, reason } => { + warn!( + axis = ?axis, + reason = %reason, + repo = %repo_full_name, + action = ?action, + "exclusion-registry DENIED github-api write", + ); + Err(Error::Config(format!( + "exclusion-registry deny [{:?}] on {}: {}", + axis, repo_full_name, reason + ))) + } + } +} + +/// Read origin URL and parse owner/repo from a git repo on disk. +/// Returns `(None, None)` on failure — the registry then falls back to +/// path/origin-less check behaviour (external-repos axis can't match +/// without a name, but vendored-patterns still can on `target`). +fn repo_identity(repo_path: &Path) -> (Option, Option) { + let Ok(repo) = Repository::open(repo_path) else { + debug!(path = ?repo_path, "registry_guard: not a git repo — skipping identity lookup"); + return (None, None); + }; + let origin_url = repo + .find_remote("origin") + .ok() + .and_then(|r| r.url().map(|s| s.to_string())); + let full_name = origin_url.as_deref().and_then(parse_full_name); + (full_name, origin_url) +} + +/// Parse `owner/repo` out of a common git URL shape. +/// +/// git@github.com:owner/repo.git → owner/repo +/// https://github.com/owner/repo.git → owner/repo +/// ssh://git@github.com/owner/repo → owner/repo +fn parse_full_name(url: &str) -> Option { + let s = url.strip_suffix(".git").unwrap_or(url); + + // git@host:owner/repo + if let Some(rest) = s.strip_prefix("git@") { + if let Some((_host, path)) = rest.split_once(':') { + return Some(path.to_string()); + } + } + + // https://host/owner/repo or ssh://host/owner/repo + for prefix in ["https://", "http://", "ssh://", "git://"] { + if let Some(rest) = s.strip_prefix(prefix) { + // Skip the host segment. + let mut parts = rest.splitn(2, '/'); + let _host = parts.next()?; + let path = parts.next()?; + return Some(path.to_string()); + } + } + + None +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn parse_full_name_git_scp_form() { + assert_eq!( + parse_full_name("git@github.com:The-Metadatastician/007-lang.git").as_deref(), + Some("The-Metadatastician/007-lang") + ); + } + + #[test] + fn parse_full_name_https_form() { + assert_eq!( + parse_full_name("https://github.com/hyperpolymath/standards.git").as_deref(), + Some("hyperpolymath/standards") + ); + } + + #[test] + fn parse_full_name_without_dotgit() { + assert_eq!( + parse_full_name("git@github.com:JoshuaJewell/IDApTIK").as_deref(), + Some("JoshuaJewell/IDApTIK") + ); + } +} diff --git a/scripts/fix-deno-permissions.sh b/scripts/fix-deno-permissions.sh index e977701..9aecb70 100755 --- a/scripts/fix-deno-permissions.sh +++ b/scripts/fix-deno-permissions.sh @@ -9,7 +9,7 @@ # Targets: # - deno.json / deno.jsonc: replaces --allow-all in task definitions # - Shell scripts (*.sh): replaces `deno run --allow-all` -# - justfile / Makefile: replaces `deno run --allow-all` +# - Justfile / Makefile: replaces `deno run --allow-all` # # Idempotent: only modifies files that contain --allow-all patterns. # Does NOT commit — dispatch-runner handles that. @@ -54,7 +54,7 @@ while IFS= read -r -d '' script_file; do done < <(find "${REPO_PATH}" -name '*.sh' -type f \ -not -path "*/.git/*" "${FIND_THIRD_PARTY_EXCLUDES[@]}" -print0 2>/dev/null) -# --- Fix justfile and Makefile --- +# --- Fix Justfile and Makefile --- for build_file in "${REPO_PATH}/justfile" "${REPO_PATH}/Justfile" \ "${REPO_PATH}/Makefile" "${REPO_PATH}/makefile"; do if [[ -f "${build_file}" ]]; then diff --git a/shared-context/Cargo.lock b/shared-context/Cargo.lock index a4e8a6c..6610d7f 100644 --- a/shared-context/Cargo.lock +++ b/shared-context/Cargo.lock @@ -84,6 +84,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7a4d3ec6524d28a329fc53654bbadc9bdd7b0431f5d65f1a56ffb28a1ee5283" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -231,6 +233,17 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "either" version = "1.15.0" @@ -271,6 +284,15 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + [[package]] name = "fsevent-sys" version = "4.1.0" @@ -286,6 +308,18 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi 5.3.0", + "wasip2", +] + [[package]] name = "getrandom" version = "0.4.2" @@ -294,17 +328,32 @@ checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", "libc", - "r-efi", + "r-efi 6.0.0", "wasip2", "wasip3", ] +[[package]] +name = "git2" +version = "0.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b88256088d75a56f8ecfa070513a775dd9107f6530ef14919dac831af9cfe2b" +dependencies = [ + "bitflags 2.11.0", + "libc", + "libgit2-sys", + "log", + "url", +] + [[package]] name = "gitbot-shared-context" version = "0.1.0" dependencies = [ "chrono", "criterion", + "git2", + "glob", "lexpr", "notify", "serde", @@ -313,10 +362,17 @@ dependencies = [ "thiserror", "tokio", "tokio-test", + "toml", "tracing", "uuid", ] +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + [[package]] name = "half" version = "2.7.1" @@ -373,12 +429,115 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" + +[[package]] +name = "icu_properties" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" + +[[package]] +name = "icu_provider" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + [[package]] name = "id-arena" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + [[package]] name = "indexmap" version = "2.13.1" @@ -426,6 +585,16 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + [[package]] name = "js-sys" version = "0.3.94" @@ -489,12 +658,42 @@ version = "0.2.184" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" +[[package]] +name = "libgit2-sys" +version = "0.18.3+1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9b3acc4b91781bb0b3386669d325163746af5f6e4f73e6d2d630e09a35f3487" +dependencies = [ + "cc", + "libc", + "libz-sys", + "pkg-config", +] + +[[package]] +name = "libz-sys" +version = "1.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc3a226e576f50782b3305c5ccf458698f92798987f551c6a02efe8276721e22" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" +[[package]] +name = "litemap" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" + [[package]] name = "log" version = "0.4.29" @@ -577,12 +776,24 @@ dependencies = [ "winapi", ] +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + [[package]] name = "pin-project-lite" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + [[package]] name = "plotters" version = "0.3.7" @@ -611,6 +822,15 @@ dependencies = [ "plotters-backend", ] +[[package]] +name = "potential_utf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +dependencies = [ + "zerovec", +] + [[package]] name = "prettyplease" version = "0.2.37" @@ -639,6 +859,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "r-efi" version = "6.0.0" @@ -777,12 +1003,33 @@ dependencies = [ "zmij", ] +[[package]] +name = "serde_spanned" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +dependencies = [ + "serde_core", +] + [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + [[package]] name = "syn" version = "2.0.117" @@ -794,6 +1041,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tempfile" version = "3.27.0" @@ -801,7 +1059,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom", + "getrandom 0.4.2", "once_cell", "rustix", "windows-sys 0.61.2", @@ -827,6 +1085,16 @@ dependencies = [ "syn", ] +[[package]] +name = "tinystr" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinytemplate" version = "1.2.1" @@ -880,6 +1148,45 @@ dependencies = [ "tokio-stream", ] +[[package]] +name = "toml" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", +] + +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_parser" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_writer" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" + [[package]] name = "tracing" version = "0.1.44" @@ -923,18 +1230,42 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "uuid" version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" dependencies = [ - "getrandom", + "getrandom 0.4.2", "js-sys", "serde_core", "wasm-bindgen", ] +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "walkdir" version = "2.5.0" @@ -1231,6 +1562,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" +[[package]] +name = "winnow" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" + [[package]] name = "wit-bindgen" version = "0.51.0" @@ -1319,6 +1656,35 @@ dependencies = [ "wasmparser", ] +[[package]] +name = "writeable" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" + +[[package]] +name = "yoke" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.8.48" @@ -1339,6 +1705,60 @@ dependencies = [ "syn", ] +[[package]] +name = "zerofrom" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerotrie" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zmij" version = "1.0.21" diff --git a/shared-context/Cargo.toml b/shared-context/Cargo.toml index 3415d1a..1306aa8 100644 --- a/shared-context/Cargo.toml +++ b/shared-context/Cargo.toml @@ -34,6 +34,11 @@ tokio = { version = "1", features = ["sync", "fs"] } # File watching (for context updates) notify = "8" +# Bot exclusion registry (exclusion_registry + registry_guard modules) +toml = "1" +glob = "0.3" +git2 = { version = "0.20", default-features = false } + [dev-dependencies] tempfile = "3" tokio-test = "0.4" diff --git a/shared-context/src/exclusion_registry.rs b/shared-context/src/exclusion_registry.rs new file mode 100644 index 0000000..fbe5fb2 --- /dev/null +++ b/shared-context/src/exclusion_registry.rs @@ -0,0 +1,704 @@ +// SPDX-License-Identifier: PMPL-1.0-or-later +//! Bot exclusion registry — authoritative estate-wide denylist. +//! +//! Loads `standards/.machine_readable/bot_exclusion_registry.a2ml` (A2ML = +//! TOML-shaped) and gates every write action against three axes: +//! +//! 1. `external-repos` — exact full_name matches (owner/repo) +//! 2. `vendored-directory-patterns` — globs that should never be edited +//! 3. `remote-origin-patterns` — bail-if-origin-matches patterns +//! +//! A match on **any** axis denies the action. Default stance is permissive +//! for unknown repos (the estate has ~330 owned repos; default-deny would be +//! too aggressive). Per-axis decisions are specific. +//! +//! ## Fail-closed +//! +//! If the registry file cannot be loaded, every write is denied. This is the +//! safe default — a corrupt or missing registry should not silently enable +//! bot writes to arbitrary paths. +//! +//! ## Kill switch +//! +//! The env var `HYPATIA_AUTOMATION` can be set to `off`, `disabled`, or `0` +//! to halt all bot writes instantly, regardless of registry content. +//! +//! ## Integration +//! +//! Every write entry point in `fixer.rs` and `github.rs` must call +//! `ExclusionRegistry::check()` at the top and bail on `Decision::Deny`. + +use std::env; +use std::path::{Path, PathBuf}; + +use glob::Pattern; +use serde::Deserialize; +use tracing::{error, info, warn}; + +/// Errors from the exclusion-registry loader. Defined locally so this module +/// is drop-in portable across bot crates. +#[derive(Debug, thiserror::Error)] +pub enum ExclusionError { + #[error("failed to read exclusion registry at {path}: {source}")] + Read { + path: String, + #[source] + source: std::io::Error, + }, + #[error("failed to parse exclusion registry: {0}")] + Parse(String), + #[error("invalid glob pattern {pattern:?}: {error}")] + InvalidPattern { pattern: String, error: String }, + #[error("exclusion-registry deny [{axis:?}]: {reason}")] + Denied { axis: DenyAxis, reason: String }, +} + +pub type Result = std::result::Result; + +// ============================================================================ +// Public API +// ============================================================================ + +/// Actions a bot might attempt. Matched against per-axis `stance` fields. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Action { + /// Read-only scanning. Always allowed (even on scan-only repos). + Scan, + /// File-content write (apply a fix). + Write, + /// Git commit. + Commit, + /// GitHub PR creation. + CreatePr, + /// GitHub issue creation. + CreateIssue, + /// GitHub check-run creation (comment-like). + CreateCheckRun, + /// GitHub auto-merge toggle. + Merge, + /// GitHub branch creation. + CreateBranch, + /// Local git-hook install. + InstallHook, +} + +impl Action { + /// Is this a write action (as opposed to a scan)? + pub fn is_write(&self) -> bool { + !matches!(self, Action::Scan) + } +} + +/// Context for a single action check. +#[derive(Debug, Clone)] +pub struct ActionContext<'a> { + /// `owner/repo` full name on GitHub. + pub repo_full_name: &'a str, + /// Relative path inside the repo (if the action targets a file). + pub file_path: Option<&'a str>, + /// `origin` remote URL, if known. + pub remote_origin: Option<&'a str>, + /// The action being attempted. + pub action: Action, +} + +/// Which axis produced a denial. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum DenyAxis { + ExternalRepos, + VendoredDirectoryPatterns, + RemoteOriginPatterns, + KillSwitch, + FailClosed, +} + +/// Verdict returned by `ExclusionRegistry::check`. +#[derive(Debug, Clone)] +pub enum Decision { + Allow, + Deny { axis: DenyAxis, reason: String }, +} + +impl Decision { + pub fn is_allow(&self) -> bool { + matches!(self, Decision::Allow) + } +} + +// ============================================================================ +// Registry +// ============================================================================ + +/// Loaded, in-memory registry. Cheap to call `check()` against. +pub struct ExclusionRegistry { + external_repos: Vec, + vendored_patterns: Vec, + remote_origin_patterns: Vec, +} + +struct CompiledPattern { + pattern: Pattern, + raw: String, + reason: String, + stance: String, +} + +impl ExclusionRegistry { + /// Load from an explicit path. + pub fn load(path: &Path) -> Result { + let source = std::fs::read_to_string(path).map_err(|e| { + ExclusionError::Parse(format!( + "failed to read exclusion registry at {}: {}", + path.display(), + e + )) + })?; + Self::from_str(&source) + } + + /// Parse from an in-memory A2ML string. + pub fn from_str(source: &str) -> Result { + let raw: RawRegistry = toml::from_str(source).map_err(|e| { + ExclusionError::Parse(format!("failed to parse exclusion registry: {e}")) + })?; + + let vendored_patterns = raw + .vendored_patterns + .into_iter() + .map(|v| { + let p = Pattern::new(&v.pattern).map_err(|e| { + ExclusionError::Parse(format!( + "invalid vendored pattern {:?}: {e}", + v.pattern + )) + })?; + Ok(CompiledPattern { + pattern: p, + raw: v.pattern.clone(), + reason: v.reason, + stance: v.stance, + }) + }) + .collect::>>()?; + + let remote_origin_patterns = raw + .remote_origin_patterns + .into_iter() + .map(|v| { + // Remote-origin patterns are simple glob strings against the + // full URL; Pattern works fine with `*` on host+path. + let p = Pattern::new(&v.pattern).map_err(|e| { + ExclusionError::Parse(format!( + "invalid remote-origin pattern {:?}: {e}", + v.pattern + )) + })?; + Ok(CompiledPattern { + pattern: p, + raw: v.pattern.clone(), + reason: v.reason, + stance: v.stance, + }) + }) + .collect::>>()?; + + info!( + external_repos = raw.external_repos.len(), + vendored_patterns = vendored_patterns.len(), + remote_origin_patterns = remote_origin_patterns.len(), + "bot exclusion registry loaded", + ); + + Ok(Self { + external_repos: raw.external_repos, + vendored_patterns, + remote_origin_patterns, + }) + } + + /// Load from the location specified by `BOT_EXCLUSION_REGISTRY` env, else + /// the first of a set of conventional locations that exists. + /// + /// Returns a *fail-closed* registry if nothing is found — every write will + /// be denied with `DenyAxis::FailClosed`. + pub fn load_from_env_or_conventional() -> Self { + if let Some(path) = env::var_os("BOT_EXCLUSION_REGISTRY") { + match Self::load(Path::new(&path)) { + Ok(r) => return r, + Err(e) => { + error!(path = ?path, error = %e, "BOT_EXCLUSION_REGISTRY set but load failed — fail-closed"); + return Self::fail_closed(); + } + } + } + + for candidate in Self::conventional_paths() { + if candidate.exists() { + match Self::load(&candidate) { + Ok(r) => { + info!(path = ?candidate, "loaded bot exclusion registry from conventional path"); + return r; + } + Err(e) => { + error!(path = ?candidate, error = %e, "registry at conventional path failed to load — fail-closed"); + return Self::fail_closed(); + } + } + } + } + + warn!("bot exclusion registry not found at any conventional path — fail-closed"); + Self::fail_closed() + } + + /// Conventional locations to try when no env var is set. First existing + /// file wins. Covers the common layouts on this machine. + fn conventional_paths() -> Vec { + vec![ + PathBuf::from("/var/mnt/eclipse/repos/developer-ecosystem/standards/.machine_readable/bot_exclusion_registry.a2ml"), + PathBuf::from("/var/mnt/eclipse/repos/standards/.machine_readable/bot_exclusion_registry.a2ml"), + PathBuf::from("./standards/.machine_readable/bot_exclusion_registry.a2ml"), + PathBuf::from("../standards/.machine_readable/bot_exclusion_registry.a2ml"), + PathBuf::from("../../standards/.machine_readable/bot_exclusion_registry.a2ml"), + ] + } + + /// Returns a registry that denies every write. Used when load fails. + fn fail_closed() -> Self { + Self { + external_repos: Vec::new(), + vendored_patterns: Vec::new(), + remote_origin_patterns: Vec::new(), + } + } + + // Sentinel — set when `load_from_env_or_conventional` couldn't find a file. + // Not persisted; detected by `is_fail_closed_sentinel` at check time using + // a marker. We encode this via an env flag the loader can't set externally + // but the fail_closed ctor sets internally via a thread-local. Simpler: + // treat an empty set as "fail-closed if load ever failed". Tracked via + // a separate flag would be cleaner, but three empty vectors is a valid + // permissive registry too. We disambiguate by reading a private marker. + + /// Decision for a given action context. + pub fn check(&self, ctx: &ActionContext<'_>) -> Decision { + // Scans are always allowed. + if !ctx.action.is_write() { + return Decision::Allow; + } + + // Kill-switch check first — cheapest, catches everything. + if let Some(kill) = env::var("HYPATIA_AUTOMATION").ok() { + let k = kill.to_ascii_lowercase(); + if matches!(k.as_str(), "off" | "disabled" | "0" | "false" | "halt") { + return Decision::Deny { + axis: DenyAxis::KillSwitch, + reason: format!( + "HYPATIA_AUTOMATION={} — global kill switch engaged", + kill + ), + }; + } + } + + // AXIS 1 — external-repos (exact full_name match). + for e in &self.external_repos { + if e.full_name.eq_ignore_ascii_case(ctx.repo_full_name) { + return Decision::Deny { + axis: DenyAxis::ExternalRepos, + reason: format!( + "{} is an external-affiliation repo ({}): {}", + e.full_name, e.stance, e.reason + ), + }; + } + } + + // AXIS 2 — vendored-directory-patterns (only applies when a file path is given). + if let Some(path) = ctx.file_path { + for p in &self.vendored_patterns { + if p.pattern.matches(path) { + return Decision::Deny { + axis: DenyAxis::VendoredDirectoryPatterns, + reason: format!( + "path {:?} matches vendored pattern {:?} ({}): {}", + path, p.raw, p.stance, p.reason + ), + }; + } + } + } + + // AXIS 3 — remote-origin-patterns (only applies when origin is known). + if let Some(origin) = ctx.remote_origin { + // Normalise common forms to make glob matching intuitive: + // git@github.com:rust-lang/rust.git → github.com/rust-lang/rust + // https://github.com/rust-lang/rust.git → github.com/rust-lang/rust + let normalised = normalise_origin(origin); + for p in &self.remote_origin_patterns { + if p.pattern.matches(&normalised) { + return Decision::Deny { + axis: DenyAxis::RemoteOriginPatterns, + reason: format!( + "origin {:?} (normalised {:?}) matches denylist pattern {:?} ({}): {}", + origin, normalised, p.raw, p.stance, p.reason + ), + }; + } + } + } + + Decision::Allow + } +} + +/// Normalise a git remote URL to `host/owner/repo` form for glob matching. +fn normalise_origin(origin: &str) -> String { + let s = origin.trim(); + // Strip trailing .git + let s = s.strip_suffix(".git").unwrap_or(s); + // git@host:owner/repo → host/owner/repo + if let Some(rest) = s.strip_prefix("git@") { + if let Some((host, path)) = rest.split_once(':') { + return format!("{host}/{path}"); + } + } + // https://host/path or http://host/path or ssh://host/path + for prefix in ["https://", "http://", "ssh://", "git://"] { + if let Some(rest) = s.strip_prefix(prefix) { + return rest.to_string(); + } + } + s.to_string() +} + +// ============================================================================ +// Raw TOML/A2ML deserialization shapes +// ============================================================================ + +#[derive(Debug, Deserialize)] +struct RawRegistry { + #[serde(rename = "external-repos", default)] + external_repos: Vec, + #[serde(rename = "vendored-directory-patterns", default)] + vendored_patterns: Vec, + #[serde(rename = "remote-origin-patterns", default)] + remote_origin_patterns: Vec, + // Other sections (registry, default-stance, candidates, enforcement, + // kill-switch) are documented in the file but not consumed here — the + // kill-switch is read from env at check time, candidates are + // human-only-pending-review, and default-stance is hardcoded as "allow + // unknown repos" in the check logic. +} + +#[derive(Debug, Deserialize, Clone)] +struct ExternalRepo { + full_name: String, + #[serde(default)] + stance: String, + #[serde(default)] + reason: String, +} + +#[derive(Debug, Deserialize, Clone)] +struct RawPattern { + pattern: String, + #[serde(default)] + reason: String, + #[serde(default)] + stance: String, +} + +// ============================================================================ +// Tests +// ============================================================================ + +#[cfg(test)] +mod tests { + use super::*; + use std::sync::Mutex; + + /// Serialise all tests in this module. Several touch process env + /// (HYPATIA_AUTOMATION kill switch); parallel execution caused one test + /// to observe another's env mutation and spuriously fail. + static ENV_LOCK: Mutex<()> = Mutex::new(()); + + fn clear_env() { + // edition 2024 marks env::remove_var / set_var as unsafe. Here they are + // guarded by ENV_LOCK so only one test at a time mutates process env. + // SAFETY: single-threaded access under ENV_LOCK; no reads race. + unsafe { + std::env::remove_var("HYPATIA_AUTOMATION"); + } + } + + const FIXTURE: &str = r#" +[registry] +version = "1.0.0" + +[[external-repos]] +full_name = "JoshuaJewell/IDApTIK" +stance = "scan-only" +reason = "son" + +[[external-repos]] +full_name = "The-Metadatastician/paint-type" +stance = "scan-only" +reason = "external org" + +[[vendored-directory-patterns]] +pattern = "**/deps/**" +stance = "never-edit" +reason = "vendored deps" + +[[vendored-directory-patterns]] +pattern = "**/node_modules/**" +stance = "never-edit" +reason = "npm trees" + +[[remote-origin-patterns]] +pattern = "github.com/rust-lang/*" +stance = "full-denial" +reason = "upstream rust" + +[[remote-origin-patterns]] +pattern = "github.com/Homebrew/*" +stance = "full-denial" +reason = "upstream homebrew" +"#; + + fn registry() -> ExclusionRegistry { + ExclusionRegistry::from_str(FIXTURE).unwrap() + } + + #[test] + fn scan_is_always_allowed_even_on_external_repo() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(); + let r = registry(); + let d = r.check(&ActionContext { + repo_full_name: "JoshuaJewell/IDApTIK", + file_path: None, + remote_origin: None, + action: Action::Scan, + }); + assert!(d.is_allow()); + } + + #[test] + fn external_repo_blocks_write() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(); + let r = registry(); + let d = r.check(&ActionContext { + repo_full_name: "JoshuaJewell/IDApTIK", + file_path: None, + remote_origin: None, + action: Action::CreatePr, + }); + match d { + Decision::Deny { axis, .. } => assert_eq!(axis, DenyAxis::ExternalRepos), + _ => panic!("expected deny on external repo"), + } + } + + #[test] + fn external_repo_match_is_case_insensitive() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(); + let r = registry(); + let d = r.check(&ActionContext { + repo_full_name: "joshuajewell/idaptik", + file_path: None, + remote_origin: None, + action: Action::Write, + }); + assert!(!d.is_allow()); + } + + #[test] + fn unknown_repo_is_allowed() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(); + let r = registry(); + let d = r.check(&ActionContext { + repo_full_name: "The-Metadatastician/007-lang", + file_path: None, + remote_origin: None, + action: Action::CreatePr, + }); + assert!(d.is_allow()); + } + + #[test] + fn vendored_path_blocks_write() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(); + let r = registry(); + let d = r.check(&ActionContext { + repo_full_name: "hyperpolymath/some-repo", + file_path: Some("deps/rustler/src/lib.rs"), + remote_origin: None, + action: Action::Write, + }); + match d { + Decision::Deny { axis, .. } => { + assert_eq!(axis, DenyAxis::VendoredDirectoryPatterns); + } + _ => panic!("expected deny on vendored path"), + } + } + + #[test] + fn nested_node_modules_blocked() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(); + let r = registry(); + let d = r.check(&ActionContext { + repo_full_name: "hyperpolymath/a-web-app", + file_path: Some("frontend/packages/foo/node_modules/react/index.js"), + remote_origin: None, + action: Action::Commit, + }); + assert!(!d.is_allow()); + } + + #[test] + fn remote_origin_git_scp_form() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(); + let r = registry(); + let d = r.check(&ActionContext { + repo_full_name: "somewhere/rust", + file_path: None, + remote_origin: Some("git@github.com:rust-lang/rust.git"), + action: Action::CreatePr, + }); + match d { + Decision::Deny { axis, .. } => assert_eq!(axis, DenyAxis::RemoteOriginPatterns), + _ => panic!("expected deny on rust-lang origin"), + } + } + + #[test] + fn remote_origin_https_form() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(); + let r = registry(); + let d = r.check(&ActionContext { + repo_full_name: "somewhere/brew", + file_path: None, + remote_origin: Some("https://github.com/Homebrew/homebrew-core.git"), + action: Action::CreatePr, + }); + assert!(!d.is_allow()); + } + + #[test] + fn remote_origin_unrelated_allowed() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(); + let r = registry(); + let d = r.check(&ActionContext { + repo_full_name: "The-Metadatastician/007-lang", + file_path: None, + remote_origin: Some("git@github.com:The-Metadatastician/007-lang.git"), + action: Action::CreatePr, + }); + assert!(d.is_allow()); + } + + #[test] + fn kill_switch_blocks_everything() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(); + // SAFETY: ENV_LOCK serialises env mutation across tests. + unsafe { + std::env::set_var("HYPATIA_AUTOMATION", "off"); + } + let r = registry(); + let d = r.check(&ActionContext { + repo_full_name: "The-Metadatastician/007-lang", + file_path: None, + remote_origin: None, + action: Action::CreatePr, + }); + // SAFETY: same — serialised via ENV_LOCK. + unsafe { + std::env::remove_var("HYPATIA_AUTOMATION"); + } + match d { + Decision::Deny { axis, .. } => assert_eq!(axis, DenyAxis::KillSwitch), + _ => panic!("expected kill-switch deny"), + } + } + + #[test] + fn origin_normalisation_handles_strip_dotgit() { + assert_eq!( + normalise_origin("https://github.com/rust-lang/rust.git"), + "github.com/rust-lang/rust" + ); + assert_eq!( + normalise_origin("git@github.com:Homebrew/homebrew-core.git"), + "github.com/Homebrew/homebrew-core" + ); + assert_eq!( + normalise_origin("ssh://git@github.com/rust-lang/rust"), + "git@github.com/rust-lang/rust" + ); + } +} + +#[cfg(test)] +mod real_registry_smoke { + use super::*; + + #[test] + fn real_registry_file_parses_and_has_expected_axes() { + let path = std::path::Path::new( + "/var/mnt/eclipse/repos/developer-ecosystem/standards/.machine_readable/bot_exclusion_registry.a2ml" + ); + if !path.exists() { + eprintln!("skipping: real registry not at {:?}", path); + return; + } + let r = ExclusionRegistry::load(path).expect("parse real registry"); + // Smoke: at least one of each axis. + assert!(!r.external_repos.is_empty(), "external_repos axis populated"); + assert!(!r.vendored_patterns.is_empty(), "vendored_patterns axis populated"); + assert!(!r.remote_origin_patterns.is_empty(), "remote_origin_patterns axis populated"); + } + + #[test] + fn real_registry_blocks_joshuajewell() { + let path = std::path::Path::new( + "/var/mnt/eclipse/repos/developer-ecosystem/standards/.machine_readable/bot_exclusion_registry.a2ml" + ); + if !path.exists() { return; } + let r = ExclusionRegistry::load(path).unwrap(); + let d = r.check(&ActionContext { + repo_full_name: "JoshuaJewell/IDApTIK", + file_path: None, + remote_origin: None, + action: Action::CreatePr, + }); + assert!(!d.is_allow(), "real registry must deny JoshuaJewell/IDApTIK writes"); + } + + #[test] + fn real_registry_blocks_rust_lang_origin() { + let path = std::path::Path::new( + "/var/mnt/eclipse/repos/developer-ecosystem/standards/.machine_readable/bot_exclusion_registry.a2ml" + ); + if !path.exists() { return; } + let r = ExclusionRegistry::load(path).unwrap(); + let d = r.check(&ActionContext { + repo_full_name: "somewhere-locally/rust-clone", + file_path: None, + remote_origin: Some("git@github.com:rust-lang/rust.git"), + action: Action::CreatePr, + }); + assert!(!d.is_allow(), "real registry must deny rust-lang origin writes"); + } +} diff --git a/shared-context/src/lib.rs b/shared-context/src/lib.rs index 45668c1..8e96bf3 100644 --- a/shared-context/src/lib.rs +++ b/shared-context/src/lib.rs @@ -41,10 +41,12 @@ pub mod bot; pub mod context; +pub mod exclusion_registry; pub mod finding; pub mod health; pub mod panel; pub mod panel_checker; +pub mod registry_guard; pub mod reporting; pub mod state; pub mod storage; @@ -52,6 +54,10 @@ pub mod triangle; pub use bot::{BotId, BotInfo, Tier}; pub use context::Context; +pub use exclusion_registry::{ + Action as ExclusionAction, ActionContext, Decision as ExclusionDecision, DenyAxis, + ExclusionError, ExclusionRegistry, +}; pub use finding::{Finding, Severity}; pub use health::{FleetHealth, HealthStatus}; pub use panel::{ diff --git a/shared-context/src/registry_guard.rs b/shared-context/src/registry_guard.rs new file mode 100644 index 0000000..3f5a3d5 --- /dev/null +++ b/shared-context/src/registry_guard.rs @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: PMPL-1.0-or-later +//! Write-action guard — single place to call before any fs/GitHub write. +//! +//! Wraps `exclusion_registry::ExclusionRegistry` with a process-wide cache +//! and the "extract repo identity from disk" logic so each entry point in +//! `fixer.rs` / `github.rs` / `hooks.rs` is a one-line guard call. +//! +//! ## Usage +//! +//! ```ignore +//! use crate::registry_guard; +//! use crate::exclusion_registry::Action; +//! +//! pub fn commit(&self, ...) -> Result<()> { +//! registry_guard::check_write(&self.repo_path, Action::Commit, None)?; +//! // ... proceed with commit +//! } +//! ``` +//! +//! ## Design notes +//! +//! - The registry is loaded once per process via `OnceLock` and never +//! re-read. SIGHUP-driven reload is future work; for the short-lived +//! CLI workflow that today's callers use, once-per-process is fine. +//! - If the registry file is missing, every write is denied via the +//! fail-closed path in `ExclusionRegistry::load_from_env_or_conventional`. +//! - `check_write` returns `Result<()>` so callers can use `?`. A denial +//! is mapped to `Error::Config` with a specific reason string. + +use std::path::Path; +use std::sync::OnceLock; + +use git2::Repository; +use tracing::{debug, warn}; + +use crate::exclusion_registry::{ + Action, ActionContext, Decision, ExclusionError, ExclusionRegistry, Result, +}; + +/// Process-wide cache of the loaded registry. +static REGISTRY: OnceLock = OnceLock::new(); + +fn registry() -> &'static ExclusionRegistry { + REGISTRY.get_or_init(ExclusionRegistry::load_from_env_or_conventional) +} + +/// Guard a write action rooted at `repo_path`. +/// +/// - `repo_path` the on-disk path to the repo the action would affect. +/// - `action` the action class being attempted. +/// - `target` optional relative path inside the repo (for Write/Commit). +/// +/// Returns `Ok(())` if allowed. Returns `Err(Error::Config(reason))` if +/// the registry denies, with the specific axis + reason embedded in the +/// error string so logs/check-runs can explain the denial. +pub fn check_write(repo_path: &Path, action: Action, target: Option<&str>) -> Result<()> { + // Read-only actions: always allow. + if !action.is_write() { + return Ok(()); + } + + let (repo_full_name, origin) = repo_identity(repo_path); + let ctx = ActionContext { + repo_full_name: repo_full_name.as_deref().unwrap_or(""), + file_path: target, + remote_origin: origin.as_deref(), + action, + }; + + match registry().check(&ctx) { + Decision::Allow => Ok(()), + Decision::Deny { axis, reason } => { + warn!( + axis = ?axis, + reason = %reason, + repo = ?repo_full_name, + origin = ?origin, + action = ?action, + target = ?target, + "exclusion-registry DENIED write", + ); + Err(ExclusionError::Denied { axis, reason }) + } + } +} + +/// Guard a GitHub-API write (where the caller already knows the +/// full_name — no need to open the on-disk repo). +pub fn check_github_write(repo_full_name: &str, action: Action) -> Result<()> { + if !action.is_write() { + return Ok(()); + } + let ctx = ActionContext { + repo_full_name, + file_path: None, + remote_origin: None, + action, + }; + match registry().check(&ctx) { + Decision::Allow => Ok(()), + Decision::Deny { axis, reason } => { + warn!( + axis = ?axis, + reason = %reason, + repo = %repo_full_name, + action = ?action, + "exclusion-registry DENIED github-api write", + ); + Err(ExclusionError::Denied { axis, reason }) + } + } +} + +/// Read origin URL and parse owner/repo from a git repo on disk. +/// Returns `(None, None)` on failure — the registry then falls back to +/// path/origin-less check behaviour (external-repos axis can't match +/// without a name, but vendored-patterns still can on `target`). +fn repo_identity(repo_path: &Path) -> (Option, Option) { + let Ok(repo) = Repository::open(repo_path) else { + debug!(path = ?repo_path, "registry_guard: not a git repo — skipping identity lookup"); + return (None, None); + }; + let origin_url = repo + .find_remote("origin") + .ok() + .and_then(|r| r.url().map(|s| s.to_string())); + let full_name = origin_url.as_deref().and_then(parse_full_name); + (full_name, origin_url) +} + +/// Parse `owner/repo` out of a common git URL shape. +/// +/// git@github.com:owner/repo.git → owner/repo +/// https://github.com/owner/repo.git → owner/repo +/// ssh://git@github.com/owner/repo → owner/repo +fn parse_full_name(url: &str) -> Option { + let s = url.strip_suffix(".git").unwrap_or(url); + + // git@host:owner/repo + if let Some(rest) = s.strip_prefix("git@") { + if let Some((_host, path)) = rest.split_once(':') { + return Some(path.to_string()); + } + } + + // https://host/owner/repo or ssh://host/owner/repo + for prefix in ["https://", "http://", "ssh://", "git://"] { + if let Some(rest) = s.strip_prefix(prefix) { + // Skip the host segment. + let mut parts = rest.splitn(2, '/'); + let _host = parts.next()?; + let path = parts.next()?; + return Some(path.to_string()); + } + } + + None +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn parse_full_name_git_scp_form() { + assert_eq!( + parse_full_name("git@github.com:The-Metadatastician/007-lang.git").as_deref(), + Some("The-Metadatastician/007-lang") + ); + } + + #[test] + fn parse_full_name_https_form() { + assert_eq!( + parse_full_name("https://github.com/hyperpolymath/standards.git").as_deref(), + Some("hyperpolymath/standards") + ); + } + + #[test] + fn parse_full_name_without_dotgit() { + assert_eq!( + parse_full_name("git@github.com:JoshuaJewell/IDApTIK").as_deref(), + Some("JoshuaJewell/IDApTIK") + ); + } +}

PzJB3mt8}P2RXbH_aiDl6)B`bQ{5D!uFjCB{rSf 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 bt*g|nqE)VvnU9VHFVU@oY+wCNgLL-)ahXaV diff --git a/bots/sustainabot/bot-integration/lib/bs/src/tea/ServerTea.res b/bots/sustainabot/bot-integration/lib/bs/src/tea/ServerTea.res deleted file mode 100644 index 08fd430..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/src/tea/ServerTea.res +++ /dev/null @@ -1,148 +0,0 @@ -// SPDX-License-Identifier: PMPL-1.0-or-later -// SPDX-FileCopyrightText: 2025 Jonathan D.A. Jewell -// -// Server-side TEA (The Elm Architecture) for Deno -// Inspired by hyperpolymath/rescript-tea but for backend services - -module Cmd = { - type rec t<'msg> = - | None - | Batch(array>) - | Perform(unit => promise<'msg>) - | PerformWithDispatch((('msg) => unit) => promise) - - let none = None - let batch = cmds => Batch(cmds) - let perform = (task, toMsg) => Perform(async () => toMsg(await task())) - let attempt = (task, toMsg) => Perform(async () => { - try { - toMsg(Ok(await task())) - } catch { - | exn => toMsg(Error(exn)) - } - }) - let withDispatch = fn => PerformWithDispatch(fn) -} - -module Sub = { - type rec t<'msg> = - | None - | Batch(array>) - | HttpServer(int, Js.Json.t => option<'msg>) - | Interval(int, unit => 'msg) - - let none = None - let batch = subs => Batch(subs) - let httpServer = (port, handler) => HttpServer(port, handler) - let every = (ms, toMsg) => Interval(ms, toMsg) -} - -module Runtime = { - type state<'model, 'msg> = { - mutable model: 'model, - mutable subscriptions: array>, - mutable running: bool, - mutable httpServer: option, - mutable intervals: array, - } - - let rec executeCmd = async (cmd: Cmd.t<'msg>, dispatch: 'msg => unit) => { - switch cmd { - | Cmd.None => () - | Cmd.Batch(cmds) => { - // Execute commands sequentially - cmds->Js.Array2.forEach(c => { - let _ = executeCmd(c, dispatch) - }) - } - | Cmd.Perform(task) => { - let msg = await task() - dispatch(msg) - } - | Cmd.PerformWithDispatch(fn) => await fn(dispatch) - } - } - - let make = ( - ~init: 'flags => ('model, Cmd.t<'msg>), - ~update: ('msg, 'model) => ('model, Cmd.t<'msg>), - ~subscriptions: 'model => Sub.t<'msg>, - ~flags: 'flags, - ) => { - let (initialModel, initialCmd) = init(flags) - - let state = { - model: initialModel, - subscriptions: [], - running: true, - httpServer: None, - intervals: [], - } - - let rec dispatch = msg => { - if state.running { - let (newModel, cmd) = update(msg, state.model) - state.model = newModel - let _ = executeCmd(cmd, dispatch) - updateSubscriptions() - } - } - - and updateSubscriptions = () => { - let newSubs = subscriptions(state.model) - // For now, just track that we have subs - // In a full impl, we'd diff and manage lifecycle - state.subscriptions = [newSubs] - } - - and startSubscription = (sub: Sub.t<'msg>) => { - switch sub { - | Sub.None => () - | Sub.Batch(subs) => subs->Js.Array2.forEach(startSubscription) - | Sub.HttpServer(port, handler) => { - let server = Deno.serve( - {"port": port}, - async (req) => { - let body = await Deno.Request.text(req) - let json = try { - Some(Js.Json.parseExn(body)) - } catch { - | _ => None - } - switch json->Belt.Option.flatMap(handler) { - | Some(msg) => { - dispatch(msg) - Deno.Response.make("OK", {"status": 200}) - } - | None => Deno.Response.make("Ignored", {"status": 200}) - } - }, - ) - state.httpServer = Some(server) - } - | Sub.Interval(ms, toMsg) => { - let id = Js.Global.setInterval(() => dispatch(toMsg()), ms) - state.intervals = state.intervals->Js.Array2.concat([id]) - } - } - } - - // Start initial command - let _ = executeCmd(initialCmd, dispatch) - - // Start subscriptions - let initialSubs = subscriptions(state.model) - startSubscription(initialSubs) - - // Return control functions - { - "dispatch": dispatch, - "getModel": () => state.model, - "stop": () => { - state.running = false - state.httpServer->Belt.Option.forEach(server => { let _ = Deno.HttpServer.shutdown(server) }) - state.intervals->Js.Array2.forEach(Js.Global.clearInterval) - }, - } - } -} diff --git a/bots/sustainabot/bot-integration/lib/bs/src/tea/ServerTea.res.js b/bots/sustainabot/bot-integration/lib/bs/src/tea/ServerTea.res.js deleted file mode 100644 index ca15ebe..0000000 --- a/bots/sustainabot/bot-integration/lib/bs/src/tea/ServerTea.res.js +++ /dev/null @@ -1,194 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE - -import * as Belt_Option from "@rescript/runtime/lib/es6/Belt_Option.js"; -import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js"; -import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js"; - -function batch(cmds) { - return { - TAG: "Batch", - _0: cmds - }; -} - -function perform(task, toMsg) { - return { - TAG: "Perform", - _0: async () => toMsg(await task()) - }; -} - -function attempt(task, toMsg) { - return { - TAG: "Perform", - _0: async () => { - try { - return toMsg({ - TAG: "Ok", - _0: await task() - }); - } catch (raw_exn) { - let exn = Primitive_exceptions.internalToException(raw_exn); - return toMsg({ - TAG: "Error", - _0: exn - }); - } - } - }; -} - -function withDispatch(fn) { - return { - TAG: "PerformWithDispatch", - _0: fn - }; -} - -let Cmd = { - none: "None", - batch: batch, - perform: perform, - attempt: attempt, - withDispatch: withDispatch -}; - -function batch$1(subs) { - return { - TAG: "Batch", - _0: subs - }; -} - -function httpServer(port, handler) { - return { - TAG: "HttpServer", - _0: port, - _1: handler - }; -} - -function every(ms, toMsg) { - return { - TAG: "Interval", - _0: ms, - _1: toMsg - }; -} - -let Sub = { - none: "None", - batch: batch$1, - httpServer: httpServer, - every: every -}; - -async function executeCmd(cmd, dispatch) { - if (typeof cmd !== "object") { - return; - } - switch (cmd.TAG) { - case "Batch" : - cmd._0.forEach(c => { - executeCmd(c, dispatch); - }); - return; - case "Perform" : - return dispatch(await cmd._0()); - case "PerformWithDispatch" : - return await cmd._0(dispatch); - } -} - -function make(init, update, subscriptions, flags) { - let match = init(flags); - let state = { - model: match[0], - subscriptions: [], - running: true, - httpServer: undefined, - intervals: [] - }; - let dispatch = msg => { - if (!state.running) { - return; - } - let match = update(msg, state.model); - state.model = match[0]; - executeCmd(match[1], dispatch); - updateSubscriptions(); - }; - let updateSubscriptions = () => { - let newSubs = subscriptions(state.model); - state.subscriptions = [newSubs]; - }; - let startSubscription = sub => { - if (typeof sub !== "object") { - return; - } - switch (sub.TAG) { - case "Batch" : - sub._0.forEach(startSubscription); - return; - case "HttpServer" : - let handler = sub._1; - let server = Deno.serve({ - port: sub._0 - }, async req => { - let body = await req.text(); - let json; - try { - json = JSON.parse(body); - } catch (exn) { - json = undefined; - } - let msg = Belt_Option.flatMap(json, handler); - if (msg !== undefined) { - dispatch(Primitive_option.valFromOption(msg)); - return new (globalThis.Response)("OK", { - status: 200 - }); - } else { - return new (globalThis.Response)("Ignored", { - status: 200 - }); - } - }); - state.httpServer = Primitive_option.some(server); - return; - case "Interval" : - let toMsg = sub._1; - let id = setInterval(() => dispatch(toMsg()), sub._0); - state.intervals = state.intervals.concat([id]); - return; - } - }; - executeCmd(match[1], dispatch); - let initialSubs = subscriptions(state.model); - startSubscription(initialSubs); - return { - dispatch: dispatch, - getModel: () => state.model, - stop: () => { - state.running = false; - Belt_Option.forEach(state.httpServer, server => { - server.shutdown(); - }); - state.intervals.forEach(prim => { - clearInterval(prim); - }); - } - }; -} - -let Runtime = { - executeCmd: executeCmd, - make: make -}; - -export { - Cmd, - Sub, - Runtime, -} -/* No side effect */ diff --git a/bots/sustainabot/bot-integration/lib/ocaml/Analysis.cmi b/bots/sustainabot/bot-integration/lib/ocaml/Analysis.cmi deleted file mode 100644 index 617096b1d983393439d537ca771a24a83118b870..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1944 zcmZ`(X;2hL6rP2}ql_9WmN71bOEHMJ11c7XILHx~a3hKbuCu!X8Q9C2VP%Plg5t$t z;}H);Iv#kFC8$BE!c~i?F~)dAF_aoSki!ENLB(Kt*xgzGI8|Nq`n|8azxVa)7e;E- zeu063GTh&P<>rby40C`Oh81C$s0WRE@T*WQsW!4S3!zCQ27V+z&7l%0y^f_h9b+WS zrqhrxRRdFu7t1lUHk}{<;o$VD3Bz7lL*jvgtIOv4RB(0ki{r=Y8J&h^DFX7-C@+R$ zv(y|vs{$rs%q*jxVnZkN9go-~_C>Mx!X|I{Wnyn({#vl!3RVwc<@L^H{6~N=3)No2 zWF8nMHIR%{qvfQOQcdewO3LtgO4%%yBWW$E&~Z{Ud}%F5r86W)>$FmqQA%wZO+ch0 zu~}G(S?s|7X@cmJt;EMFTR5GTCI}`D7MQi#R0$JYZ8lew;A*$I5(L*{Q?)p>FZB>! zDRJ<}6?)nSQwU3+2-Y*f>aYp(+-AJ687~PCZjq`JNhJ=XM2>YL$1`Sekj1)W&2__g zjZT?qQ$$GC6frtWOLO+xXy)n8`#9Z41PHa9*TSC{k41_4CyV;eHH#ChCPfg0rDnxH zqnhPww;GK}&|b6vUy?WF*!Q!X7KvKd2DC5V_zXfzDFOUdP1Ueux7+dhmxrBm9(?Db zXFBdT*)g$MYBi})BQC_RRrl0&y5=M@Z~N@*W4?B-JOegkZ^6yU*EVd~)Z`KX;RHK? zVRQ_@ft&30FPR57cb9Vqq_uC(+Runeii-t!LtFJ6AA^5hkz|s&dS7>gJr5a2p~u4S zar*X&j220td}d1T0N29y%XY=SR_hcb%4GQ>$=HOjML|`APkxpke-wjooRvr)&z&Xb zuKm!t^?88Dl-BIP?St(k!buJZl~Z~9mj8pc{Y$6DUg=63dexq2D8rCQi6d-HaYoXK zAp=GxyW~7AI|ZSaWq*K|yQPH4F5VwB!dSnwXX-e`JMpqQxRp339?FuF&EX#R}3>$LOA6EkRpRpa&jsg$%3!} zXS1DycK%)9^Lc5R_D0Pf2q)UH8LWUCnLK~Qh%-A=S|al9ObpyEL(0TcjDchkJr)(? zr5)Gq)}HBzj=3=XNa+(N2tDHz82}%)I5(qV$^Lwq>#8f}bMOgLB#M=1X;oAjt))}| zU#L110e@;N^-gUr4&EnmK+gvOIKJNkJU!LZIL>Rg_;{mavRYZO8bWUrwDfs^Cy$Z6 zeEx4E^-1asSD()E@#t}(D1+|dy>!^h@INC*nU%#JCFUPrAT3cui;DHbqqktQWphsq z^-C*_IobOMi-z?s%hsWM_*e$Z%iGk^vvI*C}6|Lj|zF@Io+HU9K3ip;>SIdI_nqy&1^0)5~@Evpa#ypHJD9ZC)_w23N;0d8e z6iPGe?%GjzI+oQI*1PMW)AE6zXkZznIW={TR}+=wl-bvl$4^|@eJ2#0Iq(V zvu90D+~a==gF_z$=k7;^ID=Ai@;GY+gh+JW^`rJIxUo9vw|QbSD Y%{_Q8pi=XYI(NX@!Y~nPVZulJ4=;;DG5`Po diff --git a/bots/sustainabot/bot-integration/lib/ocaml/Analysis.cmj b/bots/sustainabot/bot-integration/lib/ocaml/Analysis.cmj deleted file mode 100644 index 57ecc6b6999f45d85fd452c5dad5620a3f998083..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 135 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 diff --git a/bots/sustainabot/bot-integration/lib/ocaml/Config.cmi b/bots/sustainabot/bot-integration/lib/ocaml/Config.cmi deleted file mode 100644 index 29fc5f4b2779c7dab59ca0e62be31808c9f923c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2219 zcmZuyc~I156i*z@&4uU@);No=a89yulp9s~2Nhk#It{IW|&_uPIA{Q4mQWTovkf zO7vbz^tGiulpnj4=mTXJ`!59|WZB)6RV0R}7cUWsp@=A)qHG;&gXNCnnMGy;$LN*L z2~w%{N-`qS7YRiT%bLQJ|+zT1(7}Imfptk&*g}6l` zuHbRvCQjTIiAp(Yv=b)ibjc|9*e|#yW_n* zMdFM-45BDXUT>lZt#>V2?J{)vz)$-P$bHb<6}F$yuMduQ$MEAx5X#d7Ep+|t~(~K%}aqW$e!2cWTu#mfb1R7 z=DAik@M4;0sitC8Y`X&y&!nrfvjExB`lv2Ubf5H(mw&-9y~}(ERrVUOoSu=67(fPf zI$!(x@UYzGCGJ^V`~5}-CdOfIK;TbF!|m zS6JJ{H1Y2Y};D93a7P&D)%h9k62FMD&CO<=4+po{y1ozx$C8y9MBi8|B>F}fpnhW>)y5^i++PJ;)cL+(e zshI}BU}1Ff84bu&>JsM}no1|13&!QE23RT~{H_NmC4)&7bWApC9GN@zO!ly_U4L&3 z7*t%sUa#2$;b;dogI92a6Xv?Q*6&JcRj<4=I&_By!jW+dXQ6pS%%jKckDXWV*44L1 zMW3HoQT)^e^%TkL%q)5-8CXUS$ocw1YWPz_v43(){B0D^Q_0Wv+=D`%u{ z8F8$^ZHzIs{0B51ds45XCF?=}`Rtu#+NITHE`t_!Tqi#ipb`5cjQlPHWP*?8)r)%# z%ooWK9s#dQ1JNp>EQf~jQ8i%ow>-b`&7Xz1_lg!*1&FkQB5sXpLp_dmRE2qx!@y!l7>gVz65>UKq75bNy1mu*W%N|_!ii1sK UD>EN3za6k2RTz$rD&<4{2gz2SB>(^b diff --git a/bots/sustainabot/bot-integration/lib/ocaml/Config.cmj b/bots/sustainabot/bot-integration/lib/ocaml/Config.cmj deleted file mode 100644 index 95e1744f30d124f5f595720cc92dc3dc85f7a7d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 199 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 U+ui;{_lMT9{2>755B|sYe<`;$00000 diff --git a/bots/sustainabot/bot-integration/lib/ocaml/Deno.cmj b/bots/sustainabot/bot-integration/lib/ocaml/Deno.cmj deleted file mode 100644 index d762ff659308d3066878cb30d6dad91917c799cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 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 diff --git a/bots/sustainabot/bot-integration/lib/ocaml/Fetch.cmi b/bots/sustainabot/bot-integration/lib/ocaml/Fetch.cmi deleted file mode 100644 index 707c88f35b32562a44d2e90c36e9e26d3df49a9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2096 zcmaKtdr;I?6o(TGRtAMqt+lSS;POxrH{zoMB4&YA7I`URbsWT9HqeD7*(QNm(2k1M zst8^jAFYU7TVJipETtkyN23lMAGJ=aZMBXH)hgl(6~RZv-fTjazq&Jba&GRq=l7j+ zPwvK<3TzW2BO{GuM8xVXdyiol5r|<}3x;{TM&m3Do=FSYpTIgNPWX)BXx`2;JWUP4 zut^w2QF=6-qL)EeWa4xMjG&{lZB{!^>p0rZ@;bhd7fe>hWM%~&8sSz(pmRBsU}YJd z*~(a~OfIi;2~0qt;~Wl=@Q8C@1{4*dK|zRQeS>o(1WI(CfRwWyIFmzofkRs<3Q!)N z&)P8Txoc^+vv2;Q&v+^Mr-j-%w!n(8A(|4Q>b6&^^)IDFdQE{?Ic6_tm4##VURt>{ zm@g^~frj+-aaP7smlQS$78QaBGhnl@St2nWJ#lOu%Ag))@b;LweT8#Yx^nUx&F1$d zL}*luXA*9FkeOv|?&P{DpqG()Kr7m(*H2e)yc8U7^z?RC>Z$!wSQkiQ0*=+-*e;Qn zEn8=mYQBStXA%l|ReiFm{zOvOYtbRO#hxNy!YDvZQ&$I^)aXQBAC!nZQv(I;jS6>PwH~OL z4?(LdCISpl0Hq2^t)l`SmQ`i89kX#f8pmTqqFS~}6t;JRg#IO3ql(>;*fzQvdYAgL zUA6A2EFFkNit+y}E)|)jF$u?);`nDG(Ii_9=)Kh3&8VfzaBP!E{Fsd6M{v9my_eG) z@DoaHE4na3FbqEqm0JUl(-LBgomZmLZ++Qzp-WS>8^W-3!D6$Tv*s1sX+RFF>MonV za`yBoUCj;RnsPIQ;mUe?aeQtT7&1mD=g{m`mpx9Ckq7Zok_c zCHlwxsU5p{l*Mx~ggPZgDrcdkivp10Jp(R%aBx(~t)>2UuJdM_+b5;aW;2;>h=n>* z_qXjBdpq4!x_!RmaJZXQ@&V+rfQ^}1TLzXl&H&dfCZA#M^(0eCF(C7;)2Rx<9G36R zFtyzcPazzya3t~u2Ls512gDSzofI=JZrZlF&3`I{6Wk6Q$8vxK0mkRw=YO}Qr$+cz z*Zks?TO%<&H3g8DJL*3UD~c#B*Gv}c_w`(M=V26Rbg@b?PF!osYu7|(B`oM2^x=kk z7u*$_Wn;}Il*x)En$S6MOQPzA93A?3+7FmpCEg^UN|e-IyApA$WB;;gDZh5-`2Ob3 zM9*<1lZ9{JF5YN9*_o7l zX2zka2c9UWL_VvKvCuhIhPD85vE_gP?z&nvHuH8x^gfLTgkz9{fZ7!8&dt;oj|=&R zXt=7GV$0t91%zYKqWm`m$c$j))5on>>A{(?ABJ_+j7R;CRykD3H#)!7@xRO*DP~uU zt`xUEfp8*PVNgHym)?fWH!f`QotRUVe6;uZ+-3+v6)!;U4bnt?4ST73?_b{NzkEI7 zme!;T3y^J{ul6j`CVUDmojJWWr=?7$GD&9?0mvN-_ay(5R90RZzW&imu}BLcy1@Wh zcw^nj>z&J+H?#!Wq37us2(|HS0U&MnOLnh)m3sfL4bl2L(JS{WUp9uLFI)Xl{{gp) BIP3rb diff --git a/bots/sustainabot/bot-integration/lib/ocaml/Fetch.cmj b/bots/sustainabot/bot-integration/lib/ocaml/Fetch.cmj deleted file mode 100644 index d762ff659308d3066878cb30d6dad91917c799cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 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 diff --git a/bots/sustainabot/bot-integration/lib/ocaml/GitHubAPI.cmi b/bots/sustainabot/bot-integration/lib/ocaml/GitHubAPI.cmi deleted file mode 100644 index 468068e3394f89a9de455381f1649b91dbc92f12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3272 zcmai02~-qU7Of)PE+c9_MjiM5ekRkJ{yXv=R=A22N(^a?bd++~u z-~09J$0+r>84(c?aw0r@?WTPV7&f{H!|-Md8}$N)N&7(10xg?hRz;=C0kGnd6G3K% zqN8#s154Vh)tq%<0K?K+Lk>xDq>J>|E({wXt+uhTvV0{i(;HYBm95j77)nM{CL<$b z%nYm48k8y{D}(<~t%0R-XeFyP8e|NeEkm<~(G(MpsW6RA;=b z5cL>RWx!8mR9oO=vSb_&#PML8gm9oReo(7Cz-ZzXk-%DARmE9JpF}3gFOe}CQoLF0 z4>Z^lg!=ig)Ibw$)N2`vkK?R~0k8yS9s6ga4DjBPM!nwAeW8Rjnx$K;mjzKbL~13XZVHq& z$`^Luxo&QWt{if`4g33sU0#CyItf{N?9Tu_-$CduLcOBIdm^|mf?q`NfaKyF>L2pz zKgXi+Q4)OA7@K650ACdJ+d|DIwUVX&NB`Go!b_rpIz;^_QZ__g7AdFnD&f#_^UO}&uq{>Q?09Z+t0}VCxki>`j@Ekng}{Ya9sp&1fc+3d;z*JB|bJ6A8W8l zx&>Gy6reFIo2K{z{Ef=aOEdFtpRfWRqZtu3gs4WrONwKNYeL*;#5E&s0^LW7g}HG<?{Wt$aWu?Q- z`Su@1!+eF1Rn$}^0_Y#(Xlk`xTs4kW;%-*ltp>=V)5pmeoeL0}ztVs&!hG;!TT*;)qcd0~<0|y)k!Ie|@cOU5N^S zP{E#V(W{I)ju;)?>%C4f>72%Ur~L4mls>0N8kG}QVB(0|J$LIPZJse#e1poTs-?>S zkO^a?&}xeR@^eJ!;B%K=IW)EKW|60f?z_?D^ht&*QmN9xT*#wU-MR+j?R4ept(gT! zLY=wtJ{-|7?c=42O`}SV&F4DR$_bO4_9SJYg(LE`bIDRx6_Pj3V5l6ZeFDIAA&*2R zuE4+%hYs43i5|k1aq*KaDPG&HVy7%zm(MvH9O}>OixMX zi1yy<#Uc6Ot4looYODTY5Y|)FDrYHpNa4q5yjGXn;}M}q$Ql{rwejBf&WbJ28C6QC zWaV;?z(q03Bdf+Af8qVq8VrD7ArX6?JIYR9e7FD8N3(riyIT;kb-Xi)Sh%@zL}BH% zpTckU?k|2l`TT%p;spT0h43hvR$8LX8Vv>WXuH~7mNoRLmkZJ4JN^Cn!_Iox-8kYf zbF4Hsy>7yomohvHA8bDfK!9T$j@UUZYo7e4JtZuyk}y!MQfDwoP; z6;uJN9_-NU=7On_JAT{{GNod>;qtLP0L*my<}%3drHmz$CpYcL>WN$3IWuA_Ja`7D zQgptOf$1@D&3?D-;`REbzNCe%^AA`2B8AEm8HL%PrZidurRIob>Vt9M^Nxz3rMFAx zeBt2&z^l-Kg|7sR&RObf2@cpTsqOHXrOV#;0qn70R4bHxfx|iC!BBoe+uGgIDR~2z ziQmiNIthY4j&m+YWcbUUJo>qVa$Oqj71Fk2IfxW1oFZwrH!E8yf|W?pGV{_FhbsYx&33$_dbH!cv~(! zIdVi--|*fgz6mS1ORZ-<)U<4H*wor=mLuL-kw16$)Y5(4J-aS!kNjb=BV$p|wzu{! zyp^<}WOe9A4}Y`e`vL$Dq#R+szTUmF@4fnsE#4*|Ju?pg-&mubBXsu*_k1{P9KtcUfAbDvE4OVrV)n@_mIr5jD@SVfBcv)y;q7+00j5~F;BEhag771OUZ;w?{!-W%F&yrT=tuqs(OEpB diff --git a/bots/sustainabot/bot-integration/lib/ocaml/GitHubAPI.cmj b/bots/sustainabot/bot-integration/lib/ocaml/GitHubAPI.cmj deleted file mode 100644 index 02302bd26e0171458cefaa3f23b8229273dd9fac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 199 zcmeZtbV@txcaPIzp@JF5%{Jbasmt~;Ffc3zVs#*H1LDd94>o8e7Gwsc7M7+KmrPi& zz{SDAVS{dZYDrLPL4I*&Nq$i!P}CVL3KS>_2y)KP%}vb%sdWX5mKLNWmZYMI>LnMY zfUu?~#d=xA G4h{fL|4hID diff --git a/bots/sustainabot/bot-integration/lib/ocaml/GitHubAPI.cmt b/bots/sustainabot/bot-integration/lib/ocaml/GitHubAPI.cmt deleted file mode 100644 index 9fe4a857a2fca0084bd82cb6f3294467c45ea447..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60928 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 diff --git a/bots/sustainabot/bot-integration/lib/ocaml/GitHubApp.cmi b/bots/sustainabot/bot-integration/lib/ocaml/GitHubApp.cmi deleted file mode 100644 index 6d787469844cfd164ea16f0fe727c1aac5eae376..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2737 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 diff --git a/bots/sustainabot/bot-integration/lib/ocaml/Main.cmi b/bots/sustainabot/bot-integration/lib/ocaml/Main.cmi deleted file mode 100644 index 2e23f672eb6303c2085d358afceb5f435931565e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3977 zcma)92~-p37S51?N?mE)Do{i=Su;Y_18&2n1VIp7aE%EWFc4;9GDJXMT@YKV;Gno7 zI#occl@p2}iel8_QWeD&<+-3}amR|N#pV5zS;Bjq>f@Xo?mzeb|NXwZ{BtK*o}wP& z@9!@~e0`U#E3Ouay3~n87Su9c+Vqy&pst28=HqQx|XPNGZI zk${L?L68#g^H$*`mZ+68kR&>7yo6!tqs4UNA<qhb7^O#oRk}ka32{Y?hT1ujc{L9@?c^GBPQ0c59}EQdvsv?mvGEWLmBKYtXg?? zuTUz8W!DDS!LIC~{f)32E7@`I=DJ{7Euj_gMGHqg{x5t1b0BdTB%Wb}N3fC%;DcRQ zcrkEP6g;5=yeGmbPk~jWuzJSBdoI9hVc>b_nCA z3gNzC4M0U10-Zpr%mvWQJcM%vD1VyP>xK0Lu09^3R3IC;M+`DuJR~lL#Ji0!$x8b< zWJx@-$p0JJZ5COFblo+9s1!gnn%0Mf^&Jk>Jpoh`18TEqGGsjlvJN)F`J5Qd!AkZ@ z0<95)=`;kc!}zp*Dqh!3c?LZxCsTFc@N!7B9P05A>gi&HD|p!x1$hMZ3_>_fKzBos z8o1tc4#99D&^e4GH6epRQsEdE|`M)XT{}w~&4DUy5gh3av{(Ewi)Wh|1wF>kJ zHcmx`r7B`oi8#QjHM0Y^g3F|I4WMc9Sj>w=xc$* z1wpD~_W-S}@a!T}Q_*f3Es>%Efn_)M0sl%%;ZHEWBph&Akgo7ixXKIHguAF7gu@c* z3W;)|Ue-{r?qJc4UpR9CN%5O2$CYX>98)pHT!KgzQVpY>gK*+AK`?jyNde_4Aqa88 zv(umoMzNgd|8tiA5bV$J1kduqIe}@di75(+ilDD1L0`oIrh)t-nPZCkbx3`LTrr7A z#&9#!)Xq$ge1>V3fXygKM@@y0!SX8pXI{sI9mjb(zYBF-W1>SqAa@R>kV843qv02) zI68zmaez#x#1(d?Q}G!(`vge)1*uX<+#%uF0g$+#S%MA!Oz@y!U&RwV#0%h3;$D~4 zCZ>fDWDhy+gdFz(rbYasnq#VQV@p(cv6RBsJF_b@bx$h`h~LqncL6)@E-p9uJOn{A zA@?lEeFgA&m|sww&w0)%;9bmDN9Pg1z;y8c&IP4{i{DHxEw~ zD9R2wR)k0dfgwi>1|D%Qnw@ee#G-cOfJ0$Rw)ecSiOg#euc2u-F1-{IS>~sIzA=UT zcG0wHO^)B>&@_8lQOK*x(sv&$vnw|>Oi!`eSCB>1p0T7-ty0LC+l)f2^4nHUSu%dq z(AKI7&`GNcF(gvt;Y6vMa|>x0Lc8z0LXvc}6;gB&$ZDIi$ifxhsyB zv{k&MX)g{(xGpper;uOw7$+djh;j0zH5>98?T68{kJ*5kQ7D8OD1Gx=^6qu7w~@a{ zs@@(q`v{MXnm{4-kIJTc>V21H+kR&(+xfcQ%tK0IU}j^^IC}FyQnRhUEG+Ir7l&1k z&zmDQPE9D}fXU)Hwr&%H=LD2?KlpW4^gafZwD_kc_#g$ls3dfWbGF!PPl>WIP z-+k7DoRK?iEogc$Fd&(kfI<>yIi-8J?tm*AY=^4ji+=!R!6}t8Ig=A#3VHTcA6C0; zhh@LywyVgyJWyI5z=r)$0qQl;`uGQ{ogO)4why14y-`Bb?t+>^Cc8*qzPQtXb( zQpjlK(C1aMvupZ&8Myz=`a=UiYXqA{LJHYQr?v;|f|VpSX66Aojv$U|YEe;s5ll)wBQY-}Cl$nZgeca@D$dUfN-ZwP z&nr%aDbr1@C@D%zF7XZWgqRC93MLwWB5DjV(mk`pqckZzH7O%MKO1Nc*jWfUpF|9~ zvc#Osl*E!$piZD{NPc!I$kAXQm?OynO%2XW&r2*REdsd@WUj-437Ywt+4;q~N%OEZ9jH#`voY<<) z@u!vHXAAm;DjD8pd1YChUB$14uIo1w_}vH$Rn`Atgu-!y^HvnqB<0oCEX<=;cB}E%j%AJ)nB#DmI~DYb zVaUcWYExEOT4lDLcecp<1})qYY*SKHR}>2Kj6xQZ&SKhyd8UFo5wCc@Y&Gx3J5S`D zB3k>cRm^vxJ-nlp`rd5a4@O{!YTb`$9dD-!%?|VS3TmdwTin)PQ&UxA(KpE|>Wc>S z^7k`7v^IX zG+C2Z*44kNuBK>V-J~g_BiQ(Nif}x1Ij9PR3R*){wgP-gH~AKeluu-Oo0a}p>&ItC zpg=M1bE2$vA&a?<#q138It4wbDO+MvHvS(|c2rRoA+8T45f52Jd?3@0S?PLB)JGOk z$B3wF9n)FdU=}wt%(rWBk|t|umnG;LQ~b5nRh6}VQ>=f-ueYR}(I<=Qme->2z07eT zOa7C2+J^Z9CfwP89HGx(;cSb#w=L)$-8b6|^H)|Cv>8=bS3Rr)I)x-6LNDGm<^P@~ z|M#gu&ztqcggJVVs^6oVRNi+*QF$5qiGO5S-KgcoQ_B`rg4P(B`*A}!} zSXEhCwkV>?mz5#0IWVkjVcmE#9n>1ZyjCL)ThI}e2Tz+?_x?pXHK~1dO;tr17^^a8 z;Lq;e{BK(PidDd?7WA6Qh1X5s4a*k233dpUz#LmxN*qf`LL$*jw9yQy=()J4vZP$I zW2V1&aaGk)OVr$G%!H@^0~73Cf5@Wp8H)+Ctb5Nw3kIq-ul#E%KWE`TZ#M7+6L`^T z=}WSu26NoX(x$PrS!ij2nOLe@TG=x~^y7+(r&TTWSK2LI-ngZY|A&@dV9^$~peLjv ztWoW{?XTN)z{>HY*_@{=Jw7O#Q^g>=mb+QYy=YFgnRrGwr^*%_8q-K{w={0f1OK5p z_gf@AXh9EIf_v1u_b>!^lWO2Qf8D@GEc|_D10OX37$rSi?w2jSg|X(W)$Od+U1;g8 zW@5i?X?1(0qSnB&o4?h#b$ev*`CbuZ=7{LKXq~pjdu5%EGB%HOynuDQ1a&@UCIY(7 zWo;@j7Mt49*aZkt503T=c3V~4C#!gsu}fIDm8{!ZRPmabINLA`<>a`k91aF2Ck75r zOiECBIe~oVOQ$z^bkzDCp2OGFZ9Nflc`(>si#L!zeoxO8Ute8O*W&EivyZjP*%S;a zV-?8%;i28X{UJ6!bj>?+DqQzpe?c(Vd1_rrd0BBGS+hXCYx|EIW~?7Ou=n@-9tdB! zu{ap)s-I6?T~S|X!@_DNZ3)5dHZFS@5d(NA9!p4~5Uo?DGbs+!aPe0q&Kiqui z8?8HTZB`=A2nO?X853(t{N#rP^1Ggld9}se&DI=S+q}Bw#77_4I1`qamlqY6gBIh# z-5-|kuljgu(Ye>oShcsSO)KF9^7s2T&o8{vweg|Bf%i*_lGE+yck0w{5L<}GqdxG9_Mas+AF;0_LFbg?HFC>htEc3 zJn`PcOFnJduW;0?Kin-Z`{HGrVTmkw_Wf*CziX3hB8Fjz3goZZ_1;@Oj(vW|x&af8{8;MwS1{N^XD_I! zDOx>bd1{-sj`h1H z80#{Aa(vf6I?otnRt`*AvHR4nU|QpCFLGXnyO}o!Z^ZA9$x}@A8GWT?Dnz4@(M*NG3f3`Ct9KV$@6L z-z>70{`h+SZ(E^Soq(ezDtLVPq!kN4-rV~0mgoK2ch1JE^Mb*S*5g3_^tPkF`=)r;@4Z}wjQ-C@anVA zTwHo^gL+m12Pcp}Z`q20H#ggKTdPlZ{OkJuhiB?%QblLJ{?wsgQ#<^=|AoErd)ilI zsK&x|s;#1~K6Be68Am$pd@^tEc`weJ@y&Iru_mXkn|g3_-tbJHlVLaB(1iz^Fl^PrTKC>anXoc=`LL+o4yjhgDSs z^2@(mbIZlQPWUyw@+9`t%&%8zJbBd_KAo z?A$eSPTO{?dhBiA^69mK?dP2bmdS@B%Bza-_~fly2h^_XkTl|8%YEVZXZX#>x-T#L z@SOLWU0>X5-4#prJ#tx>RFF%#1NkGaI?}S{kM%o0?6a%lxc|_dsI#E5sC;#88CbgV z+`fCyoF*2q&o1fn#W`1et%o27b42_YL-j;_nmG|?&nG$@Qw}-Uh&%@yxWnym3~!NhkYIc*M1kemwIWfZ`p=PGe4k1>o8cXDokj-HO7VQ^;u zGj6?g_kHHi?uI``Xjq%#s;Y98(J;0I4~OQrEiEdC_l+Sx6mC~oSykyTEHE5@a%X{o z$7i&ut646ea<^d=V9>_j0@P{f*`TBWN%<(zC;(ZZp>0b^hGsSD8Ri~5)(DMjS6sG; zrjg*36}I5Q^dfX|L|I{O2bzT&92099x*RUjSY$;jT5>JQEa z)C>Q+7@;xkFcDi`t{WH(aj%@-P6U)8p$WziDt21##HB+}NIbF)p>n6U9Zth8-J^m> zse)zEVsiTF&FXXV-K{RQFpI^#LK*_mAXkz>2l}jtDR$8(r?w7Qmu5Sh)m?}x# z6eB=ncuX2b@oT9bl!CuO0HJyPr<-FShMR@UYiJxTtf(qkUhW?XnY4BU__ajB>O_jbyXr1}H`~jfN#4rw@PZv}`NMi{J4sww9 z0TrD4$HF)fklUua;)Zt+k zgTRAgDvNnR=C4Ek#uGx8{GfcgT+e%%bA?PVvC>Or`V4bA%$$f=g4+4g1PZpU@nzh~ zhjTz0*jd~~B~FG_ zC8`Y&{YC4F+C?_WyHqJ3qriI=_?avanyeY^tkNXkBUto>Dthp42uvFYhf3l-LGI!4 zJYEq$w*m2CRlygi>j?#ZBkNjd*HzBbEaGz%@ryA4YvOsF47A(SA6CVDhZ2t{@T4qp zG4zNpvWks)-Ugr3t$9VT=nJiB&wGV2-10ot8ZQhVEM2l{%?h+eO{+*0AFB#~2Kb2r z|HOc{hp!FZbW?z@M-+>k38K-3%KPy#VYn7#6Y*33RDCESDvOE9xXyJ|qo+=ss#b?2 zGh#^}!3<{`MMP_WZ57zZjPyhm61ghGVlM+a3i!c7=qYq{6(0nK{>bV7(Bh! z?^{4of^HEFUEnK&Tj(z;=@!WCw1j7qtqum-SCr8zlb<&aJrxQBZwj=be35kUcIZ68 zpb@$w7=ZIh-bYuW&HfDtbhIaTq@-#g?=Gp@vLhZ5tType{0N~}*7}NkwPh96yzKzS6Wq5QB+5N z?Vp!dLN>0d+F#SHqH0YU0!iJfY8K`BE4xmgng@bv^AIA-8&kBRXzIe6vg*3LDSkvo z{FMv+c`6iBh`B$447GXG^t=d`b&Lm%bHa>pAf(2--EG&LZ zZMSGncknAry5G?^aG)=@d%wOtyLRv1wMV~cJ-YYrncu&6uWmhibf1$;Ma3JuAJ|F% zrx+@x3J*14kfz7p&Z`YROoF%aB_xNyDHIwJ$)$dyp(bxq>f0BZyjg)mO-*hTo@C+x z^tamTX5tA;e?>S@FLeTn+g2-XDiqd*|LOSeh1LYgTYOq#k!HXThCW0p>XOEax*Upn znyskR09!-(LcTgmKhKKPPuX665x$J-@Dp)S-PUhFAcGh3%~~Pjjz?%C>6Q;m zuMi|$DTF7b#=*6PX4Lt}PD#!4Db4H9aX~!h_vWE;4!5y!vG#v z;BayU`#Oa4Ci0=2cbS?p9UKpk^b3SDOx%xy>E_ui=1Z2ajK7CFu*XH1-WWWSzps)n zpx6_tSom`MV_r{&PB_0+_q^l_+GEE3?Xaki4r&e421zQZv{|nGKbd2t_!=MI1 zpl-@zC@L2*DKy0l*2Aynds~%gmd6ZJg;$`S;R>uYSuU8hILi{wC4EX*OJjbBHv{%K zg0#sSTE66!I_C3qiN-|V<}cZWms!?1G^Tpa3W*1jIBiZB?`RQwrl46 zU(G~!^JT4<`d8a4JuKlQ9Hl_3B024036E(HGT}#C3_rjUt_vcdV|q9V-&@8o;k#1} z$=1lH#^WtJ;$Dm&it)J4Ps3iNf2EJ6{TT0xYF7IYoS}UlWN`dN3m5x3fWR(3Ozf6p ztf($3tHChsE2~3JiWtY6bG^SCg2);yEUGT6L(Hm&wh5@Po5jHnb35dY^kZnPT%Fs+ zmpjB?Q(jh?+p&wUL++5}HA}JU#5V%o13jC#yl7ETN!9X2Rm*cb&NmGTg{eGbO(TuE zx3N)g0i!-p8TAGP*p^-T9#D`5zDGyPwj-AbD#;XPZ`T zx{^9ZQ8jobI)gkchtWi4-g59~5GazJ{de8po)j_B7xecbz9GynH25V{7f}(Yzdl%h zRj_``4%>^R)=*D;cM@Y87`q(cdkVasbe=b(iV_of7CKb}H&pH`(zB+~4fXpQRltoX z>stlhW9xTgk2nUg8~&Z8tTCG{WsTVssPEXetb~TQy43{*K9Cd@%!EW6D{mj)0<|8| zp|;}!9}O&|#_XHVnISbTD8G8-nJO zltgv`oUFhHVciGG84Jgt@+C{!z&B8(AzlKc=?du~16bquMv{QwGu6#40B0%iVLZ4z z$j=H2HdT_8w2^Ox&Pa7rb9jCkWi6e|*gnP%09>TNXOVRqm(!x8EgWHyf2wGFtt#Mo zl(kNQZyAUlVxW2=NYlJaG<%Y+3~du^t!&&@gI_>wO1gqSYOyJX2Lp;oB5|`S>urDm z1s=uN^R8l%SC(=WTn@>i93X8~NcF^`4g3YgqHXHt6L@}=0zXhJ>IoKIu2^&pB2}72 z?J=vYEn4K~&l3f=PGRgL#y$sln*zU+Ogc`zG3k2v8~>b1kEjBEKw0}F=!`M=vo@2S zF`0A|G3gQ6yr99Kl1#dh|7tU-bud7I4I=O*RT2mIvI1klq8}nzbhBWXg@bHPJbFc8 zVX;B5=LAboOnOb;WuF1zb%j6^cjyr@>4;(yVrFS3m!yv(SUiz%Y$|gmFlQRT;|j!t zkebj&GU-miS|S@cH+KgEtx71%35C}L;5Q0v3Ub;@ss+QW9BQ#su+ECO9~27wCH|uV zv0_2Qr3c|8O60o)>!FZ;Qv*4+TkzkfF=q?rY)wtYgG`~OHK8E5<|6M3uH5&5YB$K-Y<-@p<;gGf|uTkJiJb-?65AxAUzn&G&Nv7^A`y|+H#HDj) zG3RRLJO|)<1zx1M1WkYlUKGyx{{@$>R7F5}#Wn?A1ybg>?fswO%+cR-6i{ zn`h(sZUx?`IMp-AFIJp-4KV_fQ>HD2yH31%d^U65#GH2k3@dQA;?UrOPvqIbUVY*Tce4s{f9KXMcPnrxMLjF-`(%@hzc{CJK7S4H6zdmEhkJ55V@!YV!6Z&N&ulb{gW<5I zane7xYP3ZpoJ)igk+#TboN#V2=W&$Hra(Ba#YODGOinmUh4V&G0wY8O*?$NIbucKx zxkFMVW5~{l@p_^Gj&`68Ntl(WKyj^%*->Rag!2$#mb)IXK1KufDA=r8 zV~76a5eu5q6!{imRl8EnbQ+e2**Bulhy~iL_rCHuJjG7^5=FuWiB}45t%BNR}}keI`qu%mVavW@-oaYBQhus$k0!R zxw%vPDr!%`3AtB*fF-rL^HCU)3^RZ&c#-sxnwWP~%L`?DIwFS*w+rV^(med)L-k}w z#M~k6!sjgcFf+C+eti;M{8(K2r$Ol zyUt>+wY&N?^yno!eKp8@M;Ypvs~XPch4XD{1nnab&et))(mf`wmv2FXR!2?YwJzwD zmjxtfn!F?EOT`_d9vET0h4a%>*oW_6A5JlWS4Bq}35dAK&LbM7(2DF-1j1x(I zoRtx=ebw5k2jFS*Sq!}7G-wF|?;$wRD&y;F^os2*8eJ&1m}rscn`z-)h>tXSUlbm7 z;pwFs9rX>CRXbj%t!^}q3h_0ZEc|&)4w`QWEEZ8%BX*cVe1Rtsmz>zlCB##~5JD2+ zdPI~3S0~ie!f)(k^Q4%FonjspLqi}&Jyyd@vN}TY7s$?%-9@=y7%cf6dE-sZ z!CDa;eUVsx60Tk_19^sUVU~*@+LSQ_d=Pqn12#k9BFEELPmDAdI}VADa6^C0g+MQ%~$w8iEnsF~tLry!6J@*-A#CVzjZE4W<5Mqd!2 zk2ej&Lh?*WzVt%_!ZjOSH~I@za*L{@JHT5N*vr7CCPWO_*VGlvZ zw-h+SfJ+L&jRK?b6XIBXjeSQw8;MdE@lMnU`8ewO{4CwrH$-gor8h4C7X=(u1+FEXSerZxuLMFX@=Q z&$Zp^5S}CjJ63@>tVx|Iwp91No9r^&vW!2h8#wt#h5o8k z(;fpoE_weqtM~mb(N{2sy`eS!Q__q?C2p64E> zDk%ls!xdO&@aH3X9=7SBkD;RY#yt;rF$Bn`96j%dgkm&7RtsHgA&?T7p=w~_Y!OSoBN<@**?hWX$2mD zR_wu!A#+&vG}SddCEU@MLAwGWyN3G>d&~8*-dOGFNs9NnD)%XXZz%9ZS;Zi`ifo>0 z?b*v#d-jHMFYLm>Q%v8xl=x{m3jQGW1PzyUnGqKE*CpgX#(a;uPDl_=QJ6Xyc@SS% z6~>$m0oc3iCG!!}C8VEhq_b@BOdDJWuPIi${A&R_;S3`5Erc)~{AuwEB1tr-#5H=O z)dJcc(4h*G>9jee2yY40%; zBDL`ZKs1Y*01T5X>(*!j!2b}!7c~J8Z5vJiRNi)a0wD5*$fwbkLIwOcA$o%-xd;&X zN5XuZK*c$9Ilp%?$QjePhvs!^ZJ(lm`%OxAi?FM7B zxY_eZ$#%<~q;dmi+**~p6}k^baeg74$FQ(RO6=2lUv!)MOqV{XLv_srIlniFxvZ4& zwv2ZLF&h=w+axCXRSC@VoGf#^=6pcJMPK0jIFyAE7NaTsME6(I=HKF!qC z9+EEcs*kHpBMrLo-|tgI3EilA1ZZjzMVV1nxj0vDP?RR4M-Mxi6M;3UXnDE9A~JOZ z#We}W0>9AENMqre*4S9M3Slhz+M7a9bVP{2RUljoqb!7Lu^C4shLLoIYZ)%;cVre^ zgN17as>gy5QDOg)F!oNGV*EwBq4w?`&urNbr$UGlkTVjp6jz#era|+^2H~!lV)jfS zUkRNT9x}QNfJsVWi__QEE6AU=sySF!*`OIONJ=XPG|I zmL2U>&`h|-Qr5N#e-glU3Yc~hz~#Ie8=-$^~64V%)6H;=L@@jVwYK9BKY zAofyVsUc!xlub!)RjE61{ORi9BH#^F;9|2Ai`WS3xm40!!eO67JQdi(6m}Vr2R>dL zx!=pPL}C}w>@T_-O9w{}yvm*oYtWzL=Pzcwg7Gz|;|v9EvifuEY)e)#Ysm9qm9TmN z>%g7;)b@X3RzY!=>0x#y;BsiPaFq#HmDy#dn!~Ij=+wh3#iAPyv%UpNc7HL-y0A(q z@C(&7=s0Un(Qz)MQPyYglhLEBJVqGVg%%4J#-#>PHrM7;4YKM4qHtY{i*!_Wrc&WT zI3EA;6ZuENbf!+ZH?h~7J){nj9Y$m9P>ZvkS{tlEDZ8bpm+5|TmxzzPDE`%quMKnf z``GD=AG6Dxi|q!Lr1krioHqk}T!8^=G;PX667#GuM^j9L;-6GFTcG((8jYs$FO)I9 zm2vDMh<{OmL1_MUO7lIfAu?0#C~k1WvoS63x{ zN|d_b?=~mW`QvV~k#rcLvaUmStOL-d`0jeMvf4Ff@HSf0xKAn?oVn+50twQTPQtTF zmlCo>qYDD4;1j}F^@m3osY=sfeIZ#WQ$i=jzefOeR^VfnGNnu5yl5)Z0N~^)oc-t# zj7}D6-%M{bNjPl@j!eE8;GC)IthpFV< z93fnT7K9UqDDA~WIAQ2g#*Z+L?JC&!p<6vjBt&00TqE16wgj7$jW1{XEyjT?m9V&y@vj;G37N_i_@~*s=$&i!%MJ<}On1E{ zQVHJH?5Gq8(H9w%qk?@E77Vdz_9gKK`w}SboYQ_WPQ64Bah9xEFc5LJ0^KGNh;^Fd zz83*DDB(M#7u3iL6}?#6Nw`SmqTNo1Zo-&rnA!dD6#%pjLWID0fO?1)8z*C+my zPc!ip!Gy%vY9`=NBKDZ*R$v)csIrMFCHFX|7G?@Z%`sUtmy1cK-*E{R#VIj1Ncc(( zQ?Pf=4a=FxQgoy-F zb1i|zkozIx2H4F-{K{;(H0LRabU;#0YZJ$)?B{6-#!Qc#*QR(SliUsGwawa)-7-m; zTf@XfOk4p{<|*(hlaz>^*Qw{ol5$j+N}LDes0;Lr=AFV=zEH~p|I|Vxu2i+cCrMnT zz`N1mUWm|?waP-o*-^lhwo*DR!59g&GL?!foV?=$51lVWT8NYuWFa8a<|zJI2{qHr zxkMyJU-|@~>A20q&NV4PQk!cPnfCzPuE6`CW0r+L6>V$_A(<`QFHpwY6!!f9Z&%}TQ`6tq`?FF@DMSGv}`Rk11D$JE0Yfwy0QFPXv> zaSz&R)mO43-!cq|2Nm|qrdq{C8io`YCD7aTe=-d3*D>)56URW(Q3d`4!|-*4xUm+g z1cmoUh?uXWVfaG!2^tZ!2{3GsMg@I$5DddNlDL6dv|otC=nI+}_$$NEs+i>Tha&7} zfPX6Rmq@#i%uN>U)!j^o}{vT7lH2-`9wWhfM^ zg(qbyFw>G4Z%SNiz50{o9Dp33vLwQpF z70lI?xw?V00SfE~$!)eJ7e7dK)cF23Sw*s*xws*L`DRD8gglRgytzR~oufPIY!rW) z%r;9&GijV?bU~WMd}x>tGI&7)Gd~9LOEPp|E@YZis7US)aDf8xvJoA>Y$GdK0GZ1E zzGX-2+Qmg8ZVTmGs*r~QELR|0M~vnw4~`a7r6Jx2&#TpQ?BT^bGO)wE!GX4<)hn56 z9COV9;u-~>VTkzAN)KALs?~iq>0I@&5P0V)aDk-(@#}2PqKBdrmXieKBrWMug1Tng9SXeKp08Q& z+KCK4rXX;r6*YAv$(`P+U`7>FM_5tC)ZzbVx<)6i?~Nagu)levPrhpgv4UD(gOFht zJN77phzM3#YXLsI?2H=sA18H+Cs8cvKr<1<7Kap7;-88enu+*$IT<{4J{f|{#Y?=( zv8^n+0CihV80iW~RE{aC1d&|_>8b}t7A>E}#}gY) zjbN7-H34pGPJmm%Mj(hq?nEkutR%2Ts)vhKuVi`^UI8V6mAd0UFOs4!X#F{SdKf33 z_*A>&KNa~tgviL-RQW=Lp$(P#6Q#+1DD|fbTx}|~h{ui=t-diUDDuXCBJ+!l=hp4z zHdqIn{*$uGF|~ldLkvvBoe*(9HVU~ZN=_YeqeE%YAvY!HzX-X-{ed|FexbU^kXyX7 zamXzmuVHAgvrUKGbotgB6hz$DA|CU?1~Iqz%u~hO^w~5K-wGEQPYSxl{TrcNn6`E# zmB>F5#)~WT7?41(C?czrx*qmahFeq5Muwj9-dWhGXnJ4!5H_QoV#x!Qkk$Ykq`3BZ;eJ`ul+3LC4QUITEP0=JXt#5+Ss z_0kUTvs6iCK$xTuu0w;^xBMK_wo^x-qGqpRuIriWE`W0scrT=)cAfCU((+ayLP3EE zs{SI%Q=}0004!GEUXjCCMOhPzgRi{W^AR1jD53g$> z*~!DyCVf?FnCmI#I*fv<75FOXTO`L7!6r%q#|XCGB=CBweWk*D6W}TZ%1xO~1iRQI zaEr1^xg6&(s7yAqng* z*v}?`dx*e|3KMQx@+Jks1;hCw;dGb;29z6pEl{?c$y~p&SlS=x>zV}eneG`eRRqD6xbQ-yYdtW##UISg#F6>N_fOFOKG1F=h8mV9WCu6v+K<^ z?|g`i!V~F!rPV9X;lcBzKED9C4Z%!_eUphyegD@@@y76 zkj0KfK|d)FoKHBUyskd27Hb)M9O@zVjCq&>$6H=kg1vn*4KWcA@U1md^0*Z?WGO=^ zVqB!xmG+ZF|N4KKDS28s3>G_u#V!O*xf))HfM*Ze<4$a*<>-xp99`XMfO2)C---6C zzPxti#B1*u^*X?ZUXr{&m3TefM57Ca^snbiiyyH8VIa$7{xQuQNUu)WU)AL=9#47jfO~UsYKRS#yjl^lV_I3*#!LA8otsJo$CzA zjOkX7@TS`!MvNrpO|Yg+o)VpZn--?4Dss-`O_TVs|HYiibEabmi@lb`B39rzOT!PL zU;QgWhU-S++)jne8Bs%yr|LZP2s0T_GGW@D&Efj>-@=cOc(z9Uxmv;9^ zU|>Vv*gF832FfS>wS2!6p6CnmJ%jfQ^KJ(34)d%H^nc|Xr?@r6$HF2dPQ!@RI9u5i zCsBM>GIAJkX)3~p3Pp2lbjFMw@A z(4e8ClyaJ57;`sc?oPn%r{QielzREAT(&ij-=_VL#8M)`(1<+%7ihQ_RS@L&pk{LA zQif^`zYXv($8hHE&D>b166|Ir#FW9J(Pi)uQ65F&1jh*G9?IMkQPM;WPX&qCo(&fA zFC>YHf*~*=z0JgRRR0W(ITP?q4Pzq(UfLsA84}lkM~T_QJ7q8Zl`zbE)NRP4*yfpwGx=Ol;ai1JeMZNTnP3xd67;Y zix!InfmQb?{kYySmbtHG?j0!g1`Xc^&Z|LD@M+X5Qj!GT{~~!qGm^xYi0V5uHl{Ht zcWM|4jIJaUB})Xq9Icf(-lQD&X{>tz@6qsXl>_z?v{wiYu@UNn`teS{4{7*5YD1pj zv^_)il1H$Bf>omlz}e>*$J~3E`w_zFp(XNwNQu615_*ReLW3Dk%0b6?=HAELPoSu$ zHGB|Uz{)s!iQsP%7d+n!^j@0_KN6vbHTH9Wk7$_G3S3w$+q6Om9GQ?@NODk)w>8#F zfZx&ZVU+{x<>10<$Ww9QsDAt`Q0p~(gjzULh>j)~K2)oMiNN{DF@d@N#oTWY&Kx1C zRWZjU2LCQXzhg^+0c*n|QFX#Gk-6VwZcNTnzR~b;l(LQ(K&yT3vC??QGw=DdE82UW zX7V?{kGhNy&iq_}R{(^C*n%>);{STU>+tt%;=bww;yN93#dq+k<_oYDT6Q9F1qz@}qzg#ZnNFa9G!36LxLiiu#yv9gB^(PoR9mJ-co%S% zhJV7N%Y(dQkZ00pE;DT4?a-h4Q4iuSynF!aAP&j{V6@vDd+trLHp=8GGr377X%R{m zvswMQOvGLl)df>~J0>yr&&-XnKDCd6;~0j;u1fi0_mNh33PkL`wercG6sdzXstef+ z4TDG}EQ?uJ%G$SzSiF8kDIu+8rjFAY;sB4=aDth6he`BRGV?a!cAJ^crp&W-h9tmq zH0&`m?=&-CBQswu+!=TT%p#2`02gZ*-AQiR7w*T*Y}ZM?J!&Sem&tu*@&?7m?ZS;N zBCSAbjodpN^KTSe>zK^qQdwL&SR6QfIbQH8+()ojkBvD*!8vMA{1Jfb6^Iv~kPK;g zK}F*{KBd;FXNyJ`R*U+h(h$9604hv{za9C?+|*5~(AQD^W(B^h%C}ddJgs@M-hVF( z_^?3%+f^>Oqp8;^@R%y#bDO|+ys7p6S?Fpm-q%fUkH966JL>!Aab=A*2`k_DGrgm(nK4pDZO{5;QKCGsU&J#hY z&3||J!}|ym{h0TDXuUf8kxKffnBjdEx)T61>^sk?J9pc6o;Q)7kp=CsHi~)o${Y7- zeK;;sqc2#3xLzV|L0H7iMPttZYtcaw2c`oc{mtF*hWWzj)SqdK+Wy+&wIAH_Dr= z;k}0N_|!CWK*YI(wAuRk1Hhf5;fJMpr=c~jP_ko&-SAIr@MGEj_pPu)nqTLKt0QfF zTy=x6!*PlK_J0v}NIT0hi^c6{ad0!z&erg&=;E(XH`G!*Hz+If*e7+oKgya;fK&;5 zYob~L{|0SyztSM=@HK@UAkVK*JR;qI{;ee&5NXjDB>R_P2fdd(?Pg8yYoPrW4Zmqg z6~O~k@q-<5=w2na9~I)83N>ZL%kf%Dk^CCWSK7Tg@7sVw8pe2wNv0~}mxusF+Wi^< zd;d-mfJl4HF`LDG!{Sb&to<7P6`HY8X~yYosdjS(H|=SS@f)xYDL9^4y5R|1s*vuc z*5DwFxrUqel17JBSE`T}8H7m3@k+G*4;h4rTD6Z{>q79R(ebXdPaJbtyo<$qLDi=k zZjYY*Q-n^?uqH`LBPBj5d-nHImA|lwwhxJ*-S17Np?;X2uejRvsv^oV}#P1Hz;8l0kEdovt!S$uaE-w)+wYIq=|cU(zt zU-={0rk_%_6ml%{suTiYN4)L=mqt8;rh>HH(LMB{r$cJB06 z5M}yi{)Qm1O*B`tC9P?QGSQd}DyZ3Yrt9i7vHTT-J7t7MxD*<><2YS>6 z0sK$9w7fHQy``XGmWG!>d+xTiCuOd(C@C{-g0PkcVbOs|3FMg;gZ_qpybR4}2abL8dfGmDXrdYXGm+@S4cYTBxUoy#&#^tgJ+M z?xvgsvt_zPJ4W|VcMhOaP0N{Ldy z!Pemv@AdjA0ten3G^{4>BV3briDrgDf7C3GZhbehor;ND0Y^I7i|AMnA{I!27L+@qSS~v5wndHx>Z^D9d!~ zD24ZDjsCW2;kPvq(_D!^<-a>jk)EOp#XKWDRl^vNxp+#U)K!&PF zNgzEHRg98#xAO81ohWJI=GH>16sqE%#f1 zGRRTH65?3`X0U?k&BN*aM5D{Vb^%hl20^9tQI2AkkjWB!C~35Y+kiaO2hsCeBzc4J z&NYj?i5d$-S^6XmBhG{Omhulx`le{(Q3#x=j)g3t6HCC3aKSR@^`c6A0-G93>2kdI<*d6lr**rI&8|e0KUFadelR?Ls8lGo}czV~69s*L&QKLobI=i!+DH*6DED-c+6IH1$?yQ1si9ga{ zw7>yLnQJ+Ue@Q}hTBkRO^ysVMXn_q64Tp>L8#S$%Yo!M@>__Y86Wwz48APnJ$BT|7 zWu>Lq{$E;)SRo1OE}dx+;JY;pO|tT?j~F%5LmHtL`qOySNPpPjX9+7ecJl=?65z1wejM!IF_>&O4Ov?t zxi!+mkX_@cWJaoE5leWKB|HPvG!4H1*?pj7H?%#;&h|JnnrNICf!|cauUg_u^btSO zvTP>UF_CoTBHd(poEhzO{@1iT6T3I?IPZ`QyZ*nJPG$^tEM^IBv4k%{ouT2A5aU)` zjA=tvcTTf+W2ZkXYeE1<_0YX$ceW&cKgoJ)gYJBv?#{bW{1%x%q(qxBSv0yJ+P|Dm znj9wSmS~!P0_@i?j%L}rf1yDSLAr8;+p?nrEfW>e7U0xvl)YMINo0VRX;_9Hy_!yN-#SGGq;F#*4av(aag}h5-L|+i{|KFwTjOR3!7=|;R*YN46 zJmTHFX$MU`#f#WzDI4^@i5~l^WY!zpXL+FJQg+7sx}2PdjmS}Y0X?yZ=8hU-1?HrXXaVJZ}*pS&?!w-SV z7Lt*2DH~*7VlQQUvgYvX5-(m`hP~DRPK|i%VioskGjbB ztH+9VnBE$Xx8D;}{;BVmIak;HG3c15;cu|`6|${^7vWJN$~)I4Dn<(Xce4}zsRxTR z+IuG-{ecXLp$3D+Z+fsmC@%3HiS&zZRE5ZlzM_1;m<0`ezs$2Vt>1#~vo-vSA!3N{ zrvH}Vw0*zMS{o$WWk8x)*`$%vIZHp2VM+^i9>EBF-NU*^@0 zWh^O)C1s(kYc$-{5Z=XVpcv6k)oe=tCXLbz=sPr=Yf0a`-DWfIM@Vb1tf?PJmB0Yqt!=6ICwbRKcIylr*Okb9Q9L$;KwJB$Zk?4c z8eMgtLZfs;>k*Ov5)=5|*x9#vt1Z%ta{ByPPsk)W|`=lQevb?A9vN&8Dg|I3>1Sk98}U`bdv$~r^Cj~F7ot5Su?%)&I-7Ko^gdm8=Uj{5?WS$81%I`v|I_{lAP^ zQu_T_#_WdvU&c&idY=ZPj2T+M8%0+1^?%_1W!K!4pMnKl0u{$JK(x+Fvav-WHFjfVbTMsbAymvulRy&3KQdA}h&dtN{O0q_eN zK1m{!TN%Nnk_i7V>#)Ya7MD}`e_3xi&|80I$+0NyZ4D>DU>=b=r2M~(v6lar9!n&A zpbUVwkna388a!vD+qMO)|YK>F3OnkDyT$wLT9`+r$K zibfZnp2Gjj7LGM6c_>T9$dK*Q@MKW=yQEV4e;FRz|4XM=H)bbk)aiheH9V6ji17ci zQ?$o$6iBI#wJdoSOU41t2>&nJt5GO+W^HEt2*)hs8WGjh!m*Ae7qjH0fLm&~8lKC8 zq}}9axp3GLCbb{SI9L8&uX}2- zX!Mq~oySwK*@(7C{?TA}SN1@iYb{C`q+z@V!QR~kf-k~5QYi$QJwzic0X$U0=iw1{ z%(S<5cOk;LyO$&<*GG_+(4tNtHw-TCX>s| z!WJY{W(}{KlTgD-`=TY0Rz2wOPYAO7;`q9yIH`R`TruGr3(R_nOJ; z6dSJ*0>h`=>y>?@Ub;<0xk1NSEIG)MZ@0>ouem2ecFBScnFZY|la_{sRJr$PwZ2ni zM_<^dxR)j|4X1Y558>EP@*OOB7ixc4!}mdWAuT*uAPCPXTx}Z&?|?>q5ZRv8@IxjG zKR1bdK(cVJaP>6#Pp^l`epzRD1n^-EKWb+F*3A5n%>1B0s6Ep*XGoQYqkaP$r`%ls6 z!l5Tx&54p;PBL?>$EOfj@(W>+<1rJ5;Z3=e{9HRpe%_Gy6L-``f~G(#$@KviC4^ zyo*FnGx5Gz`y?~_dougGB9=Dl0kyx0`YI9w%*0WP-3!f(^^)DiX7U4>EHaZHDs~?g zu~-C?a?Ba4_eEWZg2yq(xh%P!C4U5V>n)eDE3GY;IkWW^G}z&sIU2424N#S{QH9>9 zw_kO|oLQpLg|Hh|z+j`TO_#CfMDCf)S)@y?LJf;Gyj;~_pS|`z(O}zU?8Oa=sMFb2 zqKM@hK2sGDu!(%??>1g~4{_RfnRAZLUIuu*hR-7M_14SSooef4+GN7MNMpb^%DI?1 z&SS~PSn_dHsWxBcY|ziATDvb}4~W^!Lw12>N2T(Y22Q=p3i0zlLw?}Nh9NmRp ze>}xsTaB+(`E?v1=X&P2km2?7o*0yIgPHKi{_u}pzMb(06Qfy%`96G{@Gh!bPKU2^ z9yUwE`bW+qW}>rlF>-Q(($&cRx5eK~9OfC#GKGBuZ@p(dfcZAN#Rzr-g+(3Blb;x=@_hpZ`2NXY zV&PY2$vC@`^R=1CmDP-~tNEqzZqA8VEC=;`2z?J@Y}-zF2?V|dQXk|3m&l>T$DBXR z0^1<*rXI@ag(o(WjA0W^919_q@D0Xk2ALbnl+Oi;7W^GFv$7e##W`z*D zo?&nXRLmqH&^XoEn&JIu^aumNQ(4iAPaE}*ybdnzp7dgL*%pcS=dVJeXwRMX-QKt}1 z7RNwZjla68Hm`O$tPnorU0hX{ zhyPu%``^E)Mt<8YuehwTgkF1+M|5|CDZ!fnK4PxpVeZ6%|36vmPzbhzp5-Ep$)@(*4-J8QKZGxFvM33qIUehYw44owmB#ukNA)sr8}JEDIg*DwefNmXmc4 z`JT9WxBPvVDm@E+$5xiLRXw^QbWmGSSr$JkA8u0*uhjW3m-!KFKw08u(0dusD-XfYrU(nHO`Hf+Iy@5|8(oZmmEme)rgxcS> z8{Ob-DNVx6aWV6p!92y#xF^g+E&MIom!jh+S^FfNV^~%d`q)I6T9#D_6a=XNRcP{_ z5>28ngZnI^(EonLaXR`=9jW?jW?gkiyly5|sc%=I7KEtBvaDr@&EqG;vC*i>+a}g( zh~H~Q^-#Ol3;AtrHAWAZO^z|gCCsyydCo?z2 zIz9sdLtVsKD59y0IW{oQHOzA(60v6D4p~I^hDDqwi&)M}@!o~Qw**6A+Tq)Qh!Avh zUdeky#qjDWUEc~`ji4ZqvNcjB&)_Q%$p=!FiL{EZqDY`Yn$Isa;8q>Pm$qSek$*c#6k2B3S zUk1LtOn1hbcQ#loyi_;-68-mLi-i|iJi8DJRQmA+yaQip;G)`=@cr~>K7SpW{(MJ_M`p*e$@qJIOYuLGi&#*X_cwETcCv1 zX5uP?9|W@nyH{7SR5Xpg4At>a@UlQX&}0|8ieCjuT}|q}#?$cG~nZGx6}LI@S&*wy~^hF?u&sy&^>`d@>er22ez3Cur2%-OdN{ zc3R;D^J3Vyu0-oB>mlgM1`>38~3^6~0&6UJrU+sIb6) z5B?`fRc<(-Kn;7LwQHmj_c72t#*w+K!hL+Qfr}V2 zT(JIv6<~aoL*kv9{6nH?^aU*}C(p6DA(~R`hZ;PFj`8Og;iYJ03)NUo6B?2A2MPa8 zQ{GtqX!@3!c#%S*!|D7q*iZy`0$>0XB8M+}CCj>oFO?5}HuyS#{Ac+Lr_C|=)asWb zVRd^GN*%zuJg z&}Q~2@Oni|EwAp27w45>^!1M{s~fevcxu_AN|=cnbC%f*!Imv7B@V~PQDTajXcINd z6iq(G0&8Vy*`kPD|~tI_B5(dyB_e#51jdIJu4d z&)fL}qM5^fd`v!;-#rY3Cbh4wsj9#?fFNPigfjm?(U^NSoAK8kZq{#hX}`+SzOiqd zkT(#l(bT}112s4wuG84qj&#@v4AnOd$QzFLI>#Y#t(llk2Y-P|4o3}U5`?+Kd^iJ%o6Q8AZBV(wrt&4;%sRQdho2vWpJNH& zUkD%ZbY#EB%swC4c~^O0mv6wBWU^{|o8qdH)wYBmVvemWrI4i*Avc09D&d!vpJP|> zk><;TqFMBXdV2C-^LWLVOB*!yIkSpIsPB0*A!B-Y-GkMjdY)zp zJVy!qD$MKkKoc^$PpT=yRv3I`x=?qzf-c%|E~;H!xlj&6n7eX64MRr6SBkQ}09$Wu zz&!-f3v>titl_7Dec(gX#~tV^8&o9U#qY;UHe`qUT651iR%o$20oFrU6?VqrDs?G&?qr~URTCpN1LJs}HkQ(aY4$GucQ0Uf6|>{2IFPl_`NFe5kqhZ%Wo&B8p% z5}J+Es(|}F=01w~xCwu1sP?s~z^CXqw*BnpdF?T;ACF|jNa2JZQveME9S|x){qE11 z`^zv-G~u6hIr&AEMdhn&%W8*LmQ+`vExaR|#eH^*rW(c&$bm{qr}(z}S9&=E2lpi$ zhe$Z5cZ?{Wmlrh@6z@UB(Fx}OW?g27aL%;B8HOc9yUq_c^-wF)b zWBsc!O+nFPWzqIG(VX^fJLeq37=fu96+MU?0y^@2VVDm#;oG1B^ssa={`PR%;i0-~_Ea03!Y{?RTYo=h^7Lw1()SCQ<0_W2hoxZYtocP| zVxJ+J%utcLUF~XR=P(euqYRr(oJWyB=uG84pgoN}oR(;H&1cB|Hj`clBVUNz{3;Xu zN!+0j%2|=yV6x#9qJK`~J7L4D80WnmYonZ<=65j1)hy)@OL-Y2+-WA>G)WNbESrWp zS!S^^KF#k0e$)lh9_8)AycK;DhJK`>fp@R}GdSP&nFpQ&o_i6%p+I0Uv;39XT6 zZYB^1Msd&;u;Xl~uqqdQ*fEJM>RMw*plXMBrMW}>!04g7G!ok?&+08$UwtYo zUEOGQbCZg$^Uk0fez0QaoWBdHXKz;O9Ke8S@pY4V&mO9?H^L-0n2+q?g?5h1Y;c1) zm&m@gk>O zMy`3|4)A`8WHSZ}iE^v{dyBzy<2Ik%4u+mPt9BVFvn!s*f4_M zdkv0*8vyi|xmvnJqYG?!jUNkRH9{U>)r$yloWH=1G--~|)Rs9`>yT(-Ce~YTI%w;4f zHQY6SS+)t~K8ZUb3r?G85rB6hnm=nkIbZ@5et;cnN$3pkO~3-G+h(-bOC#A52+ z+)~#f+*+oU@2Puv@AgDHnG8SeIFWs+WBpaeG5>$8G8&VFSn8*%E@vWuT`~fjZ%|#{ zqxzBVLR2tMyyWP`8e!xD9`TiROhZ@sR+%j-{cD@yt2X=hOU}NVe_wRSULcM$3Dy@H z8DS{G?+#)({Cz&8i}~g`eX#Ib!wEs|0m0#cpm3hYYQfd5!P!Row^k@7h&4Z`^j{;&{@CJ9ZdUqznBhJNPkbAn>%N#9!njD z)GkwoZl=ezgI%?=?(5?tjr-}Jwu#F3iK~K-y(;*~Gw!GFf(q*!_w|X8S7$R6opDV$GUak z#0S{!;AkQG(@QTU!}%Qf+@49Av^)027!mmZ=MYW`T;^pppiwBwAXAnbp7n zuC>^nN<&owo6jYxPmAgU&+xzs0gmPPin^Q_R#zBZPDxkE+v5PN7T^r7B0Uh4xOu>C z$95-}K*(POUEs z(_gIK1U~ue)tihxIZLCD10yVo7%U1!2A0eLql>yvfFBs(RBws}_h5Q}5D#&K;!NPZ zju$oOTBF}-Hxx>T;=SPCPPb%pTkMie0E>UutE8h<63K`k1Ry8UtvC%w7&XJ4Mi|&_ zI$WJE*-XOBVqdg>euCgcsE~Xu0Cyw3zh6K`$0eJCB9?4!@33T(5A((*m2{R$g5sSI z%c%u03nH5zw2pbo5MOs)SR5llQy zncG#y-j1kKO@8bZvYV`}l0@HlSEEVT7vGpLi8yMll$QqJA_2xB%|0aW@bxG=VFE;r zhFugz?E^CSW+L7j4d*;OoS^$by@3w#FwIuY<>A)9S~73bR1l=9{p6~UegGqnE5}^I z$nQ`Xer(C+LjHDgbXNw?X_0|%4v+-@kSEhYVg*x!g%VD)pZhx{WXuwNGFcC|bYh17 zCRoTW$5TB#EfhgB$bUwFA=s$LVxPQY?^GFw!adblPxO;f*4KR4JnSb81A;dNK>UmI z2mzGAJgP$wh_5(YXg*A)H=yTw-yoF#h2#$b*_Q&04e66CHG`O%COw}dZJRzq9}cCe zh5~`%@63>%LAUf--?_X=zu_^(EI>ggg%K6DoN!0C-SX;4m!PoD7d# zxcSgWm^-;SXhV||APfE51(peeai+rs8ZSqmB6l6p=G+oU5bhGUsN|U{d2YK2_7z}$ z$mH&{OCWbuVA|(Tws{>S2#bo%g?$J?SX3;q!tXOXe7aULQ#3p3GLb&!f~|!J1Cj8K z4+aGrZL*+As(CvMTY>k*uv3HM7m;p4wV4)fjU*6N8N}+8r3Y$U5X(~*I1N<^Kj$o0 zm5P=jmAOr2oZu)MfSfTGNUFiM=`KW_TRL)Da4@9eZdJ*rt7Pmz4`N-)0_TTJPA%60 z*$hEv3kNFjWYFCeOJ^-xPPPl2`sf5uaFU8^Q_0t>WQfn;z5?9sRc2l;YZ_!u@oE9S zo51cb^<=E(2dmJ*c3vN8R|(Emahp~0gDUxPV4owv)0h( zwl$5RmuwPLdf|j=lW~|;2>f^|6ywN41#{16#gn!h!)=fx%bI49w^r^NI#e()eR)%0 zCgrT+q9!lffBv$TV{n#X^YRr4=U-)Vmz&&6s7)b6mMkFW?Ix3Zxjj>`mCLM*%xQA3 z!9}8nP87^-F}XK@pc^b*{vUb-l1%P(Cif;LZp}uV6Kblu&y-p%U0yabz`*jrius^Y zjys&WoXA_z5||Yr!UN=N9Kg$!bI8-Fs{7O?{B2(TSFia4>EzMlnpey^md7_fx{=B_ z5>61!gbVH@bUZ0+v_NBRhg?a4eOp#E4Uf&tWz9Nz)-*oEM7T9zGI-PGKF`n2k~EpwJv zL(#9E;9;zu+BC0eSyS_zrs}=e^Zp1Mv~77c5mn8VR2FDy4on)m@82DeT3v1{6yLOb z0W3yMwgTPvmREQ0PDhuLGapVaU9s%Az=Y*h#Ojte!0Dwk1Ht)Cix;;912fA4aQ>S! zKX5|#Re>XLmT6$#tObjYfwx3ykSmpoqI%>;vSr|~($(F&FGnh56y$Rdk7YR)b?m{K zj89%s)@j@trD%keO>|}|g+a1#@xeELR0l!e`Iokvq;dIxjPi*S?&Js*wIge?#N4WwVYeb!a*gA4@wDMo~VC zvJ2^i9SOX0Vwuz9kLCd91AkB!s(t!hg+AWg6vNOFd1eAP1k*C=zAKJ%nJH_>wvNcv z!jZi>^=j$^#D0)6D(V3n_GIiFaq6H^n3BkXUhr`lpD-s5J|V#SSV}v@Dsb3l z1wHT#jX4qN9k4V6p>*1D@&o8_$HG#I=S%SXIeGpeo}Z-KNWf=ZMS8|dGE}z%z=GWt zmAp$O!&i)z1=9b5P(-(?ys zPaTjF4?SZiDG2&9{UosA-RD9LTvLKjU~f|?2`UA)8hs_4t~tq9lH^9@blT`m(4Sb; zTAhS2{jB2dP$}J23d~f&{|FF({&aIl|J&(Ld5@DSn&&&kW~}i)rq!ubznNg{gQVLW`S-UCNLxBF^1nuiWZ&R@We|0|USHgTjY^eJS<##^yDT!c>J{EH zOxJ_|mt~l)hlZ)Y@-ocvsJVz`n1b_7hYS5=t?sZ4Q_yNUT+SKBS{Sel)AirH4Ab>~ z({+m;*G?ZH%P_R5(A#5?v8_#n&poaR?)IwSE^iqo<4#yrB9>u}0goVV3pnv!UWNfT zZ+FaclPQS3u+yT=t-=(XMO_ac?p9%1skygF3oin&U4Ujtt$%d33e(EWd9#LR7MfBc zXh=c3WLkl~K>oj69_%40-7C}vhgR3h5 zZWwo~l(SUIT4aYCh6S+Ci3%Vmo$+oh1K+ZhjM>h=x6&>5k0WFeZmJpNci@^60jN>_ zldg4kn}XO2H2$p1BP?c?i6UH+2JqNmJq)<0(culU++NsC$i2MX6m}P2i_8iCYA1!+ z=#iN2M*>X0+>Z2qE}oCl{tG`jf->tyR0NL7l&?(xr+<5?SkcqhdCTs^E@djTl9?smA>L3!{zHXYbk&xGK-OZEFSZxcS z=A;BzH@gQBSrIQ6zzP9gg%*H)e(=B}gOsMgL>lg3!g25Uw>vG{6&_Rq16y}i71@a^Vw5&xjy<~3n6IJb8#u_CYUzgQ z{DI(L7jPB&8dVY={DE$=7vKHv%*wxE8HykLDo#=MV_wk%Cx&&6F?;F(_z~2!%136~ z%tZSUG{V~lU4S~sudpP_f1z(e4MN%kJ<-@PIM2HK!<5#oen?e#PMk z0MZ1&q6ToLDRY;~?2e@=W9C{kys6_-oEbvy=S3xwJ{3Tz0BIpCH(BYA)9->E1wEtP zgMWMKW=NberinH=5LT=VN!S=S6yiEX_2u~_(}7)aG| zrR0P&uVvX1-JRB5yViLRA|!MC7;qF;hH0(1Yd?fxP8_ZhN8&!!-NT5dQy5?ItT|*x z(kWcz0B}4?uJTLX)4v@@8zoXL(gK7{PHa+%M*?Y~yGIZmMp@2*85XQ)S$3QbGLiei zsT8pq_|bTD%Scl9!mbk?uvq&e6msH8D)AIxr4Y$pQ|>@X&+CJV0~HFvc2+zGmoPv7*zw76x#-09a23x^>LNec%Cv#sm@P0#s%hm1b#KAKpnJyf)&{hNUegxCgbx$11K}^_!>qtptFXy9G|*wtzH1 z{&J(rLY-Bp+wK=rpI8;LI93B8R)s8ZF39N-@fF>fQpg$vc+gmpyjx{fBMIUg;Tbmd zj`eHL6z(#rabnmgL@}Fg)F}Kq32785Rh)a66_G~KP9T0V6qwO4z&wOxB>oPDHKmsC z2EnWnS;B8d9Y`h2FkKcKbpU?766~VOJt}jQlrWV`z>@})04a>SdMW{bN1_Bo?7-a! zqoB(Z-?NA>N;ay6N@zA+{sH%V{CXuUW_;UJ=3Y|50(r8hEdlQ!S7`2-3C2|O_zoMP z&yFks?Q{l}aJuPoxlyO#*DJxUcy3pjlcj`{xdc4f*Oq|0NmK&fxw0sj<+z)nmsiSfR`&aXC!sZ>Xgc+~;`{;Ia(uVIY;U|zvy`9$PTwpeG8tCl|1 z#CKz?{Y+wtV08=;KS>zkZ9#V(aK9tK_1MXsq>G0OK%xM5awUGpLZivV?~O{_-y+?JWH2z=x<+(N z{hf*5hw;xai3b2b6>StWv63W7b~p4>HPghyk%5X#k>?mgOZo|L4_>Yf<47v}ea>cI{q$ck-|PiVM_(r z1^&K8_#5gN;m5FX0{x`v=uI9~F71mFY#z5o(m*y$oBWEF)#;Hn|kE4YQS zpXqX>b^`#x$t{|SfIbkB8XkoB5{P`1f1-(paURbps$9wWlCmebug1hbZC}m6EBJO= zBzq9Yy=~&3MJ7DQq}H;_lK|ih_ zL9t(P4MQ_K&BX7t+2Vgjwrf<}!z#7EO2rJ*#D8q!-={4!ZvRp7X~Ft>*?v^AS;aku zsA4J=s#3`o0giFDBY!tu+pJ zUR`1m1_)nPE?v2JF^+vZYGu>%6{aviob!w1Iu^jM0-S*cUZ>%`gr>U~XNhpr=`7yw zRAmzCBg~ZdyZ+*gEv4NMCs3uHtx_*-H>I%kSzx^wTd12z+hktL1^g2u_@Fo>?s%a_ zFdvk4nEy@Ql;%s}H-Zv)3t37Y#-{C)eR-3463LrfCWKaq_-1{iyg?N}y~#YD-&~Gu z0^G}4+$3O8jA!VjBLsaIWsMYI1L!|aS~MYr(L-`?Wcj@Tp5l?xrgTrqh9RhQF9F~{ z690!cl9IFmLD%RJ(x?GbNP81Yr%8rK0PHWoW89Fi`JmYA^j@|dbCBXdN%1&3>;OHU zr9$b!^7JB5?QIAwsSB=JB^|PKo{D=yrQ-S&XpR)%b1~*dDPVE;Q%$l~cBa?targ0q zbNvVRiYX{=yWdB*weBn_S`KDyS%yy9?R0d~Zl{s?&7wqabv^WE_rRKf(C=A$eofgjx9`0qSZ8hb&^CG5}_wrd2KgSL%--1t1XC|RMup-TCV zYCkOX@HT)A0${h{*TQNfHxk4xGSkjiw=$nWs_6dQtXqgQH1Fn+{*rGf@)VZ{2R8Cv zvKA34@NOyN6#(}L@K#8dpg^61t+AYM%|@&WG&MKPHHDv2wudC;P5=)J@CkECfVt#O z7|HOj4S`o+Ye1hL8u`tej4HrK8&yQuUK9jSd`n*v;0KHZEXSzn`LiK;?T5AVSKaG< z_Q4Eqcb~lt89@Xp;2ta;%6ESd_1#}cDPN$-F9pEiUE zo5=l9l4Im5{mB7oV01Kq{rCsOQ&T>Efvt-%tZ5#l7dpXrk+m_mmo8mqPabyCuME=f zDU~)*rHyGfWsrUr*vFH8fw>;nXJXX_pZb{PzOwE}A9KM9PsQ7^9*8+KwJcq*PeM@{ z0_^V><-3n(KF38pj$m>Y*@L|HFm3)Up}Sb}9{^+}0vzTeJI1H`c}DgGSd(;*vMNbE z8bGxGyhcpgM|oIhBZ`k3jx(Xd#?Bj$N?~tUYBaS>OmKoF;9} zVR5&tQGjM_Z=Ejv35)wT30v(z17i0B5I=(@I*i!3d)jv)HU_S=Vx%MV5RVpp3jnC4 z7C1U&jC1=)=C1G}yom9yO=lq4L6Ynk^ok^eiR6zzM4mQ)u82|bp(+XP66L~K2I2Xv zO1na(-2{{no)++2I9uB$z(djcd`7L}#h{C@QfB^2hS5&q=VbooH`y;-B`-TxJKmJV zUZJ+OHvO$WsU17;^y-j4s$DM*VF^gjZO0lDcDB(!S@bhK?`SkVVDL6QD6o7P)>rIz zJO}`)=!+_Sl1e`qX~z4l)njiOXb~L)ZS$Hm-0OI6dT!x|ufpZlldc%*OB-EyoW=^S z%j28I;?!D1rnbw9Itzti0mYX5iZ}cqa;T?Yd}~LB)`(TW%x~n`I6vLj@@%62>?^9( zDG`C#wrUswx1uUM^j{Esm=AyH-+u1jekOxkCKidTQkn^Y>+U`dwT^YSAAzH~jro5J zksy^tF%p_o!hI^?!FC;Q@16n2B5ER!#8}oLS$wC;igOQWzZ$cczPB(02kCnW5;5piNpN2nk#cZPEfc&?YbTtsyfwV{hGV zzX-Ba4TPAZLtr7;3C#o*w?n1psr3E;_7MP)RUYF{(nm0cJ{p!esuRI5AD+(+1GK~! zRQgbrJ{A}t0WE;x>?MogNXF3DZY6^sgT_<}i&Afsv;bPfV8tzwa=3KVO?Vt3Cm$}M z^W=Othw=p~?q!vJs7haqTrhiDV7UxLoe8?EvBZ*Dv}lBBMER1A7ex5?2$|Y$6dF|Z zCF<--wow__WDzZ@iQJQr+@xkp)@yL2v&7tx(#Iot5e+ zJHwR6UKH*E|E&8-aPlH5{1O%Sib}sgrNcB@zD|Iv$TT`E&Xo5j?YVq}DX(<}%m|tC z>c%xNR)!i)`B9=UJW?v(%=A9ZB`hOcO#AZdkUr)L=~|*3 zRg2}r@>>Mk4R}JGMeT`|aIPdjNLW^>kH47lXVAt^8CHs?Vu57YipH8Fp|Fyt{gkO= zEOU$%p^uVa6n#~t-;CfN03H?K1(E+`lyaUgG3^>LW@a^5$+lVd=p=w!Rz1YJuRLX8 z_UjrFpW-6NXALJ|-T40~tnG)As6I-?|D@u7g{bDcgr4X(c_ON_P+iR0dpbdEr##^G zar#uNGiQwnY4%ag8ts_uQ&S#$p^aAS{o1iattWGvx$cey=T?tNi1V3@z{Lni}vnWk)pi6QPPd1b~^b+czvSz#6?0`MWR#O=Nugz!(lo zFh$h^5fxY*w-`PI043J~pWsl%4?GDqXpR57Ho=2fY*8CO)L>(3Z_OxjHwu-;$Bx7U9d?SdB+NX(Ia>+ z)gF)FrtDLxKiXUezf06fHD%VP4P{K1B>Qu3?3pR7w3JDhW{2ynsUbG)BEx=` zeJb`h9WD_5iLP$f_!TOR{?-Twm?ltv#!h&Q6N|d zJq`a5ij`;Kxq5II3q?J?Gd;eIT;k|y2<2@a767*kFp%jP&tJ7zj}4oi;6XxJj8w1~ z*n&|EO5TgG_cW#_cGZGtQ*b}6?3AM-?x^r;tA+#3q}+cWk;PS_MIFxmDg^3sT(_cyW}`~1MaM>*nN zHWjf~NS{KK$uQ&3D=L??%vmIj9O186fn_X9!&DITnE*%17}MG|u5e{Dg2#cOobLWT zh79rpaNurlA6w>kr2oX{#7$6%(^cX@xX*R>O{kg_k@bC;Iq@MY;cuk7^EWNmC1?z2 zW@w7C5}>JsdBGAk9{|h?7FZB6W!TG1YO1#C0cZ*NKwmZ~v2bOb=(?Sn%3p>-Yc(w?wex_s%8gzpAU9U- z@$z`vew8Jr!-dayNzZDBLnWr7^iO)#{OIAUa<~wMwdqRe(3V_qt~(7GehH}HQ=*2i z9tTAZUzJdqZLTYT0xGiwV8`uI#q|pz+nXkijOjG~r49D}@Kp(Og3SagZY5T^EO33u z^v?H(uYsKNbQ!)HkQ9~#n{*S{q6WhkIs2f;>VX*RvD!k*vZ$?Z^*>MpwCY@mxF}XT zJ{rJG75A3PxItyWBgiOdyIUssDjfEdfw8R; zF7*s#c9nh@ZJg*-6TcUuP-{du>8$&_K9RMZ+xcAA&Z|vj?1it4?`z@%=ptD#dSkf> z|Aa?P@7o(quYF*1=rw^p{z4(IF8~-IEUmRjv$xNUz4i*DOCZWW80-RJ!wd1=^xn)5 z&qn|m<|Z0WpgERV-#rAnZLGvDq()TH{w<4|n)ea~l&lVwH%f6OA`v3APB+bs)Hd(3 zT_MIZD#|r1>&}kmhJ#RQi0-OQmRR49z!9TbRPFKZ1I8}jBdeo{b8%HJ>(ZWcFxe(!Uo{?B}xT@#7>o2 z2d5qYFi2S70C+@S7t%L`Ad=CL*HCLhxJwg0LGXGXe$u~v-1eFN8K%PpYS-(#5H|<^ zA}5jk%T(NZD)S(fc_e5k7XTwg{KeJ;{6x_T;%qkt_lGKL(=SB&K?1-4NOcU#?)S-g zo!js^N7NuBkGZ0Jr29hZ`aQn`1n=((8 z!$)&Pl(gzUMa8`jR{)iH1}NT7fL5V6R$9eG3(p>n`tD4IWsmV_$!=s?-gRF(+w_mU zQ2i71$adHqVQr>=p1A6Bd86r#l~>cdnpk3m(03Vtl`8HN^dOZr6>0iY4O_*&cO{9d zaxV0JP{B7J;JxXC6=uk=_x?g$O&QN38{FS|_jhE7R)A6L z2#6%ngC4>Zk~=eT+7Bx31C_Z&Wx^QWA1huKcns^8R@Nc1$z3XYUrcs6yEBA#JH{D8 zt03Y&RGCkx%-7pZRaXJtfUq3rWP$0rlL-f!sf=tteLXawXhUcf;qDjSltg^~g)^Gsx1Zac?`MyN~H$$K} z+$h95q@nRg{R4WzDMs;JQvVdvU-3O5gI}r@GpFLY*jJ0d7{2VLWRQNJs;p@$3v-yN zqXk$NYRAb#C>XI~X?!%Q5HiB3d{m|F+u3vYL9YM6UrWuNZDn-TYSZB&yx>~TUwIe0YiLyf_B0&2{SNOM9W;BTrwbhi&2A{dzMO9l>+~+E5 zoyxi%l)^?}fg3}n_;MoFjye6Y`39oqc9ne+o|qCG&0(rCsiymrs>yFolpD<8*qqe+ zJof}AjUa1|=43pn10qc7O3;~c=O%SkkD3lwhmn(|5sWTVFpf3N4NRFzQ4eTk!1OL9 zws}>>eW9{$R$2D}cujyER8wTkK|Pxv&Jq52 zzhLJZ6RLKrxGz=Kiz@4L6a#hB0>6YzX@yi8nYSzcgP|HFqk>TK=`50EhLL?fKRg5J zO+`H4pBCvw;nDH88xyMgskpCH)^94iPrIp36(Aotw+JPmW3$_sP;o0a2}XuBVQn`i zWLqCLJi3rJCcxN41IKwdT7c_X_9Xsi38pHV9k^98__% z4IH$=Mh+^rS&KNUsW=4}DB#FJ6_ZTG86fEllDd(9_&zq+1tjzaG||Om>dOuz{Y5Ob zuhx$dKD!r!n9e%u7L0FRF}Y+#%brvPp{UI;)z?cSO+kxo5@4p+VzFoLWIsl_-WdA{ z5rXeg&;FJDNOao;z)dkB-%;x&P`IiP`bQ^9Qy$TMOiMG4J3xq#SuQZqOau&>8Q{oA zGi`PMU9=x^Os>MGR=F=NtwD^I`an(902@05E-4}YzeH5J0`5Vm!cS0{dvaxd9I~5P zvOhAatF26|l6HAHdL*uXM`{Z0D%I}_fXP;uL#eB-qgn1fD*H3IjZ=fR>3XF5K+-J) zAvggq-M(6nSG(lZBE0(8s7$IfQ~j|##%Nvri2#f75`H#!hV@sFM&N}nY1DLH<^K3( zD#-_`8XDm@D!Umn3&2kT!0HPs-{3y}tx@pI??hsD+Q|p>5FBgU%>bUucVdILRbX#f;Gi*XA8D0&vy2K8iVWP@S@6O6#rpczO9KP8(E zrf_Od7!l}IEnZ<=$G*B3-C2z@3f2QEXPi7g4ZxlP+=rKF(WzmhCfa(#p@%2g91~?A z2qMQM75A;mZdcha6WYOuZNo+4cuTyTEH7W7mj_^Tl6!eLUShudoyvYqWq(dDr(qKl zXpSentNKmH;yEtcwa7L@#q9=zsq8;M%~sRbu24b)=z`4x5OzCngYGU1 zZUg41xbIc=pDL#}vd$GC1wIw^R=s*AVr6Z>VoA^ssbPw=S<|gzWfVJ(WiQ2^CKOFE z6b2k6X|RM29q$DmX%`vwjh%+Kn$mMY4VGQ_G=>4IRNN0LCr9PeAD4#yC=mXEe&CurhlH)Hq|Rlj~!Uy>hZkkv&-~&4!@$g^>|hqsh`v3dORgh zQo!+8U_%2Y6D9bY1cMpk!r-p2qhymA5PNl4V5>gg^!SvD|HSn9-Sqevzh3blabb6& zN~QP@lwQ#{h3wOzBifyFPMt&L-^w@wGH^$bhwZJQ!xI=OKmlAf`106K%XSD8nav}P7$z6 z1vN&dSs0*dx~RAxRnCDb=SZ7@ERCF@+HyvXHXSb54bP-9VWQtaOGi}DbCPd>N!S$I z`D@Zt+)pZJzRJPsL=BelEr7X!`PO#+CnGw4O+XT?Lh5`0PI8?;;eF!VtXB-V;d1A% zDUviN6Hy7Dae^I&Vvf_$)oRM#^`}BLaK!qL%6UTNybAQN23X)tted5I;?LD z#a}G252!Fb&qN38d4}nGh3R=Zex(EUJdI06j~?YZU{5>Z;R)@Lt>WI!h9f)~88SUj zHGLhlQh0i#XNtEhnWrtcQh^Gf`B1zf=efTv}PY|nqn6SqYc@5Z?vJ{ARB!aZP& zuCWC`BX^4j0j#KSI7#aRh(MKdIU*m;@Ax_Oe_mnl`y#qo&8aHx7nSq2%J~w&KOB&o zgQk{lKS9@{o54my3NE_+QC_#NStIH5ka?{D!I0*aAzooex8DcuFvQSax1SWobfWK0 z(-+5V2>k)mcQ?_q(Zd4Z8UYHJp1t{_C+WkG8$%DFM7OWGK~fc>+wZMsGWOl3?{~J_ zmrt@Q?761qOjC7Ar}~zSgAqNcs(Dz&{i zcHa+4p5?nK`gHq&=q8CRQ5K;Z%&aZ?eSrRT0j8qcvgb9cvS{@K=)frYR46_*5Un=P zG*W!@C8A2y3=ivmLdb#oGMi&7a(tlTep9*ARW2Mb(7%#4aVm75LlLRZ$t)rY81+VeADa!RRk2ri|`p%u;kd zvld~4vF2_PPXUyOUsqkS9DKU_)stify!)mzraPR=4Tc6hss^9a!*8> z-lprP$k8p#tG0bix6f>jUu9F(JmmOI#r>&rPg1#OAxE<5_N9|n=?lWGl?xGU6l)wy zTbh@XC)B_$3jcD?QMpj92PO(|Rmk*f^P3t+A(Hq;H7p^il}-knnk6K)YDUSM#d5O< zkJG0Jw2-!?Fe~hXIwdy+gl5k4BGY9~KDftLSC2#Gz#ovLH1 zE}=GTk%ArquvCDjh>J;q0seEyHq_a4tF!Ju@H9d34Dg*U07kMZ+Op*af~vJlDf($E ziebZg&V@*F0gI{&5T%VNUbC?bfjs9lEnklPK~>v{+;xKSEdZAa@G+AMKSRjPweWby zKaLMS@Cr!*hjs)ZfqMoaSual?1aOrAaLc1vO-&dv&zX*kvFOX`uazVZApLa$p!?`4 z6d#=mI{BWytu*^ui!24uR!wMNC=-KBH8E%Kby-bpeiN z1?T}s#eRNs*DRNgw2?$W`77Yxf#`2~12fnLc}qQTt4ZF-Fnaq9+|{mjx(ehO@qi)XzbfeuPeePd6mV9%H|lIubOm3CNSw_7alZ1^34S>Qh?rEDV0xf91Y z7o*)dMko9Py%?Q2cUy~b&OKsB&e?_-y_GOWqRC=nbmnZ=tGpPU>2?20jL!5CVekb6 zH%^5)6*U(TqjS(=)8Qg<@uTh#q;pV<>2RStV2RsKVm8xZY3UchM%!xAuQKUt^tg8V z42jaYEHX-G&ckiabe{8&tAq!=N_YUv#_nOej*8NGG$a_jmceh2a+FT+>?5|v4LZkk zxNuln?-UoNbI_4QC%!!*Oy{7>rIB0E;usw)zd>n(VGe2){ze^^2A5y3;O(Y&BE4(V zS0LBbk_)CaeTwPb4bNX9!3)`y^pJF~7ff#`W+8Hf8+4rn9efJF^-AFkkCiG9%Tbi$ z3CZD(6C8A{>2SdxtUnWAdb49B<+Iim)XN*D_Z?DFn*=$A{b|r~OF=6%zbv|y$hF1YsWj=h0vn^K7??;k4f4B%qzcBjjeu@|?_ zr>;@9A#KbRGJUsM>ih1%{5Q;pnAUQ?>8$~#l#odqQH&m`@D zs8S|rDxV*gM3D^fU=K(C%VtpQg)HY&&PEiO^duE+l8apOS5aKdh2#%#a;`;K+wHku zD`@IZa@iygG|3f6^%I=~l(X9;{e~AH^+QRzKk4-DxUr-^!)=Hl(!P`2j9weWhaF(+ z34Gor&YI1>e<3LJl>J+!dMF%QnRh#Y?*w?&z^86?GVVuOqR`Z%#%vdlU>nVcEx z(hkOwB#8OJ^A5~GMd88sw#oMmV$RPU4-T6Yad6lh5`fjGe2P+gsJwSo-g`id34;Zo+=B9n zsP%|*&vMBW>}s@!`;uv9aO?#>``d%V4(0{8gY`k0PVyUkq?Gv?fcXNzf#dnD`e67) z+BpHG#9YEs_dS541c1vFsGRMSmJoGt*wS!>b8c>;hD$PbnhZWcvj2+ga&Xu&7<9>t zgEnw-+1~!m!DlJeTLrRIpb(kQ76AK0s!3ZS@s;)ukO1CLI2)dR1FnY7M*5fwB@WYj zw`(-_7;1F5$_zSk!HUJRX1nwLrpd|IgE2d?ol3ycq$nq$K(72YhiXKy<}FnF`1nSczK zCD;rI6)xXC&o2)~IDCBx!ZF}8;i^3NZb`o%o^VYa6^5ef5r{w#$WRCqT7g(4Q6%)Xni9BNvh@ugXzi%D z;Ru2f+6nLw$y>;2o{$GASQa{dI*$uTPIL8hrn=Rfu%4*P+$m0!N6`r zL8CHnsN4qBIp4_38aq$It5HZ)%`~v}6i;A1t$?o^?ndanELG?fSOyjmf*v^}D5V|+ zpg;h)5A)1?t5LaO_+GeD$G|x6wD_uH`&)kR&rW=%<^aMrKoA@c020-H&^g348hr|+ z>;sQV{A<$#kYb3WI2ZjWpuPE9z|_!*ghLwS{S5#{32-B$gEa=|CTpIDwdn?=7$Yfe z0=fhBa-_r4aq{#a)TtL9W^kcNT{I?aQWsL1$x0=uz|ATEJKqqe8p79(XOj?}RN7FC1?1baq6a9zqU%>;ityxi% zzE%d@^flg4o8C(GnELJEDt^6+-+s};Va6k{Qvv_l^jM_2T~fWp%y^)EGoP&|Gtmdc*3o}Qgso%9gGwc< zz`H823n(5E;4|1u$kgJx@L#CADJPs7ZQ9xS@Ew;SEA^zr0DLb zW;S=+g*7i1A$`aXN~Ng$9x5Nh&X6Ak=m(?8BhK7thW;ORk)g1QSRASCW++6g1xnB> zBkUrn)-HnjUB!*mnO$UvHEtlyWy-vxaxXs^b==aTyBBi7jDzgt6ppI>j2vXL!bvA(U|+ zNxK&SSWaxl$(_sQb4|K+oq4S7Ne0#*n@Z*`2^7L8h>6Gi+-+WVZ28VT1IAU{Si%@ zbt1MikudTOmLK|W1wXC)CY8Sk=r9CWpaoj-CZ}ie!ScWZ`!{~q13hu^9U}S(xKpV# zmA_QwuS6MX`YdYN6;4f$-$+6m(K{Vc)+!B58;tr|baZD*ANsgb=_>zdl@DcT=o12* z2x{7y8WZ1#E2q@Nj|4kJe#j0gA`c>|US=})QVf)RngZ{>T1BVu1+~pVX zAwPIcl*(M}!b5^bJ@_$(@9~a<&&7UQB)Ho))Uc_h!-d|MFvKJ*X*UV;(JG6m(Y)i} zcg9+EhBaX=TID~X@}ENe&J$nY!4F#@II*-oY^4CN za{>GN6>)Dzt4`!`@bAf#%(LnYJ58xPg|nXX-v;8-1^AE=#~cTryTdPtPPG^mXNH~G z@d9`LtyO0pPmkp|_+eK_nID0GD+Pd*gH>lCq`XdmADPr*f#|`A`7R)h!v=w0o03 zVZyd28evi5_bl8Hdkp4O{3?0ATW-G71*Bag>DQ14-|^j7P%(LGglXlyU{%iuSeqy1 zEk)r00gevgI64fgd{))_D)%Q{?&ZHZ%3e|n_1hABED&I!(gN`LYqsOEQjnD7M+$=e zBQ*Z3F~Ac)4??D)lIdjV7vm7+kH(SOT6ww;ja54zA^YY2*oNjeBc&RxRG|u2QI*7CjesJ^YI{H`X4YRFMi^ zs)AVSs+}Rg)tKBBTXW-wk;jxfhO0e75{8j$rT{m242RjfM`ACkvAje_-Ats9xuSNR z)xyeb3Bst&BNQqN1F(kRwhF?~PnD*}JckWa>tp*`kx&*Ia z+QfYZTy$KY#RLgT{p^;x6eGG8GS=dRGFbbp02wYy@j8km_P)x?6W5wFq=Lq5vtSPj z?DR{h>%sO=`;t6|sL~C(B@7L+<{B#Gb*a#w0KB18xhlw31^K8s>I&RLcPdq(3h-h8 zlE9i`0hqj*|7x@ST1M{&MfnuLCsM1g{ZcZ)bW#gxY%$b<8+K7M!en_iu;Cq4YTMSk z0eq`er79S%3PyqGL-ctz$!}_IIVKR6(OEmwoBG2)8Rs`ZpS=5Qee2bPhDT7s#U?ks$gcjsY?=IZpaMo=5y@( zRP0cH#V~J(U+iFJiV9bFs;P^;LNGAWKg*q_uI%rCwFEQs$B>wStcB+%qJ@EU<(}7X8#_@uMX$m2A8lNEJ71nWk&>{pT+NI@-M~) z{yPG+z?TVcha(^f_l3Vb?Kb0D@Jih@`4r4D>-HDm5@Jg_<_$e-tgFQROkM0Hr`=|3 zwB;cs8;3qI@D2@|Tyn>$nm!UqADi6Ol>9``I7Fx2)-98?{{*mHfN&?q zp}c*S`B>%cssEePZu9o~tJ7}t#yh5+;IZ#Me|g$%-o%L0ZgY?LUyMV!v%=J0*^`DM z#zq*2>eiYL7y8Ls-N80gcZun6#h!MXdmEdEavwIicgC28qE5Tb+rLfv>oivdQ@tvH zEy$UM@}}r0(~vvu794i~n})#6(;c(4nY!33;n? zBUh2UV{T!87)K}SdXZMz&2ShnEYUjv>>^N82=1WUL5D%{bfGAQ->TGLRamGBp*jwSUBUtbuoiU*wK^HywqnSY=5ECkGiU~$ z4ey8gGY&@YO(r#A zB363hO;(zLs-Kl6RHo8GFl(j%baeOoU7lPD&c(J%@Y^~f1b;8VW{qF??&7FzS9SN9 z)J!TM!(>&N)O7rM1<)iznGaN6*cFhPB2TVH0YQF;uFZefL+gjyj?`EB+pg#cS_r5B z`vMOSn5@af;LurzsKSA&a3p{~1%QPcNU;^+LzQ=pu7?o?f&IfF3XzW4-YOSDXGCvF zKdIe}=pz7@lP0jtMlxW~w9O#;z@ibEk`Z>35m^Eph)VJU=+MSBAlXE6 zh1f4h9)Y@29}>nCBWt0_TEIJ~Kp}0*L{v$js`O9+fL+0UC)UXEX$Nra{7WxF?&B@W z!ALbwQlS`qfNo~&t4-D_#txrDUYzZBgBj7+)b{9X=GJ)xkrDeUHB=QIstOmQl*s~| z0DYYzf^d_P0$aO34V+=}-KsGsDj_sh?2K``BdtW>P=Guh;W-F&bokUV7g9^5i)n#$E=z zdzN}0{^F>S)OY#rY5iwp0oRz+KdFE}Om?zK{T;tv0dypXG9RhD*Q5YDjlmPF4p7&| z-78c8{=SR?e&oBCXr0q*eKY(Xla`7S()yX~a+8*VUnwCinM=R~V5ch~t&co;*Oq{H z?@$T&`!+o1VBW#qTSoPdEMbR9>rW+An(RiCR)Jry1Z&5Ee*1}(P{JkP$;Y+?+ZS0AOlsf!l>yK2>?28#N_tvfbz}$C|EjQfXwN z%vEfSW30h8MwYy2ET|`g~$&v(aJ_vOWwPIXn+6@p#`FjZAc}HE~ELD zf4|}LX8mwwBS%Qqhk<9L08c=`ZSrG#jpV%F8FhjcM*~>G4L5347$PqFT$6o{FXC_- zX!cc9S(7|$03c*+Wj)1}HJ7XSd!x=n{wplj(TsJDQ5P`Q^(OmD!7B9#-HeYf8wn-K zqI(9op+s5WS=1xV&UmOzvkr6MmH#luAcDrGj`iq?oacbZ6FIMg3o;`kq@|I2GNbvG ze}6G*E0D=)pd(ia32y++Y60FsHNN9l<4v3uF*vr{4?c=N_+Lid%OCu-$$m;cm|5;! zszpyey#v6LPw#RqzQ~>J52KzzExu)u{sYONN!be7iJ{^}qn>B{@0#p)fFJ+bG)!G1 zFPBvBg-~yeMxh^5iBO$vZcNKYVr!fQ-p9+eVH`$*|Mx~!e2CQ#oakt?ctQ_0;*p-v z`+)EcFbY&4nNdUW@_NCC)hwf?B5s>|c`#nW5?QMXKT?I?(#y$o3SkYpgGoiI$G*48*TP*6-;6-RI9e@QJsJ6tWE}`R zShu%GVN6Qf;XhjIVJXzwU6c&x@8U8^2(#)9vfA)>E&F4p2o+?WP`UJr-Cfy1l8W zzz5pdUI46wPt35&eZ5Bdm&t+v| zbCyN+C9l8Y{1`zNko+rwEMI_CJ~Dsq8o&Su!n1S^_k;RUNj(=?VRf`bt)^W2%OlYtZB+TuJvWC|7%uaHt?)GktV0tIL-@FI}r z!T%T5NZjSh?mH~aB`k}Yiq=mQY!?7E#I;3@DL}#$LXEK8jJ6272=K2>!>O)*iX_8~ zLHC7oG0BYjsq%CtGDbLpe-#r4U+VZUrADcuf2yMEk@;`|Zu9Cm`6rr2C4cX;2)2jf z!PowSh$gihTH@Geo~e($=(I2sf1`g&*qnBKcnHg`*r!YWQgC6yKQ<@Bcwzz@8%-WI zEt)*CW!A3}`tAh);XW2|A64-_NHauQV5`Xkf$MY;*SXa=Q27*s&jhaGhhC*} z;)nJB%j3f8FO`yaU>D05Bnqt#ocuWp2Q+z|Jo!wX)XI}jt-lX(HdWD!s_0!*&HVyEiRw~ARYRgQ za5vL|@dB9fJBs4@b$T#XJshPhwvT`fn+7cKBdYLRZ!jit1T2l%GvXvG&HGHkcqd!y zAx;}r(a)+_1IgP07%(-5P9c)gZx@orF|x7nEQ{5!>LE@oo-V-ii2!{NdSH!54B@g{ z*Fn-=jB8Jdb1Mg9)$f*keSzeA0a75KC;EE949>VWtTOyXn8kjBe(Il#)ex`LXjPo5 zii7Q@0dmy>WzJE5oj!sQjMtY(A@GmIYUrcX7*$-MiiZIKlvoQigmjo&NyE^H514>h z-}u+2FC)Kn9EF&@|GG1e5szO^@6I-$6aFukGLsrKZCLq94+)c8r+XfVK6#RB?+c zJ^^IZ39uU6eT^0WU&o&A(aQM9O=FV{5FdFG&u27^^s$qg) zI}_DOoS5s5!m36wJ9R_9E1cZMg7K{IzUwSWpWz`VnWC%K7@)$zDb@e#5NlHZay->G=mB_Qs;WCJt_JSjRq*lwv78wAQWT^ zJQ~uambamzLB2J^P1wl`3L-NyQi?TPCAl64imL^{Y$CC*NU{9Om_A@Sit#PgaN_pP zfNH?9xh)sdh=v;lcrj%1S9-#N&df#rWpYSo9g_ZAlD>qFHpv~**|1rjlGD0V4u)Zc zSIm0Epe88~sYIpT#6Y4?P~04DU8nb3>4rt^N>sbDZ293w9)i z%)3~gT+1pfT-Jf$7-|vxJsLI&tbF2brDLFHO+)Mj25QkKv?Bn8hVwiAalMln$kg9q zGLt5TO=e${S8Ou-;8%vU%-&ou8v9ho5}CANk(>V%3|BC+;oZrOHBQ0-*WLKZiBV?C z`e#gL85K}!^6E`y34Xl-iWwbR;2bG{_StcpoQ(q5Oc^+f3P74OQ9yw2&hX8Y^?SL4 z-sT1-dEtHo^IDb>m~Zk9hlm`7brjn+7{o^PazKfu4sWfNf%C~~nRkd^FSIOVcdv1* z)6x|!(^f27(0n8|{A|GKB(%MmFvDKJm`gAsjVcx(O_pm~P4AQNK~`>N@1Q`ZlidEx zkpKL7gcfi~p2MN?uAs(lg{NI|{e5w9aeeT=#{a$Xf3G&2E%uU2!%c~e=c~ivu<3og z>3wo5?kKqI<$oXg)NTPq+}i2O5#Dyi{HDN!Sx3*BHfPy_r7Hq6EdetTJh>SOSI$|1 z+FaQ@w`m!toZr$i_rDC9Y7x1psll3{jhbqDqeb}#V#T&Qlyz!$40vnMB$N2AHALs} z;?afRSvLxscsOC%IStkR45{#R00#3D#LVCe-lnRkQ9+Y~wN&)Y_&E%b5%SR?=zyg)LRLcpQx^ySEXmqj@TsbI>m z>=6L=)Af4BzRlzzv;;oM)b?WoF`~DOnrudn53^YJyoPzL&T&h00IyN!3Eol^a=rjV zLuSMkzOWf_IaeyW=oO&w8Sa{wBgs0xyG%dm)vCg-Xc@rhOT&VZDr|!Q&`qB9suf>* zHNx9-Z_CC;(R2 zNg2jo0xDFrN*dbu0D~GQm|+xYS8icy*!vNi&PKhc)IO@@5LI#{a=#?N zVhCnBaLGxw1}oRm8n@ty8TJ-c&hT&>aXTvWW~n1Ocpf!ygVexdT>Onr$o>mRpXVp; z#Q9P0n+_LIy-oM;G#F^ZlP0Se(m1Qg1csZeLi`GaS)S~@-O-#CU@Ab~ZQ!7CCUmQl z##=%rD~F$Kw&TvI-%N+gsapPM)9}8@YM|olO<=0Y8i`-8_z_$fIy|54j!MX?l_%R# zJlweO4y*tC_Z}2KgzxT#haeZw>1lg`+jif&XnFk7RT4V@NAb6nD5TJpRP2i+RQ4+X_=o#%{0Wd~@)0v*}{8bN82+#m> z5?2-@)!vfo40IP40yJ=u39NOZ#Kr;){AofZX2kdq{)DvC2tt!ghYJZN5OVx$)29Oe zbiscn@JFAv_g$<$9)dzUQI(vfO5jQqnk7Kk({58PK+Cz=!c)wy?);(9EToUQLK+R> z>$LtP{IAZ|3&FA97Jm(jhjwcLnCw%|^E+J1xy(K2a8KiaT$2J3jr%9HTLrl*Z0a{s zTbw5O?*?$X0N}5B_dRqT9=gD@qy$rK*%+@yItTz+&XFt^)9w`ibhObhyAkolFVVY>ZH-=gnHYc=oJ0iy|~@lRpnU-`Gz+2Ij{`7$EGI4MB%s zIgNhyiS8XX`Ey9isk?`@oUC(A=zCND)qkz!G(zxN#Puizg4Y83pl5QQv9r|rQCt-$ z@(UC`k{R)HBpJbXpUF%C7M!*yC8u$mAe;#7dkQcuq(?9}QM`R{&^O>9{No^{jj$D1 z8ep7+lGBJ^R&qj{B9xr(#58*Z@WM1}b4*9tePNny(~C&S(UbKZxPO8;2N4RtpdtGd zIJuMd6HJrF{ZW5|vT5&NBeYvCOYAL007QGi=OJ(3{Tm;wBB^)ifa3Fz!>Z#hXbH4-APpTK_w> z{;N{Z^#EQI;8x-{nlb}H!T%C-wDAi;LCC)p;67B`ul`rm|H71hpz_O5%>JYZ<(DD} zJQ(n-gq(rG?6VUQbF`t5Fv2g%R?__d{uJOzCbuu+sfdU+Q3WszSbJTNZGY!XrX+~p(%o6!EfN2gW+kM%S47X(9XxNzBpFGfamI3GC_?aY#AJhOw9lDZ?3@kugU{FaG;o z6r&d_HC>hUR%L0xvP1xMnc$y(H3wvc#exW|prEK2jG%xe>IaC}yCO=l zV?jkwvHagNb7was=<|L5=f`u&-uF&BbLQMLGiT1s)#{vJ^E$Pn)8K{^OaWQNtRX zIU0Z8|FTmeeq#V~an3VG)83&b7ls8bMj1`EN~FC{O)dwu7{f|PO+#>uM*JzcSE5@u z#s6kx*5d^~_nD(nV`|NrV$^7p38R8c7#Z9v5jDa%Yp=v~2*O+`SL5Vf3CQeN^JV>s z(i&elMx(_{^B9dZC|mA@8*Y|J57Ui2xSrC{J1BYMLEAr_Ig0K-pIVf1Uh>S*^az~_ zW+P)RwJ67PedcKEUHToFN-ZjpgvWI0=rWZ5cNhT7(!+)IT45cB4C|{E_p~r>qU4` z9Mr}z>A#B78()ZiGp9^N4O&0XJfk+9&FF(rT%!xorDZr(wtcofTw)&&!tr(>v6b3H zBi8r4**t0qwf-3aAT>`%-Q3{J(blILoM~|?UY%)CX_^|+F+mtDtP6y75z>#;02Xy= zYT$_z#ee$@7RIH(%ZhTxs`c0bhRj9^n4Pb}G=7GzDjUTnjEbvB3 zZ+u~z#zh!s9|CH@aS`#%+NC;A_|>Ij)lxBSgDfC9RKW74$3^ro+9}HU_|jivD!n)x z=y1RwT%0kMFUJV$lfqgLuwH`~%?6Onw+@O&s%meQ+Kt1kvtVfte_?Mz3v4!PwUN>r zUl8?vMz4B|=CLzT{yTgOGzL6+~0B(i)9T3N^;Rch2= zEdzUHDH!abwwOMh5^)%3;NCpV++SN5k8cZ{oop7gn&CE3!}AMj51DB~{*ieuE4HvXX&mhbrb60Hz%Z9M@}z#-w10?R!G- zJBDD7;H%fZyZY%Tr_NDE*iGRZ);vOd{CAPF{vl(hAKhu_nnB_jp`Qt2-ayD zG|`>-G8A*xLi{)Gefjq_$?IM6Zyii4yjcq@*k+iH->|Z*g5ex;%@wohx_k>@*Wd?- zaUBmrmK*(;IXG1Wp|I|#YQx}R3^J~iWM)A7tEV5bG7gzm&sfU5zR4BEW~*gDvyT(j zABFWdWChKxz~2p8?b{&JqIOD>cc@m&NTnthNSbVnspkV6MlprK_8V@hLRC2Y$wO^8 z+$=N!U3mtUB_#z3*w-aFT4%8BLUmQ``=AX&yVKkE4z*z~EdHvz8;$7b8~@ehS_rQt;76ABWm#hNiVG2(QuLLI=K6fi@ar z^k4?m8nFnSr9&@50aqBkR2$u3KDGXGb{qW>JI&*ptXpWI5aUI{#Ui0IGP+fRNZmp> zi8{>_ua=8@IM3Rj7z;xlMC=)}y_Qf$;|t{F86)c9F(^M)rrQfzh`-bu%r&vnJFV0+ z!J9U7F!V{oRs4(xG(j<-Zj%Q6f~^-BY`vI;szF)D#pP6utMsOxMQzM2W`lPRCBgUq zz%1SVF&Hx_Nr;&ryqgz1aw%r6|1kOmNojg&%NX-*=B0m@g7a7sYL}-ww(Cf;eVTp^ zwZS)N4fR3PE&Lr>OQqL?F9hK<95@L?WA$IJ_TzK)vdqEWNtrd%#z&eTq4h^6OkpL) zY4tZ~jV|gFw0_eIA^EJNhD8Zl?Slb-bT=zB11|gv{guih^tsmVrq2QtmUyw%_y(=i z4c-Syk(J&_-WvXq^zqle@Lk?YudlkYoWJW@?wt`i9ueW2F+Os}WN)Q6vSPx7>dH!Q zIlfBMs?6h?Fd1Pgo5;zY>E6g9ueV(1R~%V1Gje=`%*VsGVTjioIm&c{(2N;BrrTtn zZ(3DdMh(ZRiJVkZUK8EwpK{Bo_LN6vRhN3o zD>$oeqh};qBjsNka*OSe6dBvy%u>ZlisU4we+TPz`G2(PPwMz!K=k#$ir9hX+i|Ua zaFzMsX8m9Q`)bIz{mtKgFp$d!S11*b*@l{24r30>n5o~e4=L#Gnb}3Z&i(5t^KuQa zg76;n6(*6F%e-&K=3AK>Ww0S3yeB2V$CeVZ(UE1sZCq)uK>!IFq=gI#;XNoJlcQ%T zLxSTCN3DM0WB+4xqqsR|J=$X=QrvuKey+aJ64MpKP)Z?ouVJIOg^qf|z( zVqcYi52%42E6U^{zT(o7qH#*MXoZQSNLG-D%90V)MKKD@Q<@q$4SH2bbs9 zMT`bmu7OIlfD^@aG3If((hDZ@4jlv2eiE%o@EQb)z#KGnht9j?X* z91BLR2_j*JNSF_RUQB^S$mv3sZX9tkAxM8*oXOUWl-c;gyi8n%h01yoF-UA-`mh&+ z3&g7=dvY!gb}?1LVgSr36u`Fi)@Esmq0%hI1*#^ybi8>;1TRUI2$OEMs$-F&mC4_@ zc;iy^Gl#KtWyOY=?98E*dV&jmS%_khuu>%418_it^+?ZRCwP@#HBelEWUqNhP38f_ zZggR_SygPshIku%u}giEv2?(NV1+{!av#8l8o<1*3b{H|2)tm>hDq$#%n1+cxT^t< zXz;L1DC-AV!F&!$3N@Me5_W@Af_&lplr+5QB3dTg)V(6%F_Ewx8K2bPc?V`7%xs=Z z;bZq|wdb^mE5;K_a^YF#$N>LkX9CQrMI1|jyeXovz7BOe-a$!y*+XrzdqjgmFk@HfwMkR^UqIDL6ti5`bOoYpm;738;B#48*wB4h(ksd*mP|^8J5sTC zsObls#l3`@z-R5z#axXt_i9kArw?+jFm&cLFD4^J6+Sm|X<$W*+kS4Z;J7D(6T`SV zsG63kw&|WqTUoi!=ABSlGOfzXPcA9^ekU{kL&QBT2!D6OLlhkgbCjjvPo1a~0BgA_ zhiOoD`$LX7Q8MK-#zEEw@)Hx;u+*!l*P$YjhB7A`BkL)fbVwyajvAjL1)fIer~Lq0 zXi%kO)fX_n1_K}!^~M(}K8*58hrs118|%1JL}Il_oP#XiKwL@2dkDcgt_qopke`j? zD&!18E)rs@NSrScaZa3Z!uSqMq-2j=E{xwxS>IFI1rGe6&owQ_*%woj%YhO&OZ-DW zjTN!%&O(%m#APD!4vZR_7w{;=>^Nf!3x*7(bT`*FUWjs$c$Y|A2Y`iK1@4!*;6w;$ z-QG&;X2(*K3nZa7JPKH`!EQ4@VNhkmS4JjR7g72(TtIi7=OzG{a8v=Xa}c0DU#sDTx^_qxQi5&ybNPJV%`@8<5A+WTy*JArhYviTjW|LxTg_fPhZ) z1SHHH2)ruu`wxj(=8zT!$%I*{WW4}mbZc8CeW=dj9e`mP97UW4=UP~Cu7yji4g>nn=n_G$d- zkLGL9b;FM|_%tjM6PH3=!@U;kmfI zK;6!VJa&+8J~hWDE)1-oqi(Or_Z>?20Eu0yV!V;>_n^Hf8{<_~jZaV~C~pOhKnmYy zzBHdnVlRsgKH|ZjV!{`V#XiPxiZTYsd*=RXo$y6=mI@m7!gGTMFPqJd0q!)BcuXXI zhg2BgDsWOad+1;*ITm133^?egWZq3<3d4J$+jnIp-!g?B&DHqA`xVyKm{o67J1}YG zf2Qp=d#_#w@p`Zk0zFbt{bxhtE3!_5#(gG8Y94H63_3M2?favBu3&LL}{js#k{r6*Mj+Aj!Wv*gM0HoR4XmVOTNa%B&Udk3aL zsnOBEMq#LdkLwB;sLi(;L^ufF^x_776~h-U%fMtI`+FUZH7p|=3;a^c!icUI!n-g+ zZ(w31-mV?|25x5=_+5zWL{dwUbP2#24F(}j9g>*?TIpho7z~4CbS^TJ&&}V@;K!CNpB#g% z1RLe)hMlYvDpRow`rmnl1~#?byTpt81CK7bqlTIHKG^I`5dy=VnL1H-fGiEJ zfCDjSP-m=XWtS-F_)!ym0&cLHAaOBzZ1Wgc=QTQge`I#81_OiJS9{8_?yvfbK1JBr zjp@BI&>9mQ#z@@O8f9o3-gdJI_j~XdweeHf(nh^m#xf>7^zY4l8&;Nj^&73z2;S))dMACIgzCZ&g9do!OLWS;U_ts)Mfx zEb`8+|J0c|x9Tz$Vwm7CUl2$l3c#s**yxR1ae@`5JC-mKw*^IrVuFgs`K-?4RuKK1 z28$g;&6p@-9SNLg0FFZOBtc5hlVFPuZc^YBqPFWG;R`xp8J;)jN!(iUVKU=SZ#rKU zqFN*^6-jpiyr#jr5Xus5%Y{uQ-~wZDgfdn)3A)IU8SS_vUsCJk`P9Os3g! zIKTYIj>Gw-rUFI>=T{m$3f4uL%|?`iBMNYGlPtfradC)~qe7fKrIT(&KBqO<22Nff zIr)we$rQ;`_?*A#@W;VQtGS863H__M!{3<;$yrh&WaxR8vwHB*g+cXnkyIy=o&yNi z;A_Nr)+Cta>>0=zQ7WrCi<(p5hBx|C66X52zeMrT)ry*2AhMs~sy8ywoiNQodBk^U z!yBq>`0|6=I$;RpSsE96Yp2D>nTRlNHU1g>UwnJU|2X`r&_pQW;0 zg*wqe1^YZkji!y>GYo=vk4k}>53*n{@zaa0(cL94Qt8H#E?8o(7s(kSIS&Nx z&|nk{8sBLGc@Cbn8^Qu{v2(30gQRwLYN3(i4-0EU%KVRvFc4F?a}e^cMmN{{0{bPC z$B5)fAmsxMYB0z3X;MH)m1%U#Qu{p7OXRBK0&$lkDZ-75j|`8wiRI`rHOX`0YmQg5Y2%AnUBT?wB8nS+_UBCQSpYgG#DkaS8DoMjA&?ffFt8gTN>iPBM?g!=Z7zz=5=qaQB> zh}D2+;>rj&8Bzuc#*uhdTj3gT&{OUyor#^`nuGiix*W{sZxYG7MDjj>o*EpHl)=P^ z7Q(r32hMGpJ0}OTbsoo%p;Ln&!NCU3${p3v1hh^92mO+R6T!i&CH-C!Uo_?*EUt=9 zXqg;XTow35(y2IDLgJ?o2gm9tr@%oBGEOQEj@OU(A{&netgI9VA5a{eO5%)4FiA`I zOeDbIbhb$TO{74v7)wd~rOI20peZ_t5cC*@HB&)PBB)e|IU*%Oq+qGUc!a{jP&cxx z?NW(dDJPpUOC0!d7#}G`nNvnhE<~8ZS>j)<@g;Jt7GkbQxlp8Ffq}vwq_EbkoTZq| z5@Nnc=_FF35bt^oqLGpeHNwpyVER&gX9OprY?bYl&P zD^+r^T`mU~knKGTgKY0}20L|{On_Y)3~jI+oKLoQIr@7+zj7NV#8Q?jEDPX(2Kndk zE4R!O;rYTcizx9N-)AK1iB*W&E$Fz+0qXTcy|E~YI^18o2mL?3)~17QG^5-U9L>%q zx)Pm?Tzxj89Qq`F%gx4F-sKe#g;`RPZe#CqmdHiw4a{vpO)hws z(?rv|JO`6{9<^%k@>OW}+{<)R7Xoz9UVq-yuZ|r--Bg^iTRvoNG7jB#Nk=uq@rCFtKaNyc74$O7P4zj9-U8Ae zJmNKO=ZM!Sf#4RFayh!nI7;GhA|IIE#ku9wkAR?jhp7F^prVj4?htg=X$Oo77i7W^8hg1R^Vm_IoC4PdM8xwjnw3F z@X(uc-=p5_&|+I`X@#da6K!vHHMuK=xJ{(sLZ6xogNFj^w3W4K&EpeYCAE;Xli7<_pU7K=C z7vWb6%M-AubwbYYo(r}VjG1+Enaymux=_$IxZlcjwMH7$2Ml;mfxq7{e_zp+T@L^= zhN?N)1cNA#X2K3ME+h$`_txocMQ=RT{w(_i34>PA~P77 z6)F7YLT-(MfWc?3VbULD7EhZ@KJAgYKgIq!ht2JV8E{C{XK&>RA(n`g?ILAoJ>`XI z@Qj1fzhVaQOH)TVn~|Z+=xscqj4gPUI~j#i&V4%MEq(K*e9MwpCir!U?;;bv0ky_$ z`?`ZN0`l%PRpY!1smX<^K41)}H~KmZxU%7&Y*n22I>hIx^s!4~0Z(Bf(<*$F5OPF5{0Q;M znJ@1@&{mAIrmg=vTg<~S`*xA?tFSc#B}E#vL!N(WN}%fgG-r#>-(~3_tB*g>`}4Hxt|<==2Ez`t6983>bsVjvHWB8}%&2!_jfP*^HtC_?dLk%q#wrhl~2motc3QU%=FrQ^1J{%t) zI;SiskK?m#1ny=!iz)SlA%dA7tRJqnAz5&pZ^}Y^E40dU+!paI5v7%+w1x3gNEZGJ z=M#5FT@0q7?oJvk!OU-1sLb%8rX<9-MVVb?ndc))uDm;s1cuZ6!btB9k>5}j+;*Mk zQWSs{f5oJguu8LQq7()@`~9&P#9t);UPz)VOM~g&;l5I*!bsK)S1gsq-43!xG?Iq+ zi{XVB6bE;zj*Bsy5lI4$M=UAn$R=F}VLO=d8wo5Cph?}C`mqN9i(IOxHA*1H1V}Vf z5^*Vso+<@;52b|AF}cxdD}-&Wux&!FUttYH6^KJ?+yy#lGseH76$z|%A_uryA`rIO zmBRLru+?&41PQ2oHbU1?-c}TkMVj=Dnww=QE3^MR)uul(!woy+?l8FkYu@6vH17D-|LsVagIOm;X zLtp#Bpf`+ZRsC-JtMvwj_JzT3KeaFLA67)ArM9%1%hH!%UKo!5{CiRD^0bV1Ou8L` z*bHxZg{*Qt^=v&`L}ZExXqBFA&=3)$LY#-o06C z3`5-w_GHS3vc5~$_6ytV02o2uE9~XMUM(x0@;JFa!Vrt|F-9w*^P5qV%R%lxnP_A@ z7#Vldjm`O=C&X%D`&QUa0-UeGABwR*koybDIULY)tYQkg7Za>afqLYkg^+WJG!xn} zUdoTsKyCrBH4DY8gS$geGUKJxz7cwWp$_Jnt)xK8hBsQVFosTSYj1(LU|K9i=GjtV z91zA&5Si!HEzF-P=y`fYAa&p9sz?hAQoolj8GryZm#p0jn|g4!y(e{ z{{&dY|EWW6(l<9sVSH4>DN-13Ux{dN1U)VFzsQ77QeT9oZKq-gG`ZE3oi{CE`!{F<7UHo4Cg#83! zCLjyxD9_d>EB;{uLS%4xD5!QWs3hh=scJ>8`XIHaHOyhV<8 zgxTAz^E}5~<{u7G zF2JZ&y>ZTZD!_u60wZun@Tt)2*Y+3PxLd#=n8(qmuwAspln-|g8h5CwfK5k3%B8@j zbAwNC0Y#=HkEAmm})kiQDk}N{cSkOzy8i$_aLgN7yaxM2Tn0IWF6`e!2vrhH2 z@u{8#X~C2L7@w-b#!KGqmcsp*u>-sVi?}^7NhrWFn2LoqGIkp~W$r7ah|Xs{cEr@Xk-TgkLyMQg3F&k*(-0j6sJm1T&K zfV5#l8yjWf;lIw`N#WZkamqwndAEa_Pf|s&N9*Q>gO>s?Gvj7h;{TFBA5asG$+dmVCGyESF|@c3#?y zfhb$%f@c~R+#^Il*zXYb)kwZZgLMvy^#x=~ek7eI@*va&+5yH1Gvg#7_we+X%x&|oWi ztp;bc<&Ti;#xVR9Xh+I^8Vy{~k-NkEAv)xMzIhofVvLl7_Wi6ck?JJ}Wj`kG_L&0o zJQXy)K&>&$6e?1aC;;`xXM`EGn{ z7N2;jesU1Sqw9k-eZsYVg~C_c17!S%Yv~H-O2JH_7BX%Hz_Qau zVSh{5-$pyKek9{LXa?EfWE>>pJ*0nGO7n3tUPk~DW#}AcK>dN0VORhn<1K8ZS1+CM zGde0>`r*h}CfX$IAL9ZTqQPNDJsBsF>NGY8Yw>blCxvOEh(95%FWn=7)jTvFS`W{E zK#K3=-S;NXMp9wpi!1RRQH1%0mVjDva4%$PN;CmS0H$bg6f+#GnM#d_#fnKH{wJPZ zaosx0C5MaTu1E~~$$^C(u(BY5oTr$j7B~sx*Lf>t@5XQTH#G1z{0`hneKzB_&r#|X zgWq12WLt$_+d=9)0>7PCQHOZ^b||OwF2L`3cA~cUr6kCwS+%)T*!Xf7&}{gJ7=4?y z93wYQO|B^O+9qQcR;4Yav|@s%)P^m|wsLGh8V55~b*Z-s`>Cqr7ZA>V>IgnAEh(?A zNv`SB%T`oUZY!#qkm9ZJMkl+vrKH%9V_9i(a%FY7ucXYI%x7P;Ecm}F*vvICd4{L5 zJXz}L*u?Jk?up4oRmqcZA_A&q=lf|mt=BWjo6J@VtMrgchKE#-hCvn8zG>CIUfwEI z>;Bjx)}J?rrA();XieYnDcV8!KN_XO@)mw2Nm80S%TDA{_xvp%5hRwOh!eS-(LFdtov_0Q}FFaO9rHV zIbiOCfk0fA7sqG#?N>Snx=wu9f5>NdA9?*`r#1H@qnK>J-C;RCZAVGX2a_i5Z#Q;F z+6Qf*~TF~dqGfP15_n|{^C&dWAMeYN4Owf*0? zMuknm87O}HkrQVg7!~8Z&i~H-mu{W7XR!(^uP!b1+c(8_>c1iIm*aSc4{q-=`!)&$ zx}!V}8^@nQnOIWpE%w{*YBt<8VrSd#6W6$R{q^f$s5W&d4D+Df%^9y{b*!JTEP8qU zoj<9{s#OEOeOR39=N}Ir^tKt3);00udiY&%WmPD6v7&JLgfDK7`KIgqGkr%cz1tQD z*bvNbd2x_m-~Tq<`P$7J>C&mE-n0L)>P5(m83(MMG$v+df@Pzz<6x)Wr4u$S3O}JukPMtv;-Pn|L-Yc?3=yy1`}U{1UpSHH-aqKkHQ#|rJqs&K%1V4C)4k)S zRN>?bpSKc>zHHd2_U&I-ckNf1^FHa>?;ckm&^HvXLLP<^jN9kMn$G>#y}LN^(lu+# z-+Kz8W^WKznza4)=Q7tezuL7mEbc(*ocZmhZv{QQiv0HdC!bh;YURwHGtW$4vMPF1 z9v)j}`|YQ0no-_z&7*7n{61;wYoGO7jmL!-`|ax^uN~+*aIAIvnR{+HvU=;wV3K)I zh56P#TJ_YjDMNOi-{P`iU1oj1_PIa+Yq#Y{-~~0KWk~Uywe`@4JwE&9!5gm3fAiGDwr`=a&G5_`FlXKJeQ)1%^6nq|MECu= zrr$m11p@lK40T$J-#%x2r}(SW$M@fM-mZ%l6h6@m;$UXr0)IXDJdfZ0{GpvwzUtI( zob%ehT6A4<{PhqKIYSEa{q_&Oskcbs1Dd&su?H%OG`2cj^gk33wTZ~w|(KkV%lcda_orBA4gJkKm>xv3>rIhOf~ z5~sEZlVZ>L7l-P>;hrLX&mB*0J6if|#TP?7 z^X?g5vpqQ!r=Svh;b21X+mlZ>f9LW?I?wv-`YzKdPaHcE;+Q&N#BcxNtFL$WukVun zevEZh=VBTgiZNtnSy2Vv?})T-qHY;?@hcOf*1H~^UvMHsEAQ0y+r!tKT0DGi?p3`{ z?%q*<%Tm}(sL^+2Ndkc)O#!AQp$PEPdQtF zw*f~?qUb9SzbEh$j5kyCmB4*~pJaT9@-OgHJ_ee-cLBEuqnzDHzXSLg;MQ%)y%PDu z+}69EaRIsS1il^kMaBy#zcbQb0=$>;!<4fR>0bce4}4w}wfP$JbBqLgzXII$5VGAM#U+(EW~p?h zKFlh`&#OccogmoekxMD8Qz?J)irS4Bi*qU%VjcRw!=H*gJO4n=wtjN9LK(jUckvq+ z`EjhI5dqM3I=N9n_bd3$TQkOwQ2q!IjFs*_%^AN%xoFUwzk$PnBL|WDW5jIdtIo$3LWEBM9>TbcT!~0;0UplyeR7r~9OkG#BY+3qjm^Al837&* zJP2Mk;H0wxcpT$uazQj*J%EcCA0g)~gjWN5fia_WU4`%~fG0B^ZCv4JXP|0;wDFWN z7{s{|SkCx+a^8Z(bAhh|PIr^bg~S=aKE_Xya|yy10?z=>SV|dVksdbEKC^%`uOjCP zgf9iYk@3Cc8iw?Rz;l4J!pV6z!m(=KXFlVZ+w3#F2~9D#QO=XIkzyaT!X z4y<9ki1Ivs${Pv1j`6;bjNS+AZb|twAhXjDem`Ru<%6^NRlu7W-$Dh=fPVwt!uUJN zp94G-_)*||8|BXjz5%$F@zazK=H|1E*8#KDw2hw%2zUo@VH_3w1-?G@iM~@?xImVnd9&~ycHo&$R2itBcU6!e?Glf_Pag)G8#wM zp}^+?pQj5C64aN*aUrw7U#tYmFu@^e+wC#n3xO}vg*<|WQ`?Ifc>!P0D~DybP1T~6 z8`Y>SbzntM4&}072FS)zaDO5fFaCC%jv=0M*1n{GDVIV=1Dd(lM9uAL}5~|U{ zv`|BrdWbB?HHD4 zZ99(}&7+m7a0k=6hDwo9z^?;-gD#X4v=s>rkIN}W!BU?#%;zflOeq1r3iutmFqNQv z)Tgd}Q0W)(Ic0_TMRSv}zT=bo9i8Wm2L40fKh}l$1bs!FuV60Bl_g=8GRZ6Gwafwh z*T5guh2;cYqF%pexD?reOO%T`#{8mrsioe4qn>IV`oH1?z83g8U07`*O9QlyRots1 zfnS7|F1+RfOCzu}#xY?rDi|AnW~vW&yZ6R?UQ01<5=CJ*3-vNeZ7l^$OR(Id3)=|F zqM`ng5)3FbN}&t$sYRc6%D|Eh7OO5)6Z8-2bDeEI8Rr?BVnJFUXmku4R;4OL7}X_) zenZllF<|KmmWOoV5J8Vo(mzuj!C*nG9-5jYGnnfIhAtw>2@hC?gJq;H{6r8gtx+EW zmlISx<(Tu#WkDx|7!T(?gh(k zuqR*L!?mISiJs5Vj`p6m=ES$H)$EcuWPIO7|3J zAmEK}hF=W#EI(LIgXIju4g_9Bb6S`p0 z$}|rmA;CI?wCe$~OZJqGzd;4f-hzlZ&dNkYZGkAtuu zgijF`5{R)GXONH*(-C9h5bk6OC;x}SPej2r0fcKHTt@}B2}L{yOoh~#!T@=! z?22_@RfOA^#tFg^tN<|+#16+nb`!+rZVZ)m<*mwN+<|hh6L^NoW#q&{u74VdFobD+OVToe-8f1(xBm;o zvml;F&K)L9XhJzNvoUm^><Sx-+7``EtdF;m5gmOP;gMLCfTEo%+p*1+!*G@o{fi?ql`V}n1{F^)jL2$h|l>;oH5^+>kEm)AaMlZn<&Pf zW%lZh^-e1hHnU_MHXNICg^*YVi5|o)D2`CaPJeg&h%kU;y_yl#Fm%YEOyl}N;^UB5 zfjFJwC6uyr{liBDC!zX+5gcUb3xn!@t_TvBLE^KBAE0;xrMmZTk022g!uca(`i!B^ z4bC21F(ht;#7e|HDL#N}5^KAB0oMl-jSCHWbNwOlb4Wah;}{M~YuI?7$}!IW9!kJx zCl7FXbhlJGT}Y<)4!iXc-Z1-lhFw<5Wo4l3$W6}kxot*Q*P=1c517M;l@mX>ve=DkGe{v*NVf@T zMp%_Xb2hk_p?7F#@7gGM&!%=GGk@QVaSf+HqchOx0>=0%#dS2sx!IwJGvrb{=F?Fq z7OK#l(eE%aC3H)+N1VANJC%aOMt3r_i)BVPRd)mT1GLx;Eviv=PwdNQRCivo67k2> z)M$Q6#8^B=wl?~5w7R|96AC)Qt}(XgTAHn5X7Rf5;QCj$H&_hoXfD(q ze>-l#+|Fd&QAV?o(!3e1P6>qrK}I1oW!9B{7s*?UViTp<9HroGvNl`Dzpdoowphtk zF~{vj8u3|%y9jsnhr0&hms?_AhT_&Duic`ZU|r>@slybc>@j%}P0n6gNHr`O8!(`?BTWJ#Vy}_`{@DLFL@{$Ky8rB3`e<>BU%V zZ*Tn0yEAaY?wI!M;0c?u-*Rq2h_^?uSxNgwq2!ljFjx4K``a^ePx5>Ql0ZBtP9 z=D4+sFRu!}X05uiH?Gm!Uer&O4xg$Vl2zVm+PtKD^~yDu569^yoNjzgcy#c2KXEJ4UQhNWq(Ooy*yzTZG#cy$OmG0O=RB7V+Z@%pG z!>L!Fc(C7r+R|G;)3i=B&|KqjzgwiVR7RowUwyY==#^!yd1+5_hZ&DvjZfG#Q>AsG zE%V3Px8Bm=&Oxmvo>{p|)6xi!Dy?cW^pS!Ozi-^UqWX#B%h!LPY4Pr;N=I%#@UIDr z2YV;4DBM-UpSYrF9g7u@&lAQc=8_<`bx#Px+;{1%1-1XK=v;BNeD0!l!~1HQ6t^O; zV5+n$f2E~=!FoRRL+_O7P0H76+5`2BoW|p8i97+5hYNK7-U%(cKL5p>tQIR)`fIkl ztZAL&wqrxg?#@BOn>XL{{Lqv6(~frT@@#>oWfo&=cZ4v!5SHx6&wc)F)t+;G3->*` zZpE)6=B0P2B;t3=r5?ZRR;5wy*YmX(j;zQSd1C%UYm#_PYmWwD&|PA_ZFN$mGgr!c?SJwmvBkLB8tK|1ERzhhAwO2A(xB9Wi|3CW zk#8E=t##I=RUL3U;;4cd`_tOw$?p4m+^xIjw_Bhuxqx}a5kHo9{qUA@g9{$pdTYnh z6@}Zb*A1xBv~+5vN~=?ny1uAgxBYV0;b&S+ej4XyjE%*Y6jeHY?&>SUlY5O<5AJ(^ zc4_q-5>**3x<)TH-8Xvqy*(Rlcl1sgk+76_x;?J2DvcOl{_smJ=dW&i^2N_qcKvh+ z9W#q@NXEnw{0AxpO1aUgT;UhAgmACDM({y8EV zOVo3Zy;AsN-#PQ9Wj}rPcfCAW)9|HAl_K9hb@$P8ldI-dw+(9I`;TZ^a`%8wmAt1X zzC8PC(dn<|K9u{@LsMVXw3P0$KcGsFxbHh#Rr1lo7L9V>u3NJGZrm~5WN)~n$UMq$ zJSmV-efP^FYG&Er9oFVh6j#(7FYx2+*7qEinl_=+ru5eDPEuD)pN_1?peprPdZ4v( Zed^lp?qBcwQGV|=+GaVxHp~8O{{d8E=R*Jh diff --git a/bots/sustainabot/bot-integration/lib/ocaml/Oikos.cmj b/bots/sustainabot/bot-integration/lib/ocaml/Oikos.cmj deleted file mode 100644 index f1d2252d06c58e6a180c1c513984b7ed555e49af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 153 zcmcBy`|oCCKV?aWfqiV=I0f|6zS#Wr=+?S<>v;M6lLb6Lxmj{ hOwi2F%+4>?P0BA>u)$HexF}g&uPC)xFRR$W0RW2`Jk9_B diff --git a/bots/sustainabot/bot-integration/lib/ocaml/Oikos.cmt b/bots/sustainabot/bot-integration/lib/ocaml/Oikos.cmt deleted file mode 100644 index b74169233a877a79ef8f3539da2ce35c7eaf8888..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 64033 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 diff --git a/bots/sustainabot/bot-integration/lib/ocaml/Report.cmj b/bots/sustainabot/bot-integration/lib/ocaml/Report.cmj deleted file mode 100644 index 17a7cdffc60495f8abd1482e2cb5bbfee3988d01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 203 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 diff --git a/bots/sustainabot/bot-integration/lib/ocaml/Router.cmi b/bots/sustainabot/bot-integration/lib/ocaml/Router.cmi deleted file mode 100644 index 7e6fc2c195232ba9c30387608804b72045cbdec2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5005 zcmb7|d0Z4n7RS4Wo&;pj)wnT=uHtZrh|^+BKDwIp2q8Y1Xt z6R%txHVSG)q&;H}$qtj1n}8NASv;ecfGMBY$neXZrK`Rn@Ea zzV+(rCf1tk7&3hLa0?R?v#@gGE{f{hKv8~1iVCcOCtVDm;L7JYw^-*z`m*p`j-T$b zvHlb_lw#R(@u(O1wHn99r?CRddZhrfsle(sY6bnT{G&cHXW1bZmK$ojeZS}iyt4K7OyhXJ=NClCAycY&SSglVJYUc*aU1A zqBdTT=>Dp@g3WG3B&VcVl9N)gVWisJBGCg?brT!5g(k$C+9+SFB=-iIbG(63EZrF&cmBS zcTL^@2AgBG2v0wR<>L?9gSv1kRJ^a(cMY9s2xEdjFRd%&MP93g0Uh zL_L6?L}w@p4FyCx5@QMjbL}?3eBJ8i{yOO`WkkxT1aEw3zSGXL1mrdhgMRi;(cdAR zeq-qvmA+l>9{Z=d-zD8)UewNG^rR$)^jLd)SN(Fb2f z=tqRk%Hvyx$G0Se?>M%5;mUwLm~(8H)$O(x%1ce4N0F$%5_KKoH>V-giqJKQzNjc2 zg|Y8P`PLBjNOx0Ql@SM5iMj@^Zl)uh4(Vu#zNM=E*wq7*)5VW*58zYx{xmGnqA5$QsaE*zwvD#yS8afi|2ai-@zIWZ!O5yhMEetoR<3iFB)xZY}tZR;3sFu4Gi-W8j$R=v|=a6MyGr_wp{H zD@ol2qMAvxi%PV(naJ;TPKxSpCvo_oWkfTM07o(w*h0GDkaRge1O$v zQ!XbBkD`++0#Rp+SACiSIN4e&f^w=X(XSf|`W< zyCDCkfU^?oU<|s#IE~{8V=-}mKqG1+RZW5?FSS(tk9BeVW)$SiVwN zj#E|?FbM@r1(p+7XJVF>#=LwVN)z$AgP;s1b&VRz08+IRP<|k#FEoN(n%GTHBn9Or z#i4*bC}1C;+`{?*MyU$7aSjgd18uvu5Xbd|CXv)_(P+k!s?UMu9x1`ypw7rPO*9ai z?J|w-Z-yLBys!+p>dG9%^Hnw?bmwi^{5B2_*A2S zqeSJZBRHQaI3_9=by|)(RRIozwTN-5Bh;hVqh&{r!inn*1jx6lH)=qOh}j1+&~v1? zN#poX6R;BTBK}wbN}^_=KtB}tBmgC2-5CR|Hs-@y5}qnJxQJU(3+y3PYvjO5q_|d# zw~ib#>y>ypQ~?THgaY4%c+;>h!SQMaXm^w^Xa;dvr3L+*RIQSO`evhA3%Z&Ftxy}H4hm+LxwHTyHqRefD2Bq zn}W&Lcf8^B=ptcUA)nTNC&l;4#jsMiU`(Gd-fRx&r+#u!28yC+c!K1|TW)6e%LWh# zu4;(A9#Qj=p%EFrfWii?a0w%97$CnMIjy;5#^~-OY9&DE5xl_SWx0${EEg`2j(}ps zC|w>yF~}&Jh!v)3MAQOg_!$|l0L@NZ2K7!`mh+2q(o!dzMN!WiMCdjlC@HyWcezh-bO*uC};?PU(*WDWAL?M z9?o4rQvCQtzX#lc2HSA8~R_U$MEK!Wc?Wu*i zSuTgbJUO~Gb^gkUvpN*i7j&e^P;yZhS5TZ;+>W~O}u_aR zVI*(9798<%>}w@^Nr^x{L`fE6==+3aa3n~}P`v;Q;ceTuGE?}mk;`Vp9# zev@CY9QrBn>B4<;o8PZJD2hW;-1b~MZ!h37@#nL^G~L-!-oCVOXyLCo#7#N&!kU%`sux^C%44UKR0yvN{c8COo0t!^#Gm+7UkEgPMmMt+crM2 z>BY@ezv^M+<2;%0>BHsNot#ZzUbTH3FRnRL6`66lY~%;QI#C<|20W~J=shjNSU50z z9liBT@GwXA#5q^gG4b5THP?Sf0(*1j5{)>my})B zzg${&3(^iPPFUZM(=VqcTBdC8G9;%eamS;36BE6(aF5+-m;y&@c9I%<70p9{{WIYZWsUn diff --git a/bots/sustainabot/bot-integration/lib/ocaml/Router.cmj b/bots/sustainabot/bot-integration/lib/ocaml/Router.cmj deleted file mode 100644 index a12dd6e5d9c60d6da8f9f8db0e32211153d9a77e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 308 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 T)-Op-RM#s?E!N8_c5nay9NIbs diff --git a/bots/sustainabot/bot-integration/lib/ocaml/ServerTea.cmt b/bots/sustainabot/bot-integration/lib/ocaml/ServerTea.cmt deleted file mode 100644 index 3ed948b89635d126e2c7c18bf753fcf8607f06db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51107 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