worktree-controller 1.32.4__tar.gz → 1.32.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 (79) hide show
  1. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/PKG-INFO +5 -5
  2. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/README.md +4 -4
  3. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/docs/architecture.md +4 -0
  4. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/docs/publishing.md +13 -0
  5. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/docs/roadmap.md +11 -6
  6. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/pyproject.toml +1 -1
  7. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/pyproject.toml.orig +1 -1
  8. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/__init__.py +1 -1
  9. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/integration_retry.py +5 -4
  10. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/lifecycle.py +2 -19
  11. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/semantics.py +21 -0
  12. {worktree_controller-1.32.4 → worktree_controller-1.32.5/src/worktree_controller}/tool_cli_contract.json +1 -1
  13. {worktree_controller-1.32.4/src/worktree_controller → worktree_controller-1.32.5}/tool_cli_contract.json +1 -1
  14. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/LICENSE +0 -0
  15. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/docs/client-integration.md +0 -0
  16. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/docs/daily-workflow.md +0 -0
  17. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/docs/first-change.md +0 -0
  18. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/docs/getting-started.md +0 -0
  19. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/docs/integration-boundaries.md +0 -0
  20. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/docs/operations.md +0 -0
  21. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/docs/reference.md +0 -0
  22. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/docs/scope.md +0 -0
  23. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/examples/change_task.py +0 -0
  24. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/examples/client_continuation.py +0 -0
  25. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/examples/quickstart.py +0 -0
  26. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/activation_layout.py +0 -0
  27. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/branch_retirement.py +0 -0
  28. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/canonical_refresh.py +0 -0
  29. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/canonical_transition.py +0 -0
  30. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/cleanup_attempts.py +0 -0
  31. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/cleanup_evidence.py +0 -0
  32. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/cleanup_recovery.py +0 -0
  33. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/cli.py +0 -0
  34. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/controller.py +0 -0
  35. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/convergence.py +0 -0
  36. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/delivered_closeout.py +0 -0
  37. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/disposable.py +0 -0
  38. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/environment.py +0 -0
  39. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/frozen_recovery.py +0 -0
  40. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/git_backend.py +0 -0
  41. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/governance.py +0 -0
  42. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/hardlinks.py +0 -0
  43. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/integration_cleanup.py +0 -0
  44. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/integration_conflict.py +0 -0
  45. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/keyed_document_scope.py +0 -0
  46. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/lifecycle_history.py +0 -0
  47. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/lifecycle_observation.py +0 -0
  48. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/metadata_codec.py +0 -0
  49. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/metadata_relocation.py +0 -0
  50. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/models.py +0 -0
  51. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/mount_diagnostics.py +0 -0
  52. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/multiple_cleanup_recovery.py +0 -0
  53. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/namespace_migration.py +0 -0
  54. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/native_session_recovery.py +0 -0
  55. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/owner_actions.py +0 -0
  56. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/policy.py +0 -0
  57. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/preservation.py +0 -0
  58. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/preserved_cleanup.py +0 -0
  59. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/publication_execution.py +0 -0
  60. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/reconciler.py +0 -0
  61. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/record_updates.py +0 -0
  62. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/recovery_guidance.py +0 -0
  63. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/registration_backfill.py +0 -0
  64. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/registration_prune.py +0 -0
  65. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/release_intents.py +0 -0
  66. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/rendering.py +0 -0
  67. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/resource_admission.py +0 -0
  68. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/retirement_adapters.py +0 -0
  69. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/retirement_execution.py +0 -0
  70. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/session.py +0 -0
  71. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/session_admission.py +0 -0
  72. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/source_cleanup.py +0 -0
  73. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/source_preservation.py +0 -0
  74. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/source_recovery.py +0 -0
  75. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/store.py +0 -0
  76. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/task_workflow.py +0 -0
  77. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/transaction_scope.py +0 -0
  78. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/src/worktree_controller/writer_lease.py +0 -0
  79. {worktree_controller-1.32.4 → worktree_controller-1.32.5}/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.4
3
+ Version: 1.32.5
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.2 · Linux · Python 3.12 · Apache-2.0**
26
+ **Current release: 1.32.5 · 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.2
35
+ python -m pip install worktree-controller==1.32.5
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.2 uses CLI contract **61** and storage layout **5**.
44
+ Software version 1.32.5 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.2
53
+ git checkout v1.32.5
54
54
  python examples/quickstart.py --workspace "$HOME/wc-first-run"
55
55
  ```
56
56
 
@@ -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.2 · Linux · Python 3.12 · Apache-2.0**
9
+ **Current release: 1.32.5 · 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.2
18
+ python -m pip install worktree-controller==1.32.5
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.2 uses CLI contract **61** and storage layout **5**.
27
+ Software version 1.32.5 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.2
36
+ git checkout v1.32.5
37
37
  python examples/quickstart.py --workspace "$HOME/wc-first-run"
38
38
  ```
39
39
 
@@ -83,3 +83,7 @@ mutation helpers, clock, lock scope, cancellation and history append unchanged.
83
83
  uses the same query directly; lifecycle retains its existing internal aliases. A changed HEAD
84
84
  or record version still renews immediately, and repeated unchanged expiries retain the existing
85
85
  one-day backoff cap. This extraction changes no CLI, capability or storage contract.
86
+
87
+ Scope digest and overlap queries live in `semantics` alongside scope normalization. Integration
88
+ retry calls these shared pure helpers directly; lifecycle retains compatibility aliases. Their
89
+ serialization, empty-scope interpretation and parent/child path rules remain unchanged.
@@ -102,3 +102,16 @@ Receipts distinguish a read-only audit, `PUBLISHED_VERIFIED`, and `FRESH_INSTALL
102
102
  Skipped tests remain skipped. Local installation or activation of a maintainer's WC runtime is a
103
103
  separate operation; publishing a package does not update that runtime or authorize a production
104
104
  release in any repository governed by WC.
105
+
106
+ ## Publication visibility
107
+
108
+ Successful writes can precede their visibility through GitHub or PyPI queries. After a successful
109
+ create, upload or publish command, the publisher polls only the missing observation. All phases
110
+ share one five-minute monotonic deadline, including draft, asset, PyPI and public-release visibility.
111
+ Each network command retains its own timeout; an in-flight request can finish after that deadline.
112
+ Metadata requests ask caches to revalidate. This does not guarantee immediate upstream visibility.
113
+
114
+ Every poll rechecks the immutable tag and main containment; normal inventory and byte/hash checks
115
+ remain active. Command errors, unknown assets, yanked files and identity/checksum drift stop
116
+ immediately. Polls never repeat writes. If visibility still times out, the job fails and keeps the
117
+ original bundle and current release. Audit destinations and rerun failed jobs in the same run as above.
@@ -5,12 +5,12 @@ direction. Each stage needs its own tested deliverable; later ideas are not curr
5
5
 
6
6
  ## Current baseline
7
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.
8
+ WC 1.32.5 retains CLI contract 61 and storage layout 5. The scope and architecture documents
9
+ are already on main. Previous extractions reduced private cross-module imports from 93 to
10
+ 82 and then 80. This batch moves pure scope hashing/overlap queries into `semantics`, reducing
11
+ the baseline to 78. It retains lifecycle mutation helpers, clocks and internal aliases.
12
12
 
13
- GF 1.9.7 already consumes SR's public read API and WC's versioned publication/retirement
13
+ GF 1.9.8 already consumes SR's public read API and WC's versioned publication/retirement
14
14
  protocols. CL 1.3.10 and SR 2.5.12 already use main on both hosting platforms. These completed
15
15
  items are not prerequisites still waiting to happen.
16
16
 
@@ -24,7 +24,7 @@ acceptance gates, and historical temporary-file impact. No historical evidence i
24
24
  | --- | --- | --- | --- |
25
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
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 |
27
+ | Shared quality checks: delivered | CL/SR adopt release-tools with a reviewed full commit pin | Both hosted parallel pilots and final three-version checks passed; SR retains its package check | Restore the pinned original consumer workflow; PyPI/Gitea flows remain owned by consumers |
28
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
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
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 |
@@ -44,3 +44,8 @@ Do not introduce a shared runtime Python dependency into CL/SR, merge the tools,
44
44
  Python floor, move host-specific defaults without migration, or replace existing WC/GF protocols.
45
45
  GitHub-first release consolidation and a future toolchain repository remain design decisions,
46
46
  not permission to disable existing Gitea delivery or platform controls.
47
+
48
+ This maintenance batch moves pure scope hashing and overlap queries to `semantics`, lowering
49
+ the private-import baseline from 80 to 78. Publication metadata readback now shares a bounded
50
+ visibility window; exact bytes, identities, failed-command outcomes and same-bundle recovery stay
51
+ mandatory. CL/SR shared quality checks have passed their hosted parallel and final matrices.
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "worktree-controller"
7
- version = "1.32.4"
7
+ version = "1.32.5"
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.4"
7
+ version = "1.32.5"
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.4"
3
+ __version__ = "1.32.5"
@@ -17,6 +17,8 @@ from .semantics import (
17
17
  integration_intent_abandoned,
18
18
  integration_prerequisite,
19
19
  integration_queue_order,
20
+ scope_digest,
21
+ scopes_overlap,
20
22
  unallocated_integration_conflict,
21
23
  )
22
24
  from .store import MetadataStore
@@ -57,7 +59,7 @@ def _sources(
57
59
  *,
58
60
  require_idle: bool = True,
59
61
  ) -> dict[str, Any]:
60
- from .lifecycle import _resolve_integration_sources, _scope_digest
62
+ from .lifecycle import _resolve_integration_sources
61
63
 
62
64
  observed = _resolve_integration_sources(
63
65
  repository,
@@ -74,7 +76,7 @@ def _sources(
74
76
  intent.source_finalizer_record_ids,
75
77
  intent.source_snapshot_ids,
76
78
  )
77
- if observed != expected or _scope_digest(intent.scope_paths) != intent.scope_digest:
79
+ if observed != expected or scope_digest(intent.scope_paths) != intent.scope_digest:
78
80
  raise ControllerError("SOURCE_EVIDENCE_MISMATCH", "retry cannot replace source or scope")
79
81
  evidence = {}
80
82
  for allocation, branch, head in zip(
@@ -227,7 +229,6 @@ def _prerequisite(
227
229
  parent: IntegrationIntent,
228
230
  child: IntegrationIntent,
229
231
  ) -> dict[str, Any]:
230
- from .lifecycle import _scopes_overlap
231
232
  from .semantics import effective_intent_state
232
233
 
233
234
  if (
@@ -258,7 +259,7 @@ def _prerequisite(
258
259
  and other.allocation_id is not None
259
260
  and effective_intent_state(snapshot, other) not in {"RELEASED", "ABANDONED"}
260
261
  and other.queue_sequence > parent.queue_sequence
261
- and _scopes_overlap(other.scope_paths, child.scope_paths)
262
+ and scopes_overlap(other.scope_paths, child.scope_paths)
262
263
  for other in snapshot.integration_intents.values()
263
264
  ):
264
265
  raise ControllerError(
@@ -100,6 +100,8 @@ from .semantics import integration_reconciliation as _integration_reconciliation
100
100
  from .semantics import managed_record as _managed_record
101
101
  from .semantics import publication_receipt_lease_released as _publication_receipt_lease_released
102
102
  from .semantics import record_for as _record_for
103
+ from .semantics import scope_digest as _scope_digest
104
+ from .semantics import scopes_overlap as _scopes_overlap
103
105
  from .store import (
104
106
  INTEGRATION_INTENT_CONTRACT_VERSION,
105
107
  INTEGRATION_INTENT_SCHEMA_VERSION,
@@ -152,31 +154,12 @@ def _crash_point(name: str) -> None:
152
154
  os._exit(97)
153
155
 
154
156
 
155
- def _scope_digest(scope_paths: tuple[str, ...]) -> str:
156
- encoded = json.dumps(list(scope_paths), ensure_ascii=True, separators=(",", ":"))
157
- return hashlib.sha256(encoded.encode("utf-8")).hexdigest()
158
-
159
-
160
157
  def _intent_order(intent: IntegrationIntent) -> tuple[int, int | str, str]:
161
158
  if intent.queue_sequence > 0:
162
159
  return (1, intent.queue_sequence, intent.intent_id)
163
160
  return (0, intent.enqueued_at, intent.intent_id)
164
161
 
165
162
 
166
- def _scopes_overlap(left: tuple[str, ...], right: tuple[str, ...]) -> bool:
167
- if not left or not right:
168
- return True
169
- for left_path in left:
170
- for right_path in right:
171
- if (
172
- left_path == right_path
173
- or left_path.startswith(f"{right_path}/")
174
- or right_path.startswith(f"{left_path}/")
175
- ):
176
- return True
177
- return False
178
-
179
-
180
163
  def _released_intent_evidence(
181
164
  snapshot: MetadataSnapshot,
182
165
  intent: IntegrationIntent,
@@ -2,6 +2,8 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import hashlib
6
+ import json
5
7
  from dataclasses import replace
6
8
  from pathlib import Path, PurePosixPath
7
9
  from typing import Any
@@ -204,6 +206,25 @@ def integration_queue_order(
204
206
  return (0, anchor.enqueued_at, phase, intent.intent_id)
205
207
 
206
208
 
209
+ def scope_digest(scope_paths: tuple[str, ...]) -> str:
210
+ encoded = json.dumps(list(scope_paths), ensure_ascii=True, separators=(",", ":"))
211
+ return hashlib.sha256(encoded.encode("utf-8")).hexdigest()
212
+
213
+
214
+ def scopes_overlap(left: tuple[str, ...], right: tuple[str, ...]) -> bool:
215
+ if not left or not right:
216
+ return True
217
+ for left_path in left:
218
+ for right_path in right:
219
+ if (
220
+ left_path == right_path
221
+ or left_path.startswith(f"{right_path}/")
222
+ or right_path.startswith(f"{left_path}/")
223
+ ):
224
+ return True
225
+ return False
226
+
227
+
207
228
  def normalize_scope_paths(values: tuple[str, ...]) -> tuple[str, ...]:
208
229
  normalized: set[str] = set()
209
230
  for raw in values:
@@ -1071,7 +1071,7 @@
1071
1071
  "session_launcher_entrypoint": "worktree-session",
1072
1072
  "session_entrypoint": "worktree-session-end",
1073
1073
  "tool_name": "worktree-controller",
1074
- "tool_version": "1.32.4",
1074
+ "tool_version": "1.32.5",
1075
1075
  "delivered_closeout_version": 1,
1076
1076
  "retained_archive_version": 1,
1077
1077
  "retention_convergence_version": 2,
@@ -1071,7 +1071,7 @@
1071
1071
  "session_launcher_entrypoint": "worktree-session",
1072
1072
  "session_entrypoint": "worktree-session-end",
1073
1073
  "tool_name": "worktree-controller",
1074
- "tool_version": "1.32.4",
1074
+ "tool_version": "1.32.5",
1075
1075
  "delivered_closeout_version": 1,
1076
1076
  "retained_archive_version": 1,
1077
1077
  "retention_convergence_version": 2,