ArkNotify
ArkNotify defines a reusable notification policy that routes team run events to Slack or webhook channels with configurable rate limiting.
API: arkonis.dev/v1alpha1
Kind: ArkNotify
Short name: anfy
Scope: Namespaced
ArkNotify is a reusable notification policy. Attach it to an ArkTeam via spec.notifyRef to receive alerts when runs succeed, fail, time out, or hit token budgets. Attach it to an ArkAgent to be notified when agents degrade.
Events
| Event | Fired when |
|---|
TeamSucceeded | An ArkRun reaches Succeeded phase. |
TeamFailed | An ArkRun reaches Failed phase. |
TeamTimedOut | A run hits spec.timeoutSeconds. |
BudgetExceeded | A run hits spec.maxTokens. |
DailyLimitReached | The team’s rolling 24h budget is consumed; replicas scaled to 0. |
AgentDegraded | An ArkAgent semantic health check fails. |
Omit spec.on to receive all events.
Example: Slack on failure
apiVersion: arkonis.dev/v1alpha1
kind: ArkNotify
metadata:
name: on-failure-slack
namespace: my-org
spec:
on:
- TeamFailed
- TeamTimedOut
- BudgetExceeded
rateLimitSeconds: 300
channels:
- type: slack
slack:
webhookURLFrom:
name: slack-secrets
key: incoming-webhook-url
Attach to a team:
apiVersion: arkonis.dev/v1alpha1
kind: ArkTeam
metadata:
name: blog-pipeline
spec:
notifyRef:
name: on-failure-slack
Example: Generic webhook on all events
apiVersion: arkonis.dev/v1alpha1
kind: ArkNotify
metadata:
name: audit-all
namespace: my-org
spec:
rateLimitSeconds: 0 # no rate limiting
channels:
- type: webhook
webhook:
urlFrom:
name: audit-secrets
key: webhook-url
headers:
- name: Authorization
valueFrom:
name: audit-secrets
key: token
template: |
{{ .Event }} — {{ .TeamName }}/{{ .RunName }}
{{ .Message }}
Rate limiting
rateLimitSeconds prevents notification storms. After one notification fires for a (team, event) pair, subsequent fires are suppressed until the window passes.
- Tracked per
(team, event) pair — TeamFailed and BudgetExceeded are independent. - Default:
300 seconds (5 minutes). - Set to
0 to disable.
Spec reference
spec
| Field | Type | Required | Default | Description |
|---|
on | []string | no | all events | Event types that trigger notifications. Valid values: TeamSucceeded, TeamFailed, TeamTimedOut, BudgetExceeded, DailyLimitReached, AgentDegraded. |
channels | []ChannelSpec | yes | — | Notification targets. At least one required. |
rateLimitSeconds | int | no | 300 | Minimum interval between notifications for the same (team, event) pair. 0 to disable. |
spec.channels[]
| Field | Type | Required | Description |
|---|
type | string | yes | webhook or slack. |
webhook | WebhookChannelSpec | webhook only | HTTP POST target configuration. |
slack | SlackChannelSpec | slack only | Slack incoming webhook configuration. |
template | string | no | Go template for the message body. |
channels[].webhook
| Field | Type | Required | Default | Description |
|---|
url | string | one of | — | Literal webhook URL. |
urlFrom | SecretKeySelector | one of | — | Read the URL from a Secret key. Takes precedence over url. |
method | string | no | POST | HTTP method. |
headers | []WebhookHeader | no | — | Additional HTTP headers. |
| Field | Type | Required | Description |
|---|
name | string | yes | HTTP header name. |
value | string | one of | Literal header value. |
valueFrom | SecretKeySelector | one of | Read value from a Secret key. |
channels[].slack
| Field | Type | Required | Description |
|---|
webhookURLFrom | SecretKeySelector | yes | Secret key containing the Slack incoming webhook URL. |
Message template context
| Field | Type | Description |
|---|
.Event | string | Event type string, e.g. "TeamFailed" |
.TeamName | string | ArkTeam name |
.RunName | string | ArkRun name (empty for AgentDegraded) |
.Phase | string | Terminal phase of the run |
.Namespace | string | Kubernetes namespace |
.Message | string | Human-readable detail |
.FiredAt | time.Time | When the notification was dispatched |
status
| Field | Type | Description |
|---|
lastDispatches | []DispatchResult | Most recent dispatch result per channel. |
conditions | []Condition | Ready. |
status.lastDispatches[]
| Field | Type | Description |
|---|
channelIndex | int | Zero-based index into spec.channels. |
lastFiredAt | Time | When the most recent dispatch attempt was made. |
lastEvent | string | Event type that triggered the dispatch. |
succeeded | bool | false when all retry attempts failed. |
error | string | Last error message when succeeded is false. |
See also