Complete implementation of OurDigital skills with dual-platform support (Claude Desktop + Claude Code) following standardized structure. Skills created: - 01-ourdigital-brand-guide: Brand reference & style guidelines - 02-ourdigital-blog: Korean blog drafts (blog.ourdigital.org) - 03-ourdigital-journal: English essays (journal.ourdigital.org) - 04-ourdigital-research: Research prompts & workflows - 05-ourdigital-document: Notion-to-presentation pipeline - 06-ourdigital-designer: Visual/image prompt generation - 07-ourdigital-ad-manager: Ad copywriting & keyword research - 08-ourdigital-trainer: Training materials & workshop planning - 09-ourdigital-backoffice: Quotes, proposals, cost analysis - 10-ourdigital-skill-creator: Meta skill for creating new skills Features: - YAML frontmatter with "ourdigital" or "our" prefix triggers - Standardized directory structure (code/, desktop/, shared/, docs/) - Shared environment setup (_ourdigital-shared/) - Comprehensive reference documentation - Cross-skill integration support Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
234 lines
5.8 KiB
Markdown
234 lines
5.8 KiB
Markdown
# Ownership Matrix Reference
|
|
|
|
This document provides detailed patterns for configuring the ownership matrix in `check-ownership.py`.
|
|
|
|
## Pattern Syntax
|
|
|
|
The ownership matrix uses Python regular expressions (regex) to match file paths.
|
|
|
|
### Common Patterns
|
|
|
|
| Pattern | Matches | Example Files |
|
|
|---------|---------|---------------|
|
|
| `^src/cli\.py$` | Exact file | `src/cli.py` |
|
|
| `^src/.*/cli\.py$` | Any subdirectory | `src/app/cli.py`, `src/core/cli.py` |
|
|
| `^src/core/` | Directory prefix | `src/core/main.py`, `src/core/utils/helper.py` |
|
|
| `^tests/` | All tests | `tests/test_main.py`, `tests/unit/test_foo.py` |
|
|
| `^docs/.*\.md$` | Markdown in docs | `docs/api.md`, `docs/guides/setup.md` |
|
|
| `\.py$` | All Python files | Any `.py` file |
|
|
|
|
### Regex Cheat Sheet
|
|
|
|
| Symbol | Meaning | Example |
|
|
|--------|---------|---------|
|
|
| `^` | Start of string | `^src/` matches paths starting with `src/` |
|
|
| `$` | End of string | `\.py$` matches paths ending with `.py` |
|
|
| `.` | Any character | `a.c` matches `abc`, `a1c`, etc. |
|
|
| `\.` | Literal dot | `\.py` matches `.py` |
|
|
| `*` | Zero or more | `a*` matches ``, `a`, `aa`, `aaa` |
|
|
| `+` | One or more | `a+` matches `a`, `aa`, `aaa` |
|
|
| `.*` | Any characters | `src/.*` matches anything starting with `src/` |
|
|
| `[abc]` | Character class | `[abc]` matches `a`, `b`, or `c` |
|
|
| `\w` | Word character | `\w+` matches words |
|
|
| `\d` | Digit | `\d+` matches numbers |
|
|
| `(a\|b)` | Alternation | `(foo\|bar)` matches `foo` or `bar` |
|
|
|
|
## Project-Specific Examples
|
|
|
|
### Python Project
|
|
|
|
```python
|
|
OWNERSHIP_MATRIX: Dict[str, str] = {
|
|
# Claude - Core application
|
|
r"^src/app/": "claude",
|
|
r"^src/core/": "claude",
|
|
r"^src/.*/cli\.py$": "claude",
|
|
r"^CLAUDE\.md$": "claude",
|
|
r"^AGENTS\.md$": "claude",
|
|
r"^GUARDRAILS\.md$": "claude",
|
|
|
|
# Gemini - APIs and documentation
|
|
r"^src/.*/api/": "gemini",
|
|
r"^src/.*/integrations/": "gemini",
|
|
r"^docs/": "gemini",
|
|
r"^GEMINI\.md$": "gemini",
|
|
|
|
# Codex - Testing and utilities
|
|
r"^tests/": "codex",
|
|
r"^src/.*/models\.py$": "codex",
|
|
r"^src/.*/utils/": "codex",
|
|
r"^CODEX\.md$": "codex",
|
|
}
|
|
```
|
|
|
|
### TypeScript Project
|
|
|
|
```python
|
|
OWNERSHIP_MATRIX: Dict[str, str] = {
|
|
# Claude - Core application
|
|
r"^src/app/": "claude",
|
|
r"^src/core/": "claude",
|
|
r"^src/index\.ts$": "claude",
|
|
r"^CLAUDE\.md$": "claude",
|
|
|
|
# Gemini - APIs and documentation
|
|
r"^src/api/": "gemini",
|
|
r"^src/services/": "gemini",
|
|
r"^docs/": "gemini",
|
|
r"^GEMINI\.md$": "gemini",
|
|
|
|
# Codex - Testing and utilities
|
|
r"^tests/": "codex",
|
|
r"^__tests__/": "codex",
|
|
r"^src/.*/.*\.test\.ts$": "codex",
|
|
r"^src/types/": "codex",
|
|
r"^src/utils/": "codex",
|
|
r"^CODEX\.md$": "codex",
|
|
}
|
|
```
|
|
|
|
### Monorepo Project
|
|
|
|
```python
|
|
OWNERSHIP_MATRIX: Dict[str, str] = {
|
|
# Claude - Core packages
|
|
r"^packages/core/": "claude",
|
|
r"^packages/cli/": "claude",
|
|
r"^CLAUDE\.md$": "claude",
|
|
|
|
# Gemini - API packages
|
|
r"^packages/api/": "gemini",
|
|
r"^packages/sdk/": "gemini",
|
|
r"^docs/": "gemini",
|
|
r"^GEMINI\.md$": "gemini",
|
|
|
|
# Codex - Testing and shared
|
|
r"^packages/testing/": "codex",
|
|
r"^packages/shared/": "codex",
|
|
r"^packages/.*/tests/": "codex",
|
|
r"^CODEX\.md$": "codex",
|
|
}
|
|
```
|
|
|
|
## Shared Files Configuration
|
|
|
|
Files that require coordination between agents:
|
|
|
|
```python
|
|
SHARED_FILES: Set[str] = {
|
|
# Package configuration
|
|
r"^pyproject\.toml$",
|
|
r"^package\.json$",
|
|
r"^Cargo\.toml$",
|
|
|
|
# Build configuration
|
|
r"^Makefile$",
|
|
r"^Dockerfile$",
|
|
r"^docker-compose\.ya?ml$",
|
|
|
|
# CI/CD
|
|
r"^\.github/workflows/",
|
|
r"^\.gitlab-ci\.yml$",
|
|
r"^\.circleci/",
|
|
|
|
# Project planning
|
|
r"^PROJECT_PLAN\.md$",
|
|
r"^ROADMAP\.md$",
|
|
r"^CHANGELOG\.md$",
|
|
}
|
|
```
|
|
|
|
## Unrestricted Files Configuration
|
|
|
|
Files any agent can modify:
|
|
|
|
```python
|
|
UNRESTRICTED_FILES: Set[str] = {
|
|
# Agent state
|
|
r"^\.agent-state/",
|
|
|
|
# Git configuration
|
|
r"^\.gitignore$",
|
|
r"^\.gitattributes$",
|
|
|
|
# Editor configuration
|
|
r"^\.vscode/",
|
|
r"^\.idea/",
|
|
|
|
# Documentation
|
|
r"^README\.md$",
|
|
r"^CONTRIBUTING\.md$",
|
|
r"^LICENSE$",
|
|
|
|
# Pre-commit
|
|
r"^\.pre-commit-config\.yaml$",
|
|
}
|
|
```
|
|
|
|
## Custom Agent Example
|
|
|
|
Adding a custom agent (e.g., "designer"):
|
|
|
|
```python
|
|
# 1. Add to valid agents
|
|
VALID_AGENTS = {"claude", "gemini", "codex", "human", "designer"}
|
|
|
|
# 2. Add ownership patterns
|
|
OWNERSHIP_MATRIX: Dict[str, str] = {
|
|
# ... existing patterns ...
|
|
|
|
# Designer - UI and styles
|
|
r"^src/components/": "designer",
|
|
r"^src/styles/": "designer",
|
|
r"^src/.*/.*\.css$": "designer",
|
|
r"^src/.*/.*\.scss$": "designer",
|
|
r"^DESIGNER\.md$": "designer",
|
|
}
|
|
|
|
# 3. Update commit message pattern in check_commit_message()
|
|
pattern = r"^\[(Claude|Gemini|Codex|Human|Designer|CI)\]\s+\w+(\([^)]+\))?:\s+.+"
|
|
```
|
|
|
|
## Testing Patterns
|
|
|
|
Test your patterns using Python:
|
|
|
|
```python
|
|
import re
|
|
|
|
def test_pattern(pattern: str, test_paths: list) -> None:
|
|
"""Test a regex pattern against multiple paths."""
|
|
for path in test_paths:
|
|
match = re.match(pattern, path)
|
|
print(f"{path}: {'MATCH' if match else 'NO MATCH'}")
|
|
|
|
# Example
|
|
test_pattern(r"^src/.*/cli\.py$", [
|
|
"src/cli.py", # NO MATCH (no subdirectory)
|
|
"src/app/cli.py", # MATCH
|
|
"src/core/cli.py", # MATCH
|
|
"src/a/b/cli.py", # MATCH
|
|
])
|
|
```
|
|
|
|
## Debugging Tips
|
|
|
|
1. **Pattern not matching?**
|
|
- Check for literal dots (use `\.` not `.`)
|
|
- Verify start `^` and end `$` anchors
|
|
- Test with simple paths first
|
|
|
|
2. **Pattern too broad?**
|
|
- Add more specific path components
|
|
- Use `$` to anchor end of pattern
|
|
- Add file extension matching
|
|
|
|
3. **Multiple agents matching?**
|
|
- First match wins
|
|
- Order patterns from specific to general
|
|
- Use more specific patterns for exceptions
|
|
|
|
---
|
|
|
|
*Customize the ownership matrix for your specific project structure.*
|