Skip to content

Final-State-Press/knowledge-platform

Knowledge Platform

A local-first, modular, graph-based knowledge-work application built with Python and PySide6.


The Problem

Most knowledge tools force you to think in files and folders. Notes go in one app, tasks in another, outlines in a third — and the relationships between ideas live nowhere. When a project grows complex, the structure you actually need (hierarchies, networks, cross-references, typed relationships) is constantly fighting the flat document model that most tools provide.

There are graph databases and graph editors, but they are either developer-facing infrastructure or expensive enterprise tools. There is no lightweight, extensible, locally-owned desktop application where the graph is the first-class artifact and where the shape of the graph — its node types, edge types, and validation rules — can be defined per-domain by the user or developer.


The Solution

Knowledge Platform treats structured graphs as first-class artifacts. Each workspace holds one or more graph instances, each governed by a graph type that declares what nodes and edges are valid and what attributes they carry. The application is built on a modular plugin architecture: each module contributes a graph type, a domain service, a projection (view), and a UI widget, and modules are loaded at runtime from configuration rather than hard-wired into the host.

The result is an application that can host very different knowledge tools — a hierarchical outline, a kanban board, a concept map, a bibliography — each with its own semantics, all sharing the same persistence and identity infrastructure.

Version 0.1 ships with a single module: the Outline module, which models hierarchical document outlines as a tree of nodes connected by parent-child edges.


Key Features

  • Typed graph engine — Nodes and edges carry a semantic type validated against a registered schema before any write reaches the database.
  • Local-first persistence — All data lives in a single SQLite file per workspace. No cloud account, no server, no sync required.
  • Config-driven plugin architecture — Installed modules can be enabled through modules.yaml without editing app.py or MainWindow.
  • Immutable value-objects — Nodes and edges are frozen dataclasses; every mutation produces a versioned new instance, making history tracking straightforward.
  • Strict layer separation — UI contains no business logic; domain logic contains no Qt imports. All layers communicate through explicit typed contracts (typing.Protocol).
  • Tree projection — The Outline module projects a graph into an ordered tree view with full expand/collapse, context menu, and inline editing.

Architecture Overview

graph TB
    subgraph UI
        MW[MainWindow]
        OV[OutlineView]
        OVM[OutlineViewModel]
        EB[AppEventBus]
    end

    subgraph SVC
        IGS[IGraphService Protocol]
        GS[GraphService]
        WS[WorkspaceService]
    end

    subgraph MOD
        OM[OutlineModule]
        OS[OutlineService]
        OTP[OutlineTreeProjection]
    end

    subgraph CORE
        G[Graph]
        N[Node]
        E[Edge]
        GE[GraphEngine]
        GT[GraphType]
        TR[TypeRegistry]
    end

    subgraph PERSIST
        REPO[SqliteGraphRepository]
        DB[(SQLite)]
    end

    UI -->|service calls| SVC
    SVC --> CORE
    SVC --> MOD
    MOD --> CORE
    CORE --> PERSIST

    style UI fill:#dbeafe,stroke:#3b82f6,color:#1e3a5f
    style SVC fill:#dcfce7,stroke:#22c55e,color:#14532d
    style MOD fill:#fef9c3,stroke:#eab308,color:#713f12
    style CORE fill:#fce7f3,stroke:#ec4899,color:#831843
    style PERSIST fill:#f3f4f6,stroke:#6b7280,color:#111827
Loading

For the full design — class diagrams, sequence diagrams, state machines, ER diagram, and the module extension guide — see DESIGN.md.


Requirements

Dependency Version
Python 3.11 or later
PySide6 6.6 or later
SQLAlchemy 2.0 or later
PyYAML 6.0 or later
pydantic 2.0 or later
structlog 24.0 or later
ulid-py 1.1 or later

Installation

1. Clone the repository

git clone https://github.com/mattbriggs/knowledge-platform.git
cd knowledge-platform

2. Create and activate a virtual environment

python3 -m venv .venv
source .venv/bin/activate        # macOS / Linux
# .venv\Scripts\activate         # Windows

3. Install the application

For end users (runtime only):

pip install -e .

For developers (includes test runner, type checker, linter, docs):

pip install -e ".[dev]"

Note on PySide6: The first install downloads the Qt runtime (~130 MB). This is a one-time cost per virtual environment.

4. Verify the installation

python -c "import knowledge_platform; print(knowledge_platform.__version__)"
# 0.1.0

Running the Application

knowledge-platform

Or, if the entry point script is not on your PATH:

python -m knowledge_platform.main

The application starts with an empty window. Follow these steps to create your first outline:

  1. File → New Workspace… — enter a name (e.g. My Notes).
  2. Select the Outline tab if it is not already active.
  3. File → New Outline… or click New Outline in the toolbar.
  4. The outline panel appears with a root item. Use the toolbar or right-click context menu to add, edit, and remove items.

Module Configuration

Modules are loaded from configuration at startup.

Lookup order:

  1. KNOWLEDGE_PLATFORM_MODULES_FILE
  2. ~/.knowledge_platform/modules.yaml
  3. the packaged default config

Example:

version: 1
strict: true
modules:
  - id: outline
    enabled: true
    source: entry_point

For local development, an explicit import path is also supported:

version: 1
strict: true
modules:
  - id: outline
    enabled: true
    source: import
    factory: knowledge_platform.modules.outline.module:OutlineModule

source: entry_point is the preferred mode for installed plugins. source: import is useful while developing modules in-tree before reinstalling package metadata.


Using the Outline Module

The Outline module presents a hierarchical tree of items, each with a title and optional content body.

Toolbar actions

Action Description
Add Root Item Creates a new top-level item with no parent
Add Child Item Creates a child of the currently selected item
Edit Item Opens a dialog to edit the title and content of the selected item
Remove Item Deletes the selected item and all its descendants

Context menu

Right-click any item in the tree to access the same actions contextually.

Detail panel

Selecting an item displays its full content in the panel on the right. The tree column shows a truncated preview; the detail panel shows the complete text.

Keyboard workflow (recommended)

  1. Click Add Root Item and type a title to create the document root.
  2. Select the root, click Add Child Item to add a first section.
  3. Select a section, keep adding children to build a nested hierarchy.
  4. Double-click or press Edit Item to fill in the content of any node.

Running the Tests

# All unit and integration tests (no display required)
pytest tests/unit tests/integration --no-cov

# With coverage report (domain + services, UI rendering excluded)
pytest tests/unit tests/integration

# Specific test file
pytest tests/unit/modules/outline/test_service.py -v

The exact test count will vary as the module and loader coverage evolves.


Building the Documentation

pip install -e ".[dev]"
mkdocs serve
# Open http://127.0.0.1:8000

Current Limitations

These are known constraints in the current v0.1 release. They are design decisions for a local, single-user first version — not bugs.

Limitation Detail
Data not persisted between sessions The current build uses an in-memory SQLite database (:memory:). All workspace and graph data is lost when the application closes. A file-backed database path is planned for Milestone 1.
Single active workspace The application manages one active workspace at a time, but you can create or open a different workspace from the running app.
Single active graph The UI loads one graph into the active module at a time. There is no side-by-side multi-graph editing yet.
No undo / redo Mutations are immediately committed to the graph and database. There is no undo stack. The Transaction primitive exists and could support undo in a future milestone.
No drag-and-drop reordering Items can be moved via OutlineService.move_item() but the UI does not yet expose drag-and-drop.
Single bundled module The host can load modules from configuration, but only the Outline module ships in this repository today.
No graph export There is no JSON, Markdown, or PDF export in the current version.
No search There is no cross-graph or cross-workspace search.
No multi-window Each module lives in a tab. There is no way to open two outlines side-by-side.
Single-user only The cache and persistence layer assume a single writer. Multi-process access to the same SQLite file is not safe.
No attribute indexing Node and edge attributes are stored as JSON blobs. SQL-level queries against attribute values are not supported.

Roadmap

The following milestones are planned in rough priority order. None are committed dates — they represent the natural next steps from the current architecture.

Milestone 1 — Workspace Session Polish

  • Persist the last-opened workspace and reopen it on launch.
  • Add a startup chooser for opening an existing workspace or creating a new one.
  • Persist the last-opened graph per module.

Milestone 2 — Outline UX Polish

  • Drag-and-drop reordering of outline items.
  • Keyboard shortcuts (Enter to add sibling, Tab/Shift-Tab to indent/outdent).
  • Inline title editing directly in the tree (no dialog needed for title changes).
  • Undo / redo via the Transaction primitive already in the engine.

Milestone 3 — Export & Import

  • Export an outline to Markdown (heading hierarchy).
  • Export to plain text and HTML.
  • Import a Markdown file as an outline graph.

Milestone 4 — Second Module

  • Implement a second module (e.g. Kanban board or concept map) using only package installation plus modules.yaml.
  • This milestone validates the config-driven plugin host against a different graph shape.

Milestone 5 — Search & Cross-Graph Navigation

  • Full-text search across node titles and content within a workspace.
  • Backlink view: show all nodes that reference a given node by title.

Milestone 6 — Version History

  • Surface the version counter already stored on every node and edge.
  • Record a changelog per graph (timestamp, operation, old/new attributes).
  • Allow diff-view and point-in-time restore.

Milestone 7 — Multiple Projections Per Module

  • Allow each module to register more than one projection (e.g. Outline can show tree view OR flat reading view).
  • Add a projection switcher to the module tab toolbar.

Milestone 8 — Swift / Cross-Platform Target

  • The architecture was designed to be migrated to Swift with data compatibility.
  • Milestone: define a portable on-disk format (JSON or SQLite schema) shared between the Python and Swift implementations.

Project Structure

knowledge-platform/
├── pyproject.toml               # Build system, dependencies, tool config
├── requirements.txt             # Flat dependency list for pip
├── DESIGN.md                    # Architecture, diagrams, patterns, extension guide
├── docs/                        # MkDocs source
└── src/knowledge_platform/
    ├── core/                    # Graph engine, Node, Edge, Transaction
    ├── domain/                  # GraphType system, TypeRegistry
    ├── persistence/             # SQLAlchemy ORM, SqliteGraphRepository
    ├── services/                # IGraphService contract + implementations
    ├── workspace/               # Workspace container
    ├── modules/
    │   ├── base.py              # ModuleDescriptor + GraphWidget protocols
    │   ├── registry.py          # ModuleRegistry
    │   └── outline/             # Outline plugin (self-contained)
    └── ui/
        ├── app.py               # Application bootstrap
        ├── events.py            # AppEventBus (cross-component signals)
        ├── main_window.py       # QMainWindow
        └── outline/             # Outline view + viewmodel

Contributing

Contributions are welcome. Before opening a pull request:

  1. Run the test suite: pytest tests/unit tests/integration --no-cov
  2. Run the type checker: mypy src/
  3. Run the linter: ruff check src/ tests/
  4. Run the formatter: ruff format src/ tests/
  5. Add tests for any new domain or service logic.
  6. If adding a new module, follow the module extension guide in DESIGN.md.

License

MIT — see LICENSE.

About

A modular knowledge-work application platform whose primary user-facing artifact is a structured graph.

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages