chore(ci): establish PR governance for agent collaboration (#177)

* chore(ci): establish PR governance for agent collaboration

* docs: add AGENTS playbook and strengthen agent collaboration workflow

---------

Co-authored-by: chumyin <183474434+chumyin@users.noreply.github.com>
This commit is contained in:
Chummy 2026-02-16 01:41:16 +08:00 committed by GitHub
parent dca95cac7a
commit dfe648d5ae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 1020 additions and 19 deletions

10
.github/CODEOWNERS vendored Normal file
View file

@ -0,0 +1,10 @@
# Default owner for all files
* @theonlyhennygod
# High-risk surfaces
/src/security/** @theonlyhennygod
/src/runtime/** @theonlyhennygod
/src/memory/** @theonlyhennygod
/.github/** @theonlyhennygod
/Cargo.toml @theonlyhennygod
/Cargo.lock @theonlyhennygod

93
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View file

@ -0,0 +1,93 @@
name: Bug Report
description: Report a reproducible defect in ZeroClaw
title: "[Bug]: "
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to report a bug.
Please provide a minimal reproducible case so maintainers can triage quickly.
- type: input
id: summary
attributes:
label: Summary
description: One-line description of the problem.
placeholder: zeroclaw daemon exits immediately when ...
validations:
required: true
- type: textarea
id: current
attributes:
label: Current behavior
description: What is happening now?
placeholder: The process exits with ...
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected behavior
description: What should happen instead?
placeholder: The daemon should stay alive and ...
validations:
required: true
- type: textarea
id: reproduce
attributes:
label: Steps to reproduce
description: Please provide exact commands/config.
placeholder: |
1. zeroclaw onboard --interactive
2. zeroclaw daemon
3. Observe crash in logs
render: bash
validations:
required: true
- type: textarea
id: logs
attributes:
label: Logs / stack traces
description: Paste relevant logs (redact secrets).
render: text
validations:
required: false
- type: input
id: version
attributes:
label: ZeroClaw version
placeholder: v0.1.0 / commit SHA
validations:
required: true
- type: input
id: rust
attributes:
label: Rust version
placeholder: rustc 1.xx.x
validations:
required: true
- type: input
id: os
attributes:
label: Operating system
placeholder: Ubuntu 24.04 / macOS 15 / Windows 11
validations:
required: true
- type: dropdown
id: regression
attributes:
label: Regression?
options:
- Unknown
- Yes, it worked before
- No, first-time setup
validations:
required: true

8
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View file

@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Security vulnerability report
url: https://github.com/theonlyhennygod/zeroclaw/security/policy
about: Please report security vulnerabilities privately via SECURITY.md policy.
- name: Contribution guide
url: https://github.com/theonlyhennygod/zeroclaw/blob/main/CONTRIBUTING.md
about: Please read contribution and PR requirements before opening an issue.

View file

@ -0,0 +1,64 @@
name: Feature Request
description: Propose an improvement or new capability
title: "[Feature]: "
body:
- type: markdown
attributes:
value: |
Thanks for sharing your idea.
Please focus on user value, constraints, and rollout safety.
- type: input
id: problem
attributes:
label: Problem statement
description: What user problem are you trying to solve?
placeholder: Teams need a way to ...
validations:
required: true
- type: textarea
id: proposal
attributes:
label: Proposed solution
description: Describe the preferred solution.
placeholder: Add a new subcommand / trait implementation ...
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives considered
description: What alternatives did you evaluate?
placeholder: Keep current behavior, use external tool, etc.
validations:
required: false
- type: textarea
id: architecture
attributes:
label: Architecture impact
description: Which subsystem(s) are affected?
placeholder: providers/, channels/, memory/, runtime/, security/ ...
validations:
required: true
- type: textarea
id: risk
attributes:
label: Risk and rollback
description: Main risk + how to disable/revert quickly.
placeholder: Risk is ... rollback is ...
validations:
required: true
- type: dropdown
id: breaking
attributes:
label: Breaking change?
options:
- No
- Yes
validations:
required: true

59
.github/labeler.yml vendored Normal file
View file

@ -0,0 +1,59 @@
"type: docs":
- changed-files:
- any-glob-to-any-file:
- "docs/**"
- "**/*.md"
- "LICENSE"
"type: dependencies":
- changed-files:
- any-glob-to-any-file:
- "Cargo.toml"
- "Cargo.lock"
- "deny.toml"
"type: ci":
- changed-files:
- any-glob-to-any-file:
- ".github/**"
- ".githooks/**"
"area: providers":
- changed-files:
- any-glob-to-any-file:
- "src/providers/**"
"area: channels":
- changed-files:
- any-glob-to-any-file:
- "src/channels/**"
"area: memory":
- changed-files:
- any-glob-to-any-file:
- "src/memory/**"
"area: security":
- changed-files:
- any-glob-to-any-file:
- "src/security/**"
"area: runtime":
- changed-files:
- any-glob-to-any-file:
- "src/runtime/**"
"area: tools":
- changed-files:
- any-glob-to-any-file:
- "src/tools/**"
"area: observability":
- changed-files:
- any-glob-to-any-file:
- "src/observability/**"
"area: tests":
- changed-files:
- any-glob-to-any-file:
- "tests/**"

70
.github/pull_request_template.md vendored Normal file
View file

@ -0,0 +1,70 @@
## Summary
Describe this PR in 2-5 bullets:
- Problem:
- Why it matters:
- What changed:
- What did **not** change (scope boundary):
## Change Type
- [ ] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Docs
- [ ] Security hardening
- [ ] Chore / infra
## Scope
- [ ] Core runtime / daemon
- [ ] Provider integration
- [ ] Channel integration
- [ ] Memory / storage
- [ ] Security / sandbox
- [ ] CI / release / tooling
- [ ] Documentation
## Linked Issue
- Closes #
- Related #
## Testing
Commands and result summary (required):
```bash
cargo fmt --all -- --check
cargo clippy --all-targets -- -D warnings
cargo test
```
If any command is intentionally skipped, explain why.
## Security Impact
- New permissions/capabilities? (`Yes/No`)
- New external network calls? (`Yes/No`)
- Secrets/tokens handling changed? (`Yes/No`)
- File system access scope changed? (`Yes/No`)
- If any `Yes`, describe risk and mitigation:
## Agent Collaboration Notes (recommended)
- [ ] If agent/automation tools were used, I added brief workflow notes.
- [ ] I included concrete validation evidence for this change.
- [ ] I can explain design choices and rollback steps.
If agent tools were used, optional context:
- Tool(s):
- Prompt/plan summary:
- Verification focus:
## Rollback Plan
- Fast rollback command/path:
- Feature flags or config toggles (if any):
- Observable failure symptoms:

40
.github/workflows/auto-response.yml vendored Normal file
View file

@ -0,0 +1,40 @@
name: Auto Response
on:
issues:
types: [opened]
pull_request_target:
types: [opened]
permissions: {}
jobs:
first-interaction:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- name: Greet first-time contributors
uses: actions/first-interaction@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
issue-message: |
Thanks for opening this issue.
Before maintainers triage it, please confirm:
- Repro steps are complete and run on latest `main`
- Environment details are included (OS, Rust version, ZeroClaw version)
- Sensitive values are redacted
This helps us keep issue throughput high and response latency low.
pr-message: |
Thanks for contributing to ZeroClaw.
For faster review, please ensure:
- PR template sections are fully completed
- `cargo fmt --all -- --check`, `cargo clippy --all-targets -- -D warnings`, and `cargo test` are included
- If automation/agents were used heavily, add brief workflow notes
- Scope is focused (prefer one concern per PR)
See `CONTRIBUTING.md` and `docs/pr-workflow.md` for full collaboration rules.

View file

@ -6,14 +6,86 @@ on:
pull_request:
branches: [main]
concurrency:
group: ci-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
jobs:
changes:
name: Detect Change Scope
runs-on: ubuntu-latest
outputs:
docs_only: ${{ steps.scope.outputs.docs_only }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect docs-only changes
id: scope
shell: bash
run: |
set -euo pipefail
if [ "${{ github.event_name }}" = "pull_request" ]; then
BASE="${{ github.event.pull_request.base.sha }}"
else
BASE="${{ github.event.before }}"
fi
if [ -z "$BASE" ] || ! git cat-file -e "$BASE^{commit}" 2>/dev/null; then
echo "docs_only=false" >> "$GITHUB_OUTPUT"
exit 0
fi
CHANGED="$(git diff --name-only "$BASE" HEAD || true)"
if [ -z "$CHANGED" ]; then
echo "docs_only=false" >> "$GITHUB_OUTPUT"
exit 0
fi
docs_only=true
while IFS= read -r file; do
[ -z "$file" ] && continue
case "$file" in
docs/*|*.md|*.mdx|LICENSE|.github/ISSUE_TEMPLATE/*|.github/pull_request_template.md)
;;
*)
docs_only=false
break
;;
esac
done <<< "$CHANGED"
echo "docs_only=$docs_only" >> "$GITHUB_OUTPUT"
lint:
name: Format & Lint
needs: [changes]
if: needs.changes.outputs.docs_only != 'true'
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Run rustfmt
run: cargo fmt --all -- --check
- name: Run clippy
run: cargo clippy --all-targets -- -D warnings
test:
name: Test
needs: [changes]
if: needs.changes.outputs.docs_only != 'true'
runs-on: ubuntu-latest
continue-on-error: true # Don't block PRs
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
@ -22,24 +94,55 @@ jobs:
run: cargo test --verbose
build:
name: Build
runs-on: ${{ matrix.os }}
continue-on-error: true # Don't block PRs on build failures
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
- os: macos-latest
target: x86_64-apple-darwin
- os: macos-latest
target: aarch64-apple-darwin
- os: windows-latest
target: x86_64-pc-windows-msvc
name: Build (Smoke)
needs: [changes]
if: needs.changes.outputs.docs_only != 'true'
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Build
run: cargo build --release --verbose
- name: Build release binary
run: cargo build --release --locked --verbose
docs-only:
name: Docs-Only Fast Path
needs: [changes]
if: needs.changes.outputs.docs_only == 'true'
runs-on: ubuntu-latest
steps:
- name: Skip heavy jobs for docs-only change
run: echo "Docs-only change detected. Rust lint/test/build skipped."
ci-required:
name: CI Required Gate
if: always()
needs: [changes, lint, test, build, docs-only]
runs-on: ubuntu-latest
steps:
- name: Enforce required status
shell: bash
run: |
set -euo pipefail
if [ "${{ needs.changes.outputs.docs_only }}" = "true" ]; then
echo "Docs-only fast path passed."
exit 0
fi
lint_result="${{ needs.lint.result }}"
test_result="${{ needs.test.result }}"
build_result="${{ needs.build.result }}"
echo "lint=${lint_result}"
echo "test=${test_result}"
echo "build=${build_result}"
if [ "$lint_result" != "success" ] || [ "$test_result" != "success" ] || [ "$build_result" != "success" ]; then
echo "Required CI jobs did not pass."
exit 1
fi
echo "All required CI jobs passed."

70
.github/workflows/labeler.yml vendored Normal file
View file

@ -0,0 +1,70 @@
name: PR Labeler
on:
pull_request_target:
types: [opened, reopened, synchronize, edited]
permissions:
contents: read
pull-requests: write
issues: write
jobs:
label:
runs-on: ubuntu-latest
steps:
- name: Apply path labels
uses: actions/labeler@v5
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Apply size label
uses: actions/github-script@v7
with:
script: |
const pr = context.payload.pull_request;
const sizeLabels = ["size: XS", "size: S", "size: M", "size: L", "size: XL"];
const labelColor = "BFDADC";
const changedLines = (pr.additions || 0) + (pr.deletions || 0);
let sizeLabel = "size: XL";
if (changedLines <= 80) sizeLabel = "size: XS";
else if (changedLines <= 250) sizeLabel = "size: S";
else if (changedLines <= 500) sizeLabel = "size: M";
else if (changedLines <= 1000) sizeLabel = "size: L";
for (const label of sizeLabels) {
try {
await github.rest.issues.getLabel({
owner: context.repo.owner,
repo: context.repo.repo,
name: label,
});
} catch (error) {
if (error.status !== 404) throw error;
await github.rest.issues.createLabel({
owner: context.repo.owner,
repo: context.repo.repo,
name: label,
color: labelColor,
});
}
}
const { data: currentLabels } = await github.rest.issues.listLabelsOnIssue({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
});
const keepLabels = currentLabels
.map((label) => label.name)
.filter((label) => !sizeLabels.includes(label));
const nextLabels = [...new Set([...keepLabels, sizeLabel])];
await github.rest.issues.setLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
labels: nextLabels,
});

44
.github/workflows/stale.yml vendored Normal file
View file

@ -0,0 +1,44 @@
name: Stale
on:
schedule:
- cron: "20 2 * * *"
workflow_dispatch:
permissions: {}
jobs:
stale:
permissions:
issues: write
pull-requests: write
runs-on: ubuntu-latest
steps:
- name: Mark stale issues and pull requests
uses: actions/stale@v9
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-issue-stale: 21
days-before-issue-close: 7
days-before-pr-stale: 14
days-before-pr-close: 7
stale-issue-label: stale
stale-pr-label: stale
exempt-issue-labels: security,pinned,no-stale,maintainer
exempt-pr-labels: no-stale,maintainer
remove-stale-when-updated: true
exempt-all-assignees: true
operations-per-run: 300
stale-issue-message: |
This issue was automatically marked as stale due to inactivity.
Please provide an update, reproduction details, or current status to keep it open.
close-issue-message: |
Closing this issue due to inactivity.
If the problem still exists on the latest `main`, please open a new issue with fresh repro steps.
close-issue-reason: not_planned
stale-pr-message: |
This PR was automatically marked as stale due to inactivity.
Please rebase/update and post the latest validation results.
close-pr-message: |
Closing this PR due to inactivity.
Maintainers can reopen once the branch is updated and validation is provided.

63
.github/workflows/workflow-sanity.yml vendored Normal file
View file

@ -0,0 +1,63 @@
name: Workflow Sanity
on:
pull_request:
paths:
- ".github/workflows/**"
- ".github/*.yml"
- ".github/*.yaml"
push:
branches: [main]
paths:
- ".github/workflows/**"
- ".github/*.yml"
- ".github/*.yaml"
concurrency:
group: workflow-sanity-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
permissions:
contents: read
jobs:
no-tabs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Fail on tabs in workflow files
shell: bash
run: |
set -euo pipefail
python - <<'PY'
from __future__ import annotations
import pathlib
import sys
root = pathlib.Path(".github/workflows")
bad: list[str] = []
for path in sorted(root.rglob("*.yml")):
if b"\t" in path.read_bytes():
bad.append(str(path))
for path in sorted(root.rglob("*.yaml")):
if b"\t" in path.read_bytes():
bad.append(str(path))
if bad:
print("Tabs found in workflow file(s):")
for path in bad:
print(f"- {path}")
sys.exit(1)
PY
actionlint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Lint GitHub workflows
uses: rhysd/actionlint@v1

158
AGENTS.md Normal file
View file

@ -0,0 +1,158 @@
# AGENTS.md — ZeroClaw Agent Coding Guide
This file defines the default working protocol for coding agents in this repository.
Scope: entire repository.
## 1) Project Snapshot (Read First)
ZeroClaw is a Rust-first autonomous agent runtime optimized for:
- high performance
- high efficiency
- high stability
- high extensibility
- high sustainability
- high security
Core architecture is trait-driven and modular. Most extension work should be done by implementing traits and registering in factory modules.
Key extension points:
- `src/providers/traits.rs` (`Provider`)
- `src/channels/traits.rs` (`Channel`)
- `src/tools/traits.rs` (`Tool`)
- `src/memory/traits.rs` (`Memory`)
- `src/observability/traits.rs` (`Observer`)
- `src/runtime/traits.rs` (`RuntimeAdapter`)
## 2) Repository Map (High-Level)
- `src/main.rs` — CLI entrypoint and command routing
- `src/lib.rs` — module exports and shared command enums
- `src/config/` — schema + config loading/merging
- `src/agent/` — orchestration loop
- `src/gateway/` — webhook/gateway server
- `src/security/` — policy, pairing, secret store
- `src/memory/` — markdown/sqlite memory backends + embeddings/vector merge
- `src/providers/` — model providers and resilient wrapper
- `src/channels/` — Telegram/Discord/Slack/etc channels
- `src/tools/` — tool execution surface (shell, file, memory, browser)
- `src/runtime/` — runtime adapters (currently native)
- `docs/` — architecture + process docs
- `.github/` — CI, templates, automation workflows
## 3) Non-Negotiable Engineering Constraints
### 3.1 Performance and Footprint
- Prefer minimal dependencies; avoid adding crates unless clearly justified.
- Preserve release-size profile assumptions in `Cargo.toml`.
- Avoid unnecessary allocations, clones, and blocking operations.
- Keep startup path lean; avoid heavy initialization in command parsing flow.
### 3.2 Security and Safety
- Treat `src/security/`, `src/gateway/`, `src/tools/` as high-risk surfaces.
- Never broaden filesystem/network execution scope without explicit policy checks.
- Never log secrets, tokens, raw credentials, or sensitive payloads.
- Keep default behavior secure-by-default (deny-by-default where applicable).
### 3.3 Stability and Compatibility
- Preserve CLI contract unless change is intentional and documented.
- Prefer explicit errors over silent fallback for unsupported critical paths.
- Keep changes local; avoid cross-module refactors in unrelated tasks.
## 4) Agent Workflow (Required)
1. **Read before write**
- Inspect existing module and adjacent tests before editing.
2. **Define scope boundary**
- One concern per PR; avoid mixed feature+refactor+infra patches.
3. **Implement minimal patch**
- Follow KISS/YAGNI/DRY; no speculative abstractions.
4. **Validate by risk**
- Docs-only: keep checks lightweight.
- Code changes: run relevant checks and tests.
5. **Document impact**
- Update docs/PR notes for behavior, risk, rollback.
## 5) Change Playbooks
### 5.1 Adding a Provider
- Implement `Provider` in `src/providers/`.
- Register in `src/providers/mod.rs` factory.
- Add focused tests for factory wiring and error paths.
### 5.2 Adding a Channel
- Implement `Channel` in `src/channels/`.
- Ensure `send`, `listen`, and `health_check` semantics are consistent.
- Cover auth/allowlist/health behavior with tests.
### 5.3 Adding a Tool
- Implement `Tool` in `src/tools/` with strict parameter schema.
- Validate and sanitize all inputs.
- Return structured `ToolResult`; avoid panics in runtime path.
### 5.4 Security / Runtime / Gateway Changes
- Include threat/risk notes and rollback strategy.
- Add or update tests for boundary checks and failure modes.
- Keep observability useful but non-sensitive.
## 6) Validation Matrix
Default local checks for code changes:
```bash
cargo fmt --all -- --check
cargo clippy --all-targets -- -D warnings
cargo test
```
If full checks are impractical, run the most relevant subset and document what was skipped and why.
For workflow/template-only changes, at least ensure YAML/template syntax validity.
## 7) Collaboration and PR Discipline
- Follow `.github/pull_request_template.md`.
- Keep PR descriptions concrete: problem, change, non-goals, risk, rollback.
- Use conventional commit titles.
- Prefer small PRs (`size: XS/S/M`) when possible.
Reference docs:
- `CONTRIBUTING.md`
- `docs/pr-workflow.md`
## 8) Anti-Patterns (Do Not)
- Do not add heavy dependencies for minor convenience.
- Do not silently weaken security policy or access constraints.
- Do not mix massive formatting-only changes with functional changes.
- Do not modify unrelated modules "while here".
- Do not bypass failing checks without explicit explanation.
## 9) Handoff Template (Agent -> Agent / Maintainer)
When handing off work, include:
1. What changed
2. What did not change
3. Validation run and results
4. Remaining risks / unknowns
5. Next recommended action
## 10) Vibe Coding Guardrails
When working in a fast iterative "vibe coding" style:
- Keep each iteration reversible (small commits, clear rollback).
- Validate assumptions with code search before implementing.
- Prefer deterministic behavior over clever shortcuts.
- Do not "ship and hope" on security-sensitive paths.
- If uncertain, leave a concrete TODO with verification context, not a hidden guess.

View file

@ -37,6 +37,33 @@ git push --no-verify
> **Note:** CI runs the same checks, so skipped hooks will be caught on the PR.
## High-Volume Collaboration Rules
When PR traffic is high (especially with AI-assisted contributions), these rules keep quality and throughput stable:
- **One concern per PR**: avoid mixing refactor + feature + infra in one change.
- **Small PRs first**: prefer PR size `XS/S/M`; split large work into stacked PRs.
- **Template is mandatory**: complete every section in `.github/pull_request_template.md`.
- **Explicit rollback**: every PR must include a fast rollback path.
- **Security-first review**: changes in `src/security/`, runtime, and CI need stricter validation.
Full maintainer workflow: [`docs/pr-workflow.md`](docs/pr-workflow.md).
## Agent Collaboration Guidance
Agent-assisted contributions are welcome and treated as first-class contributions.
For smoother agent-to-agent and human-to-agent review:
- Keep PR summaries concrete (problem, change, non-goals).
- Include reproducible validation evidence (`fmt`, `clippy`, `test`, scenario checks).
- Add brief workflow notes when automation materially influenced design/code.
- Call out uncertainty and risky edges explicitly.
We do **not** require PRs to declare an AI-vs-human line ratio.
Agent implementation playbook lives in [`AGENTS.md`](AGENTS.md).
## Architecture: Trait-Based Pluggability
ZeroClaw's architecture is built on **traits** — every subsystem is swappable. This means contributing a new integration is as simple as implementing a trait and registering it in the factory function.
@ -184,8 +211,9 @@ impl Tool for YourTool {
## Pull Request Checklist
- [ ] `cargo fmt` — code is formatted
- [ ] `cargo clippy -- -D warnings` — no warnings
- [ ] PR template sections are completed (including security + rollback)
- [ ] `cargo fmt --all -- --check` — code is formatted
- [ ] `cargo clippy --all-targets -- -D warnings` — no warnings
- [ ] `cargo test` — all 129+ tests pass
- [ ] New code has inline `#[cfg(test)]` tests
- [ ] No new dependencies unless absolutely necessary (we optimize for binary size)
@ -198,6 +226,7 @@ We use [Conventional Commits](https://www.conventionalcommits.org/):
```
feat: add Anthropic provider
feat(provider): add Anthropic provider
fix: path traversal edge case with symlinks
docs: update contributing guide
test: add heartbeat unicode parsing tests
@ -205,6 +234,10 @@ refactor: extract common security checks
chore: bump tokio to 1.43
```
Recommended scope keys in commit titles:
- `provider`, `channel`, `memory`, `security`, `runtime`, `ci`, `docs`, `tests`
## Code Style
- **Minimal dependencies** — every crate adds to binary size
@ -219,6 +252,14 @@ chore: bump tokio to 1.43
- **Features**: Describe the use case, propose which trait to extend
- **Security**: See [SECURITY.md](SECURITY.md) for responsible disclosure
## Maintainer Merge Policy
- Require passing `CI Required Gate` before merge.
- Require review approval for non-trivial changes.
- Require CODEOWNERS review for protected paths.
- Prefer squash merge with conventional commit title.
- Revert fast on regressions; re-land with tests.
## License
By contributing, you agree that your contributions will be licensed under the MIT License.

178
docs/pr-workflow.md Normal file
View file

@ -0,0 +1,178 @@
# ZeroClaw PR Workflow (High-Volume Collaboration)
This document defines how ZeroClaw handles high PR volume while maintaining:
- High performance
- High efficiency
- High stability
- High extensibility
- High sustainability
- High security
## 1) Governance Goals
1. Keep merge throughput predictable under heavy PR load.
2. Keep CI signal quality high (fast feedback, low false positives).
3. Keep security review explicit for risky surfaces.
4. Keep changes easy to reason about and easy to revert.
## 2) Required Repository Settings
Maintain these branch protection rules on `main`:
- Require status checks before merge.
- Require check `CI Required Gate`.
- Require pull request reviews before merge.
- Require CODEOWNERS review for protected paths.
- Dismiss stale approvals when new commits are pushed.
- Restrict force-push on protected branches.
## 3) PR Lifecycle
### Step A: Intake
- Contributor opens PR with full `.github/pull_request_template.md`.
- `PR Labeler` applies path labels + size labels.
- `Auto Response` posts first-time contributor guidance.
### Step B: Validation
- `CI Required Gate` is the merge gate.
- Docs-only PRs use fast-path and skip heavy Rust jobs.
- Non-doc PRs must pass lint, tests, and release build smoke check.
### Step C: Review
- Reviewers prioritize by risk and size labels.
- Security-sensitive paths (`src/security`, runtime, CI) require maintainer attention.
- Large PRs (`size: L`/`size: XL`) should be split unless strongly justified.
### Step D: Merge
- Prefer **squash merge** to keep history compact.
- PR title should follow Conventional Commit style.
- Merge only when rollback path is documented.
## 4) PR Size Policy
- `size: XS` <= 80 changed lines
- `size: S` <= 250 changed lines
- `size: M` <= 500 changed lines
- `size: L` <= 1000 changed lines
- `size: XL` > 1000 changed lines
Policy:
- Target `XS/S/M` by default.
- `L/XL` PRs need explicit justification and tighter test evidence.
- If a large feature is unavoidable, split into stacked PRs.
## 5) AI/Agent Contribution Policy
AI-assisted PRs are welcome, and review can also be agent-assisted.
Required:
1. Clear PR summary with scope boundary.
2. Explicit test/validation evidence.
3. Security impact and rollback notes for risky changes.
Recommended:
1. Brief tool/workflow notes when automation materially influenced the change.
2. Optional prompt/plan snippets for reproducibility.
We do **not** require contributors to quantify AI-vs-human line ownership.
Review emphasis for AI-heavy PRs:
- Contract compatibility
- Security boundaries
- Error handling and fallback behavior
- Performance and memory regressions
## 6) Review SLA and Queue Discipline
- First maintainer triage target: within 48 hours.
- If PR is blocked, maintainer leaves one actionable checklist.
- `stale` automation is used to keep queue healthy; maintainers can apply `no-stale` when needed.
## 7) Security and Stability Rules
Changes in these areas require stricter review and stronger test evidence:
- `src/security/**`
- runtime process management
- filesystem access boundaries
- network/authentication behavior
- GitHub workflows and release pipeline
Minimum for risky PRs:
- threat/risk statement
- mitigation notes
- rollback steps
## 8) Failure Recovery
If a merged PR causes regressions:
1. Revert PR immediately on `main`.
2. Open a follow-up issue with root-cause analysis.
3. Re-introduce fix only with regression tests.
Prefer fast restore of service quality over delayed perfect fixes.
## 9) Maintainer Checklist (Merge-Ready)
- Scope is focused and understandable.
- CI gate is green.
- Security impact fields are complete.
- Agent workflow notes are sufficient for reproducibility (if automation was used).
- Rollback plan is explicit.
- Commit title follows Conventional Commits.
## 10) Agent Review Operating Model
To keep review quality stable under high PR volume, we use a two-lane review model:
### Lane A: Fast triage (agent-friendly)
- Confirm PR template completeness.
- Confirm CI gate signal (`CI Required Gate`).
- Confirm risk class via labels and touched paths.
- Confirm rollback statement exists.
### Lane B: Deep review (risk-based)
Required for high-risk changes (security/runtime/gateway/CI):
- Validate threat model assumptions.
- Validate failure mode and degradation behavior.
- Validate backward compatibility and migration impact.
- Validate observability/logging impact.
## 11) Queue Priority and Label Discipline
Triage order recommendation:
1. `size: XS`/`size: S` + bug/security fixes
2. `size: M` focused changes
3. `size: L`/`size: XL` split requests or staged review
Label discipline:
- Path labels identify subsystem ownership quickly.
- Size labels drive batching strategy.
- `no-stale` is reserved for accepted-but-blocked work.
## 12) Agent Handoff Contract
When one agent hands off to another (or to a maintainer), include:
1. Scope boundary (what changed / what did not).
2. Validation evidence.
3. Open risks and unknowns.
4. Suggested next action.
This keeps context loss low and avoids repeated deep dives.