check-conventions

star 0

Validates code against all project architecture conventions. Reads project.yaml to determine applicable checks and runs them. Replaces individual check-* skills.

vincentdchn By vincentdchn schedule Updated 5/30/2026

name: check-conventions description: Validates code against all project architecture conventions. Reads project.yaml to determine applicable checks and runs them. Replaces individual check-* skills.

Check Conventions

Read-only analysis. Reports all convention violations with file path and line number.

Arguments

  • --only=check1,check2 - run only specified checks (default: all applicable)
  • --files=path1,path2 - check only these files (default: all modified files vs main)

Step 1: Load project config

Read project.yaml (in the project's config directory, default .ai/) to determine which checks apply.

Step 2: Identify scope

git diff --name-only main...HEAD 2>/dev/null || git diff --name-only HEAD~1

If --files argument provided, use that instead.

Step 3: Determine applicable checks

Check Applies when
layer-boundaries architecture.pattern is defined
error-handling conventions.error_handling is defined
barrel-exports architecture.barrel_file is defined
naming-conventions always
testing-contract always
observability conventions.observability is defined
domain-purity modified files include domain_dir or shared_domain_dir
infra-encapsulation architecture.pattern is port-adapter or hexagonal

Skip checks whose config section is absent. Respect --only filter if provided.

Step 4: Run checks

Layer Boundaries

Adapt grep patterns to the project runtime:

JS/TS (deno, node):

grep -rn "from.*[\"'].*adapters/" {ports_dir} || true
grep -rn "from.*adapters/\|from.*application/" {domain_dir} || true
grep -rln "from.*application/" src/ | xargs grep -ln "from.*adapters/" | grep -v {composition_root} || true

Go:

grep -rn '".*adapters/' {ports_dir} || true
grep -rn '".*adapters/\|".*application/' {domain_dir} || true

Python:

grep -rn "from adapters\|import adapters" {ports_dir} || true
grep -rn "from adapters\|from application\|import adapters\|import application" {domain_dir} || true

Error Handling

For style: result:

grep -rn "throw new\|throw " {ports_dir} {adapters_dir} | grep -v "_errors" || true

For style: throw:

grep -rn 'throw "' src/ || true
grep -rn "throw new Error(" src/ || true

Barrel Exports

find . -name "{barrel_file}" -not -path "*/node_modules/*" -not -path "*/.git/*"

For each barrel file, check against each entry in barrel_exports.exclude:

grep -n "from.*adapters/" {barrel_file} || true
grep -n "from.*mock\|from.*_mocks" {barrel_file} || true
grep -n "from.*test_helper\|from.*testing" {barrel_file} || true
grep -n "from.*internal\|from.*private" {barrel_file} || true

Naming Conventions

find src/ -name "*.ts" -o -name "*.js" -o -name "*.go" -o -name "*.py" -o -name "*.rs" | \
  grep -v node_modules | grep -v .git

Apply pattern from naming.files config. Check class/type names:

grep -rn "^export class\|^class\|^export interface\|^export type" src/

Testing Contract

# Find implementation files without tests
find {adapters_dir} {domain_dir} -name "*.ts" -o -name "*.go" -o -name "*.py" | \
  grep -v "_test\|.test\|.spec"

# Check mocks implement interfaces
grep -rn "^export class" {mock_dir} | grep -v "implements" || true

# Find unguarded integration tests
find {test_dir} -name "*integration*" | xargs grep -L "{integration_guard}" || true

Observability

# Unstructured logging (if style: structured)
grep -rn "logger\.\(info\|warn\|error\|debug\)" src/ | grep -v "{" || true

# Console.log in production code
grep -rn "console\.log" src/ | grep -v "test\|spec\|mock" || true

Domain Purity

For each pattern in no_infra_imports, adapt to runtime:

JS/TS:

grep -rn "from.*{pattern}\|import.*{pattern}" {domain_dir} {shared_domain_dir} || true

Go:

grep -rn '"{pattern}' {domain_dir} {shared_domain_dir} || true

Python:

grep -rn "from {pattern}\|import {pattern}" {domain_dir} {shared_domain_dir} || true

If no_persistence_fields: true:

grep -rn "partitionKey\|sortKey\|pk\|sk\|_id\|s3Key\|s3Path\|sqsHandle\|receiptHandle\|sequenceNumber" {domain_dir} {shared_domain_dir} || true

Infra Encapsulation

Adapt to runtime:

JS/TS:

grep -rn "from.*@aws-sdk\|from.*@azure\|from.*@google-cloud\|from.*pg\|from.*redis" {ports_dir} || true
grep -rn "^export class" {adapters_dir} | grep -v "implements" || true
grep -n "from.*adapters/" {barrel_file} || true

Go:

grep -rn '"github.com/aws\|"cloud.google.com\|"github.com/Azure' {ports_dir} || true

Python:

grep -rn "from boto3\|import boto3\|from google.cloud\|import redis\|from sqlalchemy" {ports_dir} || true

Output

## Convention Check Report

### Summary
- Checks run: N
- Checks passed: X/N
- Total violations: M

### Passed
- [x] Layer boundaries
- [x] Naming conventions
...

### Violations (M found)
1. **[layer-boundaries]** `src/ports/consumer.ts:12` - imports from adapters/
2. **[naming]** `src/adapters/MyAdapter.ts` - file should be snake_case
3. **[domain-purity]** `src/domain/order.ts:5` - imports @aws-sdk/client-sqs

### Severity
- BLOCKING: layer-boundaries, error-handling, domain-purity, infra-encapsulation
- WARNING: naming, barrel-exports, testing-contract, observability

Rules

  • READ-ONLY. Never modify files.
  • Report violations with exact file path and line number.
  • Skip inapplicable checks (missing config section = skip).
  • Only report concrete violations, not subjective opinions.
  • Blocking violations should fail quality gates. Warnings are advisory.
Install via CLI
npx skills add https://github.com/vincentdchn/ai --skill check-conventions
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator