worktree-controller 1.32.1__tar.gz → 1.32.4__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 (79) hide show
  1. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/PKG-INFO +15 -5
  2. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/README.md +14 -4
  3. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/docs/architecture.md +9 -2
  4. worktree_controller-1.32.4/docs/integration-boundaries.md +68 -0
  5. worktree_controller-1.32.4/docs/roadmap.md +46 -0
  6. worktree_controller-1.32.4/docs/scope.md +92 -0
  7. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/pyproject.toml +1 -1
  8. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/pyproject.toml.orig +1 -1
  9. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/__init__.py +1 -1
  10. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/canonical_transition.py +2 -2
  11. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/cli.py +1 -0
  12. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/controller.py +4 -20
  13. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/convergence.py +5 -5
  14. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/delivered_closeout.py +126 -7
  15. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/frozen_recovery.py +3 -3
  16. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/integration_conflict.py +4 -3
  17. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/integration_retry.py +10 -8
  18. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/lifecycle.py +25 -142
  19. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/preserved_cleanup.py +5 -0
  20. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/reconciler.py +3 -2
  21. worktree_controller-1.32.4/src/worktree_controller/record_updates.py +54 -0
  22. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/registration_prune.py +2 -2
  23. worktree_controller-1.32.4/src/worktree_controller/release_intents.py +57 -0
  24. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/semantics.py +52 -0
  25. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/tool_cli_contract.json +9 -1
  26. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/tool_cli_contract.json +9 -1
  27. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/LICENSE +0 -0
  28. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/docs/client-integration.md +0 -0
  29. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/docs/daily-workflow.md +0 -0
  30. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/docs/first-change.md +0 -0
  31. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/docs/getting-started.md +0 -0
  32. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/docs/operations.md +0 -0
  33. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/docs/publishing.md +0 -0
  34. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/docs/reference.md +0 -0
  35. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/examples/change_task.py +0 -0
  36. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/examples/client_continuation.py +0 -0
  37. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/examples/quickstart.py +0 -0
  38. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/activation_layout.py +0 -0
  39. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/branch_retirement.py +0 -0
  40. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/canonical_refresh.py +0 -0
  41. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/cleanup_attempts.py +0 -0
  42. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/cleanup_evidence.py +0 -0
  43. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/cleanup_recovery.py +0 -0
  44. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/disposable.py +0 -0
  45. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/environment.py +0 -0
  46. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/git_backend.py +0 -0
  47. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/governance.py +0 -0
  48. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/hardlinks.py +0 -0
  49. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/integration_cleanup.py +0 -0
  50. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/keyed_document_scope.py +0 -0
  51. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/lifecycle_history.py +0 -0
  52. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/lifecycle_observation.py +0 -0
  53. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/metadata_codec.py +0 -0
  54. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/metadata_relocation.py +0 -0
  55. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/models.py +0 -0
  56. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/mount_diagnostics.py +0 -0
  57. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/multiple_cleanup_recovery.py +0 -0
  58. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/namespace_migration.py +0 -0
  59. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/native_session_recovery.py +0 -0
  60. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/owner_actions.py +0 -0
  61. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/policy.py +0 -0
  62. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/preservation.py +0 -0
  63. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/publication_execution.py +0 -0
  64. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/recovery_guidance.py +0 -0
  65. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/registration_backfill.py +0 -0
  66. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/rendering.py +0 -0
  67. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/resource_admission.py +0 -0
  68. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/retirement_adapters.py +0 -0
  69. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/retirement_execution.py +0 -0
  70. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/session.py +0 -0
  71. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/session_admission.py +0 -0
  72. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/source_cleanup.py +0 -0
  73. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/source_preservation.py +0 -0
  74. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/source_recovery.py +0 -0
  75. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/store.py +0 -0
  76. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/task_workflow.py +0 -0
  77. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/transaction_scope.py +0 -0
  78. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/writer_lease.py +0 -0
  79. {worktree_controller-1.32.1 → worktree_controller-1.32.4}/src/worktree_controller/writer_session.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: worktree-controller
3
- Version: 1.32.1
3
+ Version: 1.32.4
4
4
  Summary: Govern Git worktree budgets, authority, ownership, and lifecycle
5
5
  License-Expression: Apache-2.0
6
6
  License-File: LICENSE
@@ -23,7 +23,7 @@ It checks repository policy before allocating a worktree, grants writing authori
23
23
  process, and records handoff, integration, recovery and release evidence. Git remains the source
24
24
  of truth for files, branches, commits and registered worktrees.
25
25
 
26
- **Current release: 1.32.0 · Linux · Python 3.12 · Apache-2.0**
26
+ **Current release: 1.32.2 · Linux · Python 3.12 · Apache-2.0**
27
27
 
28
28
  ## Install
29
29
 
@@ -32,7 +32,7 @@ Use a virtual environment in a new directory:
32
32
  ```bash
33
33
  python3.12 -m venv .venv
34
34
  . .venv/bin/activate
35
- python -m pip install worktree-controller==1.32.0
35
+ python -m pip install worktree-controller==1.32.2
36
36
  worktree-controller --version
37
37
  worktree-controller capabilities --json
38
38
  ```
@@ -41,7 +41,7 @@ WC requires Git and readable Linux `/proc`. Other operating systems and Python v
41
41
  supported by this release. Its one runtime dependency is `websockets>=15,<16`.
42
42
  On Ubuntu, if creating the environment reports that `ensurepip` is unavailable, install the
43
43
  distribution's `python3.12-venv` package first (for example, `sudo apt install python3.12-venv`).
44
- Software version 1.32.0 uses CLI contract **61** and storage layout **5**.
44
+ Software version 1.32.2 uses CLI contract **61** and storage layout **5**.
45
45
 
46
46
  ## Try it in a disposable repository
47
47
 
@@ -50,7 +50,7 @@ With the environment above active:
50
50
  ```bash
51
51
  git clone https://github.com/xuanheng-tech/worktree-controller.git wc
52
52
  cd wc
53
- git checkout v1.32.0
53
+ git checkout v1.32.2
54
54
  python examples/quickstart.py --workspace "$HOME/wc-first-run"
55
55
  ```
56
56
 
@@ -114,3 +114,13 @@ a successful process exit alone does not prove that all worktrees are settled.
114
114
  - [Report a security issue](https://github.com/xuanheng-tech/worktree-controller/blob/main/SECURITY.md)
115
115
 
116
116
  Licensed under the [Apache License 2.0](https://github.com/xuanheng-tech/worktree-controller/blob/main/LICENSE).
117
+
118
+ With `terminal_preserved_cleanup_version` 1, published integrations and completed
119
+ no-change feature/audit tasks may use the existing preservation and `resource-clean --typed`
120
+ flow. Require one exact remote-verified, lease-cleared publication or one verified original
121
+ no-change completion. Every removed tree needs immutable preservation coverage.
122
+ Plans pin the current verified proof baseline; cleanup and release recheck it without
123
+ rewriting history, reopening lifecycle or relaxing owner/HEAD/CAS, runtime, lease, retained-ref
124
+ and transaction guards. A newly observed legacy digest is not historical hash evidence.
125
+ New-format no-change completions may clean afterward only when their frozen prior cleanup
126
+ set is empty; existing pre-completion proofs retain their original CAS.
@@ -6,7 +6,7 @@ It checks repository policy before allocating a worktree, grants writing authori
6
6
  process, and records handoff, integration, recovery and release evidence. Git remains the source
7
7
  of truth for files, branches, commits and registered worktrees.
8
8
 
9
- **Current release: 1.32.0 · Linux · Python 3.12 · Apache-2.0**
9
+ **Current release: 1.32.2 · Linux · Python 3.12 · Apache-2.0**
10
10
 
11
11
  ## Install
12
12
 
@@ -15,7 +15,7 @@ Use a virtual environment in a new directory:
15
15
  ```bash
16
16
  python3.12 -m venv .venv
17
17
  . .venv/bin/activate
18
- python -m pip install worktree-controller==1.32.0
18
+ python -m pip install worktree-controller==1.32.2
19
19
  worktree-controller --version
20
20
  worktree-controller capabilities --json
21
21
  ```
@@ -24,7 +24,7 @@ WC requires Git and readable Linux `/proc`. Other operating systems and Python v
24
24
  supported by this release. Its one runtime dependency is `websockets>=15,<16`.
25
25
  On Ubuntu, if creating the environment reports that `ensurepip` is unavailable, install the
26
26
  distribution's `python3.12-venv` package first (for example, `sudo apt install python3.12-venv`).
27
- Software version 1.32.0 uses CLI contract **61** and storage layout **5**.
27
+ Software version 1.32.2 uses CLI contract **61** and storage layout **5**.
28
28
 
29
29
  ## Try it in a disposable repository
30
30
 
@@ -33,7 +33,7 @@ With the environment above active:
33
33
  ```bash
34
34
  git clone https://github.com/xuanheng-tech/worktree-controller.git wc
35
35
  cd wc
36
- git checkout v1.32.0
36
+ git checkout v1.32.2
37
37
  python examples/quickstart.py --workspace "$HOME/wc-first-run"
38
38
  ```
39
39
 
@@ -97,3 +97,13 @@ a successful process exit alone does not prove that all worktrees are settled.
97
97
  - [Report a security issue](https://github.com/xuanheng-tech/worktree-controller/blob/main/SECURITY.md)
98
98
 
99
99
  Licensed under the [Apache License 2.0](https://github.com/xuanheng-tech/worktree-controller/blob/main/LICENSE).
100
+
101
+ With `terminal_preserved_cleanup_version` 1, published integrations and completed
102
+ no-change feature/audit tasks may use the existing preservation and `resource-clean --typed`
103
+ flow. Require one exact remote-verified, lease-cleared publication or one verified original
104
+ no-change completion. Every removed tree needs immutable preservation coverage.
105
+ Plans pin the current verified proof baseline; cleanup and release recheck it without
106
+ rewriting history, reopening lifecycle or relaxing owner/HEAD/CAS, runtime, lease, retained-ref
107
+ and transaction guards. A newly observed legacy digest is not historical hash evidence.
108
+ New-format no-change completions may clean afterward only when their frozen prior cleanup
109
+ set is empty; existing pre-completion proofs retain their original CAS.
@@ -10,8 +10,9 @@ development and recovery paths; exact public interfaces live in the [contract](.
10
10
  | --- | --- | --- |
11
11
  | CLI parsing and routing | `cli.py`, command modules | Dispatch explicit operations; do not duplicate authority decisions |
12
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 |
13
+ | State and durable evidence | `models.py`, `store.py`, `metadata_codec.py`, `record_updates.py` | Validate stored identities; serialize mutations under the repository lock; record updates bump their version, and both update helpers append history |
14
+ | Shared identity and semantic checks | `semantics.py` | Consume the caller's snapshot, including effective intent state and terminal reconciliation; do not acquire authority or write metadata |
15
+ | Release-intent queries | `release_intents.py` | Select from the caller's snapshot and calculate renewal backoff using its supplied time; no metadata writes or fresh observation |
15
16
  | Budget admission | `resource_admission.py` | Preserve durable request identity and host reservations across retries |
16
17
  | Writer entitlement | `writer_lease.py`, `writer_session.py`, `governance.py` | Bind the real process identity and exact operation/target |
17
18
  | Lifecycle orchestration | `lifecycle.py` and focused recovery modules | Compose existing guards and append durable transition evidence |
@@ -76,3 +77,9 @@ Further lifecycle extraction should follow one cohesive transition at a time, ke
76
77
  scope and immutable evidence together. Avoid moving mutation helpers that depend on lifecycle's
77
78
  clock, transaction state or caller-specific guards merely to reduce a line count. Public CLI,
78
79
  capability and storage changes require their own version and compatibility review.
80
+
81
+ Release-intent selection and renewal backoff share a pure query module. Lifecycle keeps the
82
+ mutation helpers, clock, lock scope, cancellation and history append unchanged. Convergence
83
+ uses the same query directly; lifecycle retains its existing internal aliases. A changed HEAD
84
+ or record version still renews immediately, and repeated unchanged expiries retain the existing
85
+ one-day backoff cap. This extraction changes no CLI, capability or storage contract.
@@ -0,0 +1,68 @@
1
+ # Consumer and protocol boundaries
2
+
3
+ Inventory verified on 2026-10-23 against WC 1.32.3 (CLI 61, storage 5) and GF 1.9.7.
4
+ This is a source inventory, not an observation of every installed host or external user.
5
+ The public [CLI contract](../tool_cli_contract.json) remains authoritative.
6
+ [Scope](scope.md) records the conservative decision to keep existing commands supported.
7
+
8
+ ## Existing delivery protocols
9
+
10
+ | Flow | Producer authority | Consumer responsibility | Required evidence and refusal |
11
+ | --- | --- | --- | --- |
12
+ | Integration publication | WC `integration-publication-session/v1`; repository lock spans verify, authorize, push observation and completion | GF publishes the exact authorized candidate with a non-force push and independently observes the remote | Repository/allocation, lease/run, candidate, expected main, record version and validation identity must match. Missing capability, drift or incomplete completion blocks. After uncertain transport, inspect remote facts and re-enter the same identity. |
13
+ | Branch retirement | WC `branch-retirement-execution/v1` and `retirement-execution-result/v1` | GF performs only the plan-authorized exact-OID ref operation | The public plan, verify, authorize and complete results bind the operation and ancestry proof. Missing refs alone do not establish a completed retirement; retain recovery identity. |
14
+ | Sensitive source review | GF owns its review-file schema | Treat the four WC linkage fields as opaque identities | No derivation of private authority digests or parsing WC metadata to construct authority. |
15
+ | Review evidence | SR owns `snapshot-runner read`, evidence-read schema 1 and stored-era validation | GF's explicit initial-publish mode consumes public fields | Unknown schema, partial output, gaps or identity mismatch blocks; GF does not parse SR storage or hard-code its security epoch. |
16
+ | Deployment health | The published toolchain catalog, currently owned by GF | `tool-skill-sync doctor` verifies installed capabilities and the frozen runtime contract | Explicit CLI/storage allowlists and required capability versions all apply. Source availability or equal CLI numbers alone do not prove compatibility. |
17
+
18
+ These protocols already exist. The next step is preserving and testing them, not designing a
19
+ replacement message bus or accepting unknown versions. Protocol/capability versioning does not
20
+ relax the deployment catalog's explicit CLI/storage compatibility checks.
21
+
22
+ GF is independently usable for its core Git operations. WC/SR adapters run only when their
23
+ corresponding operation is requested. GF's
24
+ [adapter inventory and regression matrix](https://github.com/xuanheng-tech/git-finalizer/blob/828c35a3bc3d60c5ef25f1fb5221a086e749c0b5/docs/integration-boundaries.md)
25
+ is the consumer-owned authority. WC owns lifecycle; a GF execution receipt still needs the
26
+ formal `lease-complete` flow before lifecycle completion.
27
+
28
+ Two bounded legacy couplings remain: GF checks WC namespace directory **existence** to report
29
+ a migration blocker, and recognizes exact public contract descriptions in its scanner. Neither
30
+ is general private-state parsing. Replace the existence probe only after a producer-owned
31
+ public unmanaged/legacy/migrated verdict exists and all negative controls pass. Keep the narrow
32
+ scanner recognition until an agreed producer/consumer contract change replaces it; never widen
33
+ the scanner or silently fall back to private files.
34
+
35
+ ## Host consumers
36
+
37
+ A fresh inspection of AW's current controller client confirms the following source call paths:
38
+
39
+ | Surface | Evidence classification | Ownership decision |
40
+ | --- | --- | --- |
41
+ | `host-execution`, `execution-admit/cancel`, `admission-queue` | Direct calls | WC governs admission and resource claims; AW keeps business scheduling and host policy. |
42
+ | `session-admit` | Direct `_invoke` call after capability negotiation | Supported. The earlier audit's absence claim is obsolete. |
43
+ | `session-bind` | Argument tuple passed through `_run`, rather than a literal `_invoke` call | Supported. An `_invoke`-only search misses this consumer. |
44
+ | `binding-add/remove/transfer` | Transfer is direct; add/remove are dynamically composed by a bounded helper | Supported; explicit client/session identity and existing lease checks remain required. |
45
+ | `lifecycle-events`, `lifecycle-event-ack` | Direct calls | WC owns event identity; AW acknowledges after its own durable update. |
46
+ | `reconcile-session` | No direct external AW CLI call found in this inspection; WC's shipped session-end adapter calls the lifecycle function | Supported. No proof of exclusive use or safe deprecation. |
47
+
48
+ Also observed: plan/acquire/resume/status/capabilities, writer lease acquire/release and write
49
+ guard; integration queue/refresh/validate, publication lease acquire/complete, reconciliation,
50
+ release-intent and lifecycle-history. Static literals are evidence of a call path, not runtime
51
+ frequency or a complete list of dynamically constructed commands.
52
+
53
+ No AW identity default, resource limit, QP policy or business approval changes in this inventory.
54
+ Any future host-policy relocation needs consumer-owned changes, staged compatibility, migration
55
+ and rollback. Recovery commands remain supported until all consumers have an evidence-backed
56
+ migration and a published deprecation window.
57
+
58
+ ## Regression and change gates
59
+
60
+ - WC: public CLI/API contract tests plus the affected lifecycle/recovery suites, and the complete
61
+ integration gate for shared changes. A pure helper extraction preserves clocks, locks, request
62
+ identity, immutable history, refusal codes, retry timing and aliases.
63
+ - GF: its existing boundary tests, public-protocol negative controls and required real WC/SR
64
+ release gate. A consumer stub is not a substitute for real producer acceptance.
65
+ - Host: installed capability checks and the consumer's existing acceptance command before
66
+ activation. Source inspection is not installed-runtime or live-business acceptance.
67
+ - Preserve old receipts and explicit version allowlists. Do not count an expected nonzero refusal
68
+ as functional success, and do not infer business completion from a clean checkout.
@@ -0,0 +1,46 @@
1
+ # Maintenance roadmap
2
+
3
+ Execution baseline: 2026-10-23. This is the WC portion of the approved four-tool maintenance
4
+ direction. Each stage needs its own tested deliverable; later ideas are not current behavior.
5
+
6
+ ## Current baseline
7
+
8
+ WC 1.32.4 retains CLI contract 61 and storage layout 5. The scope and architecture documents
9
+ are already on main. Two previous extractions reduced private cross-module imports from 93 to
10
+ 82; this batch moves pure release-intent selection/backoff queries into one module, reducing
11
+ the baseline to 80. It retains lifecycle mutation helpers, clocks and internal aliases.
12
+
13
+ GF 1.9.7 already consumes SR's public read API and WC's versioned publication/retirement
14
+ protocols. CL 1.3.10 and SR 2.5.12 already use main on both hosting platforms. These completed
15
+ items are not prerequisites still waiting to happen.
16
+
17
+ [Consumer boundaries](integration-boundaries.md) correct the earlier AW session-call inventory.
18
+ Remaining evidence gaps are external consumer usage, installed-host behavior beyond the existing
19
+ acceptance gates, and historical temporary-file impact. No historical evidence is cleaned up.
20
+
21
+ ## Sequence and acceptance
22
+
23
+ | Stage | Deliverable | Exit evidence | Stop or rollback boundary |
24
+ | --- | --- | --- | --- |
25
+ | Now: boundaries | Current protocol and consumer inventory, including legacy adapters | Named owner per interface, source references, explicit unknowns; no changes to supported commands | Conflicting evidence keeps the interface supported |
26
+ | Now: WC structure | One cohesive pure release-intent query extraction | Full integration gate; existing renewal/cancellation/recovery behavior; CLI 61/storage 5 unchanged | Revert the isolated extraction if behavior differs |
27
+ | Pilot: shared quality checks | Local release-tools candidate and CL integration packet with a full commit pin | Workflow lint, CL local quality check, then all supported Python versions on real hosted CI after publication | Restore the pinned original CL workflow; PyPI/Gitea flows remain owned by consumers |
28
+ | Next 2–6 weeks | Further WC extraction only where a shared responsibility is clear; measure maintenance burden and failures | One behavior-preserving batch at a time, consumer gates, shrinking private-import baseline | Keep injected clocks, transaction and crash hooks with their owner until an explicit migration is tested |
29
+ | Following 6–12 weeks | Evaluate moving manifests, compatibility catalog and shared Skills from GF to a dedicated toolchain owner | Full ownership inventory, staged installer/migration, exactly one active writer, historical pin and rollback tests | No second simultaneous Skill authority; no ownership switch on file-copy evidence |
30
+ | Following 3–6 months | Evaluate a staged GF Python core migration | Characterization of exit/status/ref effects, isolated old/new comparisons, interruption recovery and real consumer gates | No dual production writes; preserve scanner refusals and existing installation until replacement passes |
31
+
32
+ The time ranges express ordering, not release deadlines. Batch internal maintenance with a
33
+ planned software release instead of increasing the CLI contract for every refactor. A public
34
+ behavior change still requires explicit contract/capability review and compatibility updates.
35
+
36
+ ## Shared workflow pilot boundary
37
+
38
+ Start with CL and retain its Python matrix and `just check`; only after hosted equivalence is
39
+ proved adopt SR with its additional package check. Pin all workflow dependencies to reviewed
40
+ commits. Keep upload jobs and their Trusted Publisher/environment in each repository's top-level
41
+ release workflow. First publication of a new public repository requires its own authorization.
42
+
43
+ Do not introduce a shared runtime Python dependency into CL/SR, merge the tools, relax SR's
44
+ Python floor, move host-specific defaults without migration, or replace existing WC/GF protocols.
45
+ GitHub-first release consolidation and a future toolchain repository remain design decisions,
46
+ not permission to disable existing Gitea delivery or platform controls.
@@ -0,0 +1,92 @@
1
+ # Scope and consumer surface (draft for owner decision)
2
+
3
+ This document records which parts of the public CLI are generic worktree governance and which
4
+ exist mainly for one consumer. It is an inventory plus proposed boundaries; nothing here changes
5
+ behavior, and every "proposed" line needs an owner decision before code moves.
6
+
7
+ Snapshot: WC 1.32.3, CLI contract 61, 81 commands, 66 `*_version` capability keys. The public contract
8
+ counts were rechecked on 2026-10-23. Host call paths were rechecked against current
9
+ consumer source; this remains static evidence, not a runtime trace or proof of exclusive use.
10
+ See [consumer boundaries](integration-boundaries.md) for the updated protocol inventory.
11
+
12
+ ## How the inventory was made
13
+
14
+ - **Agent Workspace (AW):** every `_invoke(...)` call in AW's controller client
15
+ (`backend/src/agent_workspace/infrastructure/worktree_controller.py`), plus argument tuples
16
+ passed through `_run`, bounded dynamic binding helpers, session-retirement and external-execution
17
+ modules. The earlier `_invoke`-only inventory missed `session-bind`. This is not proof that
18
+ dynamic or other consumers do not exist.
19
+ - **Git Finalizer (GF):** word match over `git-finalize*` and `tooling/*.py`. Common words
20
+ (`review`, `task`, `release`, `resume`, `status`, `doctor`) can be false positives; the
21
+ retirement and publication entries are confirmed by GF's adapter code.
22
+ - **Docs/examples:** word match over `README.md`, `docs/`, `examples/` and the shipped Skill.
23
+
24
+ ## 1. Generic governance core (keep; any client)
25
+
26
+ Checkout budget, ownership and safe release for any person or agent sharing a repository:
27
+
28
+ `plan`, `status`, `doctor`, `capabilities`, `acquire`, `adopt`, `park`, `reopen`, `release`,
29
+ `release-intent`, `quarantine`, `review`, `handoff`, `resume`, `task`, `complete-no-change`,
30
+ `recovery-guide`, `lifecycle-history`, `write-guard`, `writer-lease-acquire`,
31
+ `writer-lease-release`, `writer-session`, `lease-acquire`, `lease-complete`, `lease-abort`,
32
+ `integration-enqueue`, `integration-claim`, `integration-validate`, `integration-queue`,
33
+ `integration-refresh`, `reconcile`.
34
+
35
+ ## 2. Delivery-tool protocols (keep; versioned, consumed by GF)
36
+
37
+ `branch-retirement-plan`, `-verify`, `-authorize`, `-complete`, `-record`, `-status`,
38
+ `-executions`, and `publication-execution-session`. These are the public protocols GF consumes
39
+ through versioned capabilities and protocols. This does not relax explicit CLI/storage version
40
+ allowlists in the deployment catalog or permit unknown versions. See [boundaries](integration-boundaries.md).
41
+
42
+ ## 3. Host-runtime integration (used by AW today)
43
+
44
+ | Command | Used by AW | Note |
45
+ | --- | --- | --- |
46
+ | `host-execution` | yes | Budgets a host process with no repository writer lease; default `--client-id` is `agent-workspace` |
47
+ | `execution-admit`, `execution-cancel` | yes | Durable admission of governed executions |
48
+ | `admission-queue` | yes | Periodic queue reconciliation |
49
+ | `binding-add`, `binding-remove`, `binding-transfer` | yes | Runtime bindings owned by a host |
50
+ | `lifecycle-events`, `lifecycle-event-ack` | yes | Event feed with consumer acknowledgement |
51
+ | `session-admit`, `session-bind` | yes, confirmed in current source | Capability-negotiated direct/tuple call paths; retain support |
52
+ | `reconcile-session` | no direct external AW CLI call found | WC session-end calls its lifecycle function; other external consumers remain unverified |
53
+
54
+ **Proposed:** keep these in WC only if they are documented as a generic *host runtime protocol*
55
+ (any host, explicit `--client-id`, no AW-specific defaults or wording). Otherwise move the
56
+ AW-specific policy (memory budgets, default identities) into AW and keep WC's part to admission
57
+ and binding records.
58
+
59
+ ## 4. Recovery and maintenance tail
60
+
61
+ `recover-handoff`, `recover-published`, `recovery-adopt`, `release-recovery-inspect`,
62
+ `integration-abort`, `-abandon`, `-reopen`, `-resolve`, `-retry`, `-equivalent`,
63
+ `-recovery-matrix`, `close-delivered`, `close-preserved`, `adopt-delivered`, `archive-retained`,
64
+ `externalize`, `resource-register`, `resource-clean`, `resource-recover`, `gc-plan`, `gc-apply`,
65
+ `reconcile-writers`, `acquire-across`, `acquire-when-free`, `canonical-refresh`,
66
+ `canonical-transition`, `namespace-migration-plan`, `-verify`, `-receipts`, `namespace-migrate`.
67
+
68
+ A static AW/GF inventory cannot establish usage by operators, other hosts or indirect adapters.
69
+ These commands remain supported; lack of a literal call is not deprecation evidence.
70
+
71
+ **Proposed:** classify each as *supported*, *operator-only* or *deprecated* in the CLI contract,
72
+ publish a deprecation window for the last group, and stop adding a new top-level command per
73
+ recovery case — prefer one `recover` entry with typed subcases.
74
+
75
+ ## Open questions for the owner
76
+
77
+ 1. Is `host-execution` meant for hosts other than AW? If not, should its policy move to AW?
78
+ 2. Which additional consumers use the session interfaces? AW use of `session-admit` and
79
+ `session-bind` is confirmed; direct external `reconcile-session` usage remains unverified.
80
+ 3. Which section-4 commands may be deprecated, and on what timeline?
81
+
82
+ ## Current compatibility decision
83
+
84
+ Keep every existing command supported while these ownership questions are unresolved. Do not
85
+ remove host commands, change default identities, relax recovery guards or deprecate commands
86
+ from an absence of static matches. New hosts use explicit client/session identities and the
87
+ versioned public contracts described in [client integration](client-integration.md). WC remains
88
+ the lifecycle and policy authority; consumers retain their business and release approvals.
89
+
90
+ Effective integration-state interpretation lives in `semantics.py`;
91
+ record and intent updates live in `record_updates.py`. These moves preserve CLI contract 61 and
92
+ storage layout 5. See [architecture](architecture.md) for module responsibilities.
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "worktree-controller"
7
- version = "1.32.1"
7
+ version = "1.32.4"
8
8
  description = "Govern Git worktree budgets, authority, ownership, and lifecycle"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12,<3.13"
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "worktree-controller"
7
- version = "1.32.1"
7
+ version = "1.32.4"
8
8
  description = "Govern Git worktree budgets, authority, ownership, and lifecycle"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12,<3.13"
@@ -1,3 +1,3 @@
1
1
  """Worktree lifecycle controller."""
2
2
 
3
- __version__ = "1.32.1"
3
+ __version__ = "1.32.4"
@@ -19,7 +19,6 @@ from .git_backend import (
19
19
  update_branch_ref,
20
20
  validate_branch_name,
21
21
  )
22
- from .lifecycle import _updated_record
23
22
  from .models import (
24
23
  ControllerError,
25
24
  MetadataRecord,
@@ -29,6 +28,7 @@ from .models import (
29
28
  WorktreePolicy,
30
29
  )
31
30
  from .policy import default_policy, load_policy, parse_policy
31
+ from .record_updates import updated_record
32
32
  from .semantics import managed_record as _managed_record
33
33
  from .store import MetadataStore
34
34
  from .transaction_scope import conflicts
@@ -274,7 +274,7 @@ def transition_canonical(
274
274
  if not refresh_main and item.branch == expected_branch:
275
275
  git_write(item.path, ("checkout", "--no-overwrite-ignore", expected_branch))
276
276
  raise
277
- updated = _updated_record(
277
+ updated = updated_record(
278
278
  record,
279
279
  "CANONICAL_MAIN_REFRESHED" if refresh_main else "CANONICAL_TRANSITIONED",
280
280
  lifecycle="ACTIVE",
@@ -1047,6 +1047,7 @@ def _main(argv: list[str] | None) -> int:
1047
1047
  "preservation_supersession_version": 1,
1048
1048
  "retained_typed_cleanup_version": 1,
1049
1049
  "aborted_integration_preserved_cleanup_version": 1,
1050
+ "terminal_preserved_cleanup_version": 1,
1050
1051
  "preservation_leaf_version": 1,
1051
1052
  "integration_publication_execution_version": 1,
1052
1053
  "integration_retry_version": 1,
@@ -33,9 +33,9 @@ from .mount_diagnostics import diagnose_mounts, mount_warnings
33
33
  from .policy import load_policy
34
34
  from .semantics import (
35
35
  EVIDENCE_LIFECYCLES,
36
+ effective_intent_state,
36
37
  evidence_head_issues,
37
38
  integration_candidate_issues,
38
- integration_intent_abandoned,
39
39
  integration_queue_order,
40
40
  normalize_scope_paths,
41
41
  path_scope_issues,
@@ -248,22 +248,6 @@ def _intent_for_allocation(snapshot: MetadataSnapshot, allocation_id: str | None
248
248
  return matches[0] if matches else None
249
249
 
250
250
 
251
- def _effective_intent_state(snapshot: MetadataSnapshot, intent: Any) -> str:
252
- reconciliations = [
253
- receipt
254
- for receipt in snapshot.integration_reconciliation_receipts.values()
255
- if receipt.intent_id == intent.intent_id
256
- and receipt.result == "STALE_INTENT_TERMINAL_ACKNOWLEDGED"
257
- ]
258
- if len(reconciliations) > 1:
259
- raise ControllerError(
260
- "INVALID_METADATA", "integration intent has multiple terminal reconciliations"
261
- )
262
- if reconciliations:
263
- return reconciliations[0].effective_terminal_state
264
- return "ABANDONED" if integration_intent_abandoned(intent) else intent.state
265
-
266
-
267
251
  def _integration_intent_order(intent: Any) -> tuple[int, int | str, str]:
268
252
  if intent.queue_sequence > 0:
269
253
  return (1, intent.queue_sequence, intent.intent_id)
@@ -400,7 +384,7 @@ def _repository_payload(
400
384
  (
401
385
  intent
402
386
  for intent in snapshot.integration_intents.values()
403
- if _effective_intent_state(snapshot, intent) in {"QUEUED", "WAITING_SCOPE"}
387
+ if effective_intent_state(snapshot, intent) in {"QUEUED", "WAITING_SCOPE"}
404
388
  ),
405
389
  key=lambda value: integration_queue_order(snapshot, value),
406
390
  )
@@ -543,7 +527,7 @@ def _worktree_payload(
543
527
  "source_allocations": list(record.source_allocations) if record else [],
544
528
  "integration_intent_id": intent.intent_id if intent else None,
545
529
  "integration_intent_state": (
546
- _effective_intent_state(snapshot, intent)
530
+ effective_intent_state(snapshot, intent)
547
531
  if intent is not None and snapshot is not None
548
532
  else None
549
533
  ),
@@ -1317,7 +1301,7 @@ def _semantic_warnings(
1317
1301
  "RELEASED": {"RELEASED"},
1318
1302
  }
1319
1303
  for intent in snapshot.integration_intents.values():
1320
- effective_state = _effective_intent_state(snapshot, intent)
1304
+ effective_state = effective_intent_state(snapshot, intent)
1321
1305
  if effective_state in {"QUEUED", "WAITING_SCOPE", "ABANDONED"}:
1322
1306
  continue
1323
1307
  if unallocated_integration_conflict(intent):
@@ -199,13 +199,13 @@ def _is_candidate(record: MetadataRecord) -> bool:
199
199
 
200
200
 
201
201
  def _integration_bound(snapshot: MetadataSnapshot, record: MetadataRecord) -> bool:
202
- from .lifecycle import _effective_intent_state
202
+ from .semantics import effective_intent_state
203
203
 
204
204
  return any(
205
205
  intent.allocation_id == record.allocation_id
206
206
  or record.allocation_id in intent.source_allocations
207
207
  for intent in snapshot.integration_intents.values()
208
- if _effective_intent_state(snapshot, intent) not in TERMINAL_INTEGRATION_STATES
208
+ if effective_intent_state(snapshot, intent) not in TERMINAL_INTEGRATION_STATES
209
209
  ) or any(
210
210
  other.lifecycle != "RELEASED" and record.allocation_id in other.source_allocations
211
211
  for other in snapshot.records.values()
@@ -316,11 +316,11 @@ def _require_intent_renewal_due(
316
316
  stays blocked. The same rule as stale-intent renewal applies: a changed record or
317
317
  HEAD, or a first expiry, proceeds at once.
318
318
  """
319
- from .lifecycle import _release_intents_for_allocation, _renewal_due
319
+ from .release_intents import release_intent_renewal_due, release_intents_for_allocation
320
320
 
321
321
  canonical = inventory(repository_path)
322
322
  snapshot = MetadataStore(canonical.common_dir).load()
323
- intents = _release_intents_for_allocation(snapshot, record.allocation_id)
323
+ intents = release_intents_for_allocation(snapshot, record.allocation_id)
324
324
  if any(intent.status in {"PENDING", "BLOCKED_RETRYABLE"} for intent in intents):
325
325
  return # create_release_intent reuses the live intent
326
326
  stale = [intent for intent in intents if intent.status == "STALE"]
@@ -329,7 +329,7 @@ def _require_intent_renewal_due(
329
329
  # The backoff runs from the most recent time an intent of this allocation went stale.
330
330
  latest = max(stale, key=lambda intent: (intent.updated_at, intent.created_at, intent.intent_id))
331
331
  ttl = load_policy(canonical.canonical_path).release_intent_ttl_seconds
332
- if not _renewal_due(snapshot, latest, record, item.head, datetime.now(UTC), ttl):
332
+ if not release_intent_renewal_due(snapshot, latest, record, item.head, datetime.now(UTC), ttl):
333
333
  raise ControllerError(
334
334
  "RENEWAL_BACKOFF",
335
335
  f"unchanged handoff release intent is backing off after {latest.blocker or 'expiry'}",