From 794d5279a7d7b7d259768825484690daba4b6e7e Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Sun, 26 Apr 2026 04:51:25 +0000 Subject: [PATCH] chore(RAN-54): add CONTRIBUTING.md + retarget 4 _url fields to conventional paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bestpractices.dev autofill audit follow-up (board comment 0988aa47 on RAN-54). The board re-listed four MUST/SHOULD criteria still flagged on the project page despite `_status: Met` in our JSON. Root cause: the autofill bot detects evidence by *conventional path*, not by the _url field — and our URLs pointed at non-conventional locations (docs/README.md as an index, shared/runbooks/engineering-standards.md as the contribution doc, /issues for report_process). Sibling otelcontext (the closest single-product MIT analog) uses the conventional pattern and the autofill flips them all to Met automatically. Added: - CONTRIBUTING.md Conventional path the autofill bot detects. §Reporting (Issues + SECURITY.md), §Development workflow (Conventional Commits, signed commits, auto-merge), §What every PR must pass (8-row CI gate matrix with local commands), §Coding standards (delegates the full bar to shared/runbooks/engineering-standards.md). Retargeted in .bestpractices.json (status was already Met for all four): - contribution_url engineering-standards.md -> CONTRIBUTING.md - contribution_requirements_url engineering-standards.md -> CONTRIBUTING.md - documentation_basics_url docs/README.md (index) -> README.md (the docs) - report_process_url /issues -> SECURITY.md (matches the otelcontext recipe; SECURITY.md links to /issues for non-security bugs and is the conventional location autofill detects) - release_notes_url unchanged (CHANGELOG.md is the right answer — no tagged releases yet, no /releases endpoint to point at) Justifications refreshed to cite the new URL targets without changing the factual claim. After this lands the autofill rescan should flip the four flagged criteria to Met on bestpractices.dev. Per the Bestpractices board-approval gate RAN-54 stays in_review — board flips the badge to passing and posts @TechLead approved. Verified locally: JSON parses (152 top-level keys, 67 _status keys, 0 remaining `?`), no script changes (Test-SnipIT.ps1 84/84 unaffected, PSScriptAnalyzer 0 errors unaffected). Co-Authored-By: Paperclip --- .bestpractices.json | 16 +++++------ CONTRIBUTING.md | 67 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/.bestpractices.json b/.bestpractices.json index 2d5bc1b..4dd7fe5 100644 --- a/.bestpractices.json +++ b/.bestpractices.json @@ -16,12 +16,12 @@ "interact_justification": "README.md provides Install (clone + dot-source), Usage (CLI invocation + hotkeys), and Tests sections covering download, use, and contribution paths. Issue tracker at https://github.com/RandomCodeSpace/snipIT/issues is linked from the GitHub repo header.", "contribution_status": "Met", - "contribution_justification": "shared/runbooks/engineering-standards.md is the contribution-process document — it codifies branch/commit/PR rules (§3), testing tiers (§4), code style (§2), and quality gates (§1) that contributors must satisfy. SECURITY.md covers the vulnerability-report contribution path. README.md links to engineering-standards from §Engineering standards.", - "contribution_url": "https://github.com/RandomCodeSpace/snipIT/blob/main/shared/runbooks/engineering-standards.md", + "contribution_justification": "CONTRIBUTING.md at repo root is the contribution-process entry point: reporting (GitHub Issues for bugs, SECURITY.md for vulnerabilities), development workflow (fork → topic branch → Conventional Commits → signed commits via scripts/setup-git-signed.sh → PR → auto-merge on green CI), CI gate matrix with local commands, coding standards, reviewer expectations, documentation expectations. CONTRIBUTING.md delegates the full quality bar to shared/runbooks/engineering-standards.md (PowerShell variant of the company-canonical runbook).", + "contribution_url": "https://github.com/RandomCodeSpace/snipIT/blob/main/CONTRIBUTING.md", "contribution_requirements_status": "Met", - "contribution_requirements_justification": "Contribution requirements (signed commits via scripts/setup-git-signed.sh, squash-merge only, all CI gates green, PSScriptAnalyzer Error-severity zero, Trivy/Semgrep/Gitleaks/jscpd zero findings, Test-SnipIT.ps1 passing on Linux + Windows runners) are codified in shared/runbooks/engineering-standards.md §1 (Quality gates) and §3 (Branch, commit, PR rules). No standalone CONTRIBUTING.md — engineering-standards.md is the canonical contribution-requirements document.", - "contribution_requirements_url": "https://github.com/RandomCodeSpace/snipIT/blob/main/shared/runbooks/engineering-standards.md", + "contribution_requirements_justification": "CONTRIBUTING.md at repo root documents acceptable contributions: §What every PR must pass tabulates the 8 CI gates (headless tests, Windows AST parse, PSScriptAnalyzer Error-severity 0, Trivy HIGH/CRITICAL 0, Semgrep ERROR 0, Gitleaks 0, jscpd <3%, SBOM artifact) with the local commands to run each. §Coding standards covers the load-bearing rules (PowerShell 7.5+ only, Verb-Noun PascalCase, [CmdletBinding()] + param() for >1-arg functions, pure-logic functions in Core region for headless coverage, named-closure event-handler pattern, single-file deliverable invariant). The full quality bar — branch / commit / PR rules, security tooling, performance targets — is the contents of shared/runbooks/engineering-standards.md, which CONTRIBUTING.md links as the SSoT.", + "contribution_requirements_url": "https://github.com/RandomCodeSpace/snipIT/blob/main/CONTRIBUTING.md", "floss_license_status": "Met", "floss_license_justification": "MIT license — see /LICENSE at repo root. MIT is OSI-approved and FSF-recognized FLOSS; permits use, modification, and redistribution including commercial. Copyright holder: Amit Kumar.", @@ -34,8 +34,8 @@ "license_location_url": "https://github.com/RandomCodeSpace/snipIT/blob/main/LICENSE", "documentation_basics_status": "Met", - "documentation_basics_justification": "Documentation basics cover three surfaces: (1) README.md at repo root — install (clone + run), usage, hotkeys (global + preview-window), output paths, system integration, architecture overview. (2) docs/README.md — a docs/ index pointing to long-form material (current entry: docs/mockups/preview-redesign.html design mock; plus links back to README, CLAUDE, SECURITY, the engineering-standards runbook, CHANGELOG, and .bestpractices.json). (3) CLAUDE.md — agent/developer brief with build/test/run commands, conventions, gotchas, and the OpenSSF Scorecard baseline + target. Conventional discoverability path (root README → docs/ → docs/README.md) is satisfied.", - "documentation_basics_url": "https://github.com/RandomCodeSpace/snipIT/blob/main/docs/README.md", + "documentation_basics_justification": "README.md at repo root IS the basic documentation for the software: §Features (capture, preview window, annotations, output, system integration), §Hotkeys (global + preview window), §Install (3-step clone + run, no admin, what first-launch does), §Usage (annotation flow, zoom, copy/save, new snip), §Architecture (single-file region layout + 10 pure Core functions + preview-window internals), §Tests (84 headless + 42 interactive), §Project files. Long-form material (design mocks, ADR-style notes) lives under docs/ with docs/README.md as the index pointing back to README/CLAUDE/SECURITY/engineering-standards/CHANGELOG. CLAUDE.md provides the agent/developer brief with build/test/run, conventions, gotchas, and the OpenSSF Scorecard baseline + target.", + "documentation_basics_url": "https://github.com/RandomCodeSpace/snipIT/blob/main/README.md", "documentation_interface_status": "Met", "documentation_interface_justification": "snipIT's interface is the global hotkeys, system-tray widget, and preview-window editor — all documented under README.md §Hotkeys (Global + Preview window) and §Usage. There is no programmatic API surface; the .ps1 is invoked directly.", @@ -83,8 +83,8 @@ "release_notes_vulns_justification": "CHANGELOG.md reserves a dedicated `### Security` subsection inside every release entry (and the `[Unreleased]` working set) for non-trivial security fixes. The header text states explicitly: 'Each release MUST list any non-trivial security fixes under a dedicated Security subsection so downstream consumers can decide whether to upgrade.' Zero fixes to date — the current `[Unreleased]` Security subsection is honestly marked 'No security-relevant fixes shipped yet under this release line.' When a fix ships, the entry will reference the GHSA advisory + CVE per SECURITY.md §What you can expect.", "report_process_status": "Met", - "report_process_justification": "Bug-reporting process documented in README.md and the GitHub Issues tracker (https://github.com/RandomCodeSpace/snipIT/issues). Vulnerability-reporting process documented in SECURITY.md §Reporting a vulnerability (private GHSA advisory + email).", - "report_process_url": "https://github.com/RandomCodeSpace/snipIT/issues", + "report_process_justification": "SECURITY.md §Reporting a vulnerability documents the private channel for security issues (GitHub private vulnerability report at /security/advisories/new, or `ak.nitrr13@gmail.com` with `[snipIT security]` subject; 72-hour ack SLA, 7-day triage, 90-day coordinated disclosure). CONTRIBUTING.md §Reporting documents the public channel for functional bugs and feature requests — GitHub Issues at https://github.com/RandomCodeSpace/snipIT/issues. Both channels are linked from README.md.", + "report_process_url": "https://github.com/RandomCodeSpace/snipIT/blob/main/SECURITY.md", "report_tracker_status": "Met", "report_tracker_justification": "GitHub Issues at https://github.com/RandomCodeSpace/snipIT/issues serves as the public, threaded, searchable issue tracker for bug reports and enhancement requests.", diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..6723b0d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,67 @@ +# Contributing to snipIT + +Thanks for considering a contribution. snipIT is a single-script PowerShell 7.5+ tool on .NET 9 — the deliverable is `SnipIT.ps1`. There is no compile step; `git clone` + `pwsh -Sta -File .\SnipIT.ps1` is the install path. + +## Reporting + +- **Functional bugs and feature requests** — open a [GitHub Issue](https://github.com/RandomCodeSpace/snipIT/issues). Include your Windows + PowerShell + .NET versions and the shortest repro you can produce. +- **Security vulnerabilities** — do **not** open a public issue. Use the private channel documented in [`SECURITY.md`](SECURITY.md): a [GitHub private vulnerability report](https://github.com/RandomCodeSpace/snipIT/security/advisories/new) or `ak.nitrr13@gmail.com` with `[snipIT security]` in the subject. Disclosure SLA + scope are listed there. + +## Development workflow + +1. Fork and create a topic branch off `main` (e.g. `feat/window-shadow` or `fix/dpi-on-mixed-displays`). +2. Make focused, atomic commits in [Conventional Commits](https://www.conventionalcommits.org/) style (`feat:`, `fix:`, `refactor:`, `chore:`, `docs:`, `test:`, `ci:`, `perf:`). +3. Sign every commit. Run `scripts/setup-git-signed.sh` once per worktree to apply repo-local signing config (SSH / OpenPGP / x509). Branch protection on `main` rejects unsigned commits. +4. Open a PR against `main`. Auto-merge fires when CI is green; no human merge button on the happy path. + +`main` is the only protected branch. Direct pushes are blocked; squash-merge is the only allowed merge style; linear history is required. + +## What every PR must pass + +CI gates every PR on the following — please run them locally before requesting review. Each gate has zero tolerance: + +| Gate | Local command | Where it lives | +|---|---|---| +| Headless tests | `pwsh -NoProfile -File ./Test-SnipIT.ps1` (84/84 must pass) | `.github/workflows/test.yml` | +| Windows AST parse | `pwsh -NoProfile -Command "[System.Management.Automation.Language.Parser]::ParseFile((Resolve-Path ./SnipIT.ps1), [ref]\$null, [ref]\$errors)"` | `.github/workflows/test.yml` | +| **PSScriptAnalyzer** (PowerShell lint) | `pwsh -c "Invoke-ScriptAnalyzer -Path ./SnipIT.ps1 -Severity Error"` (0 errors) | `.github/workflows/security.yml` | +| Trivy filesystem scan | (CI only) | `.github/workflows/security.yml` | +| Semgrep SAST (`p/security-audit`, `p/owasp-top-ten`) | (CI only) | `.github/workflows/security.yml` | +| Gitleaks (full git history) | (CI only) | `.github/workflows/security.yml` | +| jscpd duplication < 3% (powershell, `--min-tokens 100`) | (CI only) | `.github/workflows/security.yml` | +| SBOM (SPDX + CycloneDX) | (CI only — surface only) | `.github/workflows/security.yml` | + +## Coding standards (acceptable contributions) + +The full quality bar — quality gates, code style, branch/commit/PR rules, security tooling, performance targets — is codified in [`shared/runbooks/engineering-standards.md`](shared/runbooks/engineering-standards.md), the PowerShell variant of the company-canonical runbook. Treat that file as the single source of truth for what is acceptable in this repo. The most load-bearing rules: + +- **PowerShell 7.5+ only.** No PS5.1 fallbacks, no `Add-Type` shims that only compile on Windows PowerShell. +- **Functions: `Verb-Noun` PascalCase**, [approved verbs](https://learn.microsoft.com/powershell/scripting/developer/cmdlet/approved-verbs-for-windows-powershell-commands), `[CmdletBinding()]` + `param()` for any function with > 1 parameter. +- **Pure-logic functions go in the `Core` region** of `SnipIT.ps1` so the headless test suite picks them up via `-CoreOnly`. +- **Preview-window event handlers are one-line wrappers** around named closures captured at window-creation time (e.g. `$beginPan`, `$pickColor`, `$handleMouseDown`) — keeps the test harness able to drive every code path through the closures via `-TestAction`. +- **Tests are zero-dependency** (no Pester). Follow the assertion pattern in `Test-SnipIT.ps1`. +- **Single-file deliverable is a headline product feature.** Do not propose splitting `SnipIT.ps1` into modules without an explicit board reversal. + +## What you'll need + +- Windows 11 + PowerShell 7.5+ for full interactive testing (`Test-SnipIT-Interactive.ps1`). +- Any pwsh 7.5+ host (Linux / macOS work) for headless tests. +- A signed-commit setup. `scripts/setup-git-signed.sh` does the repo-local config; the script auto-detects ssh / openpgp / x509 from your global git config. + +## Reviewing + +A PR lands when: + +1. All CI gates above are green (the protection rule on `main` enforces eight required check contexts). +2. Codex / TechLead review pass shows no HIGH-severity findings. +3. The squash commit is signed (GitHub web-flow signing handles this automatically on merge). + +For larger changes (new region in `SnipIT.ps1`, new top-level function group, new workflow file), open a brief proposal as a GitHub Issue first so we can align on shape before you sink hours into the PR. + +## Documentation + +- Update [`CHANGELOG.md`](CHANGELOG.md) `[Unreleased]` section with an entry under **Added** / **Changed** / **Fixed** / **Security** as appropriate. +- If your PR changes how to build/test/run, conventions, gotchas, or introduces a new dependency, also update [`CLAUDE.md`](CLAUDE.md). It is the agent / contributor brief read at session start. +- Long-form docs go under [`docs/`](docs/README.md). + +Thanks again — the project is small, the test suite is fast, and your PR will get a reply quickly.