diff --git a/.opencode/skills/cleverthis-guidelines/SKILL.md b/.opencode/skills/cleverthis-guidelines/SKILL.md index 70aee795c..7c472911f 100644 --- a/.opencode/skills/cleverthis-guidelines/SKILL.md +++ b/.opencode/skills/cleverthis-guidelines/SKILL.md @@ -11,8 +11,7 @@ description: | be structured, what labels to apply, how triaging works, what security practices apply, how confidentiality levels work, how sprints and DSDM work, how branch names are formed, how CI/CD works, how the TDD bug fix workflow operates with its - exact tag rules, which directory code belongs in, how the v3 vs legacy plan workflow - differs, or any other procedural or regulatory question about working at or + exact tag rules, which directory code belongs in, or any other procedural or regulatory question about working at or contributing to CleverThis. Covers: commit format and quality rules, pull request requirements and merge @@ -117,7 +116,7 @@ npm install -g commitizen@2.8.6 cz-customizable@4.0.0 git cz # interactive commit — replaces git commit # Release (triggers CI release.yml workflow): -git tag v3.6.0 && git push origin v3.6.0 +git tag v1.2.3 && git push origin v1.2.3 ``` --- @@ -589,7 +588,10 @@ Work is DONE only when ALL of the following are true: ├─ DOCUMENTATION │ ├─ Documentation updated alongside code in same commit │ ├─ References use logical module path — never line numbers -│ │ └─ Python example: mypackage.services.plan_service.PlanService.execute +│ │ ├─ Python: mypackage.services.plan_service.PlanService.execute +│ │ ├─ Java: com.example.services.PlanService.execute +│ │ ├─ TypeScript: services/planService.PlanService.execute +│ │ └─ Go: github.com/example/services.(*PlanService).Execute │ ├─ Changelog has one new entry for this commit │ └─ CONTRIBUTORS.md updated if first contribution │ @@ -1185,7 +1187,7 @@ Branch naming conventions (milestone number N is required in prefix): │ │ │ ├─ Chore / refactor / infrastructure / dependency update │ │ └─ feature/mN- (use feature/ prefix) -│ │ e.g. feature/m4-upgrade-langchain +│ │ e.g. feature/m4-upgrade-dependencies │ │ │ └─ Documentation-only change │ └─ feature/mN- @@ -1273,18 +1275,18 @@ Complete task runner guide (this project uses nox — Python): │ └─ Coverage session → verify ≥ 97% (nox -s coverage_report) │ ├─ BEFORE SUBMITTING A PR (additionally run): -│ ├─ Full default suite → ALL sessions (nox) -│ ├─ Security scan session → bandit + semgrep + vulture (nox -s security_scan) -│ ├─ Dead code session → vulture (nox -s dead_code) -│ └─ Integration test session → Robot Framework (nox -s integration_tests) +│ ├─ Full default suite → ALL sessions (nox) +│ ├─ Security scan session → (nox -s security_scan) +│ ├─ Unused code session → (nox -s dead_code) +│ └─ Integration test session → (nox -s integration_tests) │ ├─ SPECIFIC SITUATIONS: │ ├─ Auto-fix formatting: Format session (nox -s format) │ ├─ End-to-end tests: E2E session — needs real credentials (nox -s e2e_tests) │ ├─ Performance benchmarks: Benchmark session (nox -s benchmark) │ ├─ Benchmark regression: Benchmark regression session (nox -s benchmark_regression) -│ ├─ Code complexity analysis: Complexity session — Radon (nox -s complexity) -│ ├─ Build documentation: Docs session — MkDocs (nox -s docs) +│ ├─ Code complexity analysis: Complexity session (nox -s complexity) +│ ├─ Build documentation: Docs session (nox -s docs) │ ├─ Build distributable: Build session (nox -s build) │ └─ Run everything: Full default suite (nox) │ @@ -1620,8 +1622,8 @@ Release process: │ └─ All required CI checks passing on master │ ├─ STEP 2: Create and push the version tag -│ ├─ git tag v3.6.0 (format: v + semantic version number) -│ └─ git push origin v3.6.0 +│ ├─ git tag v1.2.3 (format: v + semantic version number) +│ └─ git push origin v1.2.3 │ ├─ STEP 3: release.yml workflow runs automatically │ ├─ Builds distributable artifact (Python/nox: nox -s build → wheel) @@ -1638,7 +1640,7 @@ Release process: │ └─ VERSION FORMAT ├─ v.. - ├─ e.g. v3.6.0, v3.6.1, v4.0.0 + ├─ e.g. v1.2.0, v1.2.1, v2.0.0 └─ Must follow Clever Semantic Versioning (W3C Semantic Versioning) ``` @@ -1747,7 +1749,7 @@ TDD issue-capture test requirements (detailed tag rules): | MR auto-reports retention | **1 year** | C.O.C. | | CI trigger (ci.yml) | **Push to master/develop; PRs to master/develop*** | CONTRIBUTING.md | | Nightly quality sweep | **Daily midnight UTC** (nightly-quality.yml) | CONTRIBUTING.md | -| Release trigger | **Push v* tag** (e.g. v3.6.0) | CONTRIBUTING.md | +| Release trigger | **Push v* tag** (e.g. v1.2.3) | CONTRIBUTING.md | | Required CI jobs for merge | **lint, typecheck, security, unit_tests, coverage** | CONTRIBUTING.md | | Issue ↔ PR dependency direction | **PR blocks issue; issue depends on PR** | CONTRIBUTING.md | | Epic minimum children | **2 child issues** | CONTRIBUTING.md | diff --git a/.opencode/skills/cleverthis-guidelines/references/project-tools/README.md b/.opencode/skills/cleverthis-guidelines/references/project-tools/README.md index 99f02b782..7cd5e49d6 100644 --- a/.opencode/skills/cleverthis-guidelines/references/project-tools/README.md +++ b/.opencode/skills/cleverthis-guidelines/references/project-tools/README.md @@ -1,125 +1,234 @@ # Project Tooling Guide -## Task Runner: nox +> **Language / tooling note:** This document covers tooling conventions that apply +> to all CleverThis projects. Examples use the **Python/nox** toolchain, which is +> what this specific project uses. Apply the equivalent tools for your language +> ecosystem — the principles are the same regardless of language. -Primary tool for all automated tasks. ALWAYS use nox — never invoke frameworks directly. +--- + +## Principle: Always Use the Task Runner + +Every project designates a **task runner** as the single entry point for all +quality operations — linting, formatting, type checking, testing, coverage, +security scanning, and building. Never invoke these tools directly from the +command line; always go through the task runner. + +| Purpose | Python *(this project)* | JavaScript / TypeScript | Java / Kotlin | Go | +|---------|------------------------|------------------------|---------------|----| +| Task runner | `nox` | `npm run` / `pnpm run` | Gradle / Maven | `make` / `mage` | +| All gates (default) | `nox` | `npm run all` | `./gradlew check` | `make all` | +| Lint | `nox -s lint` | `npm run lint` | `./gradlew checkstyle` | `golangci-lint run` | +| Format | `nox -s format` | `npm run format` | `./gradlew spotlessApply` | `gofmt -w .` | +| Format check (CI) | `nox -s format -- --check` | `npm run format:check` | `./gradlew spotlessCheck` | `gofmt -l .` | +| Type check | `nox -s typecheck` | `npm run typecheck` | `./gradlew compileJava` | built-in | +| Unit tests | `nox -s unit_tests` | `npm run test:unit` | `./gradlew test` | `go test ./...` | +| Integration tests | `nox -s integration_tests` | `npm run test:integration` | `./gradlew integrationTest` | `go test -tags integration` | +| Coverage | `nox -s coverage_report` | `npm run test:coverage` | `./gradlew jacocoTestReport` | `go test -cover ./...` | +| Security scan | `nox -s security_scan` | `npm audit + semgrep` | `./gradlew dependencyCheck` | `gosec ./...` | +| Unused code | `nox -s dead_code` | `ts-prune` / `knip` | `./gradlew findbugs` | `deadcode ./...` | +| Complexity | `nox -s complexity` | `eslint complexity` | `./gradlew pmd` | `gocyclo` | +| Build | `nox -s build` | `npm run build` | `./gradlew build` | `go build ./...` | +| Documentation | `nox -s docs` | `npm run docs` | `./gradlew javadoc` | `godoc` | +| Benchmarks | `nox -s benchmark` | `npm run bench` | `./gradlew jmh` | `go test -bench` | ```bash -# Run all default sessions (full quality gate — must pass before any PR) +# Python/nox — run all default sessions (full quality gate): nox # Individual sessions: -nox -s lint # ruff linting + format check -nox -s format # auto-format code with ruff (use nox -s format -- --check to check only) -nox -s typecheck # Pyright static type checking -nox -s unit_tests # BDD tests with Behave -nox -s integration_tests # Robot Framework via pabot (parallel) +nox -s lint # linting + format check (ruff) +nox -s format # auto-format code (ruff) +nox -s format -- --check # check formatting only — no changes (CI mode) +nox -s typecheck # static type checking (Pyright) +nox -s unit_tests # BDD unit tests (Behave) +nox -s integration_tests # integration tests (Robot Framework via pabot) nox -s coverage_report # generate coverage report (must be ≥ 97%) -nox -s security_scan # bandit + semgrep + vulture security scan -nox -s dead_code # vulture dead code detection -nox -s docs # build documentation with MkDocs -nox -s build # build wheel distribution -nox -s benchmark # run Airspeed Velocity benchmarks +nox -s security_scan # security scan (bandit + semgrep + vulture) +nox -s dead_code # unused code detection (vulture) +nox -s complexity # code complexity analysis (Radon) +nox -s docs # build documentation (MkDocs) +nox -s build # build distributable artifact (wheel) +nox -s benchmark # performance benchmarks (Airspeed Velocity) ``` -If a session is missing from nox configuration: add it BEFORE using it. +If a session is missing from the task runner configuration: **add it before using it**. -## Project Management: Hatch +--- + +## Project Environment and Dependency Management + +Each language ecosystem has a standard way to manage environments and dependencies. +Use the idiomatic tool for your ecosystem — do not improvise with ad-hoc scripts. + +| Language | Environment / package tool | Project manifest | +|----------|---------------------------|-----------------| +| Python *(this project)* | Hatch | `pyproject.toml` | +| JavaScript / TypeScript | npm / pnpm / yarn | `package.json` | +| Java / Kotlin | Gradle / Maven | `build.gradle` / `pom.xml` | +| Go | Go modules (built-in) | `go.mod` | +| Rust | Cargo (built-in) | `Cargo.toml` | ```bash -hatch env create # create project environment -hatch build # build project +# Python/Hatch (this project): +hatch env create # create and populate project environment +hatch build # build the project ``` -All project configuration in pyproject.toml (no Makefiles, no wrapper shell scripts). +**Universal rule:** All project configuration lives in a single project manifest +at the repository root. No Makefiles, no wrapper shell scripts, no ad-hoc aliases. +Every command must be reproducible via the official toolchain without customisation. -## Pre-commit Hooks Setup +--- + +## Pre-commit Hooks + +All projects must install pre-commit hooks that enforce quality automatically +on every commit. **Never bypass hooks with `--no-verify`.** ```bash -scripts/setup-dev.sh # install pre-commit hooks +# This project: +scripts/setup-dev.sh # installs pre-commit hooks + +# General pattern for any project: +pre-commit install # if using the pre-commit framework directly ``` -Hooks run on: format, linting, type checking, security scanning, commit message validation (via Commitizen). -Never bypass with --no-verify. +Hooks enforce: formatting, linting, type checking, security scanning, +and commit message format validation (via Commitizen). + +--- ## Commitizen (Conventional Changelog) +Commitizen validates and guides commit message format. It is language-agnostic +and works for any project since it operates on git commit messages, not source code. + ```bash -# Install: +# Install (works for any language project): npm install -g commitizen@2.8.6 cz-customizable@4.0.0 -# Use (replaces git commit): +# Use (replaces git commit for guided, validated messages): git cz ``` -Configuration: `[tool.commitizen]` in pyproject.toml +Configuration lives in the project manifest (`[tool.commitizen]` in `pyproject.toml` +for Python; a `commitizen` key in `package.json` for Node.js projects). + +--- ## CI/CD Pipeline -CI triggered on: push to branches, pull requests. -Jobs run: all nox default sessions. +CI triggers on push to branches and on pull requests. All task runner default +sessions run as parallel jobs. The `status-check` job consolidates required results +into a single branch-protection gate. To check CI status: -1. Go to PR → checks tab -2. Each job is a separate check -3. `status-check` job provides summary -4. For coverage failures: look for "COVERAGE OK" or "COVERAGE FAILED" line +1. Open the PR → go to the Checks tab +2. Each job appears as a separate named check +3. Click a failed job to view its logs +4. Look for "COVERAGE OK" or "COVERAGE FAILED" in the coverage job output + +--- ## Release Process +A release is triggered by pushing a version tag, which starts the release CI +workflow. The workflow builds the distributable artifact, optionally builds and +pushes a container image, and creates a Forgejo release with artifacts attached. + ```bash # Trigger a release by pushing a version tag: -git tag v3.6.0 -git push origin v3.6.0 +git tag v1.2.3 +git push origin v1.2.3 ``` -The release.yml workflow then: -1. Builds wheel via `nox -s build` -2. Builds Docker image (tagged with version + latest) -3. Pushes Docker image to container registry -4. Creates Forgejo release with wheel attached +This project's `release.yml` workflow: +1. Builds the distributable artifact via the task runner (Python: `nox -s build` → wheel) +2. Builds a container image tagged with the version and `latest` +3. Pushes the container image to the configured registry +4. Creates a Forgejo release with the artifact as a downloadable file -Required repository secrets for releases: -- `CONTAINER_REGISTRY`: Docker registry URL -- `CONTAINER_REGISTRY_USER`: Registry auth username -- `CONTAINER_REGISTRY_PASSWORD`: Registry auth password -- `FORGEJO_TOKEN`: API token for creating releases -- `FORGEJO_URL`: Forgejo instance URL +Required repository secrets: + +| Secret | Purpose | +|--------|---------| +| `CONTAINER_REGISTRY` | Container registry URL | +| `CONTAINER_REGISTRY_USER` | Registry authentication username | +| `CONTAINER_REGISTRY_PASSWORD` | Registry authentication password | +| `FORGEJO_TOKEN` | API token for creating Forgejo releases | +| `FORGEJO_URL` | Forgejo instance URL | + +--- ## Dependency Caching -- CI uses actions/cache@v3 based on pyproject.toml hash -- Caches automatically invalidated when dependencies change +CI jobs cache downloaded packages between runs, keyed on a hash of the project +manifest so caches are automatically invalidated when dependencies change. -## Configuration Files +| Language | Cache key | +|----------|-----------| +| Python | `pyproject.toml` hash | +| Node.js | `package-lock.json` / `pnpm-lock.yaml` hash | +| Java | Gradle user home or `.m2` directory hash | +| Go | Module cache keyed on `go.sum` hash | -- `pyproject.toml`: all project configuration (ruff, pyright, commitizen, coverage, bandit) -- `.pre-commit-config.yaml`: pre-commit hooks -- `noxfile.py`: all nox session definitions -- `robot.cfg`: Robot Framework configuration +--- + +## Project Configuration Files + +Every project has a standard set of root-level configuration files: + +| Purpose | Python *(this project)* | JavaScript | Java | +|---------|------------------------|------------|------| +| Project manifest | `pyproject.toml` | `package.json` | `build.gradle` / `pom.xml` | +| Task runner config | `noxfile.py` | scripts in `package.json` | `build.gradle` | +| Pre-commit hooks | `.pre-commit-config.yaml` | `.pre-commit-config.yaml` | `.pre-commit-config.yaml` | +| Test framework config | `robot.cfg` | `jest.config.js` / `vitest.config.ts` | `src/test/resources/` | +| CI/CD workflows | `.forgejo/workflows/` | `.forgejo/workflows/` | `.forgejo/workflows/` | + +--- ## Development Setup Checklist ```bash -# 1. Clone repository +# 1. Clone the repository git clone cd -# 2. Setup dev environment (installs pre-commit hooks) -scripts/setup-dev.sh +# 2. Set up the dev environment (installs pre-commit hooks) +scripts/setup-dev.sh # this project +# — or for other projects: +pre-commit install # generic pre-commit setup -# 3. Verify everything works -nox +# 3. Verify everything works — run the full task runner suite +nox # Python/nox +# npm run all # Node.js +# ./gradlew check # Java/Gradle +# make all # Go / make-based projects -# 4. Install Commitizen (optional but recommended) +# 4. Install Commitizen (optional but recommended — any language) npm install -g commitizen@2.8.6 cz-customizable@4.0.0 ``` +--- + ## Always Runnable -The project must always be runnable with no local setup: +The repository must always be in a runnable, testable state. On a fresh clone, +a single command must run the full quality suite without any manual setup beyond +the standard environment tool: ```bash -# A single command on freshly cloned repo should run the project -# (typically via containerization) +# Python/nox: +nox + +# Node.js: +npm install && npm run all + +# Java/Gradle: +./gradlew check + +# Go: +go test ./... ``` diff --git a/.opencode/skills/cleverthis-guidelines/references/testing/README.md b/.opencode/skills/cleverthis-guidelines/references/testing/README.md index 0242af0ea..492c404f7 100644 --- a/.opencode/skills/cleverthis-guidelines/references/testing/README.md +++ b/.opencode/skills/cleverthis-guidelines/references/testing/README.md @@ -24,7 +24,7 @@ - Step definitions grouped by feature (name step file after feature) - Add to existing step files before creating new ones - Never commit placeholder steps (all steps must be implemented) -- Never use stub/pass implementations in step definitions +- Never use empty/stub implementations in step definitions (no no-op bodies) - Run via task runner: `nox -s unit_tests` ---