From 507c4d869ae56ca7cdaf080f6fe2f0f827e27b6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Sun, 17 May 2026 11:07:09 +0300 Subject: [PATCH] docs(plan): deptrac architecture-fitness integration plan 9-task plan closing the 4 open A6 architecture-fitness gaps (conformance, layer-direction, C4 drift, active design) via deptrac as a lefthook job-10 layer-dependency gate. + cspell vocab. Co-Authored-By: Claude Opus 4.7 (1M context) --- cspell-words.txt | 6 + ...eptrac-architecture-fitness-integration.md | 555 ++++++++++++++++++ 2 files changed, 561 insertions(+) create mode 100644 docs/superpowers/plans/2026-05-17-deptrac-architecture-fitness-integration.md diff --git a/cspell-words.txt b/cspell-words.txt index 742d49c8..3b51bd57 100644 --- a/cspell-words.txt +++ b/cspell-words.txt @@ -1360,3 +1360,9 @@ PRD automazeio prds Vivek + +# deptrac architecture-fitness integration (2026-05-17) +deptrac +qossmic +mermaidjs +graphviz diff --git a/docs/superpowers/plans/2026-05-17-deptrac-architecture-fitness-integration.md b/docs/superpowers/plans/2026-05-17-deptrac-architecture-fitness-integration.md new file mode 100644 index 00000000..7961d599 --- /dev/null +++ b/docs/superpowers/plans/2026-05-17-deptrac-architecture-fitness-integration.md @@ -0,0 +1,555 @@ +# 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//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/`) 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).