# Kutby Architecture Standard

**Status:** Binding engineering architecture contract  
**Applies to:** Every module, service, component, feature, template, admin page, CLI command, and future extension  
**Theme:** Kutby  
**Audience:** Contributors, reviewers, and future maintainers  

This document defines **how Kutby is built**.

Architecture is a product feature. Consistency is mandatory.

Any implementation that violates this architecture may be rejected **even if it works**.

**Related contracts:**

| Contract | Authority |
|----------|-----------|
| `ARCHITECTURE.md` | Structure, boundaries, extension |
| `PERFORMANCE.md` | Speed, budgets, runtime cost |
| `DESIGN_SYSTEM.md` | Visual language, Components, Tokens |
| `HEADER-ENGINE.md` | Production reference Layout Engine (Header) |
| `FOOTER-ENGINE.md` | Second reference Layout Engine (Footer) |
| `HERO-ENGINE.md` | Third reference Layout Engine (Hero) |
| `CARDS-SYSTEM.md` | Shared visual Card System (not an Engine) |

All three are binding. None supersedes the others.

This is **not** a PHP style guide, a Laravel guide, or a WordPress tutorial. It is the engineering contract for **Kutby Foundation 2.5+**.

---

## 1. Architecture Philosophy

### Core beliefs

1. **Simplicity over cleverness.** Prefer the readable path over the ingenious one.
2. **Maintainability over shortcuts.** A working hack that poisons the next feature is rejected.
3. **Composition over duplication.** Assemble Modules, Components, and Registries — do not copy-paste systems.
4. **Convention over configuration.** Follow established Kutby patterns before inventing knobs.
5. **Explicit architecture over hidden magic.** Boot paths, dependencies, and side effects must be visible.
6. **Every abstraction must justify its existence.** No layers “for later” without a current consumer.
7. **Avoid architecture for architecture’s sake.** Foundation exists to ship a fast educational theme, not a framework demo.

### Default stance

When two designs both satisfy the product need, choose the one that:

- preserves Module Manager boundaries  
- keeps Theme thin  
- stays compatible with `PERFORMANCE.md` and `DESIGN_SYSTEM.md`  
- is easier to delete later  

---

## 2. Foundation Overview

**Foundation** is the stable structural core of Kutby: boot, modules, options, assets, design tokens, Admin UI primitives, and extension points. Feature UI (homepage polish, course layouts, etc.) builds **on** Foundation — it does not rewrite it.

### Layer responsibilities

| Layer | Responsibility | Must not |
|-------|----------------|----------|
| **Theme** (`Kutby\Core\Theme`) | Single entry after `functions.php`; owns Module Manager run; emits boot events | Contain feature logic, queries, or Admin markup |
| **Module Manager** | Register → boot modules; honor `kutby_modules` / `kutby_modules_register` | Know field schemas, CSS, or page HTML |
| **Modules** | Feature boundaries (`register()` / `boot()`); wire hooks and collaborators | Become dumping grounds for unrelated concerns |
| **Services / loaders** | Focused runtime work (assets, SEO output, performance toggles) | Own global application state without a Manager/cache story |
| **Managers** | Lifecycle + caching for a domain (e.g. Theme Options `Manager`) | Render UI or define field schemas alone |
| **Registries** | Single source of truth maps (fields, icons, panels) | Persist storage or enqueue assets |
| **Design System** | Tokens + visual contracts (`DESIGN_SYSTEM.md`) | Live as hardcoded values in templates |
| **Admin Components** | Reusable Admin markup API | Duplicate per-page HTML or WP settings tables by default |
| **Support** | Environment and thin cross-cutting helpers | Absorb business features |
| **Helpers / Utils** | Pure or near-pure utilities (icons path, small transforms) | Hide I/O-heavy “service” behavior |
| **Templates** | WordPress template hierarchy + thin presentation | Embed options resolution, SQL, or remote calls |

One layer, one clear responsibility. If a class spans two layers, split it.

---

## 3. Directory Structure

Canonical theme layout (conceptual):

```
kutby/
├── functions.php          # Bootstrap only
├── style.css              # Theme header (empty of feature CSS)
├── *.php                  # WP template hierarchy entrypoints
├── template-parts/        # Reusable template fragments (when present)
├── inc/                   # PHP application code (PSR-4: Kutby\)
│   ├── Core/              # Theme, ModuleManager, Autoloader, Constants, Setup
│   ├── Contracts/         # Interfaces (ModuleInterface, …)
│   ├── Modules/           # Feature modules (register/boot)
│   ├── ThemeOptions/      # Schema, FieldRegistry, Manager, Sanitizer, …
│   ├── Admin/             # Dashboard, Showcase, UI Components, Notices, views
│   ├── Pages/             # Options panel page classes
│   ├── Fields/            # Field renderers
│   ├── Design/            # Tokens PHP bridge
│   ├── Assets/            # AssetLoader, Manifest, AssetManifestManager
│   ├── Events/            # Dispatcher
│   ├── Icons/             # Icon Registry + helper
│   ├── Live/              # Live-settings stubs (no preview UI yet)
│   ├── Support/           # Environment, etc.
│   ├── Helpers/           # Utils
│   ├── Performance/       # Performance module
│   ├── SEO/               # SEO module
│   ├── Hooks/             # Frontend hook module(s)
│   ├── Integrations/      # Third-party integration loader
│   ├── Sanitizers/        # Primitive sanitizers
│   └── TemplateTags/      # Public template tag facades
├── src/                   # Vite sources (JS/CSS tokens/admin)
├── assets/                # Built + fallback assets, icons, fonts
├── PERFORMANCE.md
├── DESIGN_SYSTEM.md
└── ARCHITECTURE.md
```

### What belongs where

| Location | Belongs | Never belongs |
|----------|---------|---------------|
| `functions.php` | Constants require, Autoloader, `Theme::boot()` | Features, queries, menus, CSS |
| `inc/Core/` | Boot, Module Manager, Setup, constants, autoload | Feature modules, Admin views |
| `inc/Modules/` | `ModuleInterface` implementations / wrappers | Low-level sanitizers, raw SQL utilities |
| `inc/ThemeOptions/` | Schema, Field Registry, Manager, storage sanitization | Template markup, Vite config |
| `inc/Admin/` | Control Center shell, Components, Notices, Showcase | Frontend templates |
| `inc/Pages/` | Panel controllers extending AbstractPage patterns | Asset manifests |
| `inc/Design/` | Token resolution → CSS variables | Hardcoded page layouts |
| `inc/Assets/` | Enqueue + manifest resolution | Theme Options schema |
| `inc/Events/` | Internal event bus | Business rules that should be modules |
| `src/` | Source CSS/JS for Vite | Production-only hacks without build |
| `assets/dist/` | Production hashed bundles + manifest | Hand-edited production CSS as source of truth |
| `assets/icons/` | SVG icon files | Icon fonts |
| Root templates | Hierarchy entry + includes | Option writes, remote HTTP, directory scans |

**Rule:** New feature code lands in a Module (and its collaborators). It does not accumulate in `functions.php` or `Theme`.

---

## 4. Dependency Rules

### Hierarchy (dependencies point downward only)

```
Theme
  ↓
Module Manager / Modules
  ↓
Domain collaborators (Managers, Registries, Admin, Assets, Pages, Services)
  ↓
Support / Helpers / Sanitizers / Contracts
  ↓
Core primitives (Constants, Autoloader) + WordPress APIs
```

### Enforceable rules

- Dependencies **only point downward**.
- **No circular dependencies** between Modules or between Manager ↔ Module without an event/filter seam.
- **No cross-module coupling.** Module A must not reach into Module B’s private collaborators. Communicate via:
  - Theme Options (`Manager`)
  - `Events\Dispatcher` / `kutby/*` hooks
  - WordPress hooks with documented contracts
  - Shared Registries intentionally placed in domain namespaces
- **No hidden service locators.** Do not invent a global `$kutby_app->get('whatever')` bag. Prefer constructor injection, narrow static Managers with request caches, or Module-owned instances.
- Templates may call **TemplateTags** and documented helpers — not Module internals.

Violations are architecture defects, not “style nits.”

---

## 5. Module Rules

Every feature boundary implements `Kutby\Contracts\ModuleInterface`.

### Lifecycle

| Method | Allowed | Forbidden |
|--------|---------|-----------|
| `register()` | Attach hooks/filters; cheap construction; gate Admin-only work with `is_admin()` | Heavy I/O, remote HTTP, directory scans, unbounded queries |
| `boot()` | Demand-driven follow-up after all modules registered | Assume other modules’ private state; duplicate `register()` work |

### Rules

- **Lazy / demand-driven initialization.** Do not warm services unused on the current request (frontend vs Admin vs AJAX). See `PERFORMANCE.md` Module Loading Rules.
- **Registration is cheap. Side effects are gated.**
- Modules remain **feature-isolated**. Shared behavior moves to Support, Registries, or Events — not “just call the other module class.”
- Declare dependencies explicitly (constructor args or clear collaboration through Managers). Do not reach across namespaces for convenience.
- Emit / listen to Kutby events for cross-cutting reactions (`theme_booted`, `options_saved`, `assets_loaded`, `admin_ready`, …).
- Prefer adding a **new Module** (or thin wrapper Module) over expanding `Theme` or stuffing `FrontendHooks` with unrelated concerns.
- `ModuleLoader` remains a **BC shim** — new code uses `ModuleManager`.

Default modules are composed in `ModuleManager`; replace/extend via `kutby_modules` and `kutby_modules_register` without forking Core.

---

## 6. Services

Choose the smallest honest abstraction.

| Kind | When to create | Kutby examples |
|------|----------------|----------------|
| **Module** | Feature boundary with hooks lifecycle | `AssetsModule`, `AdminModule`, `SEO` |
| **Manager** | Domain lifecycle + cache + persistence orchestration | `ThemeOptions\Manager` |
| **Registry** | Map of definitions (single source of truth) | `FieldRegistry`, `Icons\Registry`, panel `Registry` |
| **Service / Loader** | Focused operational unit | `AssetLoader`, `SettingsBridge`, `Integrations\Loader` |
| **Factory** | Creates families of objects by key | `PageFactory` |
| **Helper / Utility** | Stateless or near-stateless transforms | `Helpers\Utils`, `Support\Environment` |
| **Component API** | UI primitives | `Admin\UI\Components` |

### Differences that matter

- **Registry** defines *what exists*. **Manager** loads/saves/caches *runtime state*. **Field renderer** draws controls. Do not merge these into one class.
- **Factory** maps IDs → instances. It should not sanitize options or enqueue assets.
- **Helper** must not grow into a disguised God Service.

### Avoid God Services

Reject classes that simultaneously: query the database, render HTML, sanitize input, enqueue assets, and call remote APIs. Split by layer.

---

## 7. Component Architecture

### Admin Components

- All Control Center UI is built through `Kutby\Admin\UI\Components` and related primitives (Notices, Icons).
- Options panels compose **AbstractPage / Schema-driven pages + Components + Field renderers**.
- **No duplicated markup** across panels for the same control.
- Developer **UI Showcase** is living documentation — it must call the Components API only.

### Frontend Components

- Future frontend UI must follow the same composition rules: reusable partials/components, token-driven styles, minimal DOM (`DESIGN_SYSTEM.md`).
- Do not invent a second Admin-like component tree for one template.

### Configuration

- Components accept configuration (attrs/args), not copy-pasted variants.
- Visual values come from **Design Tokens**, not inline styles or magic hex in PHP strings beyond token definitions.

Bypassing Components for “just this page” is an architecture violation.

---

## 8. Theme Options Architecture

### Relationship

```
Schema (definitions)
   ↓
FieldRegistry (API: defaults, validate, sanitize, labels, fields_for)
   ↓
Validate → Sanitize → Manager::save / Manager::all (cache)
   ↓
Storage (wp_options key KUTBY_OPTION_KEY)
   ↓
Rendering (Pages + Fields + Components)
```

### Rules

- **Field Registry** is the single field API over Schema. Do not fork parallel schemas.
- **Validation** runs before save (form + AJAX). Failures block persistence and surface via Notices.
- **Sanitization** remains mandatory and unchanged in role — validation does not replace it.
- **Manager** is the single read/write orchestrator with request cache. **Load once. Read many. Write once.**
- **No direct option access** for theme settings (`get_option( KUTBY_OPTION_KEY )` in feature code is forbidden). Use Manager / Field Registry.
- Panel list lives in Theme Options `Registry`; page classes live in `Pages\`.
- CSS variables for options-driven design flow through **Design Tokens**, not ad-hoc inline maps in random classes.

---

## 9. Coding Standards

Kutby PHP application code under `inc/`:

- `declare(strict_types=1);` on every file.
- Namespace under `Kutby\…` matching directory layout (Autoloader).
- Prefer **`final` classes** unless extension is an intentional public seam.
- Use **typed properties**, **return types**, and parameter types everywhere practical.
- Prefer **constructor property promotion** for simple dependencies.
- Prefer **`readonly`** where PHP version and mutability rules allow and intent is immutable.
- Prefer **dependency injection** (constructors) for collaborators; avoid pulling globals.
- **No `$GLOBALS` feature state.** WordPress APIs are allowed; Kutby feature state is not global soup.
- Keep `functions.php` free of feature code.

This section defines Kutby norms — not a complete PSR encyclopedia.

---

## 10. Class Design

- **Single responsibility** per class.
- Keep **public APIs small**; mark internals `private`/`protected` deliberately.
- Prefer **composition** (Module owns Loader; Page uses Components) over deep inheritance.
- **No inheritance abuse.** AbstractPage / SchemaDrivenPage are intentional UI seams — do not build taxonomy-of-everything hierarchies.
- Avoid ambient **static mutable state** beyond justified request caches (Manager, Manifest). Document invalidation when you add one.
- Static facades (FieldRegistry, Tokens, Notices) are acceptable when they are thin and domain-clear — they must not become dumping grounds.

---

## 11. Events

### Buses

| Mechanism | Use |
|-----------|-----|
| `Kutby\Events\Dispatcher` | Internal Kutby events (`kutby/{event}`, catch-all `kutby/event`) |
| `do_action` / `apply_filters` | WordPress-facing and BC hooks (`kutby_booted`, `kutby_options_saved`, `kutby_modules`, …) |

### Naming

- Internal Dispatcher events: short snake names (`theme_booted`, `options_saved`, `admin_ready`).
- Public WP hooks: `kutby_` prefix with clear verbs/nouns.
- Filters return values; actions must not pretend to be filters.

### Responsibilities

- Events **notify** and allow extension. They must not become a hidden control-flow spaghetti where nothing is readable without tracing twenty listeners.
- Emit after successful state changes (options saved, assets enqueued, modules registered).
- Listeners must obey `PERFORMANCE.md` Hooks Budget — especially on `init`, `admin_init`, `wp`, `shutdown`.

**Avoid event abuse:** do not replace a direct method call inside the same module with an event “for purity.”

---

## 12. Error Handling

- **Validation** errors (Field Registry) → user-facing Notices / AJAX error payloads; **no save**.
- Prefer **graceful recovery** on non-critical failures (missing optional icon file → empty string; missing dist → fallback assets).
- Use exceptions for truly exceptional programmer/contract failures — not for ordinary empty form fields.
- **Admin Notices** are the UX channel for operator feedback (`DESIGN_SYSTEM.md` Feedback States).
- Logging (when introduced) must be gated, privacy-aware, and never dump secrets or full options blobs to public logs.
- **Never expose implementation details** (stack traces, SQL, paths, raw exception messages) in Admin or frontend UI.

---

## 13. Security Principles

Never trust user input.

- **Validate** (Field Registry / explicit checks) before accepting state.
- **Sanitize** on the way in (Sanitizer + Field Registry sanitize).
- **Escape** on the way out (`esc_html`, `esc_attr`, `esc_url`, `wp_kses` for SVG, etc.).
- **Capability checks** on every Admin action and privileged AJAX (`manage_options` for Theme Options).
- **Nonces** on form posts and AJAX (`kutby_save_options`, `kutby_admin`, …).
- **File / upload handling** via WordPress media APIs and attachment IDs — not raw filesystem writes from user paths.
- SVG icons are local theme files passed through allowlists — do not render arbitrary remote SVG.

Follow WordPress security best practices; this section does not replace a full security audit checklist.

---

## 14. Performance Awareness

Architecture decisions must **preserve** `PERFORMANCE.md`.

- Do not introduce layers that force duplicate option loads, repeated `json_decode`, or render-time filesystem scans.
- Avoid unnecessary abstractions that add runtime without clarifying boundaries.
- Avoid unnecessary runtime work in `register()` / early hooks.
- Module Manager, Asset Manifest Manager, Manager cache, and Tokens exist to **reduce** cost — use them; do not bypass them with “simpler” direct I/O.

If an architectural change worsens budgets, it requires the Performance Regression Policy documentation in the PR.

---

## 15. Design Awareness

Architecture for UI must **consume** `DESIGN_SYSTEM.md`.

- Admin and future frontend UI use **Components** and **Tokens**.
- **Never bypass the Design System** with one-off CSS islands, hardcoded hex in feature PHP/CSS, or parallel notice/button systems.
- Empty, loading, and feedback states are part of the product architecture — plan for them when adding screens.
- RTL / Arabic Admin labels are product constraints; architecture must not introduce LTR-only assumptions in new Admin chrome.

---

## 16. Documentation Standards

- Public classes and non-obvious methods carry **PHPDoc** (`@package Kutby`, meaningful `@param` / `@return` when types alone are insufficient).
- **Class names:** StudlyCase, domain-clear (`FieldRegistry`, `AssetManifestManager`).
- **Method names:** short verbs/nouns matching existing APIs (`register`, `boot`, `validate_groups`).
- **Namespaces** mirror directories.
- Comments explain **why**, not what the next line obviously does.
- Avoid comment clutter and commented-out code in mainline.
- Code should explain itself; documentation contracts (`ARCHITECTURE.md`, etc.) explain the law.

User-facing strings for Admin remain Arabic per product rules; code identifiers remain English.

---

## 17. Testing Philosophy

Architecture should be **testable** even when a formal suite is thin.

- Keep collaborators **injectable** or replaceable behind interfaces/hooks.
- Avoid hidden globals and static traps that freeze the world state.
- Prefer **small isolated units** (Sanitizer, FieldRegistry validation, Tokens resolution, Manifest parsing).
- WordPress integration tests are welcome; Kutby does **not** mandate a specific framework in this contract.
- New Managers/Registries should be exercisable without booting the entire Admin UI when practical.

Untestable “ball of mud” modules are architecture debt.

---

## 18. Extensibility

### Preferred extension path

1. Add or extend a **Module** via Module Manager filters/actions.  
2. Extend **Schema / Field Registry** for new options.  
3. Add **Pages** + Components for Admin UI.  
4. Emit/listen to **Dispatcher** events for reactions.  
5. Add Vite entry points only when asset split is justified (`PERFORMANCE.md`).

### Rules

- Prefer **composition** over editing Foundation internals.
- **Avoid modifying Core** (`Theme`, Module Manager, Autoloader) unless the change is foundational and versioned.
- Do not edit Foundation to hardcode a single client feature — use modules and filters.
- Keep extension points **stable**: hook names, option key, ModuleInterface, Field Registry method contracts.
- Child-theme / plugin extensions should use documented hooks — not copy theme files needlessly.

---

## 19. Deprecation Policy

- Mark superseded APIs in PHPDoc (`@deprecated x.y.0 Use …`) and, when practical, in release notes.
- Provide a **migration path** (shim class, alias method, or documented replacement) — e.g. `ModuleLoader` → `ModuleManager`.
- Preserve **backward compatibility** across minor versions when hooks/filters are public.
- Soft-deprecate first; **graceful removal** in a major version after notice.
- Do not leave eternal dual systems without a removal plan — dual paths are temporary debt.

---

## 20. Code Review Checklist

Before approving a Kutby PR:

- [ ] **Architecture** — correct layer; Theme stays thin; Module boundaries held
- [ ] **Naming** — namespaces, classes, hooks match conventions
- [ ] **Dependencies** — downward only; no circular or cross-module coupling
- [ ] **Performance** — complies with `PERFORMANCE.md` (runtime, queries, assets, remotes, hooks)
- [ ] **Design System** — Tokens + Components; no bypass UI
- [ ] **Security** — caps, nonces, sanitize/escape, no trusted input
- [ ] **Readability** — explicit over clever; small APIs
- [ ] **Reusability** — no duplicated Components/schema/manifest logic
- [ ] **Maintainability** — Foundation not forked for a one-off
- [ ] **Testing** — logic is isolatable or covered
- [ ] **Documentation** — PHPDoc/contracts updated when public seams change
- [ ] **Theme Options** — Manager/Field Registry only; validate → sanitize → save
- [ ] **Events** — justified; not control-flow spaghetti

---

## 21. Enforcement

`ARCHITECTURE.md`, `PERFORMANCE.md`, and `DESIGN_SYSTEM.md` together form the **official engineering contracts** of Kutby.

- All Pull Requests must comply with **all three**.
- Reviewers may reject changes that violate architecture **even if functionality works**.
- Foundation 2.5 systems (Module Manager, Asset Manifest Manager, Field Registry, Design Tokens, Admin Components, Events, Notices) are the default extension surface — bypassing them requires an explicit, versioned architectural decision.
- Revisions to this document must not silently weaken boundaries; note the revision at the bottom.

**Revision:** 1.0  
**Effective:** Foundation 2.5 stable / frontend-ready era  

Build on Foundation. Do not dissolve it.
