Norns
Norns is a Kanban orchestration system where each board column runs an isolated LLM agent and a human approval gate controls progression to the next stage. The name comes from the Norse Norns: Urd, Verdandi, and Skuld.
v0.0.2 site: yanchao1999.github.io/Norns. First-use backlog: ROADMAP.md.
Features
- Local Control Room (
norns init/norns run) — UI in the browser by default, optional Electron window, config under~/.norns - Visual state machine editor for board stages, order, parallel tracks, and human-gate vs auto-advance
- FastAPI + async SQLAlchemy backend with PostgreSQL-ready configuration
- ARQ/Redis queue for isolated stage execution (optional; local IDE runs stages in-process)
- React + TypeScript Kanban UI with approval-aware movement
- Stage agents may recommend approve or reject; a human still confirms at the gate
- Encrypted connector secrets at rest with Fernet
- OpenAI-compatible stage agents with explicit per-stage tool allowlists
- PlantUML-first documentation and handoff previews
Flow Diagram
@startuml
skinparam monochrome true
actor Human
rectangle Board {
rectangle "Stage 1\n(Urd agent)" as S1
rectangle "Stage 2\n(Verdandi agent)" as S2
rectangle "Stage 3\n(Skuld agent)" as S3
}
Human --> S1 : create / approve
S1 --> Human : handoff + recommend approve/reject
Human --> S2 : confirm approve or reject
S2 --> Human : handoff + recommend approve/reject
Human --> S3 : confirm approve or reject
@enduml
Runtime Sequence
@startuml
skinparam monochrome true
actor Human
participant Frontend
participant Backend
participant Redis
participant Worker
participant Agent
Human -> Frontend : Approve card
Frontend -> Backend : POST /api/cards/{id}/approve
Backend -> Redis : enqueue next stage
Redis -> Worker : run_stage_task
Worker -> Agent : run_stage(card, stage, run)
Agent -> Backend : persist AgentRun + handoff (recommendation is advisory)
Backend -> Frontend : waiting_approval state
Human -> Frontend : confirm approve or reject
@enduml
Architecture Overview
- Boards / Stages define the workflow and per-column agent configuration. Edit stages and transition lines in the Control Room Machine view. Two default lines from one stage split the card into parallel tracks (for example unit tests and software). Lines from two or more stages into one stage join those tracks when every track has finished.
- Cards carry the work item body and current stage pointer.
- Agent runs are isolated; no chat memory is shared between stages.
- Handoffs from stage N are the only structured context for stage N+1. On a human gate, the agent may set
recommendationtoapproveorreject; the card still waits until a person confirms. Draw an If onrecommendationif that suggestion should choose the next stage after confirmation. - Connectors are Python-library backed only (PyGithub, jira, polarion); raw credentials are never exposed to agents.
Install (pip / uv)
Python 3.12+. norns run opens the Control Room in your browser. Electron is optional.
# From this checkout (needs Node.js 20+ or Docker once, to compile the UI into the package):
uv tool install .
# or
python3 -m pip install .
norns init # prints an admin password; also stored in ~/.norns/config.toml
norns run # http://127.0.0.1:8765
After this is published (see PUBLISH.md):
uv tool install norns-ide
# or
python3 -m pip install norns-ide
The PyPI name is norns-ide because norns is already taken. The command is still norns.
From GitHub after this branch is merged:
uv tool install git+https://github.com/YanChao1999/Norns.git
# or
python3 -m pip install git+https://github.com/YanChao1999/Norns.git
norns run --no-window starts the server without opening a browser (used by CI). Data lives under ~/.norns unless you pass --home or set NORNS_HOME. Use norns init --force to replace config and delete norns.db (no schema back-compat before a published 0.0.1). Set openai.api_key in ~/.norns/config.toml when you want a real model instead of a placeholder handoff.
Optional desktop window
npm install --prefix norns/electron # from a git checkout
norns run
Developer checkout
uv run is an editable install, so it does not run the wheel build that bakes the UI in. norns run compiles frontend/ on first start with npm if it is on PATH (or ./.tools/node), otherwise with Docker using the same node:20 image as docker compose up. If docker compose left frontend/node_modules root-owned, the build uses ~/.cache/norns/ui-build instead. Rebuild after UI source changes with ./scripts/stage-ui.sh (same npm-or-Docker path; it always rebuilds, unlike norns run).
uv sync
uv run norns init
uv run norns run
Docker compose (optional)
Use this when you want PostgreSQL, Redis, and a browser-based Vite dev server instead of the desktop IDE.
- Copy
.env.exampleto.envand set real secrets. - Generate unique secrets (do not keep the example values):
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" python -c "import secrets; print(secrets.token_urlsafe(32))"
Put them inENCRYPTION_KEYandSECRET_KEY. The API and worker must share the same encryption key. - Start the stack:
docker compose up
- Open:
- Frontend:
http://localhost:5173 - Backend API:
http://localhost:8000/docs
- Frontend:
- Sign in with the
ADMIN_USERNAME/ADMIN_PASSWORDfrom your.env(defaults areadmin/adminonly whenNORNS_ENV=local). For a shared host setNORNS_ENV=production, a uniqueADMIN_PASSWORD, andSESSION_COOKIE_SECURE=true. - Create a board, add a card, open it, and click Run this stage. Cards only move after approval unless a stage has auto-advance enabled.
docker compose builds a Python image once. Rebuild after dependency changes: docker compose build.
Development Setup
pip install -e ".[dev]"
python -m pytest backend/tests/ -q
bash scripts/lint.sh
cd frontend && npm install && npm run dev
Pull requests to main must pass the CI GitHub Actions check (backend tests, frontend typecheck/build, lint static analysis and format, package wheel/sdist plus norns CLI). Direct pushes to main are not blocked, but merges are.
Notes
- Local IDE mode uses SQLite and
QUEUE_BACKEND=inline(no Redis). Docker/production can keep Redis viaQUEUE_BACKEND=redis. - Schema is created with SQLAlchemy
create_all. There is no upgrade migration until 0.0.1 is published;norns init --forcedeletes the local database. - Use PostgreSQL in normal deployments via
DATABASE_URL. - Redis backs ARQ worker execution.
- PlantUML/Kroki rendering is opt-in via
PLANTUML_URL/KROKI_URL(unset means no public egress). - An empty per-stage tool allowlist grants no tools. Enable norns (create cards, edit stages/prompts, edit the state machine, inspect the git workspace), github, jira, or polarion on the column Agent dialog. Cursor stages receive those as MCP servers; OpenAI/DeepSeek stages use the same plugins as chat tools.
- Workspace (git repo): each board has a checkout path and/or
https://github.com/org/repo. Stage agents inherit the board repo; a column Agent can override with its own path/URL. Cursor stages then run in that checkout (local agent) instead of a throwaway/tmpdirectory; GitHub tools default to that repo. If neither board nor agent is set, Norns uses the git root of the process working directory. - Extra MCP servers: add an MCP connector in Settings (stdio command or HTTP URL), then enable it under Agent → Tools. Third-party Python plugins register the
norns.pluginsentry point. norns mcp --plugins norns,github,jiraruns the plugin MCP server on stdin/stdout (Cursor attaches this automatically when those tools are enabled).PUT /api/cards/{id}updates title/body only; new cards always start on the first stage.- Change
SECRET_KEYandADMIN_PASSWORDbefore any shared deployment. Sessions expire after 8 hours.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file norns_ide-0.0.2.tar.gz.
File metadata
- Download URL: norns_ide-0.0.2.tar.gz
- Upload date:
- Size: 454.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b88d8cef31d065cd592960ce6893c9e47a0786c4f1c826707e7cb45414410637
|
|
| MD5 |
4c43593e0ecea6c3f79f64a9e73750c4
|
|
| BLAKE2b-256 |
a68e371b11f786d8f310cd1d82e62e7f80880f54b1d3df1124c68d4f27abaff9
|
Provenance
The following attestation bundles were made for norns_ide-0.0.2.tar.gz:
Publisher:
publish.yml on YanChao1999/Norns
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
norns_ide-0.0.2.tar.gz -
Subject digest:
b88d8cef31d065cd592960ce6893c9e47a0786c4f1c826707e7cb45414410637 - Sigstore transparency entry: 2652015296
- Sigstore integration time:
-
Permalink:
YanChao1999/Norns@dcbf104d217edb47e506813bd6e626aef2e606af -
Branch / Tag:
refs/heads/main - Owner: https://github.com/YanChao1999
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@dcbf104d217edb47e506813bd6e626aef2e606af -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file norns_ide-0.0.2-py3-none-any.whl.
File metadata
- Download URL: norns_ide-0.0.2-py3-none-any.whl
- Upload date:
- Size: 267.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
18c5d73563a2a5a66fefc1c89f9f1661a7754b7ba809bcd6b1971a0af9fcfb98
|
|
| MD5 |
66303f1200fc66246dae72dbcd59bee7
|
|
| BLAKE2b-256 |
e4acd45df67f69972a61b9c287f1961205a8b9c82e2c9b7e31b90d3529dda9d0
|
Provenance
The following attestation bundles were made for norns_ide-0.0.2-py3-none-any.whl:
Publisher:
publish.yml on YanChao1999/Norns
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
norns_ide-0.0.2-py3-none-any.whl -
Subject digest:
18c5d73563a2a5a66fefc1c89f9f1661a7754b7ba809bcd6b1971a0af9fcfb98 - Sigstore transparency entry: 2652015449
- Sigstore integration time:
-
Permalink:
YanChao1999/Norns@dcbf104d217edb47e506813bd6e626aef2e606af -
Branch / Tag:
refs/heads/main - Owner: https://github.com/YanChao1999
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@dcbf104d217edb47e506813bd6e626aef2e606af -
Trigger Event:
workflow_dispatch
-
Statement type: