Claude
Skills
Sign in
Back

ln-642-layer-ownership-boundary-auditor

Included with Lifetime
$97 forever

Checks layer, resource ownership, and orchestration boundaries. Use when auditing architecture boundary enforcement.

General

What this skill does


> **Paths:** File paths (`references/`, `../ln-*`) are relative to this skill directory.

# Layer & Ownership Boundary Auditor

**Type:** L3 Worker

L3 Worker that audits architectural layer boundaries and detects violations.

## Purpose & Scope

- Read architecture.md to discover project's layer structure
- Detect layer violations (I/O code outside infrastructure layer)
- **Detect cross-layer consistency issues:**
  - Transaction boundaries (commit/rollback ownership)
  - Session ownership (DI vs local)
- Check pattern coverage (all HTTP calls use client abstraction)
- Detect error handling duplication
- Return violations list

**Out of Scope:**
- Blocking I/O in async functions (sync open/read in async def)
- Fire-and-forget tasks (create_task without error handler)

## Input

```
- architecture_path: string    # Path to docs/architecture.md
- codebase_root: string        # Root directory to scan
- skip_violations: string[]    # Files to skip (legacy)
- output_dir: string           # e.g., ".hex-skills/runtime-artifacts/runs/{run_id}/audit-report"

# Domain-aware (optional)
- domain_mode: "global" | "domain-aware"   # Default: "global"
- current_domain: string                   # e.g., "users", "billing" (only if domain-aware)
- scan_path: string                        # e.g., "src/users/" (only if domain-aware)
```

**When domain_mode="domain-aware":** Use `scan_path` instead of `codebase_root` for all Grep/Glob operations. Tag all findings with `domain` field.

## Workflow

Detection policy: use two-layer detection (candidate scan, then context verification); load `references/two_layer_detection.md` only when the verification method is ambiguous.
Tool policy: follow host AGENTS.md MCP preferences; load `references/mcp_tool_preferences.md` and `references/mcp_integration_patterns.md` only when host policy is absent or MCP behavior is unclear.

Use `hex-graph` first when references, call paths, or architecture coupling materially improve the audit. Use `hex-line` first for local code and config reads when available. If MCP is unavailable, unsupported, or not indexed, continue with built-in `Read/Grep/Glob/Bash` and state the fallback in the report.

### Phase 1: Discover Architecture

**MANDATORY READ:** Load `references/layer_rules.md` -- use Architecture Presets (fallback), I/O Pattern Boundary Rules (Phase 2), Coverage Checks (Phase 4), Cross-Layer Consistency rules (Phase 3).

```
Read docs/architecture.md

Extract from Section 4.2 (Top-Level Decomposition):
  - architecture_type: "Layered" | "Hexagonal" | "Clean" | "MVC" | etc.
  - layers: [{name, directories[], purpose}]

Extract from Section 5.3 (Infrastructure Layer Components):
  - infrastructure_components: [{name, responsibility}]

IF architecture.md not found:
  Use fallback presets from layer_rules.md

Build ruleset:
  FOR EACH layer:
    allowed_deps = layers that can be imported
    forbidden_deps = layers that cannot be imported
```


**Graph acceleration (if available):** IF `contextStore.graph_indexed` OR `.hex-skills/codegraph/index.db` exists:
- **Module coupling:** `analyze_architecture(path=scan_root, verbosity="full")` -- use returned coupling metrics to identify tightly-coupled layers.
- **Cross-layer calls:** `find_references(symbol)` for transaction/session functions -- trace commit/rollback ownership across layers.
- **Orchestration depth:** `trace_paths(name="ServiceFn", file="...", path_kind="calls", direction="forward", depth=3, path=scan_root)` -- measure chain depth for flat orchestration check from a concrete service symbol.
- Empty `trace_paths` from a coarse or module-level selector is not enough to clear a layer; fall back to `inspect_symbol` or grep/manual review when the selector is broad.
- Fall back to grep-based detection below if graph unavailable.
### Phase 2: Detect Layer Violations

```
scan_root = scan_path IF domain_mode == "domain-aware" ELSE codebase_root

FOR EACH violation_type IN layer_rules.md I/O Pattern Boundary Rules:
  grep_pattern = violation_type.detection_grep
  forbidden_dirs = violation_type.forbidden_in

  matches = Grep(grep_pattern, scan_root, include="*.py,*.ts,*.js")

  FOR EACH match IN matches:
    IF match.path NOT IN skip_violations:
      IF any(forbidden IN match.path FOR forbidden IN forbidden_dirs):
        violations.append({
          type: "layer_violation",
          severity: "HIGH",
          pattern: violation_type.name,
          file: match.path,
          line: match.line,
          code: match.context,
          allowed_in: violation_type.allowed_in,
          suggestion: f"Move to {violation_type.allowed_in}"
        })
```

### Phase 3: Cross-Layer Consistency Checks

#### 3.1 Transaction Boundary Violations

**What:** commit()/rollback() called at inconsistent layers (repo + service + API)

**Detection:**
```
repo_commits = Grep("\.commit\(\)|\.rollback\(\)", "**/repositories/**/*.py")
service_commits = Grep("\.commit\(\)|\.rollback\(\)", "**/services/**/*.py")
api_commits = Grep("\.commit\(\)|\.rollback\(\)", "**/api/**/*.py")

layers_with_commits = count([repo_commits, service_commits, api_commits].filter(len > 0))
```

**Safe Patterns (ignore):**
- Comment "# best-effort telemetry" in same context
- File ends with `_callbacks.py` (progress notifiers)
- Explicit `# UoW boundary` comment

**Violation Rules:**

| Condition | Severity | Issue |
|-----------|----------|-------|
| layers_with_commits >= 3 | CRITICAL | Mixed UoW ownership across all layers |
| repo + api commits | HIGH | Transaction control bypasses service layer |
| repo + service commits | HIGH | Ambiguous UoW owner (repo vs service) |
| service + api commits | MEDIUM | Transaction control spans service + API |

**Exception:** Saga pattern / distributed transactions with explicit compensating actions -> downgrade CRITICAL to MEDIUM. UoW boundary documented with `// architecture decision` or ADR -> skip.

**Recommendation:** Choose single UoW owner (service layer recommended), remove commit() from other layers

**Effort:** L (requires architectural decision + refactoring)

#### 3.2 Session Ownership Violations

**What:** Mixed DI-injected and locally-created sessions in same call chain

**Detection:**
```
di_session = Grep("Depends\(get_session\)|Depends\(get_db\)", "**/api/**/*.py")
local_session = Grep("AsyncSessionLocal\(\)|async_sessionmaker", "**/services/**/*.py")
local_in_repo = Grep("AsyncSessionLocal\(\)", "**/repositories/**/*.py")
```

**Violation Rules:**

| Condition | Severity | Issue |
|-----------|----------|-------|
| di_session AND local_in_repo in same module | HIGH | Repo creates own session while API injects different |
| local_session in service calling DI-based repo | MEDIUM | Session mismatch in call chain |

**Recommendation:** Use DI consistently OR use local sessions consistently. Document exceptions (e.g., telemetry)

**Effort:** M

#### 3.3 Flat Orchestration Violations

**What:** Service-layer functions calling other services that call yet other services -- deep orchestration chains.

**Detection:** **MANDATORY READ:** Load `references/ai_ready_architecture.md` -- map service imports, find chain depth.

**Violation Rules:**

| Condition | Severity | Issue |
|-----------|----------|-------|
| Service chain >= 3 (A->B->C->D) | HIGH | Deep orchestration |
| Service chain = 2 (A->B->C) | MEDIUM | Consider flattening |

**Recommendation:** Extract orchestrator calling all services at same level. Each service becomes a sink.

**Effort:** L

---

### Phase 4: Check Pattern Coverage

```
# HTTP Client Coverage
all_http_calls = Grep("httpx\\.|aiohttp\\.|requests\\.", codebase_root)
abstracted_calls = Grep("client\\.(get|post|put|delete)", infrastructure_dirs)

IF len(all_http_calls) > 0:
  coverage = len(abstracted_calls) / len(all_http_calls) * 100
  IF coverage < 90%:
    violations.append({
      type: "low_coverage",
      severity: "MEDIUM",
      pattern: "HTTP Client Abstraction",
      coverage: coverage,
      unco

Related in General