Skip to main content

A web framework for code that agents maintain. The right path is free fall.

Project description

Curvature

The right path is free fall.

gate PyPI Python Coverage floor License

Spiral is project spacetime

Spiral is on by default. Every directory is a local body: its substantial source files occupy surface, and the surface-to-volume law determines how much room a healthy leaf has to grow.

For a sphere of radius (r),

$$ A(r)=4\pi r^2,\qquad V(r)=\frac{4}{3}\pi r^3,\qquad \frac{V(r)}{A(r)}=\frac{r}{3}. $$

Curvature normalizes each direct source file (f) by its language's base ceiling (B_{\tau(f)}), then measures the occupied surface of directory (D):

$$ m_f=\frac{\operatorname{lines}(f)}{B_{\tau(f)}},\qquad A_D=\sum_{f\in\operatorname{direct}(D)}\min(1,m_f),\qquad R_D=\max(1,\sqrt{A_D}). $$

The effective ceiling is the ratcheted base multiplied by that local radius:

$$ C_f=\operatorname{round}(B_fR_D). $$

A lone Python leaf therefore begins at 300 lines and cannot buy room by becoming oversized. Two substantial neighboring leaves have radius (\sqrt2) and a 424-line Python ceiling; three have 520, five have 671, and eight have 849. Child directories form their own bodies, so distant project mass cannot inflate a local file. At thirteen meaningful neighbors the twelve-neighbor coordination bound fires and the directory must branch. The gate also prunes hollow branches that retain only cache archaeology or missing tracked leaves. The derivation and adoption controls live in The Spiral law.

A web framework for code that agents maintain. Live, dynamic web apps in pure Python — single-page feel, pages that update themselves in real time, zero JavaScript app code — and a gate that makes the maintainable path the only path that builds. (Not a static-site generator: state lives on the server, and open pages stay current over a live stream.)

Curvature's design center is the maintainer nobody watches: the coding agent in its forty-third session, at 2 a.m., doing whatever the shape of the code suggests. Frameworks built for humans enforce their discipline through culture. Curvature's discipline is machine-checked — every invariant in SPEC.md names the check that enforces it, and violations are reported by curvature check as anomalies — regions where the geometry failed to steer. The canonical documentation is AGENTS.md; this README is the courtesy translation. The argument for all of it is the MANIFESTO.

The shape of it

from curvature import Element, Props, redirect, respond
from curvature import html as h


class LapProps(Props):
    title: str
    done: bool


def lap(props: LapProps) -> Element:
    return h.li(props.title, class_="lap done" if props.done else "lap", id="lap")
  • Components are functions of frozen, closed pydantic props. The UI is just Python: typed by pyright, measured by coverage, tested by pytest without a browser in sight.
  • The app works with JavaScript off. Reads render full pages; writes are POST → redirect → GET through real forms. Your test suite drives it with httpx — which executes no JS — so the degraded path is the tested path, permanently.
  • Pages keep themselves current. Live (SSE) pushes updates into every open browser — the demo's roadmap redraws when anyone ships a card — with zero app JavaScript.
  • curvature.js (the only script, held under a 150-line ratcheted ceiling) boosts working links and GET forms into fragment swaps. Mutating forms stay native, so a lost connection can never turn a POST into the wrong GET. Same route, same render, one header of difference.
  • The ratchet only tightens; healthy trees Spiral. Base file ceilings fall, the coverage floor rises, and curvature ratchet is the only hand on the mechanism. Local occupied surface lets related leaves grow by radius, while a twelve-neighbor coordination bound keeps branches navigable. The 10,000-line dumping ground and the 160-file trunk remain anomalies.

Start from nothing

One prerequisite, one line (uv):

# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

Then:

uvx curvature new app pitstop     # no venv, no Python even — uv brings it
cd pitstop
./gate.sh                      # green before you write a line
./run.sh                       # http://127.0.0.1:8000

Only have pip? pip install curvature && python -m curvature new app pitstop — the python -m form dodges PATH entirely; the poured README carries the rest of the old ritual.

Onboarding an agent takes zero steps: the scaffold poured AGENTS.md, the gate, and one example component as the pattern. Point your agent at the directory and ask for a feature — the repo is the prompt.

The demo

PyPI ships the framework; the repo ships Pit Board, the demo:

git clone https://github.com/siliconsociety/Curvature && cd Curvature
uv sync && ./gate.sh
uv run uvicorn demo.app:app --reload --timeout-graceful-shutdown 1   # Pit Board

Then turn JavaScript off and use it again. Links, forms, redirects, and refreshes still work; only enhancement (fragment swaps and live push) disappears. That is the boundary.

Updating an app

Curvature has two ownership classes. The installed package owns the runtime, including curvature.js, Live, response helpers, and the gate. Update that runtime deliberately, review the lockfile, and run the app's gate:

uv lock --upgrade-package curvature
uv sync
./gate.sh

The app owns everything the scaffold or a satellite pour copied into its repository. Package upgrades never overwrite those files. When a release requires an app-source migration, its upgrade note names the files and the owner applies the diff like any other code change. See docs/UPGRADING.md for the complete contract and release-specific notes.

Status

Alpha. The contract, runtime, gate, demo, browser-level boost tests, and a fresh-pour Auth integration suite are real and self-hosting. Production readiness is earned by the gate and deployment checks, not asserted by the version label. The spec is versioned and arguable; argue by issue.

MIT. Built by Robert Sharp, with Claude Fable 5 on its last day on the subscription — read the manifesto and you'll see why that detail belongs in a README.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

curvature-0.3.0.tar.gz (52.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

curvature-0.3.0-py3-none-any.whl (73.1 kB view details)

Uploaded Python 3

File details

Details for the file curvature-0.3.0.tar.gz.

File metadata

  • Download URL: curvature-0.3.0.tar.gz
  • Upload date:
  • Size: 52.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for curvature-0.3.0.tar.gz
Algorithm Hash digest
SHA256 74c57b5b5bb7f785eccd4629e8b802200af710dff27c1695dc99b8bd48854647
MD5 3b4b5aae0bf7373bc4b158f7f9b2ff4c
BLAKE2b-256 b3942447a00a707b58d9a9d2d2b804672343c6d0e0d91dd9bcb65c39163d34da

See more details on using hashes here.

File details

Details for the file curvature-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: curvature-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 73.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for curvature-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1a6e3105c51fd49f0a3479ae23ebce18e6c183a5e4c8b44178ba1bd04877a2b5
MD5 c0b0d2965541a51b724c05e29879e7ec
BLAKE2b-256 86110bf09429d89850809f7558e0b05922f46b1fb89fa01ef7c935a9ea438f92

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page