Two files, one repository
envoyproxy/envoy ships 2 formats across 3 indexed files. The question worth asking is whether the second one says anything the first does not.
| Dimension | Shared | Only in A | Only in B | Overlap |
|---|---|---|---|---|
| Sections | 0 | 20 | 14 | 0% |
| Commands | 0 | 10 | 0 | 0% |
| Section tags | 2 | 9 | 0 | 18% |
What each file covers
Sections
0 shared · 20 only in A · 14 only in B- − AGENTS.md
- − Critical rules
- − Developer workflow
- − 1. Before starting work
- − 2. Writing code
- − 3. Building and testing
- − Docker-based (recommended — matches CI environment)
- − Local (requires local dependencies)
- − 4. Format and lint checks (required before every commit)
- − 5. Creating the commit
- − 6. Pushing and creating a PR
- − 7. Waiting for CI and review
- − 8. Addressing review comments
- − 9. After merge
- − Understanding CI
- − Inclusive language
- − BUILD file conventions
- − Updating dependencies
- − CI and GitHub Actions (for workflow file authors)
- − Key files
- + compat/openssl — Guide for AI Agents
- + Architecture in brief
- + Key files to modify
- + How to add a missing function
- + Step 1: Uncomment the declaration
- + Step 2: Add to the BUILD file
- + Step 3: Decide if a handwritten source file is needed
- + How to add a missing constant or macro
- + Constant exists in both BoringSSL and OpenSSL
- + Constant exists only in BoringSSL (no OpenSSL equivalent)
- + Constant with duplicate-case-value problem
- + uncomment.sh — common options
- + Inspecting generated output
- + Typical workflow for fixing build errors after a dep bump
Commands
0 shared · 10 only in A · 0 only in B- − git fetch origin
- − git log main..origin/main --oneline
- − git checkout main && git pull && git checkout -
- − git checkout -b <descriptive-branch-name>
- − git add <files>
- − git commit -s
- − git fetch origin main && git merge origin/main
- − gh pr checks <PR-number>
- − gh run view <run-id> --log-failed
- − git merge main
Section tags
2 shared · 9 only in A · 0 only in B- − setup
- − test
- − lint-format
- − code-style
- − git-pr
- − security
- − dependencies
- − do-not
- − docs
- build
- agent-behaviour
Line diff
envoyproxy/envoy · AGENTS.md
@@ −1 @@
1# AGENTS.md
2
3Instructions for AI coding agents (Claude Code, Copilot, Cursor, etc.) working in this repository.
4
5## Critical rules
6
71. **Always sign off commits.** The human user must sign off commits via `git commit -s` — never
8 manually write a `Signed-off-by` trailer. The sign-off attests that the committer (the user)
9 has the right to submit the code under the project's license.
102. **Always run format and lint checks before committing.** Use `tools/local_fix_format.sh` for
11 a quick local check, or run `./ci/do_ci.sh format` inside Docker for the full CI check suite.
12 Format failures are the most common CI rejection. If running checks is impractical, warn the
13 user that formatting has not been verified.
143. **Never amend commits or force-push after a PR has received human review.** Always create new
15 commits to preserve review history.
164. **Never rebase a PR that is under review.** Use `git merge main` instead to pull in recent
17 changes. The project squash-merges, so commit count does not matter.
185. **Disclose AI usage.** When submitting PRs, include a note about AI assistance in the PR
19 description. The submitter must fully understand all code being submitted.
206. **Never commit to `main`.** Always create a new branch before committing. If switching
21 contexts or unsure which branch to use, ask the user.
227. **Always push to a personal fork.** Do not create branches in the main repo.
23
24## Developer workflow
25
26### 1. Before starting work
27
28Read `CONTRIBUTING.md` for the full contribution process. Key points:
29- **Major features (>100 LOC or user-facing):** Open a GitHub issue first to discuss design.
30 For new extensions, read `EXTENSION_POLICY.md`.
31- **Small patches and bug fixes:** No prior communication needed.
32- Install git hooks: `./support/bootstrap`
33
34### 2. Writing code
35
36Read `STYLE.md` for the C++ coding style. After writing C++ code, run `clang-format` to fix
37formatting automatically rather than trying to hand-format:
38
39```bash
40clang-format -i <file>
41```
42
43Tests must:
44- Live in `test/` mirroring the `source/` structure
45- Achieve 100% coverage for new code
46- Use `StrictMock` by default, `SimulatedTimeSystem` for time, port 0 for network
47- Unit tests must be hermetic and deterministic — no real time, no randomness
48- Integration tests (in `test/integration/`) use real network on localhost
49
50### 3. Building and testing
51
52See `bazel/README.md` for full build documentation. Common commands:
53
54```bash
55# Docker-based (recommended — matches CI environment)
56./ci/run_envoy_docker.sh bash # interactive shell
57./ci/do_ci.sh debug //test/common/http/... # build + test
58./ci/do_ci.sh debug.server_only # build binary only
59
60# Local (requires local dependencies)
61bazel test -c dbg //test/common/http/... # run tests
62bazel build --config=clang -c opt //source/exe:envoy-static # optimized binary
63```
64
65Sanitizers, coverage, GDB debugging, and profiling are resource-intensive. Do **not** run
66them unless the user explicitly asks. See `bazel/README.md` and `bazel/PPROF.md`.
67
68### 4. Format and lint checks (required before every commit)
69
70Format failures are the most common CI rejection. Agents should produce content that conforms
71to the repo's style conventions for all file types (C++, BUILD, YAML, Markdown, shell, etc.).
72
73**Quick local check (recommended):**
74
75```bash
76tools/local_fix_format.sh # uncommitted changes (default)
77tools/local_fix_format.sh -main # changes since main
78tools/local_fix_format.sh -all # entire repo
79```
80
81**Individual checks:**
82
83```bash
84bazel run //tools/code_format:check_format -- fix # C++, BUILD, .bzl, .proto
85bazel run //tools/spelling:check_spelling_pedantic -- fix # spelling
86./ci/do_ci.sh format # full CI check (inside Docker)
87```
88
89**Linter config files — read these to produce compliant output without running the tools:**
90
91| Config file | What it configures |
92|-------------|--------------------|
93| `.clang-format` | C++/Proto formatting (100-col, include order, pointer alignment) |
94| `.yamllint` | YAML rules (140-col max, consistent indentation) |
95| `.flake8` | Python lint rules |
96| `rustfmt.toml` | Rust formatting (100-col, 2-space indent) |
97| `tools/spelling/spelling_dictionary.txt` | Custom word list (1700+ project terms) |
98
99### 5. Creating the commit
100
101Before your first commit in a session:
102
1031. Check if the local `main` is up to date with `origin/main`:
104 ```bash
105 git fetch origin
106 git log main..origin/main --oneline
107 ```
1082. If `main` is behind, sync it:
109 ```bash
110 git checkout main && git pull && git checkout -
111 ```
1123. Create a new branch off the updated `main`:
113 ```bash
114 git checkout -b <descriptive-branch-name>
115 ```
1164. If you had uncommitted changes that conflict with the updated `main`, ask the user whether
117 to proceed on the outdated base or resolve conflicts against the new `main`.
118
119If you're switching contexts or unsure which branch to commit to, ask the user before committing.
120
121```bash
122git add <files>
123git commit -s # -s adds Signed-off-by automatically; NEVER write it manually
124```
125
126### 6. Pushing and creating a PR
127
128**PR title format** — lower-case subsystem prefix followed by a colon:
129`docs: fix grammar error`, `router: add x-envoy-overloaded header`
130
131**PR description template** — every PR must fill in:
132
133```
134Commit Message: <what this PR does — used as the final squash-merge message>
135Additional Description: <context useful to reviewers>
136Risk Level: Low | Medium | High
137Testing: <what testing was done>
138Docs Changes: <description or N/A>
139Release Notes: <description or N/A>
140```
141
142See `PULL_REQUESTS.md` for full field descriptions and optional fields (runtime guard,
143deprecation, platform-specific features).
144
145**Release notes:** User-facing changes **must** add a release note fragment under
146`changelogs/current/`. Name the file `<area>__<short-description>.rst`.
147
148### 7. Waiting for CI and review
149
150- Do **not** create draft PRs if you want prompt reviews — draft PRs are not triaged.
151- To re-run failed CI tasks, add a `/retest` comment on the PR.
152- PRs with no activity for 14+ days may be closed.
153
154### 8. Addressing review comments
155
156- **Never amend or force-push** after a reviewer has looked at the PR. Create new commits.
157- **Never rebase.** If you need to incorporate upstream changes:
158 ```bash
159 git fetch origin main && git merge origin/main
160 ```
161- If the reviewer asked for a runtime guard, add one (see `CONTRIBUTING.md`).
162
163### 9. After merge
164
165The project squash-merges PRs. The "Commit Message" field in your PR description becomes the
166final commit message. Make sure it's up to date before merge.
167
168## Understanding CI
169
170Envoy uses a checks-based CI system. Results appear as **GitHub Check Runs** on PRs, not as
171simple workflow pass/fail statuses.
172
173**CI pipeline:**
174
1751. **`Envoy/Prechecks`** — fast checks: format/lint/spelling, dependency validation, docs build
1762. **`Envoy/Checks`** — heavier checks: compilation, tests, coverage, sanitizers
177
178**Checking CI status:**
179
180```bash
181gh pr checks <PR-number>
182gh run view <run-id> --log-failed
183```
184
185When CI fails, check the failed check run name to determine which `do_ci.sh` target to
186reproduce locally. Format failures come from `Envoy/Prechecks`; build/test failures come
187from `Envoy/Checks`.
188
189## Inclusive language
190
191The following terms are **not allowed**:
192- ~~whitelist~~ -> allowlist
193- ~~blacklist~~ -> denylist / blocklist
194- ~~master~~ -> primary / main
195- ~~slave~~ -> secondary / replica
196
197## BUILD file conventions
198
199See `bazel/DEVELOPER.md` for full BUILD file rules. Key points:
200- Use `envoy_cc_library`, `envoy_cc_test`, `envoy_cc_mock` (not raw `cc_library`)
201- Target suffixes: `_lib`, `_test`, `_mocks`, `_interface`
202- Every `#include` must have a corresponding `deps` entry
203
204## Updating dependencies
205
206See `bazel/EXTERNAL_DEPS.md` and `DEPENDENCY_POLICY.md`. When updating a version:
2071. Update version, sha256, and urls in `bazel/repository_locations.bzl`
2082. Update `release_date` in `bazel/deps.yaml` to the UTC date of the new release
2093. Prefer maintainer-provided tarballs over GitHub auto-generated ones
210
211## CI and GitHub Actions (for workflow file authors)
212
213- In `if:` conditions, do **not** wrap expressions in `${{ }}` — the `if` field evaluates
214 expressions implicitly. Use `${{ }}` only in string contexts (`run:`, `with:`, `env:`).
215- Workflow files in `.github/workflows/` are shared across all branches (main and stable release
216 branches). Do not remove variables or inputs still referenced by stable branches.
217
218## Key files
219
220| File | Purpose |
221|------|---------|
222| `STYLE.md` | C++ coding style and error handling |
223| `CONTRIBUTING.md` | Contribution guidelines, deprecation, breaking changes |
224| `PULL_REQUESTS.md` | PR field descriptions |
225| `EXTENSION_POLICY.md` | Extension lifecycle and requirements |
226| `DEPENDENCY_POLICY.md` | External dependency rules |
227| `RELEASES.md` | Release schedule and backport process |
228| `SECURITY.md` | Security reporting and disclosure |
229| `REPO_LAYOUT.md` | Repository structure |
230| `bazel/README.md` | Building, testing, sanitizers, coverage |
231| `bazel/DEVELOPER.md` | BUILD file conventions |
232| `bazel/EXTERNAL_DEPS.md` | Managing external dependencies |
233| `bazel/PPROF.md` | Performance profiling |
234| `source/extensions/extensions_metadata.yaml` | Extension status and security posture |
235| `source/common/runtime/runtime_features.cc` | Runtime feature flag defaults |
236
envoyproxy/envoy · compat/openssl/AGENTS.md
@@ +1 @@
1# compat/openssl — Guide for AI Agents
2
3Instructions for AI agents adapting the OpenSSL compatibility layer when new BoringSSL
4symbols are needed (typically after bumping gRPC, BoringSSL, or other deps).
5
6See `README.md` in this directory for the full architectural background.
7
8## Architecture in brief
9
10Envoy is built against the BoringSSL API. The compat layer lets it run on OpenSSL instead.
11
121. **Prefixer** (`prefixer/prefixer.cpp`) copies OpenSSL headers, adding an `ossl_` prefix
13 to every identifier. Output lands in `include/ossl/openssl/*.h`. It also generates
14 `source/ossl.c` (forwarding functions via dlsym) and `include/ossl.h` (the `ossl` struct
15 with function pointers for every real OpenSSL function).
16
172. **Patched BoringSSL headers** (`patch/include/openssl/*.h.sh`) start by commenting out the
18 entire BoringSSL header, then selectively uncomment the symbols the compat layer exposes.
19 The `uncomment.sh` tool handles this. The output is `include/openssl/*.h`.
20
213. **Mapping functions** (`source/*.c` or `source/*.cc`) implement each exposed BoringSSL
22 function by calling the `ossl_`-prefixed OpenSSL equivalent.
23
24## Key files to modify
25
26| File | Purpose |
27|------|---------|
28| `patch/include/openssl/<header>.h.sh` | Controls which symbols from BoringSSL's `<header>.h` are exposed |
29| `BUILD` | The `mapping_func_filegroup` list — every exposed function must be listed here |
30| `source/<function>.c` or `.cc` | Handwritten mapping when auto-generation won't work |
31
32## How to add a missing function
33
34### Step 1: Uncomment the declaration
35
36Add `--uncomment-func-decl <function_name>` to the appropriate `.h.sh` patch script.
37
38Example in `ssl.h.sh`:
39```bash
40 --uncomment-func-decl SSL_get_negotiated_group \
41```
42
43### Step 2: Add to the BUILD file
44
45Add the function name to the `mapping_func_filegroup` list (alphabetically sorted within
46its section).
47
48### Step 3: Decide if a handwritten source file is needed
49
50The build system (`bazel/rules.bzl`) auto-generates a forwarding function if no handwritten
51`source/<function>.c` or `.cc` exists. The generated code handles both cases — OpenSSL
52macros and real functions — using an `#ifdef`:
53
54```c
55// Auto-generated pattern:
56ReturnType FunctionName(args) {
57#ifdef ossl_FunctionName
58 return ossl_FunctionName(args); // macro path (expands inline)
59#else
60 return ossl.ossl_FunctionName(args); // function pointer path (via dlsym)
61#endif
62}
63```
64
65**You need a handwritten source when:**
66- The BoringSSL and OpenSSL signatures differ (different arg types, arg count)
67- The semantics differ (e.g., `SSL_CTX_set1_curves_list` has an OpenSSL 3.5 bug workaround)
68- The function has no OpenSSL equivalent at all (must be implemented from scratch)
69
70**You can rely on auto-generation when:**
71- The function exists in OpenSSL with the same signature (as a real function or macro)
72- No semantic differences need patching
73
74## How to add a missing constant or macro
75
76### Constant exists in both BoringSSL and OpenSSL
77
78Add `--uncomment-macro-redef '<pattern>'` to the `.h.sh` patch script. This generates:
79
80```c
81#ifdef ossl_CONSTANT_NAME
82#define CONSTANT_NAME ossl_CONSTANT_NAME
83#endif
84```
85
86The constant gets OpenSSL's value. Use regex patterns to cover families:
87```bash
88 --uncomment-macro-redef 'SSL_R_[[:alnum:]_]*' \
89 --uncomment-macro-redef 'OPENSSL_INIT_[[:alnum:]_]*' \
90```
91
92### Constant exists only in BoringSSL (no OpenSSL equivalent)
93
94The `--uncomment-macro-redef` approach won't work because there's no `ossl_` version — the
95`#ifdef` guard will be false and the constant stays undefined.
96
97Instead, append a standalone `#ifndef`/`#define` block at the end of the `.h.sh` script:
98
99```bash
100cat >> "$1" <<'EOF'
101
102#ifndef SSL_R_SOME_BORINGSSL_ONLY_CONSTANT
103#define SSL_R_SOME_BORINGSSL_ONLY_CONSTANT <value>
104#endif
105EOF
106```
107
108**Choosing values:** BoringSSL and OpenSSL often use the same numeric range for different
109constants. For example, BoringSSL's `SSL_R_NO_CIPHERS_PASSED = 176` collides with OpenSSL's
110`SSL_R_NO_CERTIFICATES_RETURNED = 176`. If both appear in the same switch statement,
111you get a duplicate-case error. To avoid this, use values in a range that neither library
112uses (e.g., 10000+ for `SSL_R_*` constants). The exact values don't matter at runtime
113since OpenSSL will never produce these BoringSSL-specific error codes.
114
115### Constant with duplicate-case-value problem
116
117If a constant must exist but its value collides with another constant's value (e.g.,
118`ERR_R_OVERFLOW` aliased to `ERR_R_INTERNAL_ERROR`), give it a unique value. Check
119OpenSSL's range for the constant family in `bazel-envoy/external/openssl/include/openssl/`
120and pick a value above the highest used one.
121
122## uncomment.sh — common options
123
124| Option | Effect |
125|--------|--------|
126| `--uncomment-func-decl <name>` | Uncomment a function declaration |
127| `--uncomment-macro '<pattern>'` | Uncomment a `#define` (keeps BoringSSL's value) |
128| `--uncomment-macro-redef '<pattern>'` | Redefine macro to use OpenSSL's value via `ossl_` prefix |
129| `--uncomment-enum <name>` | Uncomment an enum definition |
130| `--uncomment-struct <name>` | Uncomment a struct definition |
131| `--uncomment-typedef <name>` | Uncomment a typedef |
132| `--uncomment-typedef-redef <name>` | Redefine a typedef to use OpenSSL's type |
133| `--uncomment-regex '<pattern>'` | Uncomment lines matching a regex |
134| `--uncomment-regex-range '<start>' '<end>'` | Uncomment a multi-line block |
135| `--sed '<expression>'` | Run an arbitrary sed expression on the file |
136
137## Inspecting generated output
138
139To see what the compat layer actually produces after patching/prefixing, look in the bazel
140output directory. The exact path depends on the build configuration:
141
142```
143bazel-out/k8-fastbuild/bin/compat/openssl/include/openssl/<header>.h # patched BoringSSL header
144bazel-out/k8-fastbuild/bin/compat/openssl/include/ossl/openssl/<header>.h # prefixed OpenSSL header
145bazel-out/k8-fastbuild/bin/compat/openssl/include/ossl.h # ossl struct definition
146bazel-out/k8-fastbuild/bin/compat/openssl/source/<function>.c # auto-generated mapping
147```
148
149Check the prefixed OpenSSL headers to determine:
150- Whether an `ossl_<symbol>` exists (i.e., whether `--uncomment-macro-redef` will work)
151- Whether a symbol is a macro or a real function in OpenSSL
152- What numeric value OpenSSL assigns to a constant
153
154Check the `ossl.h` struct to see which OpenSSL functions are available as function pointers
155(only real functions, not macros).
156
157## Typical workflow for fixing build errors after a dep bump
158
1591. **Read the errors.** Group them by type: undeclared functions, undeclared constants,
160 duplicate case values.
161
1622. **For each undeclared function:**
163 - Check if it exists in BoringSSL (`bazel-envoy/external/boringssl/include/openssl/`)
164 - Check if it exists in OpenSSL (`bazel-envoy/external/openssl/include/openssl/`)
165 - Add `--uncomment-func-decl` to the patch script + entry in BUILD
166 - If OpenSSL's semantics differ, write a handwritten source file
167
1683. **For each undeclared constant:**
169 - Check if it exists in both BoringSSL and OpenSSL
170 - If yes: use `--uncomment-macro-redef` in the patch script
171 - If BoringSSL-only: append a `#ifndef`/`#define` with a collision-free value
172
1734. **For duplicate case values:**
174 - Identify which constants share the same numeric value
175 - Give the BoringSSL-only constant a unique value outside both libraries' ranges
176
1775. **Build and iterate** — new symbols may trigger further missing-symbol errors as
178 more code becomes reachable.
179
@@ −1 +1 @@
1−# AGENTS.md
1+# compat/openssl — Guide for AI Agents
22
3−Instructions for AI coding agents (Claude Code, Copilot, Cursor, etc.) working in this repository.
3+Instructions for AI agents adapting the OpenSSL compatibility layer when new BoringSSL
4+symbols are needed (typically after bumping gRPC, BoringSSL, or other deps).
45
5−## Critical rules
6+See `README.md` in this directory for the full architectural background.
67
7−1. **Always sign off commits.** The human user must sign off commits via `git commit -s` — never
8− manually write a `Signed-off-by` trailer. The sign-off attests that the committer (the user)
9− has the right to submit the code under the project's license.
10−2. **Always run format and lint checks before committing.** Use `tools/local_fix_format.sh` for
11− a quick local check, or run `./ci/do_ci.sh format` inside Docker for the full CI check suite.
12− Format failures are the most common CI rejection. If running checks is impractical, warn the
13− user that formatting has not been verified.
14−3. **Never amend commits or force-push after a PR has received human review.** Always create new
15− commits to preserve review history.
16−4. **Never rebase a PR that is under review.** Use `git merge main` instead to pull in recent
17− changes. The project squash-merges, so commit count does not matter.
18−5. **Disclose AI usage.** When submitting PRs, include a note about AI assistance in the PR
19− description. The submitter must fully understand all code being submitted.
20−6. **Never commit to `main`.** Always create a new branch before committing. If switching
21− contexts or unsure which branch to use, ask the user.
22−7. **Always push to a personal fork.** Do not create branches in the main repo.
8+## Architecture in brief
239
24−## Developer workflow
10+Envoy is built against the BoringSSL API. The compat layer lets it run on OpenSSL instead.
2511
26−### 1. Before starting work
12+1. **Prefixer** (`prefixer/prefixer.cpp`) copies OpenSSL headers, adding an `ossl_` prefix
13+ to every identifier. Output lands in `include/ossl/openssl/*.h`. It also generates
14+ `source/ossl.c` (forwarding functions via dlsym) and `include/ossl.h` (the `ossl` struct
15+ with function pointers for every real OpenSSL function).
2716
28−Read `CONTRIBUTING.md` for the full contribution process. Key points:
29−- **Major features (>100 LOC or user-facing):** Open a GitHub issue first to discuss design.
30− For new extensions, read `EXTENSION_POLICY.md`.
31−- **Small patches and bug fixes:** No prior communication needed.
32−- Install git hooks: `./support/bootstrap`
17+2. **Patched BoringSSL headers** (`patch/include/openssl/*.h.sh`) start by commenting out the
18+ entire BoringSSL header, then selectively uncomment the symbols the compat layer exposes.
19+ The `uncomment.sh` tool handles this. The output is `include/openssl/*.h`.
3320
34−### 2. Writing code
21+3. **Mapping functions** (`source/*.c` or `source/*.cc`) implement each exposed BoringSSL
22+ function by calling the `ossl_`-prefixed OpenSSL equivalent.
3523
36−Read `STYLE.md` for the C++ coding style. After writing C++ code, run `clang-format` to fix
37−formatting automatically rather than trying to hand-format:
24+## Key files to modify
3825
39−```bash
40−clang-format -i <file>
41−```
26+| File | Purpose |
27+|------|---------|
28+| `patch/include/openssl/<header>.h.sh` | Controls which symbols from BoringSSL's `<header>.h` are exposed |
29+| `BUILD` | The `mapping_func_filegroup` list — every exposed function must be listed here |
30+| `source/<function>.c` or `.cc` | Handwritten mapping when auto-generation won't work |
4231
43−Tests must:
44−- Live in `test/` mirroring the `source/` structure
45−- Achieve 100% coverage for new code
46−- Use `StrictMock` by default, `SimulatedTimeSystem` for time, port 0 for network
47−- Unit tests must be hermetic and deterministic — no real time, no randomness
48−- Integration tests (in `test/integration/`) use real network on localhost
32+## How to add a missing function
4933
50−### 3. Building and testing
34+### Step 1: Uncomment the declaration
5135
52−See `bazel/README.md` for full build documentation. Common commands:
36+Add `--uncomment-func-decl <function_name>` to the appropriate `.h.sh` patch script.
5337
38+Example in `ssl.h.sh`:
5439 ```bash
55−# Docker-based (recommended — matches CI environment)
56−./ci/run_envoy_docker.sh bash # interactive shell
57−./ci/do_ci.sh debug //test/common/http/... # build + test
58−./ci/do_ci.sh debug.server_only # build binary only
59−
60−# Local (requires local dependencies)
61−bazel test -c dbg //test/common/http/... # run tests
62−bazel build --config=clang -c opt //source/exe:envoy-static # optimized binary
40+ --uncomment-func-decl SSL_get_negotiated_group \
6341 ```
6442
65−Sanitizers, coverage, GDB debugging, and profiling are resource-intensive. Do **not** run
66−them unless the user explicitly asks. See `bazel/README.md` and `bazel/PPROF.md`.
43+### Step 2: Add to the BUILD file
6744
68−### 4. Format and lint checks (required before every commit)
45+Add the function name to the `mapping_func_filegroup` list (alphabetically sorted within
46+its section).
6947
70−Format failures are the most common CI rejection. Agents should produce content that conforms
71−to the repo's style conventions for all file types (C++, BUILD, YAML, Markdown, shell, etc.).
48+### Step 3: Decide if a handwritten source file is needed
7249
73−**Quick local check (recommended):**
50+The build system (`bazel/rules.bzl`) auto-generates a forwarding function if no handwritten
51+`source/<function>.c` or `.cc` exists. The generated code handles both cases — OpenSSL
52+macros and real functions — using an `#ifdef`:
7453
75−```bash
76−tools/local_fix_format.sh # uncommitted changes (default)
77−tools/local_fix_format.sh -main # changes since main
78−tools/local_fix_format.sh -all # entire repo
54+```c
55+// Auto-generated pattern:
56+ReturnType FunctionName(args) {
57+#ifdef ossl_FunctionName
58+ return ossl_FunctionName(args); // macro path (expands inline)
59+#else
60+ return ossl.ossl_FunctionName(args); // function pointer path (via dlsym)
61+#endif
62+}
7963 ```
8064
81−**Individual checks:**
65+**You need a handwritten source when:**
66+- The BoringSSL and OpenSSL signatures differ (different arg types, arg count)
67+- The semantics differ (e.g., `SSL_CTX_set1_curves_list` has an OpenSSL 3.5 bug workaround)
68+- The function has no OpenSSL equivalent at all (must be implemented from scratch)
8269
83−```bash
84−bazel run //tools/code_format:check_format -- fix # C++, BUILD, .bzl, .proto
85−bazel run //tools/spelling:check_spelling_pedantic -- fix # spelling
86−./ci/do_ci.sh format # full CI check (inside Docker)
87−```
70+**You can rely on auto-generation when:**
71+- The function exists in OpenSSL with the same signature (as a real function or macro)
72+- No semantic differences need patching
8873
89−**Linter config files — read these to produce compliant output without running the tools:**
74+## How to add a missing constant or macro
9075
91−| Config file | What it configures |
92−|-------------|--------------------|
93−| `.clang-format` | C++/Proto formatting (100-col, include order, pointer alignment) |
94−| `.yamllint` | YAML rules (140-col max, consistent indentation) |
95−| `.flake8` | Python lint rules |
96−| `rustfmt.toml` | Rust formatting (100-col, 2-space indent) |
97−| `tools/spelling/spelling_dictionary.txt` | Custom word list (1700+ project terms) |
76+### Constant exists in both BoringSSL and OpenSSL
9877
99−### 5. Creating the commit
78+Add `--uncomment-macro-redef '<pattern>'` to the `.h.sh` patch script. This generates:
10079
101−Before your first commit in a session:
80+```c
81+#ifdef ossl_CONSTANT_NAME
82+#define CONSTANT_NAME ossl_CONSTANT_NAME
83+#endif
84+```
10285
103−1. Check if the local `main` is up to date with `origin/main`:
104− ```bash
105− git fetch origin
106− git log main..origin/main --oneline
107− ```
108−2. If `main` is behind, sync it:
109− ```bash
110− git checkout main && git pull && git checkout -
111− ```
112−3. Create a new branch off the updated `main`:
113− ```bash
114− git checkout -b <descriptive-branch-name>
115− ```
116−4. If you had uncommitted changes that conflict with the updated `main`, ask the user whether
117− to proceed on the outdated base or resolve conflicts against the new `main`.
118−
119−If you're switching contexts or unsure which branch to commit to, ask the user before committing.
120−
86+The constant gets OpenSSL's value. Use regex patterns to cover families:
12187 ```bash
122−git add <files>
123−git commit -s # -s adds Signed-off-by automatically; NEVER write it manually
88+ --uncomment-macro-redef 'SSL_R_[[:alnum:]_]*' \
89+ --uncomment-macro-redef 'OPENSSL_INIT_[[:alnum:]_]*' \
12490 ```
12591
126−### 6. Pushing and creating a PR
92+### Constant exists only in BoringSSL (no OpenSSL equivalent)
12793
128−**PR title format** — lower-case subsystem prefix followed by a colon:
129−`docs: fix grammar error`, `router: add x-envoy-overloaded header`
94+The `--uncomment-macro-redef` approach won't work because there's no `ossl_` version — the
95+`#ifdef` guard will be false and the constant stays undefined.
13096
131−**PR description template** — every PR must fill in:
97+Instead, append a standalone `#ifndef`/`#define` block at the end of the `.h.sh` script:
13298
99+```bash
100+cat >> "$1" <<'EOF'
101+
102+#ifndef SSL_R_SOME_BORINGSSL_ONLY_CONSTANT
103+#define SSL_R_SOME_BORINGSSL_ONLY_CONSTANT <value>
104+#endif
105+EOF
133106 ```
134−Commit Message: <what this PR does — used as the final squash-merge message>
135−Additional Description: <context useful to reviewers>
136−Risk Level: Low | Medium | High
137−Testing: <what testing was done>
138−Docs Changes: <description or N/A>
139−Release Notes: <description or N/A>
140−```
141107
142−See `PULL_REQUESTS.md` for full field descriptions and optional fields (runtime guard,
143−deprecation, platform-specific features).
108+**Choosing values:** BoringSSL and OpenSSL often use the same numeric range for different
109+constants. For example, BoringSSL's `SSL_R_NO_CIPHERS_PASSED = 176` collides with OpenSSL's
110+`SSL_R_NO_CERTIFICATES_RETURNED = 176`. If both appear in the same switch statement,
111+you get a duplicate-case error. To avoid this, use values in a range that neither library
112+uses (e.g., 10000+ for `SSL_R_*` constants). The exact values don't matter at runtime
113+since OpenSSL will never produce these BoringSSL-specific error codes.
144114
145−**Release notes:** User-facing changes **must** add a release note fragment under
146−`changelogs/current/`. Name the file `<area>__<short-description>.rst`.
115+### Constant with duplicate-case-value problem
147116
148−### 7. Waiting for CI and review
117+If a constant must exist but its value collides with another constant's value (e.g.,
118+`ERR_R_OVERFLOW` aliased to `ERR_R_INTERNAL_ERROR`), give it a unique value. Check
119+OpenSSL's range for the constant family in `bazel-envoy/external/openssl/include/openssl/`
120+and pick a value above the highest used one.
149121
150−- Do **not** create draft PRs if you want prompt reviews — draft PRs are not triaged.
151−- To re-run failed CI tasks, add a `/retest` comment on the PR.
152−- PRs with no activity for 14+ days may be closed.
122+## uncomment.sh — common options
153123
154−### 8. Addressing review comments
124+| Option | Effect |
125+|--------|--------|
126+| `--uncomment-func-decl <name>` | Uncomment a function declaration |
127+| `--uncomment-macro '<pattern>'` | Uncomment a `#define` (keeps BoringSSL's value) |
128+| `--uncomment-macro-redef '<pattern>'` | Redefine macro to use OpenSSL's value via `ossl_` prefix |
129+| `--uncomment-enum <name>` | Uncomment an enum definition |
130+| `--uncomment-struct <name>` | Uncomment a struct definition |
131+| `--uncomment-typedef <name>` | Uncomment a typedef |
132+| `--uncomment-typedef-redef <name>` | Redefine a typedef to use OpenSSL's type |
133+| `--uncomment-regex '<pattern>'` | Uncomment lines matching a regex |
134+| `--uncomment-regex-range '<start>' '<end>'` | Uncomment a multi-line block |
135+| `--sed '<expression>'` | Run an arbitrary sed expression on the file |
155136
156−- **Never amend or force-push** after a reviewer has looked at the PR. Create new commits.
157−- **Never rebase.** If you need to incorporate upstream changes:
158− ```bash
159− git fetch origin main && git merge origin/main
160− ```
161−- If the reviewer asked for a runtime guard, add one (see `CONTRIBUTING.md`).
137+## Inspecting generated output
162138
163−### 9. After merge
139+To see what the compat layer actually produces after patching/prefixing, look in the bazel
140+output directory. The exact path depends on the build configuration:
164141
165−The project squash-merges PRs. The "Commit Message" field in your PR description becomes the
166−final commit message. Make sure it's up to date before merge.
167−
168−## Understanding CI
169−
170−Envoy uses a checks-based CI system. Results appear as **GitHub Check Runs** on PRs, not as
171−simple workflow pass/fail statuses.
172−
173−**CI pipeline:**
174−
175−1. **`Envoy/Prechecks`** — fast checks: format/lint/spelling, dependency validation, docs build
176−2. **`Envoy/Checks`** — heavier checks: compilation, tests, coverage, sanitizers
177−
178−**Checking CI status:**
179−
180−```bash
181−gh pr checks <PR-number>
182−gh run view <run-id> --log-failed
183142 ```
143+bazel-out/k8-fastbuild/bin/compat/openssl/include/openssl/<header>.h # patched BoringSSL header
144+bazel-out/k8-fastbuild/bin/compat/openssl/include/ossl/openssl/<header>.h # prefixed OpenSSL header
145+bazel-out/k8-fastbuild/bin/compat/openssl/include/ossl.h # ossl struct definition
146+bazel-out/k8-fastbuild/bin/compat/openssl/source/<function>.c # auto-generated mapping
147+```
184148
185−When CI fails, check the failed check run name to determine which `do_ci.sh` target to
186−reproduce locally. Format failures come from `Envoy/Prechecks`; build/test failures come
187−from `Envoy/Checks`.
149+Check the prefixed OpenSSL headers to determine:
150+- Whether an `ossl_<symbol>` exists (i.e., whether `--uncomment-macro-redef` will work)
151+- Whether a symbol is a macro or a real function in OpenSSL
152+- What numeric value OpenSSL assigns to a constant
188153
189−## Inclusive language
154+Check the `ossl.h` struct to see which OpenSSL functions are available as function pointers
155+(only real functions, not macros).
190156
191−The following terms are **not allowed**:
192−- ~~whitelist~~ -> allowlist
193−- ~~blacklist~~ -> denylist / blocklist
194−- ~~master~~ -> primary / main
195−- ~~slave~~ -> secondary / replica
157+## Typical workflow for fixing build errors after a dep bump
196158
197−## BUILD file conventions
159+1. **Read the errors.** Group them by type: undeclared functions, undeclared constants,
160+ duplicate case values.
198161
199−See `bazel/DEVELOPER.md` for full BUILD file rules. Key points:
200−- Use `envoy_cc_library`, `envoy_cc_test`, `envoy_cc_mock` (not raw `cc_library`)
201−- Target suffixes: `_lib`, `_test`, `_mocks`, `_interface`
202−- Every `#include` must have a corresponding `deps` entry
162+2. **For each undeclared function:**
163+ - Check if it exists in BoringSSL (`bazel-envoy/external/boringssl/include/openssl/`)
164+ - Check if it exists in OpenSSL (`bazel-envoy/external/openssl/include/openssl/`)
165+ - Add `--uncomment-func-decl` to the patch script + entry in BUILD
166+ - If OpenSSL's semantics differ, write a handwritten source file
203167
204−## Updating dependencies
168+3. **For each undeclared constant:**
169+ - Check if it exists in both BoringSSL and OpenSSL
170+ - If yes: use `--uncomment-macro-redef` in the patch script
171+ - If BoringSSL-only: append a `#ifndef`/`#define` with a collision-free value
205172
206−See `bazel/EXTERNAL_DEPS.md` and `DEPENDENCY_POLICY.md`. When updating a version:
207−1. Update version, sha256, and urls in `bazel/repository_locations.bzl`
208−2. Update `release_date` in `bazel/deps.yaml` to the UTC date of the new release
209−3. Prefer maintainer-provided tarballs over GitHub auto-generated ones
173+4. **For duplicate case values:**
174+ - Identify which constants share the same numeric value
175+ - Give the BoringSSL-only constant a unique value outside both libraries' ranges
210176
211−## CI and GitHub Actions (for workflow file authors)
212−
213−- In `if:` conditions, do **not** wrap expressions in `${{ }}` — the `if` field evaluates
214− expressions implicitly. Use `${{ }}` only in string contexts (`run:`, `with:`, `env:`).
215−- Workflow files in `.github/workflows/` are shared across all branches (main and stable release
216− branches). Do not remove variables or inputs still referenced by stable branches.
217−
218−## Key files
219−
220−| File | Purpose |
221−|------|---------|
222−| `STYLE.md` | C++ coding style and error handling |
223−| `CONTRIBUTING.md` | Contribution guidelines, deprecation, breaking changes |
224−| `PULL_REQUESTS.md` | PR field descriptions |
225−| `EXTENSION_POLICY.md` | Extension lifecycle and requirements |
226−| `DEPENDENCY_POLICY.md` | External dependency rules |
227−| `RELEASES.md` | Release schedule and backport process |
228−| `SECURITY.md` | Security reporting and disclosure |
229−| `REPO_LAYOUT.md` | Repository structure |
230−| `bazel/README.md` | Building, testing, sanitizers, coverage |
231−| `bazel/DEVELOPER.md` | BUILD file conventions |
232−| `bazel/EXTERNAL_DEPS.md` | Managing external dependencies |
233−| `bazel/PPROF.md` | Performance profiling |
234−| `source/extensions/extensions_metadata.yaml` | Extension status and security posture |
235−| `source/common/runtime/runtime_features.cc` | Runtime feature flag defaults |
177+5. **Build and iterate** — new symbols may trigger further missing-symbol errors as
178+ more code becomes reachable.
236179
