worktree-controller 1.30.4__tar.gz → 1.30.5__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.
Files changed (68) hide show
  1. worktree_controller-1.30.5/PKG-INFO +97 -0
  2. worktree_controller-1.30.5/README.md +80 -0
  3. worktree_controller-1.30.5/docs/architecture.md +78 -0
  4. worktree_controller-1.30.5/docs/getting-started.md +74 -0
  5. worktree_controller-1.30.5/docs/operations.md +261 -0
  6. worktree_controller-1.30.4/README.md → worktree_controller-1.30.5/docs/reference.md +8 -140
  7. worktree_controller-1.30.5/examples/quickstart.py +174 -0
  8. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/pyproject.toml +13 -2
  9. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/pyproject.toml.orig +9 -2
  10. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/__init__.py +1 -1
  11. {worktree_controller-1.30.4 → worktree_controller-1.30.5/src/worktree_controller}/tool_cli_contract.json +1 -1
  12. {worktree_controller-1.30.4/src/worktree_controller → worktree_controller-1.30.5}/tool_cli_contract.json +1 -1
  13. worktree_controller-1.30.4/PKG-INFO +0 -3149
  14. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/LICENSE +0 -0
  15. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/activation_layout.py +0 -0
  16. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/branch_retirement.py +0 -0
  17. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/canonical_refresh.py +0 -0
  18. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/canonical_transition.py +0 -0
  19. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/cleanup_attempts.py +0 -0
  20. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/cleanup_evidence.py +0 -0
  21. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/cleanup_recovery.py +0 -0
  22. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/cli.py +0 -0
  23. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/controller.py +0 -0
  24. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/convergence.py +0 -0
  25. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/delivered_closeout.py +0 -0
  26. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/disposable.py +0 -0
  27. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/environment.py +0 -0
  28. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/frozen_recovery.py +0 -0
  29. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/git_backend.py +0 -0
  30. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/governance.py +0 -0
  31. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/hardlinks.py +0 -0
  32. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/integration_cleanup.py +0 -0
  33. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/integration_conflict.py +0 -0
  34. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/integration_retry.py +0 -0
  35. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/keyed_document_scope.py +0 -0
  36. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/lifecycle.py +0 -0
  37. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/lifecycle_history.py +0 -0
  38. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/lifecycle_observation.py +0 -0
  39. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/metadata_codec.py +0 -0
  40. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/metadata_relocation.py +0 -0
  41. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/models.py +0 -0
  42. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/mount_diagnostics.py +0 -0
  43. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/multiple_cleanup_recovery.py +0 -0
  44. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/namespace_migration.py +0 -0
  45. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/native_session_recovery.py +0 -0
  46. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/owner_actions.py +0 -0
  47. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/policy.py +0 -0
  48. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/preservation.py +0 -0
  49. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/preserved_cleanup.py +0 -0
  50. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/publication_execution.py +0 -0
  51. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/reconciler.py +0 -0
  52. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/recovery_guidance.py +0 -0
  53. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/registration_backfill.py +0 -0
  54. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/registration_prune.py +0 -0
  55. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/rendering.py +0 -0
  56. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/resource_admission.py +0 -0
  57. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/retirement_adapters.py +0 -0
  58. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/retirement_execution.py +0 -0
  59. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/semantics.py +0 -0
  60. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/session.py +0 -0
  61. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/session_admission.py +0 -0
  62. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/source_cleanup.py +0 -0
  63. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/source_preservation.py +0 -0
  64. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/source_recovery.py +0 -0
  65. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/store.py +0 -0
  66. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/transaction_scope.py +0 -0
  67. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/writer_lease.py +0 -0
  68. {worktree_controller-1.30.4 → worktree_controller-1.30.5}/src/worktree_controller/writer_session.py +0 -0
@@ -0,0 +1,97 @@
1
+ Metadata-Version: 2.4
2
+ Name: worktree-controller
3
+ Version: 1.30.5
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.5 · 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.5
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
+ Software version 1.30.5 retains CLI contract **60** and storage layout **5**.
43
+
44
+ ## Try it in a disposable repository
45
+
46
+ With the environment above active:
47
+
48
+ ```bash
49
+ git clone https://github.com/xuanheng-tech/worktree-controller.git wc
50
+ cd wc
51
+ git checkout v1.30.5
52
+ python examples/quickstart.py --workspace "$HOME/wc-first-run"
53
+ ```
54
+
55
+ The workspace path must not exist; its parent must already exist. The example creates its own
56
+ repository and isolated HOME, uses no credentials or remote, and leaves existing projects alone.
57
+ It runs a small inspection task: admit a worktree, bind a live writer, check permission, observe an
58
+ expected wrong-owner refusal, inspect recovery guidance, and formally close the unchanged task.
59
+ On success it prints `PASS`, releases the linked checkout through WC, and keeps the repository,
60
+ branch and command log. On failure it stops and preserves results for inspection.
61
+
62
+ The [getting started guide](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/getting-started.md)
63
+ explains the output and how to proceed to tasks that change files. The example also ships in the
64
+ source distribution; it requires only WC and Git, with no companion delivery tools.
65
+
66
+ ## Use WC in a real project
67
+
68
+ A governed repository tracks `.agents/worktree-policy.toml` and registers its checkouts with WC.
69
+ Start with read-only `status` and `doctor`; adopt existing checkouts explicitly rather than
70
+ assuming that a clean directory is unowned. Follow the
71
+ [operations guide](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/operations.md)
72
+ for task admission, writer identity, handoff, integration and safe release.
73
+
74
+ WC manages checkout authority and lifecycle. It does not implement your task, commit changes or
75
+ publish a branch. Real handoff and integration flows use separate delivery evidence from
76
+ [Git Finalizer](https://github.com/xuanheng-tech/git-finalizer).
77
+ Context Loader and Snapshot Runner are optional companion tools; see
78
+ [optional integrations](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/reference.md#optional-integrations-and-dependencies).
79
+
80
+ When blocked, run `worktree-controller recovery-guide --repo /path/to/repo --path /path/to/checkout --json`
81
+ and follow the state-specific guidance. Preserve unfinished changes and unknown files.
82
+ At session end, use the full recorded session identity and check every allocation's result;
83
+ a successful process exit alone does not prove that all worktrees are settled.
84
+
85
+ ## Documentation and help
86
+
87
+ - [Getting started](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/getting-started.md)
88
+ - [Operations and recovery](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/operations.md)
89
+ - [Technical reference](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/reference.md)
90
+ - [Architecture](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/architecture.md)
91
+ - [Exact CLI and capability contract](https://github.com/xuanheng-tech/worktree-controller/blob/main/tool_cli_contract.json)
92
+ - [Changelog](https://github.com/xuanheng-tech/worktree-controller/blob/main/CHANGELOG.md)
93
+ - [Releases](https://github.com/xuanheng-tech/worktree-controller/releases) · [PyPI](https://pypi.org/project/worktree-controller/)
94
+ - [Report a bug](https://github.com/xuanheng-tech/worktree-controller/issues) · [Contribute](https://github.com/xuanheng-tech/worktree-controller/blob/main/CONTRIBUTING.md)
95
+ - [Report a security issue](https://github.com/xuanheng-tech/worktree-controller/blob/main/SECURITY.md)
96
+
97
+ Licensed under the [Apache License 2.0](https://github.com/xuanheng-tech/worktree-controller/blob/main/LICENSE).
@@ -0,0 +1,80 @@
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.5 · 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.5
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
+ Software version 1.30.5 retains CLI contract **60** and storage layout **5**.
26
+
27
+ ## Try it in a disposable repository
28
+
29
+ With the environment above active:
30
+
31
+ ```bash
32
+ git clone https://github.com/xuanheng-tech/worktree-controller.git wc
33
+ cd wc
34
+ git checkout v1.30.5
35
+ python examples/quickstart.py --workspace "$HOME/wc-first-run"
36
+ ```
37
+
38
+ The workspace path must not exist; its parent must already exist. The example creates its own
39
+ repository and isolated HOME, uses no credentials or remote, and leaves existing projects alone.
40
+ It runs a small inspection task: admit a worktree, bind a live writer, check permission, observe an
41
+ expected wrong-owner refusal, inspect recovery guidance, and formally close the unchanged task.
42
+ On success it prints `PASS`, releases the linked checkout through WC, and keeps the repository,
43
+ branch and command log. On failure it stops and preserves results for inspection.
44
+
45
+ The [getting started guide](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/getting-started.md)
46
+ explains the output and how to proceed to tasks that change files. The example also ships in the
47
+ source distribution; it requires only WC and Git, with no companion delivery tools.
48
+
49
+ ## Use WC in a real project
50
+
51
+ A governed repository tracks `.agents/worktree-policy.toml` and registers its checkouts with WC.
52
+ Start with read-only `status` and `doctor`; adopt existing checkouts explicitly rather than
53
+ assuming that a clean directory is unowned. Follow the
54
+ [operations guide](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/operations.md)
55
+ for task admission, writer identity, handoff, integration and safe release.
56
+
57
+ WC manages checkout authority and lifecycle. It does not implement your task, commit changes or
58
+ publish a branch. Real handoff and integration flows use separate delivery evidence from
59
+ [Git Finalizer](https://github.com/xuanheng-tech/git-finalizer).
60
+ Context Loader and Snapshot Runner are optional companion tools; see
61
+ [optional integrations](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/reference.md#optional-integrations-and-dependencies).
62
+
63
+ When blocked, run `worktree-controller recovery-guide --repo /path/to/repo --path /path/to/checkout --json`
64
+ and follow the state-specific guidance. Preserve unfinished changes and unknown files.
65
+ At session end, use the full recorded session identity and check every allocation's result;
66
+ a successful process exit alone does not prove that all worktrees are settled.
67
+
68
+ ## Documentation and help
69
+
70
+ - [Getting started](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/getting-started.md)
71
+ - [Operations and recovery](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/operations.md)
72
+ - [Technical reference](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/reference.md)
73
+ - [Architecture](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/architecture.md)
74
+ - [Exact CLI and capability contract](https://github.com/xuanheng-tech/worktree-controller/blob/main/tool_cli_contract.json)
75
+ - [Changelog](https://github.com/xuanheng-tech/worktree-controller/blob/main/CHANGELOG.md)
76
+ - [Releases](https://github.com/xuanheng-tech/worktree-controller/releases) · [PyPI](https://pypi.org/project/worktree-controller/)
77
+ - [Report a bug](https://github.com/xuanheng-tech/worktree-controller/issues) · [Contribute](https://github.com/xuanheng-tech/worktree-controller/blob/main/CONTRIBUTING.md)
78
+ - [Report a security issue](https://github.com/xuanheng-tech/worktree-controller/blob/main/SECURITY.md)
79
+
80
+ 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,74 @@
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. See the [operations guide](operations.md) for the existing
67
+ handoff, integration and recovery contracts and [Git Finalizer](https://github.com/xuanheng-tech/git-finalizer)
68
+ for delivery evidence. WC itself does not commit, push or approve a production release.
69
+
70
+ For real session closeout, pass the complete recorded selector (`--client-id`, `--session-id`,
71
+ `--run-id` when present, and `--holder`) and every known `--expected-allocation-id` to
72
+ `worktree-session-end --check`. After resolving its blockers, use `--require-complete` and require
73
+ `summary.terminal_complete=true` together with each allocation's decision. The example uses a
74
+ read-only strict check after its explicit completion and release.
@@ -0,0 +1,261 @@
1
+ # Operations
2
+
3
+ Use this page to select a flow. The [CLI contract](../tool_cli_contract.json) owns exact command,
4
+ capability and result schemas; installed `--help` owns the arguments available on this host.
5
+ The [technical reference](reference.md) retains detailed protocols and compatibility history;
6
+ the [getting started guide](getting-started.md) provides an isolated first run.
7
+
8
+ ## Start or resume development
9
+
10
+ 1. Run `tool-skill-sync doctor --repo <checkout> --summary`, then Controller `status --json`.
11
+ Read the selected repository policy and distinguish installed runtime from source candidates.
12
+ 2. Use `plan` for the existing task/authority. Reuse its allocation when supported; otherwise use
13
+ `acquire` with explicit owner, branch, base and scope. A waiting request is not an allocation.
14
+ 3. Bind the real writer process and session/run through `writer-session` or `writer-lease-acquire`.
15
+ Require `write-guard` to allow the exact operation before editing.
16
+ 4. Register rebuildable environments while ACTIVE. Run focused tests, the required project gate,
17
+ and Snapshot review before Git Finalizer commits or publishes the task branch.
18
+
19
+ ## Handoff and integrate
20
+
21
+ Publish the source branch, hand off its exact commit and scope, then enqueue one integration intent.
22
+ Claim that intent, validate its candidate with current test/Snapshot evidence, acquire a publication
23
+ lease, and use Git Finalizer to publish the exact candidate. Return the verified record to
24
+ `lease-complete`; inspect candidate and source release outcomes separately.
25
+
26
+ Advance an idle ACTIVE canonical with `canonical-refresh`. A canonical frozen in HANDOFF_READY,
27
+ including one already on main/master, uses `canonical-transition` with exact owner, record CAS,
28
+ frozen HEAD, observed local main and published remote main identities.
29
+
30
+ A frozen source cannot accept feature writes. Same-session continuation requires a compatible
31
+ consumer to send `--access read|exec|write` and the actual write target. Continuing feature work on
32
+ the source uses the supported reopen flow; handing off does not end the whole business task.
33
+ `reopen` can retain runtime bindings only when the current live, unexpired writer lease proves
34
+ their allocation, owner and session/run identity. Client names are not owner credentials.
35
+ Missing or stale lease evidence and unknown bindings remain blocked; reopening grants no new writer.
36
+
37
+ ## Resource wait and main advancing
38
+
39
+ `RESOURCE_WAIT` preserves the original durable request. Inspect its state with:
40
+
41
+ ```text
42
+ worktree-controller admission-queue --repo <canonical-repo> --json
43
+ ```
44
+
45
+ Resolve only the reported resource blocker through existing owner/retention/reconciliation flows.
46
+ Do not lower reserves, replace the authority, abandon the intent, or use a different filesystem to
47
+ evade the refused request. The selected admission strategy determines whether checkout counts are
48
+ limits or observations.
49
+
50
+ Once resources are available, replay the original frozen request with:
51
+
52
+ ```text
53
+ worktree-controller admission-queue --repo <canonical-repo> --apply --json
54
+ ```
55
+
56
+ This command can resume other eligible requests in that repository too. Read each outcome and
57
+ query status again to distinguish an allocation just acquired by the pass from its prior WAITING
58
+ row. Keep the original intent, source, scope and queue position.
59
+
60
+ If main advanced while an integration request waited without an allocation, a fresh
61
+ `integration-claim` may construct a different base and report `ADMISSION_REQUEST_DRIFT`. The guard
62
+ is intentional: it must not silently replace the existing request. Use the original-request replay
63
+ above, inspect the resulting candidate and continue its normal preparation. When its base is stale,
64
+ use the supported `integration-refresh` transition, repeat required candidate validation, and let
65
+ publication's main CAS check the refreshed base. Some states require preparation before refresh;
66
+ an `INVALID_LIFECYCLE` response is not permission to edit metadata or force a transition.
67
+
68
+ Other causes of request drift can be changed owner, target, branch or arguments. Compare the task's
69
+ original invocation and current observations; do not automatically apply the main-advance recipe
70
+ to an unrelated identity change. An unchanged clean PREPARING candidate can be observed again with
71
+ its exact original claim without allocating another checkout.
72
+
73
+ ## Recovery guidance and session closeout
74
+
75
+ When `capabilities --json` advertises `recovery_guidance_version` 1, inspect one checkout:
76
+
77
+ ```text
78
+ worktree-controller recovery-guide --repo <canonical-repo> --path <checkout> --json
79
+ ```
80
+
81
+ The result explains the observed state, blockers and the next formal step. Match its exact
82
+ allocation, owner, task, authority, branch, HEAD and record version to the existing Task. Execute
83
+ an authorized `next_steps[].argv` as an argument list, then inspect again. The guide never executes
84
+ recovery or verifies all execution guards, and never predicts a future record version. Its exit 0
85
+ means the observation succeeded; it does not mean recovery or Task completion succeeded.
86
+
87
+ For a clean, unchanged `BLOCKED` integration, direct `integration-abort` is intentionally refused
88
+ with `INVALID_LIFECYCLE` (exit 2). First use the guide's exact `quarantine` request; expected HEAD may
89
+ equal observed HEAD. Reinspect `QUARANTINED` and record formal abort, then inspect guarded release.
90
+ Unknown ignored output requires preservation and typed cleanup through the flow below. Extra
91
+ commits, changed source/scope, live leases, bindings and unfinished transactions require their
92
+ existing owner/recovery path. Do not manufacture pollution or change the frozen request.
93
+
94
+ After complete release, select the **original** integration intent:
95
+
96
+ ```text
97
+ worktree-controller recovery-guide --repo <canonical-repo> --intent-id <original-intent> --json
98
+ ```
99
+
100
+ Run the returned `integration-retry --dry-run`; only its verified public `decision.plan_id` may
101
+ be used as `--expected-plan-id` with the identical request. Reclaim the same intent through normal
102
+ admission, explicitly resolve its returned frozen source when necessary, and repeat candidate
103
+ tests and validation. Main advancing does not authorize scope changes. `doctor PASS` establishes
104
+ metadata integrity; it does not establish lifecycle, integration or production eligibility.
105
+
106
+ For an already published and released intent, 1.30.2 verifies complete matching immutable
107
+ publication and release evidence, then reports `terminal_status=PUBLISHED_RELEASED`. The only
108
+ next step is `lifecycle-history` inspection; do not retry an integration that already finished.
109
+ Missing proof or owner/task/authority/candidate drift remains blocked. This terminal explanation
110
+ does not assert business Task completion or authorize any mutation.
111
+
112
+ Before normal exit, use the real client/session/holder/run and check **all** of its checkouts:
113
+
114
+ ```text
115
+ worktree-session-end --path <canonical-repo> --client-id <client> --session-id <session> \
116
+ --holder <real-pid-or-ancestor-selector> --run-id <recorded-run> --check \
117
+ --expected-allocation-id <first-known-allocation> --expected-allocation-id <second-known-allocation>
118
+ ```
119
+
120
+ Omit `--run-id` only when the recorded run is null. With `session_closeout_expectations_version` 1,
121
+ repeat `--expected-allocation-id` for the allocations the existing Task/session knows it acquired.
122
+ These IDs add proof obligations; they never select extra mutation targets or narrow the real
123
+ selector. A missing live checkout/lease remains pending; a removed checkout counts only with
124
+ complete matching immutable release evidence. Expected IDs are opt-in for older clients.
125
+
126
+ Read every row in `allocations`, `previous_allocations` and `expected_allocations`, and require
127
+ `summary.terminal_complete=true`. Pending live rows include `recovery_argv`; missing observations
128
+ include a lifecycle-history query. A frozen handoff must still match its Finalizer commit and
129
+ record; a retained checkpoint must match HEAD and have no replacement writer or external binding.
130
+ Deliver accepted files through Finalizer/handoff, or durably save the existing Task checkpoint,
131
+ classify artifacts and park. Unknown files stay preserved. After preparation, end the session
132
+ with the same selector and expected IDs, replacing `--check` with `--require-complete`.
133
+ Both strict modes return 2 for incomplete closeout. The legacy advisory exit 0 and `SESSION_ENDED`
134
+ alone are never success evidence. Checkout settlement does not assert business completion.
135
+
136
+ These capabilities are additive to CLI 60/storage 5; older clients keep their previous interface.
137
+ They do not authorize cross-repository edits, main integration, Bundle promotion or deployment.
138
+
139
+ ## Aborted integration with preserved build output
140
+
141
+ Require `aborted_integration_preserved_cleanup_version` 1 from `capabilities --json`.
142
+ Use the same version's Python for the public `worktree_controller.preservation` module.
143
+ No consumer computes Controller digests or opens its private ledger.
144
+
145
+ 1. Read `status`, `integration-queue`, `admission-queue` and `doctor`. Identify the exact owner,
146
+ allocation, branch, HEAD, record version and failed intent. Retain the candidate's branch and
147
+ original source/failure evidence. A clean checkout or expired lease grants no removal authority.
148
+ 2. A `QUARANTINED` candidate stays fenced against direct cleanup and writes. Its recorded owner
149
+ may use the existing explicit `integration-abort --path ... --owner ...
150
+ --expected-record-version ... --reason ...`. Review its new record version and immutable abort
151
+ receipt. Missing or changed receipt evidence, publication evidence or a still-bound intent blocks
152
+ the new cleanup path. Keep the quarantine history; do not clear fields or metadata manually.
153
+ 3. On `INTEGRATION_ABORTED`, create a preservation plan and copy for **each explicitly reviewed
154
+ ignored tree**. This includes generated output which is otherwise recognized as disposable:
155
+
156
+ ```text
157
+ python -m worktree_controller.preservation plan --repo <repo> --path <candidate> \
158
+ --allocation-id <allocation> --owner <owner> --expected-record-version <version> \
159
+ --source <relative-tree> --plan-file <new-task-owned-plan-file>
160
+ python -m worktree_controller.preservation copy --plan-file <plan-file>
161
+ ```
162
+
163
+ Use the returned receipt paths and SHA-256 values. Copies preserve opaque content and literal
164
+ links rather than trusting directory names. Tracked content, dirty user files, unignored paths,
165
+ leases, bindings, incomplete runtime observation and unresolved transactions keep their guards.
166
+ 4. Run `resource-clean --typed --dry-run` with the exact owner/CAS, primary
167
+ `--preservation-receipt` / `--preservation-receipt-sha256`, and paired repeatable
168
+ `--additional-preservation-receipt` / `--additional-preservation-receipt-sha256` options.
169
+ Review every path and blocker. Apply with the producer's `--expected-plan-id`; no threshold,
170
+ policy change or private digest recipe is needed. Every deletion rechecks current evidence.
171
+ 5. Cleanup retains `INTEGRATION_ABORTED` and never releases the checkout. Consumed live-source
172
+ receipts cannot be replayed; they remain refused if the original source is absent. A fresh
173
+ empty cleanup plan verifies the completed receipts and performs no deletion. Interrupted or
174
+ partial operations use the existing exact `resource-recover` contracts, never a fresh replay.
175
+ 6. Use normal `release --dry-run`, then the same exact owner/CAS release. It keeps the branch,
176
+ records the release receipt, and settles the original durable admission reservation. An abort
177
+ or preservation alone never cancels that reservation. Preserve release evidence before any
178
+ separately authorized branch retirement.
179
+ 7. For unchanged sources, retain the existing `integration-retry` identity and queue rules. For
180
+ changed sources, use their own frozen reviewed handoffs and queued intent; do not replace sources
181
+ in an old request or inherit its priority. Terminating an old intent's scope claim, when needed,
182
+ remains a separate explicit `integration-abandon`. After release, claim the selected new intent
183
+ through ordinary admission, build and validate anew. Historical PASS does not authorize it.
184
+
185
+ ## Release and maintenance
186
+
187
+ After an official runtime rollback, synchronize its source-owned Skill with the
188
+ published installer's `sync-skill --version <active-full-oid>
189
+ --skill-rollback-from <previous-full-oid> --dry-run`, then apply the same arguments
190
+ without `--dry-run`. The previous OID must identify a retained, verified installed
191
+ runtime and be a strict descendant of the now-active commit. Installed Skill bytes
192
+ must match that exact committed source; the companion must remain unchanged. The
193
+ normal activation lock, active-pointer CAS, owned-path checks and atomic receipt
194
+ still apply. Repeating a completed sync is safe. Unknown instructions, a missing or
195
+ modified runtime, unrelated history and companion changes remain refused. This
196
+ optional installer argument does not change the runtime, storage or CLI contract;
197
+ old upgrade calls retain their ancestor-only behavior. Finish with the actual
198
+ installed `tool-skill-sync doctor --repo <checkout> --summary` and reread changed
199
+ instructions. Never copy a backup over the shared Skill to bypass a refusal.
200
+
201
+ Use `release --dry-run` to review the same guards used by execution. A clean checkout can still be
202
+ leased, in use, referenced by another environment, or lack publication/recovery evidence.
203
+ An incomplete environment scan is a blocker: inspect the reported candidate file or directory and
204
+ resolve its ownership/access/reference through the owning environment. Do not remove a reference
205
+ just to obtain a passing release.
206
+
207
+ `BINDING_IDENTITY_DRIFT` means the checkout at a bound key is not the Git registration the
208
+ binding was written for (it was removed and another worktree reused its name outside the
209
+ Controller). The checkout is unmanaged and the old allocation keeps its record. Do not write
210
+ into it under the old task: identify the new checkout's real owner and `adopt` it explicitly, or
211
+ remove it through its owner; the old task resumes from its retained branch through normal
212
+ admission.
213
+
214
+ A typed `resource-clean` refused with `HARDLINK_TOPOLOGY_BLOCKED` (for example while another
215
+ environment hardlinks the same `uv` cache files) leaves a journal that blocks the checkout and
216
+ activation. Close it with `resource-recover --stage reconcile-typed --dry-run` and the same command
217
+ with `--expected-plan-id`, then plan a fresh cleanup. Journals from before 1.28.0 that marked the
218
+ first action `FAILED_OR_PARTIAL` are accepted only when that action's `0000-before.json` is the
219
+ sole evidence and the resource tree is unchanged.
220
+
221
+ Bindings written before 1.26.0 have no registration. Run `reconcile binding-registrations
222
+ --dry-run --json`, review `candidates` and `refused`, then repeat without `--dry-run` and with
223
+ `--expected-plan-id <plan_id>`. A changed plan means the repository moved; dry-run again. Refused
224
+ bindings keep their legacy meaning; resolve them through their owner (for example release and
225
+ re-acquire) rather than writing a marker by hand.
226
+
227
+ Use `reconcile retention --actor <policy-reconciler> --json` for a read-only explanation. Apply
228
+ belongs to the delegated reconciler. Dirty or active work stays with its owner; retained branches
229
+ and immutable receipts are not disposable checkout payloads. For an interrupted release, use
230
+ `release-recovery-inspect` and replay its exact published recovery arguments.
231
+
232
+ `reconcile release-plans` keeps plans referenced by durable release receipts. They remain part
233
+ of closed lifecycle and branch-retirement evidence after the checkout is gone. It retires only
234
+ unreferenced leftover plans for already released allocations with durable release evidence.
235
+ An absent historical plan continues to block its dependent queries and retirement; preserve the
236
+ remaining evidence and recover the original plan rather than infer it from a branch or receipt.
237
+
238
+ ## Checks and deployment
239
+
240
+ `bash scripts/check-shards [SHARDS]` is the fast integration gate; SHARDS is 1–64. Collection and
241
+ workers use isolated environments. Collection failure stops before workers start; empty shards
242
+ are skipped. Success removes its temporary output, while failure/interruption prints and retains
243
+ the output directory for diagnosis. Keep that evidence outside the checkout and clean it through
244
+ its owning temporary-directory workflow after review. `scripts/check-project` remains the complete
245
+ release gate, including builds and installed smokes.
246
+
247
+ Deliver tool changes through reviewed source, contracts and source-owned Skills, then supported
248
+ stage, rollout and activation. CLI, capability and storage versions are independent checks.
249
+ Use the existing rollback flow; never repoint the active runtime by hand or activate another
250
+ owner's unintegrated candidate. Finish with installed smoke, rollout/deployment checks and doctor.
251
+
252
+ For each external consumer, distinguish three outcomes:
253
+
254
+ | Check | What it proves |
255
+ | --- | --- |
256
+ | Capability and compatibility check | The producer advertises the contract the consumer requires |
257
+ | Installed hook/adapter smoke | The installed adapter sends correct identity, access class and target |
258
+ | Actual client tool invocation | The client discovers and invokes that adapter in its running session |
259
+
260
+ Record an unobserved client invocation as unobserved. A copied hook, passing doctor or successful
261
+ direct probe does not establish that a running client has reloaded its discovery metadata.