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

# Polarion ALM

> Round-trip requirements between Polarion and Roboticks via ReqIF. WorkItem type slugs, link role mapping, Polarion-specific quirks.

# Polarion ALM

Roboticks integrates with Siemens Polarion ALM through **two complementary paths**:

1. **Direct sync via the BYO connector framework** (v1) — Roboticks (or the rbtk CLI) talks to Polarion's REST API and mirrors work items, link roles, and test records into the traceability matrix. Continuous, incremental, and links back to the original work item.
2. **ReqIF round-trip** (free, always supported) — for snapshot-style audits and read-back-with-coverage workflows. Lossless via Polarion's official ReqIF Importer/Exporter extension.

This page covers both. v1's primary mode is **CLI push** (`rbtk connector sync polarion`) since most Polarion instances are on-prem behind firewalls. Cloud sync is available when your Polarion is internet-reachable AND your org has the Polarion Technology Partner relationship activated (`partner_status = active`).

<Info>
  Polarion's REST endpoint is JSON:API at `/polarion/rest/v1/`. Auth is a Personal Access Token (PAT). OAuth2 is admin-gated and rare; PAT is the documented path.
</Info>

## Connector type and pricing

|       |                                                        |
| ----- | ------------------------------------------------------ |
| Type  | BYO requirements connector                             |
| Tier  | Team (3 BYO connectors included), Enterprise (bundled) |
| Price | **\$149 / connector / month** above the Team allowance |

You bring the Polarion license and the ReqIF Importer/Exporter extension. Roboticks never connects to Polarion directly.

## v1 direct sync (`cli_push` primary)

```mermaid theme={null}
%%{init: {"theme": "neutral", "themeVariables": {"primaryColor": "#4040ff"}} }%%
flowchart LR
    Polarion["Polarion ALM\n(/polarion/rest/v1/)"] -->|JSON:API| CLI["rbtk connector sync polarion"]
    CLI -->|/internal/connectors/polarion/ingest| Plat["Roboticks"]
```

The adapter pulls:

| Polarion entity                                                                               | Roboticks shape                                                                                                                               |
| --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `workitems` (type ∈ `systemrequirement`, `safetyrequirement`, `performancerequirement`, etc.) | `Requirement` with `external_id = {project_key}/{wi_id}`, `external_version = workitem.updated`, `external_url` deep-linking to the work item |
| `linkedworkitems`                                                                             | `RequirementRelation` (`verifies`, `derives`, `refines`, `relates_to`) with the raw Polarion role preserved in `vendor_relation_label`        |
| `testruns` + `testrecords`                                                                    | `EvidenceItem` with `status` mapped from `result` (`passed→pass`, `failed→fail`, `blocked→warn`), linked back to the work item it tests       |

Incremental sync is `updated:>{cursor}` against the work items endpoint — subsequent syncs only pull what changed.

## Setup — CLI (primary)

<Steps>
  <Step title="Add the Polarion connector">
    **Settings → Integrations → Requirements → Polarion → Subscribe**. The setup wizard first walks you through installing `rbtk` if it isn't already in your CI.
  </Step>

  <Step title="Mint a Polarion PAT">
    In Polarion: **My Account → Personal Access Tokens → Generate**. Scope: read access to the project(s) you want to mirror. Copy the token; you won't see it again.
  </Step>

  <Step title="Configure credentials in Roboticks">
    ```bash theme={null}
    rbtk connector configure polarion \
        --url=https://polarion.acme.com \
        --token=$POLARION_PAT \
        --label="acme-flight-controller" \
        --project-key=ACME \
        --project-slug=flight-controller
    ```

    The `--project-key` value is the Polarion project ID (the part of the URL after `/project/`).
  </Step>

  <Step title="Run the first sync">
    ```bash theme={null}
    rbtk connector sync polarion --label=acme-flight-controller
    ```

    First sync pulls all work items; subsequent runs are incremental.
  </Step>

  <Step title="Wire into CI">
    ```yaml theme={null}
    # .github/workflows/polarion-sync.yml
    name: Polarion sync
    on:
      schedule: [{ cron: "0 5 * * *" }]
      workflow_dispatch:
    jobs:
      sync:
        runs-on: [self-hosted, polarion-licensed]
        steps:
          - run: pipx install roboticks-cli
          - run: rbtk auth oidc-from-github
          - run: rbtk connector sync polarion --label=acme-flight-controller
    ```
  </Step>
</Steps>

## ReqIF round-trip (alternative, always free)

## One-time setup

<Steps>
  <Step title="Install the Polarion ReqIF extension">
    In Polarion: **Administration → Extensions Management → Install**. Pick **ReqIF Importer/Exporter** (Siemens-supplied). Restart the Polarion server.
  </Step>

  <Step title="Add the connector in Roboticks">
    **Settings → Integrations → Requirements → Add → Polarion**. Name it for the project (e.g., `polarion-armcontroller`).
  </Step>

  <Step title="Author a Polarion-specific field mapping">
    Polarion uses slugified workItem type IDs (`systemrequirement`, `safetyreq`) and link role IDs (`derives_from`, `verifies`). Provide a YAML mapping that handles them:

    ```yaml theme={null}
    # roboticks/polarion-mapping.yaml
    workitem_types:
      systemrequirement:  functional
      safetyrequirement:  safety
      performancereq:     performance
    fields:
      id:           id           # Polarion's intrinsic ID is already slugified
      title:        title
      description:  text
      asilPL:       asil_pl      # custom field, camelCase
      priority:     priority
    link_roles:
      derives_from: derives_from
      verifies:     confirmed_by
      refines:      refines
    type_attr_namespace: "http://eu.siemens.polarion/workitem"
    ```

    Upload via CLI:

    ```bash theme={null}
    rbtk integrations polarion update --field-map roboticks/polarion-mapping.yaml
    ```
  </Step>
</Steps>

## CI recipe

```yaml theme={null}
# .github/workflows/polarion-sync.yml
name: Polarion sync
on:
  schedule: [{ cron: "0 5 * * *" }]
  workflow_dispatch:

jobs:
  sync:
    runs-on: ubuntu-latest
    permissions: { id-token: write, contents: read }
    steps:
      - uses: actions/checkout@v4

      - name: Pull Polarion ReqIF export
        run: |
          curl -fsSL \
            -u "${{ secrets.POLARION_USER }}:${{ secrets.POLARION_TOKEN }}" \
            -H "Accept: application/octet-stream" \
            "https://polarion.acme.com/polarion/reqif/exports/armcontroller/baseline-current.reqif" \
            -o polarion-export.reqif

      - run: pipx install roboticks-cli
      - run: rbtk auth oidc-from-github

      - name: Upload to Roboticks
        run: |
          rbtk requirements upload polarion-export.reqif \
            --mode update \
            --field-map roboticks/polarion-mapping.yaml

      - name: Export Roboticks state back
        run: |
          rbtk requirements export \
            --format reqif --with-coverage \
            --out roboticks-export.reqif

      - name: Push back to Polarion
        run: |
          curl -fsSL \
            -u "${{ secrets.POLARION_USER }}:${{ secrets.POLARION_TOKEN }}" \
            -X POST -F "file=@roboticks-export.reqif" \
            "https://polarion.acme.com/polarion/reqif/imports/armcontroller"
```

## Polarion-specific quirks

### WorkItem type slugs are case-sensitive

Polarion lowercases and removes spaces in its native type IDs. `System Requirement` (display) becomes `systemrequirement` (slug). The mapping uses the slug.

### `type_attr_namespace`

Polarion qualifies its custom attributes with a namespace URI. The default `http://eu.siemens.polarion/workitem` works for most installs; check your Polarion's ReqIF export to confirm.

### Link role identifiers

Polarion link roles are also slugified (e.g., `derives_from`, `verifies`). Compare against Roboticks' canonical names (`derives_from`, `confirmed_by`, `refines`) — the mapping translates them.

### Multi-language fields

If Polarion is configured multi-language, the ReqIF export includes one `xhtml.div` per locale. The mapping picks the first locale by default; specify explicitly:

```yaml theme={null}
locale_preference: en
```

### Baseline names

Polarion exports include the baseline name in the ReqIF header. Roboticks records it as the `release` attribute on the requirement snapshot — so a Roboticks coverage report can be queried "as of Polarion baseline X" later.

## Round-trip caveats

<AccordionGroup>
  <Accordion title="Polarion custom fields with spaces">
    Polarion stores them with spaces; the ReqIF export camel-cases them silently. `ASIL/PL` becomes `aSILPL`. Mirror the camel-case in the mapping.
  </Accordion>

  <Accordion title="Workflow status doesn't round-trip">
    Polarion's workflow state (Draft / Approved / Released) is not captured by ReqIF. If you need it in Roboticks, add a custom field whose value mirrors the workflow state.
  </Accordion>

  <Accordion title="ReqIF Importer creates duplicates on re-import">
    Polarion's ReqIF Importer creates new workItems unless the `INTERNAL_ID` is preserved. Roboticks' export-back includes the original Polarion ID in `ReqIF.ForeignAttributes/polarion.workItemId` — the Importer reads this only when configured with **"Use foreign attributes for ID matching"** (Polarion 22 R2+).
  </Accordion>
</AccordionGroup>

## Validation

```bash theme={null}
# Compare counts
echo "Polarion export: $(xmllint --xpath 'count(//*[local-name()="SPEC-OBJECT"])' polarion-export.reqif)"
rbtk requirements list --output ids | wc -l
```

Both numbers should match (ignoring archived requirements).

## Troubleshooting

<AccordionGroup>
  <Accordion title="`unknown workitem type 'foobar'`">
    Add it to the `workitem_types` mapping or set a default:

    ```yaml theme={null}
    workitem_types:
      _default: functional
    ```
  </Accordion>

  <Accordion title="Polarion Import fails with `INVALID_DATATYPE`">
    Your Polarion has a typed field (e.g., `enum`) that Roboticks exports as `string`. Add an explicit type hint in the mapping:

    ```yaml theme={null}
    fields:
      priority:
        target: priority
        polarion_type: enum
    ```
  </Accordion>
</AccordionGroup>

## Next

<CardGroup cols={2}>
  <Card title="Jama" icon="diagram-project" href="/integrations/jama">
    The other big RM tool — same shape, different field names.
  </Card>

  <Card title="codeBeamer" icon="diagram-project" href="/integrations/codebeamer">
    PTC / Intland codeBeamer.
  </Card>
</CardGroup>
