SDODS
Reference

sdods.project.yaml and sdods.workspace.yaml

Field-by-field reference for the project file and the workspace file.

What you'll learn

Every field of sdods.project.yaml and of the root sdods.workspace.yaml, its type, default and purpose, derived from the Zod schemas in @sdods/contracts.

sdods.project.yaml

Identity and hierarchy

Prop

Type

Layers, browsers, routes, tags, environments

Prop

Type

Modules and processes

Prop

Type

Data and authentication

Prop

Type

Screenshots, healing, timeouts, retries, performance, accessibility

Prop

Type

Canvas

Selectors for the canvas steps. The defaults match the DOM React Flow renders; override only the keys your editor does differently. Each value is a CSS selector template: {id}, {handle}, {source}, {target}, {field} and {badge} are replaced by the step argument, escaped for a quoted CSS string, so keep them inside quotes. {testIdAttribute} is replaced by the project's testIdAttribute. A template without its required placeholder, or with an unknown one, fails config validation.

Prop

Type

A workflow builder that marks its blocks with its own attributes overrides only those keys:

canvas:
  field: '[data-subblock-id="{field}"]'
  badge: '[{testIdAttribute}="block-{badge}"]'

With that block, Then the node "agent-1" should show the "error-badge" badge looks for [data-testid="block-error-badge"] inside the node .react-flow__node[data-id="agent-1"].

Load profiles are not part of this file: each lives in projects/<slug>/load/<name>.yaml and runs with sdods load. The field reference is in Load testing.

Integrations, MCP, agents, schedules, reports

Prop

Type

Traceability

@req:<id> tags link scenarios to requirements; this block makes the ids checkable and feeds sdods report traceability. Every key is optional, and without the block any id is accepted.

Prop

Type

traceability:
  requirements: requirements.yaml # or requirements.csv with an id,title header
  link: https://jira.example.com/browse/{id}
  require: false
# requirements.yaml: a list, a map (AUTH-1: Title), or either under `requirements:`
- id: AUTH-1
  title: A registered user can sign in
- id: AUTH-2
  title: A locked account cannot sign in

The demo project

slug: demo-shop
name: Demo Shop
layers: [ui, api, hybrid, recorded]
browsers: [chromium, firefox, webkit]
testIdAttribute: data-test
routes:
  { login: /, inventory: /inventory.html, cart: /cart.html, checkout: /checkout-step-one.html }
tags:
  suites: [smoke, regression, sanity]
  extra: [mock, visual, a11y, perf, data-driven, pool, hybrid-demo]
  roles: [standard, problem, performance, locked]
envs: { default: staging, available: [local, staging] }
data:
  sources:
    users: { type: csv, path: 'data/{env}/users.csv', fallback: data/common/users.csv }
    products: { type: json, path: data/common/products.json }
  factories: ./data/factories.ts
  userPool: { dataset: users, roleColumn: role, leaseStore: file, leaseTtlMs: 600000 }
auth:
  strategy: form
  form:
    {
      loginPath: /,
      usernameSelector: '#user-name',
      passwordSelector: '#password',
      submitSelector: '#login-button',
      readyUrl: /inventory.html,
    }
screenshots:
  policy:
    {
      default: on-failure,
      '@smoke': scenario,
      '@regression': step,
      '@sanity': scenario,
      '@visual': visual,
    }
  mask: ['[data-test="shopping-cart-badge"]']
heal: { enabled: true, primaryTimeoutMs: 3000, probeTimeoutMs: 1500, minScore: 0.6 }
retries: { ci: 2, local: 0, byTag: { '@flaky': 2 } }
evidence: { trace: retain-on-failure, video: retain-on-failure }
perf: { budgets: { pageLoadMs: 4000, lcpMs: 3000, apiP95Ms: 1500 } }

Setup scenarios

setup: { tags: '@setup' } runs the scenarios matching tags before everything else in the run and skips the rest when one of them fails, instead of letting every scenario fail on its own against a broken environment or a login that does not work.

  • Every run target gets a companion target named <target>--setup (for example demo-shop--ui--chromium--setup, demo-shop--api--setup) that runs that layer's setup scenarios in the same browser, and the target depends on it (Playwright project dependencies). When a setup scenario fails, Playwright reports the target's scenarios as "did not run".
  • Setup scenarios are selected by setup.tags alone: --tags, --grep, --feature and --module narrow the target's own scenarios, never the setup tier. They are excluded from the target, so they run once.
  • Setup scenarios are ordinary scenarios: they still carry one layer tag and one suite tag. Declare the tag under tags.extra so lint does not warn about it.
  • A process can use other setup tags (setup: { tags: '@probe or @auth' }) or none (setup: false).
  • Recorded specs (layer: recorded) have no tags and get no setup tier.
tags: { extra: [setup] }
setup: { tags: '@setup' }
processes:
  - { name: release-gate, fullyParallel: false }
  - { name: quick, setup: false }

sdods.workspace.yaml

The root file names the organization and workspace every project in the repository belongs to and holds defaults.

Prop

Type

organization: { slug: sdods, name: SDODS, url: https://example.com/sdods }
workspace: { slug: default, name: Default workspace, organization: sdods }
defaults:
  browsers: [chromium, firefox, webkit]
  suites: [smoke, regression, sanity]
  testIdAttribute: data-testid
  processes:
    - {
        name: pr-check,
        trigger: pr,
        tags: '@smoke',
        browsers: [chromium],
        harMode: replay,
        gates: { minPassRate: 100 },
      }
    - {
        name: nightly-regression,
        trigger: nightly,
        tags: '@regression',
        browsers: [chromium, firefox, webkit],
        notify: [github],
        schedule: '0 2 * * *',
      }
    - {
        name: release-gate,
        trigger: release,
        tags: '@smoke or @regression',
        failOnFlaky: true,
        gates: { minPassRate: 100, maxFlaky: 0, perfBudgets: true, a11y: true },
      }

roles.matrix.yaml

An optional file next to sdods.project.yaml, validated by RolesMatrixFileSchema in @sdods/contracts. It declares role × surface matrices that sdods matrix expand turns into the Examples of @matrix:<name> outlines. The format and workflow are in Role matrices.

Prop

Type

Using an AI coding agent? Install SDODS:

Install the SDODS plugin in Claude Code: skills, subagents, commands and the MCP server.

  1. /plugin marketplace add YarlisAISolutions/sdods-skills
  2. /plugin install sdods@sdods
Learn more about using SDODS with AI tools

On this page