Default ISSUE_SINK_TYPE to state-hub (no silent Forgejo issues), hard-fail prune apply without live-images protection, refresh-live-images script, disable TaskExecutor stub by default, and document consumer/sink contracts.
3.2 KiB
Task emission consumer contract
Audience: agent-harness, per-repo Temporal workers, operators.
Owners: activity-core (producer), consumers (executors).
Related: ACTIVITY-WP-0022 (sink policy), ACTIVITY-WP-0023-T02 (executor gap).
activity-core answers when / what / where. It does not execute work. Consumers must pick up emitted tasks and produce domain evidence.
Sink matrix (ACTIVITY-WP-0022)
ISSUE_SINK_TYPE |
Behaviour | When to use |
|---|---|---|
state-hub (default) |
POST State Hub /progress/ with event_type=activity_task_spawn (override via STATE_HUB_TASK_EVENT_TYPE) |
Internal fleet findings; no Forgejo issues |
null |
Synthetic null-* refs in task_spawn_log only |
Dry-run / contract review |
rest |
POST issue-core /issues/ (may project to Forgejo) |
Explicit opt-in only when external tracker issues are intended and backend is healthy |
Unset or unknown values fall back to state-hub (safe default).
Payload: activity_task_spawn (State Hub)
Produced by StateHubProgressSink. Consumers should treat detail as the
authoritative task spec.
{
"event_type": "activity_task_spawn",
"author": "activity-core",
"summary": "<task title, max ~240 chars>",
"detail": {
"task_ref": "sh-<uuid>",
"title": "Run Binky daily rhythm (daily_brief) for 2026-07-21",
"description": "...",
"target_repo": "binky-control",
"priority": "medium",
"labels": ["binky", "rhythm", "automated"],
"source_type": "rule",
"source_id": "emit-daily-rhythm-task",
"triggering_event_id": "manual-… or scheduled",
"activity_definition_id": "<activity uuid>",
"backend": "state-hub-progress"
}
}
Required consumer behaviour
- Idempotency: key on
detail.task_refor(activity_definition_id, triggering_event_id, source_id, title). - Routing: use
target_repo(and labels) to select checkout / lane. - Completion evidence: post a domain progress event when work finishes
(e.g. Binky:
event_type=binky_daily_briefwithdetail.repo=binky-controland date), so rhythm resolvers can setdue=false. - Do not re-implement task lifecycle in activity-core.
Payload: issue-core REST (ISSUE_SINK_TYPE=rest)
See docs/issue-core-emission-boundary.md. task_spawn_log.task_ref is the
issue-core issue_id. Prefer this only for intentional external projection.
Binky daily brief path (reference)
- Schedule / one-shot:
Binky Daily Operating Rhythm. - Context:
binky_rhythm_status→due=truefordaily_brief. - Rule emit → sink (
state-hubrecommended). - Consumer (out of repo): agent-harness or operator session runs
binky-controlOperatingRhythm / brief scripts. - Completion: post
binky_daily_briefprogress so the next fire is not due.
Until a harness consumer is wired, operators may complete the brief manually
and still post the progress event — spawn without completion leaves due=true.
Anti-patterns
- Using
TaskExecutorWorkflowin activity-core for real work (disabled by default; ACTIVITY-WP-0023-T08). - Global
ISSUE_SINK_TYPE=restfor all definitions (reintroduces Forgejo spam). - Treating
task_spawn_logas task status authority.