Skip to content

Commit e3db49f

Browse files
authored
Merge pull request #40 from dcondrey/docs/readme-badge-standard
Standardize README headers, badges, and best-practices evidence
2 parents 21aafd7 + dc8c275 commit e3db49f

4 files changed

Lines changed: 251 additions & 29 deletions

File tree

.bestpractices.json

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
{
2+
"description_good_status": "Met",
3+
"description_good_justification": "README.md opening line and package.json `description` both succinctly state the project's purpose: a zero-dependency, hand-authored, cross-client HTML email framework. GitHub repo description (via `gh repo view`) matches.",
4+
5+
"interact_status": "Met",
6+
"interact_justification": "README.md 'Quickstart' section explains obtaining the code (git clone), SUPPORT.md explains feedback channels (Discussions for questions, GitHub Issues for bugs), and CONTRIBUTING.md explains how to contribute (PRs, dev setup, template scaffolding).",
7+
8+
"contribution_status": "Met",
9+
"contribution_justification": "CONTRIBUTING.md documents the full PR process: ground rules, dev setup commands, a pre-PR checklist (rebuild dist, lint 0 fail/0 warn, run smoke test, verify in a real client, fill PR checklist), and commit message conventions.",
10+
11+
"contribution_requirements_status": "Met",
12+
"contribution_requirements_justification": "CONTRIBUTING.md 'Ground rules' section states explicit acceptance requirements (never-drop-support, zero build-path dependencies, copy hygiene) and 'Before you open a PR' lists concrete gates (lint 0 fail/0 warn, smoke pass, client verification, PR checklist) plus a PR template at .github/pull_request_template.md.",
13+
14+
"floss_license_status": "Met",
15+
"floss_license_justification": "LICENSE file at repo root is the MIT License, an OSI-approved FLOSS license.",
16+
17+
"floss_license_osi_status": "Met",
18+
"floss_license_osi_justification": "MIT License (see LICENSE) is on the OSI-approved license list.",
19+
20+
"license_location_status": "Met",
21+
"license_location_justification": "LICENSE file present at the repository root (/Volumes/A/html-email/LICENSE); also referenced from README.md badge and package.json `license: \"MIT\"`.",
22+
23+
"documentation_basics_status": "Met",
24+
"documentation_basics_justification": "README.md covers quickstart, why/how, templates, and links to docs/ (quirks.md, clients.md, testing.md); CONTRIBUTING.md documents development workflow.",
25+
26+
"documentation_interface_status": "Met",
27+
"documentation_interface_justification": "The external interface is the `html-email-lint` CLI (framework/build/lint.mjs). Its inputs/outputs/flags are documented in README.md 'Lint any email' section and docs/testing.md ('Lint before you look'), including exit-code and profile behavior.",
28+
29+
"sites_https_status": "Met",
30+
"sites_https_justification": "Repo URL (https://github.com/dcondrey/html-email), live demo (https://dcondrey.github.io/html-email/), and all documentation links use HTTPS; no plain-http URLs found in README.md or docs/.",
31+
32+
"discussion_status": "Met",
33+
"discussion_justification": "GitHub Issues is enabled (`gh repo view` shows hasIssuesEnabled: true, 7 open issues at github.com/dcondrey/html-email/issues) and is URL-addressable, searchable, and open to any GitHub user without a proprietary client. SUPPORT.md also points to GitHub Discussions, but `gh api repos/dcondrey/html-email` shows `has_discussions: false` (not actually enabled), so Issues is the operative mechanism.",
34+
35+
"english_status": "Met",
36+
"english_justification": "All documentation (README.md, CONTRIBUTING.md, SECURITY.md, docs/*.md) is written in English; issue/PR templates are in English and accept English input.",
37+
38+
"maintained_status": "Met",
39+
"maintained_justification": "`git log` shows the most recent commit on 2026-08-22 and 81 commits in the last 90 days; `gh api repos/dcondrey/html-email` shows pushed_at 2026-08-24, indicating active, ongoing maintenance.",
40+
41+
"repo_public_status": "Met",
42+
"repo_public_justification": "Repository is public at https://github.com/dcondrey/html-email (`gh repo view` confirms isPrivate: false), version-controlled with git.",
43+
44+
"repo_track_status": "Met",
45+
"repo_track_justification": "git log shows full commit history with author, timestamp, and message for every change (e.g. `git log --format='%an <%ae>'` and `git log -1 --format=%ci`), tracking who changed what and when.",
46+
47+
"repo_interim_status": "Met",
48+
"repo_interim_justification": "git log shows 81 commits in the last 90 days between the single tagged release (v1.0.0), including an active 'Unreleased' section in CHANGELOG.md documenting interim work since 1.0.0.",
49+
50+
"repo_distributed_status": "Met",
51+
"repo_distributed_justification": "Repository uses git, a distributed version control system (confirmed via `.git/` directory and `git remote -v`).",
52+
53+
"version_unique_status": "Met",
54+
"version_unique_justification": "package.json declares `\"version\": \"1.0.0\"`, matching the git tag v1.0.0 (`git tag` output) and the GitHub Release (`gh release list` shows v1.0.0).",
55+
56+
"version_semver_status": "Met",
57+
"version_semver_justification": "Version 1.0.0 in package.json and tag v1.0.0 follow Semantic Versioning (MAJOR.MINOR.PATCH) format.",
58+
59+
"version_tags_status": "Met",
60+
"version_tags_justification": "`git tag` lists v1.0.0, and .github/workflows/release.yml triggers a release build on `push: tags: ['v*']`.",
61+
62+
"release_notes_status": "Met",
63+
"release_notes_justification": "CHANGELOG.md follows Keep a Changelog format with a human-readable [1.0.0] entry (Added/Fixed/Changed sections), generated via git-cliff (cliff.toml) from Conventional Commits; the GitHub Release for v1.0.0 also has auto-generated release notes (release.yml uses `generate_release_notes: true`).",
64+
65+
"release_notes_vulns_status": "N/A",
66+
"release_notes_vulns_justification": "No publicly known vulnerabilities have been fixed in any release yet (CHANGELOG.md 1.0.0 entry lists no CVE/security fixes); N/A per criterion.",
67+
68+
"report_process_status": "Met",
69+
"report_process_justification": "GitHub Issues is the bug-report process (SUPPORT.md: 'Bugs (render/build/lint): open an issue'), with a structured bug_report.yml template at .github/ISSUE_TEMPLATE/bug_report.yml.",
70+
71+
"report_tracker_status": "Met",
72+
"report_tracker_justification": "GitHub Issues is used as the individual issue tracker (github.com/dcondrey/html-email/issues), with 7 open issues observed via `gh issue list`.",
73+
74+
"report_responses_status": "Met",
75+
"report_responses_justification": "The one historical bug report (issue #1, 'Uncheckable checkboxes', opened 2014-12-05) was resolved and closed (2016-01-25). The 5 currently open issues (#31-35) are maintainer-authored roadmap/feature items (`gh issue list --json author` shows all opened by dcondrey), not unanswered external bug reports, so there is no evidence of unacknowledged external reports in the covered window.",
76+
77+
"enhancement_responses_status": "Met",
78+
"enhancement_responses_justification": "All currently open enhancement issues (#31-35) were filed and are being tracked by the maintainer (dcondrey) himself as an active roadmap; no external enhancement request is pending without engagement.",
79+
80+
"report_archive_status": "Met",
81+
"report_archive_justification": "GitHub Issues provides a publicly available, searchable archive of all reports and responses at github.com/dcondrey/html-email/issues, including closed issue #1 dating to 2014.",
82+
83+
"vulnerability_report_process_status": "Met",
84+
"vulnerability_report_process_justification": "SECURITY.md documents the vulnerability reporting process: GitHub Security Advisories (private) or email to davidcondrey@gmail.com, with expected initial response time.",
85+
86+
"vulnerability_report_private_status": "Met",
87+
"vulnerability_report_private_justification": "SECURITY.md explicitly explains private reporting: 'Open a private advisory via GitHub Security Advisories ... or email davidcondrey@gmail.com', and states 'do not report through public GitHub issues.'",
88+
89+
"vulnerability_report_response_status": "N/A",
90+
"vulnerability_report_response_justification": "No vulnerability reports have been received in the last 6 months (no security advisories found for this repo, and the project's public history shows no recorded vuln reports), so response-time cannot be evaluated; N/A per criterion.",
91+
92+
"build_status": "Met",
93+
"build_justification": "package.json defines a `build` script (`node framework/build/build.mjs ...`) that is automated and required to produce framework/dist and template outputs; used in CI (.github/workflows/ci.yml 'Build framework' step).",
94+
95+
"build_common_tools_status": "Met",
96+
"build_common_tools_justification": "Build uses Node.js and npm (`npm run build`, `npm ci`), standard/common tools for JavaScript projects; no bespoke build system.",
97+
98+
"build_floss_tools_status": "Met",
99+
"build_floss_tools_justification": "Build depends only on Node.js (FLOSS, MIT-licensed) and its own zero-dependency build.mjs script; devDependencies fast-check and puppeteer (used only for dev/test, not the build path) are also FLOSS (MIT/Apache-2.0).",
100+
101+
"test_status": "Met",
102+
"test_justification": "Automated FLOSS test suite exists: framework/build/lint.test.mjs (self-test against fixtures) and framework/build/fuzz.test.js (property-based fuzzing), run via `npm test` (package.json). Documented in CONTRIBUTING.md and README.md ('a self-test gates the linter, a fuzzer gates its edge cases').",
103+
104+
"test_invocation_status": "Met",
105+
"test_invocation_justification": "Tests are invoked via the standard `npm test` command (package.json `\"test\": \"npm run verify && npm run test:lint && npm run test:fuzz\"`), the conventional invocation for a Node.js project.",
106+
107+
"test_most_status": "Met",
108+
"test_most_justification": "lint.test.mjs exercises the linter's rule set against pass/fail fixtures (framework/build/test/good.html, bad.html) covering house-profile invariants, and fuzz.test.js property-tests the analyzer across 300 runs per property against arbitrary/malformed input, covering the 28 documented lint rules (docs/quirks.md).",
109+
110+
"test_continuous_integration_status": "Met",
111+
"test_continuous_integration_justification": ".github/workflows/ci.yml runs the self-test ('Self-test the linter') and fuzz suite ('Fuzz the rule set') on every push and PR to master.",
112+
113+
"test_policy_status": "Met",
114+
"test_policy_justification": "Recent feature commits consistently add/update test fixtures alongside new functionality (e.g. commit 16eb6ed 'feat: gate ten more documented quirks' touches framework/build/lint.test.mjs and framework/build/test/good.html; commit ab20331 likewise). This is a consistent practice though not written down verbatim in CONTRIBUTING.md.",
115+
116+
"tests_are_added_status": "Met",
117+
"tests_are_added_justification": "`git show --stat 16eb6ed` and `git show --stat ab20331` confirm framework/build/lint.test.mjs and framework/build/test/good.html were modified in the same commits that added new lint rules/functionality, demonstrating the policy was followed in recent major changes.",
118+
119+
"tests_documented_added_status": "Unmet",
120+
"tests_documented_added_justification": "CONTRIBUTING.md's 'Before you open a PR' checklist does not explicitly instruct contributors to add/update tests (lint.test.mjs fixtures or fuzz.test.js) for new functionality; the practice is followed in commit history but not written into the contribution instructions.",
121+
122+
"warnings_status": "Unmet",
123+
"warnings_justification": "No linter (e.g. ESLint) or `'use strict'`/strict-mode configuration was found for the project's own JavaScript source (no .eslintrc*, eslint.config.*, or lint script targeting framework/build/*.mjs itself found via search). FLOSS linters exist for JavaScript, so this is Unmet rather than N/A; the project does run CodeQL static analysis, but that is separate from a warnings/lint-level check.",
124+
125+
"warnings_fixed_status": "Unmet",
126+
"warnings_fixed_justification": "No JS-source linter is configured (see `warnings`), so there are no lint warnings being tracked or fixed as a matter of process.",
127+
128+
"warnings_strict_status": "Unmet",
129+
"warnings_strict_justification": "No JS-source linter/warnings configuration exists to be tuned to maximal strictness (see `warnings`).",
130+
131+
"know_secure_design_status": "Met",
132+
"know_secure_design_justification": "SECURITY.md 'Threat model for an email framework' section explicitly discusses the project's security surface (injection into rendered output, link/image destination review, unsubscribe/compliance) and a 'Supply-chain security' section describing SHA-pinned Actions, Scorecard, CodeQL, Dependency Review, Dependabot, and SLSA build provenance (.github/workflows/release.yml) — concrete evidence of secure-design awareness by the primary developer.",
133+
134+
"know_common_errors_status": "Met",
135+
"know_common_errors_justification": "Commit history shows security-motivated fixes with clear vulnerability-class awareness, e.g. commit 2de8995 'security: share one comment scanner instead of a third regex replace' and f173ac2 'security: scan for comment and tag boundaries instead of regex-replacing them', addressing regex-based injection/parsing pitfalls; CodeQL alerts (js/incomplete-multi-character-sanitization, js/unsafe-html-expansion) were triaged (fixed/dismissed) per `gh api repos/dcondrey/html-email/code-scanning/alerts`.",
136+
137+
"crypto_published_status": "N/A",
138+
"crypto_published_justification": "Project produces static HTML email and a lint tool; no cryptographic protocols or algorithms are implemented or used.",
139+
140+
"crypto_call_status": "N/A",
141+
"crypto_call_justification": "No cryptographic functionality is present in the codebase (confirmed by reviewing framework/build/*.mjs and scripts/; no crypto imports found).",
142+
143+
"crypto_floss_status": "N/A",
144+
"crypto_floss_justification": "No cryptographic functionality is implemented or required by this project.",
145+
146+
"crypto_keylength_status": "N/A",
147+
"crypto_keylength_justification": "No cryptographic keys are used or generated by this project.",
148+
149+
"crypto_working_status": "N/A",
150+
"crypto_working_justification": "No cryptographic algorithms (broken or otherwise) are used by this project.",
151+
152+
"crypto_weaknesses_status": "N/A",
153+
"crypto_weaknesses_justification": "No cryptographic algorithms are used by this project.",
154+
155+
"crypto_pfs_status": "N/A",
156+
"crypto_pfs_justification": "No key-agreement/cryptographic protocol is implemented by this project.",
157+
158+
"crypto_password_storage_status": "N/A",
159+
"crypto_password_storage_justification": "Project has no authentication system and stores no passwords.",
160+
161+
"crypto_random_status": "N/A",
162+
"crypto_random_justification": "No cryptographic keys or nonces are generated by this project.",
163+
164+
"delivery_mitm_status": "Met",
165+
"delivery_mitm_justification": "Source is delivered via git over HTTPS/SSH (git remote at git@github.com:dcondrey/html-email, and https://github.com/dcondrey/html-email.git per package.json `repository.url`), both of which counter MITM.",
166+
167+
"delivery_unsigned_status": "Met",
168+
"delivery_unsigned_justification": "No unsigned hash-only integrity check is retrieved over plain HTTP anywhere in the delivery path; source comes from GitHub over HTTPS, and release archives are additionally covered by a signed SLSA build-provenance attestation (.github/workflows/release.yml, actions/attest-build-provenance).",
169+
170+
"vulnerabilities_fixed_60_days_status": "Met",
171+
"vulnerabilities_fixed_60_days_justification": "No public, unpatched medium-or-higher severity vulnerability report was found for this project (no open GitHub Security Advisories; `gh api .../secret-scanning/alerts` returns empty; CodeQL alerts are in fixed/dismissed state per `gh api repos/dcondrey/html-email/code-scanning/alerts`).",
172+
173+
"vulnerabilities_critical_fixed_status": "Met",
174+
"vulnerabilities_critical_fixed_justification": "No critical vulnerabilities have been reported against this project to date, so none are outstanding; the SECURITY.md process (private advisory/email) is in place to enable rapid response if one is reported.",
175+
176+
"no_leaked_credentials_status": "Met",
177+
"no_leaked_credentials_justification": "`grep -rIn -E \"(api[_-]?key|secret|password|token)\\s*=\\s*['\\\"][A-Za-z0-9]{10,}\"` across the repo (excluding node_modules) found no hardcoded credentials; `gh api repos/dcondrey/html-email/secret-scanning/alerts` returns an empty list.",
178+
179+
"static_analysis_status": "Met",
180+
"static_analysis_justification": ".github/workflows/codeql.yml runs GitHub CodeQL static analysis (javascript-typescript) on push, PR, and weekly cron, a FLOSS-available static analysis tool for JavaScript.",
181+
182+
"static_analysis_common_vulnerabilities_status": "Met",
183+
"static_analysis_common_vulnerabilities_justification": ".github/codeql/codeql-config.yml sets `queries: uses: security-extended`, CodeQL's deeper security query pack covering common vulnerability classes (injection, unsafe HTML expansion, prototype pollution, etc., as seen in the alert history).",
184+
185+
"static_analysis_fixed_status": "Met",
186+
"static_analysis_fixed_justification": "`gh api repos/dcondrey/html-email/code-scanning/alerts` shows the majority of historical alerts (js/unsafe-html-expansion, js/functionality-from-untrusted-source, js/prototype-pollution-utility) in `fixed` state; remaining `dismissed` alerts (js/incomplete-multi-character-sanitization, all in legacy/, excluded via codeql-config.yml `paths-ignore: legacy/**`) are explicitly justified as an intentionally unmaintained 2014 artifact per legacy/README.md.",
187+
188+
"static_analysis_often_status": "Met",
189+
"static_analysis_often_justification": "codeql.yml runs on every push and pull_request to master in addition to a weekly cron (`cron: '31 4 * * 1'`), i.e. on every commit.",
190+
191+
"dynamic_analysis_status": "Met",
192+
"dynamic_analysis_justification": "framework/build/fuzz.test.js applies property-based dynamic fuzzing (fast-check) to the lint rule engine, run via `npm run test:fuzz` and in CI (ci.yml 'Fuzz the rule set') before merges to master.",
193+
194+
"dynamic_analysis_unsafe_status": "N/A",
195+
"dynamic_analysis_unsafe_justification": "Project contains no memory-unsafe (C/C++) code; it is pure JavaScript/Node.js.",
196+
197+
"dynamic_analysis_enable_assertions_status": "Met",
198+
"dynamic_analysis_enable_assertions_justification": "fuzz.test.js asserts invariants (no crash, no pathological backtracking, valid rule IDs/severities) across 300 runs per property (`fc.check(property, { numRuns: 300 })`), and lint.test.mjs uses explicit assert() checks against expected pass/fail output.",
199+
200+
"dynamic_analysis_fixed_status": "N/A",
201+
"dynamic_analysis_fixed_justification": "No outstanding dynamic-analysis (fuzz) findings exist; the fuzz suite currently passes cleanly in CI, so there are no medium+ findings pending a fix."
202+
}

0 commit comments

Comments
 (0)