|
| 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