diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..c4ee1f5
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,16 @@
+## What this PR does
+
+
+
+## Why
+
+
+
+## codegraph signals
+
+
diff --git a/.github/ci-templates/pr-review.workflow.yml b/.github/ci-templates/pr-review.workflow.yml
new file mode 100644
index 0000000..8386ea9
--- /dev/null
+++ b/.github/ci-templates/pr-review.workflow.yml
@@ -0,0 +1,136 @@
+# codegraph PR review workflow — TEMPLATE
+#
+# This file lives OUTSIDE .github/workflows/ on purpose: GitHub rejects
+# pushes to .github/workflows/* from OAuth tokens that lack the `workflow`
+# scope. By keeping the template here, the repo can be cloned + pushed-to
+# with the default `repo` scope; activating the workflow is a one-time
+# manual step (see README → "PR review CI").
+#
+# To activate:
+# gh auth refresh -h github.com -s workflow
+# cp .github/ci-templates/pr-review.workflow.yml .github/workflows/pr-review.yml
+# git add .github/workflows/pr-review.yml
+# git commit -m "ci: activate codegraph PR review"
+# git push
+
+name: codegraph PR review
+
+on:
+ pull_request:
+ branches: [main]
+ types: [opened, synchronize, reopened]
+
+permissions:
+ contents: read
+ pull-requests: write
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
+ cancel-in-progress: true
+
+jobs:
+ review:
+ runs-on: ubuntu-latest
+ timeout-minutes: 15
+
+ steps:
+ - name: Checkout PR head
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Setup Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.10"
+ cache: pip
+
+ - name: Install codegraph (PR head)
+ run: pip install -e .
+
+ - name: Build baseline graph from main
+ run: |
+ set -euxo pipefail
+ mkdir -p .baseline-checkout
+ git worktree add .baseline-checkout origin/main
+ (
+ cd .baseline-checkout
+ pip install -e . --quiet
+ codegraph build --no-incremental
+ codegraph baseline save --output ../.codegraph/baseline.db
+ )
+ if [ ! -f .codegraph/baseline.db ]; then
+ echo "BASELINE_MISSING=1" >> "$GITHUB_ENV"
+ echo "::warning::No baseline could be saved from main; running first-time review."
+ fi
+
+ - name: Build PR head graph
+ run: codegraph build --no-incremental
+
+ - name: Run codegraph review
+ run: |
+ set -uo pipefail
+ if [ -n "${BASELINE_MISSING:-}" ]; then
+ cat > review.md <<'EOF'
+ ## codegraph PR review
+
+ No baseline graph from `main` was available for this run, so a
+ full diff review was skipped. The PR head was still parsed
+ successfully — codegraph review will activate from the next PR.
+ EOF
+ exit 0
+ fi
+ set +e
+ codegraph review \
+ --format markdown \
+ --output review.md \
+ --fail-on high \
+ --baseline .codegraph/baseline.db
+ rc=$?
+ set -e
+ if [ "$rc" -ne 0 ]; then
+ echo "REVIEW_FAILED=1" >> "$GITHUB_ENV"
+ fi
+
+ - name: Wrap review in comment template
+ env:
+ RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+ run: |
+ set -e
+ {
+ echo "## codegraph PR review"
+ echo
+ echo ""
+ echo "Diff vs main · severity ≤ high
"
+ echo
+ cat review.md
+ echo
+ echo " "
+ echo
+ echo "Triggered by codegraph CI · last run"
+ } > comment.md
+
+ - name: Post or update PR comment
+ uses: peter-evans/create-or-update-comment@v4
+ with:
+ issue-number: ${{ github.event.pull_request.number }}
+ body-file: comment.md
+ edit-mode: replace
+ comment-tag: codegraph-review
+
+ - name: Upload review artifact
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: codegraph-review
+ path: |
+ review.md
+ comment.md
+ .codegraph/graph.db
+ retention-days: 7
+
+ - name: Fail if findings exceed threshold
+ if: env.REVIEW_FAILED == '1'
+ run: |
+ echo "::error::codegraph review found high-or-critical findings. See PR comment for details."
+ exit 1
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..d19d09c
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,19 @@
+version: 2
+updates:
+ - package-ecosystem: "pip"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+ open-pull-requests-limit: 5
+ labels:
+ - "dependencies"
+ - "python"
+
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+ open-pull-requests-limit: 3
+ labels:
+ - "dependencies"
+ - "ci"
diff --git a/README.md b/README.md
index 35799e3..03e8af0 100644
--- a/README.md
+++ b/README.md
@@ -417,6 +417,47 @@ node --test tests/*.js # 55 JS tests
---
+## PR review CI (dogfood)
+
+`codegraph` ships its own PR-review workflow as a template. Once activated,
+every PR opened against `main` runs codegraph against itself, posts the diff
+as a sticky PR comment, and fails the check on high-severity findings.
+
+The workflow lives at
+[`.github/ci-templates/pr-review.workflow.yml`](.github/ci-templates/pr-review.workflow.yml)
+(outside `.github/workflows/` so the repo can be cloned and pushed-to with a
+token that lacks the `workflow` OAuth scope). Activate with:
+
+```bash
+gh auth refresh -h github.com -s workflow
+cp .github/ci-templates/pr-review.workflow.yml .github/workflows/pr-review.yml
+git add .github/workflows/pr-review.yml
+git commit -m "ci: activate codegraph PR review"
+git push
+```
+
+Once active, the workflow:
+
+1. Builds a graph from `origin/main` and saves it as a baseline.
+2. Builds a graph from the PR head.
+3. Runs `codegraph review --format markdown --fail-on high` against the diff.
+4. Posts the result as a sticky PR comment (replaced on each push, no spam).
+5. Fails the check if any high-or-critical findings appear.
+
+**Local dry-run** before opening a PR:
+
+```bash
+git fetch origin main
+./scripts/test-pr-review-locally.sh
+# writes review.md + comment.md, exits non-zero if findings exceed --fail-on high
+```
+
+First-PR graceful path: if no baseline can be saved from `main` (brand-new
+repo, empty default branch), the workflow posts a friendly "first-time
+review" comment and passes — codegraph review activates from the next PR.
+
+---
+
## Acknowledgements
`codegraph` stands on:
diff --git a/scripts/test-pr-review-locally.sh b/scripts/test-pr-review-locally.sh
new file mode 100755
index 0000000..87ad070
--- /dev/null
+++ b/scripts/test-pr-review-locally.sh
@@ -0,0 +1,65 @@
+#!/usr/bin/env bash
+# Dry-run the PR review workflow locally so you can validate it before pushing.
+#
+# Requires:
+# - clean repo (no uncommitted changes)
+# - origin/main fetched (`git fetch origin main`)
+# - codegraph installed in editable mode (`pip install -e .`)
+#
+# Produces ./review.md and ./comment.md exactly like the CI does, but skips
+# the GitHub-API steps (comment posting, artifact upload, exit code).
+set -euo pipefail
+
+REPO_ROOT=$(git rev-parse --show-toplevel)
+cd "$REPO_ROOT"
+
+if ! git diff-index --quiet HEAD --; then
+ echo "[WARN] working tree has uncommitted changes; review will reflect them" >&2
+fi
+
+if ! command -v codegraph >/dev/null 2>&1; then
+ echo "[ERROR] codegraph not on PATH — run \`pip install -e .\` first" >&2
+ exit 1
+fi
+
+echo "==> Building baseline from origin/main"
+rm -rf /tmp/cg-baseline-checkout
+git worktree add /tmp/cg-baseline-checkout origin/main
+trap 'git worktree remove --force /tmp/cg-baseline-checkout 2>/dev/null || true' EXIT
+
+(
+ cd /tmp/cg-baseline-checkout
+ codegraph build --no-incremental
+ codegraph baseline save --output "$REPO_ROOT/.codegraph/baseline.db"
+)
+
+echo "==> Building PR-head graph"
+codegraph build --no-incremental
+
+echo "==> Running codegraph review"
+set +e
+codegraph review \
+ --format markdown \
+ --output review.md \
+ --fail-on high \
+ --baseline .codegraph/baseline.db
+rc=$?
+set -e
+
+echo "==> Wrapping into comment.md"
+{
+ echo "## codegraph PR review"
+ echo
+ echo ""
+ echo "Diff vs main · severity ≤ high
"
+ echo
+ cat review.md
+ echo
+ echo " "
+} > comment.md
+
+echo
+echo "----"
+echo "review.md and comment.md written. Review exit code: $rc"
+echo "(Non-zero = high/critical findings; CI would fail on this.)"
+exit "$rc"