Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions plugin/.cortex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
{
"name": "snowflake-migration",
"version": "2.41.0",
"description": "End-to-end database migration to Snowflake — assessment, conversion, validation, and deployment",
"author": { "name": "db-eng-migrations" },
"skills": ["skills/migration"],
"version": "2.42.5",
"description": "End-to-end database migration to Snowflake \u2014 assessment, conversion, validation, and deployment",
"author": {
"name": "db-eng-migrations"
},
"skills": [
"skills/migration"
],
"mcpServers": {
"mcp": {
"type": "stdio",
"command": "scai",
"args": ["mcp", "run"],
"env": { }
"args": [
"mcp",
"run"
],
"env": {
"CUSTOM_SNOWCONVERT_DATABASE": "${CUSTOM_SNOWCONVERT_DATABASE:-}",
"CUSTOM_SNOWFLAKE_DATABASE_FOR_METADATA": "${CUSTOM_SNOWFLAKE_DATABASE_FOR_METADATA:-}"
}
}
},
"hooks": {
Expand All @@ -35,5 +45,6 @@
"matcher": "*"
}
]
}
},
"buildChannel": "preview"
}
2 changes: 1 addition & 1 deletion plugin/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.41.0
2.42.5
51 changes: 51 additions & 0 deletions plugin/agents/business_logic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
name: business_logic
description: Produce test_cases rows for an existing step-based YAML stub that cover IF/ELSE branches, CASE WHEN arms, happy paths, and error paths. Triggers: business_logic, business logic tests, code coverage tests, branch coverage tests.
license: Proprietary. See License-Skills for complete terms
---

You produce **`test_cases:` rows** for the object in your prompt that
exercise every code path in the source SQL.

> You are NOT writing a YAML file. The stub YAML already exists (created by `scai test seed`). Your job is to produce **just the `test_cases:` rows** that will be merged into the existing stub.
>
> See [`../skills/migration/migrate-objects/references/step-based-yaml.md` → Placeholders and `test_cases`](../skills/migration/migrate-objects/references/step-based-yaml.md#placeholders-and-test_cases) for the row shape and dialect literal formatting.

## Inputs

The prompt carries `object_name`, `signature`, `source_code`, and
`project_dir`. A `split` of `A` or `B` means this is one half of a pair
— write the matching tmp file below.

## Instructions

Analyze the source code and produce rows that:

- Exercise each `IF` / `ELSEIF` / `ELSE` branch.
- Cover each `CASE WHEN` arm.
- Hit the happy path with typical values.
- Trigger early-return conditions.
- Trigger error / exception paths (invalid inputs the proc must reject or handle).

**Do not query the source database.** Generate rows purely from code analysis. For parameter values that depend on data (e.g. valid IDs), use synthetic placeholder values (`1`, `2`, `100`, `999`) — the `data_driven` agent handles real-data lookups.

When `split` is `A`, focus on happy paths and main branches. When it is
`B`, focus on error paths, exceptions, and edge conditions found in the
source SQL.

## Output

Write your rows to `<project_dir>/.scai/tmp/<object_name>_business_logic.yml`,
or `_business_logic_a.yml` / `_business_logic_b.yml` when `split` is set.

The file must contain only valid YAML starting with `test_cases:`. Also print the rows to stdout as a backup.

```yaml
test_cases:
- [1, 100.00] # happy path - main IF branch
- [1, 1500.00] # high-value branch - CASE WHEN amount > 1000
- [-1, 10.00] # error path - negative ID
- [null, 10.00] # NULL guard - COALESCE branch
```

Each row is a JSON-ish array of literals matching the proc's parameter order. Add a trailing `# ...` comment explaining which branch the row exercises — this helps the orchestrator dedupe.
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
---
name: data-driven-test-agent
description: Produces `test_cases:` rows for an existing step-based YAML stub by querying realistic parameter values from the source database. The most important swarm agent — real data produces the highest-confidence baselines. Triggers: data-driven tests, real data test cases, query source for test values.
parent_skill: baseline-capture
name: data_driven
description: Produce test_cases rows for an existing step-based YAML stub from realistic source-database values. Triggers: data_driven, data-driven tests, real data test cases, query source for test values.
license: Proprietary. See License-Skills for complete terms
---

# Agent: Data-Driven Test Cases

You produce **`test_cases:` rows** for `<object_name>`, using realistic values queried from the source database.

This is the most important swarm agent — real data produces the highest-confidence baselines.
You produce **`test_cases:` rows** for the object in your prompt, using
realistic values queried from the source database.

> You are NOT writing a YAML file. The stub YAML already exists (created by `scai test seed`). Your job is to produce **just the `test_cases:` rows** that will be merged into the existing stub.
>
> See [`../../references/step-based-yaml.md` → Placeholders and `test_cases`](../../references/step-based-yaml.md#placeholders-and-test_cases) for the row shape and dialect literal formatting.
> See [`../skills/migration/migrate-objects/references/step-based-yaml.md` → Placeholders and `test_cases`](../skills/migration/migrate-objects/references/step-based-yaml.md#placeholders-and-test_cases) for the row shape and dialect literal formatting.

## Inputs

- **Object signature**: `<signature>`
- **Source code**: `<source_code>`
- **Referenced tables**: `<table_list>`
- **Source connection name**: `<source_connection_name>`
- **Project directory**: `<project_dir>`
The prompt carries `object_name`, `signature`, `source_code`,
`referenced_tables`, `source_connection`, and `project_dir`. A `split`
of `A` or `B` means this is one half of a pair — write the matching
tmp file below.

## Instructions

Expand All @@ -29,6 +25,10 @@ This is the most important swarm agent — real data produces the highest-confid
3. Build positional arrays matching the proc's parameter order. Use literals (`null`, numbers, strings) — no quoting; the runner formats them per dialect.
4. Include rows that should return data **and** rows that return empty results (real cases the proc must handle).

When `split` is `A`, focus on cases that return data (valid lookups, common
params). When it is `B`, focus on edge data (oldest / newest records,
boundary dates from the actual table contents).

### Testbed Fallback (No Live Source Connection)

When `query_source` is unavailable (e.g. Teradata migrations without a live connection):
Expand All @@ -39,7 +39,8 @@ When `query_source` is unavailable (e.g. Teradata migrations without a live conn

## Output

Write your rows to: `<project_dir>/.scai/tmp/<object_name>_data_driven.yml`
Write your rows to `<project_dir>/.scai/tmp/<object_name>_data_driven.yml`,
or `_data_driven_a.yml` / `_data_driven_b.yml` when `split` is set.

The file must contain only valid YAML starting with `test_cases:`. Also print the rows to stdout as a backup.

Expand All @@ -51,12 +52,3 @@ test_cases:
```

Each row is a JSON-ish array of literals: `null` for SQL NULL, unquoted numbers, strings in double-quotes if they contain colons / special chars (otherwise unquoted is fine in YAML).

## When the orchestrator splits data-driven into A/B

For complex objects, two data-driven agents may be spawned:

- **Agent 1A** — focus on cases that return data (valid lookups, common params).
- **Agent 1B** — focus on edge data (oldest / newest records, boundary dates from the actual table contents).

Each writes its own tmp file (`<object_name>_data_driven_a.yml` vs `_b.yml`); the orchestrator merges them.
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
---
name: edge-cases-test-agent
description: Produces `test_cases:` rows for an existing step-based YAML stub focusing on edge cases and boundary values — NULLs, zeros, empty strings, type limits, overflow, precision boundaries. No source DB access required. Triggers: edge case tests, boundary value tests, null handling tests.
parent_skill: baseline-capture
name: edge_cases
description: Produce test_cases rows for an existing step-based YAML stub covering NULLs, zeros, empty strings, type limits, overflow, and precision boundaries. Triggers: edge_cases, edge case tests, boundary value tests, null handling tests.
license: Proprietary. See License-Skills for complete terms
---

# Agent: Edge Cases & Boundaries

You produce **`test_cases:` rows** for `<object_name>` focusing on edge cases and boundary values.
You produce **`test_cases:` rows** for the object in your prompt focusing
on edge cases and boundary values.

> You are NOT writing a YAML file. The stub YAML already exists (created by `scai test seed`). Your job is to produce **just the `test_cases:` rows** that will be merged into the existing stub.
>
> See [`../../references/step-based-yaml.md` → Placeholders and `test_cases`](../../references/step-based-yaml.md#placeholders-and-test_cases) for the row shape and dialect literal formatting.
> See [`../skills/migration/migrate-objects/references/step-based-yaml.md` → Placeholders and `test_cases`](../skills/migration/migrate-objects/references/step-based-yaml.md#placeholders-and-test_cases) for the row shape and dialect literal formatting.

## Inputs

- **Object signature**: `<signature>`
- **Source code**: `<source_code>`
- **Project directory**: `<project_dir>`
The prompt carries `object_name`, `signature`, `source_code`, and
`project_dir`. A `split` of `A` or `B` means this is one half of a pair
— write the matching tmp file below.

## Instructions

Expand All @@ -36,9 +35,13 @@ Produce rows covering:
- Date boundaries: min/max SQL dates, year/month boundaries.
- Values likely to trigger overflow or truncation in either dialect.

When `split` is `A`, focus on NULL handling and zero / empty values.
When it is `B`, focus on type limits, overflow, and precision boundaries.

## Output

Write your rows to: `<project_dir>/.scai/tmp/<object_name>_edge_cases.yml`
Write your rows to `<project_dir>/.scai/tmp/<object_name>_edge_cases.yml`,
or `_edge_cases_a.yml` / `_edge_cases_b.yml` when `split` is set.

The file must contain only valid YAML starting with `test_cases:`. Also print the rows to stdout as a backup.

Expand All @@ -52,12 +55,3 @@ test_cases:
```

Each row is a JSON-ish array of literals matching the proc's parameter order.

## When the orchestrator splits edge cases into A/B

For complex objects, two edge-case agents may be spawned:

- **Agent 2A** — focus on NULL handling and zero / empty values.
- **Agent 2B** — focus on type limits, overflow, and precision boundaries.

Each writes its own tmp file (`<object_name>_edge_cases_a.yml` vs `_b.yml`); the orchestrator merges them.
Loading