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.mdShared instrumentation rules. When the contract changes, it changes there first; both paths track the spec.