Norn: a provider-neutral multi-agent development harness
Project description
Norn
Provider-neutral multi-agent development harness for local subscription CLIs. The name evokes the Norns who shape fate: the harness coordinates independent agents toward a bounded outcome.
Status: beta. The
norn-clidistribution is published to PyPI; the source repository remains private during the beta period.
Norn provides configuration, CLI, run-state, event journal, recovery, human-readable escalation reports, provider-neutral adapters, and an executable multi-role delivery pipeline for Codex, Claude Code, Grok Build, and future command-based subscription CLIs.
norn init
norn --version
norn doctor
norn validate-config
norn providers
norn plan "add an audit log"
norn run "add an audit log"
Install the bundled explicit-invocation skill for both Codex and Claude Code:
norn install-skill --target all --scope project --project /path/to/repository
This writes .agents/skills/norn for Codex and .claude/skills/norn for Claude Code. Use
$norn in Codex or /norn in Claude Code. Install a single user-level copy with
--target codex|claude --scope user; use --force only to replace an existing
copy intentionally. Loading the skill never starts a model-consuming lifecycle
unless the user explicitly requests plan or run.
See Installation for isolated uv tool, pipx, and
virtual-environment installs from PyPI.
plan runs orchestration, planning, and plan review. run continues through
implementation, language-aware local tests/lint, the four tester roles, triage,
and final gate. UI changes require an independent E2E result from every tester.
Each required E2E result must include the executed argv, exit code, a concise
result summary, and at least one non-empty artifact created in that tester's
assigned evidence directory. The harness rejects missing, stale, symlinked, or
out-of-directory evidence and archives accepted files under
.norf/runs/<run-id>/artifacts/e2e/.
For Codex tester roles, the adapter keeps workspace-write filesystem isolation
and enables command networking through a loopback-only proxy allowlist
(localhost and 127.0.0.1). Planning and implementation roles retain their
normal network-off policy.
Profiles keep a stable logical model name while optionally mapping it to a provider-specific identifier. For example, Codex Sol is configured as:
candidates:
- provider: codex-cli
model: sol
model_id: gpt-5.6-sol
effort: high
Round limits are configured under limits or overridden per invocation:
norn run "task" --max-rounds 5 --max-total-rounds 12 \
--max-planner-retries 2 --max-final-replans 2
Known Python, Node, Rust, and Go gates are auto-detected. Projects can define additional commands as shell-free argv lists:
gates:
enabled: true
auto_detect: true
commands:
- name: integration
kind: test
command: [python3, -m, pytest, tests/integration]
Each run records role responses, model selections, attempts, findings, test
results, and round history below .norf/runs/<run-id>/. Any non-successful stop
also produces escalation-report.md and escalation.json for human judgment.
By default, run requires a clean Git repository and implements inside a
detached .norf/worktrees/<run-id>/ worktree. Set git.worktree: false only when
direct changes to the selected project directory are intentional.
Development and packaging
Install the local development tools and run the same checks as CI:
python3 -m pip install --editable ".[dev]"
ruff format --check .
ruff check .
python3 -m unittest discover -v
python3 -m build
python3 scripts/package_smoke.py dist/norn_cli-0.7.1-py3-none-any.whl
CI runs the quality suite on Python 3.12, 3.13, and 3.14, then installs the built wheel in a clean virtual environment and verifies both Codex and Claude skill copies. It uploads the distributions as a short-lived workflow artifact. Publishing a GitHub Release runs the same deterministic gates before sending the verified artifact to PyPI through OIDC Trusted Publishing; neither workflow invokes subscription models.
Release acceptance is intentionally split in two: CI performs deterministic package checks, while local acceptance invokes the authenticated subscription CLIs. Follow Release acceptance before promoting a release. See CHANGELOG for version history and Security for private vulnerability reporting.
The canonical command is norn. The legacy norf-harness executable remains an alias during
the pre-1.0 migration; new automation should use norn.
License
Copyright 2026 uruca-kk. Licensed under the Apache License 2.0.
Project details
Release history Release notifications | RSS feed
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 norn_cli-0.7.1.tar.gz.
File metadata
- Download URL: norn_cli-0.7.1.tar.gz
- Upload date:
- Size: 59.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1b0c1251d6590bcb9628ebc50205e460e7d5028a9a31f4d47dc47bf7d4056027
|
|
| MD5 |
ab839b19287bc8d082122d429693aab7
|
|
| BLAKE2b-256 |
4e5ecefa777bbd8e4b92cf352739d3bd78fd348e9cb70dcaca2957968afcb283
|
Provenance
The following attestation bundles were made for norn_cli-0.7.1.tar.gz:
Publisher:
publish.yml on uruca-kk/norn
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
norn_cli-0.7.1.tar.gz -
Subject digest:
1b0c1251d6590bcb9628ebc50205e460e7d5028a9a31f4d47dc47bf7d4056027 - Sigstore transparency entry: 2165565235
- Sigstore integration time:
-
Permalink:
uruca-kk/norn@a3f695d5ff8abfcbdd2e66b9bdc4c08be8462bcd -
Branch / Tag:
refs/tags/v0.7.1 - Owner: https://github.com/uruca-kk
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a3f695d5ff8abfcbdd2e66b9bdc4c08be8462bcd -
Trigger Event:
release
-
Statement type:
File details
Details for the file norn_cli-0.7.1-py3-none-any.whl.
File metadata
- Download URL: norn_cli-0.7.1-py3-none-any.whl
- Upload date:
- Size: 57.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef366e2a0c5ffef0fbcacd6a0da320e694feb6c106c499ab657fe7b87fd21ff1
|
|
| MD5 |
04198cd388326ffc60e9b3f5b5e7109d
|
|
| BLAKE2b-256 |
bcde7dca18b66c16c2e539d89df1a301237b9e5119979836cee47e072aa2b5a7
|
Provenance
The following attestation bundles were made for norn_cli-0.7.1-py3-none-any.whl:
Publisher:
publish.yml on uruca-kk/norn
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
norn_cli-0.7.1-py3-none-any.whl -
Subject digest:
ef366e2a0c5ffef0fbcacd6a0da320e694feb6c106c499ab657fe7b87fd21ff1 - Sigstore transparency entry: 2165565265
- Sigstore integration time:
-
Permalink:
uruca-kk/norn@a3f695d5ff8abfcbdd2e66b9bdc4c08be8462bcd -
Branch / Tag:
refs/tags/v0.7.1 - Owner: https://github.com/uruca-kk
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a3f695d5ff8abfcbdd2e66b9bdc4c08be8462bcd -
Trigger Event:
release
-
Statement type: