policy: lift estate-wide Docker ban — Podman/Containerfile now highly preferred (not mandatory)#255
Merged
Conversation
The Layer-1 sweep committed with user.email=jonathan.jewell@gmail.com.
With GitHub email-privacy enabled ("Block command line pushes that
expose my email"), every `git push` in --apply is rejected, so the
sweep opens zero PRs while reporting push failures.
Observed live: an --apply run failed 55/83 repos this way until the
email was patched locally; the retry with the noreply form opened all
51 remaining PRs with zero push errors.
Use 6759885+hyperpolymath@users.noreply.github.com (the estate's
standard author identity, already used for the gitbot-fleet restore
and PR #145) so unattended sweeps work.
Refs #252
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…preferred (not mandatory)
Docker is permitted estate-wide. Podman and `Containerfile` naming remain
HIGHLY PREFERRED, but are no longer enforced as a hard ban. Files named
`Dockerfile`/`docker-compose.yml` and `docker`-CLI usage are now low-severity
advisories: they nudge toward Podman/Containerfile without failing the
baseline-aware critical/high security gate, and `Containerfile` should still
be used when authoring new container files unless a specific tool genuinely
requires the `Dockerfile` name.
Relaxed the four enforcement sites (recognition lists in green_web/rules/
reviewer are unchanged — Docker files are legitimately present now and still
need green-web/review analysis):
- root_hygiene.ex: `Dockerfile`, `docker-compose.yml`, `docker-compose.yaml`
banned-root entries :high -> :low, reworded ("preferred", not "must").
- dogfooding.ex (HYP-DOG-005): `docker` CLI usage and a `Dockerfile` file
"medium" -> "low", reworded from "policy requires" to "highly preferred".
- code_safety.ex: `ncl_docker_not_podman` :medium -> :low; and
`check_dockerfile_naming` :high -> :low, reworded; docstring updated.
Existing tests are unaffected — they assert finding presence, `action:
:rename`, and `rule: :dockerfile_not_containerfile`, all preserved; none
asserted the old severity or the old "must/requires" reason strings.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
🔍 Hypatia Security ScanFindings: 9 issues detected
View findings[
{
"reason": "believe_me undermines formal verification (2 occurrences, CWE-704)",
"type": "believe_me",
"file": "/home/runner/work/hypatia/hypatia/src/abi/RuleEngine.idr",
"action": "flag",
"rule_module": "code_safety",
"severity": "critical"
},
{
"reason": "Nickel file missing SPDX-License-Identifier header (1 occurrences, CWE-1104)",
"type": "ncl_missing_spdx",
"file": "/home/runner/work/hypatia/hypatia/configs/config.ncl",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "unsafe block -- requires SAFETY comment (22 occurrences, CWE-676)",
"type": "unsafe_block",
"file": "/home/runner/work/hypatia/hypatia/clients/rust/hypatia-client/src/ffi.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "as_ptr exposes raw pointer that may dangle or alias unsafely (10 occurrences, CWE-676)",
"type": "as_ptr",
"file": "/home/runner/work/hypatia/hypatia/clients/rust/hypatia-client/src/ffi.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "expect() in hot path (1 occurrences, CWE-754)",
"type": "expect_in_hot_path",
"file": "/home/runner/work/hypatia/hypatia/adapters/src/codeberg.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "expect() in hot path (1 occurrences, CWE-754)",
"type": "expect_in_hot_path",
"file": "/home/runner/work/hypatia/hypatia/adapters/src/radicle.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"line": 35,
"reason": "Secret found: Password",
"type": "secret_detected",
"file": "/home/runner/work/hypatia/hypatia/.hypatia-exemptions.md",
"action": "revoke_rotate_and_purge",
"rule_module": "security_errors",
"severity": "critical"
},
{
"reason": "1 workflow(s) with tag-pinned (not SHA-pinned) actions in hypatia",
"type": "DependencyPinning",
"file": "/home/runner/work/hypatia/hypatia",
"action": "auto_fix",
"rule_module": "scorecard",
"severity": "medium",
"remediation": "Pin GitHub Actions and Docker base images by SHA hash.",
"scorecard_check": "Pinned-Dependencies"
},
{
"reason": "Repository has 2 non-main remote branch(es). Policy: single main branch only.",
"type": "GS007",
"file": ".",
"action": "delete_remote_branches",
"rule_module": "git_state",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
hyperpolymath
added a commit
to hyperpolymath/gitbot-fleet
that referenced
this pull request
May 16, 2026
…eet (#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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Estate policy change (owner directive): lift the Docker ban estate-wide; make Podman just highly preferred, and continue to prefer
Containerfilenaming when authoring new container files unless a specific tool genuinely requires theDockerfilename.What changed
The four enforcement sites are relaxed from hard bans to low-severity advisories (they no longer fail the baseline-aware critical/high security gate, but still surface the preference):
root_hygiene.ex—Dockerfile,docker-compose.yml,docker-compose.yamlbanned-root entries:high:low, reworded "preferred" (action:renamekept)dogfooding.exHYP-DOG-005 —dockerCLI usage"medium""low", "highly preferred" wordingdogfooding.exHYP-DOG-005 —Dockerfilefile present"medium""low", "highly preferred" wordingcode_safety.ex—ncl_docker_not_podman(Nickel):medium:low, rewordedcode_safety.ex—check_dockerfile_naming:high:low, reworded; docstring updatedUnchanged: the file-recognition references in
green_web.ex,rules.ex,reviewer.ex(these treatDockerfile/docker-compose.ymlas container/deployment files for green-web carbon analysis and review categorisation — Docker files are legitimately present under the new policy and still need that analysis).Tests
No test changes needed. The Docker-related tests in
test/root_hygiene_test.exsandtest/code_safety_test.exsassert finding presence,action: :rename, andrule: :dockerfile_not_containerfile— all preserved. None asserted the old severity or the old "must/requires" reason strings.Refs #252
🤖 Generated with Claude Code