diff --git a/event-types/org.statehub.workplan.completed.md b/event-types/org.statehub.workplan.completed.md new file mode 100644 index 0000000..0848dc6 --- /dev/null +++ b/event-types/org.statehub.workplan.completed.md @@ -0,0 +1,67 @@ +--- +type_id: org.statehub.workplan.completed +version: "1.0" +publisher: state-hub +governance: publisher-declared +status: active +--- + +# org.statehub.workplan.completed + +## Intent + +Emitted when a workplan reaches canonical status `finished` in State Hub. +Signals that a planned body of work has been fully delivered. + +## When Published + +State Hub emits this event when a workplan transitions to `finished` (including +via legacy `/workstreams` routes). This is the **preferred** completion subject; +subscribe here for new automations. + +## Attributes + +| Name | Type | Required | Description | +|---|---|---|---| +| workplan_id | uuid | yes | State Hub UUID of the completed workplan. | +| legacy_workstream_id | uuid | yes | Same UUID; retained for bridge consumers during migration. | +| slug | string | yes | Human-readable slug, e.g. "event-bridge". | +| title | string | yes | Workplan title. | +| topic_id | uuid | no | Topic the workplan belongs to. | +| repo_id | uuid | no | Managed repo when file-backed. | +| repo_goal_id | uuid | no | Linked repo goal when set. | + +## Example Payload + +```json +{ + "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901", + "type": "org.statehub.workplan.completed", + "version": "1.0", + "timestamp": "2026-07-08T15:30:00Z", + "publisher": "state-hub", + "attributes": { + "workplan_id": "b4eb45a9-69e3-4ab0-b00c-67a53c3117c5", + "legacy_workstream_id": "b4eb45a9-69e3-4ab0-b00c-67a53c3117c5", + "slug": "event-bridge", + "title": "Event bridge", + "topic_id": "cee7bedf-2b48-46ef-8601-006474f2ad7a", + "repo_id": null, + "repo_goal_id": null + } +} +``` + +## Consumer Notes + +- **activity-core**: Preferred subscription for post-completion workflows (SBOM + ingestion, documentation generation, domain goal updates). +- **Legacy types**: Do not subscribe to `org.workstream.completed` or + `org.statehub.workstream.completed` for new work — see sunset notes on those + catalog entries. + +## Debugging + +If this event is missing, check the workplan status in State Hub. The event is +only emitted on `finished` transitions, not on intermediate updates. See +`state-hub/docs/nats-event-subjects.md` for the authoritative subject list. \ No newline at end of file diff --git a/event-types/org.statehub.workstream.completed.md b/event-types/org.statehub.workstream.completed.md new file mode 100644 index 0000000..1dabd25 --- /dev/null +++ b/event-types/org.statehub.workstream.completed.md @@ -0,0 +1,46 @@ +--- +type_id: org.statehub.workstream.completed +version: "1.0" +publisher: state-hub +governance: publisher-declared +status: legacy +replacement: org.statehub.workplan.completed +sunset_date: "2026-12-31" +--- + +# org.statehub.workstream.completed + +## Intent + +Legacy State Hub completion subject, dual-published alongside +`org.statehub.workplan.completed` while subscribers migrate. + +## Status + +**Legacy (metered).** State Hub records usage in `legacy-meter` under +`event_subject:org.statehub.workstream.completed`. New automations must subscribe +to `org.statehub.workplan.completed` instead. + +Planned retirement: **2026-12-31** (`STATE-WP-0069` T05), subject to zero +consumers in the legacy-meter review window. + +## When Published + +State Hub emits this event on the same workplan `finished` transition as the +preferred subject. Attributes use legacy `workstream_id` naming. + +## Attributes + +| Name | Type | Required | Description | +|---|---|---|---| +| workstream_id | uuid | yes | State Hub UUID of the completed workplan. | +| slug | string | yes | Human-readable slug. | +| title | string | yes | Workplan title. | +| topic_id | uuid | no | Topic the workplan belongs to. | +| repo_id | uuid | no | Managed repo when file-backed. | +| repo_goal_id | uuid | no | Linked repo goal when set. | + +## Consumer Notes + +- Migrate subscriptions to `org.statehub.workplan.completed`. +- Do **not** introduce a bare `org.workplan.completed` subject. \ No newline at end of file diff --git a/event-types/org.workstream.completed.md b/event-types/org.workstream.completed.md index 63b6725..3640058 100644 --- a/event-types/org.workstream.completed.md +++ b/event-types/org.workstream.completed.md @@ -3,28 +3,40 @@ type_id: org.workstream.completed version: "1.0" publisher: the-custodian/state-hub governance: publisher-declared -status: active +status: deprecated +replacement: org.statehub.workplan.completed +sunset_date: "2026-12-31" --- # org.workstream.completed ## Intent -Emitted when a workstream reaches `status=done` in the Custodian State Hub. -Signals that a planned body of work has been fully delivered. +Custodian-era catalog type for workplan completion. **Deprecated** — State Hub +never published this bare `org.*` subject; it emits `org.statehub.*` subjects +instead. + +## Status + +**Deprecated.** Sunset **2026-12-31**. Map existing subscribers and documentation +references to `org.statehub.workplan.completed`. + +For the metered State Hub legacy subject (dual-published today), see +`org.statehub.workstream.completed.md`. ## When Published -State-hub emits this event when `update_workstream_status(status="done")` is -called and the workstream transitions to done state. +Not emitted by current State Hub releases. Historical documentation assumed +`update_workstream_status(status="done")`; the live publisher uses workplan +finish transitions on `/workplans` and `/workstreams` routes. ## Attributes | Name | Type | Required | Description | |---|---|---|---| -| workstream_id | uuid | yes | State-hub UUID of the completed workstream. | -| workstream_slug | string | yes | Human-readable slug, e.g. "event-bridge". | -| domain | string | yes | Domain the workstream belongs to, e.g. "custodian". | +| workstream_id | uuid | yes | State Hub UUID (legacy attribute name). | +| workstream_slug | string | yes | Human-readable slug. | +| domain | string | yes | Domain slug. | | completed_at | datetime | yes | UTC timestamp of completion. | ## Example Payload @@ -47,12 +59,11 @@ called and the workstream transitions to done state. ## Consumer Notes -- **activity-core**: Use to trigger post-completion workflows such as SBOM - ingestion, documentation generation, or domain goal updates. -- **state-hub**: This event is self-referential — a completed workstream may - trigger further automation in other domains. +- **New work**: subscribe to `org.statehub.workplan.completed` only. +- **activity-core**: Update ActivityDefinitions that still reference this + type_id before the sunset date. ## Debugging -If this event is missing, check the workstream status in state-hub. The event -is only emitted on `status=done` transitions, not on intermediate updates. +Check workplan status in State Hub and verify NATS subjects under +`org.statehub.workplan.completed`. See `state-hub/docs/nats-event-subjects.md`. \ No newline at end of file diff --git a/tests/test_workplan_event_types.py b/tests/test_workplan_event_types.py new file mode 100644 index 0000000..a779d93 --- /dev/null +++ b/tests/test_workplan_event_types.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +from pathlib import Path + +from activity_core.event_type_registry import parse_event_type_file + +_EVENT_DIR = Path(__file__).parent.parent / "event-types" + + +def test_preferred_workplan_completion_event_is_active() -> None: + event_type = parse_event_type_file(_EVENT_DIR / "org.statehub.workplan.completed.md") + + assert event_type.type_id == "org.statehub.workplan.completed" + assert event_type.status == "active" + assert event_type.publisher == "state-hub" + assert event_type.attribute_schema["workplan_id"]["required"] is True + assert "preferred" in event_type.raw_md.lower() + + +def test_legacy_statehub_completion_event_points_to_replacement() -> None: + event_type = parse_event_type_file(_EVENT_DIR / "org.statehub.workstream.completed.md") + + assert event_type.type_id == "org.statehub.workstream.completed" + assert event_type.status == "legacy" + assert "org.statehub.workplan.completed" in event_type.raw_md + + +def test_custodian_catalog_completion_event_is_deprecated() -> None: + event_type = parse_event_type_file(_EVENT_DIR / "org.workstream.completed.md") + + assert event_type.type_id == "org.workstream.completed" + assert event_type.status == "deprecated" + assert "org.statehub.workplan.completed" in event_type.raw_md + assert "2026-12-31" in event_type.raw_md \ No newline at end of file