/ownership
When you need to know who owns a path and who answers for it — the service ownership matrix (team, lead, on-call, SLA) auto-detected from git with CODEOWNERS generated, plus on-call rotations, shift handoffs and escalation paths.
> /plugin marketplace add avelikiy/great_cto> /plugin install great_cto@great-cto
Command definition
ownership.mddescription: "When you need to know who owns a path and who answers for it — the service ownership matrix (team, lead, on-call, SLA) auto-detected from git with CODEOWNERS generated, plus on-call rotations, shift handoffs and escalation paths."
argument-hint: "map | show | set <path> <team> | verify | oncall [who | handoff | schedule <team> <member1,member2,...> | escalate <service>]"
user-invocable: true
allowed-tools: Read, Write, Bash, Glob, Grep
model: sonnet
You are the Ownership command. Build and maintain the service ownership matrix, and run its on-call column (`oncall`).
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}"
case "$ACTION" in
show|map|set|verify) ;;
oncall) shift ;; # `/ownership oncall <who|schedule|handoff|escalate> …` — $1 is now the on-call action
*) ACTION=show ;;
esac---
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
doneStep 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 `/ownership oncall schedule`).
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.
---
Action: `oncall` — rotations, handoffs, escalation
On-call is already a column of the ownership matrix; `oncall` runs it — rotation schedules, who is on duty, shift handoffs, escalation paths.
Setup
source .great_cto/env.sh 2>/dev/null || export PATH="/opt/homebrew/bin:$HOME/.local/bin:/usr/local/bin:$PATH"
SCHEDULE_FILE=".great_cto/oncall-schedule.md"
OWNERSHIP_FILE=".great_cto/OWNERSHIP.md"
ONCALL_ACTION="${1:-who}" # after the dispatch shift: who | schedule | handoff | escalate---
`oncall who` (default) — who is on-call right now
Read `$SCHEDULE_FILE`. For each rotation, calculat
Read more
description: "When you need to know who owns a path and who answers for it — the service ownership matrix (team, lead, on-call, SLA) auto-detected from git with CODEOWNERS generated, plus on-call rotations, shift handoffs and escalation paths." argument-hint: "map | show | set <path> <team> | verify | oncall [who | handoff | schedule <team> <member1,member2,...> | escalate <service>]" user-invocable: true allowed-tools: Read, Write, Bash, Glob, Grep model: sonnet
You are the Ownership command. Build and maintain the service ownership matrix, and run its on-call column (`oncall`).
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}"
case "$ACTION" in
show|map|set|verify) ;;
oncall) shift ;; # `/ownership oncall <who|schedule|handoff|escalate> …` — $1 is now the on-call action
*) ACTION=show ;;
esac---
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
doneStep 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 `/ownership oncall schedule`).
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.
---
Action: `oncall` — rotations, handoffs, escalation
On-call is already a column of the ownership matrix; `oncall` runs it — rotation schedules, who is on duty, shift handoffs, escalation paths.
Setup
source .great_cto/env.sh 2>/dev/null || export PATH="/opt/homebrew/bin:$HOME/.local/bin:/usr/local/bin:$PATH"
SCHEDULE_FILE=".great_cto/oncall-schedule.md"
OWNERSHIP_FILE=".great_cto/OWNERSHIP.md"
ONCALL_ACTION="${1:-who}" # after the dispatch shift: who | schedule | handoff | escalate---
`oncall who` (default) — who is on-call right now
Read `$SCHEDULE_FILE`. For each rotation, calculat
You already have the agent. This is everything around it. great_cto runs Claude Code as a pipeline of 70 specialist agents — an independent model checks each stage before the next builds on it, spending caps refuse rather than warn, and three decisions stay yours: what gets built, how, and whether it ships.
Other commands on great-cto.
More commands from other plugins.
build
CommandImplement tasks incrementally — build, test, verify, commit. Add "auto" to run the whole plan in one approved pass.

