Skip to content

oss-baseline@v1

A minimal OSS-hygiene baseline — the documents and conventions most open-source repositories are expected to follow. Adopt it with:

extends:
- alint://bundled/oss-baseline@v1

Defaults are deliberately non-blocking (info for community-doc recommendations, warning for missing README/LICENSE, error for unambiguous bugs like committed merge markers or bidi controls). Upgrade severity in your own config when you're ready to enforce.

15 rules. Each links to its section below, which explains the check and shows its definition.

RuleReports
oss-readme-exists
warning
An open-source repo should have a README at the root.
oss-license-exists
warning
An open-source repo should declare a license at the root.
oss-license-non-empty
info
LICENSE file is suspiciously short; paste the full license text rather than a stub.
oss-readme-non-stub
info
README is very short; add a brief description and at least a usage / install section.
oss-security-policy-exists
info
Consider adding a SECURITY.md so vulnerability reporters know where to disclose.
oss-security-policy-non-empty
info
SECURITY.md is suspiciously short; describe how to report vulnerabilities and the supported-versions policy.
oss-dependency-update-tool
info
Consider configuring Dependabot or Renovate to keep dependencies and actions up to date.
oss-codeowners-exists
info
Consider adding a CODEOWNERS file so PR reviews are auto-routed.
oss-codeowners-non-empty
info
CODEOWNERS exists but appears empty; add at least one ownership rule (e.g. * @org/team).
oss-code-of-conduct-exists
info
Consider adding a CODE_OF_CONDUCT.md.
oss-gitignore-exists
info
Most OSS repos should have a .gitignore to keep build artefacts and secrets out of git.
oss-no-merge-conflict-markers
error
Merge-conflict markers must not be committed.
oss-no-bidi-controls
error
Unicode bidi override characters are a code-review hazard; reject.
oss-final-newline
info
File must end with a single \n.
oss-no-trailing-whitespace
info
No line may end with space or tab.

An open-source repo should have a README at the root.

- id: oss-readme-exists
kind: file_exists
paths: ["README.md", "README", "README.rst", "readme.md", "readme"]
root_only: true
level: warning
message: "An open-source repo should have a README at the root."
policy_url: "https://opensource.guide/starting-a-project/#writing-a-readme"

Changed in v0.9.18: case-variation broadening — LICENSE.TXT (uppercase extension) is dotnet/runtime's canonical filename and was rejected before. LICENSE.rst covers Python projects that ship the license in reST. COPYING.md / COPYING.txt cover less common variants surfaced across the case-study corpus. Filesystem globs are case-sensitive on most platforms; the brace expansion enumerates the case-variants explicitly.

An open-source repo should declare a license at the root.

- id: oss-license-exists
kind: file_exists
paths:
- "LICENSE"
- "LICENSE.{md,txt,TXT,rst}"
- "license"
- "license.{md,txt,rst}"
- "LICENSE-APACHE"
- "LICENSE-MIT"
- "LICENSE-BSD"
- "LICENSE-MPL"
- "COPYING"
- "COPYING.{md,txt}"
root_only: true
level: warning
message: "An open-source repo should declare a license at the root."
policy_url: "https://opensource.guide/legal/#which-open-source-license-is-appropriate-for-my-project"

A zero-byte LICENSE passes oss-license-exists while providing zero legal guidance. 200 bytes is a safely permissive floor — the shortest common OSS license (MIT) runs about 1 KiB once you include the copyright notice. Path list mirrors oss-license-exists so both rules check the same set.

LICENSE file is suspiciously short; paste the full license text rather than a stub.

- id: oss-license-non-empty
kind: file_min_size
paths:
- "LICENSE"
- "LICENSE.{md,txt,TXT,rst}"
- "license"
- "license.{md,txt,rst}"
- "LICENSE-APACHE"
- "LICENSE-MIT"
- "LICENSE-BSD"
- "LICENSE-MPL"
- "COPYING"
- "COPYING.{md,txt}"
min_bytes: 200
level: info
message: "LICENSE file is suspiciously short; paste the full license text rather than a stub."

Catches the classic "# Project\n\nTODO\n" README. Three lines is intentionally gentle — passes for most real READMEs without nagging early-stage repos.

README is very short; add a brief description and at least a usage / install section.

- id: oss-readme-non-stub
kind: file_min_lines
paths: ["README.md", "README", "README.rst", "readme.md", "readme"]
min_lines: 3
level: info
message: "README is very short; add a brief description and at least a usage / install section."

Consider adding a SECURITY.md so vulnerability reporters know where to disclose.

- id: oss-security-policy-exists
kind: file_exists
paths: ["SECURITY.md", ".github/SECURITY.md", "docs/SECURITY.md"]
level: info
message: "Consider adding a SECURITY.md so vulnerability reporters know where to disclose."
policy_url: "https://docs.github.com/en/code-security/getting-started/adding-a-security-policy-to-your-repository"

Mirrors OpenSSF Scorecard's Security-Policy check: the file has to actually contain reporting guidance, not be a stub. 200 bytes is the same floor as the LICENSE rule's.

SECURITY.md is suspiciously short; describe how to report vulnerabilities and the supported-versions policy.

- id: oss-security-policy-non-empty
kind: file_min_size
paths: ["SECURITY.md", ".github/SECURITY.md", "docs/SECURITY.md"]
min_bytes: 200
level: info
message: "SECURITY.md is suspiciously short; describe how to report vulnerabilities and the supported-versions policy."
policy_url: "https://github.com/ossf/scorecard/blob/main/docs/checks.md#security-policy"

OpenSSF Scorecard's Dependency-Update-Tool check. Either Dependabot or Renovate satisfies it; both are config-only (no extra Rust deps, no engine work). The wide path list covers every blessed location each tool reads.

Consider configuring Dependabot or Renovate to keep dependencies and actions up to date.

- id: oss-dependency-update-tool
kind: file_exists
paths:
- ".github/dependabot.yml"
- ".github/dependabot.yaml"
- "renovate.json"
- "renovate.json5"
- ".renovaterc"
- ".renovaterc.json"
- ".github/renovate.json"
- ".github/renovate.json5"
level: info
message: "Consider configuring Dependabot or Renovate to keep dependencies and actions up to date."
policy_url: "https://github.com/ossf/scorecard/blob/main/docs/checks.md#dependency-update-tool"

OpenSSF Scorecard's Code-Review signal. Branch-protection itself is GitHub-API state alint can't see, but a CODEOWNERS file is the on-disk piece — it auto-routes review requests and signals review expectations to contributors.

Consider adding a CODEOWNERS file so PR reviews are auto-routed.

- id: oss-codeowners-exists
kind: file_exists
paths: ["CODEOWNERS", ".github/CODEOWNERS", "docs/CODEOWNERS"]
level: info
message: "Consider adding a CODEOWNERS file so PR reviews are auto-routed."
policy_url: "https://github.com/ossf/scorecard/blob/main/docs/checks.md#code-review"

Catches the empty / placeholder CODEOWNERS that satisfies Scorecard's existence check while doing nothing useful. 10 bytes is the smallest meaningful pattern + owner pair.

CODEOWNERS exists but appears empty; add at least one ownership rule (e.g. * @org/team).

- id: oss-codeowners-non-empty
kind: file_min_size
paths: ["CODEOWNERS", ".github/CODEOWNERS", "docs/CODEOWNERS"]
min_bytes: 10
level: info
message: "CODEOWNERS exists but appears empty; add at least one ownership rule (e.g. `* @org/team`)."

Consider adding a CODE_OF_CONDUCT.md.

- id: oss-code-of-conduct-exists
kind: file_exists
paths: ["CODE_OF_CONDUCT.md", ".github/CODE_OF_CONDUCT.md", "docs/CODE_OF_CONDUCT.md"]
level: info
message: "Consider adding a CODE_OF_CONDUCT.md."
policy_url: "https://www.contributor-covenant.org/"

Most OSS repos should have a .gitignore to keep build artefacts and secrets out of git.

- id: oss-gitignore-exists
kind: file_exists
paths: .gitignore
root_only: true
level: info
message: "Most OSS repos should have a .gitignore to keep build artefacts and secrets out of git."

Merge-conflict markers must not be committed.

- id: oss-no-merge-conflict-markers
kind: no_merge_conflict_markers
paths:
include: ["**/*.md", "**/*.txt", "**/*.toml", "**/*.yml", "**/*.yaml", "**/*.json"]
level: error
message: "Merge-conflict markers must not be committed."

Trojan Source (CVE-2021-42574): bidirectional override characters can make source code read differently from how it executes.

Unicode bidi override characters are a code-review hazard; reject.

- id: oss-no-bidi-controls
kind: no_bidi_controls
paths:
include: ["**/*.md", "**/*.txt", "**/*.toml", "**/*.yml", "**/*.yaml", "**/*.json"]
level: error
message: "Unicode bidi override characters are a code-review hazard; reject."
policy_url: "https://trojansource.codes/"
  • kind: final_newline
  • level: info
  • fix: file_append_final_newline (applied by alint fix)
- id: oss-final-newline
kind: final_newline
paths: ["**/*.md", "**/*.txt", "**/*.toml", "**/*.yml", "**/*.yaml"]
level: info
fix:
file_append_final_newline: {}
- id: oss-no-trailing-whitespace
kind: no_trailing_whitespace
paths: ["**/*.md", "**/*.txt", "**/*.toml", "**/*.yml", "**/*.yaml"]
level: info
fix:
file_trim_trailing_whitespace: {}

Every rule here can be overridden by id from your own .alint.yml: change its level, or set level: off to drop it. An id that doesn't exist is an error at config load, so a typo can't silently pass.

extends:
- alint://bundled/oss-baseline@v1
rules:
- id: oss-readme-exists
level: off
- id: oss-license-exists
level: error

To take only part of the ruleset, filter it where you extend it with only: or except::

extends:
- url: alint://bundled/oss-baseline@v1
except: [oss-readme-exists]

Bundled rulesets covers versioning and how rulesets combine.

The full ruleset definition, comments included, is committed at crates/alint-dsl/rulesets/v1/oss-baseline.yml in the alint repo.