worktree-controller 1.30.6__tar.gz → 1.32.0__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 (74) hide show
  1. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/PKG-INFO +16 -5
  2. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/README.md +15 -4
  3. worktree_controller-1.32.0/docs/client-integration.md +121 -0
  4. worktree_controller-1.32.0/docs/daily-workflow.md +127 -0
  5. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/docs/first-change.md +4 -0
  6. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/docs/operations.md +69 -0
  7. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/docs/reference.md +6 -1
  8. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/examples/change_task.py +12 -9
  9. worktree_controller-1.32.0/examples/client_continuation.py +239 -0
  10. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/pyproject.toml +1 -1
  11. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/pyproject.toml.orig +1 -1
  12. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/__init__.py +1 -1
  13. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/cli.py +14 -1
  14. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/lifecycle.py +25 -3
  15. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/recovery_guidance.py +7 -0
  16. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/rendering.py +42 -0
  17. worktree_controller-1.32.0/src/worktree_controller/task_workflow.py +269 -0
  18. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/tool_cli_contract.json +37 -2
  19. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/tool_cli_contract.json +37 -2
  20. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/LICENSE +0 -0
  21. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/docs/architecture.md +0 -0
  22. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/docs/getting-started.md +0 -0
  23. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/docs/publishing.md +0 -0
  24. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/examples/quickstart.py +0 -0
  25. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/activation_layout.py +0 -0
  26. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/branch_retirement.py +0 -0
  27. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/canonical_refresh.py +0 -0
  28. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/canonical_transition.py +0 -0
  29. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/cleanup_attempts.py +0 -0
  30. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/cleanup_evidence.py +0 -0
  31. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/cleanup_recovery.py +0 -0
  32. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/controller.py +0 -0
  33. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/convergence.py +0 -0
  34. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/delivered_closeout.py +0 -0
  35. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/disposable.py +0 -0
  36. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/environment.py +0 -0
  37. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/frozen_recovery.py +0 -0
  38. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/git_backend.py +0 -0
  39. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/governance.py +0 -0
  40. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/hardlinks.py +0 -0
  41. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/integration_cleanup.py +0 -0
  42. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/integration_conflict.py +0 -0
  43. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/integration_retry.py +0 -0
  44. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/keyed_document_scope.py +0 -0
  45. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/lifecycle_history.py +0 -0
  46. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/lifecycle_observation.py +0 -0
  47. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/metadata_codec.py +0 -0
  48. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/metadata_relocation.py +0 -0
  49. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/models.py +0 -0
  50. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/mount_diagnostics.py +0 -0
  51. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/multiple_cleanup_recovery.py +0 -0
  52. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/namespace_migration.py +0 -0
  53. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/native_session_recovery.py +0 -0
  54. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/owner_actions.py +0 -0
  55. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/policy.py +0 -0
  56. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/preservation.py +0 -0
  57. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/preserved_cleanup.py +0 -0
  58. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/publication_execution.py +0 -0
  59. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/reconciler.py +0 -0
  60. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/registration_backfill.py +0 -0
  61. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/registration_prune.py +0 -0
  62. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/resource_admission.py +0 -0
  63. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/retirement_adapters.py +0 -0
  64. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/retirement_execution.py +0 -0
  65. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/semantics.py +0 -0
  66. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/session.py +0 -0
  67. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/session_admission.py +0 -0
  68. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/source_cleanup.py +0 -0
  69. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/source_preservation.py +0 -0
  70. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/source_recovery.py +0 -0
  71. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/store.py +0 -0
  72. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/transaction_scope.py +0 -0
  73. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/src/worktree_controller/writer_lease.py +0 -0
  74. {worktree_controller-1.30.6 → worktree_controller-1.32.0}/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.30.6
3
+ Version: 1.32.0
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.30.6 · Linux · Python 3.12 · Apache-2.0**
26
+ **Current release: 1.32.0 · 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.30.6
35
+ python -m pip install worktree-controller==1.32.0
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.30.6 retains CLI contract **60** and storage layout **5**.
44
+ Software version 1.32.0 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.30.6
53
+ git checkout v1.32.0
54
54
  python examples/quickstart.py --workspace "$HOME/wc-first-run"
55
55
  ```
56
56
 
@@ -69,6 +69,17 @@ To actually change a file, publish to a local bare remote, integrate and recover
69
69
  follow [your first change](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/first-change.md).
70
70
  That complete example additionally uses public Git Finalizer and Snapshot Runner installations.
71
71
 
72
+ ## Everyday tasks
73
+
74
+ Use `worktree-controller task list` to see live checkout tasks and `task show --task-key <task>`
75
+ for the recorded owner and next formal step. The [everyday task guide](docs/daily-workflow.md)
76
+ covers simpler start, original-task checkpoint/resume, guarded no-change release and exact
77
+ Finalizer handoff. These CLI 61 entrypoints retain the existing ownership, lease and policy checks.
78
+
79
+ For client developers, the [AI client integration guide](docs/client-integration.md) describes the
80
+ public identity and closeout contract, with an offline example that continues the same unfinished
81
+ task from two independent client processes while preserving its files and checkpoint.
82
+
72
83
  ## Use WC in a real project
73
84
 
74
85
  A governed repository tracks `.agents/worktree-policy.toml` and registers its checkouts with WC.
@@ -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.30.6 · Linux · Python 3.12 · Apache-2.0**
9
+ **Current release: 1.32.0 · 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.30.6
18
+ python -m pip install worktree-controller==1.32.0
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.30.6 retains CLI contract **60** and storage layout **5**.
27
+ Software version 1.32.0 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.30.6
36
+ git checkout v1.32.0
37
37
  python examples/quickstart.py --workspace "$HOME/wc-first-run"
38
38
  ```
39
39
 
@@ -52,6 +52,17 @@ To actually change a file, publish to a local bare remote, integrate and recover
52
52
  follow [your first change](https://github.com/xuanheng-tech/worktree-controller/blob/main/docs/first-change.md).
53
53
  That complete example additionally uses public Git Finalizer and Snapshot Runner installations.
54
54
 
55
+ ## Everyday tasks
56
+
57
+ Use `worktree-controller task list` to see live checkout tasks and `task show --task-key <task>`
58
+ for the recorded owner and next formal step. The [everyday task guide](docs/daily-workflow.md)
59
+ covers simpler start, original-task checkpoint/resume, guarded no-change release and exact
60
+ Finalizer handoff. These CLI 61 entrypoints retain the existing ownership, lease and policy checks.
61
+
62
+ For client developers, the [AI client integration guide](docs/client-integration.md) describes the
63
+ public identity and closeout contract, with an offline example that continues the same unfinished
64
+ task from two independent client processes while preserving its files and checkpoint.
65
+
55
66
  ## Use WC in a real project
56
67
 
57
68
  A governed repository tracks `.agents/worktree-policy.toml` and registers its checkouts with WC.
@@ -0,0 +1,121 @@
1
+ # Integrating an AI client
2
+
3
+ Use the existing public CLI as the boundary between a client and WC. The client implements the
4
+ business task and keeps its durable checkpoint; WC remains the authority for admission, writer
5
+ identity, lifecycle and release. Client names do not grant ownership or write permission.
6
+
7
+ ## Check the installed contract
8
+
9
+ Read `worktree-controller --version`, `capabilities --json` and the installed command's `--help`.
10
+ The task-oriented flow below requires CLI 61 and `task_workflow_version=1`. For checkpoint and
11
+ strict closeout, require `task_checkpoint_park_version=1`, `session_closeout_report_version=1`
12
+ and `session_closeout_expectations_version=1`. Storage layout is independently versioned (5 in
13
+ 1.31.0). A client must explicitly support the reported contract and required capabilities; a
14
+ newer version number alone is not sufficient. Refuse an unsupported contract without mutation.
15
+
16
+ Invoke commands as argument lists and parse JSON, process exit status and the specific result
17
+ together. Never parse human descriptions, evaluate a returned shell string, open WC's private
18
+ state, recreate a digest or replace a refused operation with raw Git worktree commands.
19
+
20
+ ## Keep the task and executor identities separate
21
+
22
+ | Durable business Task keeps | Current executor obtains or observes |
23
+ | --- | --- |
24
+ | Repository, task key, authority key, recorded owner | Actual live holder PID, boot identity and start time |
25
+ | Exact allocation ID, checkout path and branch | Client, session and run identity |
26
+ | Checkpoint payload, content-addressed ID and bound HEAD | Fresh writer lease and current record version |
27
+ | All allocations acquired by this task/session | Current HEAD, scope, lifecycle and blockers |
28
+ | Finalizer, integration and release evidence when applicable | Current public recovery guidance |
29
+
30
+ Changing AI clients changes the executor identity. It does not create a new business Task,
31
+ transfer its owner, replace its allocation or inherit the previous client's lease. An owner
32
+ transfer uses the existing explicit review/transfer flow. Re-observe identity, HEAD, scope and
33
+ record version before every mutation; a checkpoint is not a reusable authorization credential.
34
+
35
+ ## Start, pause and continue
36
+
37
+ 1. Inspect `status`, `doctor`, the selected policy and an existing compatible task. Use
38
+ `task start` only for a new task. Admission returns a checkout without writer entitlement.
39
+ 2. Bind the actual executor through the supported `writer-session` handshake or
40
+ `writer-lease-acquire`. Pass the exact returned holder/session/run identity to `write-guard`
41
+ for the recorded task, authority, owner, path and operation before writing.
42
+ 3. To pause, first persist the existing Task's checkpoint, including its exact HEAD and enough
43
+ context to continue. WC does not copy or verify that payload. Preserve uncommitted files,
44
+ unknown files and generated output. Inspect normal exit with the real full session selector
45
+ while its leases still exist. End through that same selector to record its allocations and
46
+ release only its own leases; inspect any incomplete result. Then use `task finish --outcome
47
+ checkpoint` with its content-addressed ID and HEAD and repeat the strict check. Releasing leases
48
+ individually before session end can lose the live selector's association: expected IDs add
49
+ proof obligations but cannot select a retained checkout or establish that association.
50
+ 4. A different client reloads the Task checkpoint, uses public `task show`/`status` to match the
51
+ original allocation, owner, path, HEAD and scope, and refuses drift. Use `task resume` with the
52
+ original owner, then acquire fresh entitlement for the new live executor and repeat the guard.
53
+ A stale recorded lease must be resolved through the original formal recovery; never steal it.
54
+ 5. When work is deliverable, use real Finalizer evidence and `task finish --outcome handoff`,
55
+ followed by the existing integration flow. A no-change finish is only for genuine unchanged
56
+ work. A checkpoint pause leaves work unfinished and retains the checkout.
57
+
58
+ See [everyday commands](daily-workflow.md) for exact examples and [operations](operations.md)
59
+ for the existing writer, cleanup, recovery and integration entrypoints.
60
+
61
+ ## End every allocation, and report failures accurately
62
+
63
+ Use the real client/session/holder/run selector with `worktree-session-end --check
64
+ --require-complete`. Add every allocation the Task/session knows it acquired with repeatable
65
+ `--expected-allocation-id`; these are additional proof obligations, not mutation selectors.
66
+ Inspect every live, previous and expected row and require `summary.terminal_complete=true`.
67
+ After preparation, end the session with the same selector and expected IDs using
68
+ `--require-complete` without `--check`. Reobserve any refusal through the public recovery guide.
69
+
70
+ An advisory exit 0 is not settlement evidence. A read-only guide may successfully describe a
71
+ blocker. `RESOURCE_WAIT` and an incomplete no-change release return 2; retain the original request
72
+ and any completed prefix. Retry only the pending formal step. Checkout settlement, business
73
+ completion and main publication each require their own evidence. A retained checkpoint can
74
+ settle an executor session while its business Task remains unfinished, but dirty or unclassified
75
+ files still require owner action and keep strict closeout incomplete. Checkpoint success alone
76
+ does not settle that obligation. Preserve the pending result when the original owner continues
77
+ the same Task in a new client; do not recreate an old holder to make it appear complete.
78
+
79
+ ## Run the offline continuation example
80
+
81
+ From the source checkout or the 1.32.0 source distribution, with WC 1.31.0 or later installed:
82
+
83
+ ```bash
84
+ python examples/client_continuation.py --workspace "$HOME/wc-client-example"
85
+ python examples/client_continuation.py --workspace "$HOME/wc-client-example" --resume
86
+ ```
87
+
88
+ The first invocation requires a new path under an existing parent. Each invocation is a real,
89
+ separate executor process with a different client/session/run identity. The example uses its
90
+ own HOME and a disposable repository, no remote, credentials, companion delivery tools or AI
91
+ service. It verifies original-task continuation, wrong-owner and competing-writer refusals,
92
+ two-checkout closeout, partial-release exit 2 and retry without duplicate completion.
93
+
94
+ The second invocation verifies that the new writer is permitted and the old client identity is
95
+ refused. It preserves the unfinished edit, unknown binary note, original checkpoint and its new
96
+ generation. Only the exact generated fixture created by the example is moved to its preservation
97
+ path; real unknown output still requires its owner's classification/preservation flow.
98
+ `PASS` means the protocol exercise completed. No business task is declared complete or published.
99
+ The original work stays `RETAINED`, with its branch, files and command/closeout evidence available.
100
+ Strict closeout correctly returns 2: the inspection checkout has complete release proof, while
101
+ the dirty unfinished checkout remains pending. Each executor formally ends its own writer session.
102
+ An existing workspace, identity/file drift or repeated resume is refused, preserving evidence.
103
+
104
+ This demonstrates two CLI consumers, not actual invocation or discovery by two AI vendors.
105
+ Vendor-specific discovery and live-client use require their own observed acceptance, as described
106
+ in [checks and deployment evidence](operations.md#checks-and-deployment).
107
+
108
+ ## Upgrade an existing managed installation
109
+
110
+ A public package installation in a new environment is separate from activation of a shared
111
+ Controller. Use the site's supported installer, published toolchain compatibility catalog,
112
+ consumer checks and rollout gate. Finish with installed smoke and the default installed doctor.
113
+ Do not repoint the active runtime, modify another client's session or widen accepted versions.
114
+
115
+ Ordinary `controller-activate activate` requires the target to descend from the active commit.
116
+ For an independent public export, 1.32.0 provides the explicit, receipt-bound
117
+ [`release-history-handover/v1` procedure](operations.md#moving-an-exact-exported-release-to-its-public-history).
118
+ It requires exact exported payloads, published release identities and current rollout gates;
119
+ ordinary bootstrap, copying the shared Skill or matching storage versions is not a substitute.
120
+ A catalog refusal blocks deployment while isolated protocol validation and source delivery can
121
+ continue. Record staged, activated and verified results separately.
@@ -0,0 +1,127 @@
1
+ # Everyday task operations
2
+
3
+ Use `worktree-controller task` for named feature/audit checkout tasks. It resolves the recorded
4
+ path, owner and record version, then calls the existing guarded lifecycle operation. The existing
5
+ low-level commands remain available. No separate task database or lifecycle is introduced.
6
+
7
+ These entrypoints require **WC 1.31.0, CLI 61, task_workflow_version 1**. Storage layout remains 5.
8
+ Check the installed `--version`, `capabilities --json` and `task --help` before using them. A newer
9
+ source checkout does not update a separately installed Controller. Governed installations still
10
+ need their normal compatibility, deployment and activation checks.
11
+
12
+ Start in an already governed repository: inspect `status`, `doctor` and its selected policy;
13
+ adopt existing checkouts explicitly. Examples below use `/project` as that repository's canonical
14
+ checkout. These commands operate locally and do not grant permission to publish or deploy.
15
+
16
+ ## See the current work
17
+
18
+ ```bash
19
+ worktree-controller task list --repo /project
20
+ worktree-controller task show --repo /project --task-key report-fix
21
+ ```
22
+
23
+ `list` shows live linked checkouts, their recorded owner, lifecycle, writer lease observation,
24
+ cleanliness and any checkpoint dependency. It is not a list of all business Tasks or queued
25
+ integrations. `show` explains the named checkout and its next formal step. After release, the
26
+ task key queries the original lifecycle history instead of inventing a new task.
27
+
28
+ Task keys can be ambiguous in imported or historical work. Mutations never pick a checkout by
29
+ owner, age or directory order. If multiple live checkouts share a key, select its exact `--path`
30
+ instead. Historical results retain their proof status and pagination; absence is not completion.
31
+
32
+ ## 1. Start and finish a task with no changes
33
+
34
+ ```bash
35
+ worktree-controller task start --repo /project --task-key report-fix \
36
+ --owner alice --scope src/reports
37
+
38
+ # An inspection that made no file changes and produced no task commit:
39
+ worktree-controller task finish --repo /project --task-key report-fix \
40
+ --owner alice --outcome no-change
41
+ ```
42
+
43
+ Start requires an explicit task key, owner and file scope. It defaults to feature role,
44
+ `authority_key=task_key`, module `task`, branch `task/<task-key>`, and the repository policy's
45
+ publication remote/branch as base. Override `--authority-key`, `--module`, `--branch`, `--base-ref`
46
+ or `--path` when your existing task requires different values. It does not fetch or substitute
47
+ another base when the policy base is unavailable locally. An existing live task is not duplicated.
48
+
49
+ Admission creates a checkout, **not write entitlement**. Before editing, bind the real writer
50
+ with the existing writer-session/lease flow and require `write-guard` to allow the operation.
51
+ Use the admitted path and declared task/authority. End only that writer's exact lease before
52
+ finishing. See [start or resume development](operations.md#start-or-resume-development).
53
+
54
+ The no-change finish first records the existing `complete-no-change` result, then attempts normal
55
+ guarded release. It retains the branch. A task commit or dirty worktree refuses no-change completion.
56
+ Unknown ignored files or registered resources can block the separate release step. In that case,
57
+ exit status is **2**, `TASK_RELEASE_BLOCKED` retains the completed prefix and provides a release
58
+ dry-run command. Preserve/classify those files through their existing owner flow. Repeating this
59
+ finish while `NO_CHANGE_COMPLETED` retries release without creating another completion receipt.
60
+ After successful release, use `task show`; another finish refuses the absent live allocation.
61
+
62
+ ## 2. Pause and continue the original task
63
+
64
+ First save a checkpoint in your existing Task system. Obtain its content-addressed ID and the
65
+ exact HEAD it records. WC records that owner's attestation; it does not create or verify the
66
+ checkpoint payload and does not copy uncommitted files into it. Then, after the writer ends:
67
+
68
+ ```bash
69
+ worktree-controller task finish --repo /project --task-key report-fix --owner alice \
70
+ --outcome checkpoint --checkpoint-id "$checkpoint_id" --checkpoint-head "$checkpoint_head" \
71
+ --waiting-on 'Awaiting source data'
72
+
73
+ worktree-controller task resume --repo /project --task-key report-fix --owner alice
74
+ ```
75
+
76
+ The checkpoint ID must use the existing `sha256:<64 hex>` or `art_<64 hex>` format. Its HEAD
77
+ must still match the checkout. Parking preserves the same checkout, branch, uncommitted files
78
+ and unknown files; work remains unfinished. Resume uses the same allocation and owner, without
79
+ creating a replacement task or writer lease. Obtain fresh write entitlement before editing again.
80
+ This entry does not release an unfinished checkout; that remains a separate reviewed owner flow.
81
+
82
+ ## 3. Hand off a completed change
83
+
84
+ Run appropriate tests/review and publish the task branch through your authorized Git Finalizer
85
+ flow. Use the actual returned record and the exact commit it binds; do not invent evidence.
86
+ After ending the exact writer:
87
+
88
+ ```bash
89
+ worktree-controller task finish --repo /project --task-key report-fix --owner alice \
90
+ --outcome handoff --finalizer-record-id "$finalizer_record_id" --commit "$commit"
91
+ ```
92
+
93
+ `TASK_HANDED_OFF` freezes the original scope and commit. It does not integrate or publish main,
94
+ release the checkout, declare the business Task complete or authorize a production deployment.
95
+ Continue the existing [handoff and integration](operations.md#handoff-and-integrate) flow, or use
96
+ the complete [first change example](first-change.md). Scope/commit drift and unknown files keep
97
+ their existing refusals. Active **or expired but still recorded** writer leases remain blocked;
98
+ these entrypoints never steal, renew or remove them.
99
+
100
+ ## Inspect a blocked integration
101
+
102
+ ```bash
103
+ worktree-controller task recover --repo /project --task-key original-integration-task
104
+ # Also works after its candidate checkout has been released:
105
+ worktree-controller task recover --repo /project --intent-id "$original_intent_id" --json
106
+ ```
107
+
108
+ `recover` is a read-only entry to the existing `recovery-guide`. It shows the recorded owner,
109
+ blockers and exact next formal command, retaining the original intent and evidence. For an
110
+ unchanged BLOCKED integration, the supported path starts with quarantine, then formal abort,
111
+ guarded release and retry of the original intent. Execute only the current owner-authorized
112
+ step, then run `recover` again: every transition can change the next command and record version.
113
+ Source/scope drift, dirty files, active publication and missing evidence still block recovery.
114
+ The entry does not run commands, edit Controller metadata or make a recovery plan executable.
115
+
116
+ ## Read results accurately
117
+
118
+ All actions accept `--json`. `list`, `show` and `recover` return 0 when observation succeeds,
119
+ including when that observation describes a blocker. This is not recovery or task completion.
120
+ Mutating actions return 0 only when the requested supported operation finishes; refusals,
121
+ `RESOURCE_WAIT` and incomplete release return 2. A waiting admission keeps its existing request;
122
+ inspect `admission-queue` instead of creating another task or branch.
123
+
124
+ Task selectors do not replace exact session closeout. At normal session exit, use the real
125
+ client/session/holder/run and every known expected allocation with `worktree-session-end --check
126
+ --require-complete`; read all rows and `summary.terminal_complete`. Business Task completion,
127
+ checkout release and published integration each require their own evidence.
@@ -6,6 +6,10 @@ pause after handoff and continue in a new process with the original task and int
6
6
  It creates a **local bare Git remote**, never contacts a hosting service, and needs no credentials.
7
7
  Use a disposable workspace; do not point it at an existing project.
8
8
 
9
+ This release uses the CLI 61 [task entrypoints](daily-workflow.md) for start, handoff and
10
+ recovery inspection; use WC 1.31.0 or newer with `task_workflow_version` 1. The underlying
11
+ writer, review, integration and closeout guards are the same as the low-level flow.
12
+
9
13
  ## Install the example's tools
10
14
 
11
15
  WC itself needs Linux, Python 3.12, Git and readable `/proc`. Install the released version using
@@ -4,9 +4,15 @@ Use this page to select a flow. The [CLI contract](../tool_cli_contract.json) ow
4
4
  capability and result schemas; installed `--help` owns the arguments available on this host.
5
5
  The [technical reference](reference.md) retains detailed protocols and compatibility history;
6
6
  the [getting started guide](getting-started.md) provides an isolated first run.
7
+ Client implementers can follow the [AI client integration guide](client-integration.md) and its
8
+ offline cross-client continuation example.
7
9
 
8
10
  ## Start or resume development
9
11
 
12
+ For everyday feature/audit work, the [task entrypoints](daily-workflow.md) resolve the original
13
+ checkout and record identity by task key, covering start, checkpoint/resume and finish. The
14
+ steps below remain the underlying authority and the route for advanced integration/recovery.
15
+
10
16
  For a worked local task, use [your first change](first-change.md). Core inspection/allocation needs
11
17
  WC and Git. The integration flow below additionally uses Git Finalizer and separate test and
12
18
  Snapshot evidence; policy schema 4+ requires both receipt identities explicitly. The worked example
@@ -256,6 +262,69 @@ stage, rollout and activation. CLI, capability and storage versions are independ
256
262
  Use the existing rollback flow; never repoint the active runtime by hand or activate another
257
263
  owner's unintegrated candidate. Finish with installed smoke, rollout/deployment checks and doctor.
258
264
 
265
+ ### Moving an exact exported release to its public history
266
+
267
+ Normal `activate` requires descendant history and normal `rollback` requires ancestor history.
268
+ An independent public export does not satisfy either rule. Since 1.32.0, the existing
269
+ `scripts/controller-activate` entry supports `release-history-handover/v1`; it does not modify
270
+ Controller lifecycle data, Git ancestry, admission policy or writer leases. Run the exact
271
+ published target's maintenance script, with the normal site configuration:
272
+
273
+ ```bash
274
+ export CONTROLLER_ROLLOUT_REPO=/absolute/public/canonical-checkout
275
+ export CONTROLLER_ROLLOUT_GIT_SOURCE=https://github.com/your-org/worktree-controller.git
276
+ export CONTROLLER_ROLLOUT_GOVERNED=/absolute/repo-one:/absolute/repo-two
277
+ controller-activate stage --version FULL_TARGET_OID --temp-helper /absolute/tool-temp-dir
278
+ controller-activate history-activate --version FULL_TARGET_OID \
279
+ --request-id original-export-request --handover-baseline FULL_PUBLIC_ROOT_OID \
280
+ --previous-source-repo /absolute/retained-original-source \
281
+ --consumer /absolute/installed-host-capability-command --dry-run
282
+ ```
283
+
284
+ Repeat `--consumer` for every effective external host and include the site's published
285
+ `--toolchain-compatibility /absolute/catalog.json` when one is configured. The optional checker
286
+ must understand CLI 61 and `controller-runtime-source/v1` (Git Finalizer 1.9.4 or later for the
287
+ bundled checker). Stage writes that immutable, owned source manifest beside the runtime; it binds
288
+ the exact commit, primary source checkout, Git common directory, history root, contract hash and
289
+ Skill hash. Legacy installations without it retain their existing source selection. Invalid or
290
+ changed manifests must fail rather than silently fall back. Keep both source histories and both
291
+ installed runtimes available for verification and rollback.
292
+
293
+ The gate requires a root release whose runtime, packaging, maintenance scripts and complete Skill
294
+ payload exactly equal the original frozen predecessor. Both public baseline and target must have
295
+ live matching stable release tags. The target must descend from that baseline and preserve storage,
296
+ metadata and writer-lease formats and installed Skill bytes. This entry cannot combine namespace,
297
+ policy, Skill or cleanup migrations. Existing resource, metadata and consumer gates still run.
298
+ Live compatible writer sessions may continue; incompatible, stale or incomplete evidence is not
299
+ made eligible by this procedure.
300
+
301
+ Inspect the single JSON result. Dry-run exit 0 means `plan_ready=true`, **not** completed activation.
302
+ Apply the identical request without `--dry-run`, adding its exact `--expected-plan-id`. The plan
303
+ binds the current active pointer, scope and compatibility catalog. The producer saves an immutable
304
+ receipt before switching. Preserve its `receipt` and `receipt_sha256` from the result. On interruption
305
+ or an uncertain result, inspect the original request and active pin before retrying; do not invent
306
+ another request identity. Resume using only the original receipt and SHA256:
307
+
308
+ ```bash
309
+ controller-activate history-activate --history-receipt /absolute/original-receipt.json \
310
+ --history-receipt-sha256 ORIGINAL_SHA256 --consumer /absolute/installed-host-capability-command \
311
+ --dry-run
312
+ controller-activate history-rollback --history-receipt /absolute/original-receipt.json \
313
+ --history-receipt-sha256 ORIGINAL_SHA256 --consumer /absolute/installed-host-capability-command \
314
+ --dry-run
315
+ ```
316
+
317
+ For either action, inspect a fresh plan and apply with its exact plan ID. Keep the original governed
318
+ repositories and consumers; adding current checks is allowed, omitting original checks is refused.
319
+ An explicit rollback request fences subsequent forward reuse of that request. Unknown pending files
320
+ are preserved. An interrupted producer write is preserved byte for byte before an exact retry.
321
+ Exit 0 with `operation_complete=true` proves the requested active pin and postchecks; a repeated
322
+ verified operation may report `activation_performed=false`. Refusal exits 2. Failed activation
323
+ followed by verified predecessor restoration exits 3 with `operation_complete=false`; this is a
324
+ failure, not successful upgrade. If restoration itself cannot pass current gates, the entry reports
325
+ the observed active commit and preserves evidence for the original recovery. Finish with installed
326
+ smoke and the default deployment doctor; runtime activation never grants business release approval.
327
+
259
328
  For each external consumer, distinguish three outcomes:
260
329
 
261
330
  | Check | What it proves |
@@ -1,5 +1,8 @@
1
1
  # Technical reference
2
2
 
3
+ For the task-oriented CLI 61 entrypoints, see [everyday task operations](daily-workflow.md).
4
+ They delegate to the existing lifecycle guards and introduce no additional stored state.
5
+
3
6
  For a first run, use the [getting started guide](getting-started.md). This reference retains
4
7
  the detailed contracts, historical compatibility notes and benchmark evidence previously in the README.
5
8
  The [CLI contract](../tool_cli_contract.json) is authoritative for exact interfaces.
@@ -31,7 +34,9 @@ for core inspection/allocation; selecting a delivery flow can add explicit evide
31
34
  Repositories created under the current namespace never invoke it.
32
35
  - **Maintainer deployment.** `scripts/controller-activate` and `scripts/controller-runtime` are the
33
36
  source-owned runtime activation and start entry points used by a maintainer's host; they are not
34
- required to install or use the published package.
37
+ required to install or use the published package. Since 1.32.0, their explicit
38
+ `release-history-handover/v1` and `controller-runtime-source/v1` contracts support exact public
39
+ exports and immutable runtime provenance; see the [maintenance procedure](operations.md#moving-an-exact-exported-release-to-its-public-history).
35
40
 
36
41
  From 1.30.1, a completed cleanup at a retained source may survive normal park/resume
37
42
  cycles followed by a formal handoff of the same HEAD and owner. Verification requires
@@ -99,7 +99,11 @@ def main():
99
99
  (workspace / name).write_text(json.dumps(value, indent=2) + "\n")
100
100
 
101
101
  def wc(command, *arguments):
102
- value = json.loads(run(controller, command, "--repo", repo, "--json", *arguments))
102
+ if command == "task":
103
+ action, *arguments = arguments
104
+ value = json.loads(run(controller, command, action, "--repo", repo, "--json", *arguments))
105
+ else:
106
+ value = json.loads(run(controller, command, "--repo", repo, "--json", *arguments))
103
107
  require(not value.get("errors"), f"Controller refused {command}; see commands.jsonl")
104
108
  print(f"{command}: {(value.get('decision') or {}).get('code', 'observed')}", flush=True)
105
109
  return value
@@ -146,11 +150,10 @@ def main():
146
150
  "--message", "Initialize local demo", "--", "README.md", ".agents/worktree-policy.toml")
147
151
  wc("adopt", "--path", repo, "--task-key", "demo-control", "--authority-key", "demo-control",
148
152
  "--module", "demo", "--role", "control-plane", "--owner", OWNER, "--lifecycle", "ACTIVE")
149
- request = ["--task-key", "demo-change", "--authority-key", "demo-change", "--module", "demo", "--role", "feature"]
150
- require(wc("plan", *request)["decision"]["code"] == "CREATE_ALLOWED", "admission refused")
151
- acquired = wc("acquire", *request, "--owner", OWNER, "--branch", "demo/change",
152
- "--base-ref", "main", "--path", source, "--scope", "README.md")
153
- allocation = acquired["decision"]["allocation_id"]
153
+ acquired = wc("task", "start", "--task-key", "demo-change", "--module", "demo",
154
+ "--owner", OWNER, "--branch", "demo/change", "--base-ref", "main",
155
+ "--path", source, "--scope", "README.md")
156
+ allocation = acquired["decision"]["operation"]["allocation_id"]
154
157
  lease = wc("writer-lease-acquire", "--path", source, "--owner", OWNER,
155
158
  "--holder-pid", os.getpid(), *identity)["decision"]
156
159
  guard = wc("write-guard", "--path", source, "--task-key", "demo-change",
@@ -168,8 +171,8 @@ def main():
168
171
  wc("writer-lease-release", "--path", source, "--lease-id", lease["lease_id"],
169
172
  "--holder-pid", holder["pid"], "--holder-boot-id", holder["boot_id"],
170
173
  "--holder-start-ticks", holder["start_ticks"], *identity)
171
- wc("handoff", "--path", source, "--expected-record-version", row(source)["record_version"],
172
- "--kind", "integration-ready", "--commit", commit, "--finalizer-commit", commit,
174
+ wc("task", "finish", "--task-key", "demo-change", "--owner", OWNER,
175
+ "--outcome", "handoff", "--commit", commit,
173
176
  "--finalizer-record-id", workspace / "source-finalizer.json")
174
177
  queued = wc("integration-enqueue", "--task-key", "demo-integration", "--authority-key",
175
178
  "demo-integration", "--module", "demo", "--owner", OWNER,
@@ -197,7 +200,7 @@ def main():
197
200
  require(not run("git", "-C", path, "status", "--porcelain"),
198
201
  f"uncommitted files remain in {path}; preserve them and follow recovery-guide")
199
202
 
200
- guide = wc("recovery-guide", "--intent-id", checkpoint["intent_id"])["decision"]
203
+ guide = wc("task", "recover", "--intent-id", checkpoint["intent_id"])["decision"]["guidance"]
201
204
  if guide.get("terminal_status") != "PUBLISHED_RELEASED":
202
205
  require(guide["intent"]["state"] in {"QUEUED", "PREPARING_INTEGRATION"},
203
206
  "this demo resumes only queued or unchanged claimed work; follow recovery-guide")