PRD Concrete Syntax is the textual form a PRD takes on disk. A PRD is written in a .prd file using structured markdown consistent with the Specy ecosystem’s other DSLs (.sysreq, the domain DSL). The syntax is opinionated about block structure but forgiving about prose — long-form descriptions, rationales, and stories are first-class. This page shows a trimmed working example (the RideNow PRD) and then lists the syntax rules that govern each construct.

Rideshare Example

A compact PRD for a rideshare marketplace. The example is trimmed for readability — the full version (with all personas, jobs, outcomes, and releases) lives in the metamodel reference. Every construct shown below has its own detailed page in this reference:

Example:

product "RideNow" {

  vision "A ride-hailing platform that connects riders with drivers in real time,
         offering reliable, affordable transportation in urban markets."

  problem {
    situation "Urban commuters and occasional travelers need on-demand transportation."
    complication "Public transit is unreliable, taxis are expensive and hard to find,
                  personal cars are costly to own and park."
    question "How can we provide reliable, affordable door-to-door transportation
              available within minutes?"
  }

  non-goals {
    "Replace public transit — we complement it, not compete with it"
    "Own the vehicle fleet — we are a marketplace, not a fleet operator"
    "Serve rural areas — unit economics require urban density"
  }

  persona "Daily commuter rider" {
    role "A working professional who commutes to the office 5 days a week"
    goals {
      "Get to work reliably within 30 minutes"
      "Know the fare before committing"
    }
    frustrations {
      "Unpredictable wait times"
      "Surge pricing during peak hours"
    }
    context "Uses smartphone, rides during rush hours, price-sensitive"
    weight primary
  }

  persona "Part-time driver" {
    role "A vehicle owner who drives to supplement income on a flexible schedule"
    goals {
      "Earn predictable income during chosen hours"
      "Receive payment reliably and quickly"
    }
    frustrations {
      "Long idle time between rides"
      "Riders who cancel after driver commits"
    }
    context "Owns car, drives evenings and weekends, values autonomy"
    weight primary
  }

  job "Know total cost before committing to a ride" {
    persona "Daily commuter rider"
    statement "When I need a ride but have a limited budget,
               I want to know the exact fare before I commit,
               so I can decide whether to ride or take a cheaper alternative."
    type functional
    importance critical
    satisfaction underserved
    desired-outcomes {
      "Minimize the difference between estimated fare and actual fare" {
        importance high
        current-satisfaction low
      }
    }
  }

  evidence "Rider NPS drop Q3" {
    type analytics
    summary "Rider NPS dropped 15 points in Q3. Exit surveys cite unpredictable
             wait times (42%) and surge pricing surprises (31%) as top reasons."
    source-reference "Rider Experience Quarterly Report Q3-2025, slide 14"
    date 2025-10-15
    confidence strong
    supports "Reduce rider wait time"
  }

  goal "Reduce rider wait time" {
    statement "Reduce average time from ride request to driver assignment
               to under 30 seconds in served markets"
    horizon short-term
    owner "Head of Ride Operations"
    metric {
      indicator "p50 time from RideRequested to RideRequestMatched"
      target "< 30 seconds"
      baseline "45 seconds (current)"
      measurement "Event timestamp delta in production"
    }
  }

  hypothesis "Upfront fare reduces abandonment" {
    intervention "Show fare estimate before rider confirms the ride request"
    expected-outcome "Rider conversion from request to confirmation increases by 20%"
    mechanism "Eliminating fare uncertainty reduces abandonment at the commitment step"
    validation-method "A/B test in pilot market"
    status proposed
    proposes "Ride request and fare estimate"
    predicts "Reduce rider wait time"
  }

  feature "Ride request and fare estimate" {
    summary "Rider enters destination and sees an upfront fare estimate before committing"
    persona "Daily commuter rider"
    value-proposition "Eliminates fare anxiety — rider knows the cost before the trip"
    priority must
    status accepted
    addresses "Know total cost before committing to a ride"
    advances "Reduce rider wait time"
    tested-by "Upfront fare reduces abandonment"
    design-references {
      "Fare estimate screen" -> "figma.com/file/abc123/ride-request-flow"
    }
    non-goals {
      "Let riders negotiate the fare — pricing is algorithmic only"
    }
    stories {
      "As a daily commuter rider, I want to see the fare before I confirm,
       so that I can decide if the ride is worth the cost." {
        acceptance-criteria {
          "Fare estimate is displayed within 3 seconds of entering destination"
          "Fare breakdown shows base fare, distance, time, and surge if applicable"
          "Rider can cancel without penalty before confirming"
        }
      }
    }
  }

  feature "Free cancellation before driver assignment" {
    summary "Riders can cancel without fee while no driver has been assigned"
    persona "Daily commuter rider"
    value-proposition "Reduces commitment anxiety — riders explore options freely"
    priority must
    status accepted
  }

  feature "Driver weekly payout" {
    summary "Drivers receive accumulated earnings every Monday via bank transfer"
    persona "Part-time driver"
    value-proposition "Predictable income cadence — drivers can plan finances"
    priority must
    status accepted
  }

  assumption "GPS accuracy sufficient for matching" {
    statement "Driver smartphones in target markets have GPS accuracy within 20 meters"
    impact-if-wrong "Matching assigns wrong drivers, ETAs unreliable, no-show rate rises"
    validation-plan "Measure GPS accuracy on 100 driver devices in first pilot market"
    status unvalidated
    underpins "Ride request and fare estimate"
  }

  risk "Regulatory surge pricing ban" {
    statement "Local regulators may ban or cap surge pricing in key markets"
    likelihood medium
    impact high
    mitigation mitigate
    owner "Head of Legal"
    threatens "Reduce rider wait time"
  }

  constraint "PCI-DSS compliance" {
    statement "All payment card data must comply with PCI-DSS Level 1"
    source regulatory
    constrains "Ride request and fare estimate", "Driver weekly payout"
  }

  open-question "Cancellation fee in competitive markets" {
    question "Should we charge cancellation fees in markets where competitors don't?"
    context "Charging fees protects drivers but may drive riders to competitors."
    owner "Head of Product"
    deadline 2026-04-01
    status open
    blocks "Free cancellation before driver assignment"
  }

  release "R1 — Core ride loop" {
    target-date "Q2 2026"
    theme "Minimum viable ride-hailing: request, match, ride, pay"
    status planned
    includes {
      "Ride request and fare estimate"
      "Free cancellation before driver assignment"
      "Driver weekly payout"
    }
    exit-criteria {
      "All must features pass acceptance"
      "No P0 bugs open"
      "Pilot market onboarded with 100+ drivers"
    }
  }
}

Syntax Rules

The rules below cover every top-level construct that can appear inside a product block. Enumerations (priority, status, confidence, etc.) use the keyword values listed — the DSL does not allow arbitrary strings where an enum is expected.

  • product "<name>" opens the PRD. Everything else is nested inside.
  • problem { situation, complication, question } follows the SCQ (Situation-Complication-Question) framework for problem framing.
  • non-goals { ... } declares strategic exclusions at product level — what the product deliberately does not aim to do. Also available inside feature blocks for tactical exclusions.
  • evidence "<name>" { type, summary, source-reference, date, confidence, supports } documents data that grounds decisions. type is user-research, analytics, market-research, customer-feedback, or domain-expertise. confidence is strong, moderate, or weak.
  • persona "<name>" { role, goals, frustrations, context, weight } defines a user archetype. weight is primary, secondary, or excluded.
  • job "<name>" { persona, statement, type, importance, satisfaction, related-to, desired-outcomes { ... } } defines a situation-triggered task a persona is trying to accomplish. type is functional, emotional, or social. importance is critical, important, or nice-to-have. satisfaction is unserved, underserved, adequately-served, or overserved. Jobs are optional — they enrich the demand-side model but are not required for a valid PRD.
  • desired-outcomes { "<statement>" { importance, current-satisfaction } } embeds desired outcomes within a job. Each outcome follows the canonical form: direction + metric + object + clarifier. importance is high, medium, or low. current-satisfaction is low, medium, or high. High importance + low satisfaction = underserved outcome = opportunity.
  • addresses "<job name>", ... inside a feature references the jobs that feature helps get done.
  • goal "<name>" { statement, horizon, owner, metric { ... } } defines a measurable business objective. horizon is short-term, mid-term, or long-term.
  • hypothesis "<name>" { intervention, expected-outcome, mechanism, validation-method, status, proposes, predicts } declares a testable causal claim linking a feature to a goal. status is proposed, testing, validated, invalidated, or inconclusive.
  • feature "<name>" { summary, persona, value-proposition, priority, status, advances, tested-by, design-references, non-goals, stories { ... } } defines a product capability. priority uses MoSCoW (must, should, could, wont). status is proposed, accepted, in-progress, delivered, deferred, or rejected.
  • design-references { "<label>" -> "<uri>" } inside a feature or journey points to visual artifacts (Figma, prototypes, wireframes). The PRD references designs; it does not contain them.
  • stories { "<story text>" { acceptance-criteria { ... } } } embeds user stories within a feature. Each story follows the “As a…, I want…, so that…” form. Acceptance criteria are the primary candidates for formalization into EARS requirements.
  • assumption "<name>" { statement, impact-if-wrong, validation-plan, status, underpins } documents beliefs. status is unvalidated, validated, or invalidated.
  • risk "<name>" { statement, likelihood, impact, mitigation, owner, threatens } documents threats. mitigation is accept, mitigate, avoid, or transfer.
  • constraint "<name>" { statement, source, constrains } documents non-negotiable boundaries. source is regulatory, contractual, technical, organizational, or market.
  • open-question "<name>" { question, context, owner, deadline, status, blocks, resolution } tracks acknowledged unknowns. status is open, investigating, resolved, or deferred. When resolved, the resolution field records the answer.
  • release "<name>" { target-date, theme, status, depends-on, includes, exit-criteria } defines a delivery milestone. status is planned, in-progress, shipped, or cancelled.
  • journey "<name>" for "<persona>" { trigger, outcome, design-references, steps { ... } } defines a user journey (may appear at product level or within a feature).

The PRD does not contain system requirements. The bridge from PRD to system requirements is the source field on EARS requirements — see Releases & Traceability for the convention and the example grammar.