marsh-lib 0.3.2__tar.gz → 0.3.3__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 (82) hide show
  1. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/PKG-INFO +1 -1
  2. marsh_lib-0.3.3/docs/releases/v0.3.3.md +33 -0
  3. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/pyproject.toml +1 -1
  4. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/core/serialization.py +4 -26
  5. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/docker/docker_executor.py +5 -1
  6. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/.circleci/config.yml +0 -0
  7. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/.github/ISSUE_TEMPLATE/bug-report.md +0 -0
  8. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  9. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/.github/ISSUE_TEMPLATE/other.md +0 -0
  10. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/.github/pull_request_template.md +0 -0
  11. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/.github/workflows/docker-integration.yml +0 -0
  12. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/.github/workflows/release-rehearsal.yml +0 -0
  13. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/.github/workflows/release.yml +0 -0
  14. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/.github/workflows/ssh-integration.yml +0 -0
  15. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/.github/workflows/test.yml +0 -0
  16. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/.gitignore +0 -0
  17. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/LICENSE +0 -0
  18. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/README.md +0 -0
  19. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/Taskfile.yml +0 -0
  20. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/docs/P0_REPOSITORY_AUDIT.md +0 -0
  21. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/docs/P6_UX_COMPOSITION_EVALUATION.md +0 -0
  22. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/docs/api-migration.md +0 -0
  23. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/docs/architecture.md +0 -0
  24. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/docs/v0.3.2-test-portability.md +0 -0
  25. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/docs/workflow-guide.md +0 -0
  26. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/run_act.sh +0 -0
  27. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/run_pytest.sh +0 -0
  28. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/run_tests_with_sysbox.sh +0 -0
  29. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/__init__.py +0 -0
  30. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/bash/__init__.py +0 -0
  31. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/bash/bash_factory.py +0 -0
  32. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/bash/bash_grammar.py +0 -0
  33. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/bash/bash_runner_decorators.py +0 -0
  34. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/bash/bash_script.py +0 -0
  35. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/constants.py +0 -0
  36. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/core/__init__.py +0 -0
  37. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/core/authenticator.py +0 -0
  38. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/core/cache.py +0 -0
  39. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/core/cmd_run_decorator.py +0 -0
  40. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/core/cmd_runner_spec.py +0 -0
  41. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/core/command_grammar.py +0 -0
  42. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/core/configuration.py +0 -0
  43. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/core/connector.py +0 -0
  44. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/core/conveyor.py +0 -0
  45. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/core/dag_bridge.py +0 -0
  46. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/core/diagnostics.py +0 -0
  47. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/core/domain.py +0 -0
  48. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/core/executor.py +0 -0
  49. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/core/expression.py +0 -0
  50. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/core/observability.py +0 -0
  51. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/core/policies.py +0 -0
  52. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/core/providers.py +0 -0
  53. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/core/runtime.py +0 -0
  54. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/core/script.py +0 -0
  55. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/core/validation.py +0 -0
  56. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/dag/__init__.py +0 -0
  57. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/dag/dag.py +0 -0
  58. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/dag/node.py +0 -0
  59. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/dag/startable.py +0 -0
  60. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/docker/__init__.py +0 -0
  61. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/docker/docker_command_grammar.py +0 -0
  62. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/exceptions.py +0 -0
  63. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/logger.py +0 -0
  64. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/modifier_functions/__init__.py +0 -0
  65. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/modifier_functions/case_conversion.py +0 -0
  66. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/modifier_functions/readers.py +0 -0
  67. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/powershell/__init__.py +0 -0
  68. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/processor_functions/__init__.py +0 -0
  69. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/processor_functions/printers.py +0 -0
  70. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/processor_functions/raisers.py +0 -0
  71. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/processor_functions/redirections.py +0 -0
  72. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/providers/__init__.py +0 -0
  73. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/runtime/__init__.py +0 -0
  74. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/signals.py +0 -0
  75. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/ssh/__init__.py +0 -0
  76. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/ssh/ssh_command_grammar.py +0 -0
  77. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/ssh/ssh_connector.py +0 -0
  78. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/ssh/ssh_factory.py +0 -0
  79. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/utils/__init__.py +0 -0
  80. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/utils/output_streams.py +0 -0
  81. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/src/marsh/workflow/__init__.py +0 -0
  82. {marsh_lib-0.3.2 → marsh_lib-0.3.3}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: marsh-lib
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: Lightweight, extensible Python library for building, managing, and executing command workflows.
5
5
  Project-URL: Repository, https://github.com/CedricAnover/marsh
6
6
  Author-email: Cedric Anover <cedric.anover@hotmail.com>
@@ -0,0 +1,33 @@
1
+ # v0.3.3 — Kernel Contract Stabilization
2
+
3
+ ## Summary
4
+
5
+ v0.3.3 stabilizes the smallest Marsh execution kernel before further provider and concurrency work.
6
+
7
+ ## Contract changes
8
+
9
+ - `plan_workflow()` is the canonical dependency-planning semantic owner.
10
+ - `validate_workflow()` delegates to canonical planning instead of maintaining a second topological implementation.
11
+ - Deterministic task order and initial readiness are regression-tested.
12
+ - Scheduler and Machine replacement are covered by conformance tests.
13
+ - Lifecycle, failure, timeout, cancellation, dependency-skip, and fail-fast semantics are regression-tested.
14
+ - Modern namespace compatibility remains covered without removing legacy APIs.
15
+ - Observer failures remain non-authoritative and cannot change execution outcomes.
16
+
17
+ ## Reliability fix
18
+
19
+ - Hardened Docker container cleanup against auto-remove races that can surface as stale-container `404 Not Found` errors.
20
+
21
+ ## Verification
22
+
23
+ - CircleCI: Python 3.10, 3.11, 3.12
24
+ - CircleCI: lint and wheel build
25
+ - CircleCI: Docker integration
26
+ - CircleCI: SSH integration
27
+ - GitHub Actions: Linux test/coverage
28
+ - GitHub Actions: native Windows portability
29
+ - GitHub Actions: Docker integration smoke
30
+
31
+ ## Scope guardrails
32
+
33
+ No new runtime dependency, concurrency engine, remote execution model, workflow IR expansion, or provider architecture expansion was introduced in this release.
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "marsh-lib"
7
- version = "0.3.2"
7
+ version = "0.3.3"
8
8
  description = "Lightweight, extensible Python library for building, managing, and executing command workflows."
9
9
  authors = [{ name = "Cedric Anover", email = "cedric.anover@hotmail.com" }]
10
10
  license = { text = "MIT" }
@@ -1,39 +1,17 @@
1
1
  """Workflow validation and deterministic serialization."""
2
2
 
3
3
  import json
4
- from heapq import heappop, heappush
5
4
  from typing import Any, Mapping
6
5
 
7
6
  from marsh.core.configuration import normalize_workflow
8
7
  from marsh.core.domain import Workflow
8
+ from marsh.core.runtime import plan_workflow
9
9
 
10
10
 
11
11
  def validate_workflow(workflow: Workflow | Mapping[str, Any]) -> tuple[str, ...]:
12
- workflow = normalize_workflow(workflow)
13
- tasks = {task.id: task for task in workflow.tasks}
14
- indegree = {task_id: 0 for task_id in tasks}
15
- dependents = {task_id: [] for task_id in tasks}
16
- for task in workflow.tasks:
17
- for dependency in task.dependencies:
18
- if dependency not in tasks:
19
- raise ValueError(f"task {task.id!r} has unknown dependencies: {dependency}")
20
- indegree[task.id] += 1
21
- dependents[dependency].append(task.id)
22
- ready = []
23
- for task_id, degree in indegree.items():
24
- if degree == 0:
25
- heappush(ready, task_id)
26
- order = []
27
- while ready:
28
- task_id = heappop(ready)
29
- order.append(task_id)
30
- for dependent in sorted(dependents[task_id]):
31
- indegree[dependent] -= 1
32
- if indegree[dependent] == 0:
33
- heappush(ready, dependent)
34
- if len(order) != len(tasks):
35
- raise ValueError("workflow contains a dependency cycle")
36
- return tuple(order)
12
+ """Validate dependencies using the canonical planning semantic owner."""
13
+
14
+ return plan_workflow(normalize_workflow(workflow)).order
37
15
 
38
16
 
39
17
  def _data(value: Any) -> Any:
@@ -103,7 +103,11 @@ class DockerContainer:
103
103
  self._timer.cancel()
104
104
 
105
105
  # Remove the Container
106
- all_containers: list[Container] = self._client.containers.list(all=True)
106
+ try:
107
+ all_containers: list[Container] = self._client.containers.list(all=True)
108
+ except NotFound:
109
+ all_containers = []
110
+
107
111
  for container in all_containers:
108
112
  if container.name == self._name:
109
113
  try:
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes