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
167 changes: 167 additions & 0 deletions .aiguard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
version: 1

context:
small:
include:
- ARCHITECTURE.md
- SNAPSHOT.md
- README.md
- pyproject.toml
- package.json
- frontend/package.json
- contracts/**
large:
roots: [backend, app, src, frontend]
exclude_dirs:
- .git
- .venv
- venv
- node_modules
- dist
- build
- .next
- __pycache__


- __pypackages__

- .pytest_cache
- .mypy_cache
- .ruff_cache
exclude_globs: ["**/*.min.js", "**/*.map"]
max_files: 220
max_kb_each: 64

evidence:
commands:
- git status --porcelain=v1 || true
- git diff || true
- python --version || true
- node --version || true
- npm --version || true


evidence:
commands:
- git status --porcelain=v1 || true
- git diff || true
- python --version || true
- node --version || true
- npm --version || true


dlp:
enable: true
block_on_detect: true
mask: true
allowlist_files:
- ".env.example"
- "frontend/.env.example"

guard:

max_files: 10
max_lines: 400
forbid_full_rewrite: true

forbid_full_rewrite: true
allow_full_rewrite_globs:
- "core/aiguard.py"
- ".github/workflows/oceansguard.yml"



checks:
commands:
# ====

# Backend (FastAPI / Python)
# ====

# compileall: backend/app/src が存在する場合のみ実行(無ければスキップ)

# Backend (Python)
# ====

- >
python -c "import os,sys,subprocess;
targets=[d for d in ('backend','app','src') if os.path.isdir(d)];
sys.exit(subprocess.call([sys.executable,'-m','compileall',*targets]) if targets else 0)"


# ruff: インストール済み かつ 対象dir存在時のみ実行(無ければスキップ)


- >
python -c "import os,sys,subprocess,importlib.util;
targets=[d for d in ('backend','app','src') if os.path.isdir(d)];
has=importlib.util.find_spec('ruff') is not None;
sys.exit(subprocess.call([sys.executable,'-m','ruff','check',*targets]) if (has and targets) else 0)"


# mypy: インストール済み かつ 対象dir存在時のみ実行(無ければスキップ)


- >
python -c "import os,sys,subprocess,importlib.util;
targets=[d for d in ('backend','app','src') if os.path.isdir(d)];
has=importlib.util.find_spec('mypy') is not None;
sys.exit(subprocess.call([sys.executable,'-m','mypy',*targets]) if (has and targets) else 0)"


# pytest: tests が存在し、pytest導入済みの場合のみ実行(無ければスキップ)


- >
python -c "import os,sys,subprocess,importlib.util;
has=importlib.util.find_spec('pytest') is not None;
has_tests=any(os.path.isdir(p) for p in ('tests','backend/tests','app/tests','src/tests'));
sys.exit(subprocess.call([sys.executable,'-m','pytest','-q']) if (has and has_tests) else 0)"

# ====

# Frontend (React / Node)
# ====

# npm ci (or npm install): frontend が存在する場合のみ実行

# Frontend (React)
# ====

- >
python -c "import os,sys,subprocess;
d='frontend';
sys.exit(0 if not os.path.isdir(d) else (subprocess.call('npm ci --silent', cwd=d, shell=True) if os.path.exists(os.path.join(d,'package-lock.json')) else subprocess.call('npm install --silent', cwd=d, shell=True)))"


# npm run build: frontend が存在する場合のみ実行


- >
python -c "import os,sys,subprocess;
d='frontend';
sys.exit(0 if not os.path.isdir(d) else subprocess.call('npm run build --silent', cwd=d, shell=True))"


# (既存の Python / React checks の下に追加)
- python core/openapi_contract.py

- >
python -c "import os,sys;
sys.exit(0 if not os.path.exists('contracts/openapi.json') else
__import__('subprocess').call([sys.executable,'core/openapi_contract.py']))"

# 失敗時ログ要約(check が失敗しても要約は残す)
- python core/summarize_logs.py || true




output:
pack: ai_context_pack.md
audit: CHANGELOG_AI.md
testlog: ai_test_last.log


report_json: ai_check_report.json

31 changes: 23 additions & 8 deletions .github/workflows/oceansguard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,36 @@ jobs:
- name: Upgrade pip
run: python -m pip install --upgrade pip

# FastAPI / OpenAPI契約チェック用(未使用PJでも害なし)
- name: Install Python tooling (best-effort)
- name: Install tooling (best-effort)
run: |
pip install uvicorn fastapi || true
pip install pyyaml || true
pip install ruff mypy pytest || true
pip install uvicorn fastapi || true

- name: Resolve OceansGuard entry
id: og
run: |
if [ -f "tools/OceansGuard/core/aiguard.py" ]; then
echo "ENTRY=tools/OceansGuard/core/aiguard.py" >> $GITHUB_OUTPUT
elif [ -f "core/aiguard.py" ]; then
echo "ENTRY=core/aiguard.py" >> $GITHUB_OUTPUT
else
echo "OceansGuard entry not found" >&2
exit 1
fi

# React がある場合に備えて:node_modules はnpm ci/build側で吸収
- name: OceansGuard init (idempotent)
run: |
python tools/OceansGuard/core/aiguard.py init
python "${{ steps.og.outputs.ENTRY }}" init --repo .

- name: OceansGuard pack
- name: OceansGuard run (pack + check)
run: |
python tools/OceansGuard/core/aiguard.py pack

python "${{ steps.og.outputs.ENTRY }}" pack --repo .

- name: OceansGuard check
run: |
python tools/OceansGuard/core/aiguard.py check
python "${{ steps.og.outputs.ENTRY }}" check --repo .

python "${{ steps.og.outputs.ENTRY }}" run --repo . --task "CI guard" --strict

4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,6 @@ cython_debug/
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
# refer to https://docs.cursor.com/context/ignore-files
.cursorignore
.cursorindexingignore
.cursorindexingignoreai_context_pack.md
ai_check_report.json
ai_test_last.log
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "common"]
path = common
url = https://github.com/OceansCreative/OceansCommon.git
11 changes: 11 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# ARCHITECTURE

- レイヤ構成
- 依存方向
- 外部I/O(API/DB)


_generated by OceansGuard init @ 2025-12-31T00:29:25_

_generated by OceansGuard init @ 2025-12-31T10:35:26_

107 changes: 59 additions & 48 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,50 +1,61 @@
# README.md
# OceansGuard

OceansGuard は、生成AIによるコード変更を
**CI・契約・セキュリティで機械的に裁くためのガードレール**です。

## 目的
- AIにコードを書かせても事故らせない
- 人が説明・確認・判断しなくてよい開発
- どの言語・フレームワークでも共通運用

## 基本思想
- AIは「提案者」
- 正しさは「テスト・契約・ポリシー」が決める
- 通らない変更は採用されない

## 使い方(各プロジェクト側)
```bash
python path/to/aiguard.py init
python path/to/aiguard.py pack
python path/to/aiguard.py check

対応フェーズ

開発前 / 開発途中 / 開発後 すべて対応


---

## ③ あなたの「不可がほぼ無い」運用フロー(確定)
**どの案件でもこれだけ**



AIに投げる前 → ai:pack
AI差分適用後 → ai:check
通ったら → 採用


- 考えない
- 説明しない
- レビューしない

---

## ④ 最初のGit操作(推奨)
```bash
git add .
git commit -m "feat: initial OceansGuard core structure"
git tag v0.1.0
git push origin main --tags
AI-assisted development guardrails for any repository.

## What it solves
- AI-generated changes that accidentally drop existing code
- Lack of global context (only partial files shown)
- Forgetfulness / inconsistent constraints across sessions
- No test / lint guarantees
- Secret leakage (keys/tokens) into commits
- Risky full-rewrite changes

## Core commands

### init
Create minimal guard files in target repo (idempotent; no overwrite).

python core/aiguard.py init --repo .

### pack
Generate AI context pack (diff-first).
```
python core/aiguard.py pack --repo .
```
### check
Run guard checks + configured project checks and write reports.
```
python core/aiguard.py check --repo .
```
### run
Shortcut = pack + check.
```
python core/aiguard.py run --repo . --task "your task"
```
## Strict mode
--strict makes guardrails non-negotiable:
- requires PyYAML
- fails if checks.commands is empty
- fails if contracts/openapi.json is missing/empty
```
python core/aiguard.py run --repo . --task "CI guard" --strict
```

## Submodule usage (recommended)
In your target repository:
```
git submodule add https://github.com/OceansCreative/OceansGuard.git tools/OceansGuard
python tools/OceansGuard/core/aiguard.py init --repo .
python tools/OceansGuard/core/aiguard.py run --repo . --task "初回ガード適用"
```
## Outputs
- ai_context_pack.md: single file to paste into AI chat
- ai_test_last.log: raw execution logs
- ai_check_report.json: structured result for CI/PR gating

## Git hooks (prevent committing to main)
Install with:
```
python core/install_hooks.py --repo .
```
11 changes: 11 additions & 0 deletions SNAPSHOT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# SNAPSHOT

- 現在の仕様
- 既知の制約
- 触ってはいけない領域


_generated by OceansGuard init @ 2025-12-31T00:29:25_

_generated by OceansGuard init @ 2025-12-31T10:35:26_

1 change: 1 addition & 0 deletions common
Submodule common added at 69429d
7 changes: 7 additions & 0 deletions contracts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Contracts

このディレクトリには、守るべき契約(スキーマ/仕様)を置きます。

- OpenAPI: contracts/openapi.json(または openapi.yaml)
- DB schema snapshot
- DTO/型
8 changes: 8 additions & 0 deletions contracts/openapi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"openapi": "3.0.3",
"info": {
"title": "OceansGuard Placeholder API",
"version": "0.0.0"
},
"paths": {}
}
Loading