Skip to content
Development
Command

/ownership

Service ownership matrix. Who owns what: team, tech lead, on-call, SLA. Auto-detects from git history. Generates CODEOWNERS.

From plugin
7044 skills69 agents44 commands
shell
$ npx -y skills add avelikiy/great_cto --agent claude-code

Ships with great-cto. Installing the plugin gets this command.

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/ownership

Context preview

What this command does when you run it.

Service ownership matrix. Who owns what: team, tech lead, on-call, SLA. Auto-detects from git history. Generates CODEOWNERS.

Command definition

ownership.md
description: "Service ownership matrix. Who owns what: team, tech lead, on-call, SLA. Auto-detects from git history. Generates CODEOWNERS."
argument-hint: "map | show | set <path> <team> | verify"
user-invocable: true
allowed-tools: Read, Write, Bash, Glob, Grep
model: sonnet

You are the Ownership command. Build and maintain the service ownership matrix.

Setup

source .great_cto/env.sh 2>/dev/null || export PATH="/opt/homebrew/bin:$HOME/.local/bin:/usr/local/bin:$PATH"
OWNERSHIP_FILE=".great_cto/OWNERSHIP.md"
ACTION="${1:-show}"

---

Action: `show` (default)

Read and display `.great_cto/OWNERSHIP.md`. If file missing → suggest running `/ownership map`.

[ -f "$OWNERSHIP_FILE" ] && cat "$OWNERSHIP_FILE" || echo "No ownership map yet. Run: /ownership map"

Output the table as-is. Append:

Last updated: <file mtime>
To update an entry: /ownership set <path> <team>
To rebuild from git: /ownership map

---

Action: `map` — auto-detect ownership from codebase

Step 1: Read existing CODEOWNERS if present

cat CODEOWNERS 2>/dev/null | grep -v "^#" | grep -v "^$" | head -40

Step 2: Detect top-level service boundaries

# Find service roots: dirs with their own package.json / pyproject.toml / go.mod / Cargo.toml
find . -maxdepth 3 \( -name "package.json" -o -name "pyproject.toml" -o -name "go.mod" -o -name "Cargo.toml" \) \
  -not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null | sed 's|/[^/]*$||' | sort -u | head -20

# Fallback: top-level dirs with significant code
find . -maxdepth 2 -type d -not -path "*/.git/*" -not -path "*/node_modules/*" -not -name ".*" 2>/dev/null \
  | xargs -I{} sh -c 'COUNT=$(find "{}" -name "*.ts" -o -name "*.py" -o -name "*.go" -o -name "*.rs" 2>/dev/null | wc -l); [ $COUNT -gt 5 ] && echo "$COUNT {}"' \
  | sort -rn | head -15 | awk '{print $2}'

Step 3: For each service path, find top contributor (last 90 days)

for PATH_DIR in <detected-paths>; do
  echo "=== $PATH_DIR ==="
  git log --since="90 days ago" --format="%ae" -- "$PATH_DIR" 2>/dev/null \
    | sort | uniq -c | sort -rn | head -3
done

Step 4: Read team info from PROJECT.md

grep -E "^teams:|^team:" .great_cto/PROJECT.md 2>/dev/null || echo "no teams defined"

Step 5: Build ownership table

From the data above, construct `.great_cto/OWNERSHIP.md`:

# Ownership Map
> Auto-generated by /ownership map on <date>. Edit manually or re-run /ownership map to refresh.

## Services

| Path | Team | Architect | On-call | Slack | SLA | Notes |
|------|------|-----------|---------|-------|-----|-------|
| api/auth | platform | @<top-contributor> | — | — | — | — |
| api/payments | commerce | @<top-contributor> | — | — | — | — |
| infra/ | infra | @<top-contributor> | — | — | — | — |

## Unowned paths
> Paths with significant code but no clear owner. Assign with: /ownership set <path> <team>
- <path>: <N> commits, top author: @<email>

## Teams
| Team | Slack | Lead |
|------|-------|------|
| platform | — | — |
| commerce | — | — |
| infra | — | — |

Fill `Architect` with top git contributor for that path. Leave On-call, Slack, SLA as `—` (to be filled manually or via `/oncall`).

Tell CTO: "Draft generated. Fill in On-call and Slack columns, then run `/ownership verify`."

Step 6: Generate CODEOWNERS

# Write CODEOWNERS from ownership table
echo "# Auto-generated by /ownership map — $(date +%Y-%m-%d)" > CODEOWNERS
echo "# Edit .great_cto/OWNERSHIP.md and re-run /ownership map to update" >> CODEOWNERS
echo "" >> CODEOWNERS
# For each row in the table:
# <path>  @<architect-github-handle>

Note: CODEOWNERS requires GitHub usernames (not emails). If only emails available, write placeholder `@<email>` and note: "Replace with GitHub handles in CODEOWNERS."

---

Action: `set <path> <team>` — update one entry

# Args: $2 = path, $3 = team
PATH_ARG="$2"
TEAM_ARG="$3"

Find the row for `$PATH_ARG` in OWNERSHIP.md and update Team column to `$TEAM_ARG`. If row doesn't exist → add it to the Services table. After update → regenerate CODEOWNERS entry for that path.

Confirm: `Ownership updated: $PATH_ARG → $TEAM_ARG`

---

Action: `verify` — check for gaps

# Find paths with code but no owner
find src/ app/ lib/ services/ -maxdepth 2 -type d 2>/dev/null | while read DIR; do
  grep -q "$DIR" "$OWNERSHIP_FILE" 2>/dev/null || echo "UNOWNED: $DIR"
done | head -20

# Find owners who no longer commit (left the team?)
grep -oE '@[a-zA-Z0-9._-]+' "$OWNERSHIP_FILE" 2>/dev/null | sort -u | while read HANDLE; do
  EMAIL=$(echo "$HANDLE" | tr -d '@')
  LAST=$(git log --format="%ar" --author="$EMAIL" -1 2>/dev/null || echo "never")
  echo "$HANDLE: last commit $LAST"
done

Output:

Ownership gaps: N unowned paths
Stale owners: M owners with no commit in 90+ days
Run /ownership set <path> <team> to fix gaps.
Read more
Read it on GitHub ↗
Ships withgreat-cto

Don't buy software. Get the work done. GreatCTO ships AI autopilots that run a whole business function — medical coding, legal docs, procurement, accounting, IT, tax — from intake to outcome. A qualified human signs only the judgment calls. Live connectors, built-in compliance.

Get the whole plugin, auto-invoked
Stats
70
Stars
0
Views
12
Forks
Active
Maintenance
JavaScript
Language
MIT
License
54m ago
Last commit
4mo ago
Created

Repo: avelikiy/great_cto