worktree-controller 1.30.4__tar.gz → 1.30.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- worktree_controller-1.30.6/PKG-INFO +105 -0
- worktree_controller-1.30.6/README.md +88 -0
- worktree_controller-1.30.6/docs/architecture.md +78 -0
- worktree_controller-1.30.6/docs/first-change.md +140 -0
- worktree_controller-1.30.6/docs/getting-started.md +75 -0
- worktree_controller-1.30.6/docs/operations.md +268 -0
- worktree_controller-1.30.6/docs/publishing.md +104 -0
- worktree_controller-1.30.4/README.md → worktree_controller-1.30.6/docs/reference.md +13 -142
- worktree_controller-1.30.6/examples/change_task.py +242 -0
- worktree_controller-1.30.6/examples/quickstart.py +174 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/pyproject.toml +13 -2
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/pyproject.toml.orig +9 -2
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/__init__.py +1 -1
- {worktree_controller-1.30.4 → worktree_controller-1.30.6/src/worktree_controller}/tool_cli_contract.json +1 -1
- {worktree_controller-1.30.4/src/worktree_controller → worktree_controller-1.30.6}/tool_cli_contract.json +1 -1
- worktree_controller-1.30.4/PKG-INFO +0 -3149
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/LICENSE +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/activation_layout.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/branch_retirement.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/canonical_refresh.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/canonical_transition.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/cleanup_attempts.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/cleanup_evidence.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/cleanup_recovery.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/cli.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/controller.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/convergence.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/delivered_closeout.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/disposable.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/environment.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/frozen_recovery.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/git_backend.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/governance.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/hardlinks.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/integration_cleanup.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/integration_conflict.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/integration_retry.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/keyed_document_scope.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/lifecycle.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/lifecycle_history.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/lifecycle_observation.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/metadata_codec.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/metadata_relocation.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/models.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/mount_diagnostics.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/multiple_cleanup_recovery.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/namespace_migration.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/native_session_recovery.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/owner_actions.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/policy.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/preservation.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/preserved_cleanup.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/publication_execution.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/reconciler.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/recovery_guidance.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/registration_backfill.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/registration_prune.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/rendering.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/resource_admission.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/retirement_adapters.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/retirement_execution.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/semantics.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/session.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/session_admission.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/source_cleanup.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/source_preservation.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/source_recovery.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/store.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/transaction_scope.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/writer_lease.py +0 -0
- {worktree_controller-1.30.4 → worktree_controller-1.30.6}/src/worktree_controller/writer_session.py +0 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: worktree-controller
|
|
3
|
+
Version: 1.30.6
|
|
4
|
+
Summary: Govern Git worktree budgets, authority, ownership, and lifecycle
|
|
5
|
+
License-Expression: Apache-2.0
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
9
|
+
Requires-Dist: websockets>=15,<16
|
|
10
|
+
Requires-Python: >=3.12, <3.13
|
|
11
|
+
Project-URL: Homepage, https://github.com/xuanheng-tech/worktree-controller
|
|
12
|
+
Project-URL: Documentation, https://github.com/xuanheng-tech/worktree-controller/blob/main/README.md
|
|
13
|
+
Project-URL: Repository, https://github.com/xuanheng-tech/worktree-controller
|
|
14
|
+
Project-URL: Issues, https://github.com/xuanheng-tech/worktree-controller/issues
|
|
15
|
+
Project-URL: Changelog, https://github.com/xuanheng-tech/worktree-controller/blob/main/CHANGELOG.md
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# Worktree Controller
|
|
19
|
+
|
|
20
|
+
Worktree Controller (WC) helps people and AI agents share a Git repository without losing track of
|
|
21
|
+
who owns each working directory, what it may change, and whether it is safe to close.
|
|
22
|
+
It checks repository policy before allocating a worktree, grants writing authority to a live
|
|
23
|
+
process, and records handoff, integration, recovery and release evidence. Git remains the source
|
|
24
|
+
of truth for files, branches, commits and registered worktrees.
|
|
25
|
+
|
|
26
|
+
**Current release: 1.30.6 · Linux · Python 3.12 · Apache-2.0**
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
Use a virtual environment in a new directory:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
python3.12 -m venv .venv
|
|
34
|
+
. .venv/bin/activate
|
|
35
|
+
python -m pip install worktree-controller==1.30.6
|
|
36
|
+
worktree-controller --version
|
|
37
|
+
worktree-controller capabilities --json
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
WC requires Git and readable Linux `/proc`. Other operating systems and Python versions are not
|
|
41
|
+
supported by this release. Its one runtime dependency is `websockets>=15,<16`.
|
|
42
|
+
On Ubuntu, if creating the environment reports that `ensurepip` is unavailable, install the
|
|
43
|
+
distribution's `python3.12-venv` package first (for example, `sudo apt install python3.12-venv`).
|
|
44
|
+
Software version 1.30.6 retains CLI contract **60** and storage layout **5**.
|
|
45
|
+
|
|
46
|
+
## Try it in a disposable repository
|
|
47
|
+
|
|
48
|
+
With the environment above active:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
git clone https://github.com/xuanheng-tech/worktree-controller.git wc
|
|
52
|
+
cd wc
|
|
53
|
+
git checkout v1.30.6
|
|
54
|
+
python examples/quickstart.py --workspace "$HOME/wc-first-run"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The workspace path must not exist; its parent must already exist. The example creates its own
|
|
58
|
+
repository and isolated HOME, uses no credentials or remote, and leaves existing projects alone.
|
|
59
|
+
It runs a small inspection task: admit a worktree, bind a live writer, check permission, observe an
|
|
60
|
+
expected wrong-owner refusal, inspect recovery guidance, and formally close the unchanged task.
|
|
61
|
+
On success it prints `PASS`, releases the linked checkout through WC, and keeps the repository,
|
|
62
|
+
branch and command log. On failure it stops and preserves results for inspection.
|
|
63
|
+
|
|
64
|
+
The [getting started guide](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/getting-started.md)
|
|
65
|
+
explains the output and how to proceed to tasks that change files. The example also ships in the
|
|
66
|
+
source distribution; it requires only WC and Git, with no companion delivery tools.
|
|
67
|
+
|
|
68
|
+
To actually change a file, publish to a local bare remote, integrate and recover a paused task,
|
|
69
|
+
follow [your first change](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/first-change.md).
|
|
70
|
+
That complete example additionally uses public Git Finalizer and Snapshot Runner installations.
|
|
71
|
+
|
|
72
|
+
## Use WC in a real project
|
|
73
|
+
|
|
74
|
+
A governed repository tracks `.agents/worktree-policy.toml` and registers its checkouts with WC.
|
|
75
|
+
Start with read-only `status` and `doctor`; adopt existing checkouts explicitly rather than
|
|
76
|
+
assuming that a clean directory is unowned. Follow the
|
|
77
|
+
[operations guide](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/operations.md)
|
|
78
|
+
for task admission, writer identity, handoff, integration and safe release.
|
|
79
|
+
|
|
80
|
+
WC manages checkout authority and lifecycle. It does not implement your task, commit changes or
|
|
81
|
+
publish a branch. Real handoff and integration flows use separate delivery evidence from
|
|
82
|
+
[Git Finalizer](https://github.com/xuanheng-tech/git-finalizer).
|
|
83
|
+
Context Loader and the maintenance checker are optional. The complete integration example uses
|
|
84
|
+
Snapshot Runner for the explicit review receipts required by its policy; see
|
|
85
|
+
[optional integrations](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/reference.md#optional-integrations-and-dependencies).
|
|
86
|
+
|
|
87
|
+
When blocked, run `worktree-controller recovery-guide --repo /path/to/repo --path /path/to/checkout --json`
|
|
88
|
+
and follow the state-specific guidance. Preserve unfinished changes and unknown files.
|
|
89
|
+
At session end, use the full recorded session identity and check every allocation's result;
|
|
90
|
+
a successful process exit alone does not prove that all worktrees are settled.
|
|
91
|
+
|
|
92
|
+
## Documentation and help
|
|
93
|
+
|
|
94
|
+
- [Getting started](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/getting-started.md)
|
|
95
|
+
- [Operations and recovery](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/operations.md)
|
|
96
|
+
- [Technical reference](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/reference.md)
|
|
97
|
+
- [Architecture](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/architecture.md)
|
|
98
|
+
- [Exact CLI and capability contract](https://github.com/xuanheng-tech/worktree-controller/blob/main/tool_cli_contract.json)
|
|
99
|
+
- [Changelog](https://github.com/xuanheng-tech/worktree-controller/blob/main/CHANGELOG.md)
|
|
100
|
+
- [Publishing and recovery](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/publishing.md)
|
|
101
|
+
- [Releases](https://github.com/xuanheng-tech/worktree-controller/releases) · [PyPI](https://pypi.org/project/worktree-controller/)
|
|
102
|
+
- [Report a bug](https://github.com/xuanheng-tech/worktree-controller/issues) · [Contribute](https://github.com/xuanheng-tech/worktree-controller/blob/main/CONTRIBUTING.md)
|
|
103
|
+
- [Report a security issue](https://github.com/xuanheng-tech/worktree-controller/blob/main/SECURITY.md)
|
|
104
|
+
|
|
105
|
+
Licensed under the [Apache License 2.0](https://github.com/xuanheng-tech/worktree-controller/blob/main/LICENSE).
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Worktree Controller
|
|
2
|
+
|
|
3
|
+
Worktree Controller (WC) helps people and AI agents share a Git repository without losing track of
|
|
4
|
+
who owns each working directory, what it may change, and whether it is safe to close.
|
|
5
|
+
It checks repository policy before allocating a worktree, grants writing authority to a live
|
|
6
|
+
process, and records handoff, integration, recovery and release evidence. Git remains the source
|
|
7
|
+
of truth for files, branches, commits and registered worktrees.
|
|
8
|
+
|
|
9
|
+
**Current release: 1.30.6 · Linux · Python 3.12 · Apache-2.0**
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
Use a virtual environment in a new directory:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
python3.12 -m venv .venv
|
|
17
|
+
. .venv/bin/activate
|
|
18
|
+
python -m pip install worktree-controller==1.30.6
|
|
19
|
+
worktree-controller --version
|
|
20
|
+
worktree-controller capabilities --json
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
WC requires Git and readable Linux `/proc`. Other operating systems and Python versions are not
|
|
24
|
+
supported by this release. Its one runtime dependency is `websockets>=15,<16`.
|
|
25
|
+
On Ubuntu, if creating the environment reports that `ensurepip` is unavailable, install the
|
|
26
|
+
distribution's `python3.12-venv` package first (for example, `sudo apt install python3.12-venv`).
|
|
27
|
+
Software version 1.30.6 retains CLI contract **60** and storage layout **5**.
|
|
28
|
+
|
|
29
|
+
## Try it in a disposable repository
|
|
30
|
+
|
|
31
|
+
With the environment above active:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
git clone https://github.com/xuanheng-tech/worktree-controller.git wc
|
|
35
|
+
cd wc
|
|
36
|
+
git checkout v1.30.6
|
|
37
|
+
python examples/quickstart.py --workspace "$HOME/wc-first-run"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The workspace path must not exist; its parent must already exist. The example creates its own
|
|
41
|
+
repository and isolated HOME, uses no credentials or remote, and leaves existing projects alone.
|
|
42
|
+
It runs a small inspection task: admit a worktree, bind a live writer, check permission, observe an
|
|
43
|
+
expected wrong-owner refusal, inspect recovery guidance, and formally close the unchanged task.
|
|
44
|
+
On success it prints `PASS`, releases the linked checkout through WC, and keeps the repository,
|
|
45
|
+
branch and command log. On failure it stops and preserves results for inspection.
|
|
46
|
+
|
|
47
|
+
The [getting started guide](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/getting-started.md)
|
|
48
|
+
explains the output and how to proceed to tasks that change files. The example also ships in the
|
|
49
|
+
source distribution; it requires only WC and Git, with no companion delivery tools.
|
|
50
|
+
|
|
51
|
+
To actually change a file, publish to a local bare remote, integrate and recover a paused task,
|
|
52
|
+
follow [your first change](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/first-change.md).
|
|
53
|
+
That complete example additionally uses public Git Finalizer and Snapshot Runner installations.
|
|
54
|
+
|
|
55
|
+
## Use WC in a real project
|
|
56
|
+
|
|
57
|
+
A governed repository tracks `.agents/worktree-policy.toml` and registers its checkouts with WC.
|
|
58
|
+
Start with read-only `status` and `doctor`; adopt existing checkouts explicitly rather than
|
|
59
|
+
assuming that a clean directory is unowned. Follow the
|
|
60
|
+
[operations guide](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/operations.md)
|
|
61
|
+
for task admission, writer identity, handoff, integration and safe release.
|
|
62
|
+
|
|
63
|
+
WC manages checkout authority and lifecycle. It does not implement your task, commit changes or
|
|
64
|
+
publish a branch. Real handoff and integration flows use separate delivery evidence from
|
|
65
|
+
[Git Finalizer](https://github.com/xuanheng-tech/git-finalizer).
|
|
66
|
+
Context Loader and the maintenance checker are optional. The complete integration example uses
|
|
67
|
+
Snapshot Runner for the explicit review receipts required by its policy; see
|
|
68
|
+
[optional integrations](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/reference.md#optional-integrations-and-dependencies).
|
|
69
|
+
|
|
70
|
+
When blocked, run `worktree-controller recovery-guide --repo /path/to/repo --path /path/to/checkout --json`
|
|
71
|
+
and follow the state-specific guidance. Preserve unfinished changes and unknown files.
|
|
72
|
+
At session end, use the full recorded session identity and check every allocation's result;
|
|
73
|
+
a successful process exit alone does not prove that all worktrees are settled.
|
|
74
|
+
|
|
75
|
+
## Documentation and help
|
|
76
|
+
|
|
77
|
+
- [Getting started](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/getting-started.md)
|
|
78
|
+
- [Operations and recovery](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/operations.md)
|
|
79
|
+
- [Technical reference](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/reference.md)
|
|
80
|
+
- [Architecture](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/architecture.md)
|
|
81
|
+
- [Exact CLI and capability contract](https://github.com/xuanheng-tech/worktree-controller/blob/main/tool_cli_contract.json)
|
|
82
|
+
- [Changelog](https://github.com/xuanheng-tech/worktree-controller/blob/main/CHANGELOG.md)
|
|
83
|
+
- [Publishing and recovery](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/publishing.md)
|
|
84
|
+
- [Releases](https://github.com/xuanheng-tech/worktree-controller/releases) · [PyPI](https://pypi.org/project/worktree-controller/)
|
|
85
|
+
- [Report a bug](https://github.com/xuanheng-tech/worktree-controller/issues) · [Contribute](https://github.com/xuanheng-tech/worktree-controller/blob/main/CONTRIBUTING.md)
|
|
86
|
+
- [Report a security issue](https://github.com/xuanheng-tech/worktree-controller/blob/main/SECURITY.md)
|
|
87
|
+
|
|
88
|
+
Licensed under the [Apache License 2.0](https://github.com/xuanheng-tech/worktree-controller/blob/main/LICENSE).
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Architecture and maintenance boundaries
|
|
2
|
+
|
|
3
|
+
The Controller adds authority and lifecycle to Git facts. It does not replace Git, the caller's
|
|
4
|
+
test/review evidence, or Git Finalizer publication. See [operations](operations.md) for the normal
|
|
5
|
+
development and recovery paths; exact public interfaces live in the [contract](../tool_cli_contract.json).
|
|
6
|
+
|
|
7
|
+
## Responsibilities
|
|
8
|
+
|
|
9
|
+
| Area | Existing implementation | Invariant |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| CLI parsing and routing | `cli.py`, command modules | Dispatch explicit operations; do not duplicate authority decisions |
|
|
12
|
+
| Git observations and mutations | `git_backend.py` | Git owns registrations, refs, paths, HEAD and cleanliness |
|
|
13
|
+
| State and durable evidence | `models.py`, `store.py`, `metadata_codec.py` | Validate stored identities; serialize mutations under the repository lock |
|
|
14
|
+
| Shared identity and semantic checks | `semantics.py` | Consume the caller's snapshot; do not acquire authority or write metadata |
|
|
15
|
+
| Budget admission | `resource_admission.py` | Preserve durable request identity and host reservations across retries |
|
|
16
|
+
| Writer entitlement | `writer_lease.py`, `writer_session.py`, `governance.py` | Bind the real process identity and exact operation/target |
|
|
17
|
+
| Lifecycle orchestration | `lifecycle.py` and focused recovery modules | Compose existing guards and append durable transition evidence |
|
|
18
|
+
| Environment and resource inspection | `environment.py`, `disposable.py`, preservation modules | Incomplete observation blocks dependent deletion; unknown content is retained |
|
|
19
|
+
| Publication execution | `publication_execution.py` and Finalizer protocol | Exact candidate, validation, lease and current remote main must agree |
|
|
20
|
+
| Idle-work maintenance | `convergence.py`, `reconciler.py` | Only delegated authority closes eligible unused allocations |
|
|
21
|
+
|
|
22
|
+
This is a responsibility map, not a claim of an acyclic module graph. Lifecycle orchestration
|
|
23
|
+
still imports and is imported by focused modules, including deferred imports. New code should use
|
|
24
|
+
the narrow existing owner of a guard instead of importing lifecycle merely to look up a record.
|
|
25
|
+
|
|
26
|
+
`semantics.record_for`, `managed_record` and `assert_record_version` are internal shared helpers.
|
|
27
|
+
They preserve binding lookup, Git registration checks and allocation/version CAS errors. They do
|
|
28
|
+
not refresh a snapshot or establish a transaction. A mutation caller must retain its existing
|
|
29
|
+
repository lock and apply the relevant role, owner, lifecycle, resource and runtime checks.
|
|
30
|
+
Compatibility aliases in lifecycle/controller keep existing internal call sites usable; new
|
|
31
|
+
consumers should import the shared helpers directly.
|
|
32
|
+
|
|
33
|
+
## Durable state and recovery
|
|
34
|
+
|
|
35
|
+
Resolve the repository's actual Git common directory; a linked checkout's `.git` can be a file.
|
|
36
|
+
Controller Git commands drop inherited repository selection (`GIT_DIR`, `GIT_INDEX_FILE` and the
|
|
37
|
+
other variables in `git_backend.REPOSITORY_SELECTION_ENVIRONMENT`). A worktree key is derived
|
|
38
|
+
from the Git administrative directory name, which Git reuses after a removal; a linked binding
|
|
39
|
+
therefore also carries a `worktree-registration/v1` token that must match the marker inside that
|
|
40
|
+
administrative directory. `MetadataStore` withdraws a mismatched binding for every consumer and
|
|
41
|
+
reports `BINDING_IDENTITY_DRIFT`; new binding writers pass the registration to `write_record`.
|
|
42
|
+
Bindings that predate registrations gain one only through `registration_backfill`, which ties
|
|
43
|
+
them to the live registration on matching Git and record evidence and writes nothing else.
|
|
44
|
+
Every directory under the metadata root is a `MetadataStore` attribute declared in the layout
|
|
45
|
+
contract; a listing failure other than absence fails closed.
|
|
46
|
+
The `worktree-controller/v1` namespace suffix is not its storage layout version. Repository
|
|
47
|
+
metadata and host admission reservations have separate locks and identities. Never infer an
|
|
48
|
+
allocation, completed cleanup, publication or release from a missing path or a clean Git status.
|
|
49
|
+
|
|
50
|
+
Before changing a transition, follow its ordinary path and its interrupted path: persisted request,
|
|
51
|
+
allocation, frozen handoff, integration preparation, validation, publication and release receipts.
|
|
52
|
+
Use typed recovery entries for partial operations. Preserve the original request and evidence;
|
|
53
|
+
an error explanation must not silently substitute a new intent or relax the original guard.
|
|
54
|
+
|
|
55
|
+
## Validation and future changes
|
|
56
|
+
|
|
57
|
+
Start with regressions for the observed failure and its unchanged refusal boundary. For shared
|
|
58
|
+
authority checks, cover both successful callers and the error taxonomy. Use `check-shards` for
|
|
59
|
+
the parallel integration gate and `check-project` for the complete package/release gate. Build
|
|
60
|
+
and installed smoke results are distinct from a live external client's behavior.
|
|
61
|
+
|
|
62
|
+
History growth should be measured with `scripts/benchmark-cli` before changing storage. Compare
|
|
63
|
+
pinned executables on the same synthetic fixtures, alternating repeated calls, and retain the
|
|
64
|
+
history sizes, timing, peak RSS and cache limitations. A faster lookup must not skip fresh evidence
|
|
65
|
+
validation or introduce a second authoritative state store. Indexing or additional caching needs
|
|
66
|
+
a demonstrated bottleneck and explicit invalidation/recovery tests.
|
|
67
|
+
|
|
68
|
+
Runtime scans that gate deletion read every same-UID process. Positive references and read
|
|
69
|
+
failures other than permission denial block; a permission-denied same-UID process without a
|
|
70
|
+
verified holder association is a host visibility gap (for example a non-dumpable service
|
|
71
|
+
manager), reported by typed cleanup and tolerated by release. Both scans require the checkout to
|
|
72
|
+
keep one path and inode for the whole scan. The strict scan, which also refuses visibility gaps,
|
|
73
|
+
is for consumers that must prove complete visibility.
|
|
74
|
+
|
|
75
|
+
Further lifecycle extraction should follow one cohesive transition at a time, keeping its lock
|
|
76
|
+
scope and immutable evidence together. Avoid moving mutation helpers that depend on lifecycle's
|
|
77
|
+
clock, transaction state or caller-specific guards merely to reduce a line count. Public CLI,
|
|
78
|
+
capability and storage changes require their own version and compatibility review.
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Deliver your first change
|
|
2
|
+
|
|
3
|
+
This example changes one README, commits and publishes its branch through Git Finalizer, hands
|
|
4
|
+
it off to WC, reviews and validates an integration candidate, and publishes local main. It can
|
|
5
|
+
pause after handoff and continue in a new process with the original task and integration request.
|
|
6
|
+
It creates a **local bare Git remote**, never contacts a hosting service, and needs no credentials.
|
|
7
|
+
Use a disposable workspace; do not point it at an existing project.
|
|
8
|
+
|
|
9
|
+
## Install the example's tools
|
|
10
|
+
|
|
11
|
+
WC itself needs Linux, Python 3.12, Git and readable `/proc`. Install the released version using
|
|
12
|
+
the [README](../README.md#install). On Ubuntu, a Python installation without `ensurepip` also
|
|
13
|
+
needs its distribution's `python3.12-venv` package before `python3.12 -m venv` can work.
|
|
14
|
+
|
|
15
|
+
This complete delivery example also uses these public tools:
|
|
16
|
+
|
|
17
|
+
- [Git Finalizer 1.9.3](https://github.com/xuanheng-tech/git-finalizer#installation): download its
|
|
18
|
+
published release tarball and checksum file, verify them, and keep all `git-finalize*` companions
|
|
19
|
+
together as its installation instructions describe. It is not a PyPI package.
|
|
20
|
+
- [Snapshot Runner 2.5.11](https://github.com/xuanheng-tech/snapshot-runner#requirements-and-installation):
|
|
21
|
+
install its PyPI package in a separate virtual environment. Its own interpreter needs
|
|
22
|
+
Python 3.12.13 or a later supported version; using Python 3.12.13+ for both environments meets
|
|
23
|
+
WC's Python 3.12 requirement too. WC's core Python requirement is unchanged.
|
|
24
|
+
|
|
25
|
+
For example, with a suitable Python 3.12 already installed and a new `runner-venv` path:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
python3.12 --version
|
|
29
|
+
python3.12 -m venv /absolute/path/to/runner-venv
|
|
30
|
+
/absolute/path/to/runner-venv/bin/python -m pip install 'snapshot-runner==2.5.11'
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Use the WC environment's Python to run the example. Pass the two installed entrypoints
|
|
34
|
+
explicitly, or put their directories on PATH. `tool-skill-sync`, Context Loader, agent clients,
|
|
35
|
+
model APIs and personal Skills are not required by this example.
|
|
36
|
+
|
|
37
|
+
WC policy schema 4 and newer requires separate explicit **test and Snapshot receipt identities**
|
|
38
|
+
at `integration-validate`. The example creates real Snapshot Runner artifacts and reads their
|
|
39
|
+
README evidence; it checks the expected README content and clean candidate separately. A tool's
|
|
40
|
+
successful evidence collection alone is not a passed test or code review. No fake receipt, lowered
|
|
41
|
+
policy version or changed Controller state is used.
|
|
42
|
+
|
|
43
|
+
## Run the whole task
|
|
44
|
+
|
|
45
|
+
From this release's source checkout, with the WC environment active:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
python examples/change_task.py --workspace "$HOME/wc-first-change" \
|
|
49
|
+
--finalizer /absolute/path/to/git-finalize \
|
|
50
|
+
--snapshot-runner /absolute/path/to/runner-venv/bin/snapshot-runner
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The workspace path must be new and its parent must exist. The script refuses an existing path
|
|
54
|
+
without changing it. The source archive includes both `change_task.py` and its neighboring
|
|
55
|
+
`quickstart.py`; keep them together. Missing tools are refused before the workspace is created.
|
|
56
|
+
|
|
57
|
+
`PASS` means all of the following were checked:
|
|
58
|
+
|
|
59
|
+
1. The admitted feature's real writer passed the write guard before changing `README.md`.
|
|
60
|
+
2. The exact file scope was reviewed, committed and published to the local remote with Finalizer.
|
|
61
|
+
3. The writer ended and its exact commit was handed off, then queued and claimed through WC.
|
|
62
|
+
4. Tests and Snapshot evidence were bound to the candidate before its main-publication lease.
|
|
63
|
+
5. Finalizer and WC independently verified the published commit; WC released both linked checkouts.
|
|
64
|
+
6. Canonical main was refreshed, the delivered README was checked, strict closeout proof covered
|
|
65
|
+
both known allocations, and `doctor` passed.
|
|
66
|
+
|
|
67
|
+
The example intentionally changes only a known text file, so its content review is narrow and
|
|
68
|
+
deterministic. Real application changes need their own tests and appropriate review.
|
|
69
|
+
This local demonstration does not authorize a hosted publication or production deployment.
|
|
70
|
+
|
|
71
|
+
## Pause and resume the same task
|
|
72
|
+
|
|
73
|
+
Use a different new workspace for this exercise:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
python examples/change_task.py --workspace "$HOME/wc-change-resume" \
|
|
77
|
+
--finalizer /absolute/path/to/git-finalize \
|
|
78
|
+
--snapshot-runner /absolute/path/to/runner-venv/bin/snapshot-runner \
|
|
79
|
+
--pause-after-handoff
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The output is **`PAUSED`**, not `PASS`. The change and its branch have reached the local remote,
|
|
83
|
+
the feature writer is released, and `handoff.json` records the original task's source, repository
|
|
84
|
+
and integration identities. The integration is queued, with no candidate checkout yet.
|
|
85
|
+
The preserved source is still awaiting integration; this is not completed business work.
|
|
86
|
+
|
|
87
|
+
Run in a new process with the **same** workspace and installed tools:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
python examples/change_task.py --workspace "$HOME/wc-change-resume" \
|
|
91
|
+
--finalizer /absolute/path/to/git-finalize \
|
|
92
|
+
--snapshot-runner /absolute/path/to/runner-venv/bin/snapshot-runner --resume
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Resume checks the existing repository, local remote, source identity and uncommitted files. It
|
|
96
|
+
claims the original queued intent, or observes the same unchanged claimed candidate. It does not
|
|
97
|
+
create another task, replace source evidence, reset a branch or delete unknown files. Repeating
|
|
98
|
+
resume after verified completion only rechecks the delivered result and closeout evidence.
|
|
99
|
+
|
|
100
|
+
## Inspect a failure and keep the evidence
|
|
101
|
+
|
|
102
|
+
Every command's actual exit code, stdout and stderr is saved in `commands.jsonl`. The workspace
|
|
103
|
+
also retains Finalizer receipts, Snapshot summaries and artifacts, content-check results, branches,
|
|
104
|
+
the local remote and final `closeout.json`. Linked checkouts are removed only through WC.
|
|
105
|
+
|
|
106
|
+
An unexpected refusal stops with nonzero exit status and preserves the current result. This
|
|
107
|
+
example's resume entry covers queued or unchanged claimed handoffs and verified completion;
|
|
108
|
+
it is not a general crash-recovery engine. For a different interruption point, unknown files,
|
|
109
|
+
identity drift or a publication in progress, inspect the saved command and the formal
|
|
110
|
+
[recovery guidance](operations.md#recovery-guidance-and-session-closeout). Do not rerun without
|
|
111
|
+
`--resume` into an old workspace or clear metadata to make the example continue.
|
|
112
|
+
|
|
113
|
+
The isolated state is under the workspace's `home/`. For inspection, activate the WC environment
|
|
114
|
+
and use the actual workspace path:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
workspace="$HOME/wc-change-resume"
|
|
118
|
+
HOME="$workspace/home" XDG_STATE_HOME="$workspace/home/.local/state" \
|
|
119
|
+
worktree-controller status --repo "$workspace/main" --json
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Use the original `intent_id` from `handoff.json` with `recovery-guide --intent-id` even after a
|
|
123
|
+
checkout is released. Follow each returned owner/CAS step and reobserve. `doctor PASS` and an
|
|
124
|
+
observation command's exit 0 do not prove recovery, integration or task completion.
|
|
125
|
+
|
|
126
|
+
## Repeat the regression as a contributor
|
|
127
|
+
|
|
128
|
+
The default test suite checks refusal of existing workspaces and missing prerequisites. The real
|
|
129
|
+
cross-tool regression is explicit opt-in, runs entirely against temporary local repositories,
|
|
130
|
+
and covers unknown-file preservation, source drift, pause/resume and completed replay:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
WC_DEMO_FINALIZER=/absolute/path/to/git-finalize \
|
|
134
|
+
WC_DEMO_SNAPSHOT_RUNNER=/absolute/path/to/runner-venv/bin/snapshot-runner \
|
|
135
|
+
uv run --locked --python 3.12 --no-env-file python -m pytest -q tests/test_change_task.py \
|
|
136
|
+
-p no:cacheprovider --basetemp /absolute/path/to/a/new/demo-pytest
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Install the contributor environment as described in [CONTRIBUTING](../CONTRIBUTING.md). Without
|
|
140
|
+
both opt-in entrypoints, the cross-tool case is skipped; a skipped case is not acceptance evidence.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Getting started
|
|
2
|
+
|
|
3
|
+
Use Linux, Python 3.12, Git and readable `/proc`. Install WC in a virtual environment using the
|
|
4
|
+
[README instructions](../README.md#install). The example needs no credentials, running service,
|
|
5
|
+
companion tool or connection to a remote repository.
|
|
6
|
+
|
|
7
|
+
## Run the example
|
|
8
|
+
|
|
9
|
+
From the release's source checkout, with that environment active:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
python examples/quickstart.py --workspace "$HOME/wc-first-run"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The parent directory must exist and the workspace path must be new, including on a second run.
|
|
16
|
+
The script refuses an existing directory even when it is empty. A PyPI source archive includes
|
|
17
|
+
the same `examples/quickstart.py` if you prefer downloading that over cloning the repository.
|
|
18
|
+
|
|
19
|
+
The script creates `main/` as a new repository and `inspection/` as its governed linked checkout.
|
|
20
|
+
An isolated `home/` keeps demo metadata separate from your normal WC state. `commands.jsonl`
|
|
21
|
+
records every Git and WC command, actual exit code and JSON response. No real project is changed.
|
|
22
|
+
|
|
23
|
+
## What to expect
|
|
24
|
+
|
|
25
|
+
| Step | Meaning |
|
|
26
|
+
| --- | --- |
|
|
27
|
+
| `adopt`, `plan`, `acquire` | Register the demo's canonical checkout, check admission, allocate an inspection task. |
|
|
28
|
+
| `writer-lease-acquire`, `WRITE_ALLOWED` | Bind the real demo process and check its exact task, owner and session. |
|
|
29
|
+
| `BLOCK_OWNER_MISMATCH` | An intentional negative control: another owner is refused with exit code **1**. No forbidden write runs. |
|
|
30
|
+
| `recovery-guide` | Read the current state and available formal next steps. This permission refusal does not itself change the allocation to `BLOCKED`. |
|
|
31
|
+
| Inspection | Read the README; this task produces no source edit or new task commit. |
|
|
32
|
+
| `complete-no-change`, `release --dry-run`, `release` | End the unchanged task and release its checkout through the Controller. |
|
|
33
|
+
| Strict closeout check, `doctor`, `PASS` | Require completion proof for that exact allocation and verify metadata integrity. |
|
|
34
|
+
|
|
35
|
+
The final `PASS` means the expected refusal was observed and the example's closeout checks passed.
|
|
36
|
+
It does not mean a main-branch integration or release occurred. The repository, inspection branch,
|
|
37
|
+
isolated HOME and log remain in the workspace; the linked `inspection/` directory is released.
|
|
38
|
+
The script never deletes the workspace or a branch.
|
|
39
|
+
|
|
40
|
+
## If it stops
|
|
41
|
+
|
|
42
|
+
Read the last output and `commands.jsonl`. Unexpected exits stop the script; admission refusals
|
|
43
|
+
are not retried under another identity. Resource requirements still apply on a small machine.
|
|
44
|
+
An interrupted run can leave an allocation or writer lease, so do not delete a checkout by hand
|
|
45
|
+
or rerun into its existing path.
|
|
46
|
+
|
|
47
|
+
To inspect the same isolated state, replace the workspace below with the actual absolute path:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
workspace="$HOME/wc-first-run"
|
|
51
|
+
HOME="$workspace/home" XDG_STATE_HOME="$workspace/home/.local/state" \
|
|
52
|
+
worktree-controller status --repo "$workspace/main" --json
|
|
53
|
+
HOME="$workspace/home" XDG_STATE_HOME="$workspace/home/.local/state" \
|
|
54
|
+
worktree-controller recovery-guide --repo "$workspace/main" --path "$workspace/inspection" --json
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Use the recorded owner, allocation, process/session identity and current record version when
|
|
58
|
+
following the returned formal recovery guidance. Never edit Controller metadata or weaken a guard.
|
|
59
|
+
An already released checkout is inspected with `lifecycle-history`; directory absence alone does
|
|
60
|
+
not establish completion.
|
|
61
|
+
|
|
62
|
+
## Move on to work that changes files
|
|
63
|
+
|
|
64
|
+
The example deliberately performs a genuine no-change inspection, so `complete-no-change` is
|
|
65
|
+
appropriate. A task that edits files or creates commits must preserve or deliver that work;
|
|
66
|
+
it cannot use this shortcut. Follow [your first change](first-change.md) for an executable local
|
|
67
|
+
commit, handoff, integration and pause/resume example with public companion tools. See the
|
|
68
|
+
[operations guide](operations.md) for the existing contracts. WC itself does not commit, push
|
|
69
|
+
or approve a production release.
|
|
70
|
+
|
|
71
|
+
For real session closeout, pass the complete recorded selector (`--client-id`, `--session-id`,
|
|
72
|
+
`--run-id` when present, and `--holder`) and every known `--expected-allocation-id` to
|
|
73
|
+
`worktree-session-end --check`. After resolving its blockers, use `--require-complete` and require
|
|
74
|
+
`summary.terminal_complete=true` together with each allocation's decision. The example uses a
|
|
75
|
+
read-only strict check after its explicit completion and release.
|