Files
the-custodian/workplans/CUST-WP-0040-state-hub-nats-activity-core-integration.md
tegwick ca8a09ed04 feat(state-hub): CUST-WP-0040 — NATS lifecycle event publishing for activity-core
Makes the state hub an event publisher so activity-core can drive
maintenance automation declaratively via ActivityDefinitions, rather
than the hub creating tasks itself.

- api/events/: lazy JetStream publisher + EventEnvelope mirroring
  activity-core's contract; no-op when NATS_URL unset, fire-and-forget
  with logged failures so publishing never breaks an API request.
- Wired publishers on the five v1.0 lifecycle events:
    org.statehub.repo.registered        (POST /repos/)
    org.statehub.workstream.completed   (PATCH /workstreams/* on transition)
    org.statehub.decision.resolved      (POST /decisions/*/resolve)
    org.statehub.domain.goal.activated  (POST /domain-goals/*/activate)
    org.statehub.task.stale             (scripts/cleanup_stale_tasks.py)
- docs/nats-event-subjects.md: subject naming convention + catalog.
- docs/cron-migration.md: design stub for replacing custodian-sync
  systemd timer and cleanup-stale cron with ActivityDefinitions
  (depends on activity-core WP-0003).
- docs/activity-core-delegation.md: protocol, invariants, cutover plan.
- SCOPE.md: declares activity-core as downstream event consumer and
  restates that the state hub stays a read model, not a task factory.

Workplan: workplans/CUST-WP-0040-state-hub-nats-activity-core-integration.md
242 tests pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 05:49:29 +02:00

176 lines
7.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: CUST-WP-0040
type: workplan
domain: custodian
repo: the-custodian
status: completed
state_hub_workstream_id: d8ac100b-a844-46a5-9684-415df0d32539
tasks:
- id: T01
title: Connect state hub event publisher to NATS JetStream
state_hub_task_id: c4bfa299-54dd-4ede-b5fa-9ae27dce5b2c
status: done
- id: T02
title: Define NATS subject schema for state hub lifecycle events
state_hub_task_id: 2ae236a4-8a16-4998-92dc-83bc48378d3d
status: done
- id: T03
title: Implement state hub lifecycle events as NATS EventEnvelopes
state_hub_task_id: ccb5a3fb-d5e5-4781-9e5d-552ad09477f5
status: done
- id: T04
title: Migrate state hub maintenance crons to activity-core ActivityDefinitions (design stub)
state_hub_task_id: 933b2a80-cbd6-436f-b092-c39dc6f1c9c4
status: done
- id: T05
title: Document state hub → activity-core delegation protocol
state_hub_task_id: b261d4b8-4039-4610-aaad-eb45bf3a51de
status: done
- id: T06
title: Update SCOPE.md to reflect activity-core delegation
state_hub_task_id: 356682e6-e608-4f58-b418-cdef2b9435f2
status: done
created: "2026-05-14"
---
# CUST-WP-0040: State Hub NATS / Activity-Core Integration
## Purpose
The Custodian State Hub currently runs bespoke maintenance cron jobs and
ad-hoc event handling internally. With activity-core established as the
org-wide Event Bridge, the state hub should delegate maintenance automation
to activity-core by publishing lifecycle events on NATS JetStream — rather
than implementing task creation itself.
This workplan makes the state hub an event *publisher* and removes it from
the task-generation business. The result: maintenance automations are governed
by ActivityDefinitions in activity-core (auditable, rule-based, testable)
rather than scattered cron code in the-custodian.
## Context
- **activity-core** (WP-0003 in progress): event loop that receives NATS events
and evaluates rules/instructions to create tasks in issue-core.
- **State hub**: tracks domain state, workstreams, decisions, and progress events.
It knows when things happen (repo registered, workstream completed, stale task).
- **The gap**: the state hub knows about org events but has no way to publish them
to NATS so that activity-core can react. This workplan closes that gap.
See: `docs/adr/adr-001-event-bridge-architecture.md` in activity-core for the
delegation protocol design.
## Scope
**In scope:**
- NATS JetStream publisher client in the state hub
- EventEnvelope schema for state hub lifecycle events
- NATS subject naming convention for state hub events
- Design stub for migrating existing maintenance crons to ActivityDefinitions
- Protocol documentation
**Out of scope:**
- activity-core rule/instruction implementation (lives in activity-core WP-0003)
- Removing existing state hub crons before activity-core is ready (sequencing risk)
- project-core (future)
## Tasks
### T01 — Connect state hub event publisher to NATS JetStream
Add a NATS JetStream publisher client to the state hub. It should:
- Connect to the NATS server on startup (use existing NATS config pattern)
- Expose a `publish_event(envelope: EventEnvelope)` function
- Be disabled/no-op when `NATS_URL` is not set (for environments without NATS)
- Log publish success/failure with event ID
**Key file**: `state_hub/events/nats_publisher.py` (new)
### T02 — Define NATS subject schema for state hub lifecycle events
Document and agree on the NATS subject naming convention for state hub events.
Proposed pattern: `org.statehub.{noun}.{verb}` — e.g.:
- `org.statehub.repo.registered`
- `org.statehub.workstream.completed`
- `org.statehub.task.stale`
- `org.statehub.domain.goal.activated`
Write the subject schema as a section in `docs/nats-event-subjects.md`.
Cross-reference with activity-core's event-types registry.
### T03 — Implement state hub lifecycle events as NATS EventEnvelopes
Wire the NATS publisher into state hub write operations. Candidate events:
- `org.statehub.repo.registered` — when a repo is registered in the hub
- `org.statehub.workstream.completed` — when a workstream status → completed
- `org.statehub.task.stale` — periodic check, tasks not updated in 14+ days
Each event must conform to the EventEnvelope schema defined in activity-core's
event type registry. Write a stub event type definition file in activity-core
at `event-types/org.statehub.repo.registered.md` (or coordinate with the
activity-core agent to do so).
### T04 — Migrate state hub maintenance crons to activity-core ActivityDefinitions (design stub)
**Design stub only — not yet implemented.**
List the existing maintenance cron jobs in the state hub codebase. For each:
- Identify the equivalent ActivityDefinition trigger (cron expression, event type)
- Draft the rule/instruction that would replace the cron logic
- Note any context sources required (state hub API, repo-scoping)
- Flag blockers (e.g., activity-core WP-0003 phase not yet complete)
Output: a markdown table in this workplan and/or in `docs/cron-migration.md`.
### T05 — Document state hub → activity-core delegation protocol
Write `docs/activity-core-delegation.md` explaining:
- Why state hub delegates maintenance automation to activity-core
- Which lifecycle events the state hub publishes and why
- How activity-core ActivityDefinitions react (cross-reference WP-0003)
- What remains in the state hub vs. what moves to ActivityDefinitions
- Operational checklist: what to verify when a maintenance cron is being migrated
### T06 — Update SCOPE.md to reflect activity-core delegation
Update the state hub's SCOPE.md (or write one if missing):
- Add activity-core as a downstream consumer of state hub lifecycle events
- Clarify that maintenance task creation moves to activity-core
- Note that the state hub remains the authoritative *read model* (not a task factory)
## Build Order
```
T01 (NATS publisher) → T03 (wire events)
T02 (subject schema) → T03
T03 → T04 (migration stub, requires events to exist)
T04 → T05 (docs, requires migration list)
T06 (independent — SCOPE.md update)
```
## Completion Criteria
1. State hub publishes at least one lifecycle event type to NATS on relevant writes
2. Subject naming convention documented and agreed with activity-core team
3. Migration stub completed — all existing crons listed with ActivityDefinition drafts
4. Delegation protocol documented
5. SCOPE.md updated
## Notes
- **Sequencing**: complete T01T03 before activity-core WP-0003 is done, so the
first ActivityDefinitions that consume state hub events can be tested end-to-end.
- **No removal yet**: do not remove existing state hub crons until activity-core
ActivityDefinitions are validated in staging. Run both in parallel initially.
- The state hub must never write directly to activity-core's database — only via NATS.
## Change History
- v0.1 (2026-05-14): Stub created by activity-core agent during WP-0003 planning.
Local agent to flesh out and implement.
- v0.2 (2026-05-17): All tasks complete. NATS publisher landed at
`state-hub/api/events/`, lifecycle events wired in repos/workstreams/
decisions/domain_goals routers + cleanup_stale_tasks.py. Subject
schema, cron-migration design stub, delegation protocol docs, and
SCOPE.md updates committed.