diff --git a/.bestpractices.json b/.bestpractices.json new file mode 100644 index 0000000..f25ea71 --- /dev/null +++ b/.bestpractices.json @@ -0,0 +1,88 @@ +{ + "description_good_status": "Met", + "description_good_justification": "README.md describes efctl's purpose, users, and major capabilities.", + "interact_status": "Met", + "interact_justification": "The public issue tracker supports user and maintainer interaction: https://github.com/Scetrov/efctl/issues.", + "contribution_status": "Met", + "contribution_justification": "The contribution process is documented in CONTRIBUTING.md: https://github.com/Scetrov/efctl/blob/main/CONTRIBUTING.md.", + "floss_license_status": "Met", + "floss_license_justification": "The project is distributed under the OSI-approved MIT License.", + "license_location_status": "Met", + "license_location_justification": "The repository root contains the license text: https://github.com/Scetrov/efctl/blob/main/LICENSE.", + "documentation_basics_status": "Met", + "documentation_basics_justification": "README.md documents installation, usage, and project capabilities.", + "documentation_interface_status": "Met", + "documentation_interface_justification": "Generated CLI reference is maintained under docs/ and linked from README.md.", + "sites_https_status": "Met", + "sites_https_justification": "The public repository, documentation links, releases, and vulnerability reporting endpoint use HTTPS.", + "discussion_status": "Met", + "discussion_justification": "Public discussions and issue reports are retained in the repository issue tracker.", + "maintained_status": "Met", + "maintained_justification": "The repository has current releases, dependency updates, CI maintenance, and active source changes.", + "repo_public_status": "Met", + "repo_public_justification": "The complete source repository is publicly available on GitHub.", + "repo_track_status": "Met", + "repo_track_justification": "Git tracks the project history and published tags.", + "repo_interim_status": "Met", + "repo_interim_justification": "Changes are developed in Git branches and reviewed through GitHub pull requests before mainline integration.", + "version_unique_status": "Met", + "version_unique_justification": "Published releases use unique SemVer tags from v0.0.1 through v0.3.6.", + "release_notes_status": "Met", + "release_notes_justification": "Human-readable summaries for every published release are maintained in CHANGELOG.md: https://github.com/Scetrov/efctl/blob/main/CHANGELOG.md.", + "release_notes_vulns_status": "N/A", + "release_notes_vulns_justification": "No published efctl release fixed a publicly known efctl runtime vulnerability with a CVE or similar identifier.", + "report_process_status": "Met", + "report_process_justification": "Bug-report guidance is published in CONTRIBUTING.md: https://github.com/Scetrov/efctl/blob/main/CONTRIBUTING.md.", + "report_responses_status": "Met", + "report_responses_justification": "Maintainers respond to public reports through the repository issue tracker and pull-request workflow.", + "report_archive_status": "Met", + "report_archive_justification": "The public issue tracker preserves report history: https://github.com/Scetrov/efctl/issues.", + "vulnerability_report_process_status": "Met", + "vulnerability_report_process_justification": "SECURITY.md publishes the private vulnerability-reporting process: https://github.com/Scetrov/efctl/blob/main/SECURITY.md.", + "vulnerability_report_private_status": "Met", + "vulnerability_report_private_justification": "GitHub private vulnerability reporting is documented in SECURITY.md: https://github.com/Scetrov/efctl/security/advisories/new.", + "vulnerability_report_response_status": "N/A", + "vulnerability_report_response_justification": "No private vulnerability reports were received in the applicable six-month window.", + "build_status": "Met", + "build_justification": "The documented Go build and the release workflow build reproducible platform binaries.", + "test_status": "Met", + "test_justification": "The repository contains unit, integration, and E2E Go tests run by CI.", + "test_policy_status": "Met", + "test_policy_justification": "CONTRIBUTING.md requires automated tests for new functionality and bug fixes.", + "tests_are_added_status": "Met", + "tests_are_added_justification": "Contributor policy requires corresponding automated tests for production changes.", + "warnings_status": "Met", + "warnings_justification": "go vet runs in pre-commit and make vet, and CI runs the standard test workflow.", + "warnings_fixed_status": "Met", + "warnings_fixed_justification": "CONTRIBUTING.md requires all applicable formatting and warning checks to pass before review.", + "know_secure_design_status": "Met", + "know_secure_design_justification": "docs/threat-model.md documents the project's security considerations and boundaries.", + "know_common_errors_status": "Met", + "know_common_errors_justification": "Contributor guidance and pre-commit checks cover formatting, static analysis, secrets, and vulnerability scanning.", + "crypto_published_status": "N/A", + "crypto_published_justification": "efctl does not implement or select cryptographic protocols or algorithms as a project security mechanism.", + "crypto_floss_status": "N/A", + "crypto_floss_justification": "efctl has no cryptographic functionality requiring a non-FLOSS implementation.", + "crypto_keylength_status": "N/A", + "crypto_keylength_justification": "efctl does not define cryptographic key lengths as a security mechanism.", + "crypto_working_status": "N/A", + "crypto_working_justification": "efctl does not implement cryptographic algorithms whose correctness requires project-specific validation.", + "crypto_password_storage_status": "N/A", + "crypto_password_storage_justification": "efctl does not store user passwords.", + "crypto_random_status": "N/A", + "crypto_random_justification": "efctl does not generate security-sensitive random values as a project security mechanism.", + "delivery_mitm_status": "Met", + "delivery_mitm_justification": "Release artifacts are distributed through GitHub's HTTPS release service.", + "delivery_unsigned_status": "Met", + "delivery_unsigned_justification": "The release workflow signs binary artifacts with Cosign and publishes attestations.", + "vulnerabilities_fixed_60_days_status": "Met", + "vulnerabilities_fixed_60_days_justification": "SECURITY.md requires acknowledgement within seven days and coordinates remediation and disclosure.", + "no_leaked_credentials_status": "Met", + "no_leaked_credentials_justification": "gitleaks runs as a configured pre-commit secret-detection quality gate.", + "static_analysis_status": "Met", + "static_analysis_justification": "CodeQL, go vet, gosec, and govulncheck provide static analysis in CI and local quality gates.", + "static_analysis_fixed_status": "Met", + "static_analysis_fixed_justification": "Contributor policy requires applicable security and static-analysis checks to pass before acceptance.", + "dynamic_analysis_fixed_status": "N/A", + "dynamic_analysis_fixed_justification": "No dynamic-analysis finding is currently applicable; the project does not operate a dynamic-analysis tool that has reported an unresolved issue." +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..7082402 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,103 @@ +# Changelog + +All notable user-visible and security-relevant changes to efctl are documented here. No historical release fixed a publicly known efctl runtime vulnerability with a CVE or similar identifier. + +## Unreleased + +- Add human-readable entries here for user-visible changes and security fixes. Identify any publicly known efctl runtime vulnerability fixed by the release. + +## v0.3.6 + +- Remove a vulnerable `x/crypto` dependency and refresh project dependencies and contracts. + +## v0.3.5 + +- Add remote development startup configuration and harden supply-chain workflows. + +## v0.3.4 + +- Finalize the prior pnpm, esbuild, and mnemonic-leak remediation work. + +## v0.3.3 + +- Guard Sui configuration loading and add pnpm diagnostics. + +## v0.3.2 + +- Improve Sui configuration safety, pnpm diagnostics, and dependency security maintenance. + +## v0.3.1 + +- Normalize `.env` line endings for Windows environments. + +## v0.3.0 + +- Add extension build and test commands and improve package discovery. + +## v0.2.4 + +- Improve extension publishing and assembly artifacts, validation, and AI-assisted initialization guidance. + +## v0.2.3 + +- Add GraphQL endpoint information to environment summaries and dashboard output. + +## v0.2.2 + +- Add faucet support and improve Windows script compatibility and test reliability. + +## v0.2.1 + +- Improve doctor repository detection and resolve local quality-check issues. + +## v0.2.0 + +- Add `efctl init` and `efctl doctor` commands. + +## v0.1.2 + +- Avoid unnecessary SELinux relabeling when Docker does not require it. + +## v0.1.1 + +- Allow extension deployment from additional folders. + +## v0.1.0 + +- Add world-query functionality and improve container-runtime test resilience. + +## v0.0.9 + +- Improve dashboard display and deployment-summary extraction. + +## v0.0.8 + +- Upgrade to Go 1.26 and add release artifact attestations and SBOMs. + +## v0.0.7 + +- Improve Windows support, configuration discovery, container lifecycle handling, and dashboard behavior. + +## v0.0.6 + +- Deliver comprehensive dashboard usability and environment-information improvements. + +## v0.0.5 + +- Add extension initialization and publishing commands and improve command output. + +## v0.0.4 + +- Configure the Sui client and update project documentation. + +## v0.0.3 + +- Refine terminal UI formatting, spinner spacing, and developer editor configuration. + +## v0.0.2 + +- Add self-update and version commands and improve cross-platform installation instructions. + +## v0.0.1 + +- Establish the initial efctl release with CI and project branding. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 165d24c..7eadd55 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,6 +29,30 @@ First off, thank you for considering contributing to `efctl`! It's people like y 4. Push your branch and open a Pull Request. 5. Please use the provided Pull Request template and fill it out completely. +## Required Checks and Tests + +New functionality and bug fixes **must include automated tests** at the appropriate level: unit tests for isolated logic, integration tests for component interactions, and E2E tests for user workflows. Run the applicable checks before requesting review: + +```bash +make fmt-check # formatting +make vet # compiler and static-analysis warnings +go test ./... # unit tests, including repository invariants +make test-integration # integration tests +make test-e2e # Docker-backed end-to-end tests +make security # gosec and govulncheck security checks +pre-commit run --all-files # complete local quality gate +``` + +All applicable checks must pass. Regenerate CLI documentation with `make docs` when a command or its output changes. + +## Release Notes + +For every user-visible change or security fix, add a concise human-readable entry under the `Unreleased` section in [CHANGELOG.md](CHANGELOG.md). Do not use raw commit logs as release notes. If the change fixes a publicly known efctl runtime vulnerability (for example, one with a CVE), identify it in that entry. + +## Best Practices Badge Owner Workflow + +After this change merges to the default branch, an authorized bestpractices.dev editor must open [project 13754](https://www.bestpractices.dev/projects/13754), review the proposals imported from `.bestpractices.json`, save the reviewed answers, and verify both the project JSON endpoint and the live README badge. The repository file proposes answers only; it does not change the service assessment by itself. If an answer is inaccurate, correct it in the service and submit a repository follow-up; reverting this repository change does not roll back an already saved service answer. + ## Bug Reports & Feature Requests If you encounter an issue or have a feature idea, please open an Issue on GitHub using the provided templates. Provide as much detail as possible (logs, reproduction steps, environment details) when reporting bugs. diff --git a/README.md b/README.md index a26f604..6a08ba5 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ ![efctl Logo](https://raw.githubusercontent.com/Scetrov/efctl/refs/heads/main/assets/logo.png) +[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/13754/badge)](https://www.bestpractices.dev/projects/13754) + > [!IMPORTANT] > `efctl` is a high-performance CLI designed to automate the lifecycle of EVE Frontier local world contracts and smart gates. diff --git a/bestpractices_test.go b/bestpractices_test.go new file mode 100644 index 0000000..136ff87 --- /dev/null +++ b/bestpractices_test.go @@ -0,0 +1,129 @@ +package main + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + "regexp" + "runtime" + "sort" + "strings" + "testing" +) + +var mandatoryPassingControls = []string{ + "description_good", "interact", "contribution", "floss_license", "license_location", + "documentation_basics", "documentation_interface", "sites_https", "discussion", "maintained", + "repo_public", "repo_track", "repo_interim", "version_unique", "release_notes", + "release_notes_vulns", "report_process", "report_responses", "report_archive", + "vulnerability_report_process", "vulnerability_report_private", "vulnerability_report_response", + "build", "test", "test_policy", "tests_are_added", "warnings", "warnings_fixed", + "know_secure_design", "know_common_errors", "crypto_published", "crypto_floss", "crypto_keylength", + "crypto_working", "crypto_password_storage", "crypto_random", "delivery_mitm", "delivery_unsigned", + "vulnerabilities_fixed_60_days", "no_leaked_credentials", "static_analysis", "static_analysis_fixed", + "dynamic_analysis_fixed", +} + +var urlRequiredControls = map[string]bool{ + "contribution": true, + "license_location": true, + "release_notes": true, + "report_process": true, + "report_archive": true, + "vulnerability_report_process": true, + "vulnerability_report_private": true, +} + +var auditedReleaseTags = []string{ + "v0.0.1", "v0.0.2", "v0.0.3", "v0.0.4", "v0.0.5", "v0.0.6", "v0.0.7", "v0.0.8", "v0.0.9", + "v0.1.0", "v0.1.1", "v0.1.2", "v0.2.0", "v0.2.1", "v0.2.2", "v0.2.3", "v0.2.4", "v0.3.0", + "v0.3.1", "v0.3.2", "v0.3.3", "v0.3.4", "v0.3.5", "v0.3.6", +} + +var httpsURL = regexp.MustCompile(`https://[^\s)]+`) +var applicabilityExplanation = regexp.MustCompile(`(?i)\b(no|not applicable|does not|not used|without)\b`) + +func repositoryRoot(t *testing.T) string { + t.Helper() + _, file, _, ok := runtime.Caller(0) + if !ok { + t.Fatal("runtime.Caller: cannot determine repository root") + } + return filepath.Dir(file) +} + +func readBestPracticesManifest(t *testing.T) map[string]string { + t.Helper() + path := filepath.Join(repositoryRoot(t), ".bestpractices.json") + data, err := os.ReadFile(path) + if err != nil { + t.Fatalf("read .bestpractices.json: %v", err) + } + var manifest map[string]string + if err := json.Unmarshal(data, &manifest); err != nil { + t.Fatalf("parse .bestpractices.json: %v", err) + } + return manifest +} + +func TestBestPracticesMandatoryControlAttestation(t *testing.T) { + manifest := readBestPracticesManifest(t) + want := make(map[string]bool, len(mandatoryPassingControls)) + for _, control := range mandatoryPassingControls { + want[control] = true + status, ok := manifest[control+"_status"] + if !ok { + t.Errorf("missing mandatory status for %q", control) + continue + } + if status != "Met" && status != "N/A" { + t.Errorf("%q has status %q; want Met or N/A", control, status) + } + + justification := strings.TrimSpace(manifest[control+"_justification"]) + if justification == "" { + t.Errorf("%q is missing a paired justification", control) + continue + } + if status == "N/A" && !applicabilityExplanation.MatchString(justification) { + t.Errorf("%q is N/A without an applicability explanation", control) + } + if urlRequiredControls[control] && status == "Met" && !httpsURL.MatchString(justification) { + t.Errorf("%q is Met but lacks required HTTPS evidence URL", control) + } + } + + var unexpected []string + for key := range manifest { + if !strings.HasSuffix(key, "_status") { + continue + } + control := strings.TrimSuffix(key, "_status") + if !want[control] { + unexpected = append(unexpected, control) + } + } + sort.Strings(unexpected) + if len(unexpected) > 0 { + t.Errorf("unexpected non-mandatory status keys: %s", strings.Join(unexpected, ", ")) + } +} + +func TestBestPracticesReleaseHistory(t *testing.T) { + path := filepath.Join(repositoryRoot(t), "CHANGELOG.md") + data, err := os.ReadFile(path) + if err != nil { + t.Fatalf("read CHANGELOG.md: %v", err) + } + content := string(data) + if !regexp.MustCompile(`(?m)^## Unreleased\s*$`).MatchString(content) { + t.Error("CHANGELOG.md must contain a level-two Unreleased heading") + } + for _, tag := range auditedReleaseTags { + heading := regexp.MustCompile(fmt.Sprintf(`(?m)^## \[?%s\]?\s*$`, regexp.QuoteMeta(tag))) + if !heading.MatchString(content) { + t.Errorf("CHANGELOG.md is missing a level-two heading for audited release %s", tag) + } + } +} diff --git a/openspec/changes/archive/2026-07-22-attest-best-practices-passing-controls/.openspec.yaml b/openspec/changes/archive/2026-07-22-attest-best-practices-passing-controls/.openspec.yaml new file mode 100644 index 0000000..7250f8f --- /dev/null +++ b/openspec/changes/archive/2026-07-22-attest-best-practices-passing-controls/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-07-22 diff --git a/openspec/changes/archive/2026-07-22-attest-best-practices-passing-controls/design.md b/openspec/changes/archive/2026-07-22-attest-best-practices-passing-controls/design.md new file mode 100644 index 0000000..ff29503 --- /dev/null +++ b/openspec/changes/archive/2026-07-22-attest-best-practices-passing-controls/design.md @@ -0,0 +1,87 @@ +## Context + +Bestpractices.dev project 13754 currently has 11 mandatory passing controls marked Met, 31 unanswered, and `release_notes` marked Unmet. Repository inspection found evidence for most unanswered controls in the README, generated CLI documentation, contribution and security policies, Git history, GitHub Issues, tests, security workflows, release signing, and scanning configuration. The notable documentation gap is a complete human-readable release history: some historical GitHub releases contain only a generated comparison link, which does not satisfy the criterion by itself. + +A top-level `.bestpractices.json` is recognized by the badge service, but its values are proposals rather than authoritative updates. An authorized project editor must review and save those proposals before the badge state changes. The artifact must therefore be both machine-consumable and independently reviewable, without overstating controls that require private maintainer knowledge. + +## Goals / Non-Goals + +**Goals:** + +- Provide evidence-backed `Met` or justified `N/A` proposals for all 43 mandatory passing controls. +- Close the release-notes and contributor-policy documentation gaps. +- Make incomplete or malformed attestations fail the repository's normal test workflow. +- Preserve a clear manual acceptance and verification step for bestpractices.dev project 13754. +- Keep the live badge state visible after the change merges. + +**Non-Goals:** + +- Pursue Silver or Gold badge controls, or optional Passing `SHOULD` and `SUGGESTED` controls. +- Change efctl's CLI behavior, public interfaces, cryptographic behavior, or runtime dependencies. +- Automate authenticated writes to bestpractices.dev. +- Claim facts about private vulnerability reports without maintainer confirmation. +- Retroactively rewrite Git tags or release artifacts. + +## Decisions + +### Maintain a focused mandatory-control manifest + +The top-level `.bestpractices.json` will contain the current 43 Passing `MUST` control statuses and their evidence, rather than copying the entire project API response. Each status will be `Met` or `N/A`; unknown and unmet values are prohibited. Justifications will point to repository files, workflows, release pages, issue history, or GitHub security features as appropriate. + +Keeping the manifest focused limits drift and avoids making unaudited claims for optional or higher-tier controls. Copying the complete API response was rejected because it includes mutable service metadata and controls outside this change's scope. + +### Treat attestations as claims that require evidence + +Controls observable from the public repository will use direct URLs and concise explanations. Controls involving private facts will use `N/A` or `Met` only after maintainer confirmation. In particular, `vulnerability_report_response` must reflect whether reports were received during the applicable six-month window; if reports exist, their initial-response times must be checked before the answer is selected. + +The implementation will distinguish repository evidence from self-attestation instead of inferring private facts from an empty public advisory list. + +### Add one canonical human-readable release history + +A top-level `CHANGELOG.md` will provide a human-readable entry for every existing SemVer release and an `Unreleased` section for future work. Entries will summarize user-relevant changes rather than merely reproducing commit logs or comparison links. Publicly known runtime vulnerabilities fixed by a release will be identified; where none apply, the attestation will use the criterion's allowed N/A answer with a truthful justification. + +Editing every historical GitHub release was rejected as the primary solution because it is an out-of-band operation that cannot be reviewed in the implementation PR. The existing release workflow may continue generating GitHub release notes, while the changelog remains the repository-owned canonical evidence. + +### Put contributor obligations in contributor-facing documentation + +`CONTRIBUTING.md` will explicitly require tests for new functionality and bug fixes, list the standard unit/integration/E2E and quality commands, and require human-readable release notes for user-visible changes. Existing agent-only instructions and local hooks remain supporting evidence, but contributor-facing policy becomes authoritative. + +### Validate the attestation offline through Go tests + +A repository-level Go test will parse `.bestpractices.json` using the standard library and compare its status keys with a pinned set of the 43 mandatory controls audited for this change. It will reject missing or extra mandatory status keys, invalid statuses, missing paired justifications, unjustified N/A answers, and missing evidence URLs for URL-required controls. It will also verify that every repository SemVer tag represented by the audited release set has a changelog heading. + +The validator will not fetch bestpractices.dev or evidence URLs during tests. Network validation was rejected because it would make normal tests flaky and would not prove authenticated acceptance on the service. The pinned criterion set intentionally turns upstream criterion changes into an explicit repository update rather than silently changing compliance claims. + +### Use existing CI to enforce the invariant + +The validator will run under the existing `go test ./...` CI and pre-commit workflows. Existing CodeQL, gosec, govulncheck, gitleaks, dependency review, and release-signing configuration will be cited as evidence rather than duplicated solely for the badge. CI or release configuration will only be changed if implementation reveals that a proposed `Met` answer is not enforced by the cited mechanism. + +### Keep service acceptance manual and auditable + +Contributor documentation will describe the post-merge sequence: an authorized editor opens project 13754, reviews the repository-proposed values, saves them, and verifies the JSON endpoint and live badge. The README badge will use the service's live badge endpoint, so it accurately reflects pending or passing state without hard-coded success text. + +## Risks / Trade-offs + +- **[Historical release summaries may be incomplete]** → Reconstruct entries from release pages, merged pull requests, and tagged diffs; keep statements concise and factual. +- **[A self-attested private fact may be wrong]** → Require maintainer confirmation for vulnerability-response claims and document the applicable time window. +- **[The upstream mandatory criterion set may change]** → Pin the audited set in tests so drift causes a deliberate maintenance update rather than silent failure. +- **[Evidence URLs on the moving `main` branch can change]** → Prefer stable repository paths for maintained policies and tagged release URLs for historical evidence; validate URL shape offline. +- **[A merged manifest does not itself award the badge]** → Include explicit owner acceptance and post-save verification tasks. +- **[A large changelog adds maintenance cost]** → Use a standard concise format and require entries only for user-visible or security-relevant changes. + +## Migration Plan + +1. Add failing attestation-validation tests that encode the audited mandatory control set and changelog expectations. +2. Add contributor and release-note documentation needed to support the proposed answers. +3. Add `.bestpractices.json` and make the validation tests pass. +4. Run repository tests and all pre-commit hooks. +5. Merge the implementation PR. +6. Have an authorized project editor review and save the proposals on bestpractices.dev. +7. Verify project 13754 reports passing status and the README badge resolves correctly. + +Rollback consists of reverting the repository PR. Any answers already saved on bestpractices.dev must be reviewed separately because reverting the manifest does not automatically revert service state. + +## Open Questions + +- The maintainer must confirm whether any private vulnerability reports were received in the six months preceding submission and, if so, whether every initial response was within 14 days. +- During implementation, release history inspection may identify historical GitHub release descriptions worth correcting out of band, but those edits are not required for the repository PR if `CHANGELOG.md` provides complete human-readable evidence. diff --git a/openspec/changes/archive/2026-07-22-attest-best-practices-passing-controls/proposal.md b/openspec/changes/archive/2026-07-22-attest-best-practices-passing-controls/proposal.md new file mode 100644 index 0000000..38128fd --- /dev/null +++ b/openspec/changes/archive/2026-07-22-attest-best-practices-passing-controls/proposal.md @@ -0,0 +1,30 @@ +## Why + +Efctl's OpenSSF Best Practices assessment currently records only 11 of 43 mandatory passing controls as met, even though the repository already contains evidence for most unanswered controls. The remaining evidence and documentation gaps must be made explicit, reviewable, and continuously validated so project 13754 can earn and retain the passing badge. + +## What Changes + +- Add a repository-owned `.bestpractices.json` manifest that proposes evidence-backed answers for every mandatory passing control. +- Add human-readable release notes covering existing releases and establish release-note expectations for future releases, including treatment of publicly known vulnerabilities. +- Strengthen contributor guidance so new functionality and bug fixes require corresponding automated tests and documented quality checks. +- Add automated validation that the attestation is valid JSON, covers every mandatory passing control, contains no unknown or unmet answers, and justifies N/A answers and URL-required controls. +- Document the post-merge owner review required to accept the repository proposals on bestpractices.dev and verify that project 13754 reaches passing status. +- Add the project badge to the README so its live assessment state is visible. + +## Capabilities + +### New Capabilities +- `best-practices-attestation`: Repository evidence, release-note policy, contributor requirements, validation, and acceptance workflow for maintaining the OpenSSF Best Practices passing badge. + +### Modified Capabilities + +None. + +## Impact + +- Adds `.bestpractices.json` and a human-readable release history such as `CHANGELOG.md`. +- Updates contributor and project documentation, including `CONTRIBUTING.md` and `README.md`. +- Adds repository-level tests or quality-gate configuration for validating the attestation artifact. +- May strengthen CI or release checks where existing practice is not sufficiently enforceable evidence. +- Requires an authorized project owner to review and save the proposed answers for bestpractices.dev project 13754 after merge; the repository file cannot award the badge by itself. +- No user-facing CLI behavior, public API, or Go runtime dependency changes are expected. diff --git a/openspec/changes/archive/2026-07-22-attest-best-practices-passing-controls/specs/best-practices-attestation/spec.md b/openspec/changes/archive/2026-07-22-attest-best-practices-passing-controls/specs/best-practices-attestation/spec.md new file mode 100644 index 0000000..c6205a0 --- /dev/null +++ b/openspec/changes/archive/2026-07-22-attest-best-practices-passing-controls/specs/best-practices-attestation/spec.md @@ -0,0 +1,75 @@ +## ADDED Requirements + +### Requirement: Complete mandatory-control attestation +The repository SHALL contain a top-level `.bestpractices.json` that proposes an answer for every mandatory OpenSSF Best Practices Passing control in the audited 43-control set. Every proposed status SHALL be `Met` or `N/A`; the manifest MUST NOT contain unknown or unmet mandatory-control statuses. + +#### Scenario: All mandatory controls are represented +- **WHEN** the attestation validator reads `.bestpractices.json` +- **THEN** it finds exactly one status entry for each of the 43 audited mandatory Passing controls + +#### Scenario: Incomplete status is rejected +- **WHEN** a mandatory control is missing or has status `?`, `Unknown`, or `Unmet` +- **THEN** repository validation fails and identifies the affected control + +### Requirement: Evidence-backed answers +Every mandatory-control answer SHALL have a concise justification grounded in repository evidence or an explicit maintainer attestation. Controls requiring a URL SHALL include an HTTPS evidence URL, and every `N/A` answer SHALL explain why the criterion does not apply. + +#### Scenario: Publicly observable control is justified +- **WHEN** a control can be verified from repository files, workflows, releases, issues, or security settings +- **THEN** its justification identifies the relevant evidence and includes an HTTPS URL when the criterion requires one + +#### Scenario: N/A answer is justified +- **WHEN** a mandatory control is marked `N/A` +- **THEN** its justification states the factual condition that makes the criterion inapplicable + +#### Scenario: Private vulnerability-response claim is selected +- **WHEN** `vulnerability_report_response` is added to the manifest +- **THEN** its status and justification reflect maintainer-confirmed reports and response times for the applicable six-month window + +### Requirement: Human-readable release history +The repository SHALL maintain a canonical `CHANGELOG.md` with a human-readable summary for every existing SemVer release and an `Unreleased` section for future changes. Release summaries MUST NOT consist only of raw version-control logs or comparison links, and applicable publicly known runtime vulnerabilities SHALL be identified in the relevant release entry. + +#### Scenario: Historical releases are covered +- **WHEN** the release-history validator compares the audited repository tags with `CHANGELOG.md` +- **THEN** every existing SemVer release has a corresponding human-readable changelog section + +#### Scenario: Future user-visible change is proposed +- **WHEN** a contribution changes user-visible behavior or fixes a security issue +- **THEN** contributor policy requires an appropriate entry under `Unreleased` + +#### Scenario: Release fixes a publicly known runtime vulnerability +- **WHEN** a release fixes a project vulnerability that already has a CVE or similar public identifier +- **THEN** the release notes identify that vulnerability + +### Requirement: Contributor test and quality policy +Contributor-facing documentation SHALL require automated tests for new functionality and bug fixes, SHALL identify the standard test and quality commands, and SHALL require all applicable checks to pass before a change is accepted. + +#### Scenario: Contributor adds functionality +- **WHEN** a contributor proposes new or changed production functionality +- **THEN** the documented contribution process requires corresponding automated tests at the appropriate unit, integration, or E2E level + +#### Scenario: Contributor prepares a pull request +- **WHEN** a contributor follows the documented pull-request process +- **THEN** the documentation directs them to run the applicable formatting, warning, security, and test checks + +### Requirement: Offline attestation validation +The repository SHALL provide an automated, network-independent validator for `.bestpractices.json` and its release-history invariants. The validator SHALL run through the existing standard Go test workflow. + +#### Scenario: Valid attestation is tested in CI +- **WHEN** `go test ./...` runs locally or in CI +- **THEN** the attestation and changelog invariants are evaluated without external network access + +#### Scenario: Required evidence is removed +- **WHEN** a mandatory status, justification, required URL, or audited changelog heading is removed or malformed +- **THEN** the standard test workflow fails with an actionable error + +### Requirement: Manual badge acceptance and verification +The repository SHALL document that `.bestpractices.json` supplies proposed answers only and that an authorized project editor must review and save them for bestpractices.dev project 13754. The README SHALL display the service's live project badge rather than a hard-coded passing image or statement. + +#### Scenario: Implementation is merged +- **WHEN** the implementation PR reaches the default branch +- **THEN** the documented process directs an authorized editor to review, save, and verify the proposed answers on bestpractices.dev + +#### Scenario: Badge state changes +- **WHEN** bestpractices.dev updates project 13754 from pending to passing or later changes its status +- **THEN** the README badge reflects the service's current state without a repository content change diff --git a/openspec/changes/archive/2026-07-22-attest-best-practices-passing-controls/tasks.md b/openspec/changes/archive/2026-07-22-attest-best-practices-passing-controls/tasks.md new file mode 100644 index 0000000..5714518 --- /dev/null +++ b/openspec/changes/archive/2026-07-22-attest-best-practices-passing-controls/tasks.md @@ -0,0 +1,32 @@ +## 1. Confirm Evidence Baseline + +- [x] 1.1 Record the audited list of 43 mandatory Passing controls and map each control to its public repository evidence or required maintainer attestation. +- [x] 1.2 Confirm whether private vulnerability reports were received during the applicable six-month window and select an accurate `vulnerability_report_response` status and justification. +- [x] 1.3 Audit every existing SemVer tag and release page to identify the human-readable summary and any publicly known runtime vulnerability fixed by each release. + +## 2. Add Failing Compliance Tests + +- [x] 2.1 Add a failing repository-level Go test that requires `.bestpractices.json`, exactly covers the audited mandatory status keys, permits only `Met` or `N/A`, and requires paired justifications. +- [x] 2.2 Extend the failing test to require HTTPS evidence for URL-required controls and a non-empty applicability explanation for every `N/A` answer. +- [x] 2.3 Add a failing release-history test that requires an `Unreleased` section and a changelog heading for every audited SemVer release. + +## 3. Close Documentation Gaps + +- [x] 3.1 Add `CHANGELOG.md` with concise human-readable summaries for every existing release and an `Unreleased` section for future user-visible and security changes. +- [x] 3.2 Update `CONTRIBUTING.md` to require tests for new functionality and bug fixes and to document the standard formatting, warning, security, unit, integration, and E2E checks. +- [x] 3.3 Document contributor expectations for adding human-readable release notes and identifying applicable publicly known runtime vulnerabilities. +- [x] 3.4 Document the post-merge bestpractices.dev owner workflow, including proposal review, save, project 13754 verification, and rollback considerations. + +## 4. Create the Passing-Control Attestation + +- [x] 4.1 Add top-level `.bestpractices.json` with evidence-backed `Met` or justified `N/A` proposals for all 43 mandatory Passing controls. +- [x] 4.2 Ensure repository-observable claims cite precise maintained-file, workflow, issue, release, tag, or security-feature evidence and that private claims match the maintainer confirmation from task 1.2. +- [x] 4.3 Reconcile any claim that existing repository enforcement cannot support by strengthening the relevant documentation or quality gate, or by correcting the proposed status. +- [x] 4.4 Make the compliance and release-history tests pass without network access. + +## 5. Expose and Verify the Badge + +- [x] 5.1 Add the live bestpractices.dev project 13754 badge to `README.md` without hard-coding a passing state. +- [x] 5.2 Run `go test ./...` and verify the new invariant tests fail clearly when a mandatory status, justification, required URL, or changelog heading is intentionally omitted. +- [x] 5.3 Run all pre-commit hooks and resolve every formatting, lint, security, generated-documentation, and test failure. +- [x] 5.4 Review the implementation diff to confirm it contains no optional Silver/Gold claims, no unverifiable private assertions, and no runtime behavior or dependency changes outside the approved scope. diff --git a/openspec/specs/best-practices-attestation/spec.md b/openspec/specs/best-practices-attestation/spec.md new file mode 100644 index 0000000..c6205a0 --- /dev/null +++ b/openspec/specs/best-practices-attestation/spec.md @@ -0,0 +1,75 @@ +## ADDED Requirements + +### Requirement: Complete mandatory-control attestation +The repository SHALL contain a top-level `.bestpractices.json` that proposes an answer for every mandatory OpenSSF Best Practices Passing control in the audited 43-control set. Every proposed status SHALL be `Met` or `N/A`; the manifest MUST NOT contain unknown or unmet mandatory-control statuses. + +#### Scenario: All mandatory controls are represented +- **WHEN** the attestation validator reads `.bestpractices.json` +- **THEN** it finds exactly one status entry for each of the 43 audited mandatory Passing controls + +#### Scenario: Incomplete status is rejected +- **WHEN** a mandatory control is missing or has status `?`, `Unknown`, or `Unmet` +- **THEN** repository validation fails and identifies the affected control + +### Requirement: Evidence-backed answers +Every mandatory-control answer SHALL have a concise justification grounded in repository evidence or an explicit maintainer attestation. Controls requiring a URL SHALL include an HTTPS evidence URL, and every `N/A` answer SHALL explain why the criterion does not apply. + +#### Scenario: Publicly observable control is justified +- **WHEN** a control can be verified from repository files, workflows, releases, issues, or security settings +- **THEN** its justification identifies the relevant evidence and includes an HTTPS URL when the criterion requires one + +#### Scenario: N/A answer is justified +- **WHEN** a mandatory control is marked `N/A` +- **THEN** its justification states the factual condition that makes the criterion inapplicable + +#### Scenario: Private vulnerability-response claim is selected +- **WHEN** `vulnerability_report_response` is added to the manifest +- **THEN** its status and justification reflect maintainer-confirmed reports and response times for the applicable six-month window + +### Requirement: Human-readable release history +The repository SHALL maintain a canonical `CHANGELOG.md` with a human-readable summary for every existing SemVer release and an `Unreleased` section for future changes. Release summaries MUST NOT consist only of raw version-control logs or comparison links, and applicable publicly known runtime vulnerabilities SHALL be identified in the relevant release entry. + +#### Scenario: Historical releases are covered +- **WHEN** the release-history validator compares the audited repository tags with `CHANGELOG.md` +- **THEN** every existing SemVer release has a corresponding human-readable changelog section + +#### Scenario: Future user-visible change is proposed +- **WHEN** a contribution changes user-visible behavior or fixes a security issue +- **THEN** contributor policy requires an appropriate entry under `Unreleased` + +#### Scenario: Release fixes a publicly known runtime vulnerability +- **WHEN** a release fixes a project vulnerability that already has a CVE or similar public identifier +- **THEN** the release notes identify that vulnerability + +### Requirement: Contributor test and quality policy +Contributor-facing documentation SHALL require automated tests for new functionality and bug fixes, SHALL identify the standard test and quality commands, and SHALL require all applicable checks to pass before a change is accepted. + +#### Scenario: Contributor adds functionality +- **WHEN** a contributor proposes new or changed production functionality +- **THEN** the documented contribution process requires corresponding automated tests at the appropriate unit, integration, or E2E level + +#### Scenario: Contributor prepares a pull request +- **WHEN** a contributor follows the documented pull-request process +- **THEN** the documentation directs them to run the applicable formatting, warning, security, and test checks + +### Requirement: Offline attestation validation +The repository SHALL provide an automated, network-independent validator for `.bestpractices.json` and its release-history invariants. The validator SHALL run through the existing standard Go test workflow. + +#### Scenario: Valid attestation is tested in CI +- **WHEN** `go test ./...` runs locally or in CI +- **THEN** the attestation and changelog invariants are evaluated without external network access + +#### Scenario: Required evidence is removed +- **WHEN** a mandatory status, justification, required URL, or audited changelog heading is removed or malformed +- **THEN** the standard test workflow fails with an actionable error + +### Requirement: Manual badge acceptance and verification +The repository SHALL document that `.bestpractices.json` supplies proposed answers only and that an authorized project editor must review and save them for bestpractices.dev project 13754. The README SHALL display the service's live project badge rather than a hard-coded passing image or statement. + +#### Scenario: Implementation is merged +- **WHEN** the implementation PR reaches the default branch +- **THEN** the documented process directs an authorized editor to review, save, and verify the proposed answers on bestpractices.dev + +#### Scenario: Badge state changes +- **WHEN** bestpractices.dev updates project 13754 from pending to passing or later changes its status +- **THEN** the README badge reflects the service's current state without a repository content change