Skip to main content

Worktree is a declarative runtime system for defining and synchronizing persistent Artifact graphs between memory and external backends, with explicit lifecycle control and composable state trees.

Project description

worktree

Worktree is a declarative runtime system for defining and synchronizing persistent Artifact graphs between memory and external backends, with explicit lifecycle control and composable state trees.

If you run the following program for the first time, you will get "0" on stdout and the counter.json file in /data directory. If you rerun it, you'll be getting consecutive integers each time (and the file will change to track last printed number).

from worktree.contract import Worktree
from worktree.impl.items.pydantic_model import PydanticArtifact
from worktree.mounting.base import BaseMounter
from worktree.impl.accessibility.filesystem import FilesystemMountDriver

# Define an artifact mapping to a JSON object
class Counter(PydanticArtifact):
    mount_path = "counter.json"
    number: int = 0

# Define a worktree containing the artifact
class CounterWorktree(Worktree):
    counter: Counter

# Instantiate the mount driver and mounter
driver = FilesystemMountDriver()
root = driver.mount("/data")
mounter = BaseMounter(root)

# Mount the worktree (performing downstream sync automatically)
worktree = mounter.mount(CounterWorktree)

# Print and increment
print(worktree.counter.number) 
worktree.counter.number += 1

# Commit changes back to "/data/counter.json"
worktree.commit()

Poor for scripting, poor for webservices, pretty awesome for agentic systems.


Core Abstractions

Worktree bridges the gap between structured in-memory Python models and external, persistent storage backends. It is built around a few central abstractions:

  • Syncable: The base contract defining the synchronization lifecycle:

    • sync(): Pulls/validates state from storage to the in-memory models; if no storage representation is present, initializes the state and commits it.
    • commit(): Writes the current in-memory state back to storage.
  • Accessible (Object | Collection): Abstractions representing storage nodes:

    • Object represents a file-like entry (supporting text and binary read/write operations).
    • Collection represents a directory-like entry (supporting resource creation, deletion, and traversal).

    [!NOTE] We intentionally avoid strict "file" or "directory" terminology. The underlying storage accesses are generic abstractions (Object and Collection) which can be implemented for any storage provider — such as AWS S3, databases, remote APIs, sandboxed virtual shells, or SQL DBs. While the codebase currently provides Filesystem and InMemory drivers, extending this to a new backend is straightforward.

  • Claim (ObjectClaim | CollectionClaim): Models resource ownership. Each BaseWorktreeItem declares which paths/files it claims to own.

  • BaseWorktreeItem: A base class for concrete leaf items (such as Artifact or Anchor). It manages the state initialization, validation, and serialization logic for each declared claim during a sync or commit.

  • Artifact[Value] / Anchor[Handle]:

    • Artifact has an in-memory representation (its value()).
    • Anchor controls resources with no direct in-memory representation (exposing a handle()).

    [!NOTE] If you use the filesystem storage driver, then Artifact.value() usually represents the loaded contents of a file, while Anchor.handle() models a path to the managed directory. The distinction is meant to help us avoid representing actual data as indirect pointers or producing specialized abstractions over structures that are not meant to live in memory.

  • Worktree: A composable class containing other WorktreeItems. Sub-worktrees can run in sub-collections (directories) recursively.


Layout Anchors and Nested Configurations

For more complex directory structures, you can use a LayoutAnchor to organize collections without creating synchronization boundaries.

LayoutAnchor allows you to nest other layout anchors and artifacts using standard field annotations or nested inner classes:

from worktree.contract import Worktree, LayoutAnchor
from worktree.impl.items.pydantic_model import PydanticArtifact
from worktree.mounting.base import BaseMounter
from worktree.impl.accessibility.filesystem import FilesystemMountDriver

# Define artifacts
class DatabaseConfig(PydanticArtifact):
    mount_path = "db.json"
    host: str = "localhost"
    port: int = 5432

class ServerConfig(PydanticArtifact):
    mount_path = "server.json"
    debug: bool = False

# Define a layout with nested layouts and artifacts
class AppLayout(LayoutAnchor):
    # Defining a nested layout using an inner class
    class Storage(LayoutAnchor):
        db: DatabaseConfig
    
    # Declare fields matching the layout structure
    storage: Storage
    config: ServerConfig
    logs: LayoutAnchor  # Bare directory/collection stub

class ProjectWorktree(Worktree):
    app: AppLayout

# Mount and synchronize
driver = FilesystemMountDriver()
root = driver.mount("/data")
mounter = BaseMounter(root)
tree = mounter.mount(ProjectWorktree)

# Access deep-nested properties directly
print(tree.app.storage.db.host)  # prints "localhost" on first run, but "postgres.prod" on consecutive ones (see following lines)
print(tree.app.config.debug)     # prints False

# Modify nested values
tree.app.storage.db.host = "postgres.prod"
tree.commit()  # Recursively commits all modified artifacts

Synchronization Lifecycle

Downstream Synchronization (sync)

For each claim defined by ownership_claims():

  1. Checks if the resource exists at the claimed path within its mounted collection.
  2. If missing:
    • Touches/mkdir-s the target resource.
    • Runs initialize_object / initialize_collection (sets up default field states).
    • Performs an initial commit_object / commit_collection to write defaults to storage.
  3. If present:
    • Runs validate_object / validate_collection to load the stored content and validate/populate in-memory fields.

Upstream Synchronization (commit)

For each claim:

  1. Retrieves the stored resource (asserting it exists).
  2. Executes commit_object / commit_collection to write current in-memory field values back to storage.

Development

We use uv for python dependency and environment management.

Installation

Clone the repository and install dependencies:

uv sync

Running Tests

Execute the test suite (covering unit and E2E scenarios):

uv run pytest

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

worktree-0.1.0.tar.gz (13.6 kB view details)

Uploaded Source

Built Distribution

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

worktree-0.1.0-py3-none-any.whl (16.1 kB view details)

Uploaded Python 3

File details

Details for the file worktree-0.1.0.tar.gz.

File metadata

  • Download URL: worktree-0.1.0.tar.gz
  • Upload date:
  • Size: 13.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for worktree-0.1.0.tar.gz
Algorithm Hash digest
SHA256 041afb2926d712948c0058f1471f04215c772a15667d2eab8ca55e6aaaee9854
MD5 02219efd2ff2b1c48a674538ec2ade70
BLAKE2b-256 56768e448ea9bc60525f7f79e1e72fdc982dfa5daa2267b951aa1a512cb570fe

See more details on using hashes here.

Provenance

The following attestation bundles were made for worktree-0.1.0.tar.gz:

Publisher: on_release.yml on FilipMalczak/worktree

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file worktree-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: worktree-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 16.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for worktree-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ff95585712ef55c0e58d2b975da8ff6acf19be1c8276cad0e6e4caa0f2842df2
MD5 44612230279495e1ecf660662dcccd7a
BLAKE2b-256 33c6fa1f33b9f2ad658b7a433de706d5bbde8c114ff69146510768fdcc404770

See more details on using hashes here.

Provenance

The following attestation bundles were made for worktree-0.1.0-py3-none-any.whl:

Publisher: on_release.yml on FilipMalczak/worktree

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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