generated from coulomb/repo-seed
Issue-core requires a shared ingestion key on POST /issues/. The REST sink now sends Authorization: Bearer using ISSUE_CORE_API_KEY and fails fast when the key is missing under ISSUE_SINK_TYPE=rest. Updates .env.example, emission boundary docs, and unit tests for the header contract and missing-key error.
73 lines
2.6 KiB
Markdown
73 lines
2.6 KiB
Markdown
# Issue-Core Emission Boundary
|
|
|
|
activity-core owns the decision to spawn a task and the audit trail that says
|
|
why it spawned. It does not own downstream task lifecycle state after emission.
|
|
|
|
## Current authoritative endpoint
|
|
|
|
The current authoritative boundary is the issue-core REST API:
|
|
|
|
```text
|
|
POST {ISSUE_CORE_URL}/issues/
|
|
```
|
|
|
|
`IssueCoreRestSink` authenticates with the shared `ISSUE_CORE_API_KEY` env var
|
|
(same value as the issue-core server) via `Authorization: Bearer <key>` and
|
|
sends this payload:
|
|
|
|
```json
|
|
{
|
|
"title": "Run SBOM rescan for activity-core",
|
|
"description": "",
|
|
"target_repo": "activity-core",
|
|
"priority": "medium",
|
|
"labels": ["sbom", "security", "automated"],
|
|
"due_in_days": null,
|
|
"source_type": "rule",
|
|
"source_id": "flag-stale-sbom",
|
|
"triggering_event_id": "event-or-schedule-key",
|
|
"activity_definition_id": "activity-definition-uuid"
|
|
}
|
|
```
|
|
|
|
The expected response contains `issue_id` and may include `issue_url` and
|
|
`backend`. activity-core stores only the returned task reference in
|
|
`task_spawn_log`; issue-core remains authoritative for task status, assignment,
|
|
comments, closure, and cancellation.
|
|
|
|
## REST versus NATS
|
|
|
|
Keep REST as the active emission contract until issue-core publishes and owns a
|
|
durable NATS consumer for task-creation commands. NATS is still appropriate for
|
|
event intake into activity-core, but task creation needs an acknowledged,
|
|
idempotent command boundary. A future NATS sink must return or later correlate a
|
|
task reference before it can replace `IssueCoreRestSink`.
|
|
|
|
## Safe operating modes
|
|
|
|
- `ISSUE_SINK_TYPE=null`: dry-run/audit mode. Task specs are rendered and the
|
|
workflow records synthetic `null-*` references. This is the current Railiance
|
|
production setting.
|
|
- `ISSUE_SINK_TYPE=rest`: live task creation. Sink failures raise out of
|
|
`emit_tasks`, so Temporal retries and the workflow history make failures
|
|
visible.
|
|
|
|
Weekly SBOM staleness is safe to evaluate in dry-run mode because the rule
|
|
contract is deterministic and tested. Do not enable it against the real REST sink
|
|
until `ISSUE_CORE_API_KEY`, endpoint reachability, and duplicate-handling are
|
|
verified in the target environment.
|
|
|
|
## Verification
|
|
|
|
Local contract tests cover the rendered weekly SBOM task path and the REST
|
|
payload shape:
|
|
|
|
```bash
|
|
uv run pytest tests/test_integration_event_bridge.py tests/test_issue_sink.py
|
|
```
|
|
|
|
For a live environment, run with `ISSUE_SINK_TYPE=null` first and confirm
|
|
`task_spawn_log` contains the expected source id, condition, triggering event id,
|
|
and synthetic task reference. Then switch to `ISSUE_SINK_TYPE=rest` only after a
|
|
single known-safe rule match creates one issue-core task with the same fields.
|