Skip to main content

YAML Export Strategy

This document defines how Traceo exports requirements data to YAML format for version control integration, backup, and interoperability.

Overview

Traceo supports bidirectional synchronization between PostgreSQL (primary data store) and YAML files (git-friendly format). This enables:
  • Version Control: Track requirement changes in git
  • Code Review: Review requirement changes in pull requests
  • Backup: Human-readable backup format
  • Interoperability: Import/export with other tools
  • Offline Access: Work with requirements without database connection

Export Triggers

TriggerMechanismUse CaseLatency
On-Demand APIPOST /api/export/yamlManual backup, migrationImmediate
WebhookDatabase trigger → EngineReal-time git sync<1 second
ScheduledCron jobPeriodic snapshotsConfigurable
MCP Toolexport_to_yaml toolAI agent workflowsImmediate

File Structure

requirements/
├── business-requirements/
│   ├── BR-001.yaml
│   ├── BR-002.yaml
│   └── index.yaml
├── functional-requirements/
│   ├── FR-AUTH-001.yaml
│   ├── FR-AUTH-002.yaml
│   └── index.yaml
├── non-functional-requirements/
│   ├── NFR-PERF-001.yaml
│   └── index.yaml
├── system-requirements/
│   ├── SYS-DB-001.yaml
│   └── index.yaml
├── implementation-requirements/
│   ├── IMPL-AUTH-001.yaml
│   └── index.yaml
├── verification-requirements/
│   ├── VER-AUTH-001.yaml
│   └── index.yaml
├── relationships/
│   └── relationships.yaml
└── manifest.yaml

YAML Schema

Requirement File

# FR-AUTH-001.yaml
---
id: FR-AUTH-001
title: User Authentication
description: |
  Users must be able to authenticate using email/password 
  or OAuth providers (Google, Microsoft).
type: functional_requirement
classification: L2-Functional
status: active
priority: P0-critical
version: 3

acceptance_criteria:
  - id: AC-001
    description: User can register with email and password
    status: verified
    test_ref:
      - TC-AUTH-001
  - id: AC-002
    description: User can log in with Google OAuth
    status: verified
    test_ref:
      - TC-AUTH-002
  - id: AC-003
    description: User can reset password via email
    status: pending
    test_ref: []

success_criteria:
  - metric: Login Success Rate
    target: ">99.5%"
    current: "99.8%"
    status: target_met
    measurement_method: Prometheus metrics

stakeholders:
  technical_owner: Auth Team Lead
  code_reviewers:
    - security-team

relationships:
  implements:
    - BR-001
  constrained_by:
    - NFR-PERF-001
  verified_by:
    - VER-AUTH-001

metadata:
  created: 2024-01-15T10:30:00Z
  last_modified: 2024-01-20T14:45:00Z
  author: bob@acme.com
  change_reason: Added OAuth requirement
  source: Requirements Workshop Q1

Index File

# functional-requirements/index.yaml
---
type: functional_requirement
count: 15
requirements:
  - id: FR-AUTH-001
    title: User Authentication
    status: active
    priority: P0-critical
  - id: FR-AUTH-002
    title: Session Management
    status: active
    priority: P1-high
  # ... more requirements

Relationships File

# relationships/relationships.yaml
---
generated_at: 2024-01-20T15:00:00Z
relationships:
  - source: FR-AUTH-001
    target: BR-001
    type: implements
  - source: NFR-PERF-001
    target: FR-AUTH-001
    type: constrains
  - source: IMPL-AUTH-001
    target: FR-AUTH-001
    type: satisfies
  - source: VER-AUTH-001
    target: IMPL-AUTH-001
    type: verified_by

Manifest File

# manifest.yaml
---
version: "1.0"
workspace: product-a
tenant: acme-corp
generated_at: 2024-01-20T15:00:00Z
schema_version: 1

summary:
  total_requirements: 45
  by_type:
    business_requirement: 5
    functional_requirement: 15
    non_functional_requirement: 8
    system_requirement: 7
    implementation_requirement: 6
    verification_requirement: 4
  by_status:
    draft: 3
    active: 30
    implemented: 8
    verified: 4

export_options:
  include_relationships: true
  include_versions: false
  include_metadata: true

API Endpoints

Export All Requirements

POST /api/export/yaml
Content-Type: application/json
Authorization: Bearer {jwt}

{
  "format": "directory",  // or "single_file"
  "include_relationships": true,
  "include_versions": false,
  "type_filter": ["functional_requirement", "business_requirement"]
}
Response:
{
  "download_url": "/api/export/download/abc123",
  "expires_at": "2024-01-20T16:00:00Z",
  "file_count": 20,
  "total_size_bytes": 45678
}

Export Single Requirement

GET /api/requirements/{id}/yaml
Authorization: Bearer {jwt}
Response: Raw YAML content

Import from YAML

POST /api/import/yaml
Content-Type: multipart/form-data
Authorization: Bearer {jwt}

file: requirements.zip
options: {"update_existing": true, "validate_only": false}

Webhook Configuration

Database Trigger (PostgreSQL)

-- Trigger function to notify on requirement changes
CREATE OR REPLACE FUNCTION notify_requirement_change()
RETURNS TRIGGER AS $$
BEGIN
    PERFORM pg_notify(
        'requirement_changes',
        json_build_object(
            'action', TG_OP,
            'workspace_id', NEW.workspace_id,
            'requirement_id', NEW.id,
            'external_id', NEW.external_id
        )::text
    );
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER requirement_change_trigger
    AFTER INSERT OR UPDATE ON requirements
    FOR EACH ROW EXECUTE FUNCTION notify_requirement_change();

Engine Webhook Handler

async def handle_requirement_change(payload: dict):
    """Export requirement to YAML on change."""
    requirement_id = payload["requirement_id"]
    workspace_id = payload["workspace_id"]
    
    # Fetch full requirement
    requirement = await repository.get(requirement_id)
    
    # Export to YAML
    yaml_content = export_requirement_to_yaml(requirement)
    
    # Write to git-backed storage
    await git_storage.write(
        workspace_id=workspace_id,
        path=f"{requirement.type.value}/{requirement.external_id}.yaml",
        content=yaml_content
    )
    
    # Optionally commit and push
    if settings.auto_commit:
        await git_storage.commit_and_push(
            message=f"Update {requirement.external_id}: {payload['action']}"
        )

Git Integration

Auto-Commit Configuration

# .traceo/config.yaml
git_sync:
  enabled: true
  remote: origin
  branch: main
  auto_commit: true
  auto_push: false  # Require manual push for review
  commit_template: "[traceo] {action} {requirement_id}: {title}"

GitHub Actions Workflow

# .github/workflows/requirements-sync.yml
name: Requirements Sync

on:
  push:
    paths:
      - 'requirements/**/*.yaml'

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Validate YAML schema
        run: |
          pip install pyyaml jsonschema
          python scripts/validate_requirements.py
      
      - name: Check relationships
        run: |
          python scripts/check_relationships.py

Import Workflow

Validation Pipeline

┌─────────────┐    ┌──────────────┐    ┌─────────────┐    ┌──────────┐
│ Parse YAML  │───>│ Schema Check │───>│ Relationship│───>│ Database │
│             │    │              │    │ Validation  │    │ Upsert   │
└─────────────┘    └──────────────┘    └─────────────┘    └──────────┘
                          │                   │
                          ▼                   ▼
                   ┌──────────────┐    ┌─────────────┐
                   │ Error Report │    │ Warning Log │
                   └──────────────┘    └─────────────┘

Import Options

OptionDescriptionDefault
update_existingUpdate existing requirements by external_idtrue
create_missingCreate requirements not in databasetrue
delete_orphanedDelete DB requirements not in YAMLfalse
validate_onlyRun validation without writingfalse
ignore_errorsContinue on validation errorsfalse

Best Practices

1. Directory Structure

  • Group by requirement type for easier navigation
  • Use consistent naming: {TYPE}-{CATEGORY}-{NUMBER}.yaml
  • Include index files for quick reference

2. Git Workflow

  • Use feature branches for requirement changes
  • Review requirement changes in PRs
  • Tag releases with version numbers

3. Conflict Resolution

  • Database is source of truth for live data
  • YAML is source of truth for versioned snapshots
  • Timestamps determine which version wins on conflict

4. Performance

  • Export incrementally (only changed requirements)
  • Use streaming for large exports
  • Compress archives for download

5. Security

  • Never include sensitive metadata in YAML
  • Use workspace-scoped exports
  • Validate input on import

MCP Tool Integration

@mcp.tool()
async def export_to_yaml(
    requirement_ids: list[str] | None = None,
    include_relationships: bool = True
) -> str:
    """
    Export requirements to YAML format.
    
    Args:
        requirement_ids: Specific IDs to export (all if None)
        include_relationships: Include relationship data
    
    Returns:
        YAML content or download URL for large exports
    """
    ...

Future Enhancements

  1. Real-time Sync: WebSocket-based live updates
  2. Diff View: Visual requirement diff in web UI
  3. Merge Tool: Three-way merge for conflicts
  4. Templates: Starter templates for common requirement types
  5. Validation Rules: Custom validation rules per workspace
See also: