Skip to content

Commit f591022

Browse files
ci: add PR English check and translate AGENTS.md for Codex review (#68)
* ci: add PR English language check job Add pr-language job that checks PR title and body contain primarily ASCII characters (threshold: 30% non-ASCII fails). This enforces English-only PR descriptions for consistency. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: translate all AGENTS.md files to English Translate root and subdirectory AGENTS.md files from Japanese to English for Codex automatic review compatibility. Add Review Guidelines sections for Codex to follow. CLAUDE.md remains in Japanese as the Claude Code instruction file. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * ci: add Claude Code PR review workflow Add GitHub Actions workflow for automated PR review using anthropics/claude-code-action. Runs on PR open/sync and @claude comments. Uses OAuth token (Pro/Max plan) to avoid API usage costs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent d8226e5 commit f591022

7 files changed

Lines changed: 382 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,47 @@ jobs:
232232
name: benchmark-results
233233
path: bench/benchmark_results.txt
234234

235+
pr-language:
236+
name: PR language check (English)
237+
if: github.event_name == 'pull_request'
238+
runs-on: ubuntu-latest
239+
steps:
240+
- name: Check PR title and body are in English
241+
uses: actions/github-script@v7
242+
with:
243+
script: |
244+
const title = context.payload.pull_request.title;
245+
const body = context.payload.pull_request.body || '';
246+
247+
// Detect non-ASCII heavy content (CJK, Cyrillic, etc.)
248+
const nonAsciiRatio = (str) => {
249+
if (!str || str.length === 0) return 0;
250+
const nonAscii = str.match(/[^\x00-\x7F]/g) || [];
251+
return nonAscii.length / str.length;
252+
};
253+
254+
const titleRatio = nonAsciiRatio(title);
255+
const bodyRatio = nonAsciiRatio(body);
256+
257+
console.log(`Title non-ASCII ratio: ${(titleRatio * 100).toFixed(1)}%`);
258+
console.log(`Body non-ASCII ratio: ${(bodyRatio * 100).toFixed(1)}%`);
259+
260+
const threshold = 0.3;
261+
const issues = [];
262+
263+
if (titleRatio > threshold) {
264+
issues.push(`PR title contains ${(titleRatio * 100).toFixed(0)}% non-ASCII characters. Please use English.`);
265+
}
266+
if (body.length > 0 && bodyRatio > threshold) {
267+
issues.push(`PR body contains ${(bodyRatio * 100).toFixed(0)}% non-ASCII characters. Please use English.`);
268+
}
269+
270+
if (issues.length > 0) {
271+
core.setFailed(issues.join('\n'));
272+
} else {
273+
console.log('PR title and body are in English.');
274+
}
275+
235276
links:
236277
name: README and docs link check
237278
runs-on: ubuntu-latest

.github/workflows/claude.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Claude Code
2+
3+
on:
4+
issue_comment:
5+
types: [created]
6+
pull_request_review_comment:
7+
types: [created]
8+
pull_request:
9+
types: [opened, synchronize]
10+
11+
jobs:
12+
claude:
13+
if: |
14+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
15+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
16+
(github.event_name == 'pull_request')
17+
runs-on: ubuntu-latest
18+
permissions:
19+
contents: read
20+
pull-requests: write
21+
issues: write
22+
id-token: write
23+
steps:
24+
- uses: actions/checkout@v4
25+
26+
- uses: anthropics/claude-code-action@v1
27+
with:
28+
anthropic_api_key: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
29+
prompt: |
30+
Review this PR. Follow the guidelines in CLAUDE.md and AGENTS.md.
31+
Focus on:
32+
- Correctness and potential bugs
33+
- Go error wrapping (fmt.Errorf with %w)
34+
- Python type hints and docstrings
35+
- UDS security (socket permissions, HMAC)
36+
- Performance regressions in IPC paths
37+
Be concise. Only flag real issues.
38+
claude_args: "--max-turns 5 --model claude-sonnet-4-5-20250929"

AGENTS.md

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
<!-- OPENSPEC:START -->
2+
# OpenSpec Integration
3+
4+
This project uses OpenSpec for spec-driven development. When creating proposals, refer to:
5+
6+
- `openspec/AGENTS.md` - Workflow and format
7+
- `openspec/project.md` - Project conventions
8+
- `openspec/specs/` - Current specifications
9+
- `openspec/changes/` - In-progress proposals
10+
11+
Before starting spec-driven development, run `openspec list` and `openspec show [item]` to review the current state.
12+
<!-- OPENSPEC:END -->
13+
14+
---
15+
16+
# pyproc - AI Agent Instructions
17+
18+
## Project Core
19+
20+
pyproc's scope is fixed to "fast, stable invocation of Python from Go as if it were a local function, within the same host/Pod via UDS." Cross-host communication is out of scope.
21+
22+
v1.0 "Done" means not adding features, but "meeting the conditions for enterprise adoption":
23+
- API/protocol stabilization
24+
- Documentation and automation of operations, observability, security, compatibility, and release processes
25+
26+
## Public API (subject to SemVer)
27+
28+
1. Go API: exported symbols in `pkg/pyproc` (Pool, WorkerConfig, CallTyped, CodecType, Transport, etc.)
29+
2. Python worker API: `expose`, `run_worker`
30+
3. Wire protocol: compatibility conditions for JSON/MessagePack/Protobuf codecs
31+
4. Config schema & env vars: `PYPROC_POOL_WORKERS`, `PYPROC_SOCKET_DIR`, etc.
32+
33+
## SemVer Policy (0.y.z period)
34+
35+
- Breaking changes bump MINOR (y)
36+
- v1.0.0 defines the Public API
37+
- Released versions are immutable (fixes ship as new versions)
38+
- Go: tags `vX.Y.Z` (Go Modules convention)
39+
- Python: PEP 440 compliant `X.Y.Z`
40+
41+
Current version gap: Go v0.4.0 / pyproc-worker 0.1.0
42+
43+
## Non-Goals
44+
45+
- Cross-host communication (use gRPC/REST services instead)
46+
- Arbitrary user-submitted Python code execution (trusted code assumption)
47+
- GPU cluster management or distributed inference infrastructure
48+
49+
## K8s/Container Strategy
50+
51+
Achieved through "K8s + container distribution completeness," not cloud-specific solutions:
52+
- Reference Dockerfile (Go binary + Python runtime + pyproc-worker)
53+
- K8s manifests (emptyDir for socket write directory)
54+
- Same-container configuration is first-class (sidecar separation is a non-goal for v1.0)
55+
56+
## v1.0 Roadmap
57+
58+
- v0.5.0: High-efficiency IPC enhancements, config schema formalization, Dockerfile stabilization
59+
- v0.6.0: Public API outline freeze, deprecate-then-remove procedure, compatibility table publication
60+
- v0.7.0: Observability (metrics name/label/semantics stabilization)
61+
- v0.8.0: Security hardening (UDS permissions/HMAC auth templating, K8s emptyDir design guidelines)
62+
- v0.9.0: API Freeze, compatibility tests (contract tests) in CI
63+
- v1.0.0: Public API finalized, enterprise-ready release
64+
65+
See `.ssd/` for details.
66+
67+
## Command Reference
68+
69+
```bash
70+
# Go tests (race detector enabled)
71+
go test -v -race ./...
72+
73+
# Python tests
74+
cd worker/python && uv run pytest -v --cov=pyproc_worker
75+
76+
# Go lint
77+
golangci-lint run ./...
78+
79+
# Python lint + format
80+
cd worker/python && uv run ruff check . && uv run ruff format --check .
81+
82+
# Benchmarks
83+
make bench-quick
84+
85+
# OpenSpec
86+
openspec list
87+
openspec show [item]
88+
openspec validate --strict
89+
```
90+
91+
## Subdirectory AGENTS.md
92+
93+
- `worker/python/AGENTS.md` - Python worker development
94+
- `internal/AGENTS.md` - Go internal implementation
95+
- `docs/AGENTS.md` - Documentation
96+
- `bench/AGENTS.md` - Benchmarks
97+
98+
## Documentation
99+
100+
- `README.md` - User-facing overview
101+
- `CONTRIBUTING.md` - Contribution guide
102+
- `docs/design.md` - Design decisions
103+
- `docs/security.md` - Security threat model
104+
- `docs/ops.md` - Operations guide
105+
106+
## Review Guidelines
107+
108+
- Go errors must be wrapped with `fmt.Errorf("context: %w", err)`
109+
- Python functions must have type hints and Google-style docstrings
110+
- All exported Go types/functions must have doc comments
111+
- Channel operations must use `select + context.Done()` for cancellation
112+
- UDS socket permissions must be 0660
113+
- Do not log PII or secrets
114+
- Do not weaken tests, lints, or CI gates to pass checks
115+
- Security-related files (`docs/security.md`, `internal/protocol/`, `.claude/rules/security.md`) require explicit reviewer approval
116+
- Performance-sensitive changes in IPC hot paths must include benchmark results

bench/AGENTS.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Benchmarks
2+
3+
Performance measurement and CI gates.
4+
5+
## Commands
6+
7+
```bash
8+
# Quick run
9+
go test -bench=BenchmarkPool -benchtime=10x .
10+
11+
# Full run (with memory profiling)
12+
go test -bench=. -benchtime=100x -benchmem .
13+
14+
# Latency percentiles
15+
go test -bench=BenchmarkLatencyPercentiles -benchtime=10s .
16+
```
17+
18+
## CI Gate Thresholds
19+
20+
| Metric | Target | Notes |
21+
|--------|--------|-------|
22+
| p50 | < 100us | Simple function call |
23+
| p99 | < 500us | Includes GC and process overhead |
24+
25+
Threshold violations trigger CI warnings (currently non-blocking).
26+
27+
## Adding Benchmarks
28+
29+
- `Benchmark` prefix required
30+
- Reflect real use cases (synthetic benchmarks must be labeled separately)
31+
- Include parallelism tests with varying worker counts
32+
- Output both req/s and latency
33+
34+
## Notes
35+
36+
- Python worker required (`uv sync` must be completed)
37+
- Socket files created at `/tmp/pyproc-*.sock`; cleaned up on exit
38+
- CI and local results may differ (use relative comparisons, not absolute values)
39+
40+
## Review Guidelines
41+
42+
- Benchmark changes must include before/after comparison results
43+
- Do not lower CI gate thresholds without explicit approval
44+
- New benchmarks must test realistic workloads

docs/AGENTS.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Documentation
2+
3+
User-facing documentation. Built with MkDocs.
4+
5+
## Commands
6+
7+
```bash
8+
# Local preview
9+
mkdocs serve
10+
11+
# Link validation (runs in CI)
12+
lychee --config ../.lychee.toml *.md
13+
```
14+
15+
## File Structure
16+
17+
```
18+
docs/
19+
├── design.md Architecture, design decisions
20+
├── ops.md Operations guide, monitoring, troubleshooting
21+
└── security.md Threat model, security boundaries
22+
```
23+
24+
## Writing Conventions
25+
26+
- Heading levels: H1 for title only, body starts at H2
27+
- Code blocks: language specifier required (```go, ```python, ```bash)
28+
- Internal links: use relative paths (`[ops](ops.md)`)
29+
- External links: CI validates with lychee; broken links block merge
30+
31+
## Notes
32+
33+
- Changes to `security.md` require review (security impact)
34+
- Maintain consistency with README.md (avoid duplication, cross-reference)
35+
- Diagrams: use Mermaid or ASCII art (avoid external image dependencies)
36+
37+
## Review Guidelines
38+
39+
- All code examples must be runnable and tested
40+
- Security documentation changes require explicit reviewer approval
41+
- Links must be valid (CI enforced via lychee)

internal/AGENTS.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Internal Packages
2+
3+
Non-public implementation. Referenced only from pkg/pyproc.
4+
5+
## Design Principles
6+
7+
- Thin pkg, thick internal: public API in pkg/, implementation details in internal/
8+
- Interface boundaries: protocol, health, logging are independently swappable
9+
- Error propagation: always wrap with `fmt.Errorf("context: %w", err)`
10+
11+
## Package Structure
12+
13+
```
14+
internal/
15+
├── protocol/ UDS communication, message serialization (msgpack)
16+
├── health/ Health checks, automatic restart
17+
└── logging/ Structured logging
18+
```
19+
20+
## Code Conventions
21+
22+
- Doc comments required on all exported types/functions
23+
- context.Context is the first parameter
24+
- Channel operations must use select + context.Done() for cancellation
25+
- Table-driven tests recommended
26+
27+
## Tests
28+
29+
```bash
30+
go test -v -race ./internal/...
31+
go test -coverprofile=coverage.out ./internal/...
32+
```
33+
34+
Coverage target: 100% (CI non-blocking but aimed for)
35+
36+
## Review Guidelines
37+
38+
- Errors must be wrapped with `fmt.Errorf("context: %w", err)`
39+
- All channel operations must be cancellable via context
40+
- Security-sensitive code in protocol/ requires explicit approval
41+
- No exported symbols should leak from internal/

worker/python/AGENTS.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Python Worker
2+
3+
pyproc-worker PyPI package. Python worker implementation called from Go via UDS.
4+
5+
## Commands
6+
7+
```bash
8+
# Install dependencies (pip is not supported)
9+
uv sync --all-extras --dev
10+
11+
# Tests
12+
uv run pytest -v --cov=pyproc_worker --cov-report=term-missing
13+
14+
# Lint & Format
15+
uv run ruff check .
16+
uv run ruff format --check .
17+
18+
# Type check
19+
uv run ty check .
20+
```
21+
22+
## Code Conventions
23+
24+
- Type hints required on all function signatures
25+
- Docstrings: Google style (Args/Returns/Raises)
26+
- Use `@expose` decorator to register public functions
27+
- Raise errors explicitly; minimize catch blocks
28+
29+
## File Structure
30+
31+
```
32+
pyproc_worker/
33+
├── __init__.py # expose, Worker class, run_worker exports
34+
├── codec.py # JSONCodec, get_codec()
35+
├── tracing.py # OpenTelemetry integration
36+
├── cancellation.py # CancellationError, CancellationManager
37+
└── cli.py # CLI entry point
38+
tests/
39+
└── test_*.py # pytest format
40+
```
41+
42+
## Public API (subject to SemVer)
43+
44+
- `expose` decorator
45+
- `run_worker` function
46+
- Their arguments, exceptions, and return types will be frozen at v1.0
47+
48+
## Notes
49+
50+
- GIL is bypassed via process isolation (not threads)
51+
- Load models/heavy libraries at worker startup (not per-request)
52+
- Avoid memory leaks: do not accumulate global state
53+
- orjson is the default codec; msgspec is optional
54+
- Currently v0.1.0. Maintain compatibility table with Go side v0.4.0
55+
56+
## Review Guidelines
57+
58+
- All functions must have type hints and Google-style docstrings
59+
- Do not use pip; uv is the only supported package manager
60+
- Error messages must not leak internal state or PII
61+
- Test coverage must not decrease

0 commit comments

Comments
 (0)