Production web systems and business software: multi-tenant data models, authentication and role-based access, PostgreSQL, offline-capable frontends, and interfaces that work in both French and Arabic, right-to-left included rather than merely translated. Alongside that, systems work in Rust and release-pipeline security in other people's repositories.
Based in Morocco, working across EMEA and US-morning hours. Open to product engineering, contract work and consulting.
wahibelkhadiri06@gmail.com · LinkedIn
15 merged pull requests into 12 repositories I don't own, reviewed and
accepted by their maintainers. The through-line is release-pipeline security:
${{ ... }} is pasted into a shell as text before bash parses it, so a tag name
or dispatch input stops being data and becomes part of the program — almost
always in the one job holding the publishing credentials.
Release-pipeline hardening
- PrefectHQ/prefect — ✅ merged: the release ref was expanded into two shell bodies in the jobs that publish to PyPI, one of them holding
id-token: writefor Trusted Publishing (#22882) - thingctx/thingctx — ✅ merged: pinned every third-party GitHub Action to a commit SHA across CI and release workflows (#127)
- dbt-labs/dbt-core — the workflow that publishes to GitHub, PyPI and Docker: dispatch inputs expanded unquoted into an
echoand into a command substitution (#15994) - sqlfluff/sqlfluff — ✅ merged: release workflow: the version input reached a command substitution and a step carrying
GITHUB_TOKEN(#8375) - sktime/pytorch-forecasting — PyPI release workflow: tag name expanded into the tag check that gates the build, plus a least-privilege
permissions:block the file had never declared (#2385)
Bugs found by tooling I wrote
The tool is autofix-safety —
two adapters, one invariant, and a README written so the numbers can be checked
rather than believed: tool version, corpus commit, command, environment, result,
limitations. It also records the run that found nothing (ruff, 1,607 of its
own fixtures and 1,805 CPython stdlib files, clean), and the finding that stopped
reproducing once upstream fixed it.
A linter's core promise is that fixing valid input leaves valid input. Almost no project tests that across its whole corpus — fixtures are tested for parsing, and rules are tested for their fix, but not for the two composed. So I wrote a scanner that asserts it, and pointed it at a 9k-star SQL linter.
I also pointed it at ruff — 1,607 fixtures,
--select ALL --fix --unsafe-fixes, with CPython's own ast.parse as the judge
rather than the tool under test. It found nothing. Reporting that too, because
a method that only publishes its hits is a sales pitch.
- sqlfluff/sqlfluff —
fixsilently welds adjacent tokens together, so the file it writes lexes differently from the one it read. Still reproducing onmain:8 | ~ ~ ~4→8 | ~~~4, and in Oracle two keywords —MULTISET EXCEPT→MULTISETEXCEPT— welded byLT02, a rule whose only job is indentation. Upstream has since patched one instance of this class in its own rule (#8395); the argument in my PR is that guarding once, where fixes are applied, ends the class instead of meeting it again in the next layout rule. Fix plus cross-dialect regression tests, each validated to fail without it (#8415)
- sqlfluff/sqlfluff —
RF06unquotes both halves of a MySQL/MariaDB'user'@'host'account specification, which is syntax rather than a quoted identifier.CREATE USER,GRANT,DROP USERandDEFINER =all come back unparsable, on the default rule set (#8462) - sqlfluff/sqlfluff — the opposite
failure of the same rule:
RF06replaces a procedure or function name with a segment the grammar at that position cannot accept —FunctionNameSegmenttakesTypedParser("word")or a quoted identifier, and the rule hands it anaked_identifier— so the fix is silently dropped on 20 of the project's own fixtures while the tool prints "please report this as a bug" (#8466) - sqlfluff/sqlfluff — lint-result caching for files that came back clean, so a pre-commit run stops re-parsing files nothing touched (#8418)
Correctness, performance and dead code
- sktime/sktime — ✅ merged: removed mutable default arguments (B006) from the ConvTimeNet backbones (#10730)
- vprusso/toqito — ✅ merged: vectorized the depolarizing-channel Kraus-operator construction (dropped the
d²nested-loop allocations), verified identical output across dims/parameters (#1921) - Tracer-Cloud/opensre — ✅ merged: fixed a CLI config-precedence bug so
OPENSRE_INTERACTIVEandconfig.ymlare honored when no--interactiveflag is given, with a regression test (#4387) - RonaldHensbergen/composable-data-stack — ✅ merged: removed an unreachable default-credential security branch (dead code / false coverage) with regression tests (#344, #345)
- vedaant00/opendot — ✅ merged:
grepno longer crashes on paths outside the workspace;list_fileshonors the shared ignore set (#73, #61) - masumi-network/Citadel — ✅ merged: dropped a dead
session_tracere-export facade, then covered the notification gateways and logging utils (#130, #131) - skodaconnect/myskoda — ✅ merged: added the missing
SoftwareStatusenum members so updates in progress stop failing to parse (#641) - abduznik/instrumation — ✅ merged: the duplicate-address scanner no longer breaks on empty or
Noneinput (#137) - mldsveda/PyScrappy — ✅ merged: aligned the GitHub scraper's default result count with the MCP tool (#82)
- every-app/open-seo — a self-hosted container can silently serve a stale client build: the entrypoint fingerprints a hardcoded env list that has to mirror
vite.config.ts'senvPrefix, and only a comment keeps them in sync (#316)
| Project | Stack |
|---|---|
| AgentOS — runtime for AI agents: supervised lifecycle, gRPC bus, secrets vault, deterministic trace replay. | Rust · 10-crate workspace · MIT/Apache-2.0 |
| AI Content OS — 8 specialized agents, a visual workflow engine, and a router that picks the right model per task. | Python · FastAPI + React |
| TaskFlow Pro — task management on a custom MVC; the domain layer stays free of framework and persistence concerns. | PHP 8.1 · PSR-12 · PHPStan 5 |
- I Shipped My First Rust Release, and CI Turned Red Twice in 20 Minutes
- I Taught an Open-Source SEO Tool to Check Whether Your Site Is Readable by AI Agents
AgentOS is open to contributors: issues labelled
good first issue
and help wanted
cover Rust internals, CLI ergonomics and docs. Design questions live in
Discussions.
243 commits · 133 pull requests · 18 issues · 8 stars across 5 projects · 5 days streak
Public contributions, counted 2026-09-11 by a daily Action · joined GitHub this year · contributor to 26 repos I don't own



