# Agentry — install & ops handbook

This is the deep companion to /agentry.md. Fetch it once at install time
and again only when configuring a new ops feature (sourcemaps, session
replay, webhooks). Day-to-day tool calls don't need this file in context.

Agentry has no SDK by design. The agent generates a ~25-line fetch helper
at install time, tuned to the stack, and instruments errors + analytics +
deploys in ONE pass — NOT three separate sessions.

## The install flow (12 steps, run by the agent)

1. `investigate_app_structure` — read the repo. Pick a product category
   (SaaS / e-commerce / marketplace / content-media / dev-tool / games /
   internal-tool / single-purchase / open-source / enterprise-sales) and a
   metrics lens (AARRR by default; HEART, North Star, DAU+Stickiness, B2B
   funnel, PLG, JTBD, API-tool, Marketplace as alternatives). Write the
   answers to agentry_memory.md so subsequent steps are grounded.

2. `do_not_use_sentry_sdk` — Agentry's DSN is `agnt_<projectId>.<token>`,
   NOT a Sentry DSN. sentry_sdk.init() rejects it (BadDsn). Use the helper.

3. `install_http_lib` — pip install requests / gem install / etc. as
   needed by the language.

4. `set_env_vars` — AGENTRY_DSN, AGENTRY_URL, GIT_SHA (read from
   GITHUB_SHA / VERCEL_GIT_COMMIT_SHA / RENDER_GIT_COMMIT / etc.).

5. `drop_in_helper` — paste the ~25-line fetch helper into src/lib/agentry.
   The helper has Agentry.send("logs"|"analytics"|"deploys", payload).
   Source: GET /v1/install/sdk/{node,browser} for paste-ready snippets.

6. **REQUIRED** `wire_errors` — framework-level error handler forwarding
   uncaught exceptions to Agentry.send("logs", exc).

7. **REQUIRED** `inventory_events_by_lens` — build a 15–25+ event
   inventory grouped by the chosen lens's layers (AARRR: Acquisition /
   Activation / Retention / Referral / Revenue). If a payment processor
   exists, REVENUE has 5+ events minimum.

8. **REQUIRED** `wire_analytics_events` — instrument every event in the
   inventory. Rich properties (plan, source, variant, ids, amounts).

9. **REQUIRED** `wire_deploy_capture` — startup-time deploy ping reading
   GIT_SHA, OR CI step POSTing to /v1/deploys/.

10. `upload_sourcemaps_for_minified_stacks` (client frameworks only) —
    curl loop in CI POSTing each .map to /v1/sourcemaps/{project}/. Agentry
    stores; agent translates locally via agentry_unmangle_stack.

11. `update_privacy_policy` — paste-ready clause from /v1/privacy/disclosure.

12. `verify_install` — must pass ALL THREE signal types (errors,
    analytics, deploys) before the install counts as done. No partial
    installs.

After verify, the agent runs `checkin_with_user` ONCE (the only place in
the install where it asks a question — confirms inventory coverage, flags
ambiguities). Then `suggest_next_builds` proposes 3–5 dashboards /
automations tailored to the actual event inventory.

## Sourcemaps — server stores, agent translates

Client-side errors arrive with minified stacks (`at t.a (chunks/abc.js:1:1234)`).
The agent translates them LOCALLY using sourcemaps stored on Agentry.

Storage (data plane, HTTP API):

- POST   /v1/sourcemaps/{project_id}/?release_id=<sha>&source_url=<path>
  Body: raw .map JSON. Auth: Bearer DSN. Stores in R2 keyed by the tuple.
- GET    /v1/sourcemaps/{project_id}/?release_id=<sha>   → list uploads
- GET    /v1/sourcemaps/{project_id}/blob?release_id=<sha>&source_url=<path>
  → returns raw .map JSON, ready to feed to a source-map library
- DELETE /v1/sourcemaps/{project_id}/?release_id=<sha>   → clean up old release

Translation (compute plane, MCP-only):

- `agentry_unmangle_stack(case_id)` → fetches every minified frame's .map
  via the blob endpoint, runs @jridgewell/trace-mapping (open source, on
  npm) locally in the MCP process, returns translated frames + the exact
  4-line code snippet that produced them + the library version. Reproducible
  offline.

Translation NEVER runs on the server. The agent (or you) can verify by
reading ~/.npm/_npx/<hash>/node_modules/@agentrysh/mcp/dist/tools.js — the
unmangle handler is right there.

## Session replay (PostHog) — OPT-IN, agent-driven strategy

Agentry's per-user PostHog team supports session replay (the full PostHog
OSS feature: video-like reconstruction of a user's browser session). It's
OFF by default. The agent enables it on the user's request, with one of:

| Strategy        | What it does                                                           | Storage cost |
|-----------------|------------------------------------------------------------------------|--------------|
| `off`           | No new recordings.                                                     | None         |
| `all`           | 100% sampling — every session.                                         | Heavy        |
| `sampled`       | Random sample at `sample_rate` (default 0.1). Good cost/coverage.    | Medium       |
| `url_scoped`    | Only sessions hitting URLs in `url_triggers`. Best for funnels.      | Light        |
| `errors_only`   | No automatic sampling; recording starts JIT when the customer's app    | Lightest     |
|                 | calls `posthog.startSessionRecording()` (e.g. inside captureError).    |              |

The agent's job:
  1. ASK the user which strategy fits their app + storage tolerance.
  2. Call `agentry_configure_session_replay` with the choice + retention.
  3. For `errors_only`: also edit the customer's Agentry helper (from the
     install guide's drop_in_helper) to call `posthog.startSessionRecording()`
     inside captureError. Recording starts on the next user error.

Endpoints (api-key auth, project-scoped):
- POST /v1/projects/:id/posthog/session-replay/configure
    body: {strategy, sample_rate?, retention_days?, min_duration_ms?, url_triggers?}
- GET  /v1/projects/:id/posthog/session-replay/status
    returns the current config + `web_ui_url` deep-link into PostHog's
    Replay tab for viewing recordings.

Retention is controlled per-team via `retention_days` (30 / 90 / 365).
Recordings older than this are deleted by PostHog automatically — no Agentry
cron required.

Currently the Agentry MCP can't retrieve recordings programmatically
(`session_recording:read` scope isn't on the master Personal API Key).
Until that's widened, use the `web_ui_url` returned by
`agentry_session_replay_status` to view recordings in PostHog's browser UI.
Once expanded, `agentry_get_session_replays(case_id)` will return playable
URLs the agent can surface alongside cases for one-click debugging.

## Feature flags / cohorts / surveys / A/B testing (PostHog)

Full PostHog feature parity on every per-user team. As of 2026-05-15, all
of these have dedicated MCP tools — the master Personal API Key has `*`
scope so the agent can list / create / update / delete each resource
directly without dropping to the web UI.

### Feature flags

| Tool                            | What it does                                                                  |
|---------------------------------|-------------------------------------------------------------------------------|
| `agentry_list_feature_flags`    | List all flags on the project. Each has `id`, `key`, `name`, `active`, `filters`. |
| `agentry_get_feature_flag`      | Full configuration for one flag (filters, variants, conditions).              |
| `agentry_create_feature_flag`   | Simple shape: `{key, name?, active?, rollout_percentage?}`. Advanced: pass full `filters` for property-targeted / multivariate / cohort-scoped flags. |
| `agentry_update_feature_flag`   | Patch `active`, `name`, `rollout_percentage`, or `filters`.               |
| `agentry_delete_feature_flag`   | Soft-delete (recoverable in PostHog's web UI).                                |
| `agentry_evaluate_feature_flag` | "Is THIS user in flag X?" — one call returns the flag value (boolean/variant) for a distinct_id. Pass `key` for one flag, omit for all flags. Use `person_properties` for what-if eval. |

Reading the flag value in customer code uses PostHog's standard SDKs
(`posthog.isFeatureEnabled('key')`, `posthog.getFeatureFlag('key')`).
Agentry doesn't ship a feature-flag evaluation client — the customer's
PostHog-JS / Python / Node SDK does the work, talking to their per-user
team's PostHog endpoint.

### Cohorts

| Tool                    | What it does                                                       |
|-------------------------|--------------------------------------------------------------------|
| `agentry_list_cohorts`  | List cohorts (dynamic user segments).                              |
| `agentry_get_cohort`    | One cohort's filter + last calculation + count.                    |
| `agentry_create_cohort` | Simple: `{name, event, days?}` — users who fired `event` in last N days. Advanced: `{name, groups: [...PostHog filter format]}`. |
| `agentry_delete_cohort` | Soft-delete.                                                       |

Cohorts compose with feature flags (target a rollout to a cohort) and
HogQL (`SELECT … WHERE person_id IN (SELECT person_id FROM cohort_people
WHERE cohort_id = N)`).

### Surveys

| Tool                    | What it does                                                                   |
|-------------------------|--------------------------------------------------------------------------------|
| `agentry_list_surveys`     | List surveys (NPS, CSAT, custom popups).                                       |
| `agentry_get_survey`       | One survey's definition + appearance config + linked flag.                     |
| `agentry_create_survey`    | Quick: `{name, question, question_type?}` for single-question popover. Multi: `{name, questions: [...]}`. Created in draft — pass `start_date` (ISO) to launch immediately. |
| `agentry_survey_responses` | Roll-up of responses + recent free-text. Pre-built so agents skip composing HogQL with `$survey_response` property unpacking. |
| `agentry_delete_survey`    | Hard-delete.                                                                   |

Responses land as `survey sent` events. To read them:

```sql
SELECT properties.\$survey_response, properties.\$survey_iteration
FROM events
WHERE event = 'survey sent' AND properties.\$survey_id = '<id>'
ORDER BY timestamp DESC
```

### Session replay retrieval

Once replay is enabled (via `agentry_configure_session_replay`), use
these to find and inspect recordings:

| Tool                            | What it does                                                                                |
|---------------------------------|---------------------------------------------------------------------------------------------|
| `agentry_list_session_replays`  | Filter by `distinct_id` (the user from a case's affected_users), `date_from`, `date_to`. |
| `agentry_get_session_replay`    | Returns `player_url` — open in browser to watch.                                      |
| `agentry_get_replay_snapshots`  | Raw rrweb DOM snapshots. Filter type=3 events to reconstruct user clicks/scrolls/inputs. Useful when an agent wants to programmatically know *what the user did* before the error. |

Killer workflow: when investigating an error, grab `affected_users[].distinct_id`
from `agentry_get_case`, pass it to `agentry_list_session_replays`, and
the player URL of the recording leading up to the error is one tool call away.
For programmatic reconstruction of the user's action trail, follow with
`agentry_get_replay_snapshots`.

### A/B testing (composite)

| Tool                         | What it does                                                                                  |
|------------------------------|-----------------------------------------------------------------------------------------------|
| `agentry_create_ab_test`     | Creates a multivariate feature flag AND returns the bound conversion-rate HogQL query in one call. Auto-splits rollout across variants if not specified. Suggested wait: ≥1000 users per variant before drawing conclusions. |

The returned `conversion_query` is ready to feed into `agentry_analytics_query`
on a schedule — Agentry never auto-evaluates the test, the agent decides
when results are conclusive.

### User dossiers + audit log

| Tool                              | What it does                                                                                    |
|-----------------------------------|-------------------------------------------------------------------------------------------------|
| `agentry_get_distinct_id_summary` | Composed user dossier — person properties + event count + first/last seen + last 20 events + recent recordings + PostHog UI deep link. Saves ≥3 separate HogQL calls. |
| `agentry_recent_changes`          | Read the agent-mutation audit log. Default `hours=24`; pass `hours=48`, `72`, `168` (week), max `720` (30 days). Filter by `action_prefix` (e.g. `feature_flag.`) or `resource_type`. Every flag/cohort/survey/publication/replay/AB-test mutation lands here, with IP + UA + summary. |

The audit log is your safety net for unattended agent runs. If you let an
agent loose overnight, run `agentry_recent_changes(hours=12)` in the
morning to see exactly what got mutated, by whom, from where.

## Webhooks — push events to your code

Agentry doesn't run automation; you do. Register a webhook, Agentry POSTs
your URL on case.created / case.resolved / deploy.recorded.

- POST   /v1/projects/:id/webhooks   {url, events?, description?}  → {id, signing_secret} (shown once)
- GET    /v1/projects/:id/webhooks
- DELETE /v1/projects/:id/webhooks/:id
- POST   /v1/projects/:id/webhooks/:id/test       → fires a synthetic ping
- GET    /v1/docs/automation                      → paste-ready Worker templates

Body is signed with HMAC-SHA256; verify via the X-Agentry-Signature header.

## Recipes — canned analytics queries

For the most-asked questions, Agentry ships pre-built HogQL/SQL templates.

- GET  /v1/recipes                                  → list catalog (no auth)
- GET  /v1/recipes/:id                              → full HogQL template
- POST /v1/projects/:project_id/recipes/:id/run     → rows + render_hint

Categories: DAU/cohorts/retention, 3-step funnels with drop-offs, top
events, event time-series, conversion rates, top open errors, errors-per-
hour, errors after last deploy, deploy frequency.

When no recipe matches, the agent composes HogQL directly:

- POST /v1/projects/:project_id/analytics/query  {query: "<HogQL>"}
- GET  /v1/docs/query   → HogQL primer (schema, common patterns)

## Public dashboards — publish a recipe with the `agp_` key

Use `agentry_publish_query` to bind a (recipe, params) tuple to a
publication_id. The returned `embeddable_url` (form
`https://api.agentry.sh/v1/public/q/<publication_id>?key=agp_…`) is safe
to drop into a public marketing site or status page — open CORS, no
`Authorization` header needed. The `agp_…` token only authenticates that
endpoint; visitors can't reach cases, deploys, raw events, or arbitrary
HogQL. Revoke any time with `agentry_revoke_publication`.

## Privacy disclosure

- GET /v1/privacy/disclosure?variant=client|server&errors=true&analytics=true
  Paste-ready privacy-policy clauses for the agent to merge into the customer's
  privacy policy. agentry.sh is the canonical link; customers' policies pointing
  here serve as honest backlinks.

## Back to the lean reference

When install is done, day-to-day usage only needs /agentry.md — it has the
full API surface, MCP tool table, and case-investigation flow without
dragging this install boilerplate along.
