establishing-code-ownership — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited establishing-code-ownership (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Two sources, checked in order:
: source of truth under products/.** Lists owning team(s) under owners: as bare slugs (the CODEOWNERS handle minus @PostHog/: conversations, logs, team-self-driving, …) and owns **all** of products/<name>/**`. Lives in the dir it owns, so never stale.CODEOWNERS is hard/blocking (mostly infra); CODEOWNERS-soft carries most product mappings for shared code (backend, frontend scenes, generated artifacts, overrides).ownership.jsownership.js automates the deterministic repo-file resolution for both lookups. It finds the repo root from its own location (cwd- and worktree-independent) and enumerates tracked files via git ls-files. Run it first, then fall back to the manual reasoning below for what it can't resolve.
S=.agents/skills/establishing-code-ownership/ownership.js
node $S file posthog/hogql/printer.py # who owns this file (pass --all to see every matching CODEOWNERS rule)
node $S team team-surveys # every tracked file the team owns (slug or @PostHog/ handle both work)
node $S unowned # every tracked file with no owner (append path prefixes to scope, e.g. `unowned products/ frontend/`)For glob matching it uses the vendored, GitHub-faithful matcher .github/scripts/codeowners.js (a zero-dependency JS port of hmarr/codeowners), the same matcher the reviewer auto-assigner runs in CI, so answers track what CI assigns rather than a separate reimplementation. That matcher reproduces GitHub's own CODEOWNERS rules: a slash-free pattern matches at any depth, a trailing slash matches a directory and its contents, and dir/* matches only direct children. So a CODEOWNERS-soft entry the script shows as unowned is genuinely dead — both CI and GitHub skip it too, not a quirk of a stricter local matcher.
Precedence: product.yaml for products/<name>/**; else a blocking CODEOWNERS owner; else the last-matching CODEOWNERS-soft rule. A blocking CODEOWNERS glob with no owner (a reset, e.g. posthog/hogql/database/schema/**) only clears the blocking owner, it does not erase a soft mapping. file prints the source line behind each answer.
It does not trace generated files to their source's owner, consult the handbook, or search Slack. When it returns no owner (or the path is a generated file), keep going with the steps below.
product.yaml owners:; prefix each slug with @PostHog/ (team-replay → @PostHog/team-replay). This beats any matching CODEOWNERS entry. No CODEOWNERS entry for a product path is fine, not a gap.CODEOWNERS-soft first, then CODEOWNERS). Precedence is last-match-wins, so take the latest/most-specific matching glob, not the first hit.Generated files often have no CODEOWNERS entry; trace to the input they're generated from and use that owner (e.g. services/mcp/src/tools/generated/<x>.ts comes from products/<name>/mcp/tools.yaml). Distinguish:
When they differ, report the logical owner and flag the gap so the operator can decide whether to pin it in CODEOWNERS-soft.
Check both sources or you'll miss code:
for the slug**; each hit is all of that products/<name>/**`. One team often owns several, so don't stop at the first.@PostHog/team-surveys, …) for everything outside products/.Owned paths span backend AND `frontend/src/...`. Cover both, or say up front you're doing one side.
Verify CODEOWNERS-soft paths on disk. They drift (a moved product leaves old paths behind); product.yaml doesn't. For any missing path, the code likely relocated into a products/<name>/ the team already owns; flag the stale entry to the operator rather than silently substituting.
If neither product.yaml nor CODEOWNERS resolves it, consult the feature-ownership handbook (teams to product areas). It's a genuine last resort: coarse-grained (broad areas, not files) and hand-maintained (lags repo moves and reorgs). Prefer the repo files, and flag any handbook-sourced answer as possibly stale.
If even the handbook fails and the Slack MCP is available, search Slack. It's the least authoritative source (opinions, stale threads), so verify against the repo files and flag the answer as Slack-sourced.
@PostHog/<slug>, e.g. @PostHog/team-replay.product.yaml): handle minus @PostHog/, e.g. team-replay.team- (team-self-driving), some don't (conversations, logs). If a name doesn't resolve, try both forms.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.