Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[flake8]
max-line-length = 120
extend-ignore = E203, W503
exclude = .git, __pycache__, */migrations/*
7 changes: 5 additions & 2 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
## Checklist

- [ ] Targets Odoo 17.0 and follows the existing code style
- [ ] Added/updated tests under `tests/` (tagged `codexoo`); CI is green
- [ ] Updated `CHANGELOG.md`
- [ ] Added/updated tests under `tests/` (tagged `codexoo`) and they pass locally
- [ ] Updated `CHANGELOG.md` (bullet under `## [Unreleased]`)
- [ ] Updated `SECURITY.md` if this touches a safety-critical path (else N/A)
- [ ] All commits are signed off (`git commit -s` → DCO)
- [ ] I am the author and have reviewed/understand **all** code here, including any AI-assisted parts, and it is mine to license
- [ ] Tool endpoints still run **as the user, never superuser**
- [ ] Did not alter Codex engine references (ChatGPT/device-code login, `CODEX_HOME`,
CLI glob, `codex_thread_id` / `codex_item_id`)
Expand Down
103 changes: 103 additions & 0 deletions .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
name: PR checks

# Enforced contribution gates for community pull requests. Each job below is a
# separate status check; mark them "required" in branch protection to block merge.
on:
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled]

permissions:
contents: read

jobs:
changelog:
name: changelog
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Require a CHANGELOG.md update
if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip-changelog') }}
run: |
set -euo pipefail
git fetch --no-tags --depth=1 origin "${{ github.base_ref }}"
if git diff --name-only "origin/${{ github.base_ref }}...HEAD" | grep -qx 'CHANGELOG.md'; then
echo "CHANGELOG.md updated ✓"
else
echo "::error::This PR must update CHANGELOG.md (add a bullet under '## [Unreleased]'). A maintainer can apply the 'skip-changelog' label for trivial PRs."
exit 1
fi

dco:
name: dco
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Verify Signed-off-by on every commit
run: |
set -euo pipefail
git fetch --no-tags origin "${{ github.base_ref }}"
fail=0
for sha in $(git rev-list "origin/${{ github.base_ref }}..HEAD"); do
if ! git log -1 --format='%(trailers:key=Signed-off-by)' "$sha" | grep -qiE '<.+@.+>'; then
subject=$(git log -1 --format='%s' "$sha")
echo "::error::Commit $sha (\"$subject\") is missing a Signed-off-by line."
fail=1
fi
done
if [ "$fail" -ne 0 ]; then
echo "Fix with: git commit -s --amend (single commit)"
echo " or: git rebase --signoff origin/${{ github.base_ref }} (several)"
exit 1
fi
echo "All commits signed off ✓"

security-doc:
name: security-doc
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Require SECURITY.md when touching safety-critical paths
if: ${{ !contains(github.event.pull_request.labels.*.name, 'security-reviewed') }}
run: |
set -euo pipefail
git fetch --no-tags --depth=1 origin "${{ github.base_ref }}"
changed=$(git diff --name-only "origin/${{ github.base_ref }}...HEAD")
sensitive=$(printf '%s\n' "$changed" | grep -E '(/controllers/(tools|main)\.py$|/models/ir_http\.py$|/models/[^/]*_session\.py$|/models/[^/]*_tool\.py$|/bridge/|/security/)' || true)
if [ -n "$sensitive" ]; then
echo "Safety-critical files changed:"; printf '%s\n' "$sensitive"
if printf '%s\n' "$changed" | grep -qx 'SECURITY.md'; then
echo "SECURITY.md updated ✓"
else
echo "::error::This PR changes safety-critical files but does not update SECURITY.md. Update SECURITY.md to reflect the change, or have a maintainer add the 'security-reviewed' label."
exit 1
fi
else
echo "No safety-critical paths touched ✓"
fi

lint:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: pip install flake8
- name: flake8 on changed Python files
run: |
set -euo pipefail
git fetch --no-tags --depth=1 origin "${{ github.base_ref }}"
files=$(git diff --name-only --diff-filter=ACMR "origin/${{ github.base_ref }}...HEAD" \
| grep -E '\.py$' | grep -vE '(/migrations/|__pycache__)' || true)
if [ -z "$files" ]; then echo "No Python files changed ✓"; exit 0; fi
echo "Linting:"; printf '%s\n' "$files"
printf '%s\n' "$files" | xargs flake8
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@

All notable changes to **Codexoo** are documented here. The format is based on
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project uses
Odoo-style versioning (`17.0.MAJOR.MINOR.PATCH`).
Odoo-style versioning (`17.0.MAJOR.MINOR.PATCH`). Add new entries under
`## [Unreleased]`; a maintainer assigns the version at release time.

## [Unreleased]

### Added
- **Contribution gates** — a `pr-checks` CI workflow (CHANGELOG, DCO sign-off,
SECURITY.md-when-relevant, flake8) plus branch protection, and `CONTRIBUTING.md`
guidance covering AI-assisted contributions and the Developer Certificate of
Origin (`DCO`).

## [17.0.1.0.3] — 2026-06-11

Expand Down
62 changes: 59 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,65 @@ welcome — bug reports, documentation, tests, and code.

## Pull requests

- One logical change per PR; write a clear description and link any issue.
- Make sure CI is green (lint + tests).
- Update `CHANGELOG.md` under an *Unreleased* heading.
Open one logical change per PR with a clear description; link any issue
(`Closes #123`). The items below are **enforced by CI and branch protection** — the
merge button stays disabled until they pass:

- **Changelog.** Add a bullet under the `## [Unreleased]` heading in
[`CHANGELOG.md`](CHANGELOG.md). (A maintainer can apply the `skip-changelog` label
for genuinely trivial PRs.)
- **Security docs.** If your PR touches a safety-critical path —
`controllers/tools.py`, `controllers/main.py`, `models/ir_http.py`,
`models/*_session.py`, `models/*_tool.py`, `bridge/`, or `security/` — update
[`SECURITY.md`](SECURITY.md) to reflect the change (or have a maintainer apply the
`security-reviewed` label).
- **Sign-off.** Every commit must be signed off — see *Developer Certificate of
Origin* below.
- **Lint.** `flake8` must pass on the Python files you changed.
- **Review.** At least one maintainer approval.

There is no test job in CI, so run the suite locally before pushing:

```bash
odoo-bin ... -i codexoo --test-tags codexoo --stop-after-init
```

## AI-assisted contributions

AI coding tools are welcome here — this project is itself an AI assistant. The bar is
simply the same as for any other contribution:

- **You are the author.** You are fully accountable for every line, AI-generated or
not. Only open PRs you understand and can explain; reviewers may ask how a change
works.
- **Provenance.** AI can emit third-party or copyleft code verbatim. Submit only code
that is your original work, or that you otherwise have the right to license under
the terms in *Licensing of contributions* below. If you can't vouch for a snippet's
origin, don't include it.
- **Never let AI weaken the security model.** Re-read [`SECURITY.md`](SECURITY.md).
Changes that introduce `sudo()` / superuser execution, broaden the SQL tool past
read-only `SELECT`, bypass `ir.model.access` or record rules, widen the bridge
token's scope, or re-enable denied CLI built-ins **will be rejected** — AI
assistants suggest these "helpfully" all the time. Keep the invariants and ship
tests that prove them.
- **Verify.** Run the tests locally; never paste credentials, customer data, or
proprietary code into an AI tool while working on this project.
- **Quality over volume.** Low-effort or bulk AI-generated PRs that don't meet the
bar may be closed without a detailed review.

## Developer Certificate of Origin

Contributions are accepted under the **Developer Certificate of Origin 1.1** (full
text in the [`DCO`](DCO) file). Sign off every commit:

```bash
git commit -s -m "your message"
```

This appends a `Signed-off-by: Your Name <you@example.com>` trailer. Signing off
certifies the DCO **and**, for this project, that any AI-assisted code in the commit
is yours to license under the terms below. CI rejects unsigned commits; fix them with
`git commit -s --amend` (one commit) or `git rebase --signoff origin/17.0` (several).

### Licensing of contributions (important)

Expand Down
34 changes: 34 additions & 0 deletions DCO
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
Developer Certificate of Origin
Version 1.1

Copyright (C) 2004, 2006 The Linux Foundation and its contributors.

Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.


Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or

(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or

(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.

(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ superuser, with a full audit trail.**

[![License: LGPL-3.0](https://img.shields.io/badge/License-LGPL%20v3-blue.svg)](LICENSE)
[![Odoo](https://img.shields.io/badge/Odoo-17.0-714B67.svg)](https://www.odoo.com)
[![CI](https://github.com/cicdoo/codexoo/actions/workflows/ci.yml/badge.svg)](https://github.com/cicdoo/codexoo/actions/workflows/ci.yml)
[![PR checks](https://github.com/cicdoo/codexoo/actions/workflows/pr-checks.yml/badge.svg)](https://github.com/cicdoo/codexoo/actions/workflows/pr-checks.yml)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md)

[Quick start](#-quick-start) · [Security model](#-security-model) ·
Expand Down
Loading