experimental.lifecycle
Usage
Store lifecycle: create a store tether then owns, and reclaim it.
Experimental. Everything else tether does to a store is recoverable from the manifests: a deleted pin can be repaired, a deleted branch re-forked. delete-store cannot be, and its blast radius is a whole store. The feature has also not yet run against the resources it was written for – an S3 prefix, a second clone – outside tests with stand-ins. So it lives here, behind the same seam as the registry: the stable surface is what users type and import (tether add --create, tether gc --delete-stores, Repo.create, Repo.add(create=True)), and the engine half is imported lazily by those entry points. Module paths under tether.experimental are not API.
What is here:
- the created-store index beside the repository lock (
tether-created.jsonl) and the reader of the touched-store journal (tether-touched.jsonl). The journal itself – what this clone has forked a branch in or pinned – is core-owned and written by every fork and pin (tether.oplog.append_touched), so that stable commands never import this module and the record is complete by the time the feature graduates; only the consumer lives here; - create_store: the
add --createpath (make, mark, index, register, fork on a bookmark), and undo_add_store, its reversal while the store is still empty; - the
gc --delete-storesstep (plan_stores, apply_store_action): release this dataset’s dead refs in stores no manifest names, and delete a created store once the backend confirms nothing else remains, under the rules documented onplan_created_storesandplan_store_refs.
The backend contract this rides on (Capability.CREATE: create, owner, is_ref_empty, delete_store) stays in tether.backends.base with conformance coverage; it is a per-backend fact, marked experimental in its docstring.
Graduation criteria – what has to be true before this moves back into tether.repo and loses the experimental note:
- The S3 arm of Icechunk’s delete_store has run once against a real bucket (the in-memory obstore test covers the logic, not the service).
- The two-clone scenario in
tests/test_store_lifecycle.pyhas run against a real remote (a hosted git or jj remote), not a local clone. - One release cycle with the feature in users’ hands and no data-loss report.
- A second Forkable backend declares CREATE (Neon project or branch; Lance once an empty schema is acceptable), showing the capability generalises beyond “make an empty directory or repository”.
- A decision on the touched index: keep it as the mechanism for dead refs in unnamed stores, or fold that into
--prune-bookmarksby walking the stores of every manifest in history.
Attributes
| Name | Description |
|---|---|
| CREATED_FILENAME | Repository-wide index of stores tether created, kept next to the |
| STORE_OPS | The plan verbs this module applies (apply_store_action). |
CREATED_FILENAME
Repository-wide index of stores tether created, kept next to the
CREATED_FILENAME="tether-created.jsonl"
repository lock in the shared VCS store (VcsAdapter.shared_dir()): one clone of the dataset, every checkout, never committed. History cannot hold this – an abandoned fork takes the manifest that named the store with it – and a workspace’s own log dies with forget-workspace. This survives both.
STORE_OPS
The plan verbs this module applies (apply_store_action).
STORE_OPS=frozenset({"keep-store", "forget-store", "forget-touched", "delete-store"})
Classes
| Name | Description |
|---|---|
| CreatedStore |
One store tether made (add --create); gc may remove it once nothing
|
CreatedStore
One store tether made (add --create); gc may remove it once nothing
Usage
CreatedStore(
dataset_id,
kind,
identity,
locator,
key,
at,
bookmark=None,
)references it and the store confirms the owner marker.
Parameter Attributes
dataset_id: strkind: stridentity: dict[str, Any]-
ObjectBackend.identity(locator): what a manifest reference is matched on. locator: dict[str, Any]key: str-
The key it was registered under at creation (informational).
at: strbookmark: str | None = None-
The bookmark the store was created on. Its
tether.ws.*branch is the one this clone can account for whengcjudges the store; a same-dataset branch of a bookmark this clone never had may be another actor’s.
Functions
| Name | Description |
|---|---|
| append_created() | Record a store tether just created (journal-style, synced). |
| apply_store_action() |
Apply one store verb of a gc plan (called from apply_gc, after every
|
| create_store() |
The add --create path, under the caller’s writer lock: require
|
| created_stores() |
Stores this dataset created (add --create) and has not yet removed.
|
| plan_stores() |
The gc --delete-stores step: created stores first (they may be
|
| preview_store_action() | What a dry run reports for one store verb. |
| read_created() | Every created store on record (optionally one dataset’s), oldest first. |
| remove_created() |
Forget a store (deleted by gc, or by undo add).
|
| touched_stores() | Stores this clone has forked or pinned in. |
| undo_add_store() |
add --create made a store: take it away again while it is still
|
append_created()
Record a store tether just created (journal-style, synced).
Usage
append_created(shared_dir, entry)apply_store_action()
Apply one store verb of a gc plan (called from apply_gc, after every
Usage
apply_store_action(repo, a, report, errors, op)other action; delete-store re-checks owner and emptiness first).
create_store()
The add --create path, under the caller’s writer lock: require
Usage
create_store(repo, key, kind, locator, *, policy, pre)CREATE, journal, have the backend make the store with this dataset’s owner marker, index it, register it with origin = "created", and on a non-trunk bookmark fork its working branch at once.
created_stores()
Stores this dataset created (add --create) and has not yet removed.
Usage
created_stores(repo)plan_stores()
The gc --delete-stores step: created stores first (they may be
Usage
plan_stores(
repo,
plan,
manifests,
*,
keep_bookmarks,
prune_bookmarks,
force,
claimed=()
)deleted), then this clone’s dead refs in every other store it touched.
preview_store_action()
What a dry run reports for one store verb.
Usage
preview_store_action(a, report)read_created()
Every created store on record (optionally one dataset’s), oldest first.
Usage
read_created(shared_dir, dataset_id=None)remove_created()
Forget a store (deleted by gc, or by undo add).
Usage
remove_created(shared_dir, dataset_id, identity)touched_stores()
Stores this clone has forked or pinned in.
Usage
touched_stores(repo)undo_add_store()
add --create made a store: take it away again while it is still
Usage
undo_add_store(repo, entry, report)empty (its own working branch, if add forked one, does not count); a store that has been written to stays, and gc decides later.