fix(cla-assistant): make the allowlist bots only, and default it here (ENG-2017) - #56
Merged
Merged
Conversation
… (ENG-2017)
Staff sign like everybody else now. The allowlist defaults in this file and a
wrapper stops passing one.
Fifteen repos carried six different hand-maintained lists naming 25 people
between them, and 11 of those 25 had already left the org, so each was a former
colleague still exempt from signing a CLA on GPL-3.0 and Elastic-2.0 code. A
list of people is an access-control list: it needs an owner and a review, and
nobody was going to give six copies either. One comment from an employee is
cheaper than that, and it produces a signature instead of an assumption that an
employment agreement was in place and covered the work.
Bots stay, because a bot cannot sign. It cannot post the agreement sentence, so
with no exemption its pull request is red forever, and lightwood alone has 36
Dependabot pull requests in its last 100. Only the two that actually open pull
requests in this org are listed. github-actions[bot] needs no entry: the action
already drops user id 41898282 in graphql.ts.
Dropping the human entries also removes two live defects. checkAllowList.ts
compares non-wildcard entries with `pattern === committer`, exact and
case-sensitive, so every list's `Stpmax` never once matched the real login
`StpMax`. And `bot*` compiled to an UNANCHORED `new RegExp("bot.*").test(login)`,
which matches any login containing "bot": `robotnik`, `sabotage` and
`elliotbotson` were all exempt from the CLA in all fifteen repos. Naming the two
bots removes the wildcard and the hole with it.
tests/test_cla_allowlist.py pins all three: no wildcard, no humans, and the
lookalikes stay unexempt. Against the old list it fails 8 of its 11 cases.
lucas-koontz
added a commit
to mindsdb/dataprep_ml
that referenced
this pull request
Aug 28, 2026
…2017)
The allowlist moved into mindsdb/github-actions and is bots only. This repo
carried one of six hand-maintained copies naming people, and 11 of the 25 names
across those copies had already left the org while still being exempt from
signing. Staff sign like everybody else now. A bot cannot sign, so the two that
actually open pull requests in this org stay exempt in the reusable.
Dropping the line also drops two defects that rode inside it. `bot*` compiled to
an unanchored `new RegExp("bot.*").test(login)`, so it exempted any login
containing "bot", `robotnik` and `sabotage` included. And `Stpmax` never matched
the real login `StpMax`, because non-wildcard entries are compared with a
case-sensitive `===`.
Needs mindsdb/github-actions#56 first, which gives the input a default.
lucas-koontz
added a commit
to mindsdb/lightwood
that referenced
this pull request
Aug 28, 2026
…2017)
The allowlist moved into mindsdb/github-actions and is bots only. This repo
carried one of six hand-maintained copies naming people, and 11 of the 25 names
across those copies had already left the org while still being exempt from
signing. Staff sign like everybody else now. A bot cannot sign, so the two that
actually open pull requests in this org stay exempt in the reusable.
Dropping the line also drops two defects that rode inside it. `bot*` compiled to
an unanchored `new RegExp("bot.*").test(login)`, so it exempted any login
containing "bot", `robotnik` and `sabotage` included. And `Stpmax` never matched
the real login `StpMax`, because non-wildcard entries are compared with a
case-sensitive `===`.
Needs mindsdb/github-actions#56 first, which gives the input a default.
lucas-koontz
added a commit
to mindsdb/minds_python_sdk
that referenced
this pull request
Aug 28, 2026
…2017)
The allowlist moved into mindsdb/github-actions and is bots only. This repo
carried one of six hand-maintained copies naming people, and 11 of the 25 names
across those copies had already left the org while still being exempt from
signing. Staff sign like everybody else now. A bot cannot sign, so the two that
actually open pull requests in this org stay exempt in the reusable.
Dropping the line also drops two defects that rode inside it. `bot*` compiled to
an unanchored `new RegExp("bot.*").test(login)`, so it exempted any login
containing "bot", `robotnik` and `sabotage` included. And `Stpmax` never matched
the real login `StpMax`, because non-wildcard entries are compared with a
case-sensitive `===`.
Needs mindsdb/github-actions#56 first, which gives the input a default.
lucas-koontz
added a commit
to mindsdb/mindsdb-js-sdk
that referenced
this pull request
Aug 28, 2026
…2017)
The allowlist moved into mindsdb/github-actions and is bots only. This repo
carried one of six hand-maintained copies naming people, and 11 of the 25 names
across those copies had already left the org while still being exempt from
signing. Staff sign like everybody else now. A bot cannot sign, so the two that
actually open pull requests in this org stay exempt in the reusable.
Dropping the line also drops two defects that rode inside it. `bot*` compiled to
an unanchored `new RegExp("bot.*").test(login)`, so it exempted any login
containing "bot", `robotnik` and `sabotage` included. And `Stpmax` never matched
the real login `StpMax`, because non-wildcard entries are compared with a
case-sensitive `===`.
Needs mindsdb/github-actions#56 first, which gives the input a default.
lucas-koontz
added a commit
to mindsdb/mindsdb_evaluator
that referenced
this pull request
Aug 28, 2026
…2017)
The allowlist moved into mindsdb/github-actions and is bots only. This repo
carried one of six hand-maintained copies naming people, and 11 of the 25 names
across those copies had already left the org while still being exempt from
signing. Staff sign like everybody else now. A bot cannot sign, so the two that
actually open pull requests in this org stay exempt in the reusable.
Dropping the line also drops two defects that rode inside it. `bot*` compiled to
an unanchored `new RegExp("bot.*").test(login)`, so it exempted any login
containing "bot", `robotnik` and `sabotage` included. And `Stpmax` never matched
the real login `StpMax`, because non-wildcard entries are compared with a
case-sensitive `===`.
Needs mindsdb/github-actions#56 first, which gives the input a default.
lucas-koontz
added a commit
to mindsdb/mindsdb_python_sdk
that referenced
this pull request
Aug 28, 2026
…2017)
The allowlist moved into mindsdb/github-actions and is bots only. This repo
carried one of six hand-maintained copies naming people, and 11 of the 25 names
across those copies had already left the org while still being exempt from
signing. Staff sign like everybody else now. A bot cannot sign, so the two that
actually open pull requests in this org stay exempt in the reusable.
Dropping the line also drops two defects that rode inside it. `bot*` compiled to
an unanchored `new RegExp("bot.*").test(login)`, so it exempted any login
containing "bot", `robotnik` and `sabotage` included. And `Stpmax` never matched
the real login `StpMax`, because non-wildcard entries are compared with a
case-sensitive `===`.
Needs mindsdb/github-actions#56 first, which gives the input a default.
lucas-koontz
added a commit
to mindsdb/type_infer
that referenced
this pull request
Aug 28, 2026
…2017)
The allowlist moved into mindsdb/github-actions and is bots only. This repo
carried one of six hand-maintained copies naming people, and 11 of the 25 names
across those copies had already left the org while still being exempt from
signing. Staff sign like everybody else now. A bot cannot sign, so the two that
actually open pull requests in this org stay exempt in the reusable.
Dropping the line also drops two defects that rode inside it. `bot*` compiled to
an unanchored `new RegExp("bot.*").test(login)`, so it exempted any login
containing "bot", `robotnik` and `sabotage` included. And `Stpmax` never matched
the real login `StpMax`, because non-wildcard entries are compared with a
case-sensitive `===`.
Needs mindsdb/github-actions#56 first, which gives the input a default.
lucas-koontz
added a commit
to mindsdb/anton
that referenced
this pull request
Aug 28, 2026
…2017)
The allowlist moved into mindsdb/github-actions and is bots only. This repo
carried one of six hand-maintained copies naming people, and 11 of the 25 names
across those copies had already left the org while still being exempt from
signing. Staff sign like everybody else now. A bot cannot sign, so the two that
actually open pull requests in this org stay exempt in the reusable.
Dropping the line also drops two defects that rode inside it. `bot*` compiled to
an unanchored `new RegExp("bot.*").test(login)`, so it exempted any login
containing "bot", `robotnik` and `sabotage` included. And `Stpmax` never matched
the real login `StpMax`, because non-wildcard entries are compared with a
case-sensitive `===`.
Needs mindsdb/github-actions#56 first, which gives the input a default.
lucas-koontz
added a commit
to mindsdb/cowork
that referenced
this pull request
Aug 28, 2026
…2017)
The allowlist moved into mindsdb/github-actions and is bots only. This repo
carried one of six hand-maintained copies naming people, and 11 of the 25 names
across those copies had already left the org while still being exempt from
signing. Staff sign like everybody else now. A bot cannot sign, so the two that
actually open pull requests in this org stay exempt in the reusable.
Dropping the line also drops two defects that rode inside it. `bot*` compiled to
an unanchored `new RegExp("bot.*").test(login)`, so it exempted any login
containing "bot", `robotnik` and `sabotage` included. And `Stpmax` never matched
the real login `StpMax`, because non-wildcard entries are compared with a
case-sensitive `===`.
Needs mindsdb/github-actions#56 first, which gives the input a default.
lucas-koontz
added a commit
to mindsdb/cowork-server
that referenced
this pull request
Aug 28, 2026
…2017)
The allowlist moved into mindsdb/github-actions and is bots only. This repo
carried one of six hand-maintained copies naming people, and 11 of the 25 names
across those copies had already left the org while still being exempt from
signing. Staff sign like everybody else now. A bot cannot sign, so the two that
actually open pull requests in this org stay exempt in the reusable.
Dropping the line also drops two defects that rode inside it. `bot*` compiled to
an unanchored `new RegExp("bot.*").test(login)`, so it exempted any login
containing "bot", `robotnik` and `sabotage` included. And `Stpmax` never matched
the real login `StpMax`, because non-wildcard entries are compared with a
case-sensitive `===`.
Needs mindsdb/github-actions#56 first, which gives the input a default.
lucas-koontz
added a commit
to mindsdb/engine
that referenced
this pull request
Aug 28, 2026
…egration tests (ENG-2017) Two changes, both about a check saying nothing useful. The CLA allowlist moved into mindsdb/github-actions and is bots only. This repo carried one of six hand-maintained copies naming people, and 11 of the 25 names across those copies had already left the org while still being exempt from signing. Staff sign like everybody else now. Dropping the line also drops two defects that rode inside it: `bot*` compiled to an unanchored regex that exempted any login containing "bot", and `Stpmax` never matched the real login `StpMax` because the comparison is a case-sensitive `===`. Needs mindsdb/github-actions#56 first, which gives the input a default. `All Tests Succeeded` failed on every first-party pull request that carried no deploy label, so its red carried no information. A skipped run_integration_tests means two different things: with no deploy label there was nothing to run them against, which is fine, and a deploy that failed also leaves them skipped, which is not. Reading `!= 'success'` treated both the same. It now gates on whether anything was actually deployed, so a genuine deploy failure still fails the collection job and an unlabelled pull request does not.
lucas-koontz
added a commit
to mindsdb/data-vault
that referenced
this pull request
Aug 28, 2026
…egration tests (ENG-2017) Two changes, both about a check saying nothing useful. The CLA allowlist moved into mindsdb/github-actions and is bots only. This repo carried one of six hand-maintained copies naming people, and 11 of the 25 names across those copies had already left the org while still being exempt from signing. Staff sign like everybody else now. Dropping the line also drops two defects that rode inside it: `bot*` compiled to an unanchored regex that exempted any login containing "bot", and `Stpmax` never matched the real login `StpMax` because the comparison is a case-sensitive `===`. Needs mindsdb/github-actions#56 first, which gives the input a default. `All Tests Succeeded` failed on every first-party pull request that carried no deploy label, so its red carried no information. A skipped run_integration_tests means two different things: with no deploy label there was nothing to run them against, which is fine, and a deploy that failed also leaves them skipped, which is not. Reading `!= 'success'` treated both the same. It now gates on whether anything was actually deployed, so a genuine deploy failure still fails the collection job and an unlabelled pull request does not.
This was referenced Aug 28, 2026
Merged
Merged
Merged
mindsdb-devops
approved these changes
Aug 28, 2026
mindsdb-devops
pushed a commit
to mindsdb/lightwood
that referenced
this pull request
Aug 28, 2026
… (ENG-2017) (#1294) * chore(cla): call the shared CLA reusable instead of a self-hosted job (ENG-2017) The CLA check ran on mdb-dev, a pod inside the newdev cluster. Its triggers, pull_request_target and issue_comment, both run in base-repo context, so GitHub's fork-approval gate never applied and any account could start that pod by opening a pull request or leaving a comment. Replace the hand-rolled job with the reusable anton, cowork and cowork-server already call. It runs on ubuntu-latest, pins the third-party action to a commit, grants actions read rather than write, and skips the job outright for a comment that is not a CLA comment. Refs: ENG-2017 * fix(cla): point the agreement link at the canonical repository (ENG-2017) Both URLs the org uses for this document are rename redirects that resolve to the same repository and serve byte-identical content. A redirect is fine until somebody creates a repository at the old name, and this is the page a contributor reads before agreeing to it. Name the repository that actually holds the file. Refs: ENG-2017 * chore(cla): stop passing an allowlist, the reusable owns it now (ENG-2017) The allowlist moved into mindsdb/github-actions and is bots only. This repo carried one of six hand-maintained copies naming people, and 11 of the 25 names across those copies had already left the org while still being exempt from signing. Staff sign like everybody else now. A bot cannot sign, so the two that actually open pull requests in this org stay exempt in the reusable. Dropping the line also drops two defects that rode inside it. `bot*` compiled to an unanchored `new RegExp("bot.*").test(login)`, so it exempted any login containing "bot", `robotnik` and `sabotage` included. And `Stpmax` never matched the real login `StpMax`, because non-wildcard entries are compared with a case-sensitive `===`. Needs mindsdb/github-actions#56 first, which gives the input a default. * chore(ci): require DevOps review on .github/ (ENG-2017) This repo accepts pull requests from outside contributors and had no CODEOWNERS at all, so a workflow change here needed no particular reviewer. Everything under .github/ decides what runs in CI, on which runner, and with which secrets in scope, which is a trust boundary rather than product code. Auto-request only for now. Making it a hard gate needs require_code_owner_reviews in branch protection, which this repo does not have; that rides ENG-2013's org ruleset.
mindsdb-devops
pushed a commit
to mindsdb/cowork
that referenced
this pull request
Aug 28, 2026
…-2017) (#745) * chore(cla): point the agreement link at the canonical repository (ENG-2017) The URL this passed was an alias that redirects to the repository actually holding the file, and it served byte-identical content, so nothing a contributor reads changes. An alias stops being harmless the moment somebody creates a repository at that name, and this is the page a contributor reads before agreeing to it. Ten library repos moved to the canonical name in the same change set; this makes all thirteen agree. Refs: ENG-2017 * chore(cla): grant actions read rather than write (ENG-2017) The shared reusable now declares `actions: read`, so write buys this caller nothing: a called workflow can never hold more than its caller grants, and the callee's own declaration caps it further. The only write the scope would buy is pullRerunRunner.ts re-running a previously failed CLA run, and that API refuses a GITHUB_TOKEN. Dropping the scope entirely is not an option, because the same file lists the repo's workflows first and main.ts turns any throw into a failed job. This is the grant the README documents for a caller, and this repo was one of three still on the old one. * chore(cla): stop passing an allowlist, the reusable owns it now (ENG-2017) The allowlist moved into mindsdb/github-actions and is bots only. This repo carried one of six hand-maintained copies naming people, and 11 of the 25 names across those copies had already left the org while still being exempt from signing. Staff sign like everybody else now. A bot cannot sign, so the two that actually open pull requests in this org stay exempt in the reusable. Dropping the line also drops two defects that rode inside it. `bot*` compiled to an unanchored `new RegExp("bot.*").test(login)`, so it exempted any login containing "bot", `robotnik` and `sabotage` included. And `Stpmax` never matched the real login `StpMax`, because non-wildcard entries are compared with a case-sensitive `===`. Needs mindsdb/github-actions#56 first, which gives the input a default.
mindsdb-devops
pushed a commit
to mindsdb/anton
that referenced
this pull request
Aug 28, 2026
…-2017) (#409) * chore(cla): point the agreement link at the canonical repository (ENG-2017) The URL this passed was an alias that redirects to the repository actually holding the file, and it served byte-identical content, so nothing a contributor reads changes. An alias stops being harmless the moment somebody creates a repository at that name, and this is the page a contributor reads before agreeing to it. Ten library repos moved to the canonical name in the same change set; this makes all thirteen agree. Refs: ENG-2017 * chore(cla): grant actions read rather than write (ENG-2017) The shared reusable now declares `actions: read`, so write buys this caller nothing: a called workflow can never hold more than its caller grants, and the callee's own declaration caps it further. The only write the scope would buy is pullRerunRunner.ts re-running a previously failed CLA run, and that API refuses a GITHUB_TOKEN. Dropping the scope entirely is not an option, because the same file lists the repo's workflows first and main.ts turns any throw into a failed job. This is the grant the README documents for a caller, and this repo was one of three still on the old one. * chore(cla): stop passing an allowlist, the reusable owns it now (ENG-2017) The allowlist moved into mindsdb/github-actions and is bots only. This repo carried one of six hand-maintained copies naming people, and 11 of the 25 names across those copies had already left the org while still being exempt from signing. Staff sign like everybody else now. A bot cannot sign, so the two that actually open pull requests in this org stay exempt in the reusable. Dropping the line also drops two defects that rode inside it. `bot*` compiled to an unanchored `new RegExp("bot.*").test(login)`, so it exempted any login containing "bot", `robotnik` and `sabotage` included. And `Stpmax` never matched the real login `StpMax`, because non-wildcard entries are compared with a case-sensitive `===`. Needs mindsdb/github-actions#56 first, which gives the input a default.
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.
User story
As whoever has to know who is exempt from signing our contributor agreement
I want that answer in one file, and to be a list of bots rather than a list of people
So that nobody has to prune six copies of a stale employee roster, and nobody forgets to
Why this matters
Fifteen repositories carried six different hand-maintained allowlists, naming 25 people between them. They are not six policies. They are six snapshots of who worked here when each repository was last touched.
11 of those 25 are no longer in the mindsdb org:
George3d6,Ricram2,ala12326571,dusvyat,dylanketterer,ilia-tsyplenkov,maximlopin,mindsdbadmin,paxcema,tmichaeldb,tomhuds. An allowlist entry exempts that account from signing, so each is a former colleague who can contribute to GPL-3.0 and Elastic-2.0 code without signing anything.A list of people is an access-control list. It needs an owner and a review, and nobody was ever going to give six copies either.
What changes
Staff sign like everybody else. It is one comment, it produces an actual signed record rather than an assumption that somebody's employment agreement was in place and covered the work, and it deletes the stale-list problem instead of managing it.
Bots stay, and that is not a shortcut. A bot cannot post the agreement sentence, so with no exemption its pull request is red forever. Measured across all fifteen repositories, exactly two bots open pull requests here:
lightwoodalone has 36 Dependabot pull requests in its last 100.github-actions[bot]needs no entry, because the action already drops user id 41898282 ingraphql.tsbefore the allowlist is consulted.The list lives here and defaults. A wrapper now passes
path-to-documentand nothing else.Two live defects this removes
Both come out of
checkAllowList.ts, and both were in all fifteen repositories.bot*was never a prefix match. The action compiles it tonew RegExp("bot.*")and calls.test(), which is unanchored and searches anywhere in the string. So it also exempted any login containing "bot". I ran the action's own matcher:dependabot[bot]robotniksabotageelliotbotsonThat is an opt-out anybody could grant themselves by choosing a username. Naming the two bots removes the wildcard and the hole with it.
Stpmaxnever matchedStpMax. Non-wildcard entries are compared withpattern === committer, exact and case-sensitive. Every one of the six lists writesStpmax; the real login isStpMax. He has been exempt in zero repositories and asked to sign every time. Dropping the human entries makes the whole class unreachable.Acceptance criteria
allowlistinput defaults, so a caller can omit it.*, so no lookalike login is exempt.dependabot[bot]andmindsdb-release-train[bot]stay exempt, so bot pull requests do not go permanently red.allowlistkeeps working. Making a required input optional is backward compatible, which is what lets the thirteen wrappers drop it in any order after this merges.How to test
lightwoodstill passes the CLA check with no comment.uv run --with pyyaml --with pytest --python 3.12 -m pytest tests/test_cla_allowlist.py -q. Then putbot*, ZoranPandovskiback as the default and run it again; it should go red.Notes for the reviewer
Everyone at MindsDB will be asked to sign, once per repository, the first time they open a pull request there. That is the intended cost and it is worth saying out loud before this merges, because it will surprise people. Fourteen current org members are affected. It is one comment each.
The
mindsdbadminquestion is left open on purpose. It is in every one of the six lists, it is not an org member, andengine's andminds_python_sdk's release jobs still guard ongithub.actor != 'mindsdbadmin', so something still uses it. Whether it needs an exemption is a question for whoever owns that account, not something to guess at here.Ex-staff lose their exemption, and I think that is correct rather than a regression. All eleven are already out of the org. If they contribute again they sign, like any other outside contributor. Say if you would rather grandfather any of them, because it is one entry.
The test is a real guard, not coverage theatre. Against the old list it fails 8 of its 11 cases, including all four lookalike logins.
Verified locally
pytest tests/ -qbot*, ZoranPandovski, torrmal, Stpmax, mindsdbadminand re-ran: 8 failed, 3 passed. Restored: 11 passed.actionlintworkflow_graph.py --allow-external-reusablesgh api repos/mindsdb/<repo>/pulls?state=all&per_page=100across all 15:dependabot[bot]42,mindsdb-release-train[bot]13, nothing else.github-actions[bot]is filtered upstreamgraphql.tsdrops id 41898282;gh api user/41898282resolves togithub-actions[bot].gh api orgs/mindsdb/members/<login>for all 25 named logins: 14 members, 11 not.Ships with
The thirteen wrappers that currently pass their own list drop it, in any order
after this merges. Making a required input optional is backward compatible, so
nothing breaks in the window between.
Merge order: this one first. A wrapper that drops
allowlistwhile theinput is still
required: truefails to load.Refs: ENG-2017