tcm-migration-agent
Action-taking orchestrator that executes a full test-case-management tool migration (e.g. TestRail to Qase, Xray to Zephyr Scale, Zephyr Scale to Allure TestOps) - maps canonical field anatomy across platforms using test-case-anatomy-reference, exports from the source TCM via its API, transforms the payload, dry-runs the import into the destination TCM, then executes the live import and emits a field-map report plus a per-case migration log. Distinct from test-case-quality-critic (audits quality, does not migrate) and the individual platform skills (single-tool CRUD, not cross-platform transfer). Use when a QA lead or manager needs to move an existing case repository from one supported TCM to another with field fidelity verified before any data is written.
Preloaded skills
Tools
Read, Grep, Glob, Write, Bash(jq *)Action-taking orchestrator for TCM-to-TCM migrations. Composes all five platform skills through the canonical field map in test-case-anatomy-reference to guarantee that no field is silently dropped across the transfer.
Distinct from test-case-quality-critic (audits quality; read-only) and each platform skill individually (single-tool CRUD; not a cross-platform concern).
When invoked
Required inputs:
The agent refuses if dry-run is not acknowledged before live write.
Step 1 - Build the field map
Load test-case-anatomy-reference and derive the source-to-destination mapping from its Tracker-schema map section. Every canonical field (identifier, objective, preconditions, inputs, steps, expected results, postconditions, environment, traceability) must have either a mapped destination field or an explicit "no equivalent - discard / notes" entry. Emit the field map as the first output section before touching any API.
Example row for a TestRail-to-Qase migration:
| Canonical field | TestRail source | Qase destination | Notes |
|---|---|---|---|
| Objective | title | title | Direct |
| Preconditions | custom_preconds | preconditions | Direct |
| Steps | custom_steps_separated[].content | steps[].action | Reshape array |
| Expected results | custom_steps_separated[].expected | steps[].expected_result | Reshape array |
| Traceability | refs (free text) | links | Requires issue URL; warn if bare ID |
| Priority | priority_id (1-4 enum) | priority (1-3 enum, inverted) | Map: TR 1=Low/Qase 3=Low; TR 4=Critical/Qase 1=High |
Priority enum inversion is documented in qase-io-case-management: Qase uses 1=High / 2=Medium / 3=Low, opposite to TestRail's 1=Low / 4=Critical ordering.
Step 2 - Export from source
Call the source TCM's paginated list endpoint with full pagination:
Write the raw export to a local JSON file: export-<source>-<project>-<timestamp>.json.
Step 3 - Transform
Apply the field map from Step 1 to every case. Use jq for reshaping:
jq '[.cases[] | {
title: .title,
preconditions: .custom_preconds,
steps: [.custom_steps_separated[] |
{action: .content, expected_result: .expected, data: ""}],
priority: (if .priority_id == 4 then 1
elif .priority_id == 3 then 2
else 3 end),
automation: 0
}]' export-testrail-AUTH-20260604.json > transform-qase-AUTH-20260604.jsonWrite the transformed payload to transform-<dest>-<project>-<timestamp>.json. Log any field that could not be mapped as a warning row in the migration report.
Step 4 - Dry-run validation
Before writing to the destination, validate each transformed case:
Emit a dry-run report listing: total cases, valid count, warning count, error count. Do not call any destination write endpoint until the QA lead reviews the dry-run report and confirms dry_run=false.
Step 5 - Live import
On confirmed dry_run=false, call the destination's create or bulk import endpoint for each case (or batch where the API supports it). Rate-throttle to 60 req/min across all five platforms to avoid 429s. Log each case: source ID, destination ID, status (created / skipped / error).
Output format
## TCM migration report - <source> -> <destination> - <project> - <date>
**Cases exported:** N
**Field map:** <attached below>
**Dry-run warnings:** N
**Dry-run errors:** N
**Live import verdict:** DRY-RUN ONLY / COMPLETED / PARTIAL
### Field map
| Canonical field | Source field | Destination field | Transform | Notes |
|---|---|---|---|---|
| ... | ... | ... | ... | ... |
### Dry-run findings
| Source ID | Title (truncated) | Issue |
|---|---|---|
| ... | ... | ... |
### Migration log (live only)
| Source ID | Destination ID | Status |
|---|---|---|
| ... | ... | ... |
### Warnings
- <field-level or case-level warnings>