Skip to main content
Glama

Parse verification case record

parse_vcr

Parse a verification case record markdown file into a structured VcrDocument. Returns a non-raising validation result for parse failures instead of exceptions.

Instructions

Parse a verification case record markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.vcr.models.v1.VcrDocument. An existing file that fails to parse returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError/yaml.YAMLError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); a truly-absent or unreadable path still raises the OSError-family file-access error (FileNotFoundError/PermissionError/OSError) from Path.read_text(). The file's language is derived from its path position relative to the verification case record base directory: a file in the flat docs/vcr/ directory parses canonical (no heading-mapping table); a file in a direct two-letter docs/vcr/{language}/ subdirectory parses through that language's table (an actionable ValueError when no table exists for the language); any other location parses canonical.

Input Schema

NameRequiredDescriptionDefault
pathYes

Output Schema

NameRequiredDescriptionDefault
resultYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changedv0.37.0
    • changedOutput schema / $defs / AcceptanceCriterion / description
      Previous value: -"`### AC-NNN (Method): <criterion text>` under `## Acceptance Criteria` -- one verification criterion.\n\nThe number, method, and criterion text all live in the heading itself\n(e.g. `### AC-001 (Test): The revoke endpoint returns 204 within 1s`),\nconstrained by the regex `@alias` above and enforced by `match_alias`\n(`re.fullmatch`) at parse time -- a missing/out-of-range/malformed\nnumber, an unknown method word, or a title-less heading all fail the\nparse eagerly (REQ-003). AC numbers need not be contiguous (gaps are\nallowed, numbers are never renumbered); duplicates are rejected by\n`Vcr`'s own after-validator (the `ValidationError` channel, mirroring\nDEC's `Decision._validate_option_numbers_unique`).\n\nUnlike DEC's `Option`/RSK's `Probability`/`Impact` (all *leaf* sections\nwith zero other declared fields, so their own `.text` computed property\nreturns the *complete* extent verbatim, heading marker and any body\ntext both included), this class declares two other fields\n(`description`, `test_steps`), making it a *composite* section: its own\n`.text` therefore returns only the heading's own inline content (marker\nstripped, body text excluded -- see `MarkdownSection.text`'s composite\nbranch). `number`/`method` below are matched against that heading-only\n`.text` directly, not `.text.splitlines()[0]` -- the DEC/RSK idiom's\nexact mechanics don't apply verbatim here because of this leaf/composite\ndifference, even though the underlying idea (compute a value from the\nretained heading text via a private module-level compiled regex) is the\nsame. A consequence: an `AcceptanceCriterion`'s body may contain nothing\nbesides an optional free-form `description` paragraph followed by an\noptional `#### Test Steps` -- both independently optional (e.g. one\ncriterion may carry only a description, another only `Test Steps`,\nanother both, another neither), in that fixed declaration order.\n\nParameters\n----------\ndescription:\n    The lead paragraph directly under the heading -- free-form prose\n    elaborating on the criterion beyond what fits in the heading\n    itself (mirrors `MoreInformation`'s \"free-form, no fixed format\"\n    tone). Optional; independent of `test_steps`.\ntest_steps:\n    `#### Test Steps` sub-section (a numbered verification procedure).\n    Optional; independent of `description`.\nnumber:\n    Computed. The criterion's 3-digit number (e.g. `1` for\n    `### AC-001 (Test): ...`). Never stored separately -- derived from\n    the retained heading text.\nmethod:\n    Computed. The closed DTAIS method word carried by the heading\n    (e.g. `\"Test\"` for `### AC-001 (Test): ...`), exactly as written\n    (not lowercased/normalized). Never stored separately -- derived\n    from the retained heading text."New value: +"`### AC-NNN (Method): <criterion text>` under `## Acceptance Criteria` -- one verification criterion.\n\nThe number, method, and criterion text all live in the heading itself\n(e.g. `### AC-001 (Test): The revoke endpoint returns 204 within 1s`),\nconstrained by the regex `@alias` above and enforced by `match_alias`\n(`re.fullmatch`) at parse time -- a missing/out-of-range/malformed\nnumber, an unknown method word, or a title-less heading all fail the\nparse eagerly (REQ-003). The method word is one of the five DTAIS words:\n`Demonstration`, `Test`, `Analysis`, `Inspection`, `Special` (the\n`specmgr://dtais` vocabulary). AC numbers need not be contiguous (gaps are\nallowed, numbers are never renumbered); duplicates are rejected by\n`Vcr`'s own after-validator (the `ValidationError` channel, mirroring\nDEC's `Decision._validate_option_numbers_unique`).\n\nUnlike DEC's `Option`/RSK's `Probability`/`Impact` (all *leaf* sections\nwith zero other declared fields, so their own `.text` computed property\nreturns the *complete* extent verbatim, heading marker and any body\ntext both included), this class declares two other fields\n(`description`, `test_steps`), making it a *composite* section: its own\n`.text` therefore returns only the heading's own inline content (marker\nstripped, body text excluded -- see `MarkdownSection.text`'s composite\nbranch). `number`/`method` below are matched against that heading-only\n`.text` directly, not `.text.splitlines()[0]` -- the DEC/RSK idiom's\nexact mechanics don't apply verbatim here because of this leaf/composite\ndifference, even though the underlying idea (compute a value from the\nretained heading text via a private module-level compiled regex) is the\nsame. A consequence: an `AcceptanceCriterion`'s body may contain nothing\nbesides an optional free-form `description` paragraph followed by an\noptional `#### Test Steps` -- both independently optional (e.g. one\ncriterion may carry only a description, another only `Test Steps`,\nanother both, another neither), in that fixed declaration order.\n\nParameters\n----------\ndescription:\n    The lead paragraph directly under the heading -- free-form prose\n    elaborating on the criterion beyond what fits in the heading\n    itself (mirrors `MoreInformation`'s \"free-form, no fixed format\"\n    tone). Optional; independent of `test_steps`.\ntest_steps:\n    `#### Test Steps` sub-section (a numbered verification procedure).\n    Optional; independent of `description`.\nnumber:\n    Computed. The criterion's 3-digit number (e.g. `1` for\n    `### AC-001 (Test): ...`). Never stored separately -- derived from\n    the retained heading text.\nmethod:\n    Computed. The closed DTAIS method word carried by the heading\n    (e.g. `\"Test\"` for `### AC-001 (Test): ...`), exactly as written\n    (not lowercased/normalized). Never stored separately -- derived\n    from the retained heading text."
    • addedOutput schema / $defs / AcceptanceCriterion / pattern
      Added value: +"^AC-(\\d{3}) \\((Demonstration|Test|Analysis|Inspection|Special)\\): .+$"
    • addedOutput schema / $defs / VcrFrontmatter / properties / status / enum
      Added value: +[
      +  "approved",
      +  "complete",
      +  "draft",
      +  "progress"
      +]
  2. First observedv0.36.0

TDQS

A4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations supplied, the description carries the whole burden and does so thoroughly: parse failures on an existing file return a non-raising ValidateResult with valid=False and a 300-char-capped errors[].message instead of raising AssertionError/ValidationError/YAMLError, while an absent or unreadable path still raises the OSError family from Path.read_text(). It also discloses the language-resolution rule keyed to path position, including the actionable ValueError when no table exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose is front-loaded in the first clause, but the body is a single dense block salted with internal bookkeeping (feat-110, ADR UUIDs, 'case 5 of the ADR 519d1206 non-raising-structured-result workaround chain', GitHub issue #204) that adds little for an agent choosing or calling the tool. The genuinely useful facts — non-raising parse failure, raising file-access failure, path-based language resolution — are buried in the same run-on sentence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter parse tool with no annotations and an existing output schema, the description covers everything an agent needs before calling: what the input file looks like, what happens on parse failure versus file-access failure, and how path placement silently selects the heading-mapping table. Return-value shape is deferred to the output schema, which is appropriate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate for the single undocumented `path` parameter, and it does: it explains that the file's language is derived from the path's position relative to the VCR base directory — flat docs/vcr/ parses canonical, docs/vcr/{language}/ uses that language's heading-mapping table, anything else parses canonical. It stops short of stating whether the path is absolute or base-relative, which leaves a residual ambiguity.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence gives a precise verb, resource and output type: 'Parse a verification case record markdown file (YAML frontmatter + body) from disk into a structured ... VcrDocument'. That separates it from get_vcr/list_vcr/create_vcr by verb alone, but the description never names a sibling or states explicitly that it is the read-and-deserialize counterpart to the generic `validate` tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated: an agent can infer it should call this when it has a file path on disk that needs turning into a VcrDocument, and the mention of the generic `validate` tool hints at an alternative. There is no explicit when-to-use/when-not guidance and no routing to get_vcr, validate, or parse_* siblings for other artifact types.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Deploy Server

Other Tools