# deptrac Architecture-Fitness Integration Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Close the four open architecture-fitness gaps inside map section A6 — active feature-architecture design, architecture conformance, layer/dependency-direction enforcement, and C4-component-diagram drift — by integrating **deptrac** as a declarative, zero-LLM layer-dependency gate wired into the lefthook pre-commit chain.

**Architecture:** A6 «Архитектура систем» currently has three nodes (adr-kit #36 / mermaid-skill #37 / architecture-patterns #38) covering *record / visualize / reference* — but nothing **enforces** that code keeps matching the chosen layered architecture beyond `adr-judge`'s narrow regex scope. deptrac is a deterministic static-analysis tool (no LLM, matches the AK6 principle adr-kit was built under): it parses the `App\` source into named layers (Controller / Service / Model / Job / …) and fails the build on disallowed dependency directions. Pre-existing violations are captured once into a baseline so the gate is green from day one and only catches *new* drift. deptrac's code-derived graph output doubles as a drift-proof C4-component diagram. deptrac becomes the 4th architecture-tooling tool — A6 goes 3 → 4 nodes.

**Tech Stack:** deptrac (`qossmic/deptrac` — PHP static analysis, declarative YAML, BSD-3); composer dev-dependency in `app/` (PHAR-in-`bin/` fallback — DT1); lefthook (pre-commit job 10); the project normative docs; `docs/automation-graph.html` (vis.js).

---

## Sequencing (locked 2026-05-17)

This is the **4th** tooling-integration epic. The A6, D3, and C9 plans lock a strict, never-interleaved order because all four epics touch the same shared files (the map, the 4 normative docs, the Tooling counter, `cspell-words.txt`). deptrac joins that queue:

- **A6** architecture-tooling — ✅ complete, on `origin/main`.
- **D3** audit-risk-tooling — must run to completion and push **first**.
- **C9** project-management-tooling — runs after D3.
- **deptrac** (this plan) — runs after D3; its slot **relative to C9** (before or after) is the user's call at the Execution Handoff. Both orders are valid — deptrac shares no logical dependency with C9.

Task 1 forks the working branch from the **then-current** `origin/main` (not hard-coded). The Tooling registry number is **runtime-resolved** (DT-NUM) — never hard-code a number before reading the live counter; A6 took #36-38, D3 claims #39-40, C9 claims #41(-42).

---

## Tool Identity (verified 2026-05-17 — re-verify in Task 1)

| Item | Value |
|---|---|
| Tool | **deptrac** — PHP architecture layer/dependency enforcement |
| Package | `qossmic/deptrac` (Composer) — **Task 1 re-confirms the current package name, major version, PHP 8.3 / Laravel 13 compatibility, and the collector-config syntax** |
| License | BSD-3-Clause (permissive) |
| Install mode | Composer **dev-dependency** in `app/`; **fallback** = PHAR in `bin/deptrac.phar` if the dependency resolver conflicts (DT1) |
| Hooks | None — deptrac is a CLI tool, registers no Claude Code lifecycle hooks |
| LLM cost | Zero — pure static analysis (AST), no API calls (AK6-aligned) |
| Category | off-phase, **architecture-tooling** — 4th tool of that subcategory (with #36-38) |

**Out of scope (deliberate — YAGNI).** JS-side module-boundary enforcement for `resources/js` (`eslint-plugin-boundaries` / `dependency-cruiser`) is a separate future epic. This plan closes the **PHP/backend** architecture-fitness gaps only. Context/container-level C4 drift (external systems — Yandex Cloud, Unisender, JivoSite, Sentry) is inherently hand-maintained; it is covered by a §8 self-review checklist line (Task 7), not by tooling.

---

## Design Decisions & Conflict Audit

Pattern follows the AK1-AK6 (A6) / TB1 (D3) / CP-PG (C9) audits. Verified against `lefthook.yml`, `app/composer.json`, the `app/app/` tree, `app/phpstan.neon`, and the A6/D3/C9 plans.

| # | Sev | Conflict | Resolution (locked) |
|---|---|---|---|
| DT1 | 🟡 | `composer require --dev qossmic/deptrac` may conflict with Laravel 13's dependency tree (deptrac historically ships isolated). | Task 2: try the composer dev-dep first. If the resolver conflicts → fallback to a pinned `bin/deptrac.phar` (the project already vendors `bin/gitleaks.exe`, `bin/squawk.exe`, `bin/lychee.exe` this way). Decision criterion + both paths are in Task 2. |
| DT2 | 🟢 | deptrac becomes the 10th pre-commit job — adds latency per commit. | deptrac on a codebase this size analyses in ~1-3 s. Measured in Task 5 Step 4; recorded. `glob: "app/**/*.php"` scopes the job to PHP changes only. |
| DT3 | 🟡 | The **first** `deptrac analyse` will report pre-existing layer violations in current `app/` code → job 10 would block **every** commit. | **The headline risk.** Task 4 generates `app/deptrac.baseline.yaml` (`deptrac analyse --formatter=baseline`) capturing all current violations; job 10 then fails only on **new** drift. Same philosophy as `app/phpstan-baseline.neon`. The baseline count is recorded as architecture debt in `docs/architecture/`. |
| DT4 | 🟢 | Overlap with Larastan #12 (§5 п.6 — no two tools per task). | Different tasks: Larastan = type-level bug detection (PHPStan); deptrac = layer-dependency graph. Not a duplicate. Stated explicitly in the Tooling entry (Task 7). |
| DT5 | 🟢 | Overlap with adr-kit's `adr-judge` #36 — both "architecture enforcement" in lefthook. | Complementary, different mechanism: `adr-judge` = declarative regex on ADR `## Enforcement` text blocks; deptrac = AST-level layer-dependency graph. Documented in the Tooling entry + an ADR (Task 3 Step 5). |
| DT6 | 🟢 | The project nests Laravel at `app/`, so the `App\` source is `app/app/`. | deptrac config lives at `app/deptrac.yaml`; `paths: [app]` resolves to `app/app/`. lefthook job 10 uses `root: "app/"`. |
| DT7 | 🟢 | New `deptrac.yaml` / `deptrac.baseline.yaml` files. | `.yaml` — no pre-commit lint job touches it (squawk = `*.sql`, cspell/markdownlint = `*.md`). No lint conflict. |
| DT8 | 🟢 | Native Windows (no Docker / nested-virt — see `project_phase1_strategy`). | deptrac is pure PHP, runs via `php`. No extension/virtualization dependency (unlike pg_partman). |
| DT-NUM | 🟡 | A6 = #36-38, D3 = #39-40, C9 = #41(-42). deptrac must not collide. | Task 7 reads the **live** `docs/Tooling_v8_3.md` Прил. Н §0 counter and assigns `counter + 1`. Never hard-code. |

---

## File Structure

| File | Created / Modified | Responsibility |
|---|---|---|
| `app/deptrac.yaml` | Create | deptrac layer definitions + dependency ruleset |
| `app/deptrac.baseline.yaml` | Create | Baseline of pre-existing violations (DT3) |
| `app/composer.json` + `app/composer.lock` | Modify | deptrac dev-dependency (DT1 primary path) |
| `bin/deptrac.phar` | Create *(conditional — DT1 fallback only)* | Vendored deptrac PHAR if the composer resolver conflicts |
| `lefthook.yml` | Modify | New pre-commit **job 10** `deptrac` |
| `docs/architecture/c4-component-layers.md` | Create | Code-derived layer/component diagram (gap 4) + baseline-debt note |
| `docs/adr/ADR-005-architecture-fitness-deptrac.md` | Create | ADR recording the layer model + deptrac decision (reuses adr-kit from A6) |
| `docs/Tooling_v8_3.md` | Modify | Прил. Н — new architecture-tooling subsection + §0 counter bump |
| `docs/Plugin_stack_rules_v1.md` | Modify | R10.1 Блок 1 — new deptrac row |
| `docs/Pravila_raboty_Claude_v1_1.md` | Modify | §13.2 — extend the architecture-tooling category note |
| `CLAUDE.md` | Modify (**via claude-md-management only** — §5 п.10) | §3 title count, §1 row 2b count, new §3.3 row, §6 paragraph |
| `docs/CHANGELOG_claude_md.md` | Modify | CLAUDE.md version-bump entry |
| `docs/automation-graph.html` | Modify | New `deptrac` node → `NODE_SECTION` A6; header metrics |
| `cspell-words.txt` | Modify | deptrac vocabulary (`deptrac`, `qossmic`, `Deptrac`, …) |

---

## Task 1: Pre-flight — branch, baseline, fact-check, spike

**Files:** none modified (read-only) except a new branch.

- [ ] **Step 1: Confirm tree state and create the working branch**

```bash
cd "c:/моя/проекты/портал crm/Документация"
git status --short
git fetch origin
git checkout -b feat/deptrac-architecture-fitness origin/main
git rev-parse --short HEAD
```

Expected: D3 (and, per the user's chosen slot, C9) are already on `origin/main`. Record the `origin/main` HEAD SHA as the regression baseline. Push pattern at the end: `git push origin feat/deptrac-architecture-fitness:main`.

- [ ] **Step 2: Baseline regression**

Run `/regression quick`. Expected: GREEN. Record the last green Pest / Vitest counts from memory `project_state.md`. This epic changes **no** `app/` runtime code → the Task 9 run must match exactly.

- [ ] **Step 3: Snapshot the hook chain**

Read `.claude/settings.json` and `~/.claude/settings.json`; record every lifecycle hook. deptrac registers none — this snapshot is the Task 9 comparison baseline.

- [ ] **Step 4: Fact-check deptrac (DT1)**

WebFetch `https://github.com/qossmic/deptrac` and the Packagist page. Confirm and record:

- Current Composer package name + latest major version.
- PHP 8.3 / Laravel 13 compatibility (deptrac analyses source, does not load the app — compatibility is just the PHP runtime version).
- The collector config syntax for the installed major (`type: directory` path-regex vs `type: classLike` namespace-regex) — Task 3 writes the config for **this** syntax.
- The available `--formatter` values (specifically whether `mermaidjs` exists — Task 6 uses it; fallback `graphviz`).

If the current major's config schema differs materially from the Task 3 example below → adjust Task 3's config to match; note the deviation.

- [ ] **Step 5: Spike — run deptrac once on the real codebase**

Install deptrac into a throwaway location (do **not** commit yet) and run it once to learn the real violation count — this sizes DT3:

```bash
cd app
composer require --dev qossmic/deptrac --no-interaction --dry-run
```

Record whether `--dry-run` reports a dependency conflict (drives Task 2's path). Then do a real throwaway install + a single `vendor/bin/deptrac analyse` against a *minimal* temp config (one `Service`/`Model` layer pair) just to confirm the binary runs on Windows and prints a violation report. Record the rough violation count. Revert the throwaway install (`git checkout app/composer.json app/composer.lock`) — Task 2 does the real, committed install.

No repo files committed in Task 1.

---

## Task 2: Install deptrac

**Files:** Modify `app/composer.json`, `app/composer.lock` — **or** Create `bin/deptrac.phar` (DT1 fallback).

- [ ] **Step 1: Install — primary path (composer dev-dependency)**

If Task 1 Step 5 reported **no** resolver conflict:

```bash
cd app
composer require --dev qossmic/deptrac --no-interaction
php vendor/bin/deptrac --version
```

Expected: deptrac added under `require-dev` in `app/composer.json`; `vendor/bin/deptrac` exists; `--version` prints the version. Record it.

- [ ] **Step 2: Install — fallback path (PHAR in `bin/`)**

Run this **only if** Step 1's `composer require` failed the dependency resolver. Download the pinned PHAR release asset from `https://github.com/qossmic/deptrac/releases` into `bin/deptrac.phar`:

```bash
curl -L -o bin/deptrac.phar https://github.com/qossmic/deptrac/releases/download/<version>/deptrac.phar
php bin/deptrac.phar --version
```

Expected: `php bin/deptrac.phar --version` prints the version. Record which path (Step 1 or Step 2) was taken — every later `deptrac` invocation in this plan uses `php vendor/bin/deptrac` (Step 1) **or** `php ../bin/deptrac.phar` run from `app/` (Step 2).

- [ ] **Step 3: Verify the offline security audit still passes**

```bash
cd app && composer audit --locked
```

Expected: 0 advisories (Roave already gates installs; this confirms deptrac added none).

- [ ] **Step 4: Commit**

Primary path:

```bash
git add app/composer.json app/composer.lock
git commit -m "build(deptrac): add deptrac as a composer dev-dependency (DT1)"
```

Fallback path:

```bash
git add bin/deptrac.phar
git commit -m "build(deptrac): vendor deptrac PHAR into bin/ (DT1 fallback)"
```

---

## Task 3: Author `deptrac.yaml` — layers + conservative ruleset

**Files:** Create `app/deptrac.yaml`; Create `docs/adr/ADR-005-architecture-fitness-deptrac.md`.

- [ ] **Step 1: Write the deptrac config**

Create `app/deptrac.yaml` (adjust the collector `type` to the syntax recorded in Task 1 Step 4 — the example uses the `type: directory` path-regex form):

```yaml
deptrac:
  paths:
    - ./app
  layers:
    - name: Controller
      collectors: [{ type: directory, value: app/Http/Controllers/.* }]
    - name: Request
      collectors: [{ type: directory, value: app/Http/Requests/.* }]
    - name: Resource
      collectors: [{ type: directory, value: app/Http/Resources/.* }]
    - name: Middleware
      collectors: [{ type: directory, value: app/Http/Middleware/.* }]
    - name: Service
      collectors: [{ type: directory, value: app/Services/.* }]
    - name: Job
      collectors: [{ type: directory, value: app/Jobs/.* }]
    - name: Console
      collectors: [{ type: directory, value: app/Console/.* }]
    - name: Repository
      collectors: [{ type: directory, value: app/Repositories/.* }]
    - name: Model
      collectors: [{ type: directory, value: app/Models/.* }]
    - name: Mail
      collectors: [{ type: directory, value: app/Mail/.* }]
    - name: Rule
      collectors: [{ type: directory, value: app/Rules/.* }]
    - name: Exception
      collectors: [{ type: directory, value: app/Exceptions/.* }]
    - name: Provider
      collectors: [{ type: directory, value: app/Providers/.* }]
  ruleset:
    # Conservative ruleset — enforces only the architecturally-wrong directions
    # (inward/upward deps). Whatever current code violates is captured by the
    # Task 4 baseline; this gate then catches only NEW drift.
    Controller: [Service, Request, Resource, Model, Job, Mail, Repository, Rule, Exception]
    Middleware: [Service, Model, Exception]
    Service: [Service, Model, Repository, Job, Mail, Rule, Exception]
    Job: [Service, Model, Repository, Mail, Exception]
    Console: [Service, Model, Repository, Job, Mail, Exception]
    Repository: [Model, Exception]
    Request: [Rule, Model]
    Resource: [Model]
    Rule: [Model]
    Mail: [Model]
    Model: ~          # bottom layer — depends on nothing in App\
    Provider: [Controller, Service, Job, Console, Repository, Model, Mail, Middleware, Request, Resource, Rule, Exception]
```

- [ ] **Step 2: Run deptrac — see the current state (the "failing test")**

Primary: `cd app && php vendor/bin/deptrac analyse --no-progress` (fallback: `cd app && php ../bin/deptrac.phar analyse --no-progress`).
Expected: deptrac parses the config and prints a violation report. If the config has a **schema error**, deptrac prints the offending key — fix per its message and re-run. Record the violation count + the uncovered-class count. A non-zero violation count here is expected and correct (it is the architecture debt the baseline will capture).

- [ ] **Step 3: Write ADR-005**

Create `docs/adr/ADR-005-architecture-fitness-deptrac.md` (Nygard format — mirror the shape of `docs/adr/ADR-000`..`ADR-003`):

```markdown
# ADR-005: Architecture-fitness enforcement via deptrac

- **Status:** Accepted
- **Date:** 2026-05-17
- **Deciders:** Дмитрий

## Context
Map section A6 had tools to *record* (adr-kit), *visualize* (mermaid-skill) and
*reference* (architecture-patterns) architecture — but nothing enforced that the
code keeps matching the layered architecture (Controller → Service → Model …).
`adr-judge` enforces only what is hand-written as a regex in an ADR Enforcement
block — too narrow for dependency-direction rules.

## Decision
- Adopt **deptrac** — a declarative, zero-LLM static-analysis tool — as the
  layer-dependency gate, wired as lefthook pre-commit job 10.
- The layer model and ruleset are defined in `app/deptrac.yaml` (conservative —
  enforces only inward/upward-violating directions).
- Pre-existing violations are captured in `app/deptrac.baseline.yaml`; the gate
  fails only on NEW drift. Reducing the baseline is tracked architecture debt.

## Consequences
- Positive: layer drift is caught at commit time, deterministically, free.
- Risk: a too-strict ruleset produces noise — mitigated by the conservative
  ruleset + the baseline.

## Enforcement
The layer rules live in `app/deptrac.yaml`, enforced by lefthook job 10 — not by
an `adr-judge` regex. This ADR has no `adr-judge` Enforcement clause.
```

- [ ] **Step 4: Lint + commit**

```bash
npx markdownlint-cli2 "docs/adr/ADR-005-*.md"
npx cspell --no-progress --no-summary --no-gitignore "docs/adr/ADR-005-*.md"
```

Add valid flagged terms (`deptrac`, `qossmic`, `Nygard`, …) to `cspell-words.txt`. Then:

```bash
git add app/deptrac.yaml docs/adr/ADR-005-*.md cspell-words.txt
git commit -m "feat(deptrac): layer model + ruleset config + ADR-005"
```

---

## Task 4: Generate the baseline (DT3 — the headline risk)

**Files:** Create `app/deptrac.baseline.yaml`; Modify `app/deptrac.yaml`.

- [ ] **Step 1: Generate the baseline file**

```bash
cd app && php vendor/bin/deptrac analyse --formatter=baseline --output=deptrac.baseline.yaml
```

(Fallback binary: `php ../bin/deptrac.phar …`.) Expected: `app/deptrac.baseline.yaml` is created, listing every current violation as a skipped entry.

- [ ] **Step 2: Wire the baseline into the config**

Edit `app/deptrac.yaml` — add under the `deptrac:` key:

```yaml
  baseline_file: ./deptrac.baseline.yaml
```

- [ ] **Step 3: Run deptrac — confirm GREEN (the "passing test")**

```bash
cd app && php vendor/bin/deptrac analyse --no-progress
```

Expected: **0 reported violations** (all pre-existing ones absorbed by the baseline). Exit code 0. If any violation still reports → the baseline did not capture it; regenerate (Step 1) and re-check.

- [ ] **Step 4: Commit**

```bash
git add app/deptrac.yaml app/deptrac.baseline.yaml
git commit -m "feat(deptrac): baseline pre-existing violations — gate green from day 1 (DT3)"
```

---

## Task 5: Wire lefthook pre-commit job 10

**Files:** Modify `lefthook.yml`.

- [ ] **Step 1: Add job 10**

Edit `lefthook.yml` — append after job 9 (`adr-judge`), inside `pre-commit.jobs`:

```yaml
    # 10. deptrac — архитектурный гейт направления зависимостей / границ слоёв
    # (Прил. Н — architecture-tooling). Анализирует app/app/** по слоям из
    # app/deptrac.yaml; baseline_file гасит унаследованные нарушения (DT3) —
    # job падает только на НОВОМ дрейфе. Без glob точечного анализа: deptrac
    # строит граф классов, нужен весь app/. Чистый PHP, без LLM (AK6).
    - name: deptrac
      glob: "app/**/*.php"
      root: "app/"
      run: php vendor/bin/deptrac analyse --no-progress
      fail_text: |
        deptrac: staged-изменение нарушает направление зависимостей между
        слоями (см. file:line выше и app/deptrac.yaml ruleset).
        Если это осознанное архитектурное изменение — сначала обнови
        app/deptrac.yaml (и при необходимости ADR-005), затем коммить.
```

Fallback-PHAR variant of the `run:` line: `run: php ../bin/deptrac.phar analyse --no-progress` — use whichever Task 2 path was taken.

- [ ] **Step 2: Verify the full chain runs**

```bash
npx lefthook run pre-commit
```

Expected: all 10 jobs execute; job 10 `deptrac` runs and reports 0 violations (baseline applied). Record job 10's wall-time (DT2).

- [ ] **Step 3: Red-green — prove the gate actually catches drift**

Introduce a deliberate violation, confirm deptrac flags it, then revert:

```bash
# pick a Model and make it import a Service (a forbidden upward dependency)
```

Edit any file under `app/app/Models/` to add `use App\Services\NotificationService;` and reference it. Run `cd app && php vendor/bin/deptrac analyse --no-progress`.
Expected: **deptrac reports 1 violation** (`Model must not depend on Service`), exit code non-zero. Then revert the edit (`git checkout app/app/Models/<file>`) and re-run — expected 0 violations again. This is the red-green proof that job 10 works.

- [ ] **Step 4: Commit**

```bash
git add lefthook.yml
git commit -m "ci(deptrac): wire deptrac as lefthook pre-commit job 10"
```

---

## Task 6: Code-derived C4-component diagram (gap 4)

**Files:** Create `docs/architecture/c4-component-layers.md`; Modify the `docs/architecture/` index.

- [ ] **Step 1: Generate the layer graph from code**

If Task 1 Step 4 confirmed a `mermaidjs` formatter:

```bash
cd app && php vendor/bin/deptrac analyse --formatter=mermaidjs --output=../docs/architecture/_deptrac-layers.mmd
```

Else use `--formatter=graphviz-dot --output=../docs/architecture/_deptrac-layers.dot`. The graph is **derived from the actual code** — it cannot drift.

- [ ] **Step 2: Create the diagram doc**

Create `docs/architecture/c4-component-layers.md`: a short intro, then the generated Mermaid graph embedded in a ```mermaid fence (or, for the graphviz fallback, a note + the committed `.dot` file). Include the recorded baseline violation count (Task 4 Step 1) as a one-line "architecture debt" figure. State that this is the **component-level** C4 view, derived from `app/deptrac.yaml`, regenerate via the Task 6 Step 1 command — and that **context/container-level** C4 (`c4-context.md`, external systems) stays hand-maintained.

- [ ] **Step 3: Link it from the architecture index**

Read the `docs/architecture/` index/README created by the A6 epic; add a link to `c4-component-layers.md` next to `c4-context.md`.

- [ ] **Step 4: Lint + commit**

```bash
npx markdownlint-cli2 "docs/architecture/c4-component-layers.md"
npx cspell --no-progress --no-summary --no-gitignore "docs/architecture/c4-component-layers.md"
git add docs/architecture/
git commit -m "docs(arch): code-derived C4 component-layer diagram from deptrac (gap 4)"
```

---

## Task 7: Normative registry sync (DT-NUM)

**Files:** Modify `docs/Tooling_v8_3.md`, `docs/Plugin_stack_rules_v1.md`, `docs/Pravila_raboty_Claude_v1_1.md`, `CLAUDE.md`, `docs/CHANGELOG_claude_md.md`, `cspell-words.txt`.

- [ ] **Step 1: Read the registry homes + the live counter (DT-NUM)**

Read for exact insertion points and the **current** counter: `docs/Tooling_v8_3.md` Прил. Н §0 + the last `§4.x` subsection (architecture-tooling = §4.11-4.13); `docs/Plugin_stack_rules_v1.md` R10.1 Блок 1; `docs/Pravila_raboty_Claude_v1_1.md` §13.2. Assign deptrac the number `counter + 1` — **after** the A6/D3/C9 entries already present. Record `#N`.

- [ ] **Step 2: Add the Tooling Прил. Н subsection**

Edit `docs/Tooling_v8_3.md`: add a `§4.x` subsection for `#N deptrac`, category **architecture-tooling** (off-phase — the 4th tool of that subcategory, with adr-kit/mermaid/architecture-patterns). Record: `qossmic/deptrac` BSD-3; install mode (composer dev-dep or `bin/deptrac.phar` — whichever Task 2 took); config `app/deptrac.yaml` + `app/deptrac.baseline.yaml`; lefthook job 10; zero-LLM (AK6-aligned); the DT4 boundary vs Larastan (#12 — type analysis ≠ layer graph) and DT5 vs adr-judge (#36 — regex ≠ AST graph). Bump the §0 counter and the Прил. Н version header. Mirror the shape of the §4.11 adr-kit entry.

- [ ] **Step 3: Add the PSR_v1 R10.1 row**

Edit `docs/Plugin_stack_rules_v1.md`: add a deptrac row to R10.1 Блок 1, category **architecture-tooling** — explicitly *outside* the UI-pool → no R6.0/R6.1 stack-filter, no R14 pipeline (same treatment as adr-kit/architecture-patterns). Bump the PSR_v1 version header.

- [ ] **Step 4: Extend the Pravila §13.2 note**

Edit `docs/Pravila_raboty_Claude_v1_1.md` §13.2: the **architecture-tooling** category note already exists (added by A6 for #36-38) — extend it to include `#N deptrac`. Re-read Pravila §0/§13 first to keep numbering consistent. Bump the Pravila version header.

- [ ] **Step 5: Update CLAUDE.md via the governed channel**

Invoke `/claude-md-management:claude-md-improver`. Apply: §3 title count bump (+1); §1 priority-chain row 2b count bump (+1); a new §3.3 row for `#N deptrac` (architecture-tooling, lefthook job 10, mirrors the #36 adr-kit row); a §6 paragraph noting the deptrac architecture-fitness integration. The plugin also writes the `docs/CHANGELOG_claude_md.md` entry and bumps the §0 cross-ref versions. **Do not** edit `CLAUDE.md` directly (§5 п.10).

- [ ] **Step 6: Lint + commit**

```bash
npx markdownlint-cli2 "docs/Tooling_v8_3.md" "docs/Plugin_stack_rules_v1.md" "docs/Pravila_raboty_Claude_v1_1.md" "docs/CHANGELOG_claude_md.md"
npx cspell --no-progress --no-summary --no-gitignore "docs/Tooling_v8_3.md" "docs/Plugin_stack_rules_v1.md" "docs/Pravila_raboty_Claude_v1_1.md"
git add docs/Tooling_v8_3.md docs/Plugin_stack_rules_v1.md docs/Pravila_raboty_Claude_v1_1.md CLAUDE.md docs/CHANGELOG_claude_md.md cspell-words.txt
git commit -m "docs(deptrac): register #N deptrac architecture-tooling (DT-NUM)"
```

---

## Task 8: Reflect deptrac on the map — extend section A6

**Files:** Modify `docs/automation-graph.html`.

- [ ] **Step 1: Read the structures to replicate**

In `docs/automation-graph.html` read, as templates, the A6 node `adr_kit` across `NODES`, `NODE_DETAILS`/`nd(...)`, `NODE_META`, `NODE_SECTION`, and the lefthook-job nodes (`lh_larastan`) — deptrac is both an architecture-tooling node and a lefthook job. Record the current node/edge counts from the header comment.

- [ ] **Step 2: Add the `deptrac` node**

Add to `NODES` a `deptrac` node replicating the `adr_kit` shape (plugins/tooling group, `ring`/`pos` near the other A6 nodes). Add a matching `nd(...)` / `NODE_DETAILS` entry (Russian, per the file's convention) and a `NODE_META` entry with `since: '17.05.2026'`:
> "deptrac — архитектурный гейт: статический анализ направления зависимостей между слоями (Controller/Service/Model/…), lefthook job 10, baseline на унаследованные нарушения. Декларативно, без LLM (AK6). Закрывает A6-пробелы conformance + границы слоёв + дрейф C4."

Add an edge from `tooling` (or `psr_v1`) to `deptrac`, mirroring the A6 edges.

- [ ] **Step 3: Map the node to section A6**

In `NODE_SECTION` add `deptrac: 'A6',`. Section A6 «Архитектура систем» goes 3 → 4 nodes. Update the group-count comment (plugins/tooling) and the header node/edge metrics (+1 node, +1 edge).

- [ ] **Step 4: Smoke-test the map**

```bash
npx stylelint docs/automation-graph.html
```

Open `docs/automation-graph.html` via a local `http.server` (quirk 90 — `file://` rejected) with Playwright MCP. Verify: 0 JS console errors (favicon 404 is harmless); `NODES.length` increased by 1; the `deptrac` node renders; clicking section A6 highlights 4 nodes.

- [ ] **Step 5: Commit**

```bash
git add docs/automation-graph.html
git commit -m "feat(map): deptrac node — extends section A6 to 4 nodes"
```

---

## Task 9: Final regression & branch finish

**Files:** none modified.

- [ ] **Step 1: Full pre-commit chain**

```bash
npx lefthook run pre-commit
```

Expected: all **10** jobs green (job 10 `deptrac` = 0 violations, baseline applied).

- [ ] **Step 2: Confirm app runtime code untouched — run the suites**

This epic adds only `deptrac.yaml` + a composer dev-dep + docs; it changes **no** `app/` runtime code:

```bash
cd app && composer test:parallel
npm run test:vue
```

Expected: Pest and Vitest counts **identical** to the Task 1 Step 2 baseline (0 regressions). Record exact counts; write out any failure with file:line.

- [ ] **Step 3: Confirm the hook chain is intact**

Compare `.claude/settings.json` + `~/.claude/settings.json` to the Task 1 Step 3 snapshot — unchanged. The economy marker still appears; the Stop verifier still runs. deptrac leaked no lifecycle hook.

- [ ] **Step 4: Pre-push checks**

```bash
./bin/gitleaks.exe detect --source . --no-banner --config .gitleaks.toml --redact
./bin/lychee.exe --config .lychee.toml "docs/**/*.md" "*.md"
```

Expected: gitleaks 0 leaks; lychee 0 broken (new `docs/architecture/c4-component-layers.md` + `docs/adr/ADR-005-*.md` are scanned — fix or `.lychee.toml`-exclude any link).

- [ ] **Step 5: Finish the branch**

Invoke `superpowers:finishing-a-development-branch` — present the standard options. Do **not** push without an explicit user choice. Push pattern: `git push origin feat/deptrac-architecture-fitness:main`.

---

## Self-Review

**1. Spec coverage (the 4 A6 gaps).** Gap «conformance / fitness» + gap «направление зависимостей / границ слоёв» → Tasks 3-5 (deptrac.yaml ruleset + baseline + lefthook job 10, red-green-proven). Gap «дрейф C4 vs код» → Task 6 (code-derived component diagram; context-level explicitly carried to a §8 checklist line — Task 7 Step 5 via the §6 paragraph / acknowledged out-of-tooling). Gap «активное проектирование архитектуры фичи» → **deliberately not a tool**: it is covered by the existing cross-cutting `brainstorming`/`writing-plans`/SPARC-architect + architecture-patterns #38, and ADR-005 (Task 3) records the layer model that design work now references — closing the gap by wiring, not by an install (per the agreed analysis; a 4th overlapping design agent would violate §5 п.6). Conflict audit: DT1→T2, DT2→T5.2, DT3→T4, DT4/DT5→T7.2, DT6→T3.1, DT7→(no task — no lint conflict), DT8→T2, DT-NUM→T1/T7.1. No gaps.

**2. Placeholder scan.** `#N` (Task 7) and the deptrac package version / collector syntax / formatter list (Task 3, Task 6) are **runtime-resolved by design** — Task 1 Steps 4-5 carry concrete resolution criteria (same pattern as the A6/D3/C9 plans). The `deptrac.yaml`, `lefthook.yml` job 10, and ADR-005 contents are shown in full. No "TBD" / "handle edge cases".

**3. Consistency.** Branch `feat/deptrac-architecture-fitness` consistent T1↔T9. Node id `deptrac` consistent T8 Steps 2-3. Category **architecture-tooling** consistent T7 Steps 2-4. Paths consistent: `app/deptrac.yaml`, `app/deptrac.baseline.yaml`, `docs/architecture/c4-component-layers.md`, `docs/adr/ADR-005-*.md`. The DT1 primary/fallback fork (composer dep vs `bin/deptrac.phar`) is flagged uniformly (T2, T5.1 `run:` line, T7.2). lefthook job count 9 → 10 consistent T5↔T9.

---

## Execution Handoff

Plan complete and saved to `docs/superpowers/plans/2026-05-17-deptrac-architecture-fitness-integration.md`.

**Sequencing decision required before execution** (see the "Sequencing" header): this epic runs **after D3**. Its slot relative to **C9** is the user's call — `… → D3 → deptrac → C9` or `… → D3 → C9 → deptrac`. Both are valid.

**Execution method:**

1. **Subagent-Driven (recommended)** — fresh subagent per task, two-stage review. *Caveat:* Task 1 Step 4-5 (WebFetch), Task 7 Step 5 (`claude-md-management`), Task 8 Step 4 (Playwright smoke) are main-session-bound — those steps stay with the controller.
2. **Inline Execution** — `superpowers:executing-plans`, batch with checkpoints (same as the A6/D3/C9 plans — install/config/docs-heavy with interactive steps).
