> ## Documentation Index
> Fetch the complete documentation index at: https://docs.paradime.io/llms.txt
> Use this file to discover all available pages before exploring further.

# MongoDB schema drift triager

> Build a Jira-driven DinoAI agent that picks up agent-ready tickets, verifies the requested dbt™ change against MongoDB and Snowflake, and ships it as a PR.

The MongoDB schema drift triager is a Jira-driven DinoAI agent: it picks up tickets labelled `agent-ready`, works out the dbt™ change each ticket is asking for, verifies the change against live data before touching the repo, and ships it as a PR. It was built for planned MongoDB schema evolution (the drift is announced in a ticket before or as it lands), but the pattern is generic: column renames, new models, source or test additions, any repo-local dbt™ edit a ticket can scope. It is read-only on Jira, so the PR description is the link back to the ticket.

<Note>
  **Prerequisites**

  * [Jira connected](/integrations/jira) so the agent can call `list_jira_issues` and `get_jira_issue` (read-only: it never comments or transitions tickets).
  * A [MongoDB connection](/products/dino-ai/tools-and-features/warehouse-tool/mongodb-tools) so the agent can verify drift against the source collection.
  * A warehouse connection (the agent confirms landed columns and types via `run_sql_query`).
  * [Slack connected](/integrations/slack) (the agent posts a note when the queue is empty or a discrepancy blocks a ticket).
  * Your repository connected so the agent can branch, commit, and open PRs.
  * Tickets to automate must carry the label `agent-ready` and not be done.

  Estimated time: 15 minutes.
</Note>

## Steps

<Steps>
  <Step title="Create the agent">
    In the **Agent** app, open **Agents**, select **New agent**, and choose **Start from scratch**. Fill in the builder fields below, leave **Model** on **Auto**. See [Build an agent in the UI](/guides/programmable-agents/build-in-the-agent-ui) for a tour of the builder.

    **Name**: `mongodb-schema-drift-triager`

    **Role**:

    ```text theme={"system"}
    Jira-driven dbt change resolver. Picks up tickets labelled
    "agent-ready", figures out the dbt change the ticket is asking for,
    and ships it as a PR. Generic — the change can be a schema-drift
    accommodation (e.g. MongoDB source evolution), a column rename, a
    new model, a source/test addition, or any other repo-local dbt edit
    the ticket scopes. Read-only on Jira: cannot comment, change labels,
    or move status; the PR description is the link back to the ticket.
    ```

    **Goal**:

    ```text theme={"system"}
    Resolve ONE Jira ticket per invocation, end-to-end.

    Steps (run in order):

    1. Find the ticket.
       - If the trigger message contains a ticket key (e.g. DATA-123)
         or a full Jira URL, use that one.
       - Otherwise call list_jira_issues with the JQL
         labels = "agent-ready" AND statusCategory != "Done"
         ORDER BY created ASC and pick the OLDEST open one.
       - State the chosen ticket key up front. If no eligible ticket
         exists, post a short Slack note and exit cleanly.

    2. Read the ticket. If a required detail is missing, state your
       assumption and proceed.

    3. Confirm against live data when the change depends on external
       state. Examples:
         - MongoDB drift → mongodb_collection_schema + mongodb_count /
           mongodb_aggregate + 2–3 mongodb_find samples to verify the
           documented change matches what's actually in the collection.
         - Warehouse source change → run_sql_query against the relevant
           table to confirm columns/types.
         - Repo-only refactor (rename, test add) → skip this step.
       Never edit dbt for a change that hasn't actually landed yet —
       if the ticket and the live data disagree, post the discrepancy
       to Slack, reference it in no PR, and stop.

    4. Plan the edit. Read the affected dbt files (staging model + YAML,
       mart, sources, tests) and the surrounding project for downstream
       consumers via ripgrep_search. Identify the minimum additive set of
       edits — never silently drop a column a downstream mart may still
       use. For drift, prefer COALESCE-style fallbacks so both old and
       new shapes are supported during the transition.

    5. Apply the edits. Update SQL, YAML docs, tests, and source
       declarations as needed. Run `dbt parse` (or `dbt compile`) to
       verify the project still parses before opening the PR — if it
       doesn't, fix or back out and re-plan.

    6. PR. Branch agent/<ticket-key>-<short-slug>, commit with a clear
       message referencing the Jira key. PR description must include:
         - link back to the Jira ticket (the PR is the only feedback
           channel — there is no comment back on the ticket)
         - one-line summary of the change requested
         - files changed and why
         - per-criterion mapping from each acceptance criterion in the
           ticket to where it's addressed in the diff
         - any live-data evidence captured in step 3 (counts, sample
           docs, schema diff)

    One PR per ticket. No bundling across tickets. If the ticket scope
    is larger than one PR (e.g. multi-model rewrite), open the first
    PR addressing the most-upstream piece and list the follow-up PRs
    you'd recommend in the PR description.
    ```

    **Backstory**:

    ```text theme={"system"}
    Act immediately — no confirmation prompts, no "shall I proceed?". If
    something is ambiguous, state your assumption and continue. The Jira
    ticket is the source of intent (what change the team agreed to
    make); live data (MongoDB, the warehouse, the repo itself) is the
    source of truth (what's actually there right now). When the two
    disagree, surface the discrepancy in the PR description and on
    Slack, then proceed based on what the live data says.

    Prefer surgical, additive edits. The goal is a model that supports
    both the old and new shapes during a transition, not a "clean
    v2-only" rewrite. For non-drift changes (renames, new models, test
    adds) keep edits scoped to what the ticket actually asks for —
    don't refactor neighbouring code.

    Only work on ONE ticket per invocation. If multiple tickets carry
    the "agent-ready" label, pick the oldest, ship its PR, and let the
    next invocation pick up the next one — bundling tickets together is
    forbidden because each one needs its own reviewer round-trip.
    ```

    **Allowed tools** (everything else is refused, see the [Tools Reference](/products/dino-ai/programmable-agents/tools-reference)):

    * `get_jira_issue`, `list_jira_issues`
    * `list_mongodb_collections`, `mongodb_collection_schema`, `mongodb_count`, `mongodb_aggregate`, `mongodb_find`
    * `run_sql_query`
    * `read_file`, `write_file`, `replace_in_file`, `search_files_and_directories`, `ripgrep_search`
    * `run_terminal_command`
    * `post_slack_message`

    **Output**: set the Slack channel to `#dinoai-demo` (or your team's channel, updating the channel in the Goal to match).

    <Info>
      The Jira allowlist is deliberately read-only: no `add_jira_comment` or `update_jira_issue`. This agent never writes to the ticket, so it can safely run against a Jira project the data team does not own; all its output lands in the PR and Slack. If you want the full ticket lifecycle (status transitions and comments), use the [Jira change request agent](/guides/programmable-agents/jira-change-request-agent) pattern instead.
    </Info>
  </Step>

  <Step title="Deploy the agent">
    Select **Deploy** and choose where the agent lives: **Just here** saves it to the workspace and makes it live immediately, **Open a pull request** commits it to your repo as `.dinoai/agents/mongodb-schema-drift-triager.yml` so it is governed as code. Both appear in the Bolt agent picker. See [Creating Agents in the App](/products/dino-ai/programmable-agents/creating-agents-in-the-app).
  </Step>

  <Step title="Run it with Bolt">
    On the **Agents** page, hover the agent card and select **Schedule**. This opens a new Bolt schedule with the **Run Paradime DinoAI Agent** command already added and the agent pre-selected. The command runs natively, so no API keys or environment variables are needed. Set the **Task**:

    ```text theme={"system"}
    Resolve the oldest open agent-ready Jira ticket end to end.
    ```

    Because the agent resolves one ticket per invocation, pick a cadence that matches your ticket volume: `0 9 * * 1-5` (weekdays at 9 AM) drains one ticket per day, or add the same command several times to the schedule to process several tickets per run. To point a run at a specific ticket, put the key in the task: `Resolve DATA-123.` See [Run an agent with Bolt](/guides/programmable-agents/run-an-agent-with-bolt) for the full walkthrough.
  </Step>
</Steps>

<Check>
  After a run, the oldest `agent-ready` ticket has one PR on an `agent/<ticket-key>-<slug>` branch whose description links the ticket, maps each acceptance criterion to the diff, and embeds the live-data evidence (counts, sample documents, schema diff). When the queue is empty the agent posts a short Slack note and exits cleanly. When the ticket describes a change the live data does not confirm, no PR is opened and the discrepancy lands in Slack instead.
</Check>

## How it works

The agent separates **intent** from **truth**: the Jira ticket says what the team agreed to change, but before editing anything it checks that the change actually landed, sampling the MongoDB collection for drift tickets or querying the warehouse for source changes. A ticket that describes drift that has not happened yet produces a Slack discrepancy note, not a broken model. Because Jira access is read-only, the PR description carries everything a reviewer needs: the ticket link, the acceptance-criteria mapping, and the evidence.

```text theme={"system"}
1. Pick ticket: from the trigger message, or oldest open "agent-ready"
2. Read ticket → intended change
3. Verify against live data (Mongo schema/samples, warehouse columns)
   → mismatch: Slack note, stop; no PR
4. Plan minimum additive edit; check downstream consumers
5. Edit SQL/YAML/tests; dbt parse must pass
6. One PR per ticket: link, criteria mapping, evidence
```

Compare the two MongoDB drift agents: the [schema drift healer](/guides/programmable-agents/mongo-schema-drift-healer) is **reactive** (a pipeline already failed; self-healing hands it the error log), while this triager is **proactive** (the drift is announced in a ticket and handled before or as it breaks anything). Teams running both cover planned and unplanned drift with the same additive-patching conventions.

## Next steps

<CardGroup cols={2}>
  <Card title="MongoDB schema drift healer" href="/guides/programmable-agents/mongo-schema-drift-healer" icon="workflow">
    The reactive variant, triggered by self-healing on failure.
  </Card>

  <Card title="Jira change request agent" href="/guides/programmable-agents/jira-change-request-agent" icon="ticket">
    The Jira-writing variant with status transitions and comments.
  </Card>

  <Card title="Run an agent with Bolt" href="/guides/programmable-agents/run-an-agent-with-bolt" icon="rocket">
    Trigger agents from a Bolt schedule.
  </Card>

  <Card title="MongoDB tools reference" href="/products/dino-ai/tools-and-features/warehouse-tool/mongodb-tools" icon="database">
    The read-only MongoDB tools this agent uses.
  </Card>
</CardGroup>


## Related topics

- [MongoDB schema drift healer](/guides/programmable-agents/mongo-schema-drift-healer.md)
- [MongoDB](/integrations/mongodb.md)
- [MongoDB Tools](/products/dino-ai/tools-and-features/warehouse-tool/mongodb-tools.md)
- [Integrations](/integrations/index.md)
- [Tools Reference](/products/dino-ai/programmable-agents/tools-reference.md)
