orchestrata_ultimate.openspec.render

Reference › orchestrata_ultimate › openspec › render

render writes OpenSpec models back to markdown (SPEC-104 FR-004 and FR-007) and is the inverse of parse: parsing the output of render_spec round-trips structurally. render_spec renders an OpenSpecDoc as a capability spec.md (using _render_requirement for each requirement). render_delta renders change-delta blocks. render_proposal produces a change proposal.md with Why, What Changes and Impact sections, and render_tasks produces a tasks.md checklist under a numbered group heading. repo uses all of these when writing to disk. Types come from models.

At a glance

Source src/orchestrata_ultimate/openspec/render.py
Lines of code 73
Classes 0
Functions 5
Imports (internal) orchestrata_ultimate.core.traceability, orchestrata_ultimate.openspec.models
Imported by orchestrata_ultimate.openspec, orchestrata_ultimate.openspec.repo
Tests that import it none

Class diagram

No classes; see Functions.

Dependency diagram

Dependency diagram orchestrata_ultimate.openspec.render

API

Functions

Function Signature Summary
_render_requirement traces _render_requirement(req: Requirement) -> str
render_spec traces render_spec(doc: OpenSpecDoc) -> str Render an OpenSpecDoc to a valid OpenSpec capability spec.md.
render_delta traces render_delta(deltas: list[Delta]) -> str Render change-delta blocks (## ADDED/MODIFIED/REMOVED/RENAMED Requirements).
render_proposal traces render_proposal(why: str, what: list[str], impact: str = '') -> str Render an OpenSpec change proposal.md (## Why / ## What Changes / ## Impact).
render_tasks traces render_tasks(tasks: list[str], group: str = 'Implementation') -> str Render an OpenSpec tasks.md checklist (## 1.

Source

Permalink: https://gitlab.com/MSamy/orchestrata-ultimate-architecture/-/blob/a4cbc2bdf/src/orchestrata_ultimate/openspec/render.py

"""Render OpenSpec models back to OpenSpec markdown (SPEC-104 FR-004/007).

Inverse of :mod:`orchestrata_ultimate.openspec.parse` — ``parse_spec(render_spec(doc))``
round-trips structurally. Also renders change-proposal artifacts (proposal.md,
tasks.md, delta spec.md).
"""

from __future__ import annotations

from orchestrata_ultimate.core.traceability import traces
from orchestrata_ultimate.openspec.models import Delta, OpenSpecDoc, Requirement


@traces(spec="104", story="US-104-001", reqs=["REQ-104-006", "REQ-104-007"])
def _render_requirement(req: Requirement) -> str:
    parts = [f"### Requirement: {req.title}"]
    if req.text:
        parts.append("")
        parts.append(req.text)
    for scen in req.scenarios:
        parts.append("")
        parts.append(f"#### Scenario: {scen.name}")
        parts.extend(scen.lines)
    return "\n".join(parts)


@traces(spec="104", story="US-104-001", reqs=["REQ-104-006"])
def render_spec(doc: OpenSpecDoc) -> str:
    """Render an OpenSpecDoc to a valid OpenSpec capability spec.md."""
    title = doc.capability or "Capability"
    out = [f"# {title} Specification", "", "## Purpose", "", doc.purpose or "(TBD)", ""]
    out.append("## Requirements")
    for req in doc.requirements:
        out.append("")
        out.append(_render_requirement(req))
    return "\n".join(out).rstrip() + "\n"


@traces(spec="104", story="US-104-001", reqs=["REQ-104-007"])
def render_delta(deltas: list[Delta]) -> str:
    """Render change-delta blocks (## ADDED/MODIFIED/REMOVED/RENAMED Requirements)."""
    out = [
        line
        for delta in deltas
        for line in (
            f"## {delta.operation} Requirements",
            *(
                item
                for req in delta.requirements
                for item in ("", _render_requirement(req))
            ),
            "",
        )
    ]
    return "\n".join(out).rstrip() + "\n"


@traces(spec="104", story="US-104-001", reqs=["REQ-104-007"])
def render_proposal(why: str, what: list[str], impact: str = "") -> str:
    """Render an OpenSpec change proposal.md (## Why / ## What Changes / ## Impact)."""
    out = ["## Why", "", why.strip() or "(TBD)", "", "## What Changes", ""]
    out.extend(f"- {item}" for item in what)
    if impact:
        out.extend(["", "## Impact", "", impact.strip()])
    return "\n".join(out).rstrip() + "\n"


@traces(spec="104", story="US-104-001", reqs=["REQ-104-007"])
def render_tasks(tasks: list[str], group: str = "Implementation") -> str:
    """Render an OpenSpec tasks.md checklist (## 1. Group, - [ ] 1.n task)."""
    out = [f"## 1. {group}", ""]
    out.extend(f"- [ ] 1.{i} {task}" for i, task in enumerate(tasks, start=1))
    return "\n".join(out).rstrip() + "\n"