7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 1 | # Contributing to `matrix-rust-sdk` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 2 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 3 | ## Chat rooms |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 4 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 5 | In addition to our [main Matrix room], we have a development room at |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 6 | [#matrix-rust-sdk-dev:flipdot.org]. Please use it to discuss potential changes, |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 7 | the overall direction of development and related topics. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 8 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 9 | [main Matrix room]: https://matrix.to/#/#matrix-rust-sdk:matrix.org |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 10 | [#matrix-rust-sdk-dev:flipdot.org]: https://matrix.to/#/#matrix-rust-sdk-dev:flipdot.org |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 11 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 12 | ## Testing |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 13 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 14 | You can run most of the tests that also happen in CI also using |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 15 | `cargo xtask ci`. This needs a few dependencies to be installed, as it also runs |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 16 | automatic WASM tests: |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 17 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 18 | ```bash |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 19 | rustup component add clippy |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 20 | cargo install cargo-nextest typos-cli wasm-pack |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 21 | ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 22 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 23 | If you want to execute only one part of CI, there are a few sub-commands (see |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 24 | `cargo xtask ci --help`). |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 25 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 26 | Some tests are not automatically run in `cargo xtask ci`, for example the |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 27 | integration tests that need a running synapse instance. These tests reside in |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 28 | `./testing/matrix-sdk-integration-testing`. See its |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 29 | [README](./testing/matrix-sdk-integration-testing/README.md) to easily set up a |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 30 | synapse for testing purposes. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 31 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 32 | ### Snapshot testing |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 33 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 34 | You can add/review snapshot tests using [insta.rs](https://insta.rs) |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 35 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 36 | Every new struct/enum that derives `Serialize` `Deserialise` should have a |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 37 | snapshot test for it. Any code change that breaks serialisation will then break |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 38 | a test, the author will then have to decide how to handle migration and test it |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 39 | if needed. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 40 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 41 | And for an improved review experience it's recommended (but not necessary) to |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 42 | install the `cargo-insta` tool: |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 43 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 44 | Unix: |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 45 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 46 | ```shell |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 47 | curl -LsSf https://insta.rs/install.sh | sh |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 48 | ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 49 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 50 | Windows: |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 51 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 52 | ```shell |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 53 | powershell -c "irm https://insta.rs/install.ps1 | iex" |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 54 | ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 55 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 56 | Usual flow is to first run the test, then review them. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 57 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 58 | ```shell |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 59 | cargo insta test |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 60 | cargo insta review |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 61 | ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 62 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 63 | ### Intermittent failure policy |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 64 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 65 | While we strive to add test coverage for as many features as we can, it |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 66 | sometimes happens that the tests will be intermittently failing in CI (such |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 67 | tests are sometimes called "flaky"). This can be caused by race conditions |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 68 | of all sorts, either in the test code itself, but sometimes in the underlying |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 69 | feature being tested too, and as such, it requires some investigation, usually |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 70 | from the original author of the test. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 71 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 72 | Whenever such an intermittent failure happens, we try to open an issue to track |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 73 | the failures, adding the |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 74 | [`intermittent-failure`](https://github.com/matrix-org/matrix-rust-sdk/issues?q=is%3Aissue%20state%3Aopen%20label%3Aintermittent-failure) |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 75 | label to it, and commenting with links to CI runs where the failure happened. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 76 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 77 | If a test has been intermittently failing for **two weeks** or more, and no one |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 78 | is actively working on fixing it, then we might decide to mark the test as |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 79 | `ignored` until it is fixed, to not cause unrelated failures in other |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 80 | contributors' pull requests and pushes. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 81 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 82 | ## Pull requests |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 83 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 84 | Ideally, a PR should have a _proper title_, with _atomic logical commits_, and |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 85 | each commit should have a _good commit message_. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 86 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 87 | A _proper PR title_ would be a one-liner summary of the changes in the PR, |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 88 | following the same guidelines of a good commit message, including the |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 89 | area/feature prefix. Something like `FFI: Allow logs files to be pruned.` would |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 90 | be a good PR title. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 91 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 92 | (An additional bad example of a bad PR title would be `mynickname/branch name`, |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 93 | that is, just the branch name.) |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 94 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 95 | ## Writing changelog entries |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 96 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 97 | We use towncrier to generate changelogs from individual fragment files. Each |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 98 | change must be documented as a changelog fragment in the appropriate crate: |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 99 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 100 | ```text |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 101 | /crates/<crate-name>/changelog.d/ |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 102 | ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 103 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 104 | Each changelog fragment must include **both the pull request number and the |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 105 | fragment type** in its filename: |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 106 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 107 | ```text |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 108 | <PR number>.<fragment type>.md |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 109 | ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 110 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 111 | For example: |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 112 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 113 | ```text |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 114 | 4357.added.md |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 115 | 4357.fixed.md |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 116 | 4357.changed.md |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 117 | ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 118 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 119 | The pull request link is automatically added during changelog generation, so it |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 120 | must not be included manually. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 121 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 122 | We use standard towncrier fragment types to categorize changes. Common types |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 123 | include: |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 124 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 125 | - `added` – new features or functionality |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 126 | - `changed` – changes in existing behavior |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 127 | - `fixed` – bug fixes |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 128 | - `removed` – removed features or APIs |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 129 | - `security` – security-related fixes |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 130 | - `internal` – changes that do not affect users (refactoring, CI, tooling) |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 131 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 132 | Choose the type that best matches the nature of the change. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 133 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 134 | A well-written changelog entry should be understandable even to those who may |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 135 | not be deeply familiar with the project. Provide enough context to ensure |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 136 | clarity and ease of understanding. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 137 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 138 | A couple of examples of bad changelog entry would look like: |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 139 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 140 | ```markdown |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 141 | - Fixed a panic. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 142 | ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 143 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 144 | ```markdown |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 145 | Added the Bar function to Foo. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 146 | ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 147 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 148 | A good example of a changelog entry could look like the following: |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 149 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 150 | ```markdown |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 151 | Use the inviter's server name and the server name from the room alias as |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 152 | fallback values for the via parameter when requesting the room summary from the |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 153 | homeserver. This ensures requests succeed even when the room being previewed is |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 154 | hosted on a federated server. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 155 | ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 156 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 157 | For security-related changelog entries, please include the following additional |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 158 | details alongside the pull request number: |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 159 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 160 | - Impact: Clearly describe the issue's potential impact on users or systems. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 161 | - CVE Number: If available, include the CVE (Common Vulnerabilities and |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 162 | Exposures) identifier. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 163 | - GitHub Advisory Link: Provide a link to the corresponding GitHub security |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 164 | advisory for further context. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 165 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 166 | ```markdown |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 167 | Use a constant-time Base64 encoder for secret key material to mitigate |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 168 | side-channel attacks leaking secret key material |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 169 | [CVE-2024-40640](https://www.cve.org/CVERecord?id=CVE-2024-40640), |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 170 | [GHSA-j8cm-g7r6-hfpq](https://github.com/matrix-org/vodozemac/security/advisories/GHSA-j8cm-g7r6-hfpq)). |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 171 | ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 172 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 173 | ## Commit message format |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 174 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 175 | Commit messages should be formatted as Conventional Commits. In addition, some |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 176 | git trailers are supported and have special meaning (see below). |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 177 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 178 | ### Conventional commits |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 179 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 180 | Conventional Commits are structured as follows: |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 181 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 182 | ```text |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 183 | <type>(<scope>): <short summary> |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 184 | ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 185 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 186 | The type of changes which will be included in changelogs is one of the |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 187 | following: |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 188 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 189 | - `feat`: A new feature |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 190 | - `fix`: A bugfix |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 191 | - `doc`: Documentation changes |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 192 | - `refactor`: Code refactoring |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 193 | - `perf`: Performance improvements |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 194 | - `ci`: Changes to CI configuration files and scripts |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 195 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 196 | The scope is optional and can specify the area of the codebase affected (e.g., |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 197 | olm, cipher). |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 198 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 199 | ### Security fixes |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 200 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 201 | Commits addressing security vulnerabilities must include specific trailers for |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 202 | vulnerability metadata, which should also be reflected in the corresponding |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 203 | changelog entry. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 204 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 205 | The metadata must be included in the following git-trailers: |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 206 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 207 | - `Security-Impact`: The magnitude of harm that can be expected, i.e. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 208 | low/moderate/high/critical. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 209 | - `CVE`: The CVE that was assigned to this issue. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 210 | - `GitHub-Advisory`: The GitHub advisory identifier. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 211 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 212 | Please include all the fields that are available. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 213 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 214 | Example: |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 215 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 216 | ```text |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 217 | fix(crypto): Use a constant-time Base64 encoder for secret key material |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 218 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 219 | This patch fixes a security issue around a side-channel vulnerability[1] |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 220 | when decoding secret key material using Base64. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 221 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 222 | In some circumstances an attacker can obtain information about secret |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 223 | secret key material via a controlled-channel and side-channel attack. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 224 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 225 | This patch avoids the side-channel by switching to the base64ct crate |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 226 | for the encoding, and more importantly, the decoding of secret key |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 227 | material. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 228 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 229 | Security-Impact: Low |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 230 | CVE: CVE-2024-40640 |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 231 | GitHub-Advisory: GHSA-j8cm-g7r6-hfpq |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 232 | ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 233 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 234 | ## Review process |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 235 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 236 | To streamline the review process and make it easier for maintainers to review |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 237 | your contributions, follow these basic rules: |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 238 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 239 | 1. Do not force push after a review has started. This helps maintainers track |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 240 | incremental changes without confusion and makes it easier to follow the |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 241 | evolution of the code. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 242 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 243 | 2. Do not mix moves and refactoring with functional changes. Keep these in |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 244 | separate commits for clarity. This ensures that the purpose of each commit is |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 245 | clear and easy to review. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 246 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 247 | 3. Each commit must compile. If commits don’t compile, git bisect becomes |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 248 | unusable, which hampers the debugging process and makes it harder to identify |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 249 | the source of issues. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 250 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 251 | 4. Commits should only introduce test failures if they are proving that a bug |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 252 | exists. New features should never introduce test failures. Test failures |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 253 | should only be used to demonstrate existing bugs, not as part of adding new |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 254 | functionality. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 255 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 256 | 5. Keep PRs on topic and small. Large PRs are harder to review and more prone to |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 257 | delays. Create small, focused commits that address a single topic. Use a |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 258 | combination of [git add] -p or [git checkout] -p to split changes into |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 259 | logical units. This makes your work easier to review and reduces the chance |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 260 | of introducing unrelated changes. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 261 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 262 | [git add]: https://git-scm.com/docs/git-add#Documentation/git-add.txt---patch |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 263 | [git checkout]: https://git-scm.com/docs/git-checkout#Documentation/git-checkout.txt---patch |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 264 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 265 | ### Addressing review comments using fixup commits |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 266 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 267 | So you posted a PR and the maintainers aren't quite happy with it. Here are some |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 268 | guidelines to make the maintainers life easier and increase the chances that |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 269 | your PR will be reviewed swiftly. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 270 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 271 | 1. Use [fixup] commits. When addressing reviewer feedback, you can create fixup |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 272 | commits. These commits mark your changes as corrections of specific previous |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 273 | commits in the PR. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 274 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 275 | Example: |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 276 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 277 | ```shell |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 278 | git commit --fixup=<commit-hash> |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 279 | ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 280 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 281 | This command creates a new commit that refers to an existing one, making it |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 282 | easier to rebase and squash later while showing reviewers the history of fixes. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 283 | For extra points, link to the fixup commit in the thread where the change was |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 284 | requested. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 285 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 286 | 2. After all requested changes were addressed, feel free to re-request a review. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 287 | People might not notice that all changes were addressed. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 288 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 289 | 3. Once the PR has been approved, rebase your PR to squash all the fixup |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 290 | commits, the [autosquash] option can help with this. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 291 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 292 | ```shell |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 293 | git rebase main --interactive --autosquash |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 294 | ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 295 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 296 | [fixup]: https://git-scm.com/docs/git-commit#Documentation/git-commit.txt---fixupamendrewordltcommitgt |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 297 | [autosquash]: https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt---autosquash |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 298 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 299 | ## Sign off |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 300 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 301 | In order to have a concrete record that your contribution is intentional |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 302 | and you agree to license it under the same terms as the project's |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 303 | license, we've adopted the same lightweight approach that the [Linux |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 304 | Kernel](https://www.kernel.org/doc/Documentation/SubmittingPatches), |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 305 | [Docker](https://github.com/docker/docker/blob/master/CONTRIBUTING.md), |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 306 | and many other projects use: the DCO ([Developer Certificate of |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 307 | Origin](http://developercertificate.org/)). This is a simple declaration that |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 308 | you wrote the contribution or otherwise have the right to contribute it to |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 309 | Matrix: |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 310 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 311 | ```text |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 312 | Developer Certificate of Origin |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 313 | Version 1.1 |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 314 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 315 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 316 | 660 York Street, Suite 102, |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 317 | San Francisco, CA 94110 USA |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 318 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 319 | Everyone is permitted to copy and distribute verbatim copies of this |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 320 | license document, but changing it is not allowed. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 321 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 322 | Developer's Certificate of Origin 1.1 |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 323 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 324 | By making a contribution to this project, I certify that: |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 325 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 326 | (a) The contribution was created in whole or in part by me and I |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 327 | have the right to submit it under the open source license |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 328 | indicated in the file; or |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 329 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 330 | (b) The contribution is based upon previous work that, to the best |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 331 | of my knowledge, is covered under an appropriate open source |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 332 | license and I have the right under that license to submit that |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 333 | work with modifications, whether created in whole or in part |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 334 | by me, under the same open source license (unless I am |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 335 | permitted to submit under a different license), as indicated |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 336 | in the file; or |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 337 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 338 | (c) The contribution was provided directly to me by some other |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 339 | person who certified (a), (b) or (c) and I have not modified |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 340 | it. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 341 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 342 | (d) I understand and agree that this project and the contribution |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 343 | are public and that a record of the contribution (including all |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 344 | personal information I submit with it, including my sign-off) is |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 345 | maintained indefinitely and may be redistributed consistent with |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 346 | this project or the open source license(s) involved. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 347 | ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 348 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 349 | If you agree to this for your contribution, then all that's needed is to |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 350 | include the line in your commit or pull request comment: |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 351 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 352 | ```text |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 353 | Signed-off-by: Your Name <your@email.example.org> |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 354 | ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 355 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 356 | Git allows you to add this signoff automatically when using the `-s` flag to |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 357 | `git commit`, which uses the name and email set in your `user.name` and |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 358 | `user.email` git configs. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 359 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 360 | If you forgot to sign off your commits before making your pull request and are |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 361 | on Git 2.17+ you can mass signoff using rebase: |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 362 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 363 | ```text |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 364 | git rebase --signoff origin/main |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 365 | ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 366 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 367 | ## AI policy |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 368 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 369 | This policy is a copy of the [Forgejo's AI agreement][Forgejo]. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 370 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 371 | ### Terminology |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 372 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 373 | This does not necessarily reflect the official or commonly used terminology. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 374 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 375 | Software and services that heavily rely on large language model technology to |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 376 | generate their outcomes are referred to as _Artificial Intelligence_ (AI). |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 377 | Examples of products that fit this definition: GitHub Copilot, ChatGPT, Claude |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 378 | Sonnet, DeepSeek, Llama and Gemini. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 379 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 380 | There is a distinction between _general_ and _narrow_ AI, all the aforementioned |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 381 | examples fall under general AI as they were not trained to execute a specific |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 382 | well-defined task. Narrow AI is trained to be used for specific well-defined |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 383 | tasks where the problem space is known in advance. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 384 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 385 | _Vibe coding_ is the practice where AI creates a code change (feature, bugfix, |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 386 | tests, refactor) with a human that describes what needs to be implemented. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 387 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 388 | _AI agents_ are AIs that are configured to perform interactions or make changes |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 389 | with little to no human supervision. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 390 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 391 | ### Agreement |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 392 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 393 | 1. If content was made with the help of AI, you **must** convey that this is |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 394 | the case. This includes content that you authored but was motivated by a |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 395 | suggestion of AI. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 396 | 2. If at any point you used AI's work in your contribution you should make |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 397 | an effort to **verify** that you can submit this under the license of the |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 398 | repository. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 399 | 3. The **accountability** of using AI in a contribution lies with the person |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 400 | that makes that contribution. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 401 | 4. All communication, that includes: commit messages, pull request messages, |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 402 | documentation, code comments and issues (and comments on issues/pull |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 403 | requests), that is intended to be read by people to understand your thoughts |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 404 | and work **must not** have been generated with AI. We exclude machine |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 405 | translation and tooling that helps with grammar and spelling check. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 406 | 5. Using general AI for review is **forbidden**. If the change contains changes |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 407 | to the user experience it has to be approved by a human reviewer. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 408 | 6. It is **not allowed** to use AI in an autonomous-looking way to contribute to |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 409 | the Matrix Rust SDK. This also applies when someone engages in _vibe coding_ |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 410 | or uses so-called _agent mode_. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 411 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 412 | [Forgejo]: https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md |