A successful API call is not necessarily a completed business action. A payment can remain pending, an accepted push can remain undelivered, and a secret update can leave consumers using an older credential. These events report the local operation result at the facade’s driver boundary, not those later outcomes.
Enable the service’s construction-time Events policy and listen on that same
bus. Omitted or nil buses publish nothing. Publication is synchronous and
best effort: listener failures cannot replace returned results, but delay or
stop later observations. Other processes receive nothing automatically.
Do not drive required fulfillment, auditing, or reconciliation solely from these
notifications; use an application-owned durable record.
Payments
payment.Builder.Events enables two topics, both carrying
payment.OperationEvent{Operation, ErrorType}:
| Topic | Name | Driver Result |
|---|---|---|
payment.OperationCompleted |
payment.operation.completed |
Nil error. |
payment.OperationFailed |
payment.operation.failed |
Nonnil error. |
Each validated facade call that reaches the driver and returns publishes one
observation after its telemetry operation ends. Operation is the fixed
snake_case facade operation, such as get_payment or refund_payment.
Validation failures, missing drivers, pre-canceled calls, and provider panics
publish nothing. Cancellation returned after driver dispatch can still publish.
Completion includes reads, pending results, and idempotent replays. It proves neither authorization nor settlement and must not be treated as fulfillment eligibility. The payload omits resource IDs, amounts, keys, references, URLs, handoff secrets, and native errors.
ErrorType is empty on completion. On failure it is a payment sentinel name,
context.Canceled, context.DeadlineExceeded, or unknown.
payment.ErrOutcomeUnknown outranks all joined causes: the provider might have
applied a mutation. Other context classifications precede other payment sentinels.
The returned error retains original causes separately.
To observe uncertainty without exporting provider diagnostics, use context and
payment from arkoren.dev/core/service/payment, with your existing bus and logger:
_, err := bus.Listen(payment.OperationFailed,
func(ctx context.Context, notice payment.OperationEvent) error {
logger.WarnContext(ctx, "payment call failed",
"operation", notice.Operation,
"error_type", notice.ErrorType)
return nil
})
This records the classification, not whether funds moved. Never infer that retry
with a new key is safe. Follow payment recovery for
uncertain outcomes; operation behavior belongs in
hosted checkout,
explicit completion,
refunds, and subscriptions.
See the payment API reference.
Push Notifications
push.Builder.Events enables push.Accepted (push.submission.accepted) and
push.Failed (push.submission.failed). Both carry
SubmissionEvent{Duration, ErrorClass} for the returned driver call from Send.
Nil error selects acceptance; nonnil error selects failure. Preflight rejection,
missing drivers, and provider panics publish neither.
Duration measures driver work, excluding listener execution and telemetry
completion, not device latency. ErrorClass is empty on acceptance; otherwise
it is outcome_unknown, canceled, deadline_exceeded, a push sentinel name,
or error, in that precedence. Unknown acceptance outranks cancellation because
the provider might already have accepted the submission.
Payloads omit recipients, endpoints, tokens, contents, receipts, and native
errors. Acceptance is not delivery or display; failure is not proof that delivery
cannot occur. Native returned errors remain available to the caller and require
separate redaction. Retry and registration cleanup stay application-owned; see
Push Notifications and the
push API reference.
Search
search.Builder.Events enables administrative outcomes only. All three topics
carry MutationEvent{Operation, Duration, ErrorClass}:
| Topic | Name | Observation |
|---|---|---|
search.Synced |
search.index.synced |
Sync returned nil error. |
search.Dropped |
search.index.dropped |
Drop returned nil error. |
search.Failed |
search.index.failed |
Either administrative call returned an error. |
Operation is sync or drop. Duration measures driver work, excluding listener
execution. ErrorClass is empty on success; otherwise context classes canceled
and deadline_exceeded precede known search sentinel names, with error as the
fallback. Native errors, index names, documents, queries, and document IDs are absent.
Sync can succeed without changes, and dropping an absent index can succeed.
Failure can follow partial changes, particularly across multiple indexes; neither
atomicity nor rollback is implied. Check, queries, document writes/deletes,
invalid registrations, and provider panics publish nothing. Deployment procedures
stay in Deploying Search; see the
search API reference.
Secrets
secret.Builder.Events enables secret.MutationSucceeded
(secret.mutation.succeeded) and secret.MutationFailed
(secret.mutation.failed). Both carry MutationEvent{Operation, ErrorType} after
facade Put, Update, or Delete returns from the driver. Nil error selects
success; nonnil error selects failure, including a missing secret.
Operation is put, update, or delete. ErrorType is empty on success;
otherwise it is secret.ErrNotFound, context.Canceled,
context.DeadlineExceeded, or other. Names, versions, values, sizes, and native
diagnostics are omitted. Context cancellation and deadline classifications take
precedence over secret.ErrNotFound. Returned driver errors remain unchanged.
Reads, direct driver/native calls, provider-console updates, and other-process
writes are outside these observations. Success does not prove credential rollout,
global rotation, or permanent erasure; failure does not establish that the
provider made no change. See Managing Secrets and the
secret API reference.