Behavior reference
Both the hosted UI flow and the BYOK skill flow implement the same behavioral contract. This page is the reference for what "good Everscribe instrumentation" looks like — what counts as a handler worth recording, what event names look like, how TenantID gets inferred, and when the agent refuses.
What counts as an instrumentable handler
An HTTP handler is a candidate for instrumentation when both are true:
- It mutates state, grants access, or affects auditable account state — auth, billing, admin, data exports, security ops.
- It's reachable via HTTP — i.e. it has a route registration matching one of the framework patterns the SDK supports.
What gets skipped
Even when an endpoint is HTTP-reachable, the agent silently skips these categories:
- Health checks —
/healthz,/health,/ping,/ready - Metrics endpoints —
/metrics,/prometheus,/stats - Static asset routes —
/static,/assets,/public - Documentation routes —
/docs,/swagger,/openapi.json - GET-only listing endpoints that don't mutate or grant access
- Liveness / readiness probes
If you disagree with a skip decision — e.g. a GET endpoint that returns sensitive data you want logged — add the handler back via chat ("instrument GET /v1/admin/exports") in either flow.
Event-naming convention
Event names are dot.separated, past-tense, resource.verb shape:
- ✅
user.password.changed,billing.invoice.refunded,admin.user.impersonated - ❌
changePassword,password_change,Password.Changed
The agent emits a first guess per handler; you can rename inline on the candidate card (hosted UI) or in chat ("rename user.signup to account.created"). Both paths apply the rename before generating the diff.
Categories
Every candidate is tagged with one category from this list. Categories drive how the Events dashboard groups + filters audit events.
| Category | Examples |
|---|---|
auth |
login, logout, MFA enrollment |
authz |
role grants, permission changes |
account |
profile edits, email changes, account deletion |
billing |
invoice issuance, refunds, plan changes |
data |
exports, deletes, bulk operations |
admin |
impersonation, support actions, configuration changes |
security_ops |
key rotation, session revocation, IP allowlist changes |
other |
anything that's auditable but doesn't fit a bucket above |
TenantID inference
For multi-tenant apps, every event carries an optional TenantID so customers running multi-tenant SaaS can scope events per workspace. The agent infers TenantID per handler from the actor's scope:
| Confidence | What it means |
|---|---|
high |
One unambiguous identifier in scope — me.OrganizationID, workspace.ID, tenant.ID, req.user.OrgID |
medium |
Plausible but ambiguous — e.g. multiple OrgID-shaped fields, or the handler accepts an org_id query param |
low |
Nothing clearly identifiable, or multiple plausible candidates that look equally valid |
unknown |
No tenant source in scope — usually pre-auth (POST /login, POST /signup) where the actor isn't bound to a tenant yet |
You can override the agent's pick inline on each candidate card (hosted UI) or in chat. Single-tenant apps can leave TenantID blank on every handler — TenantID is opt-in per event, not required.
Spec source
The canonical statement of this contract lives in docs/auto-instrument-spec.md → Shared instrumentation rules. When the contract changes, it changes there first; both paths track the spec.