dominus-sdk-python 3.0.4__tar.gz → 3.0.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 (58) hide show
  1. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/PKG-INFO +7 -3
  2. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/README.md +6 -2
  3. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/__init__.py +1 -1
  4. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/authority.py +302 -28
  5. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/files.py +56 -45
  6. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/logs.py +38 -0
  7. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus_sdk_python.egg-info/PKG-INFO +7 -3
  8. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/pyproject.toml +1 -1
  9. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/tests/test_authority_public_vocabulary.py +94 -2
  10. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/tests/test_logs.py +28 -1
  11. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/config/__init__.py +0 -0
  12. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/config/endpoints.py +0 -0
  13. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/errors.py +0 -0
  14. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/helpers/__init__.py +0 -0
  15. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/helpers/auth.py +0 -0
  16. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/helpers/cache.py +0 -0
  17. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/helpers/console_capture.py +0 -0
  18. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/helpers/core.py +0 -0
  19. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/helpers/crypto.py +0 -0
  20. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/helpers/sse.py +0 -0
  21. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/helpers/trace.py +0 -0
  22. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/__init__.py +0 -0
  23. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/admin.py +0 -0
  24. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/ai.py +0 -0
  25. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/artifacts.py +0 -0
  26. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/auth.py +0 -0
  27. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/courier.py +0 -0
  28. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/db.py +0 -0
  29. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/ddl.py +0 -0
  30. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/deployer.py +0 -0
  31. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/fastapi.py +0 -0
  32. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/health.py +0 -0
  33. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/jobs.py +0 -0
  34. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/portal.py +0 -0
  35. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/processor.py +0 -0
  36. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/redis.py +0 -0
  37. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/secrets.py +0 -0
  38. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/secure.py +0 -0
  39. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/sync.py +0 -0
  40. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/warden.py +0 -0
  41. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/namespaces/workflow.py +0 -0
  42. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/services/__init__.py +0 -0
  43. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus/start.py +0 -0
  44. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus_sdk_python.egg-info/SOURCES.txt +0 -0
  45. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus_sdk_python.egg-info/dependency_links.txt +0 -0
  46. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus_sdk_python.egg-info/requires.txt +0 -0
  47. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/dominus_sdk_python.egg-info/top_level.txt +0 -0
  48. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/setup.cfg +0 -0
  49. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/tests/test_auth.py +0 -0
  50. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/tests/test_control_plane_namespaces.py +0 -0
  51. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/tests/test_errors.py +0 -0
  52. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/tests/test_flat_commands.py +0 -0
  53. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/tests/test_health.py +0 -0
  54. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/tests/test_provisioning_parity.py +0 -0
  55. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/tests/test_public_exports.py +0 -0
  56. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/tests/test_transport_compat.py +0 -0
  57. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/tests/test_workflow_lifecycle.py +0 -0
  58. {dominus_sdk_python-3.0.4 → dominus_sdk_python-3.0.5}/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: 3.0.4
3
+ Version: 3.0.5
4
4
  Summary: Python SDK for the Dominus gateway-first platform
5
5
  Author-email: CareBridge Systems <dev@carebridge.io>
6
6
  License: Proprietary
@@ -41,7 +41,7 @@ Async Python SDK for the Dominus gateway-first service plane.
41
41
  - Namespace-first API with a small root shortcut surface
42
42
  - Gateway-scoped client mode for MCP and other user-JWT sessions
43
43
  - Local helpers for JWT verification, trace propagation, retries, and console capture
44
- - Current package version: `3.0.4`
44
+ - Current package version: `3.0.5`
45
45
 
46
46
  ## Install
47
47
 
@@ -69,7 +69,11 @@ run = await dominus.workflow.ensure(
69
69
  company="summit-radiology",
70
70
  )
71
71
 
72
- timeline = await dominus.workflow.get_run_timeline(run["run_id"])
72
+ timeline = await dominus.authority.get_run_timeline(
73
+ run["run_id"],
74
+ since="2026-04-11T08:33:00Z",
75
+ until="2026-04-11T09:33:00Z",
76
+ )
73
77
  ```
74
78
 
75
79
  ## Session-Scoped Clients
@@ -8,7 +8,7 @@ Async Python SDK for the Dominus gateway-first service plane.
8
8
  - Namespace-first API with a small root shortcut surface
9
9
  - Gateway-scoped client mode for MCP and other user-JWT sessions
10
10
  - Local helpers for JWT verification, trace propagation, retries, and console capture
11
- - Current package version: `3.0.4`
11
+ - Current package version: `3.0.5`
12
12
 
13
13
  ## Install
14
14
 
@@ -36,7 +36,11 @@ run = await dominus.workflow.ensure(
36
36
  company="summit-radiology",
37
37
  )
38
38
 
39
- timeline = await dominus.workflow.get_run_timeline(run["run_id"])
39
+ timeline = await dominus.authority.get_run_timeline(
40
+ run["run_id"],
41
+ since="2026-04-11T08:33:00Z",
42
+ until="2026-04-11T09:33:00Z",
43
+ )
40
44
  ```
41
45
 
42
46
  ## Session-Scoped Clients
@@ -163,7 +163,7 @@ from .errors import (
163
163
  TimeoutError as DominusTimeoutError,
164
164
  )
165
165
 
166
- __version__ = "3.0.2"
166
+ __version__ = "3.0.5"
167
167
  __all__ = [
168
168
  # Main SDK instance
169
169
  "dominus",
@@ -118,6 +118,7 @@ class AuthorityNamespace:
118
118
  target_org_id: Optional[str],
119
119
  target_env: Optional[str],
120
120
  target_app_slug: Optional[str] = None,
121
+ shared_app_slug: Optional[str] = None,
121
122
  ) -> Dict[str, Any]:
122
123
  out: Dict[str, Any] = {}
123
124
  if app_slug:
@@ -130,6 +131,8 @@ class AuthorityNamespace:
130
131
  out["target_app_slug"] = target_app_slug
131
132
  if target_env:
132
133
  out["target_env"] = target_env
134
+ if shared_app_slug:
135
+ out["shared_app_slug"] = shared_app_slug
133
136
  return out
134
137
 
135
138
  def _target_query_params(
@@ -167,6 +170,7 @@ class AuthorityNamespace:
167
170
  workflow_id: Optional[str] = None,
168
171
  workflow_ref: Optional[str] = None,
169
172
  run_kind: Optional[str] = None,
173
+ bootstrap_profile: Optional[str] = None,
170
174
  company_slug: Optional[str] = None,
171
175
  slug: Optional[str] = None,
172
176
  instance_id: Optional[str] = None,
@@ -207,7 +211,7 @@ class AuthorityNamespace:
207
211
 
208
212
  For company bootstrap, pass ``run_kind="company.bootstrap"`` (or ``company_bootstrap``) plus
209
213
  ``company``, ``company_slug``, or ``slug``. Optional bootstrap fields mirror
210
- ``bootstrap_company`` (``execution_mode``, ``region``, …).
214
+ ``bootstrap_company`` (``execution_mode``, ``region``, ``bootstrap_profile``, …).
211
215
  """
212
216
  bootstrap = _is_company_bootstrap_run_kind(run_kind)
213
217
  if not bootstrap and not workflow_id and not workflow_ref:
@@ -233,6 +237,7 @@ class AuthorityNamespace:
233
237
  if bootstrap:
234
238
  body = _compact({
235
239
  "run_kind": run_kind,
240
+ "bootstrap_profile": bootstrap_profile,
236
241
  "workflow_id": workflow_id,
237
242
  "workflow_ref": workflow_ref,
238
243
  "instance_id": instance_id,
@@ -264,6 +269,7 @@ class AuthorityNamespace:
264
269
  body = _compact({
265
270
  "workflow_id": workflow_id,
266
271
  "workflow_ref": workflow_ref,
272
+ "bootstrap_profile": bootstrap_profile,
267
273
  "instance_id": instance_id,
268
274
  "instance_key": instance_key,
269
275
  "group": group,
@@ -444,21 +450,51 @@ class AuthorityNamespace:
444
450
  body,
445
451
  )
446
452
 
447
- async def get_run_timeline(self, run_id: str, *, timeout: Optional[float] = None) -> Dict[str, Any]:
453
+ async def get_run_timeline(
454
+ self,
455
+ run_id: str,
456
+ *,
457
+ since: Optional[str] = None,
458
+ until: Optional[str] = None,
459
+ window_hours: Optional[int] = None,
460
+ limit: Optional[int] = None,
461
+ timeout: Optional[float] = None,
462
+ ) -> Dict[str, Any]:
448
463
  """Get run state-transition timeline. ``GET /api/authority/runs/{run_id}/timeline``."""
449
464
  if not run_id:
450
465
  raise ValueError("run_id is required")
466
+ qs = _query_string({
467
+ "since": since,
468
+ "until": until,
469
+ "window_hours": window_hours,
470
+ "limit": limit,
471
+ })
451
472
  return await self._get(
452
- f"/api/authority/runs/{quote(run_id, safe='')}/timeline",
473
+ f"/api/authority/runs/{quote(run_id, safe='')}/timeline{qs}",
453
474
  timeout=self._http_timeout(timeout, 30.0),
454
475
  )
455
476
 
456
- async def get_run_dossier(self, run_id: str, *, timeout: Optional[float] = None) -> Dict[str, Any]:
477
+ async def get_run_dossier(
478
+ self,
479
+ run_id: str,
480
+ *,
481
+ since: Optional[str] = None,
482
+ until: Optional[str] = None,
483
+ window_hours: Optional[int] = None,
484
+ limit: Optional[int] = None,
485
+ timeout: Optional[float] = None,
486
+ ) -> Dict[str, Any]:
457
487
  """Get the full Authority dossier for a run. ``GET /api/authority/dossiers/run/{run_id}``."""
458
488
  if not run_id:
459
489
  raise ValueError("run_id is required")
490
+ qs = _query_string({
491
+ "since": since,
492
+ "until": until,
493
+ "window_hours": window_hours,
494
+ "limit": limit,
495
+ })
460
496
  return await self._get(
461
- f"/api/authority/dossiers/run/{quote(run_id, safe='')}",
497
+ f"/api/authority/dossiers/run/{quote(run_id, safe='')}{qs}",
462
498
  timeout=self._http_timeout(timeout, 30.0),
463
499
  )
464
500
 
@@ -469,90 +505,278 @@ class AuthorityNamespace:
469
505
  async def publish_workflow(
470
506
  self,
471
507
  *,
472
- workflow_ref: str,
508
+ name: Optional[str] = None,
509
+ yaml_content: Optional[str] = None,
510
+ workflow_ref: Optional[str] = None,
473
511
  workflow_id: Optional[str] = None,
474
- version: Optional[Any] = None,
475
- status: Optional[str] = None,
476
- pinned: Optional[bool] = None,
477
- bindings: Optional[Dict[str, Any]] = None,
512
+ description: Optional[str] = None,
513
+ tags: Optional[Any] = None,
478
514
  metadata: Optional[Dict[str, Any]] = None,
479
515
  app_slug: Optional[str] = None,
480
516
  env: Optional[str] = None,
481
517
  target_org_id: Optional[str] = None,
518
+ target_app_slug: Optional[str] = None,
482
519
  target_env: Optional[str] = None,
520
+ shared_app_slug: Optional[str] = None,
483
521
  initiator_type: Optional[str] = None,
484
522
  initiator_id: Optional[str] = None,
485
523
  idempotency_key: Optional[str] = None,
524
+ timeout: Optional[float] = None,
486
525
  ) -> Dict[str, Any]:
487
526
  """Publish a workflow to the Authority registry. ``POST /api/authority/workflows/publish``."""
488
- if not workflow_ref:
489
- raise ValueError("publish_workflow requires workflow_ref")
490
527
  body = _compact({
528
+ "name": name,
529
+ "yaml_content": yaml_content,
491
530
  "workflow_ref": workflow_ref,
492
531
  "workflow_id": workflow_id,
493
- "version": version,
494
- "status": status,
495
- "pinned": pinned,
496
- "bindings": bindings,
532
+ "description": description,
533
+ "tags": tags,
497
534
  "metadata": metadata,
498
535
  **self._initiator(initiator_type, initiator_id, idempotency_key),
499
- **self._scope(app_slug, env, target_org_id, target_env),
536
+ **self._scope(
537
+ app_slug,
538
+ env,
539
+ target_org_id,
540
+ target_env,
541
+ target_app_slug=target_app_slug,
542
+ shared_app_slug=shared_app_slug,
543
+ ),
500
544
  })
501
- return await self._post("/api/authority/workflows/publish", body)
545
+ return await self._post(
546
+ "/api/authority/workflows/publish",
547
+ body,
548
+ timeout=self._http_timeout(timeout, 30.0),
549
+ )
502
550
 
503
551
  async def list_bindings(
504
552
  self,
505
553
  *,
506
- workflow_ref: Optional[str] = None,
507
- workflow_id: Optional[str] = None,
554
+ source_workflow_ref: Optional[str] = None,
555
+ workflow_type: Optional[str] = None,
556
+ company_slug: Optional[str] = None,
508
557
  status: Optional[str] = None,
509
558
  app_slug: Optional[str] = None,
510
559
  env: Optional[str] = None,
511
560
  target_org_id: Optional[str] = None,
561
+ target_app_slug: Optional[str] = None,
512
562
  target_env: Optional[str] = None,
563
+ shared_app_slug: Optional[str] = None,
513
564
  limit: int = 50,
514
565
  offset: int = 0,
566
+ timeout: Optional[float] = None,
515
567
  ) -> Dict[str, Any]:
516
568
  """List Authority workflow bindings. ``GET /api/authority/workflow-bindings``."""
517
569
  tid, tev = self._target_query_params(target_org_id, target_env)
518
570
  qs = _query_string({
519
- "workflow_ref": workflow_ref,
520
- "workflow_id": workflow_id,
571
+ "source_workflow_ref": source_workflow_ref,
572
+ "workflow_type": workflow_type,
573
+ "company_slug": company_slug,
521
574
  "status": status,
522
575
  "app_slug": app_slug,
523
576
  "env": env,
524
577
  "target_org_id": tid,
578
+ "target_app_slug": target_app_slug,
525
579
  "target_env": tev,
580
+ "shared_app_slug": shared_app_slug,
526
581
  "limit": limit,
527
582
  "offset": offset,
528
583
  })
529
- return await self._get(f"/api/authority/workflow-bindings{qs}")
584
+ return await self._get(
585
+ f"/api/authority/workflow-bindings{qs}",
586
+ timeout=self._http_timeout(timeout, 30.0),
587
+ )
530
588
 
531
589
  async def list_publications(
532
590
  self,
533
591
  *,
534
- workflow_ref: Optional[str] = None,
592
+ publication_id: Optional[str] = None,
593
+ binding_id: Optional[str] = None,
594
+ source_workflow_ref: Optional[str] = None,
595
+ workflow_type: Optional[str] = None,
596
+ company_slug: Optional[str] = None,
535
597
  status: Optional[str] = None,
536
598
  app_slug: Optional[str] = None,
537
599
  env: Optional[str] = None,
538
600
  target_org_id: Optional[str] = None,
601
+ target_app_slug: Optional[str] = None,
539
602
  target_env: Optional[str] = None,
603
+ shared_app_slug: Optional[str] = None,
540
604
  limit: int = 50,
541
605
  offset: int = 0,
606
+ timeout: Optional[float] = None,
542
607
  ) -> Dict[str, Any]:
543
608
  """List Authority workflow publications. ``GET /api/authority/workflow-publications``."""
544
609
  tid, tev = self._target_query_params(target_org_id, target_env)
545
610
  qs = _query_string({
546
- "workflow_ref": workflow_ref,
611
+ "publication_id": publication_id,
612
+ "binding_id": binding_id,
613
+ "source_workflow_ref": source_workflow_ref,
614
+ "workflow_type": workflow_type,
615
+ "company_slug": company_slug,
547
616
  "status": status,
548
617
  "app_slug": app_slug,
549
618
  "env": env,
550
619
  "target_org_id": tid,
620
+ "target_app_slug": target_app_slug,
551
621
  "target_env": tev,
622
+ "shared_app_slug": shared_app_slug,
552
623
  "limit": limit,
553
624
  "offset": offset,
554
625
  })
555
- return await self._get(f"/api/authority/workflow-publications{qs}")
626
+ return await self._get(
627
+ f"/api/authority/workflow-publications{qs}",
628
+ timeout=self._http_timeout(timeout, 30.0),
629
+ )
630
+
631
+ async def create_workflow_binding(
632
+ self,
633
+ *,
634
+ company_slug: str,
635
+ workflow_type: str,
636
+ source_workflow_id: str,
637
+ target_workflow_id: str,
638
+ source_workflow_ref: Optional[str] = None,
639
+ source_org_id: Optional[str] = None,
640
+ source_version: Optional[int] = None,
641
+ target_tenant_slug: Optional[str] = None,
642
+ target_workflow_slug: Optional[str] = None,
643
+ active_publication_id: Optional[str] = None,
644
+ publication_state: Optional[str] = None,
645
+ publication_operation: Optional[str] = None,
646
+ source_hash: Optional[str] = None,
647
+ target_hash: Optional[str] = None,
648
+ drift_status: Optional[str] = None,
649
+ drift_checked_at: Optional[str] = None,
650
+ metadata: Optional[Dict[str, Any]] = None,
651
+ status: Optional[str] = None,
652
+ published_at: Optional[str] = None,
653
+ app_slug: Optional[str] = None,
654
+ env: Optional[str] = None,
655
+ target_org_id: Optional[str] = None,
656
+ target_app_slug: Optional[str] = None,
657
+ target_env: Optional[str] = None,
658
+ shared_app_slug: Optional[str] = None,
659
+ initiator_type: Optional[str] = None,
660
+ initiator_id: Optional[str] = None,
661
+ idempotency_key: Optional[str] = None,
662
+ timeout: Optional[float] = None,
663
+ ) -> Dict[str, Any]:
664
+ """Create or update a workflow binding. ``POST /api/authority/workflow-bindings``."""
665
+ body = _compact({
666
+ "company_slug": company_slug,
667
+ "workflow_type": workflow_type,
668
+ "source_workflow_ref": source_workflow_ref,
669
+ "source_org_id": source_org_id,
670
+ "source_workflow_id": source_workflow_id,
671
+ "source_version": source_version,
672
+ "target_tenant_slug": target_tenant_slug,
673
+ "target_workflow_slug": target_workflow_slug,
674
+ "target_workflow_id": target_workflow_id,
675
+ "active_publication_id": active_publication_id,
676
+ "publication_state": publication_state,
677
+ "publication_operation": publication_operation,
678
+ "source_hash": source_hash,
679
+ "target_hash": target_hash,
680
+ "drift_status": drift_status,
681
+ "drift_checked_at": drift_checked_at,
682
+ "metadata": metadata,
683
+ "status": status,
684
+ "published_at": published_at,
685
+ **self._initiator(initiator_type, initiator_id, idempotency_key),
686
+ **self._scope(
687
+ app_slug,
688
+ env,
689
+ target_org_id,
690
+ target_env,
691
+ target_app_slug=target_app_slug,
692
+ shared_app_slug=shared_app_slug,
693
+ ),
694
+ })
695
+ return await self._post(
696
+ "/api/authority/workflow-bindings",
697
+ body,
698
+ timeout=self._http_timeout(timeout, 30.0),
699
+ )
700
+
701
+ async def create_workflow_publication(
702
+ self,
703
+ *,
704
+ company_slug: str,
705
+ workflow_type: str,
706
+ source_workflow_id: str,
707
+ target_workflow_id: str,
708
+ source_workflow_ref: Optional[str] = None,
709
+ source_org_id: Optional[str] = None,
710
+ operation: Optional[str] = None,
711
+ source_version: Optional[int] = None,
712
+ source_hash: Optional[str] = None,
713
+ source_name: Optional[str] = None,
714
+ source_description: Optional[str] = None,
715
+ source_tags: Optional[list[Any]] = None,
716
+ source_yaml: Optional[str] = None,
717
+ target_tenant_slug: Optional[str] = None,
718
+ target_workflow_slug: Optional[str] = None,
719
+ target_hash: Optional[str] = None,
720
+ previous_publication_id: Optional[str] = None,
721
+ rollback_of_publication_id: Optional[str] = None,
722
+ publication_status: Optional[str] = None,
723
+ binding_status: Optional[str] = None,
724
+ publication_metadata: Optional[Dict[str, Any]] = None,
725
+ binding_metadata: Optional[Dict[str, Any]] = None,
726
+ metadata: Optional[Dict[str, Any]] = None,
727
+ published_at: Optional[str] = None,
728
+ app_slug: Optional[str] = None,
729
+ env: Optional[str] = None,
730
+ target_org_id: Optional[str] = None,
731
+ target_app_slug: Optional[str] = None,
732
+ target_env: Optional[str] = None,
733
+ shared_app_slug: Optional[str] = None,
734
+ initiator_type: Optional[str] = None,
735
+ initiator_id: Optional[str] = None,
736
+ idempotency_key: Optional[str] = None,
737
+ timeout: Optional[float] = None,
738
+ ) -> Dict[str, Any]:
739
+ """Create or upsert a workflow publication. ``POST /api/authority/workflow-publications``."""
740
+ body = _compact({
741
+ "company_slug": company_slug,
742
+ "workflow_type": workflow_type,
743
+ "source_workflow_ref": source_workflow_ref,
744
+ "source_org_id": source_org_id,
745
+ "operation": operation,
746
+ "source_workflow_id": source_workflow_id,
747
+ "source_version": source_version,
748
+ "source_hash": source_hash,
749
+ "source_name": source_name,
750
+ "source_description": source_description,
751
+ "source_tags": source_tags,
752
+ "source_yaml": source_yaml,
753
+ "target_tenant_slug": target_tenant_slug,
754
+ "target_workflow_slug": target_workflow_slug,
755
+ "target_workflow_id": target_workflow_id,
756
+ "target_hash": target_hash,
757
+ "previous_publication_id": previous_publication_id,
758
+ "rollback_of_publication_id": rollback_of_publication_id,
759
+ "publication_status": publication_status,
760
+ "binding_status": binding_status,
761
+ "publication_metadata": publication_metadata,
762
+ "binding_metadata": binding_metadata,
763
+ "metadata": metadata,
764
+ "published_at": published_at,
765
+ **self._initiator(initiator_type, initiator_id, idempotency_key),
766
+ **self._scope(
767
+ app_slug,
768
+ env,
769
+ target_org_id,
770
+ target_env,
771
+ target_app_slug=target_app_slug,
772
+ shared_app_slug=shared_app_slug,
773
+ ),
774
+ })
775
+ return await self._post(
776
+ "/api/authority/workflow-publications",
777
+ body,
778
+ timeout=self._http_timeout(timeout, 30.0),
779
+ )
556
780
 
557
781
  # ==================================================================
558
782
  # Companies
@@ -655,6 +879,7 @@ class AuthorityNamespace:
655
879
  action: Optional[str] = None,
656
880
  run_id: Optional[str] = None,
657
881
  reason: Optional[str] = None,
882
+ bootstrap_profile: Optional[str] = None,
658
883
  shared_app_slug: Optional[str] = None,
659
884
  region: Optional[str] = None,
660
885
  system: Optional[str] = None,
@@ -684,6 +909,7 @@ class AuthorityNamespace:
684
909
  "action": action,
685
910
  "run_id": run_id,
686
911
  "reason": reason,
912
+ "bootstrap_profile": bootstrap_profile,
687
913
  "shared_app_slug": shared_app_slug,
688
914
  "region": region,
689
915
  "system": system,
@@ -742,6 +968,10 @@ class AuthorityNamespace:
742
968
  env: Optional[str] = None,
743
969
  target_org_id: Optional[str] = None,
744
970
  target_env: Optional[str] = None,
971
+ since: Optional[str] = None,
972
+ until: Optional[str] = None,
973
+ window_hours: Optional[int] = None,
974
+ limit: Optional[int] = None,
745
975
  timeout: Optional[float] = None,
746
976
  ) -> Dict[str, Any]:
747
977
  """Get full Authority dossier for a company. ``GET /api/authority/dossiers/company/{company}``."""
@@ -753,6 +983,10 @@ class AuthorityNamespace:
753
983
  "env": env,
754
984
  "target_org_id": tid,
755
985
  "target_env": tev,
986
+ "since": since,
987
+ "until": until,
988
+ "window_hours": window_hours,
989
+ "limit": limit,
756
990
  })
757
991
  return await self._get(
758
992
  f"/api/authority/dossiers/company/{quote(company_slug, safe='')}{qs}",
@@ -889,7 +1123,16 @@ class AuthorityNamespace:
889
1123
  timeout=self._http_timeout(timeout, 30.0),
890
1124
  )
891
1125
 
892
- async def get_deploy_dossier(self, deploy_id: str, *, timeout: Optional[float] = None) -> Dict[str, Any]:
1126
+ async def get_deploy_dossier(
1127
+ self,
1128
+ deploy_id: str,
1129
+ *,
1130
+ since: Optional[str] = None,
1131
+ until: Optional[str] = None,
1132
+ window_hours: Optional[int] = None,
1133
+ limit: Optional[int] = None,
1134
+ timeout: Optional[float] = None,
1135
+ ) -> Dict[str, Any]:
893
1136
  """
894
1137
  Get the full Authority dossier for a deploy.
895
1138
  ``GET /api/authority/dossiers/deploy/{deploy_id}``.
@@ -900,8 +1143,14 @@ class AuthorityNamespace:
900
1143
  """
901
1144
  if not deploy_id:
902
1145
  raise ValueError("deploy_id is required")
1146
+ qs = _query_string({
1147
+ "since": since,
1148
+ "until": until,
1149
+ "window_hours": window_hours,
1150
+ "limit": limit,
1151
+ })
903
1152
  return await self._get(
904
- f"/api/authority/dossiers/deploy/{quote(deploy_id, safe='')}",
1153
+ f"/api/authority/dossiers/deploy/{quote(deploy_id, safe='')}{qs}",
905
1154
  timeout=self._http_timeout(timeout, 30.0),
906
1155
  )
907
1156
 
@@ -1272,6 +1521,8 @@ class AuthorityNamespace:
1272
1521
  company: Optional[str] = None,
1273
1522
  run_id: Optional[str] = None,
1274
1523
  filters: Optional[Dict[str, Any]] = None,
1524
+ since: Optional[str] = None,
1525
+ until: Optional[str] = None,
1275
1526
  window_hours: Optional[int] = None,
1276
1527
  limit: Optional[int] = None,
1277
1528
  app_slug: Optional[str] = None,
@@ -1289,6 +1540,8 @@ class AuthorityNamespace:
1289
1540
  "company": company,
1290
1541
  "run_id": run_id,
1291
1542
  "filters": filters,
1543
+ "since": since,
1544
+ "until": until,
1292
1545
  "window_hours": window_hours,
1293
1546
  "limit": limit,
1294
1547
  **self._initiator(initiator_type, initiator_id, idempotency_key),
@@ -1300,6 +1553,27 @@ class AuthorityNamespace:
1300
1553
  timeout=self._http_timeout(timeout, 30.0),
1301
1554
  )
1302
1555
 
1556
+ async def get_timeline_archive_status(
1557
+ self,
1558
+ *,
1559
+ all_scopes: bool = False,
1560
+ app_slug: Optional[str] = None,
1561
+ env: Optional[str] = None,
1562
+ limit: Optional[int] = None,
1563
+ timeout: Optional[float] = None,
1564
+ ) -> Dict[str, Any]:
1565
+ """Get Authority timeline archive backlog state. ``GET /api/authority/timelines/archive-status``."""
1566
+ qs = _query_string({
1567
+ "all_scopes": "true" if all_scopes else None,
1568
+ "app_slug": app_slug,
1569
+ "env": env,
1570
+ "limit": limit,
1571
+ })
1572
+ return await self._get(
1573
+ f"/api/authority/timelines/archive-status{qs}",
1574
+ timeout=self._http_timeout(timeout, 15.0),
1575
+ )
1576
+
1303
1577
  # ==================================================================
1304
1578
  # Context
1305
1579
  # ==================================================================