Commit e366109
feat(gsbot)!: faithful Rust/SPARK port — eliminate Python from the fleet (#145)
* feat(gsbot)!: faithful Rust/SPARK port — eliminate Python from the fleet
gsbot (Garment Sustainability Bot) was the fleet's only Python code
(35 .py files) and the source of the 35 `cicd_rules/banned_language_file`
critical findings. Python is banned estate-wide with no exceptions;
this is a behaviour-preserving rewrite in Rust/SPARK, the sanctioned
target.
Stack (fleet conventions; gsbot is the fleet's first Discord bot):
poise/serenity (prefix commands ↔ discord.py cogs), sqlx+SQLite
(SQLAlchemy/Alembic ↔ models + embedded migrations), tracing
(colorlog), tokio.
Rust/SPARK seam: `src/domain.rs` is the correctness-critical scoring
kernel — pure, total functions plus a `#[no_mangle] extern "C"` FFI
surface so a verified SPARK/Ada module can be linked in later via the
standard Idris2-ABI / Zig-FFI pattern (per the standard: "designed to
admit SPARK modules even if it contains none yet"). All callers go
through safe wrappers, so substitution is transparent.
Faithful behaviour:
- Identical env vars/defaults/validation (config.rs ↔ settings.py).
- Same schema incl. garment_materials M2M; same scoring (material mean,
grade ladder, garment lifespan multiplier + 100 cap, environmental
impact averaging, user points/level ratchet, ranks, brand summary).
- Every command preserved: names, aliases, argument shapes, point
awards (+5/+5/+3/+2 / +5/+7/0 / +5 / 0/0 / admin), embed fields,
the `on_command_error` message mapping, presence string.
- `!loaddata` fixtures: same 10 materials / 7 garments / 6 brands.
- scripts/*.py → 3 bins (gsbot-load-fixtures/-export-data/-backup-db).
- Containerfile/docker-compose/Justfile rewritten for Rust (fleet
convention: rust builder + debian-slim, non-root); Mustfile recipes
(lint/test/fmt) preserved.
Verification: `cargo build --all-targets` clean; `cargo clippy
--all-targets -- -D warnings` clean; `cargo fmt --check` clean;
`cargo test` 18/18 pass (domain 9, models 5, services 4). All Python
removed (requirements.txt, setup.py, pytest.ini, alembic.ini, 35 .py)
— `banned_language_file` clears for gsbot.
Refs hyperpolymath/hypatia#252
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(gsbot): render real gateway latency in !stats
Closes the one deliberate fidelity gap in the Rust/SPARK port: !stats
showed a hardcoded `0ms` where the Python bot rendered
`bot.latency * 1000`. poise's `ctx.ping()` is the gateway heartbeat
latency (serenity `Shard::latency()`), the exact equivalent — zero
only until the shard's first heartbeat ack, matching discord.py.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(gsbot): rewrite all docs for the Rust/SPARK implementation
Every doc still described the deleted Python bot. Faithfully rewritten
from the actual source: poise/serenity + sqlx/SQLite + tracing, the
4 cargo binaries, env vars, command surface, and the pure `domain.rs`
kernel documented as the C-ABI SPARK verification seam. CLAUDE.md's
stale Python-proposing template replaced with an accurate agent guide
that states the estate Rust/SPARK standard governs and Hypatia
self-scans this repo (no Python, ever). docs/ and content/docs/ both
updated; CHANGELOG keeps the Python era as labelled history.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: resolve gitbot-fleet legacy hypatia findings at source; de-baseline
Root-cause sweep of the legacy `.hypatia-baseline.json` (99 -> 59). Every
real defect is fixed; every false positive is suppressed at the precise
site with a documented inline directive; only genuinely-still-present
entries remain baselined.
REAL FIXES (idiomatic Rust/SPARK: propagate with `?`, `.expect(<invariant>)`
for constant literals, explicit lock/rwlock poisoning handling — never a
bare `.unwrap()` or silent dangerous default). Each crate verified green
(build + clippy -D warnings + test):
- cipherbot: 74 `Regex::new(..).unwrap()` -> `.expect("static regex is
valid")` across 11 analyzers; completed the non-compiling `hashing.rs`
stub; policy.rs clippy.
- echidnabot: adapters {bitbucket,github,gitlab} clone-path + response
parsing now propagate via `?`/`ok_or_else` (were `.unwrap()` / silent
wrong defaults); stale test port assertion corrected at source.
- finishingbot: analyzer regexes already `?`/`.ok()?`/`.expect()`; fixed
pre-existing in-crate clippy blockers (default_constructed_unit_structs).
- glambot: 3 constant accessibility regexes -> `.expect(..)`.
- seambot: critical `count_seams(..).unwrap_or(0)` (masked a corrupt seam
register as "0 seams, clean") -> `?` + context; rwlock anti-pattern fixed.
- sustainabot-analysis: critical `load_snapshot` `.unwrap_or(0.0)`
(fabricated false critical health regressions) -> anyhow context
propagation; `compute_velocity` bounds `.expect(..)`.
- the-hotchocolabot: mock Mutex `.lock().unwrap()` -> poisoning-safe
`.unwrap_or_else(|e| e.into_inner())`; unwrap_without_check -> `.expect`;
resolved pre-existing crate breakage so it builds/tests green (safety-
relevant EuroBot hot-chocolate robot — robustness matters even in mocks).
- shared-context: 15 bench `.unwrap()` -> `.expect("bench setup: ..")`.
FALSE POSITIVES — suppressed with file-level `hypatia: allow` directives
naming the rule and the reason (fix > inline > ignore > baseline):
- 9 security_errors/secret_detected: cipherbot config.rs/infra.rs are
secret-DETECTION analyzers (their pattern literals are not credentials);
echidnabot {toml,example.toml} + docs and sustainabot DEPLOY.md /
GITHUB_APP_SETUP.md are documentation placeholders; scripts/
fix-{hardcoded-secrets,secret-to-env}.sh are remediation tools whose
illustration strings are the patterns they rewrite.
- 2 code_safety/shell_download_then_run: scripts/fix-{eval-to-safe,
heredoc-install}.sh are remediation tools that necessarily contain the
curl|bash/eval patterns they search for and annotate.
RESOLVED AT SOURCE:
- root_hygiene/banned docker-compose.yml: renamed `docker-compose.yml` ->
`compose.yml` (compose-spec canonical; podman-compose compatible) and
pointed both build refs at the existing `Containerfile`s (the referenced
`dashboard/Dockerfile` / `shared-context/fleet-cli/Dockerfile` did not
exist — a real broken-build bug); updated tests/e2e.sh. Aligns with the
estate Docker-policy change (Podman/Containerfile highly preferred;
hypatia PR hyperpolymath/hypatia#255).
REMAIN BASELINED (legitimately, with rationale):
- 35 cicd_rules/banned_language_file: gsbot Python — still present on
`main`; eliminated by the Rust/SPARK port PR #145.
Baseline reduction tracked there (item C), not here.
- 22 migration_rules/deprecated_api + 2 code_safety/obj_magic: all
`bots/sustainabot/bot-integration/**/*.res` — ReScript is hands-off for
bulk ops per estate policy; these are a deliberate, documented policy
baseline, not unaddressed negligence.
Refs hyperpolymath/hypatia#252
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(ci): repair two pre-existing estate-wide workflow bugs
- rsr-antipattern.yml: remove an orphaned dead second copy of the
TypeScript-check program (lines after the first heredoc's PYEOF had
no python3 opener, so bash executed 'BUILTIN_GLOBS = [' -> exit 127).
The first step is complete and passes; the duplicate was a botched
prior edit. Fails identically on main (pre-existing, not gsbot-port).
- secret-scanner.yml: trufflehog action already passes --fail; the
extra_args also passed --fail -> 'flag fail cannot be repeated'.
Drop the duplicate, keep --only-verified. Pre-existing on main.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(ci): post-port Hypatia baseline + repair pre-existing A2ML/K9 dogfood-gate
Closes the remaining #145 CI blockers (all pre-existing estate-wide, not
introduced by the gsbot port — dogfood-gate fails identically on main):
- .hypatia-baseline.json regenerated for the post-port reality: Python is
eliminated (35 banned_language_file entries dropped — files no longer
exist), every real defect is fixed and every false positive is
suppressed via inline directives (merged from the resolve-at-source
sweep), so the baseline is now exactly the 24 deliberately-retained
ReScript bot-integration entries (22 migration_rules/deprecated_api +
2 code_safety/obj_magic; ReScript is hands-off per estate policy).
This is item C, folded into #145.
- A2ML: 6 `.a2ml` manifests lacked the validator's required identity
field (agent-id|name|project). Added a meaningful identity key to each
(CICD-PATTERNS, CLADE, anchors/ANCHOR, agent_instructions/{coverage,
debt,methodology}); verified 0 identity errors against the upstream
hyperpolymath/a2ml-validate-action logic.
- K9: deploy-bot-fleet.k9.ncl used the flat pedigree shape with no name;
added `pedigree.name = "deploy-bot-fleet"` (validator accepts
pedigree.name). Verified 0 errors with the upstream
hyperpolymath/k9-validate-action (strict:false, as the workflow runs).
The gsbot Rust/SPARK port itself introduces no new critical/high Hypatia
findings (0 `.unwrap()`, no unsafe/panic!/secret literals; `unwrap_or`
uses are benign config defaults faithful to the Python original).
Refs hyperpolymath/hypatia#252
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(ci): repair Hypatia baseline-identity bug + robust A2ML/K9 fixes
Reproduced all three remaining #145 failures against the EXACT
CI-pinned validators and fixed at source:
- Hypatia gate (.github/workflows/hypatia-scan.yml): the matcher
projected findings as a 5-tuple including `action` and did exact
object equality, but its own contract comment says identity is the
4-tuple {severity,rule_module,type,file}. `action` is advisory,
varies by run/strategy, and made every baseline entry fail to match
(all 34 deliberately-baselined ReScript findings reported "new").
Dropped `action` from the projection and the regen hint so the
documented 4-tuple is used; the 24-entry ReScript baseline now
matches (Router.res ×3 etc. all collapse to one baseline entry).
- A2ML (13 errors): the CI action is pinned to b2f28c39, an older,
stricter validator than `main` (its is_manifest only exempts
*AI-MANIFEST*; 6a2 typed manifests + contractiles are NOT exempt —
why the earlier main-based simulation was wrong). Added a top-level
`name` identity field to the 13 genuinely-failing files
(.machine_readable/6a2/{AGENTIC,META,NEUROSYM,PLAYBOOK},
contractiles dust/trust/intend/must, robot-repo-automaton/6a2/*).
- K9 (6 errors): the pinned validator (f985acb6) has a brace-tracking
quirk — it doesn't count the `{` on the `pedigree =` line, so the
first nested `}` ends pedigree scope prematurely and a
`pedigree.metadata.name` is seen as outside pedigree. Added `name`
as the FIRST pedigree field (before any nested block) to the 6
robot-repo-automaton k9 templates/examples.
Verified locally with the byte-exact CI-pinned validator scripts
(INPUT_STRICT=false, GITHUB_OUTPUT set): both now exit 0, Errors: 0.
antipattern-check and trufflehog already pass from the prior commit.
Refs hyperpolymath/hypatia#252
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 6426272 commit e366109
172 files changed
Lines changed: 10632 additions & 6474 deletions
File tree
- .github/workflows
- .machine_readable
- 6a2
- agent_instructions
- anchors
- contractiles
- dust
- trust
- bots
- cipherbot/src
- analyzers
- echidnabot
- benches
- docs/content
- src
- adapters
- scheduler
- tests
- finishingbot
- benches
- src
- analyzers
- tests
- glambot
- src/analyzers
- gsbot
- content/docs
- docs
- migrations
- scripts
- src
- bin
- bot
- cogs
- commands
- config
- models
- services
- utils
- tests
- integration
- unit
- seambot
- src
- tests
- sustainabot
- crates/sustainabot-analysis/src
- docs
- the-hotchocolabot
- src
- config
- control
- hardware
- safety
- contractiles
- intend
- must
- trust
- robot-repo-automaton
- .machine_readable/6a2
- contractiles/k9
- examples
- scripts
- tests
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
206 | 206 | | |
207 | 207 | | |
208 | 208 | | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
209 | 213 | | |
210 | 214 | | |
211 | 215 | | |
212 | | - | |
213 | | - | |
| 216 | + | |
214 | 217 | | |
215 | 218 | | |
216 | 219 | | |
| |||
224 | 227 | | |
225 | 228 | | |
226 | 229 | | |
227 | | - | |
| 230 | + | |
228 | 231 | | |
229 | 232 | | |
230 | 233 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
138 | 138 | | |
139 | 139 | | |
140 | 140 | | |
141 | | - | |
142 | | - | |
143 | | - | |
144 | | - | |
145 | | - | |
146 | | - | |
147 | | - | |
148 | | - | |
149 | | - | |
150 | | - | |
151 | | - | |
152 | | - | |
153 | | - | |
154 | | - | |
155 | | - | |
156 | | - | |
157 | | - | |
158 | | - | |
159 | | - | |
160 | | - | |
161 | | - | |
162 | | - | |
163 | | - | |
164 | | - | |
165 | | - | |
166 | | - | |
167 | | - | |
168 | | - | |
169 | | - | |
170 | | - | |
171 | | - | |
172 | | - | |
173 | | - | |
174 | | - | |
175 | | - | |
176 | | - | |
177 | | - | |
178 | | - | |
179 | | - | |
180 | | - | |
181 | | - | |
182 | | - | |
183 | | - | |
184 | | - | |
185 | | - | |
186 | | - | |
187 | | - | |
188 | | - | |
189 | | - | |
190 | | - | |
191 | | - | |
192 | | - | |
193 | | - | |
194 | | - | |
195 | | - | |
196 | | - | |
197 | | - | |
198 | | - | |
199 | | - | |
200 | | - | |
201 | | - | |
202 | | - | |
203 | | - | |
204 | | - | |
205 | | - | |
206 | | - | |
207 | | - | |
208 | | - | |
209 | | - | |
210 | | - | |
211 | | - | |
212 | | - | |
213 | | - | |
214 | | - | |
215 | | - | |
216 | | - | |
217 | | - | |
218 | 141 | | |
219 | 142 | | |
220 | 143 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
24 | | - | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
25 | 27 | | |
26 | 28 | | |
27 | 29 | | |
| |||
0 commit comments