diff --git a/.agents/skills/prepare-patch-release/SKILL.md b/.agents/skills/prepare-patch-release/SKILL.md new file mode 100644 index 0000000000..da9bd3a04e --- /dev/null +++ b/.agents/skills/prepare-patch-release/SKILL.md @@ -0,0 +1,103 @@ +--- +name: prepare-patch-release +description: Do all the tasks needed for a patch release of the project.argument-hint: [new-version] +--- + +Do all the tasks needed for a patch release of the project. These patch +releases generally happen on the first day of every month. + +Arguments: `$ARGUMENTS` +- First argument (optional): the version of the upcoming release we are +preparing. If omitted, find the most recent tag on this branch, and the +new version will update the third portion of the version. It might be +either a version number (like `3.1.4.0`) or a tag (like `v3.1.4.0`). + +Hint: The numeric "version" is a four-part numeric deignation with the pattern +`MAJOR.MINOR.PATCH.TWEAK`. The "version tag" is usually the numeric version +with a "v" prepended, for example, `v3.1.4.0`. + +## Steps and Checklist + +- [ ] Determine the version of the new release. +- [ ] Update the main @CMakeLists.txt. +- [ ] Use the "release-notes-update" skill to update @CHANGES.md. +- [ ] Review the release notes to ensure that the changes do not deprecate any + API calls or break API or ABI backward-compatibility, or remove support + for any dependency or toolchain versions. If you think these rules are + being violated, ask for confirmation. +- [ ] Review @README.md for changes. +- [ ] Review @INSTALL.md for changes. +- [ ] Review @CREDITS.md for changes. +- [ ] Review @SECURITY.md for changes. + +## Steps to determine the versions of the last and new releases. + +1. **Determine the previous tag** if not provided by looking at the + most recent git tag in the current branch, and deducing the 4-part + version number from that. +2. The assumed new version for a patch release has the same major and minor + numbers, the patch number is incremented by one since the last tag, and the + tweak number is "0". +3. If no optional version was present in the arguments, use the assumed new + version. +4. If a version was supplied in the arguments, double check that it differs + from the last tag as explained above. If it does not, ask for verification + that the version requested is correct before proceeding. + +## Steps to update CMakeLists.txt + +1. In the main @CMakeLists.txt, alter the version to that of the new release, + if it isn't already the same. +2. For a patch release, ensure that `${PROJECT_NAME}_SUPPORTED_RELEASE` should + be set to ON. In main (not yet a supported release) it shold be OFF. If you + find these to not be as expected, ask for confirmation of whether to fix. +3. For a patch release, `PROJECT_VERSEION_RELEASE_TYPE` should be set to empty + (""). In main, it will typically be "dev", "beta", or other designations. + If you find these to not be as expected, ask for confirmation of whether to + fix. + +## Reviewing README.md + +If this release added support for any new image file formats, be sure that +README.md mentions them in its list of image formats supported. + +## Reviewing INSTALL.md + +If any of the new commits (as described in the release notes for this version) +appear to add dependencies, or add support for new versions of dependencies, +be sure that INSTALL.md is updated to include that dependency (if not already +listed among the required and optional dependencies), and reflects the latest +version that we claim to support. + +Double check @externalpackages.cmake and ensure that any minimum required +versions of dependencies that cmake will enforce match the oldest versions +of those dependencies as documentd in INSTALL.md. + +## Reviewing CREDITS.md + +The @CREDITS.md file lists all known contributors to the project, sorted alpha +by first name. In cases where an author's actual name is unknown, we use the +GitHub userid. + +Ensure that any authors referenced in the new release notes for the version we +are releasing are inserted in the credit list, if they are not already +present. You don't need to check older versions, we presume those have already +been included. + +## Reviewing SECURITY.md + +The @SECURITY.md file lists which versions are currently supported at what +levels, and lists all previously-fixed SVE's or security advisories. Be sure +to check this file in older branches (the last two releases, say), and if you +are preparing a patch release, also check in main and more recent (higher +numbered) releases for more recently modified SECURITY.md, and be sure that +this branch gets amended with any information that seems to have been updated +more recently in those other branches. Check whichever is newer of the local +and remote copy of that branch, since the local one may have had release notes +or its version in CMakeLists.txt updated, but not yet pushed to GitHub. + + +## Reference + +- Full release procedures: `docs/dev/RELEASING.md` +- Steps for updating release notes: `release-notes-update/SKILL.md` diff --git a/.agents/skills/release-notes-update/SKILL.md b/.agents/skills/release-notes-update/SKILL.md new file mode 100644 index 0000000000..ab8fcf2b30 --- /dev/null +++ b/.agents/skills/release-notes-update/SKILL.md @@ -0,0 +1,232 @@ +--- +name: release-notes-update +description: Generate or update release notes for a patch, minor, or major release, or just to update main. Run git-cliff, organize and edit the output per project conventions, and insert into CHANGES.md. +argument-hint: [patch|minor|major|main] [prev-tag] +--- + +Generate release notes for an OpenImageIO release. + +Arguments: `$ARGUMENTS` +- First argument (optional): release type — `patch` (default), `minor`, `major`, or `main`. +- Second argument (optional): previous release tag (e.g. `v3.1.2.0`). If omitted, find the most recent tag automatically. If the release type is `main`, instead of a tag, look for the last commit at which the CHANGES.md file was updated. + +## Steps + +1. **Determine the previous tag** if not provided: + ``` + git describe --tags --abbrev=0 + ``` + or look at recent tags: `git tag --sort=-version:refname | head -10`. + However, if the "release type" is `main`, instead of a tag, just find + the commit at which CHANGES.md was last updated. + +2. **Run git-cliff** to get raw commit data: + ``` + git cliff -c src/doc/cliff.toml ..HEAD > /tmp/cliff-out.md + ``` + Read `/tmp/cliff-out.md` to see the raw output. + +3. **Read CHANGES.md** to see the current top of the file and understand where to insert. + +4. **Format the release notes** according to the release type: + +### For patch releases: + +Follow the skeleton in `docs/dev/Changes-skeleton-patch.md`: + +``` +Release X.Y.Z.W (Month DD, YYYY) -- compared to X.Y.Z.W-1 +--------------------------------------------------------- +- *category*: Description. [#NNNN](https://github.com/AcademySoftwareFoundation/OpenImageIO/pull/NNNN) (by author) +``` + +Rules: +- **Remove** the section headings git-cliff generates; patch notes are a flat + list. +- **Add conventional commit prefixes** to any "uncategorized" entries (those + lacking a `feat:`, `fix:`, etc. prefix). +- **Reorder** entries logically: feature enhancements first, then bug fixes, + then build/CI fixes, then internal changes, then test improvements, then + docs/admin. +- **Omit** entries that are purely internal and too minor to matter to users. + Ask for confirmation about entries you propose to omit. +- Prefer to use author's actual name if known. If the name cannot be found, + the GitHub userid can be used instead. +- Omit the author if it is the project leader, Larry Gritz, unless he is not + the dominant author (at least 75% of commits) in this release. +- Keep entries to one line each. Be terse but informative. +- Use the format `*subsystem*:` for the category prefix (e.g., image file + format like `*exr*:`, utility like `*oiiotool*:`, class or API category like + `*IBA*:`, or topic category such as `*build*:`, `*ci*:`, `*docs*:`). +- We aim to make patch releases on the first day of each month. If we are + within a few days of a month end, list the date as the beginning of the + upcoming month. Ask for confirmation that this is the planned release date. + + +### For minor or major releases: + +Follow the skeleton in `docs/dev/Changes-skeleton-major.md`. Sections: + +``` +Release X.Y.0.0 (Month, YYYY) -- compared to X.Y-1 +-------------------------------------------------- + +### New minimum dependencies and compatibility changes: +### ⛰️ Major new features and public API changes: + * *New image file format support:* + * *oiiotool new features and major improvements*: + * *Command line utilities*: + * *API changes* + * Other notable new feature: +### 🚀 Performance improvements: +### 🐛 Fixes and feature enhancements: +### 🔧 Internals and developer goodies +### 🏗 Build/test/CI and platform ports: + * CMake build system and scripts: + * Dependency and platform support: + * Testing and Continuous integration (CI) systems: +### 📚 Notable documentation changes: +### 🏢 Project Administration +### 🤝 Contributors +``` + +Note that the section outline may already be present, in which case you +only need to fit items into the existing category outline. + +Rules: +- Group commits into sections; within each section, cluster related items together. +- When needed, expand terse one-liners into enough prose that users understand what changed and why it matters. +- For `feat:` commits, make sure the feature is explained sufficiently — don't just copy the commit subject. +- For `api:` or `api!:` commits, clearly call out what changed in the public API. +- Include PR links and author attribution for every entry. +- The notes should "tell the story" of the release, not just be a dump of commit subjects. +- We aim to make major/minor releases approximately in October 1 of each year. If the anticipted release date is already in the file, don't change it. If it is not present, ask for confirmation of the planned release date. + +### For updating release notes in main: + +Rules: +- Generally, follow the rules for "major/minor releases", except as noted in other items below. +- Don't apply a new skeleton of category listings unless they are not present for the upcoming release. + +5. **Insert the formatted notes** into `CHANGES.md` in the appropriate place (as detailed below). Leave the existing content intact. +- When updating `main` or preparing a `major` or `minor` release, insert the updates in the top section for the upcoming major/minor release. Insert a new set of category sections only if it's not already present. +- When doing a `patch` release, insert the changes immediately above the last patch release of that branch, so that CHANGES.md lists releases in descending numerical (version) order. +- When porting a set of release notes from a release branch into main, or from an older (obsolete) release branch to the current release branch, insert it into the right place to maintain overall descending order. + +6. **Double check that the notes are adequately descriptive.** (See more + detailed description of this step below.) + +7. **Forward-port release notes from release branches if needed** + +8. **Show a summary** of what was inserted and ask the user to review before finalizing. + +## Forward-porting release notes + +Release notes may have been generated independently in main, and release +branches. When updating one branch, we ensure that any changes from older +branches have been incorporated. + +- When preparing `patch` release notes, check the CHANGES.md file in the + "dev-X.(Y-1)" branch for the previous minor release family to identify any + X.(Y-1).Z patch release notes that are not reflected in the current release + notes that we are updating. +- When updating `main` or doing a `major` or `minor` release, check the + CHANGES.md file in both the "dev-X.(Y-1)" and "dev-X.(Y-2)" branches. + Check whichever is newer of the local and remote copy of that branch, since + the local one may have had release notes or its version in CMakeLists.txt + updated, but not yet pushed to GitHub. +- If any patch releases are present in the older dev branches checked, insert + the release notes for those patch releases into the right positions in the + current release notes that we are updating. +- If a change is forward-ported in this manner and the same PR is an update in + the current set of changes we are updating as our main task, document that + in the current set of notes using the following convention: in the line of + the notes, the explanation of the version where it appears should reflect + the first version of all branches where it appeared, for example, `(3.2.0.0, + 3.1.3.0, 3.0.8.0)` to indicate that the patch was added to each of those + versions. The versions should be listed in descending order. + +## Useful abbreviations for category labels + +| Abbrev | Meaning | +|--------|---------| +| IB | ImageBuf | +| IBA | ImageBufAlgo | +| IC | ImageCache | +| TS | TextureSystem | +| oiiotool | the oiiotool command | +| build | CMake/build system | +| deps | Changes to accommodate dependency or toolchain changes | +| ci | CI/GitHub Actions | +| docs | documentation | +| int | internal/refactor | +| test | testsuite or unit tests | +| HEADER.h | Developer utilities in a public header file | + +## Combining PRs into single entries + +To be more concise and easier to read, within a release's notes, related +PRs/commits can be combined into a single bullet-point line, which would look +like +``` +- *category*: Combined Description. [#NNNN1](URL) (by author1) [#NNNN2](URL2) (by author2) [#NNNN2](URL2) (by author2) + +``` +if fully combined, or if explained one by one, +``` +- *category*: Description 1 [#NNNN1](URL) (by author1), amendment 2, [#NNNN2](URL2) (by author2), amendment 3, [#NNNN3](URL3) (by author3) +``` +Choose the fully combined or explained one by one based on which is more clear +to the reader. + +If the authors are all the same, only have the author designation at the end. + +Here are the cases where it's ok to combine commits in this way: +- If it is clear that multiple PRs are part of the same feature or fix, + consisting of an initial commit, and subsequent smaller changes or + continuations of the same topic. +- An initial commit, and a subsequent commit that is obviously a fix to a bug + in the initial commit. +- "CI" changes that all only add new cases to the test matrix. +- "CI" changes that all only fix spontaneous breakages in the GitHub runners. +- "Build" changes that are all just minor updates to versions of dependencies + that we support or test against. + +Some more examples of combined commit messages: + +``` + - feat: Add GPS metadata functionality for TIFF [PR1](PR URL 1) [PR2](PR URL 2) [PR3](PR URL 3) (by author). + - ci: New CI variants for MSVS 2026 [PR1](PR URL 1) (by author1), VFX Platform 2027 [PR2](PR URL 2) (by author2). + - ci: Various fixes for unexpected changes to GitHub Actions runners [PR1](PR URL 1), [PR2](PR URL 2) (by author) + - build: Added support for gcc 15 [PR1](PR URL 1) (by author1), OpenEXR 3.5.1 [PR2](PR URL 2) (by author2), libtiff 4.8 [PR3](PR URL 3) (by author3). +``` + +Always ask for confirmation before combining commits in this manner. Confirm +separately for each proposed combination of a group of multiple original +commits into a single commit. Give the user the opportunity to revise the +combined description or request other changes for the grouping. + +## Double check that the notes are adequately descriptive + +For newly added items for this release, read the short descriptions provided +by git-cliff, double check them against the full commit messages to be sure +the one-line summary is adequate. If the summary is misleading, too brief and +leaving out the fact that an important thing was changed, or not adequately +capturing the scope of changes, feel free to propose an alternate wording that +will make it more clear to readers what changed as a result of the PR. Ask for +confirmation on these and explain why you felt the one-line description wasn't +enough. + +One example of a case where this is needed is if the one line description +merely mentions a new image processing capability by name, but the full commit +message makes it clear that a new ImageBufAlgo API call was added, and also a +new oiiotool command line argument was added, and that couldn't all be +described in the one-line brief message of the commit. + +## Reference + +Full release procedures: `docs/dev/RELEASING.md` +Patch skeleton: `docs/dev/Changes-skeleton-patch.md` +Major skeleton: `docs/dev/Changes-skeleton-major.md` +Example good patch notes: https://github.com/AcademySoftwareFoundation/OpenImageIO/releases/tag/v3.0.0.0 +Example good major/minor notes: https://github.com/AcademySoftwareFoundation/OpenImageIO/releases/tag/v3.1.6.1 diff --git a/.claude/.gitignore b/.claude/.gitignore new file mode 100644 index 0000000000..eafd2abf7a --- /dev/null +++ b/.claude/.gitignore @@ -0,0 +1,2 @@ +# Per-user Claude Code settings override (not shared) +settings.local.json diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md new file mode 100644 index 0000000000..43c994c2d3 --- /dev/null +++ b/.claude/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md diff --git a/.claude/skills b/.claude/skills new file mode 120000 index 0000000000..2b7a412b8f --- /dev/null +++ b/.claude/skills @@ -0,0 +1 @@ +../.agents/skills \ No newline at end of file diff --git a/.codex/.gitignore b/.codex/.gitignore new file mode 100644 index 0000000000..945247ca8a --- /dev/null +++ b/.codex/.gitignore @@ -0,0 +1,2 @@ +# Codex session/cache files (per-user) +*.log diff --git a/.codex/skills b/.codex/skills new file mode 120000 index 0000000000..2b7a412b8f --- /dev/null +++ b/.codex/skills @@ -0,0 +1 @@ +../.agents/skills \ No newline at end of file diff --git a/.cursor/.gitignore b/.cursor/.gitignore new file mode 100644 index 0000000000..898c79188f --- /dev/null +++ b/.cursor/.gitignore @@ -0,0 +1,4 @@ +# Cursor Composer session history (per-user) +composer/ +# Cursor chat logs (per-user) +chat/ diff --git a/.cursor/rules/project.mdc b/.cursor/rules/project.mdc new file mode 120000 index 0000000000..b7e6491d3a --- /dev/null +++ b/.cursor/rules/project.mdc @@ -0,0 +1 @@ +../../AGENTS.md \ No newline at end of file diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 120000 index 0000000000..be77ac83a1 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1 @@ +../AGENTS.md \ No newline at end of file diff --git a/.opencode/.gitignore b/.opencode/.gitignore new file mode 100644 index 0000000000..65e7db1c24 --- /dev/null +++ b/.opencode/.gitignore @@ -0,0 +1,4 @@ +node_modules +package.json +package-lock.json +bun.lock \ No newline at end of file diff --git a/.opencode/commands/prepare-patch-release.md b/.opencode/commands/prepare-patch-release.md new file mode 120000 index 0000000000..bda0380c3c --- /dev/null +++ b/.opencode/commands/prepare-patch-release.md @@ -0,0 +1 @@ +../../.agents/skills/prepare-patch-release/SKILL.md \ No newline at end of file diff --git a/.opencode/commands/release-notes-update.md b/.opencode/commands/release-notes-update.md new file mode 120000 index 0000000000..087ff3fe33 --- /dev/null +++ b/.opencode/commands/release-notes-update.md @@ -0,0 +1 @@ +../../.agents/skills/release-notes-update/SKILL.md \ No newline at end of file diff --git a/.opencode/skills b/.opencode/skills new file mode 120000 index 0000000000..2b7a412b8f --- /dev/null +++ b/.opencode/skills @@ -0,0 +1 @@ +../.agents/skills \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000000..159302aa56 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,182 @@ +# OpenImageIO Agent Guide + +This file provides guidance to coding assistants when working with code in +this repository. + +## Project Overview + +OpenImageIO (OIIO) is a C++17 library and toolset for reading, writing, and +manipulating image files across many formats, designed for VFX/animation/film +production. Part of the Academy Software Foundation (ASWF). Canonical repo: +http://github.com/AcademySoftwareFoundation/OpenImageIO + +**Core libraries:** + +- `libOpenImageIO` — Main library: ImageInput/ImageOutput (file I/O), ImageBuf/ImageBufAlgo (image processing), ImageCache/TextureSystem (texture mapping) +- `libOpenImageIO_Util` — Utility library (string_view, ustring, span, threading, filesystem, etc.) + +**Command line tools** + +- `oiiotool`: general image processing CLI +- `iinfo`: print info & metadata for an image file +- `iconvert`: simple format conversion +- `maketx`: convert images to tiled and MIP-mapped textures. +- `iv`: image viewer + +## Repo map + +- `src/include/OpenImageIO/` : Public API headers +- `src/libOpenImageIO/` : Core library (ImageBuf, ImageBufAlgo, + ImageInput/ImageOutput base classes) +- `src/libtexture/` : ImageCache, TextureSystem +- `src/libutil/` : Utility class implementations +- `src/.imageio/` : Per-format ImageInput/ImageOutput plugins. +- `src/python/` : Python bindings using pybind11 +- `src/` : CLI tools (oiiotool, iinfo, iconvert, maketx, iv) +- `testsuite/` : End-to-end/regression tests + reference outputs +- `src/cmake/`, `CMakeLists.txt` : Build system +- `.github/workflows/ci.yml` : GitHub Actions CI +- `src/build-scripts` Helper scripts used for build & CI +- `src/doc/` : User manual source (+ Doxygen comments in the public headers) +- `docs/dev/` : Developer documentation +- `docs/dev/Architecture.md` : Major subsystems overview + + +## Build and verification + +Common build commands via the Makefile convenience wrapper: +```bash +make # configure, build, install (Release) +make debug # debug build +make clean # wipe build dir (needed when switching branches/modes) +make clang-format # format all source files +make test # full testsuite +make test TEST= # subset matching regex +``` + +Or directly with cmake: +```bash +cmake -B build -S . +cmake --build build --target install +ctest --test-dir build -R --output-on-failure +``` + +By default, builds into `./build` and installs into `./dist`. + +## Testsuite notes + +- Test output lands in `build/testsuite//`; references in + `testsuite//ref/` +- Read `testsuite/TESTSUITE-README.md` before updating references or + diagnosing failures +- For platform-specific diffs, add a variant ref (e.g. `out-win.txt`) rather + than overwriting +- Be conservative loosening image diff thresholds — use the minimum needed +- Check uploaded CI artifacts before changing references when local + reproduction is unclear + +## Code formatting and file conventions + +- `clang-format` enforced (`.clang-format`); CI rejects non-conforming code — + run `make clang-format` before committing +- Lines ~80 cols; ASCII only in code and comments; `#pragma once` for headers +- New files: standard copyright + SPDX notice +- `CamelCase` classes, `snake_case` locals, `ALL_CAPS` macros, `m_foo` private + members +- 3 blank lines between free functions/classes; 1 between class methods; max 1 + blank line inside a function body +- `//` for regular comments; `///` Doxygen for public API +- If a file has a strong local style, imitate that. + +## C++ guidelines + +- Error handling: prefer `bool` returns, explicit status propagation, and + `errorfmt()`-style reporting — not exceptions — consistent with the + surrounding subsystem +- Preserve API, ABI, and behavior compatibility unless the task explicitly + requires a break +- For hot paths: no hidden allocation in inner loops or parallel regions; + precompute outside hot paths +- For kernel-style image work, use existing `ImageBufAlgo` and + `parallel_image` patterns before inventing a new execution model + +## OIIO utility types (prefer over raw C++ equivalents) + +Prefer C++17 `std` and Imath types except as noted below. Avoid introducing +new third-party dependencies without a strong reason. + +- `OIIO::string_view` — non-owning string/`char*` (like `std::string_view`) +- `OIIO::span` / `OIIO::cspan` — non-owning contiguous data (like + `std::span`); use instead of pointer+length pairs +- `OIIO::image_span` — describes pixel buffer memory layout (pointer, sizes, + strides) +- `OIIO::Filesystem::*` — file/directory utilities (`filesystem.h`) +- `strutil.h` : string processing utilities +- `Strutil::format()` / `Strutil::print()` (= `OIIO::print()`) — string + formatting/output; **never** `printf` or `<<` streams +- `fmath.h` — fast/safe math, avoids NaN/Inf +- `simd.h` — SIMD helpers +- `unittest.h` — unit test macros + +## Safe programming in C++ + +- Try to avoid passing raw pointers as function arguments. +- Use `std::unique_ptr` and `std::shared_ptr` rather than raw ownership when + new ownership must be expressed, but do not churn existing code just to + "modernize" it. +- Prefer `OIIO::string_view` when passing non-mutable strings or C-style + `char*` strings. +- Prefer `OIIO::span` rather than passing raw pointers + a separate length, or + passing a raw pointer with an implied (but not explicitly passed) length. + `OIIO::cspan` is a synonmym when the underlying data is const/non-mutable. + `OIIO::span` or `OIIO::cspan` can be used to represent + contiguous untyped data. These are our equivalent of C++ `std::span`. +- Prefer `OIIO::image_span` to describe the memory layout of multi-dimensional + pixel buffers (such as are used to describe where to read or write image + pixels), rather than passing raw pointers, sizes, and strides. + +## Performance and determinism + +- For hot image-processing code, avoid hidden allocation in inner loops or + parallel regions. +- Precompute setup work outside hot paths when practical. +- Keep data flow and ownership explicit. +- Preserve deterministic results where practical. +- Avoid unnecessary global state or synchronization. +- For kernel-style work, look for existing `ImageBufAlgo` and + `parallel_image` patterns before inventing a new execution model. +- Prefer incremental performance fixes backed by measurement or concrete + reasoning over speculative rewrites. + +## Change impact checklist + +- Bug fixes and behavior changes → add/update tests +- Public API changes → update Python bindings, docs, `CHANGES.md` +- `ImageBufAlgo` changes → consider oiiotool exposure, docs, Python, tests +- Format plugin changes → regression coverage for metadata, edge cases, + read/write +- CLI changes → update tests and help text +- Build/dependency changes → check CMake logic, CI, optional-feature coverage + +## Commits and PRs + +- Keep PRs narrow and easy to review. +- Prefix format: `type(subsystem): message` — subsystem is optional but helpful. +- Valid types: `fix:`, `feat:`, `perf:`, `api:`, `int:`, `build:`, `test:`, + `ci:`, `docs:`, `refactor:`, `style:`, `admin:`, `revert:`. +- Add a subsystem tag when it helps, e.g. `fix(exr):` or `perf(IBA):`. +- Write commit messages and PR descriptions that explain why the change is + needed, what behavior changes, and any non-obvious implementation choices. + +## AI policy + +Refer to `docs/dev/AI_Policy.md`. + +See `docs/dev/AI_Policy.md`. Key rule: if AI assistance contributed materially +to a patch, the commit must include `Assisted-by: / `. The human +author is responsible for understanding, testing, and defending all changes. + +## References + +- `CONTRIBUTING.md` : general contribution guidelines and recap of coding + conventions. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c1287b91aa..7a2540f1e3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -93,6 +93,16 @@ High-level summary: Please do read the whole [Policy on AI Coding Assistants](docs/dev/AI_Policy.md) for all the details. +The repository includes configuration for several AI coding assistants +(Claude Code, Cursor, GitHub Copilot, OpenAI Codex, Opencode). Much of this +uses symbolic links to keep a single source of truth in `AGENTS.md`. **Windows +users** must enable symlink support before cloning or the agent integrations +will silently malfunction: + +1. Enable [Windows Developer Mode](https://learn.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development) +2. `git config --global core.symlinks true` +3. Then clone (or re-clone) the repository. + Contributor License Agreement (CLA) and Intellectual Property -------------------------------------------------------------