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):
    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):
    host: str = "localhost"
    port: int = 5432

class ServerConfig(PydanticArtifact):
    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.2.0.tar.gz (14.0 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.2.0-py3-none-any.whl (16.6 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for worktree-0.2.0.tar.gz
Algorithm Hash digest
SHA256 ee04db895c5fc8cd723fb9a7beb98a6040185e7baad9e95f66747b14a2537b54
MD5 20cf4a7ad95e4a5a794d9e4d98cc0b72
BLAKE2b-256 1c359d09b2004c3271b249149f663deb2926b67dec15b7153331dcfe81d5ed54

See more details on using hashes here.

Provenance

The following attestation bundles were made for worktree-0.2.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.2.0-py3-none-any.whl.

File metadata

  • Download URL: worktree-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 16.6 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.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 185b1cc8df8fa6fd7b14a7f4cc87b7e1ec77df4c4668d6516a724c3d3dd0b803
MD5 3f505cb866bdbaa650bd3da2e1dd12a0
BLAKE2b-256 cf44ccd59a8fae1b27a404d87a3ce4849e414662dac7e61e8e43740dba920173

See more details on using hashes here.

Provenance

The following attestation bundles were made for worktree-0.2.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