diff --git a/.bestpractices.json b/.bestpractices.json index 6b803c5..903c55b 100644 --- a/.bestpractices.json +++ b/.bestpractices.json @@ -1,11 +1,38 @@ { - "_comment": "OpenSSF Best Practices answers for the 'passing' tier. The bestpractices.dev BadgeApp reads this file from the repo root (per docs/bestpractices-json.md upstream) when the project is registered there, and uses each _status / _justification pair as the proposed answer. To trigger re-ingestion after edits, the maintainer opens the project's edit page on bestpractices.dev and clicks 'Save (and continue) 🤖'. Status '?' means 'unknown' and is ignored — safe placeholder. .github/workflows/bestpractices.yml lints this file on every push to main so it stays parseable and on-schema. Per the upstream criteria, only the eight criteria with met_url_required=true (contribution, contribution_requirements, license_location, release_notes, report_process, report_archive, vulnerability_report_process, vulnerability_report_private) carry a bare URL in their justification; every other justification is prose only.", + "$schema": "https://bestpractices.coreinfrastructure.org/projects.schema.json", + "_comment": "OpenSSF Best Practices answers for the 'passing' tier. The bestpractices.dev BadgeApp reads this file from the repo root (per docs/bestpractices-json.md upstream) when the project is registered there, and uses each _status / _justification pair as the proposed answer. To trigger re-ingestion after edits, the maintainer opens the project's edit page on bestpractices.dev and clicks 'Save (and continue) 🤖'. Status '?' means 'unknown' and is ignored — safe placeholder. .github/workflows/bestpractices.yml lints this file on every push to main so it stays parseable and on-schema.", + "project_id": 12716, "name": "ctm", "description": "Claude Tmux Manager — survive SSH drops, reattach from your phone.", "homepage_url": "https://github.com/RandomCodeSpace/ctm", "repo_url": "https://github.com/RandomCodeSpace/ctm", "license": "MIT", + "level": "passing", + "badge_url": "https://www.bestpractices.dev/projects/12716/badge", + "project_page_url": "https://www.bestpractices.dev/en/projects/12716", + + "evidence": { + "license_file": "LICENSE", + "contributing_guide": "CONTRIBUTING.md", + "vulnerability_report_process": "SECURITY.md", + "release_notes": "CHANGELOG.md", + "build_reproducible": "Makefile + go build -tags sqlite_fts5 ./...", + "ci_workflow": ".github/workflows/ci.yml", + "release_workflow": ".github/workflows/release.yml", + "code_scanning": ".github/workflows/codeql.yml", + "supply_chain_scorecard": ".github/workflows/scorecard.yml", + "static_analysis_sonar": "sonar-project.properties + SonarCloud quality gate", + "bestpractices_lint": ".github/workflows/bestpractices.yml", + "private_vulnerability_reporting": "GitHub repo setting (security advisories enabled)", + "secret_scanning": "GitHub repo setting (secret_scanning + push_protection enabled)" + }, + + "audit": { + "self_assessment_date": "2026-05-01", + "scorecard_dashboard": "https://scorecard.dev/viewer/?uri=github.com/RandomCodeSpace/ctm", + "sonarcloud_dashboard": "https://sonarcloud.io/summary/overall?id=RandomCodeSpace_ctm" + }, "description_good_status": "Met", "description_good_justification": "README opens with: 'Claude Tmux Manager — survive SSH drops, reattach from your phone.'", @@ -17,7 +44,7 @@ "contribution_justification": "https://github.com/RandomCodeSpace/ctm/blob/main/CONTRIBUTING.md", "contribution_requirements_status": "Met", - "contribution_requirements_justification": "https://github.com/RandomCodeSpace/ctm/blob/main/CONTRIBUTING.md#coding-standards", + "contribution_requirements_justification": "CONTRIBUTING.md documents PR requirements: branch naming, scoped PRs, tests required for new logic, conventional-commit subjects, all checks passing (go vet, go test -race, pnpm tsc --noEmit, pnpm vitest, SonarCloud, CodeQL, OpenSSF Scorecard). https://github.com/RandomCodeSpace/ctm/blob/main/CONTRIBUTING.md#coding-standards", "floss_license_status": "Met", "floss_license_justification": "MIT License.", @@ -28,9 +55,6 @@ "license_location_status": "Met", "license_location_justification": "https://github.com/RandomCodeSpace/ctm/blob/main/LICENSE", - "documentation_basics_status": "Met", - "documentation_basics_justification": "README documents installation, configuration, and primary commands.", - "documentation_interface_status": "Met", "documentation_interface_justification": "README has a Commands section listing every external interface (yolo, safe, attach, kill, list, ctm serve, etc.).", @@ -68,7 +92,7 @@ "version_tags_justification": "Releases are git-tagged.", "release_notes_status": "Met", - "release_notes_justification": "https://github.com/RandomCodeSpace/ctm/releases", + "release_notes_justification": "https://github.com/RandomCodeSpace/ctm/blob/main/CHANGELOG.md", "release_notes_vulns_status": "N/A", "release_notes_vulns_justification": "No publicly disclosed vulnerabilities to date.", diff --git a/.github/workflows/bestpractices.yml b/.github/workflows/bestpractices.yml index 565a9d6..5751af0 100644 --- a/.github/workflows/bestpractices.yml +++ b/.github/workflows/bestpractices.yml @@ -53,7 +53,6 @@ jobs: floss_license floss_license_osi license_location - documentation_basics documentation_interface sites_https discussion @@ -152,9 +151,15 @@ jobs: # 4. unknown criterion keys (likely typos) known = set(criteria) - # tolerate a few additional metadata keys - meta = {"_comment", "name", "description", "homepage_url", "repo_url", - "license", "homepage_url_status", "homepage_url_justification"} + # tolerate a few additional metadata keys. The non-criterion + # fields ($schema, project_id, level, badge_url, + # project_page_url, evidence, audit) mirror the schema used + # by other RandomCodeSpace projects on bestpractices.dev so + # the BadgeApp's auto-ingest reads our intent unambiguously. + meta = {"_comment", "$schema", "name", "description", "homepage_url", + "repo_url", "license", "project_id", "level", "badge_url", + "project_page_url", "evidence", "audit", + "homepage_url_status", "homepage_url_justification"} for k in data: if k in meta: continue diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..58fcb23 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,111 @@ +# Changelog + +All notable changes to **ctm** are documented in this file. + +The format is based on [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html). +Each release is identified by an immutable `vX.Y.Z` git tag. + +## How releases are produced + +Releases are cut by the [`release.yml`](.github/workflows/release.yml) +workflow. On every push to `main` the workflow: + +1. Builds the embedded UI (`make ui`). +2. Runs the full Go test suite under the race detector + (`go test -tags sqlite_fts5 -race ./...`). +3. Cross-compiles `linux-amd64`, `linux-arm64`, `darwin-amd64`, + `darwin-arm64` binaries plus a vendored source tarball. +4. Publishes a GitHub Release with `SHA256SUMS`, conventional-commit + grouped notes, and an air-gapped source archive. + +This in-repo file is the canonical, human-curated history. The +matching GitHub Release page for each `vX.Y.Z` tag carries the +generated notes plus the signed checksums — see +. + +## [Unreleased] + +No unreleased changes. + +## [0.1.0] — 2026-04-18 onwards + +The `v0.1` line is the first stable series. Subsequent `0.1.x` +patches (v0.1.1 through v0.1.18 and ongoing) are non-breaking +hardening and coverage releases — see the GitHub Releases page for +per-patch notes. The line is summarised here by theme: + +### Added + +- OpenSSF Best Practices passing-tier wiring: `.bestpractices.json`, + CI lint workflow, and the live badge in the README pointing at + project [12716](https://www.bestpractices.dev/en/projects/12716). + ([#17], [#18], [#19]) +- OpenSSF Scorecard workflow on every push to `main` plus weekly + schedule, results published at + . + Badge wired in README. ([#16]) +- `CONTRIBUTING.md` and `SECURITY.md` documenting PR conventions, + bug-report flow, and the private vulnerability-reporting process. + +### Changed + +- Sonar maintainability and reliability passes: 256 → 0 outstanding + smells. Mix of in-code fixes and explicit Accept / False Positive + buckets via `.github/workflows/sonar-bulk-accept.yml`. + ([#13], [#14], [#15]) +- Test coverage uplifted past the 85% threshold across Go and + TypeScript: UI Dashboard, hooks, `internal/serve` gaps, + `cmd/yolo` refactor, `cmd/logs` and `cmd/overlay` extras, + and SonarCloud's new-code coverage gate enforced on every PR. + ([#10], [#11], [#12], [#13]) +- CI runs `go test -race` on every PR and release; race-detector + findings fail the build. + +### Fixed + +- Real data-race in test code (`cmd/logs_extra_test.go`) caught by + `-race` in CI: `withFlags` helper's deferred restore raced the + next test's read. Fixed by gating goroutine exit through + `sync.WaitGroup`. + +[#10]: https://github.com/RandomCodeSpace/ctm/pull/10 +[#11]: https://github.com/RandomCodeSpace/ctm/pull/11 +[#12]: https://github.com/RandomCodeSpace/ctm/pull/12 +[#13]: https://github.com/RandomCodeSpace/ctm/pull/13 +[#14]: https://github.com/RandomCodeSpace/ctm/pull/14 +[#15]: https://github.com/RandomCodeSpace/ctm/pull/15 +[#16]: https://github.com/RandomCodeSpace/ctm/pull/16 +[#17]: https://github.com/RandomCodeSpace/ctm/pull/17 +[#18]: https://github.com/RandomCodeSpace/ctm/pull/18 +[#19]: https://github.com/RandomCodeSpace/ctm/pull/19 + +## [0.1.0] — 2026-04-18 + +First stable release. The CLI surface (`yolo`, `safe`, `attach`, +`kill`, `list`, `serve`) and the embedded `ctm serve` HTTP daemon +(V25 status feed, V26 quota tracking, V27 single-user auth via +argon2id + session tokens) are committed. + +### Added + +- Prebuilt cross-compiled binaries (`linux-amd64`, `linux-arm64`, + `darwin-amd64`, `darwin-arm64`) and a vendored air-gapped source + tarball published on every tag. +- `ctm serve` HTTP daemon binding `127.0.0.1` only by default, + with mutation endpoints gated by bearer token + Origin allow-list. + +### Changed + +- README reshaped to promote prebuilt binaries in Quickstart; + Requirements section trimmed. +- Release matrix dropped Windows targets — `syscall.Flock` is + POSIX-only, and Windows users run the Linux binary under WSL. + +## [0.0.1] — 2026-04 (and earlier) + +Pre-stable releases. The `v0.0.x` line covered the initial +prototype (tmux session orchestration, Claude session bridging, +log capture). See the +[GitHub Releases page](https://github.com/RandomCodeSpace/ctm/releases) +for per-patch notes.