dominus-sdk-python 9.0.12__tar.gz → 9.0.13__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 (87) hide show
  1. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/PKG-INFO +4 -4
  2. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/README.md +3 -3
  3. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/__init__.py +1 -1
  4. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/authority.py +46 -2
  5. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus_sdk_python.egg-info/PKG-INFO +4 -4
  6. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/pyproject.toml +1 -1
  7. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_authority_public_vocabulary.py +85 -0
  8. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/config/__init__.py +0 -0
  9. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/config/endpoints.py +0 -0
  10. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/contract/__init__.py +0 -0
  11. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/contract/envelope.py +0 -0
  12. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/contract/projections.py +0 -0
  13. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/errors.py +0 -0
  14. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/helpers/__init__.py +0 -0
  15. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/helpers/auth.py +0 -0
  16. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/helpers/cache.py +0 -0
  17. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/helpers/console_capture.py +0 -0
  18. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/helpers/core.py +0 -0
  19. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/helpers/crypto.py +0 -0
  20. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/helpers/sse.py +0 -0
  21. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/helpers/trace.py +0 -0
  22. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/__init__.py +0 -0
  23. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/admin.py +0 -0
  24. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/ai.py +0 -0
  25. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/artifacts.py +0 -0
  26. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/auth.py +0 -0
  27. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/browser.py +0 -0
  28. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/coder.py +0 -0
  29. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/courier.py +0 -0
  30. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/db.py +0 -0
  31. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/ddl.py +0 -0
  32. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/deployer.py +0 -0
  33. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/fastapi.py +0 -0
  34. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/files.py +0 -0
  35. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/health.py +0 -0
  36. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/jobs.py +0 -0
  37. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/logs.py +0 -0
  38. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/platform.py +0 -0
  39. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/portal.py +0 -0
  40. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/processor.py +0 -0
  41. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/publisher.py +0 -0
  42. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/recipes.py +0 -0
  43. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/redis.py +0 -0
  44. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/secrets.py +0 -0
  45. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/secure.py +0 -0
  46. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/stash.py +0 -0
  47. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/sync.py +0 -0
  48. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/usage.py +0 -0
  49. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/warden.py +0 -0
  50. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/namespaces/workflow.py +0 -0
  51. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/py.typed +0 -0
  52. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/services/__init__.py +0 -0
  53. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus/start.py +0 -0
  54. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus_sdk_python.egg-info/SOURCES.txt +0 -0
  55. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus_sdk_python.egg-info/dependency_links.txt +0 -0
  56. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus_sdk_python.egg-info/requires.txt +0 -0
  57. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/dominus_sdk_python.egg-info/top_level.txt +0 -0
  58. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/setup.cfg +0 -0
  59. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_ai_namespace.py +0 -0
  60. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_artifacts_namespace.py +0 -0
  61. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_auth.py +0 -0
  62. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_browser_namespace.py +0 -0
  63. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_contract.py +0 -0
  64. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_control_plane_namespaces.py +0 -0
  65. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_error_recovery_action.py +0 -0
  66. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_errors.py +0 -0
  67. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_errors_aliases.py +0 -0
  68. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_flat_commands.py +0 -0
  69. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_health.py +0 -0
  70. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_logs.py +0 -0
  71. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_namespace_barrel_exports.py +0 -0
  72. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_platform_coder_namespaces.py +0 -0
  73. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_provisioning_parity.py +0 -0
  74. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_public_exports.py +0 -0
  75. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_publisher_namespace.py +0 -0
  76. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_readme_quickstart_catalog.py +0 -0
  77. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_recipes_namespace.py +0 -0
  78. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_recipes_stash_routing.py +0 -0
  79. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_secrets_presence_contract.py +0 -0
  80. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_stash_artifact_facade.py +0 -0
  81. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_stash_tables_namespace.py +0 -0
  82. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_token_precedence.py +0 -0
  83. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_transport_compat.py +0 -0
  84. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_usage_namespace.py +0 -0
  85. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_version_consistency.py +0 -0
  86. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_workflow_lifecycle.py +0 -0
  87. {dominus_sdk_python-9.0.12 → dominus_sdk_python-9.0.13}/tests/test_workflow_refs.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dominus-sdk-python
3
- Version: 9.0.12
3
+ Version: 9.0.13
4
4
  Summary: Python SDK for the Dominus gateway-first platform
5
5
  Author-email: CareBridge Systems <dev@carebridge.io>
6
6
  License-Expression: LicenseRef-Proprietary
@@ -38,8 +38,8 @@ Async Python SDK for the Dominus gateway-first service plane.
38
38
  ## Agent Guide
39
39
 
40
40
  Start with `docs/agent-guide/INDEX.md`. The current snapshot is
41
- `docs/agent-guide/2026-09-14-1300-sdk-python/00-reading-order.md`; the latest
42
- cleanup audit is `docs/janitor/2026-09-14-1300-sdk-python-cleanup-audit.md`.
41
+ `docs/agent-guide/2026-09-19-1300-sdk-python/00-reading-order.md`; the latest
42
+ cleanup audit is `docs/janitor/2026-09-19-1300-sdk-python-cleanup-audit.md`.
43
43
 
44
44
  ## What This Repo Ships
45
45
 
@@ -48,7 +48,7 @@ cleanup audit is `docs/janitor/2026-09-14-1300-sdk-python-cleanup-audit.md`.
48
48
  - Gateway-scoped client mode for MCP and other user-JWT sessions
49
49
  - Transport compatibility for wrapped `{success,data}` responses and unwrapped Warden/control-plane success objects
50
50
  - Local helpers for JWT verification, trace propagation, retries, and console capture
51
- - Current package version: `9.0.12`
51
+ - Current package version: `9.0.13`
52
52
 
53
53
  ## Install
54
54
 
@@ -5,8 +5,8 @@ Async Python SDK for the Dominus gateway-first service plane.
5
5
  ## Agent Guide
6
6
 
7
7
  Start with `docs/agent-guide/INDEX.md`. The current snapshot is
8
- `docs/agent-guide/2026-09-14-1300-sdk-python/00-reading-order.md`; the latest
9
- cleanup audit is `docs/janitor/2026-09-14-1300-sdk-python-cleanup-audit.md`.
8
+ `docs/agent-guide/2026-09-19-1300-sdk-python/00-reading-order.md`; the latest
9
+ cleanup audit is `docs/janitor/2026-09-19-1300-sdk-python-cleanup-audit.md`.
10
10
 
11
11
  ## What This Repo Ships
12
12
 
@@ -15,7 +15,7 @@ cleanup audit is `docs/janitor/2026-09-14-1300-sdk-python-cleanup-audit.md`.
15
15
  - Gateway-scoped client mode for MCP and other user-JWT sessions
16
16
  - Transport compatibility for wrapped `{success,data}` responses and unwrapped Warden/control-plane success objects
17
17
  - Local helpers for JWT verification, trace propagation, retries, and console capture
18
- - Current package version: `9.0.12`
18
+ - Current package version: `9.0.13`
19
19
 
20
20
  ## Install
21
21
 
@@ -191,7 +191,7 @@ from .errors import (
191
191
  TimeoutError as DominusTimeoutError,
192
192
  )
193
193
 
194
- __version__ = "9.0.12"
194
+ __version__ = "9.0.13"
195
195
  __all__ = [
196
196
  # Main SDK instance
197
197
  "dominus",
@@ -56,6 +56,11 @@ LIST_RUN_KIND = "workflow"
56
56
  #: top-level projection on the wire; this SDK never relies on that default.
57
57
  RESULT_VIEW_BOUND = "bound"
58
58
 
59
+ #: Canonical coherent deploy read view. Authority still serves the legacy
60
+ #: ``latest_deployment_*`` projection when ``view`` is omitted; this SDK never
61
+ #: relies on that default, and carries no legacy fallback.
62
+ DEPLOY_VIEW_COHERENT = "coherent"
63
+
59
64
 
60
65
  def remote_command_outcome(payload: Mapping[str, Any]) -> Dict[str, Any]:
61
66
  """Unwrap a canonical ``RemoteCommandResult`` to the remote outcome it carries.
@@ -72,6 +77,35 @@ def remote_command_outcome(payload: Mapping[str, Any]) -> Dict[str, Any]:
72
77
  return dict(payload)
73
78
 
74
79
 
80
+ def coherent_deploy_state(payload: Mapping[str, Any]) -> Dict[str, Any]:
81
+ """Split a coherent deploy read into current state, labeled history, provenance.
82
+
83
+ A coherent read returns the deploy's one current rollout, its executor
84
+ history, and the provenance naming which rollout is current. This accessor
85
+ keeps that separation intact so history can never be read as current state:
86
+ ``current_rollout`` stays ``None`` when Authority reports the read as
87
+ partial (an unset or unresolvable ``current_rollout_id``), and the newest
88
+ history entry is never substituted for it. ``partial`` restates the
89
+ provenance flag for callers that branch on it.
90
+ """
91
+ envelope: Mapping[str, Any] = payload if isinstance(payload, Mapping) else {}
92
+ provenance = envelope.get("provenance")
93
+ provenance = dict(provenance) if isinstance(provenance, Mapping) else {}
94
+ current = envelope.get("current_rollout")
95
+ history = envelope.get("executor_history")
96
+ return {
97
+ "deploy": dict(envelope.get("deploy") or {}),
98
+ "current_rollout": dict(current) if isinstance(current, Mapping) else None,
99
+ "executor_history": (
100
+ [dict(row) for row in history if isinstance(row, Mapping)]
101
+ if isinstance(history, list)
102
+ else []
103
+ ),
104
+ "provenance": provenance,
105
+ "partial": bool(provenance.get("partial")),
106
+ }
107
+
108
+
75
109
  def _is_workflow_recipe_ref(value: Optional[str]) -> bool:
76
110
  return str(value or "").strip().startswith("recipe://workflow-recipe-v1/")
77
111
 
@@ -1077,11 +1111,21 @@ class AuthorityNamespace:
1077
1111
  )
1078
1112
 
1079
1113
  async def get_deploy(self, deploy_id: str, *, timeout: Optional[float] = None) -> Dict[str, Any]:
1080
- """Get deploy by id. ``GET /api/authority/deploys/{deploy_id}``."""
1114
+ """Get deploy by id in coherent current state.
1115
+
1116
+ ``GET /api/authority/deploys/{deploy_id}?view=coherent`` returns
1117
+ ``{deploy, current_rollout, executor_history, provenance}``: the single
1118
+ current rollout, the executor history labeled as history, and the
1119
+ provenance naming which rollout is current (``partial`` when Authority
1120
+ cannot resolve one). The view is requested explicitly so the read never
1121
+ rides the server's legacy default, and there is no legacy fallback.
1122
+ Use :func:`coherent_deploy_state` to read the sections apart.
1123
+ """
1081
1124
  if not deploy_id:
1082
1125
  raise ValueError("deploy_id is required")
1126
+ qs = _query_string({"view": DEPLOY_VIEW_COHERENT})
1083
1127
  return await self._get(
1084
- f"/api/authority/deploys/{quote(deploy_id, safe='')}",
1128
+ f"/api/authority/deploys/{quote(deploy_id, safe='')}{qs}",
1085
1129
  timeout=self._http_timeout(timeout, 30.0),
1086
1130
  )
1087
1131
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dominus-sdk-python
3
- Version: 9.0.12
3
+ Version: 9.0.13
4
4
  Summary: Python SDK for the Dominus gateway-first platform
5
5
  Author-email: CareBridge Systems <dev@carebridge.io>
6
6
  License-Expression: LicenseRef-Proprietary
@@ -38,8 +38,8 @@ Async Python SDK for the Dominus gateway-first service plane.
38
38
  ## Agent Guide
39
39
 
40
40
  Start with `docs/agent-guide/INDEX.md`. The current snapshot is
41
- `docs/agent-guide/2026-09-14-1300-sdk-python/00-reading-order.md`; the latest
42
- cleanup audit is `docs/janitor/2026-09-14-1300-sdk-python-cleanup-audit.md`.
41
+ `docs/agent-guide/2026-09-19-1300-sdk-python/00-reading-order.md`; the latest
42
+ cleanup audit is `docs/janitor/2026-09-19-1300-sdk-python-cleanup-audit.md`.
43
43
 
44
44
  ## What This Repo Ships
45
45
 
@@ -48,7 +48,7 @@ cleanup audit is `docs/janitor/2026-09-14-1300-sdk-python-cleanup-audit.md`.
48
48
  - Gateway-scoped client mode for MCP and other user-JWT sessions
49
49
  - Transport compatibility for wrapped `{success,data}` responses and unwrapped Warden/control-plane success objects
50
50
  - Local helpers for JWT verification, trace propagation, retries, and console capture
51
- - Current package version: `9.0.12`
51
+ - Current package version: `9.0.13`
52
52
 
53
53
  ## Install
54
54
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dominus-sdk-python"
7
- version = "9.0.12"
7
+ version = "9.0.13"
8
8
  description = "Python SDK for the Dominus gateway-first platform"
9
9
  readme = "README.md"
10
10
  license = "LicenseRef-Proprietary"
@@ -611,6 +611,91 @@ async def test_bootstrap_provisioning_target_carries_repo_template():
611
611
  assert "repo_template" not in absent_client.calls[-1]["body"]
612
612
 
613
613
 
614
+ # --- Task 16: singular deploy reader reads coherent current state --
615
+
616
+
617
+ @pytest.mark.asyncio
618
+ async def test_get_deploy_requests_the_coherent_view_explicitly():
619
+ from dominus.namespaces.authority import DEPLOY_VIEW_COHERENT
620
+
621
+ client = FakeClient()
622
+ ns = AuthorityNamespace(client)
623
+
624
+ await ns.get_deploy("deploy::dominus-authority--production")
625
+
626
+ assert client.calls[0]["method"] == "GET"
627
+ assert client.calls[0]["endpoint"] == (
628
+ "/api/authority/deploys/deploy%3A%3Adominus-authority--production?view=coherent"
629
+ )
630
+ # The view is named on the wire, never inherited from the server default.
631
+ assert DEPLOY_VIEW_COHERENT == "coherent"
632
+
633
+
634
+ def test_coherent_deploy_state_keeps_current_and_history_labeled_apart():
635
+ from dominus.namespaces.authority import coherent_deploy_state
636
+
637
+ state = coherent_deploy_state(
638
+ {
639
+ "deploy": {"deploy_id": "deploy-1", "app_slug": "carebridge"},
640
+ "current_rollout": {"rollout_id": "rollout-2", "generation": 7},
641
+ "executor_history": [
642
+ {"rollout_id": "rollout-1", "generation": 6},
643
+ {"rollout_id": "rollout-2", "generation": 7, "is_current": True},
644
+ ],
645
+ "provenance": {
646
+ "view": "coherent",
647
+ "source": "current_rollout",
648
+ "rollout_id": "rollout-2",
649
+ "generation": 7,
650
+ "is_current": True,
651
+ "partial": False,
652
+ },
653
+ }
654
+ )
655
+
656
+ assert state["current_rollout"]["rollout_id"] == "rollout-2"
657
+ assert [row["rollout_id"] for row in state["executor_history"]] == ["rollout-1", "rollout-2"]
658
+ assert state["provenance"]["generation"] == 7
659
+ assert state["partial"] is False
660
+
661
+
662
+ def test_coherent_deploy_state_never_substitutes_history_for_a_missing_current_rollout():
663
+ from dominus.namespaces.authority import coherent_deploy_state
664
+
665
+ state = coherent_deploy_state(
666
+ {
667
+ "deploy": {"deploy_id": "deploy-2"},
668
+ "current_rollout": None,
669
+ "executor_history": [{"rollout_id": "rollout-9", "generation": 3}],
670
+ "provenance": {
671
+ "view": "coherent",
672
+ "source": None,
673
+ "rollout_id": None,
674
+ "is_current": False,
675
+ "partial": True,
676
+ },
677
+ }
678
+ )
679
+
680
+ # An unresolved current rollout stays an explicit partial; the newest
681
+ # history entry is not promoted into its place.
682
+ assert state["current_rollout"] is None
683
+ assert state["partial"] is True
684
+ assert [row["rollout_id"] for row in state["executor_history"]] == ["rollout-9"]
685
+
686
+
687
+ def test_coherent_deploy_state_tolerates_a_non_envelope_payload():
688
+ from dominus.namespaces.authority import coherent_deploy_state
689
+
690
+ state = coherent_deploy_state({"code": "authority.deploy_not_found"})
691
+
692
+ assert state["deploy"] == {}
693
+ assert state["current_rollout"] is None
694
+ assert state["executor_history"] == []
695
+ assert state["provenance"] == {}
696
+ assert state["partial"] is False
697
+
698
+
614
699
  def test_bootstrap_signature_carries_standalone_and_root_role():
615
700
  bootstrap_sig = inspect.signature(AuthorityNamespace.bootstrap_provisioning_target)
616
701
  assert "standalone" in bootstrap_sig.parameters