System Architecture

The application strictly enforces a Clean Architecture-inspired four-layer model.

Layered Architecture

  1. UI Layer (src/routes/, src/lib/components/)
    Pure presentation. Renders data from the State layer and triggers State methods on interaction. Does not perform I/O.
  2. State Layer (src/lib/state/)
    Svelte 5 runes (.svelte.ts). Acts as the single source of truth for the UI (issuesStore, modeStore). Orchestrates calls to the Service layer and maintains the commit queue.
  3. Service Layer (src/lib/services/)
    Pure domain logic. Parses YAML, validates issues, manages relations, computes integrity hashes. Never touches the DOM, network, or filesystem.
  4. Adapter Layer (src/lib/adapters/)
    The only layer that performs I/O. Exposes a unified WritableDirectoryAdapter interface implemented by Local and Remote strategies.

System Context

Below is a Mermaid representation of the System Context. The User can either connect directly to their local filesystem, or route through the browser to a Git Provider via REST.

flowchart TD
    User([User]) -->|"Local Edit"| Browser("quill.md SPA")
    User -->|"Remote Edit"| Browser
    
    subgraph BrowserEnv ["Browser Environment"]
      Browser --> LocalAdapter["LocalFsAdapter"]
      Browser --> RemoteAdapter["RemoteWritableAdapter"]
    end
    
    LocalAdapter -->|"File System Access API"| LocalDisk[("Local .quill.md/")]
    RemoteAdapter -->|"REST API"| GitHub[("GitHub/GitLab API")]
  

Domain Services

The domain services are isolated from the framework (SvelteKit) and I/O. They take raw string inputs and return typed Issue objects.

Strict Boundary
A Service must never import from src/lib/adapters/. The State layer is responsible for fetching data via Adapters and passing it to Services.