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:Objectrepresents a file-like entry (supporting text and binary read/write operations).Collectionrepresents 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 (
ObjectandCollection) 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 providesFilesystemandInMemorydrivers, extending this to a new backend is straightforward. -
Claim(ObjectClaim|CollectionClaim): Models resource ownership. EachBaseWorktreeItemdeclares which paths/files it claims to own. -
BaseWorktreeItem: A base class for concrete leaf items (such asArtifactorAnchor). It manages the state initialization, validation, and serialization logic for each declared claim during a sync or commit. -
Artifact[Value]/Anchor[Handle]:Artifacthas an in-memory representation (itsvalue()).Anchorcontrols resources with no direct in-memory representation (exposing ahandle()).
[!NOTE] If you use the filesystem storage driver, then
Artifact.value()usually represents the loaded contents of a file, whileAnchor.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 otherWorktreeItems. 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():
- Checks if the resource exists at the claimed path within its mounted collection.
- If missing:
- Touches/mkdir-s the target resource.
- Runs
initialize_object/initialize_collection(sets up default field states). - Performs an initial
commit_object/commit_collectionto write defaults to storage.
- If present:
- Runs
validate_object/validate_collectionto load the stored content and validate/populate in-memory fields.
- Runs
Upstream Synchronization (commit)
For each claim:
- Retrieves the stored resource (asserting it exists).
- Executes
commit_object/commit_collectionto 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
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 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
041afb2926d712948c0058f1471f04215c772a15667d2eab8ca55e6aaaee9854
|
|
| MD5 |
02219efd2ff2b1c48a674538ec2ade70
|
|
| BLAKE2b-256 |
56768e448ea9bc60525f7f79e1e72fdc982dfa5daa2267b951aa1a512cb570fe
|
Provenance
The following attestation bundles were made for worktree-0.1.0.tar.gz:
Publisher:
on_release.yml on FilipMalczak/worktree
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
worktree-0.1.0.tar.gz -
Subject digest:
041afb2926d712948c0058f1471f04215c772a15667d2eab8ca55e6aaaee9854 - Sigstore transparency entry: 1968534273
- Sigstore integration time:
-
Permalink:
FilipMalczak/worktree@073bd15ffb2f7283c1eeb3248b77ff8446b63c31 -
Branch / Tag:
refs/tags/0.1.0 - Owner: https://github.com/FilipMalczak
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
on_release.yml@073bd15ffb2f7283c1eeb3248b77ff8446b63c31 -
Trigger Event:
release
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ff95585712ef55c0e58d2b975da8ff6acf19be1c8276cad0e6e4caa0f2842df2
|
|
| MD5 |
44612230279495e1ecf660662dcccd7a
|
|
| BLAKE2b-256 |
33c6fa1f33b9f2ad658b7a433de706d5bbde8c114ff69146510768fdcc404770
|
Provenance
The following attestation bundles were made for worktree-0.1.0-py3-none-any.whl:
Publisher:
on_release.yml on FilipMalczak/worktree
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
worktree-0.1.0-py3-none-any.whl -
Subject digest:
ff95585712ef55c0e58d2b975da8ff6acf19be1c8276cad0e6e4caa0f2842df2 - Sigstore transparency entry: 1968534404
- Sigstore integration time:
-
Permalink:
FilipMalczak/worktree@073bd15ffb2f7283c1eeb3248b77ff8446b63c31 -
Branch / Tag:
refs/tags/0.1.0 - Owner: https://github.com/FilipMalczak
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
on_release.yml@073bd15ffb2f7283c1eeb3248b77ff8446b63c31 -
Trigger Event:
release
-
Statement type: