From 241e9655c30a784f1111894f60f640ee3e3325f9 Mon Sep 17 00:00:00 2001 From: xeonvs <11463419+xeonvs@users.noreply.github.com> Date: Fri, 14 Aug 2026 14:09:12 +0200 Subject: [PATCH 1/2] Keep GitLab example release paths consistent --- PLANS.md | 15 ++++++++++++++- changelog.d/86.bugfix.md | 1 + examples/gitlab/ocr-review.gitlab-ci.yml | 4 ++-- tests/test_integration_contracts.py | 8 ++++++++ tests/test_testpypi_preview.py | 12 ++++++++---- 5 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 changelog.d/86.bugfix.md diff --git a/PLANS.md b/PLANS.md index ca171a2..8a797b1 100644 --- a/PLANS.md +++ b/PLANS.md @@ -4,4 +4,17 @@ Use this file for active or blocked repository work. Update it before implementa ## Active Work -No active or blocked repository work. +### Community conduct policy and example-version consistency + +- **Status:** active +- **Release classification:** `no-release`; governance documentation and correction of the public example do not authorize stable artifact publication. The example correction receives a Towncrier fragment for the next ordinary release. +- **Objective:** establish one public Code of Conduct with a confidential enforcement route, link it from contributor and project entry points, and complete the already-started toolkit-version update in the synthetic GitLab example without changing runtime behavior. +- **Owners and boundaries:** `CODE_OF_CONDUCT.md` owns community behavior, scope, reporting, privacy, and enforcement. `CONTRIBUTING.md` links contributors to that policy; `README.md` exposes it from the public documentation index; `docs/engineering/project_principles.md` records documentation ownership without duplicating conduct rules. The GitLab example remains synthetic documentation, while `tests/test_integration_contracts.py` protects its internally consistent release-derived wheel references. +- **Trust and privacy:** conduct reports use the repository's available private maintainer channel and must not be filed as public issues. Public files contain no private contacts or provider material. The example uses only public immutable release coordinates and does not introduce credentials. +- **Implementation slices:** + 1. [x] Complete the `0.6.0` example pin by deriving the checksum URL and wheel install path from `OCR_TOOLKIT_VERSION`; add a regression assertion and documentation changelog fragment. + 2. [x] Add Contributor Covenant 2.1 as `CODE_OF_CONDUCT.md`, adapt only the confidential reporting method, and add concise links/ownership entries in contributor and project documentation. +- **Validation:** self-review the complete diff before each commit; run the focused integration/documentation tests, `git diff --check`, and `scripts/quality.sh check`; confirm the conduct document has no placeholder contact method and the example has no hard-coded toolkit wheel/release version outside its single variable. +- **Checkpoint:** the example consistency test passes and self-review confirms that the checksum URL, requirement, downloaded filename, digest check, and installation now derive from one version variable. +- **Checkpoint:** Contributor Covenant 2.1 is the canonical conduct owner; README, contribution guidance, package metadata, CODEOWNERS, and the issue chooser point to it without copying its behavioral rules. The confidential route is distinct in purpose from vulnerability reporting and no placeholder contact remains. +- **Closure:** leave the branch ready for one protected documentation PR, with no push until the coherent work and validation are complete. Reset this file to its empty template in the final local commit because no stable release archive is required. diff --git a/changelog.d/86.bugfix.md b/changelog.d/86.bugfix.md new file mode 100644 index 0000000..4c9a9a7 --- /dev/null +++ b/changelog.d/86.bugfix.md @@ -0,0 +1 @@ +Derive every release URL and wheel path in the synthetic GitLab example from its single toolkit version pin. diff --git a/examples/gitlab/ocr-review.gitlab-ci.yml b/examples/gitlab/ocr-review.gitlab-ci.yml index bcfb795..c027898 100644 --- a/examples/gitlab/ocr-review.gitlab-ci.yml +++ b/examples/gitlab/ocr-review.gitlab-ci.yml @@ -8,7 +8,7 @@ default: variables: OCR_VERSION: "v1.9.3" OCR_TOOLKIT_VERSION: "0.6.0" - OCR_TOOLKIT_CHECKSUMS_URL: "https://github.com/xeonvs/open-code-review-toolkit/releases/download/v0.1.0/SHA256SUMS" + OCR_TOOLKIT_CHECKSUMS_URL: "https://github.com/xeonvs/open-code-review-toolkit/releases/download/v${OCR_TOOLKIT_VERSION}/SHA256SUMS" OCR_SHA256: "d494812b9ba316a34bb08efbaebf871ab1069e83f5892c5d87d93ab703626838" OCR_POST_MODE: "draft" OCR_STRICT_POSTING: "true" @@ -67,7 +67,7 @@ open_code_review: --index-url https://pypi.org/simple --dest /tmp --requirement /tmp/ocr-toolkit-requirement.txt - echo "${OCR_TOOLKIT_WHEEL_SHA256} /tmp/${OCR_TOOLKIT_WHEEL}" | sha256sum --check --strict - - pip install --no-deps /tmp/open_code_review_toolkit-0.1.0-py3-none-any.whl + - pip install --no-deps "/tmp/${OCR_TOOLKIT_WHEEL}" - if [ "${OCR_RUN_HELPER_TESTS:-false}" = "true" ]; then uv run pytest tests; fi - ocr-ci preflight - ocr-ci configure diff --git a/tests/test_integration_contracts.py b/tests/test_integration_contracts.py index 1c09bc8..7d638bd 100644 --- a/tests/test_integration_contracts.py +++ b/tests/test_integration_contracts.py @@ -4,6 +4,7 @@ import ast import json +import re from tests.support import HELPER_DIR, PROJECT_ROOT @@ -89,6 +90,13 @@ def test_gitlab_docs_match_the_current_review_surface() -> None: assert "OCR_LLM_VALIDATE_MODEL" in workflow assert "OCR_TOOLKIT_VERSION" in workflow assert "OCR_TOOLKIT_CHECKSUMS_URL" in workflow + assert ( + 'OCR_TOOLKIT_CHECKSUMS_URL: "https://github.com/xeonvs/' + 'open-code-review-toolkit/releases/download/v${OCR_TOOLKIT_VERSION}/SHA256SUMS"' in workflow + ) + assert 'pip install --no-deps "/tmp/${OCR_TOOLKIT_WHEEL}"' in workflow + assert not re.search(r"releases/download/v\d+\.\d+\.\d+/SHA256SUMS", workflow) + assert not re.search(r"pip install --no-deps /tmp/open_code_review_toolkit-\d", workflow) assert ".opencodereview/accepted-decisions.md" in configuration assert "ocr-accept: generated-client-timeout" in configuration assert "not a source-code parser" in configuration diff --git a/tests/test_testpypi_preview.py b/tests/test_testpypi_preview.py index 8475859..4f268d6 100644 --- a/tests/test_testpypi_preview.py +++ b/tests/test_testpypi_preview.py @@ -194,17 +194,21 @@ def test_workflow_bounds_and_verifies_every_testpypi_download() -> None: def test_gitlab_example_uses_pinned_bounded_stable_wheel_install() -> None: example = GITLAB_EXAMPLE.read_text(encoding="utf-8") - wheel_name = "open_code_review_toolkit-0.1.0-py3-none-any.whl" + stable_version = (PROJECT_ROOT / ".release-version").read_text(encoding="utf-8").strip() - assert "releases/download/v0.1.0/SHA256SUMS" in example - assert wheel_name in example + assert f'OCR_TOOLKIT_VERSION: "{stable_version}"' in example + assert "releases/download/v${OCR_TOOLKIT_VERSION}/SHA256SUMS" in example + assert ( + 'OCR_TOOLKIT_WHEEL="open_code_review_toolkit-${OCR_TOOLKIT_VERSION}-py3-none-any.whl"' + in example + ) assert "--require-hashes --no-deps --only-binary=:all:" in example assert "--retries 3 --timeout 10" in example assert "--retry 3 --retry-delay 2 --retry-connrefused" in example assert "--connect-timeout 10 --max-time 120" in example assert "--proto '=https' --proto-redir '=https'" in example assert "sha256sum --check --strict" in example - assert f"pip install --no-deps /tmp/{wheel_name}" in example + assert 'pip install --no-deps "/tmp/${OCR_TOOLKIT_WHEEL}"' in example def test_production_release_verifies_reviewed_registry_artifacts() -> None: From 7ab79836a2c90ebb833d2c50e5e9b59179995f3c Mon Sep 17 00:00:00 2001 From: xeonvs <11463419+xeonvs@users.noreply.github.com> Date: Fri, 14 Aug 2026 14:14:07 +0200 Subject: [PATCH 2/2] Add project Code of Conduct --- .github/CODEOWNERS | 1 + .github/ISSUE_TEMPLATE/config.yml | 3 + CODE_OF_CONDUCT.md | 83 ++++++++++++++++++++++++++ CONTRIBUTING.md | 6 +- PLANS.md | 15 +---- README.md | 1 + changelog.d/86.doc.md | 1 + docs/engineering/project_principles.md | 1 + pyproject.toml | 1 + tests/test_operations_docs.py | 23 +++++++ 10 files changed, 119 insertions(+), 16 deletions(-) create mode 100644 CODE_OF_CONDUCT.md create mode 100644 changelog.d/86.doc.md diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 3a123c4..b6b3b22 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,4 +2,5 @@ /.github/ @xeonvs /docs/security.md @xeonvs /SECURITY.md @xeonvs +/CODE_OF_CONDUCT.md @xeonvs /src/ocr_toolkit/posting/ @xeonvs diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index e07de8c..fa7e0ab 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,5 +1,8 @@ blank_issues_enabled: false contact_links: + - name: Code of Conduct report + url: https://github.com/xeonvs/open-code-review-toolkit/security/advisories/new + about: Report conduct incidents privately and start the title with [Code of Conduct]. - name: Security vulnerability url: https://github.com/xeonvs/open-code-review-toolkit/security/advisories/new about: Report vulnerabilities privately. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..7fd7357 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,83 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported privately through [GitHub private vulnerability reporting](https://github.com/xeonvs/open-code-review-toolkit/security/advisories/new). Start the report title with `[Code of Conduct]`; this route is used only to keep the report confidential and does not classify the incident as a software vulnerability. Do not report conduct incidents in public issues. All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of actions. + +**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, available at [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at [https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fe9adfb..af96d28 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,6 +2,8 @@ Thank you for improving Open Code Review Toolkit. Keep changes focused, add regression tests for behavior changes, and use synthetic examples only. +Participation in this project is governed by the [Code of Conduct](CODE_OF_CONDUCT.md). Report conduct incidents through its private enforcement route rather than a public issue. + 1. Create a branch from `main`. 2. Install the locked development environment with `uv sync --frozen`. 3. Update `PLANS.md` for substantial work. @@ -9,6 +11,6 @@ Thank you for improving Open Code Review Toolkit. Keep changes focused, add regr 5. Run the checks in [docs/development.md](docs/development.md). 6. Open a pull request; protected `main` accepts changes only through green pull requests. -Every non-release merge publishes a `0.2.0.devN` development build to TestPyPI. Stable releases use a repository-owned `release/vX.Y.Z` branch and an exact `Release vX.Y.Z` pull-request title; merging that reviewed PR authorizes the automated TestPyPI, PyPI, and GitHub Release chain. +Every non-release merge publishes a development build for the current `.next-version` line to TestPyPI. Stable releases use a repository-owned `release/vX.Y.Z` branch and an exact `Release vX.Y.Z` pull-request title; merging that reviewed PR authorizes the automated TestPyPI, PyPI, and GitHub Release chain. -Do not include real credentials, provider payloads, internal hosts, or private repository details. Security reports should follow [SECURITY.md](SECURITY.md), not public issues. +Do not include real credentials, provider payloads, internal hosts, or private repository details. Security reports should follow [SECURITY.md](SECURITY.md), while conduct incidents follow [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md); neither belongs in a public issue. diff --git a/PLANS.md b/PLANS.md index 8a797b1..ca171a2 100644 --- a/PLANS.md +++ b/PLANS.md @@ -4,17 +4,4 @@ Use this file for active or blocked repository work. Update it before implementa ## Active Work -### Community conduct policy and example-version consistency - -- **Status:** active -- **Release classification:** `no-release`; governance documentation and correction of the public example do not authorize stable artifact publication. The example correction receives a Towncrier fragment for the next ordinary release. -- **Objective:** establish one public Code of Conduct with a confidential enforcement route, link it from contributor and project entry points, and complete the already-started toolkit-version update in the synthetic GitLab example without changing runtime behavior. -- **Owners and boundaries:** `CODE_OF_CONDUCT.md` owns community behavior, scope, reporting, privacy, and enforcement. `CONTRIBUTING.md` links contributors to that policy; `README.md` exposes it from the public documentation index; `docs/engineering/project_principles.md` records documentation ownership without duplicating conduct rules. The GitLab example remains synthetic documentation, while `tests/test_integration_contracts.py` protects its internally consistent release-derived wheel references. -- **Trust and privacy:** conduct reports use the repository's available private maintainer channel and must not be filed as public issues. Public files contain no private contacts or provider material. The example uses only public immutable release coordinates and does not introduce credentials. -- **Implementation slices:** - 1. [x] Complete the `0.6.0` example pin by deriving the checksum URL and wheel install path from `OCR_TOOLKIT_VERSION`; add a regression assertion and documentation changelog fragment. - 2. [x] Add Contributor Covenant 2.1 as `CODE_OF_CONDUCT.md`, adapt only the confidential reporting method, and add concise links/ownership entries in contributor and project documentation. -- **Validation:** self-review the complete diff before each commit; run the focused integration/documentation tests, `git diff --check`, and `scripts/quality.sh check`; confirm the conduct document has no placeholder contact method and the example has no hard-coded toolkit wheel/release version outside its single variable. -- **Checkpoint:** the example consistency test passes and self-review confirms that the checksum URL, requirement, downloaded filename, digest check, and installation now derive from one version variable. -- **Checkpoint:** Contributor Covenant 2.1 is the canonical conduct owner; README, contribution guidance, package metadata, CODEOWNERS, and the issue chooser point to it without copying its behavioral rules. The confidential route is distinct in purpose from vulnerability reporting and no placeholder contact remains. -- **Closure:** leave the branch ready for one protected documentation PR, with no push until the coherent work and validation are complete. Reset this file to its empty template in the final local commit because no stable release archive is required. +No active or blocked repository work. diff --git a/README.md b/README.md index b61d458..883cab0 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,7 @@ Repository content, OCR output, and provider responses are untrusted inputs. The ## Development and release - [Contributing](CONTRIBUTING.md) +- [Code of Conduct](CODE_OF_CONDUCT.md) - [Development guide](docs/development.md) - [Security policy](SECURITY.md) - [Release process](docs/release.md) diff --git a/changelog.d/86.doc.md b/changelog.d/86.doc.md new file mode 100644 index 0000000..70666ad --- /dev/null +++ b/changelog.d/86.doc.md @@ -0,0 +1 @@ +Adopt Contributor Covenant 2.1 with a confidential conduct-reporting route and links from the public contributor documentation. diff --git a/docs/engineering/project_principles.md b/docs/engineering/project_principles.md index 5a9197e..bd6c102 100644 --- a/docs/engineering/project_principles.md +++ b/docs/engineering/project_principles.md @@ -61,6 +61,7 @@ Mandatory evidence and usage metadata are composed once and applied across skipp ## Documentation Ownership - `README.md` owns the concise public introduction and quick start. +- `CODE_OF_CONDUCT.md` owns community behavior, scope, confidential reporting, and enforcement; `CONTRIBUTING.md` owns the contribution workflow. - `docs/configuration.md` owns the environment and generated-configuration contract. - `docs/operations.md` owns the public review state machine; `docs/gitlab.md` owns GitLab setup and operator procedure. - `docs/security.md` owns runtime trust guarantees; `SECURITY.md` owns vulnerability reporting. diff --git a/pyproject.toml b/pyproject.toml index 9351ac4..63bb7ca 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,7 @@ Homepage = "https://github.com/xeonvs/open-code-review-toolkit" Repository = "https://github.com/xeonvs/open-code-review-toolkit" Issues = "https://github.com/xeonvs/open-code-review-toolkit/issues" Changelog = "https://github.com/xeonvs/open-code-review-toolkit/blob/main/CHANGELOG.md" +"Code of Conduct" = "https://github.com/xeonvs/open-code-review-toolkit/blob/main/CODE_OF_CONDUCT.md" [project.scripts] ocr-ci = "ocr_toolkit.cli:main" diff --git a/tests/test_operations_docs.py b/tests/test_operations_docs.py index e152c68..15835f1 100644 --- a/tests/test_operations_docs.py +++ b/tests/test_operations_docs.py @@ -8,6 +8,7 @@ GITLAB_GUIDE = PROJECT_ROOT / "docs" / "gitlab.md" CONFIGURATION = PROJECT_ROOT / "docs" / "configuration.md" GITLAB_EXAMPLE = PROJECT_ROOT / "examples" / "gitlab" / "ocr-review.gitlab-ci.yml" +CODE_OF_CONDUCT = PROJECT_ROOT / "CODE_OF_CONDUCT.md" def test_readme_and_gitlab_guide_link_to_operations() -> None: @@ -19,6 +20,28 @@ def test_readme_and_gitlab_guide_link_to_operations() -> None: assert "## How reviews evolve" in readme +def test_community_conduct_policy_has_a_private_enforcement_route() -> None: + """Keep conduct reports private and separate from public issue intake.""" + + conduct = CODE_OF_CONDUCT.read_text(encoding="utf-8") + readme = README.read_text(encoding="utf-8") + contributing = (PROJECT_ROOT / "CONTRIBUTING.md").read_text(encoding="utf-8") + issue_config = (PROJECT_ROOT / ".github" / "ISSUE_TEMPLATE" / "config.yml").read_text( + encoding="utf-8" + ) + + assert "Contributor Covenant" in conduct + assert "version 2.1" in conduct + assert "[INSERT CONTACT METHOD]" not in conduct + assert "security/advisories/new" in conduct + assert "[Code of Conduct]" in conduct + assert "Do not report conduct incidents in public issues" in conduct + assert "CODE_OF_CONDUCT.md" in readme + assert contributing.count("(CODE_OF_CONDUCT.md)") == 2 + assert "Code of Conduct report" in issue_config + assert "Security vulnerability" in issue_config + + def test_operations_guide_documents_lifecycle_contract() -> None: operations = OPERATIONS.read_text(encoding="utf-8")