Palimpsests

Projects that follow the best practices below can voluntarily self-certify and show that they've achieved an Open Source Security Foundation (OpenSSF) best practices badge.

There is no set of practices that can guarantee that software will never have defects or vulnerabilities; even formal methods can fail if the specifications or assumptions are wrong. Nor is there any set of practices that can guarantee that a project will sustain a healthy and well-functioning development community. However, following best practices can help improve the results of projects. For example, some practices enable multi-person review before release, which can both help find otherwise hard-to-find technical vulnerabilities and help build trust and a desire for repeated interaction among developers from different companies. To earn a badge, all MUST and MUST NOT criteria must be met, all SHOULD criteria must be met OR be unmet with justification, and all SUGGESTED criteria must be met OR unmet (we want them considered at least). If you want to enter justification text as a generic comment, instead of being a rationale that the situation is acceptable, start the text block with '//' followed by a space. Feedback is welcome via the GitHub site as issues or pull requests There is also a mailing list for general discussion.

We gladly provide the information in several locales, however, if there is any conflict or inconsistency between the translations, the English version is the authoritative version.
If this is your project, please show your badge status on your project page! The badge status looks like this: Badge level for project 13534 is gold Here is how to embed it:
You can show your badge status by embedding this in your markdown file:
[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/13534/badge)](https://www.bestpractices.dev/projects/13534)
or by embedding this in your HTML:
<a href="https://www.bestpractices.dev/projects/13534"><img src="https://www.bestpractices.dev/projects/13534/badge"></a>


These are the Gold level criteria. You can also view the Passing or Silver level criteria.

Baseline Series: Baseline Level 1 Baseline Level 2 Baseline Level 3

        

 Basics 5/5

  • General

    Note that other projects may use the same name.

    Layered local-LLM inference engine for agentic workloads: Ollama and llama.cpp behind one abstraction, context-memory (sink/window/evict + block retrieval), encrypted audit log. Native L3 serving layer in progress.

    Please use SPDX license expression format; examples include "Apache-2.0", "BSD-2-Clause", "BSD-3-Clause", "GPL-2.0+", "LGPL-3.0+", "MIT", and "(BSD-2-Clause OR Ruby)". Do not include single quotes or double quotes.
    If there is more than one language, list them as comma-separated values (spaces optional) and sort them from most to least used. If there is a long list, please list at least the first three most common ones. If there is no language (e.g., this is a documentation-only or test-only project), use the single character "-". Please use a conventional capitalization for each language, e.g., "JavaScript".
    The Common Platform Enumeration (CPE) is a structured naming scheme for information technology systems, software, and packages. It is used in a number of systems and databases when reporting vulnerabilities.
  • Prerequisites


    The project MUST achieve a silver level badge. [achieve_silver]

  • Project oversight


    The project MUST have a "bus factor" of 2 or more. (URL required) [bus_factor]
    A "bus factor" (aka "truck factor") is the minimum number of project members that have to suddenly disappear from a project ("hit by a bus") before the project stalls due to lack of knowledgeable or competent personnel. The truck-factor tool can estimate this for projects on GitHub. For more information, see Assessing the Bus Factor of Git Repositories by Cosentino et al.

    The project's bus factor is 2. Two people are significant contributors, each able to keep the project going on their own: the maintainer (@andreysparish) and the co-maintainer (@olksandrvertel-arch). Both hold repository-admin rights and can independently review, merge, and release; the co-maintainer has 35+ commits, including the hardware-isolation test suite and the role of independent PALA-1 verifier. Losing either one would not halt the project. Roles and the split of work are documented in docs/GOVERNANCE.md, and the contribution history is visible in the repository.
    URL (required) — the contributors graph is the most direct evidence of a bus factor ≥ 2:
    https://github.com/Assault-Consulting/Palimpsests/graphs/contributors



    The project MUST have at least two unassociated significant contributors. (URL required) [contributors_unassociated]
    Contributors are associated if they are paid to work by the same organization (as an employee or contractor) and the organization stands to benefit from the project's results. Financial grants do not count as being from the same organization if they pass through other organizations (e.g., science grants paid to different organizations from a common government or NGO source do not cause contributors to be associated). Someone is a significant contributor if they have made non-trivial contributions to the project in the past year. Examples of good indicators of a significant contributor are: written at least 1,000 lines of code, contributed 50 commits, or contributed at least 20 pages of documentation.

    Unassociated significant contributors in the past year: (1) Oleksii Turak, independent developer, no relationship with Assault Consulting — author of the fifth independent PALA-1 verification: a from-spec Perl 5 verifier with a hand-rolled NIST-validated AES-GCM implementation, ~2,300 lines (verifier + methodology + run record), merged 2026-08-18 (docs/specs/pala-1/independent-runs/turak/); (2) Sharyar Naseem, independent — the fourth independent verification run and a merged feature contribution (export seq-range bounds, PR #135, 2026-08-14). The two contributors are not associated with each other or with Assault Consulting; neither is paid by Assault Consulting. Andrii Sparysh and Oleksandr Verteletskyi (Assault Consulting) are counted as one associated group and excluded. Evidence: https://github.com/Assault-Consulting/Palimpsests/graphs/contributors


  • Other


    The project MUST include a license statement in each source file. This MAY be done by including the following inside a comment near the beginning of each file: SPDX-License-Identifier: [SPDX license expression for project]. [license_per_file]
    This MAY also be done by including a statement in natural language identifying the license. The project MAY also include a stable URL pointing to the license text, or the full license text. Note that the criterion license_location requires the project license be in a standard location. See this SPDX tutorial for more information about SPDX license expressions. Note the relationship with copyright_per_file, whose content would typically precede the license information.

    Every file in the Palimpsests repository has an explicit SPDX license statement. Most source files include an inline # SPDX-License-Identifier: [expression] comment near the top of the file; the remaining files are covered by a catch-all annotation in REUSE.toml (path = "**"). The project uses two licenses, each declared per file with the correct SPDX expression: the main codebase is Apache-2.0, while the PALA-1 specification and its reference implementations are dedicated to the public domain as CC0-1.0 (so a third party can implement the format without being bound by Apache terms). The repository is compliant with version 3.3 of the REUSE Specification: reuse lint reports 206/206 files with license information. The full license texts are stored in the standard location under LICENSES/ (Apache-2.0.txt and CC0-1.0.txt), and the conventional LICENSE file remains at the repository root.


 Change Control 4/4

  • Public version-controlled source repository


    The project's source repository MUST use a common distributed version control software (e.g., git or mercurial). [repo_distributed]
    Git is not specifically required and projects can use centralized version control software (such as subversion) with justification.

    Repository on GitHub, which uses git. git is distributed.



    The project MUST clearly identify small tasks that can be performed by new or casual contributors. (URL required) [small_tasks]
    This identification is typically done by marking selected issues in an issue tracker with one or more tags the project uses for the purpose, e.g., up-for-grabs, first-timers-only, "Small fix", microtask, or IdealFirstBug. These new tasks need not involve adding functionality; they can be improving documentation, adding test cases, or anything else that aids the project and helps the contributor understand more about the project.

    The project maintains a good first issue label that marks starter tasks suitable for new or casual contributors — small, self-contained work such as documentation fixes, CLI polish, and additional test cases (the label and its initial set of tasks were curated on 2026-08-14). These tasks do not require adding core functionality, so they can be picked up by contributors who are not yet familiar with the codebase. They are discoverable as a filtered list of open issues carrying the label (see URL).
    met_url:
    https://github.com/Assault-Consulting/Palimpsests/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22



    The project MUST require two-factor authentication (2FA) for developers for changing a central repository or accessing sensitive data (such as private vulnerability reports). This 2FA mechanism MAY use mechanisms without cryptographic mechanisms such as SMS, though that is not recommended. [require_2FA]

    GitHub requires 2FA as of March 2023. [osps_ac_01_01]



    The project's two-factor authentication (2FA) SHOULD use cryptographic mechanisms to prevent impersonation. Short Message Service (SMS) based 2FA, by itself, does NOT meet this criterion, since it is not encrypted. [secure_2FA]
    A 2FA mechanism that meets this criterion would be a Time-based One-Time Password (TOTP) application that automatically generates an authentication code that changes after a certain period of time. Note that GitHub supports TOTP.

    Two-factor authentication for the project's maintainers is provided by a Time-based One-Time Password (TOTP) authenticator application, not SMS. TOTP is a cryptographic mechanism — an HMAC-based one-time code derived from a shared secret and the current time — so it does not carry the impersonation risk of unencrypted SMS-based 2FA. All maintainers with write/admin access to the central GitHub repository authenticate with app-based TOTP (and/or hardware security keys); none rely on SMS.


 Quality 7/7

  • Coding standards


    The project MUST document its code review requirements, including how code review is conducted, what must be checked, and what is required to be acceptable. (URL required) [code_review_standards]
    See also two_person_review and contribution_requirements.

    Code review requirements are documented in docs/REVIEW.md, with the contributor workflow in CONTRIBUTING.md and merge authority in GOVERNANCE.md. The document covers all three required elements. How review is conducted: every change — code and documentation — lands through a pull request that a non-author must approve before merge; main is branch-protected, so required green checks plus one non-author approval are enforced, not merely requested. What must be checked: the reviewer confirms that tests ship with behavior and that coverage stays above the gate (statement ≥ 90%, branch ≥ 80%), that ruff lint is clean, that any new dependency is justified, that security-sensitive paths (audit chain, key management, the crypto boundary, untrusted-input deserialization, the capability boundary) receive extra scrutiny against SECURITY.md / THREAT_MODEL.md / ASSURANCE-CASE.md, that public API/CLI and wire-format changes are deliberate and respect the format freeze, and that documentation matches the change; changes affecting released artifacts additionally require byte-verification and a green reproducible-build job. What is acceptable: approval means the reviewer believes the change is correct, tested, within the project's security and design boundaries, and free of known issues that would argue against inclusion — a reviewer who is unsure asks rather than approves, and author confidence alone is not grounds to merge.
    met_url:
    https://github.com/Assault-Consulting/Palimpsests/blob/main/docs/REVIEW.md



    The project MUST have at least 50% of all proposed modifications reviewed before release by a person other than the author, to determine if it is a worthwhile modification and free of known issues which would argue against its inclusion [two_person_review]

    Every proposed modification to Palimpsests is reviewed by a non-author before release, which far exceeds the 50% threshold. main is branch-protected: direct pushes are blocked, and every change — code and documentation alike — must go through a pull request that receives at least one approval from a person other than the author, plus a green required status check (ci-complete: lint, tests, and coverage across macOS/Linux/Windows), before it can be merged. These protections have been enforced since 2026-07-11 (documented in GOVERNANCE.md), which is the measurement anchor for the review-coverage figure: every merge from that date forward is non-author reviewed, so the reviewed fraction is effectively 100% and monotonically rising. The requirement is documented in GOVERNANCE.md and CONTRIBUTING.md.


  • Working build system


    The project MUST have a reproducible build. If no building occurs (e.g., scripting languages where the source code is used directly instead of being compiled), select "not applicable" (N/A). (URL required) [build_reproducible]
    A reproducible build means that multiple parties can independently redo the process of generating information from source files and get exactly the same bit-for-bit result. In some cases, this can be resolved by forcing some sort order. JavaScript developers may consider using npm shrinkwrap and webpack OccurrenceOrderPlugin. GCC and clang users may find the -frandom-seed option useful. The build environment (including the toolset) can often be defined for external parties by specifying the cryptographic hash of a specific container or virtual machine that they can use for rebuilding. The reproducible builds project has documentation on how to do this.

    Palimpsests has a reproducible build, so this is Met rather than N/A: the project publishes distribution artifacts, and both the sdist (.tar.gz) and the wheel (.whl) are bit-for-bit reproducible — building the same commit produces identical bytes. Determinism is achieved by building with hatchling via PEP 517 (fixed archive-member order, no wall-clock build time stamped into output), pinning SOURCE_DATE_EPOCH to the commit date, and fixing LC_ALL=C.UTF-8, TZ=UTC, and umask 0022. This is enforced on every push and pull request by the reproducible-build job in .github/workflows/ci.yml, which runs scripts/check_reproducible_build.sh to build the artifacts twice and fail if they differ; the job is a required check in the ci-complete gate. The release workflow builds published artifacts with the same pinned SOURCE_DATE_EPOCH/locale/umask, so released files are the reproducible ones. A step-by-step reproduction recipe is documented (docs/REPRODUCIBLE-BUILD.md) so any third party can independently rebuild a release and verify it by hash. Reproducibility covers the Python distribution artifacts; the optional native (llama.cpp) path links against a separately installed C library and is out of scope.
    https://github.com/Assault-Consulting/Palimpsests/blob/main/docs/REPRODUCIBLE-BUILD.md


  • Automated test suite


    A test suite MUST be invocable in a standard way for that language. (URL required) [test_invocation]
    For example, "make check", "mvn test", or "rake test" (Ruby).

    The test suite is invoked in the standard way for Python: python -m pytest (equivalently pytest) from the repository root, with pytest configured in the standard [tool.pytest.ini_options] section of pyproject.toml. This is the conventional Python test invocation, documented in CONTRIBUTING.md and used unchanged by the CI workflow. URL: https://github.com/Assault-Consulting/Palimpsests/blob/main/pyproject.toml



    The project MUST implement continuous integration, where new or changed code is frequently integrated into a central code repository and automated tests are run on the result. (URL required) [test_continuous_integration]
    In most cases this means that each developer who works full-time on the project integrates at least daily.

    The project uses continuous integration. On every push to main and every pull request, GitHub Actions runs the automated test suite (pytest) and the linter (ruff) across a matrix of three operating systems (Linux, macOS, Windows) and two Python versions (3.11, 3.12). New and changed code is integrated into main frequently via pull requests, with the tests run automatically on each. Branch protection requires the checks to pass before merge. URL: https://github.com/Assault-Consulting/Palimpsests/blob/main/.github/workflows/ci.yml



    The project MUST have FLOSS automated test suite(s) that provide at least 90% statement coverage if there is at least one FLOSS tool that can measure this criterion in the selected language. [test_statement_coverage90]

    A FLOSS coverage tool exists for the selected language (coverage.py, run via pytest-cov), so N/A does not apply and the project meets the bar directly. The automated pytest suite achieves 90.3% statement coverage measured over the whole src/palimpsests package; only if TYPE_CHECKING: blocks and raise NotImplementedError lines are excluded, per the standard coverage convention. The single module that reads low — the in-process ctypes backend llamacpp_backend.py, which can only run with the optional [native] extra against a real GGUF model on GPU hardware and therefore cannot be exercised in CI — is counted, not omitted: the overall figure clears 90% with it included, and that backend is validated separately on hardware (benchmarks/RUNBOOK.md). Coverage is computed on every push and pull request (pytest --cov --cov-report=json) and enforced by scripts/coverage_gate.py, which fails the build below 90% statement (and 80% branch). The coverage job is a required check in the ci-complete gate, so coverage cannot silently regress below the bar.



    The project MUST have FLOSS automated test suite(s) that provide at least 80% branch coverage if there is at least one FLOSS tool that can measure this criterion in the selected language. [test_branch_coverage80]

    A FLOSS coverage tool exists for the selected language (coverage.py, run via pytest-cov with branch coverage enabled), so N/A does not apply and the project meets the bar directly. The automated pytest suite achieves 82.4% branch coverage measured over the whole src/palimpsests package, with branch = true set in the coverage configuration; only if TYPE_CHECKING: blocks and raise NotImplementedError lines are excluded, per the standard convention. The hardware-only in-process ctypes backend llamacpp_backend.py — runnable only with the optional [native] extra against a real GGUF model on GPU hardware, so not exercisable in CI — is counted, not omitted: the overall figure clears 80% with it included, and that backend is validated separately on hardware (benchmarks/RUNBOOK.md). Branch coverage is computed on every push and pull request and enforced together with statement coverage by scripts/coverage_gate.py, which fails the build below 80% branch (and 90% statement). The coverage job is a required check in the ci-complete gate, so branch coverage cannot silently regress below the bar.


 Security 5/5

  • Use basic good cryptographic practices

    Note that some software does not need to use cryptographic mechanisms. If your project produces software that (1) includes, activates, or enables encryption functionality, and (2) might be released from the United States (US) to outside the US or to a non-US-citizen, you may be legally required to take a few extra steps. Typically this just involves sending an email. For more information, see the encryption section of Understanding Open Source Technology & US Export Controls.

    The software produced by the project MUST support secure protocols for all of its network communications, such as SSHv2 or later, TLS1.2 or later (HTTPS), IPsec, SFTP, and SNMPv3. Insecure protocols such as FTP, HTTP, telnet, SSLv3 or earlier, and SSHv1 MUST be disabled by default, and only enabled if the user specifically configures it. If the software produced by the project does not support network communications, select "not applicable" (N/A). [crypto_used_network]

    Where the software makes network communication, it uses secure protocols only. Outbound network access (e.g. talking to model/back-end endpoints and to release/publishing infrastructure) goes through httpx over HTTPS/TLS — TLS 1.2+ as negotiated by the platform's TLS stack — and release publishing uses HTTPS with OIDC Trusted Publishing and Sigstore. The project does not implement or default to any insecure protocol (no plain HTTP fetch-and-trust, no FTP/telnet/SSLv3/SSHv1); an insecure transport is not enabled anywhere by default. The core product is a local-first, on-device inference engine, so most operation involves no network at all, and what network communication exists is over TLS.



    The software produced by the project MUST, if it supports or uses TLS, support at least TLS version 1.2. Note that the predecessor of TLS was called SSL. If the software does not use TLS, select "not applicable" (N/A). [crypto_tls12]

    The software uses TLS and supports TLS 1.2 or later. All HTTPS communication goes through httpx, which uses Python's standard TLS stack (OpenSSL via the ssl module); on the supported Python versions (3.11+) that stack negotiates TLS 1.2 and 1.3 and treats older SSL/TLS versions as disabled by default. The project does not force, pin, or fall back to any pre-1.2 protocol (no SSLv3/TLS 1.0/1.1), so TLS 1.2+ is the effective floor for every TLS connection it makes.


  • Secured delivery against man-in-the-middle (MITM) attacks


    The project website, repository (if accessible via the web), and download site (if separate) MUST include key hardening headers with nonpermissive values. (URL required) [hardened_site]
    Note that GitHub and GitLab are known to meet this. Sites such as https://securityheaders.com/ can quickly check this. The key hardening headers are: Content Security Policy (CSP), HTTP Strict Transport Security (HSTS), X-Content-Type-Options (as "nosniff"), and X-Frame-Options. Fully static web sites with no ability to log in via the web pages could omit some hardening headers with less risk, but there's no reliable way to detect such sites, so we require these headers even if they are fully static sites.

    The project website (https://palimpsests.dev) returns the four key hardening headers with nonpermissive values on every response, configured in site/vercel.json. Content-Security-Policy: default-src 'self' with object-src 'none', frame-ancestors 'none', base-uri 'self', and upgrade-insecure-requests. Strict-Transport-Security: max-age=63072000; includeSubDomains; preload (two years). X-Content-Type-Options: nosniff. X-Frame-Options: DENY. It additionally sets Referrer-Policy and a restrictive Permissions-Policy. An external scan (securityheaders.com, 2026-08-14) grades the site A, with all key headers present; the only item below A+ is 'unsafe-inline' in script-src/style-src, tracked as a site improvement. The source repository and the download site are hosted on GitHub (and the package is published to PyPI), which are known to meet this criterion.


  • Other security issues


    The project MUST have performed a security review within the last 5 years. This review MUST consider the security requirements and security boundary. [security_review]
    This MAY be done by the project members and/or an independent evaluation. This evaluation MAY be supported by static and dynamic analysis tools, but there also must be human review to identify problems (particularly in design) that tools cannot detect.

    The project performed an internal security review in July 2026 — within the last 5 years — documented in docs/security/AUDIT-2026-07.md. It was a human review (manual examination of the audit subsystem, key management, process lifecycle, native backend, KV store, context memory, and CLI), supported by Bandit SAST and dependency/workflow review, covering the full source tree at a pinned commit plus the CI workflows and the published PyPI artifact. The review explicitly considered both the security requirements and the security boundary: the assets and properties to protect, the trust boundaries (the filesystem and the Python→C hand-off), and attacker capabilities are documented in docs/THREAT_MODEL.md, and the audit assessed the design against them — including validating the project's stated "honest boundary" (what the tamper-evident anchor does and does not guarantee; e.g., an attacker holding both the key and keychain-write access is explicitly out of scope). The review produced concrete findings (H1–H2, M1–M4, L1–L3) with severity and remediation status; most were fixed in PR #47, and the remaining items are tracked as explicit, boundary-scoped decisions.



    Hardening mechanisms MUST be used in the software produced by the project so that software defects are less likely to result in security vulnerabilities. (URL required) [hardening]
    Hardening mechanisms may include HTTP headers like Content Security Policy (CSP), compiler flags to mitigate attacks (such as -fstack-protector), or compiler flags to eliminate undefined behavior. For our purposes least privilege is not considered a hardening mechanism (least privilege is important, but separate).

    The software uses hardening mechanisms so that a defect is less likely to become a security vulnerability. The primary mechanism is language choice: all code the project produces is written in a memory-safe language (Python), eliminating whole classes of defect-to-vulnerability paths (buffer overflows, use-after-free). The single memory-unsafe boundary — the third-party llama.cpp C library — is isolated behind an optional [native] extra, and the untrusted-input surface in front of it (the KV-state validator guarding load_state) is coverage-guided fuzzed with Atheris, so malformed input is rejected before any byte reaches C. Additional mechanisms: SQL is parameterized throughout (no injection); there is no unsafe deserialization (pickle/eval/shell=True are absent); cryptographic keys come from a CSPRNG (secrets.token_bytes); the at-rest audit store is encrypted (SQLCipher/AES-256) with the key held in the OS keychain, and the design fails closed — it refuses to open rather than fall back to plaintext if SQLCipher is unavailable; the audit chain's canonical serialization is length-prefixed so field boundaries cannot be forged; provider exception text is clipped before it enters the log to prevent secret leakage; and the CI/release pipeline runs with least-privilege permissions, SHA-pinned actions, and OIDC-scoped publishing. These mechanisms, and the security argument for them, are documented in docs/ASSURANCE-CASE.md, with the asset-to-mechanism mapping in docs/THREAT_MODEL.md. As a local-first library with no network service of its own, HTTP transport-hardening headers do not apply to the software itself; the project website's hardening headers are covered separately under hardened_site.
    https://github.com/Assault-Consulting/Palimpsests/blob/main/docs/ASSURANCE-CASE.md


 Analysis 2/2

  • Dynamic code analysis


    The project MUST apply at least one dynamic analysis tool to any proposed major production release of the software produced by the project before its release. [dynamic_analysis]
    A dynamic analysis tool examines the software by executing it with specific inputs. For example, the project MAY use a fuzzing tool (e.g., American Fuzzy Lop) or a web application scanner (e.g., OWASP ZAP or w3af). In some cases the OSS-Fuzz project may be willing to apply fuzz testing to your project. For purposes of this criterion the dynamic analysis tool needs to vary the inputs in some way to look for various kinds of problems or be an automated test suite with at least 80% branch coverage. The Wikipedia page on dynamic analysis and the OWASP page on fuzzing identify some dynamic analysis tools. The analysis tool(s) MAY be focused on looking for security vulnerabilities, but this is not required.

    The project applies a dynamic analysis tool — Atheris, the Python binding for libFuzzer — as coverage-guided fuzzing. The harness (fuzz/fuzz_state_blob.py) targets the security-critical untrusted-input boundary: NativeSession.load_state, the pure-Python frame parser standing between arbitrary bytes and the C KV-state deserializer (llama_state_seq_set_data). It enforces the invariant that a malformed blob is rejected in Python (raising StateBlobError, with the backend never called) and never reaches C; any other outcome is a finding. Fuzzing runs in .github/workflows/fuzz.yml: a short deterministic regression pass on every push and pull request to main (so a previously found crash cannot silently return), plus a longer time-budgeted run nightly and on demand. Because every change to main is fuzzed and releases are cut from main, at least one dynamic analysis tool has been applied to the code before each release. Assertions are enabled during the run (the harness executes under CPython without -O). The one memory-unsafe component — the third-party llama.cpp C library — is outside the project's own code; the harness deliberately fuzzes the project's guard in front of it. (Independently, the project's automated test suite also exceeds 80% branch coverage, which on its own satisfies this criterion.)
    https://github.com/Assault-Consulting/Palimpsests/blob/main/fuzz/README.md



    The project SHOULD include many run-time assertions in the software it produces and check those assertions during dynamic analysis. [dynamic_analysis_enable_assertions]
    This criterion does not suggest enabling assertions during production; that is entirely up to the project and its users to decide. This criterion's focus is instead to improve fault detection during dynamic analysis before deployment. Enabling assertions in production use is completely different from enabling assertions during dynamic analysis (such as testing). In some cases enabling assertions in production use is extremely unwise (especially in high-integrity components). There are many arguments against enabling assertions in production, e.g., libraries should not crash callers, their presence may cause rejection by app stores, and/or activating an assertion in production may expose private data such as private keys. Beware that in many Linux distributions NDEBUG is not defined, so C/C++ assert() will by default be enabled for production in those environments. It may be important to use a different assertion mechanism or defining NDEBUG for production in those environments.

    The project deliberately enforces validation and invariants with explicit exceptions (raise, ~113 across the codebase) rather than assert, because assert is stripped under -O and must not be relied on for checks that need to always execute. These checks run unconditionally, including during fuzzing. The project does not add a large number of dedicated assert-style assertions solely for dynamic analysis, so this SHOULD is not claimed as met.



You can use tools and AI systems to propose changes via a simple URL, such as https://www.bestpractices.dev/en/projects/13534/choose/edit?osps_ac_01_01_status=Met&osps_ac_01_01_justification=GitHub+enforced. See our automation proposals system for how to do that. This data is available under the Community Data License Agreement – Permissive, Version 2.0 (CDLA-Permissive-2.0). This means that a Data Recipient may share the Data, with or without modifications, so long as the Data Recipient makes available the text of this agreement with the shared Data. Please credit andreysparish and the OpenSSF Best Practices badge contributors.

Project badge entry owned by: andreysparish.
Entry created on 2026-07-08 10:49:53 UTC, last updated on 2026-08-23 07:20:40 UTC. Last achieved passing badge on 2026-07-08 11:51:23 UTC.