DEVELOPMENT.md (6559B)
1 # Development 2 3 For general usage, installation, and configuration, see the [README](README.md). 4 5 ## Dev Setup 6 7 ### On your host machine 8 9 Ensure you have [uv](https://docs.astral.sh/uv/getting-started/installation/) installed, and that you have the correct env variables set to run Vet (Vet defaults to Anthropic models so this means you should have your ANTHROPIC_API_KEY set). 10 11 Then run: 12 13 ```bash 14 uv run vet 15 ``` 16 17 ### Containerized 18 19 You can use the `Containerfile` in `dev/` at the repo root to create a container that suffices to run Vet for development purposes. 20 21 #### Setup 22 23 Create a `.env` file at the repo root with your API keys. The recommended keys are `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, and `CODEX_API_KEY`. 24 25 To include Claude Code in the image add: 26 27 ``` 28 I_CHOOSE_CONVENIENCE_OVER_FREEDOM=true 29 ``` 30 31 Without this Claude Code will not be installed in the image. 32 33 #### Running Vet in a Container 34 35 ```bash 36 ./dev/vet.sh --list-models 37 ./dev/vet.sh "check for bugs" --base-commit main 38 ./dev/vet.sh --base-commit main --agentic --agent-harness codex 39 ./dev/vet.sh --base-commit main --agentic --agent-harness claude # requires I_CHOOSE_CONVENIENCE_OVER_FREEDOM=true 40 ./dev/vet.sh --base-commit main --agentic --agent-harness opencode 41 ``` 42 43 The image is built automatically on each run. This process should be fast due to layer caching. 44 45 #### Interactive Development 46 47 ```bash 48 ./dev/run.sh 49 ``` 50 51 Starts an interactive shell in the container. The repo is bind-mounted at `/app`. 52 53 ## Formatting Hooks 54 55 Install pre-commit hooks once per clone: 56 57 ```bash 58 uvx pre-commit install 59 ``` 60 61 Run formatting hooks manually across the repo: 62 63 ```bash 64 uvx pre-commit run --all-files 65 ``` 66 67 After installation, `isort` and `black` run automatically on staged Python files before each commit. 68 69 ## Running Tests 70 71 ### Unit tests 72 73 All unit tests are run with: 74 75 ```bash 76 uv run pytest 77 ``` 78 79 This command should be preserved the sole way to run unit tests. 80 81 ## Concepts 82 83 ### Issue identifiers 84 85 Issue identifiers are pieces of logic capable of finding issues in code. We foresee two basic kinds of those: 86 87 1. File-checking ones. 88 - To check for "objective" issues in existing files. 89 2. Commit-checking ones. 90 - To check for the quality of a single commit. 91 - "Assuming that we can treat the commit message as a requirement, how well does the commit implement it?" 92 93 By default, `vet` runs all the registered issue identifiers and outputs all the found issues on the standard output in JSON format. 94 95 #### Adding new Issue Identifiers 96 97 If you want to add a new issue identifier, you need to: 98 99 1. Implement the `IssueIdentifier` protocol from `vet.imbue_tools.repo_utils.data_types`. 100 2. Register the new issue identifier by adding it to `IDENTIFIERS` in `vet.issue_identifiers.registry`. 101 102 Based on your needs, instead of the above, you can also extend one of the existing batched zero-shot issue identifiers: 103 - `vet/issue_identifiers/batched_commit_check.py` 104 (for commit checking) 105 In that case you would simply expand the rubric in the prompt. That is actually the preferred way to catch issues at the moment due to efficiency. 106 Refer to the source code for more details. 107 108 ### Model registry 109 110 The `registry/models.json` file contains model definitions distributed via the `--update-models` CLI option. See [`registry/CONTRIBUTING.md`](registry/CONTRIBUTING.md) for expectations about what models should be added to the registry. 111 112 ## CI / CD 113 114 ### GitHub Actions naming conventions 115 116 Workflows follow a consistent naming scheme across three layers: 117 118 - **File name**: `<verb>-<target>.yml` (e.g. `test-unit.yml`) 119 - **Display name** (`name:`): `<Verb> / <Target>` (e.g. `Test / Unit`) 120 - **Job name**: short target identifier (e.g. `unit`) 121 122 The `/` in display names creates visual grouping in the GitHub Actions UI. Group related workflows under a shared prefix (e.g. `Test /`, `Publish /`). Standalone workflows (e.g. `Vet`) don't need a prefix. 123 124 Current workflows: 125 126 - `test-unit.yml` (`Test / Unit`, job: `unit`) — pytest suite (lint + unit tests) 127 - `test-pkgbuild.yml` (`Test / PKGBUILD`, job: `pkgbuild`) — Arch Linux package build + smoke test 128 - `vet.yml` (`Vet`, job: `vet`) — Self-review via vet on PRs (uses the reusable action via `uses: ./`) 129 - `vet-agentic.yml` (`Vet (Agentic)`, job: `vet`) — Agentic self-review via vet on PRs (uses the reusable action via `uses: ./`) 130 - `publish-pypi.yml` (`Publish / PyPI`, job: `pypi`) — Build and publish to PyPI on tag push 131 - `publish-github-release.yml` (`Publish / GitHub Release`, job: `github-release`) — Create a GitHub Release on tag push 132 133 ### Continuous Deployment 134 135 Vet is published to PyPI via the `publish-pypi.yml` GitHub Actions workflow. Deployment is triggered by pushing a git tag that starts with `v` (e.g. `v0.2.0`). 136 137 ### Releasing a new version 138 139 1. Create and checkout a branch to bump the version, using the naming convention `{name}/v{version}` (e.g. `john/v0.2.0`) 140 2. Update the version in `pyproject.toml` 141 3. Update `pkgver` in `pkg/arch/PKGBUILD` 142 4. Commit and push the changes 143 5. Tag the commit and push the tag: 144 ```bash 145 git tag v0.2.0 -m "v0.2.0: Updated XYZ" 146 git push origin v0.2.0 147 ``` 148 6. Create a PR for the new branch 149 7. The `Publish / PyPI` workflow will automatically build and publish the package 150 8. Merge PR into main. 151 152 ## Development Notes 153 154 ### Logging 155 156 When creating a new entry point into vet, you must call `configure_logging(verbose: int, log_file: Path | None)` from `vet.cli.main`. 157 158 User-facing status messages (top-level lifecycle, warnings visible to the user) use `print(..., file=sys.stderr)` directly — not loguru. Loguru is for internal diagnostics only. 159 160 Log level heuristics: 161 162 - **TRACE** - API payloads, token counts, dollar costs, agent subprocess messages. 163 - **DEBUG** - Everything internal: API exceptions before re-raise, retries, fallbacks, identifier selection, history loading, context assembly. All LLM provider exception handlers must log at DEBUG before raising (see `_openai_exception_manager` for the pattern). 164 - **WARNING** - Degraded conditions: LLM content blocked/flagged, unrecognized config values, malformed user data. Note: spend limit warnings also `print()` directly to stderr so they are always visible to the user. 165 - **ERROR** - Failures that prevent producing results. Use `log_exception()` from `vet.imbue_core.async_monkey_patches` for tracebacks. 166 167 ### README links 168 169 The README is rendered on PyPI which does not resolve relative links that otherwise work on GitHub. Always use full URLs when linking to resources from the README.