Skip to content

feat(dq): add create_dq_job + prepare_create_dq_job MCP tools#88

Open
vvaks0 wants to merge 7 commits into
mainfrom
feat/dev-197672-create-dq-job
Open

feat(dq): add create_dq_job + prepare_create_dq_job MCP tools#88
vvaks0 wants to merge 7 commits into
mainfrom
feat/dev-197672-create-dq-job

Conversation

@vvaks0

@vvaks0 vvaks0 commented Jul 1, 2026

Copy link
Copy Markdown

🎯 What does this PR do?

Adds a guided, multi-turn data-quality job creation flow for DEV-197672.

  • prepare_create_dq_job (read-only) walks the discovery chain — resolves the edge connection, detects the job type (PUSHDOWN/PULLUP) from its capabilities, and enumerates data sources, schemas, tables and columns — returning a ready-to-use plan. It also resolves the location from a catalog Table asset (id / URL / name) for the table-asset-page entry point.
  • create_dq_job builds and submits the job via the PUBLIC DQ API (POST /rest/dq/1.0/jobs) behind a confirm-checkpoint preview. Supports column selection, a single-column row filter, row sampling, time-slice scheduling (${rd}/${rdEnd} composed into a dialect-aware source query), recurring schedules, monitors + adaptive settings, notifications, Pullup sizing / Parallel JDBC, and Pushdown compute.
  • Discovery uses internal BFF endpoints, since the public DQ API exposes no connection/edge metadata browse.

Validated end-to-end on a live stack: create -> persist -> run FINISHED.

Refs: DEV-197672

✅ Checklist

  • My code follows the style guidelines of this project.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have made corresponding changes to the documentation (if needed).
  • My commit messages follow the Conventional Commits standard.

@vvaks0
vvaks0 requested a review from a team as a code owner July 1, 2026 20:27
Comment thread pkg/tools/prepare_create_dq_job/tool.go Outdated
return &chip.Tool[Input, Output]{
Name: "prepare_create_dq_job",
Title: "Prepare to Create Data Quality Job",
Description: "Read-only companion to create_dq_job. Walks the data-quality wizard's discovery chain — resolve the edge " +

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vvaks0 I would be careful with too many Collibra-coded words within this which LLMs might have a challenge understanding. I know this is a companion tool, but it might make sense to explain a bit more what create_dq_job is, as well as be more explicit with words like 'job', 'edge', etc

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@EricWarnerCollibra My one concern is that job might be too generic and could collide with other tools. Would you prefer we unpack dq to data_quality?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vvaks0 yes, for sure on the tool name. I also might suggest adding more detail in the description, as an LLM may be viewing this tool independently. Overall, a few examples of user questions per tool, especially ones that are vague, are really helpful for us to understand behavior via evaluations

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aberkowCollibra

Copy link
Copy Markdown

@vvaks0 do we have tests on the DQ side to ensure these API contracts will not change and will fail if someone modifies?

@aberkowCollibra

Copy link
Copy Markdown

@vvaks0

  1. We'd like any DQ admin tools (create/edit/delete) behind a flag, similar to --experimental  we have for the Data Product skills
  2. We need more in depth descriptions
  3. We need to map to personas. I'm told existing examples in repo. https://engineering-collibra.atlassian.net/wiki/spaces/AIENG/pages/19152601130/Chip+Tool+Personas+and+Permission+Mapping?atlOrigin=eyJpIjoiNjY2YzdkOGZhNDA1NDUwN2JmMTI0MzM2MTAzYzYxYjgiLCJwIjoiY29uZmx1ZW5jZS1jaGF0cy1pbnQifQ

vvaks0 added a commit that referenced this pull request Jul 15, 2026
…imental, clarify descriptions

Addresses review feedback on #88.

- Drop the internal /jobs/name, /jobs/{name}/exists, and /jobs/{name}/validJobName
  calls. Naming now relies on the PUBLIC create API: omitting jobName lets the server
  auto-assign a collision-free name (returned in the response); a user-supplied name
  is validated client-side against the server's rules (charset + no leading hyphen).
- Rename the tools to create_data_quality_job / prepare_create_data_quality_job and
  expand their descriptions with plain-language framing (job/edge/connection) plus
  example user requests, for better LLM comprehension and evaluations.
- Gate both tools behind a new "data-quality" experimental feature (off by default),
  like the Data Product skills, since they write to Collibra.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@svc-snyk-github-jira

svc-snyk-github-jira commented Jul 15, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

vvaks0 and others added 2 commits July 15, 2026 19:43
Adds a guided, multi-turn data-quality job creation flow for DEV-197672.

prepare_create_dq_job (read-only) walks the discovery chain — resolve the
edge connection, detect the job type (PUSHDOWN/PULLUP) from its capabilities,
and enumerate data sources, schemas, tables and columns — returning a
ready-to-use plan. It also resolves the location from a catalog Table asset
(id / URL / name) for the table-asset-page entry point.

create_dq_job builds and submits the job via the PUBLIC DQ API
(POST /rest/dq/1.0/jobs) behind a confirm-checkpoint preview. It supports
column selection, a single-column row filter, row sampling, time-slice
scheduling (${rd}/${rdEnd} composed into a dialect-aware source query),
recurring schedules, monitors + adaptive settings, notifications, Pullup
sizing / Parallel JDBC, and Pushdown compute. Discovery uses internal BFF
endpoints (the public DQ API exposes no connection/edge metadata browse).

Validated end-to-end on a live stack: create -> persist -> run FINISHED.

Refs: DEV-197672

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…imental, clarify descriptions

Addresses review feedback on #88.

- Drop the internal /jobs/name, /jobs/{name}/exists, and /jobs/{name}/validJobName
  calls. Naming now relies on the PUBLIC create API: omitting jobName lets the server
  auto-assign a collision-free name (returned in the response); a user-supplied name
  is validated client-side against the server's rules (charset + no leading hyphen).
- Rename the tools to create_data_quality_job / prepare_create_data_quality_job and
  expand their descriptions with plain-language framing (job/edge/connection) plus
  example user requests, for better LLM comprehension and evaluations.
- Gate both tools behind a new "data-quality" experimental feature (off by default),
  like the Data Product skills, since they write to Collibra.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vvaks0
vvaks0 force-pushed the feat/dev-197672-create-dq-job branch from 749732a to deb3c62 Compare July 15, 2026 23:44
@vvaks0

vvaks0 commented Jul 15, 2026

Copy link
Copy Markdown
Author

@vvaks0 do we have tests on the DQ side to ensure these API contracts will not change and will fail if someone modifies?

@aberkow Collibra Here is what I am going to propose internally but it will take a bit of time to work through it with the team as there is some team level messaging required here.

https://github.com/collibra/dq/pull/7591

@vvaks0

vvaks0 commented Jul 15, 2026

Copy link
Copy Markdown
Author

@vvaks0

  1. We'd like any DQ admin tools (create/edit/delete) behind a flag, similar to --experimental  we have for the Data Product skills
  2. We need more in depth descriptions
  3. We need to map to personas. I'm told existing examples in repo. https://engineering-collibra.atlassian.net/wiki/spaces/AIENG/pages/19152601130/Chip+Tool+Personas+and+Permission+Mapping?atlOrigin=eyJpIjoiNjY2YzdkOGZhNDA1NDUwN2JmMTI0MzM2MTAzYzYxYjgiLCJwIjoiY29uZmx1ZW5jZS1jaGF0cy1pbnQifQ

@aberkowCollibra Done

@aberkowCollibra

Copy link
Copy Markdown

@EricWarnerCollibra @vvaks0 all changes requested have been made and verified.

selectedColumns projects the chosen columns into the source query's
SELECT list (falling back to SELECT * only when omitted), per
dqColumnsPart in pkg/clients/dq_source_query.go. The schema description
wrongly claimed it left the query as SELECT *.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

// dqRowFilterPart mirrors the wizard's createRowFilterPart: `col op 'value'` (value single-quoted;
// BIGQUERY bare for numeric). For valueless operators (IS NULL / IS NOT NULL) the value is omitted.
func dqRowFilterPart(in DqSourceQueryInput, dialect string) string {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filterOperator/filterValue flow straight into the scan SQL — could an embedded quote or an odd operator break out of the query here?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed

Comment thread pkg/tools/prepare_create_dq_job/tool.go Outdated
// that tells the agent whether it has everything needed to call create_data_quality_job,
// what's still missing (with the options to choose from), or what couldn't be
// resolved. It performs NO mutations.
package prepare_create_dq_job

@nevers nevers Jul 22, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question on the tool split: did you consider baking this companion tool into create_data_quality_job instead of a separate prepare_ tool?
The create_data_quality_job already re-resolves the connection, job type, permissions, etc. itself, and it already has a status/confirm state machine — discovery could be one more state (incomplete + options when the location isn't fully specified).
We've had issues with the prepare_/create_ pairing and moved away from it (e.g. we removed prepare_add_business_term and made prepare_create_asset optional CC @bobby-smedley)
The problem is that it couples two tools through the LLM which is not guaranteed. Also, with users manually selecting tools in Maestro, this could potentially enable one without the other and get a broken flow.
One tool spanning discovery → preview → create would avoid both.

@vvaks0 vvaks0 Jul 23, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. Since Maestro shows individual tools instead of functional packages (like a plugin would), we can't make sure the user will select all the tools they need. I will look for a way to combine them.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool 👍 I'm pushing for grouping tools (i.e. like functional packages) for a while now. We'll get there at some point.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed, one tool now.

vvaks0 and others added 4 commits July 24, 2026 14:47
dqRowFilterPart spliced filterValue and filterOperator straight into the
scan query: the value was single-quoted but embedded quotes were left
as-is (a value like `x' OR '1'='1` broke out of the literal), and the
operator was used verbatim with no allow-list.

- Escape the value as a SQL string literal (double embedded single
  quotes) via dqEscapeStringLiteral — the standard escape honored by
  Postgres/Oracle/MySQL/etc.
- Add DqFilterOperators + IsAllowedDqFilterOperator (case-insensitive,
  whitespace-normalized) covering the wizard's set: = != <> > >= < <=
  LIKE IS NULL IS NOT NULL. The operator has no literal escape, so it
  must be one of these.

Column names were already quoted via dqEscapeIdentifier.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fold the read-only prepare_create_data_quality_job discovery tool into
create_data_quality_job so one tool spans discovery -> preview -> create,
per review on #88. The prepare_/create_ split coupled two tools through
the LLM and let Maestro enable one without the other (a broken flow).

- New discover.go: resolves the location (connection -> data source ->
  schema -> table), enumerating options for the FIRST missing field
  (status=incomplete). Fields the caller supplies are trusted, so a
  fully-specified call is still a single build+preview with no extra
  browse round-trips.
- Input: drop edgeSiteName/edgeConnectionName; add connection (UUID or
  name) + the tableAsset* resolvers; dataSource/schema/table optional.
- Output: add discovery options and, on preview, the option catalogs
  (columns/monitors/adaptiveMonitorSettings/notifications) formerly
  surfaced at prepare's `ready` step.
- Enforce the row-filter operator allow-list (clients.IsAllowedDqFilter-
  Operator) at the input layer.
- Remove the prepare_create_dq_job package; update registration, the
  experimental help text, and internal doc strings.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e-dq-job

# Conflicts:
#	pkg/tools/register_test.go
The public create does not auto-assign a unique default name: an empty
jobName is rejected, and a concrete existing name is upserted/re-run, so
there is no conflict to react to. A default create for an existing table
therefore silently re-ran the existing job instead of making a distinct
one. Mirror the wizard (DatasetBll.getDatasetName) client-side, using
public endpoints only:

- clients.SearchDqJobNames: page the public GET /rest/dq/1.0/jobs search.
- clients.NextAvailableDqJobName: base when free, else "base_N" for the
  smallest free N (first duplicate -> _1); ignores non-numeric suffixes.
- clients.validatedDqDataset: port of getValidatedDataset (charset strip,
  data_quality_job fallback, 252 cap).
- clients.ResolveAutoDqJobName ties them together.

create_data_quality_job now resolves the name up front when jobName is
omitted (reflected in both preview and create); an explicit name is
validated and used as-is. Removed the dead 409-retry path. Added tool
annotations (ReadOnly/Destructive/Idempotent/OpenWorld) matching the
create_asset/create_assessment convention.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants