| create_tskA | Create a new task list: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the task list base directory. A content-validation failure of the submitted body 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 (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. The structure reference is the get_tsk_schema tool (the generated JSON Schema); the get_tsk_template/get_tsk_example tools return the authoring template and a complete sample. Returns the newly created document's frontmatter only (no body); use the corresponding get_tsk tool to fetch the full document afterward. The optional language parameter (default 'en', feat-197-i18n) selects the language to create the document in: omitted/'en' = a new flat docs/tsk/ document with a fresh id, exactly the default behavior (id must then be omitted); a non-default ISO 639-1-shaped lowercase two-letter code (e.g. 'de') creates a TRANSLATION of an existing task list instead: id -- the shared id of the existing EN source document -- is then required (no fresh id is assigned; the variant carries the same id), the EN source must exist (else TskNotFoundError), and the variant is written to docs/tsk/{language}/ under the EN source's exact file name with status draft; content is validated through that language's heading-mapping table (translated headings are accepted) and persisted verbatim. An existing variant of that id and language is never overwritten (FileExistsError). A malformed language, one with no packaged heading-mapping table, a missing id for a non-default language, or an id given for the default language is a ValueError raised before any file access. |
| get_tskA | Read, parse, and return a full task list document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_tsk -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str). The optional language parameter (default 'en') selects the language variant to read: omitted/'en' = the flat docs/tsk/ document, exactly the default behavior; any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = that language's variant at docs/tsk/{language}/ (the EN source's exact basename). The language is shape-validated before any file access (a path-injection-shaped payload is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError, also before any file access. A raw=True read of a variant returns the variant's on-disk body verbatim (translation preserved); a raw=False read parses it through the variant's heading table, so the structured model holds canonical heading text. The ParseFailureResult error of a broken variant is byte-identical to list_tsk(language=...)'s failed row for the same file. |
| get_tsk_exampleA | Return a complete, valid sample task list document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example. |
| get_tsk_schemaA | Return the TSK domain's generated JSON Schema (2020-12 dialect) as raw text -- the machine-readable, parsed-JSON view of the document structure, not the markdown view (call get_tsk_template for the authoring starting point). Fetch it for constraint discovery, structural questions, or an unresolved validation error -- never as a mandatory pre-authoring fetch. Generated by specmgr schema and kept current by a pre-commit hook/CI step; includes a $comment schema-layout version marker for detecting a shape change without diffing the whole document. |
| get_tsk_templateA | Return a TSK document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new task list. |
| list_tskA | Ids, titles, statuses, and refs of task lists in the configured task list base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_tsk tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the task lists whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored. The optional language parameter (default 'en') selects the directory scanned: omitted/'en' = the flat docs/tsk/ directory (the default behavior, unchanged); any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = only that language's docs/tsk/{language}/ subdirectory, listing exactly the existing variants of that language (there is deliberately no 'all languages' mode). The language is shape-validated before any file access (an invalid-shaped value is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError. |
| parse_tskA | Parse a task list markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.tsk.models.v1.TskDocument. 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 task list base directory: a file in the flat docs/tsk/ directory parses canonical (no heading-mapping table); a file in a direct two-letter docs/tsk/{language}/ subdirectory parses through that language's table (an actionable ValueError when no table exists for the language); any other location parses canonical. |
| create_golA | Create a new goal: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the goal base directory. A content-validation failure of the submitted body 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 (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. The structure reference is the get_gol_schema tool (the generated JSON Schema); the get_gol_template/get_gol_example tools return the authoring template and a complete sample. Returns the newly created document's frontmatter only (no body); use the corresponding get_gol tool to fetch the full document afterward. The optional language parameter (default 'en', feat-197-i18n) selects the language to create the document in: omitted/'en' = a new flat docs/gol/ document with a fresh id, exactly the default behavior (id must then be omitted); a non-default ISO 639-1-shaped lowercase two-letter code (e.g. 'de') creates a TRANSLATION of an existing goal instead: id -- the shared id of the existing EN source document -- is then required (no fresh id is assigned; the variant carries the same id), the EN source must exist (else GolNotFoundError), and the variant is written to docs/gol/{language}/ under the EN source's exact file name with status draft; content is validated through that language's heading-mapping table (translated headings are accepted) and persisted verbatim. An existing variant of that id and language is never overwritten (FileExistsError). A malformed language, one with no packaged heading-mapping table, a missing id for a non-default language, or an id given for the default language is a ValueError raised before any file access. |
| get_golA | Read, parse, and return a full goal document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_gol -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str). The optional language parameter (default 'en') selects the language variant to read: omitted/'en' = the flat docs/gol/ document, exactly the default behavior; any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = that language's variant at docs/gol/{language}/ (the EN source's exact basename). The language is shape-validated before any file access (a path-injection-shaped payload is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError, also before any file access. A raw=True read of a variant returns the variant's on-disk body verbatim (translation preserved); a raw=False read parses it through the variant's heading table, so the structured model holds canonical heading text. The ParseFailureResult error of a broken variant is byte-identical to list_gol(language=...)'s failed row for the same file. |
| get_gol_exampleA | Return a complete, valid sample goal document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example. |
| get_gol_schemaA | Return the GOL domain's generated JSON Schema (2020-12 dialect) as raw text -- the machine-readable, parsed-JSON view of the document structure, not the markdown view (call get_gol_template for the authoring starting point). Fetch it for constraint discovery, structural questions, or an unresolved validation error -- never as a mandatory pre-authoring fetch. Generated by specmgr schema and kept current by a pre-commit hook/CI step; includes a $comment schema-layout version marker for detecting a shape change without diffing the whole document. |
| get_gol_templateA | Return a GOL document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new goal. |
| list_golA | Ids, titles, statuses, and refs of goals in the configured goal base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_gol tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the goals whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored. The optional language parameter (default 'en') selects the directory scanned: omitted/'en' = the flat docs/gol/ directory (the default behavior, unchanged); any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = only that language's docs/gol/{language}/ subdirectory, listing exactly the existing variants of that language (there is deliberately no 'all languages' mode). The language is shape-validated before any file access (an invalid-shaped value is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError. |
| parse_golA | Parse a goal markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.gol.models.v1.GolDocument. 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 goal base directory: a file in the flat docs/gol/ directory parses canonical (no heading-mapping table); a file in a direct two-letter docs/gol/{language}/ subdirectory parses through that language's table (an actionable ValueError when no table exists for the language); any other location parses canonical. |
| create_prbA | Create a new Problem Statement: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the problem statement base directory. A content-validation failure of the submitted body 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 (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. The structure reference is the get_prb_schema tool (the generated JSON Schema); the get_prb_template/get_prb_example tools return the authoring template and a complete sample. Returns the newly created document's frontmatter only (no body); use the corresponding get_prb tool to fetch the full document afterward. The optional language parameter (default 'en', feat-197-i18n) selects the language to create the document in: omitted/'en' = a new flat docs/prb/ document with a fresh id, exactly the default behavior (id must then be omitted); a non-default ISO 639-1-shaped lowercase two-letter code (e.g. 'de') creates a TRANSLATION of an existing problem statement instead: id -- the shared id of the existing EN source document -- is then required (no fresh id is assigned; the variant carries the same id), the EN source must exist (else PrbNotFoundError), and the variant is written to docs/prb/{language}/ under the EN source's exact file name with status draft; content is validated through that language's heading-mapping table (translated headings are accepted) and persisted verbatim. An existing variant of that id and language is never overwritten (FileExistsError). A malformed language, one with no packaged heading-mapping table, a missing id for a non-default language, or an id given for the default language is a ValueError raised before any file access. |
| get_prbA | Read, parse, and return a full problem statement document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_prb -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str). The optional language parameter (default 'en') selects the language variant to read: omitted/'en' = the flat docs/prb/ document, exactly the default behavior; any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = that language's variant at docs/prb/{language}/ (the EN source's exact basename). The language is shape-validated before any file access (a path-injection-shaped payload is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError, also before any file access. A raw=True read of a variant returns the variant's on-disk body verbatim (translation preserved); a raw=False read parses it through the variant's heading table, so the structured model holds canonical heading text. The ParseFailureResult error of a broken variant is byte-identical to list_prb(language=...)'s failed row for the same file. |
| get_prb_exampleA | Return a complete, valid sample problem statement document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example. |
| get_prb_schemaA | Return the PRB domain's generated JSON Schema (2020-12 dialect) as raw text -- the machine-readable, parsed-JSON view of the document structure, not the markdown view (call get_prb_template for the authoring starting point). Fetch it for constraint discovery, structural questions, or an unresolved validation error -- never as a mandatory pre-authoring fetch. Generated by specmgr schema and kept current by a pre-commit hook/CI step; includes a $comment schema-layout version marker for detecting a shape change without diffing the whole document. |
| get_prb_templateA | Return a PRB document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new problem statement. |
| list_prbA | Ids, titles, statuses, and refs of problem statements in the configured problem statement base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_prb tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the problem statements whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored. The optional language parameter (default 'en') selects the directory scanned: omitted/'en' = the flat docs/prb/ directory (the default behavior, unchanged); any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = only that language's docs/prb/{language}/ subdirectory, listing exactly the existing variants of that language (there is deliberately no 'all languages' mode). The language is shape-validated before any file access (an invalid-shaped value is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError. |
| parse_prbA | Parse a problem statement markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.prb.models.v1.PrbDocument. 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 problem statement base directory: a file in the flat docs/prb/ directory parses canonical (no heading-mapping table); a file in a direct two-letter docs/prb/{language}/ subdirectory parses through that language's table (an actionable ValueError when no table exists for the language); any other location parses canonical. |
| create_qaA | Create a new Question and Answer (QA) document: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the QA base directory. A content-validation failure of the submitted body 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 (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. The structure reference is the get_qa_schema tool (the generated JSON Schema); the get_qa_template/get_qa_example tools return the authoring template and a complete sample. Returns the newly created document's frontmatter only (no body); use the corresponding get_qa tool to fetch the full document afterward. The optional language parameter (default 'en', feat-197-i18n) selects the language to create the document in: omitted/'en' = a new flat docs/qa/ document with a fresh id, exactly the default behavior (id must then be omitted); a non-default ISO 639-1-shaped lowercase two-letter code (e.g. 'de') creates a TRANSLATION of an existing QA document instead: id -- the shared id of the existing EN source document -- is then required (no fresh id is assigned; the variant carries the same id), the EN source must exist (else QaNotFoundError), and the variant is written to docs/qa/{language}/ under the EN source's exact file name with status draft; content is validated through that language's heading-mapping table (translated headings are accepted) and persisted verbatim. An existing variant of that id and language is never overwritten (FileExistsError). A malformed language, one with no packaged heading-mapping table, a missing id for a non-default language, or an id given for the default language is a ValueError raised before any file access. |
| get_qaA | Read, parse, and return a full QA document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_qa -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str). The optional language parameter (default 'en') selects the language variant to read: omitted/'en' = the flat docs/qa/ document, exactly the default behavior; any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = that language's variant at docs/qa/{language}/ (the EN source's exact basename). The language is shape-validated before any file access (a path-injection-shaped payload is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError, also before any file access. A raw=True read of a variant returns the variant's on-disk body verbatim (translation preserved); a raw=False read parses it through the variant's heading table, so the structured model holds canonical heading text. The ParseFailureResult error of a broken variant is byte-identical to list_qa(language=...)'s failed row for the same file. |
| get_qa_exampleA | Return a complete, valid sample QA document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example. |
| get_qa_schemaA | Return the QA domain's generated JSON Schema (2020-12 dialect) as raw text -- the machine-readable, parsed-JSON view of the document structure, not the markdown view (call get_qa_template for the authoring starting point). Fetch it for constraint discovery, structural questions, or an unresolved validation error -- never as a mandatory pre-authoring fetch. Generated by specmgr schema and kept current by a pre-commit hook/CI step; includes a $comment schema-layout version marker for detecting a shape change without diffing the whole document. |
| get_qa_templateA | Return a QA document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new QA document. |
| list_qaA | Ids, titles, statuses, and refs of QA documents in the configured QA base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_qa tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the QA documents whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored. The optional language parameter (default 'en') selects the directory scanned: omitted/'en' = the flat docs/qa/ directory (the default behavior, unchanged); any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = only that language's docs/qa/{language}/ subdirectory, listing exactly the existing variants of that language (there is deliberately no 'all languages' mode). The language is shape-validated before any file access (an invalid-shaped value is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError. |
| parse_qaA | Parse a QA document markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.qa.models.v2.QaDocument. 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 QA document base directory: a file in the flat docs/qa/ directory parses canonical (no heading-mapping table); a file in a direct two-letter docs/qa/{language}/ subdirectory parses through that language's table (an actionable ValueError when no table exists for the language); any other location parses canonical. |
| create_reqA | Create a new requirement: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the requirement base directory. A content-validation failure of the submitted body 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 (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. The structure reference is the get_req_schema tool (the generated JSON Schema); the get_req_template/get_req_example tools return the authoring template and a complete sample. Returns the newly created document's frontmatter only (no body); use the corresponding get_req tool to fetch the full document afterward. The optional language parameter (default 'en', feat-197-i18n) selects the language to create the document in: omitted/'en' = a new flat docs/req/ document with a fresh id, exactly the default behavior (id must then be omitted); a non-default ISO 639-1-shaped lowercase two-letter code (e.g. 'de') creates a TRANSLATION of an existing requirement instead: id -- the shared id of the existing EN source document -- is then required (no fresh id is assigned; the variant carries the same id), the EN source must exist (else ReqNotFoundError), and the variant is written to docs/req/{language}/ under the EN source's exact file name with status draft; content is validated through that language's heading-mapping table (translated headings are accepted) and persisted verbatim. An existing variant of that id and language is never overwritten (FileExistsError). A malformed language, one with no packaged heading-mapping table, a missing id for a non-default language, or an id given for the default language is a ValueError raised before any file access. |
| get_reqA | Read, parse, and return a full requirement document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_req -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str). The optional language parameter (default 'en') selects the language variant to read: omitted/'en' = the flat docs/req/ document, exactly the default behavior; any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = that language's variant at docs/req/{language}/ (the EN source's exact basename). The language is shape-validated before any file access (a path-injection-shaped payload is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError, also before any file access. A raw=True read of a variant returns the variant's on-disk body verbatim (translation preserved); a raw=False read parses it through the variant's heading table, so the structured model holds canonical heading text. The ParseFailureResult error of a broken variant is byte-identical to list_req(language=...)'s failed row for the same file. |
| get_req_exampleA | Return a complete, valid sample requirement document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example. |
| get_req_schemaA | Return the REQ domain's generated JSON Schema (2020-12 dialect) as raw text -- the machine-readable, parsed-JSON view of the document structure, not the markdown view (call get_req_template for the authoring starting point). Fetch it for constraint discovery, structural questions, or an unresolved validation error -- never as a mandatory pre-authoring fetch. Generated by specmgr schema and kept current by a pre-commit hook/CI step; includes a $comment schema-layout version marker for detecting a shape change without diffing the whole document. |
| get_req_templateA | Return a REQ document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new requirement. |
| list_reqA | Ids, titles, statuses, and refs of requirements in the configured requirement base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_req tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the requirements whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored. The optional language parameter (default 'en') selects the directory scanned: omitted/'en' = the flat docs/req/ directory (the default behavior, unchanged); any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = only that language's docs/req/{language}/ subdirectory, listing exactly the existing variants of that language (there is deliberately no 'all languages' mode). The language is shape-validated before any file access (an invalid-shaped value is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError. |
| parse_reqB | Parse a requirement markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.req.models.v1.ReqDocument. 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 requirement base directory: a file in the flat docs/req/ directory parses canonical (no heading-mapping table); a file in a direct two-letter docs/req/{language}/ subdirectory parses through that language's table (an actionable ValueError when no table exists for the language); any other location parses canonical. |
| create_rskA | Create a new risk: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the risk base directory. A content-validation failure of the submitted body 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 (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. The structure reference is the get_rsk_schema tool (the generated JSON Schema); the get_rsk_template/get_rsk_example tools return the authoring template and a complete sample. Returns the newly created document's frontmatter only (no body); use the corresponding get_rsk tool to fetch the full document afterward. The optional language parameter (default 'en', feat-197-i18n) selects the language to create the document in: omitted/'en' = a new flat docs/rsk/ document with a fresh id, exactly the default behavior (id must then be omitted); a non-default ISO 639-1-shaped lowercase two-letter code (e.g. 'de') creates a TRANSLATION of an existing risk instead: id -- the shared id of the existing EN source document -- is then required (no fresh id is assigned; the variant carries the same id), the EN source must exist (else RskNotFoundError), and the variant is written to docs/rsk/{language}/ under the EN source's exact file name with status open; content is validated through that language's heading-mapping table (translated headings are accepted) and persisted verbatim. An existing variant of that id and language is never overwritten (FileExistsError). A malformed language, one with no packaged heading-mapping table, a missing id for a non-default language, or an id given for the default language is a ValueError raised before any file access. |
| get_rskA | Read, parse, and return a full risk document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_rsk -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str). The optional language parameter (default 'en') selects the language variant to read: omitted/'en' = the flat docs/rsk/ document, exactly the default behavior; any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = that language's variant at docs/rsk/{language}/ (the EN source's exact basename). The language is shape-validated before any file access (a path-injection-shaped payload is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError, also before any file access. A raw=True read of a variant returns the variant's on-disk body verbatim (translation preserved); a raw=False read parses it through the variant's heading table, so the structured model holds canonical heading text. The ParseFailureResult error of a broken variant is byte-identical to list_rsk(language=...)'s failed row for the same file. |
| get_rsk_exampleA | Return a complete, valid sample risk document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example. |
| get_rsk_schemaA | Return the RSK domain's generated JSON Schema (2020-12 dialect) as raw text -- the machine-readable, parsed-JSON view of the document structure, not the markdown view (call get_rsk_template for the authoring starting point). Fetch it for constraint discovery, structural questions, or an unresolved validation error -- never as a mandatory pre-authoring fetch. Generated by specmgr schema and kept current by a pre-commit hook/CI step; includes a $comment schema-layout version marker for detecting a shape change without diffing the whole document. |
| get_rsk_templateA | Return a risk document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new risk. |
| list_rskA | Ids, titles, statuses, and refs of risks in the configured risk base directory, one page at a time, for context before addressing one by id. Each line also carries the initial/residual 5x5 zone levels, the TARA strategy word, the first ## Scope entry, and the residual-risk coordinates (residual_probability/residual_impact/residual_product). 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_rsk tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the risks whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored. The optional language parameter (default 'en') selects the directory scanned: omitted/'en' = the flat docs/rsk/ directory (the default behavior, unchanged); any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = only that language's docs/rsk/{language}/ subdirectory, listing exactly the existing variants of that language (there is deliberately no 'all languages' mode). The language is shape-validated before any file access (an invalid-shaped value is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError. |
| parse_rskA | Parse a risk markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.rsk.models.v1.RskDocument. 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 risk base directory: a file in the flat docs/rsk/ directory parses canonical (no heading-mapping table); a file in a direct two-letter docs/rsk/{language}/ subdirectory parses through that language's table (an actionable ValueError when no table exists for the language); any other location parses canonical. |
| create_sopA | Create a new Standard Operating Procedure: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the SOP base directory. A content-validation failure of the submitted body 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 (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. The structure reference is the get_sop_schema tool (the generated JSON Schema); the get_sop_template/get_sop_example tools return the authoring template and a complete sample. Returns the newly created document's frontmatter only (no body); use the corresponding get_sop tool to fetch the full document afterward. The optional language parameter (default 'en', feat-197-i18n) selects the language to create the document in: omitted/'en' = a new flat docs/sop/ document with a fresh id, exactly the default behavior (id must then be omitted); a non-default ISO 639-1-shaped lowercase two-letter code (e.g. 'de') creates a TRANSLATION of an existing Standard Operating Procedure instead: id -- the shared id of the existing EN source document -- is then required (no fresh id is assigned; the variant carries the same id), the EN source must exist (else SopNotFoundError), and the variant is written to docs/sop/{language}/ under the EN source's exact file name with status draft; content is validated through that language's heading-mapping table (translated headings are accepted) and persisted verbatim. An existing variant of that id and language is never overwritten (FileExistsError). A malformed language, one with no packaged heading-mapping table, a missing id for a non-default language, or an id given for the default language is a ValueError raised before any file access. |
| get_sopA | Read, parse, and return a full SOP document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_sop -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str). The optional language parameter (default 'en') selects the language variant to read: omitted/'en' = the flat docs/sop/ document, exactly the default behavior; any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = that language's variant at docs/sop/{language}/ (the EN source's exact basename). The language is shape-validated before any file access (a path-injection-shaped payload is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError, also before any file access. A raw=True read of a variant returns the variant's on-disk body verbatim (translation preserved); a raw=False read parses it through the variant's heading table, so the structured model holds canonical heading text. The ParseFailureResult error of a broken variant is byte-identical to list_sop(language=...)'s failed row for the same file. |
| get_sop_exampleA | Return a complete, valid sample Standard Operating Procedure document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example. |
| get_sop_schemaA | Return the SOP domain's generated JSON Schema (2020-12 dialect) as raw text -- the machine-readable, parsed-JSON view of the document structure, not the markdown view (call get_sop_template for the authoring starting point). Fetch it for constraint discovery, structural questions, or an unresolved validation error -- never as a mandatory pre-authoring fetch. Generated by specmgr schema and kept current by a pre-commit hook/CI step; includes a $comment schema-layout version marker for detecting a shape change without diffing the whole document. |
| get_sop_templateA | Return a SOP document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new Standard Operating Procedure. |
| list_sopA | Ids, titles, statuses, and refs of Standard Operating Procedures in the configured SOP base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_sop tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the Standard Operating Procedures whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored. The optional language parameter (default 'en') selects the directory scanned: omitted/'en' = the flat docs/sop/ directory (the default behavior, unchanged); any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = only that language's docs/sop/{language}/ subdirectory, listing exactly the existing variants of that language (there is deliberately no 'all languages' mode). The language is shape-validated before any file access (an invalid-shaped value is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError. |
| parse_sopA | Parse a Standard Operating Procedure markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.sop.models.v1.SopDocument. 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 Standard Operating Procedure base directory: a file in the flat docs/sop/ directory parses canonical (no heading-mapping table); a file in a direct two-letter docs/sop/{language}/ subdirectory parses through that language's table (an actionable ValueError when no table exists for the language); any other location parses canonical. |
| create_sysrsA | Create a new System Requirements Specification: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the System Requirements Specification base directory. A content-validation failure of the submitted body 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 (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. The structure reference is the get_sysrs_schema tool (the generated JSON Schema); the get_sysrs_template/get_sysrs_example tools return the authoring template and a complete sample. Returns the newly created document's frontmatter only (no body); use the corresponding get_sysrs tool to fetch the full document afterward. The optional language parameter (default 'en', feat-197-i18n) selects the language to create the document in: omitted/'en' = a new flat docs/sysrs/ document with a fresh id, exactly the default behavior (id must then be omitted); a non-default ISO 639-1-shaped lowercase two-letter code (e.g. 'de') creates a TRANSLATION of an existing System Requirements Specification instead: id -- the shared id of the existing EN source document -- is then required (no fresh id is assigned; the variant carries the same id), the EN source must exist (else SysrsNotFoundError), and the variant is written to docs/sysrs/{language}/ under the EN source's exact file name with status draft; content is validated through that language's heading-mapping table (translated headings are accepted) and persisted verbatim. An existing variant of that id and language is never overwritten (FileExistsError). A malformed language, one with no packaged heading-mapping table, a missing id for a non-default language, or an id given for the default language is a ValueError raised before any file access. |
| get_sysrsA | Read, parse, and return a full System Requirements Specification document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_sysrs -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str). The optional language parameter (default 'en') selects the language variant to read: omitted/'en' = the flat docs/sysrs/ document, exactly the default behavior; any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = that language's variant at docs/sysrs/{language}/ (the EN source's exact basename). The language is shape-validated before any file access (a path-injection-shaped payload is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError, also before any file access. A raw=True read of a variant returns the variant's on-disk body verbatim (translation preserved); a raw=False read parses it through the variant's heading table, so the structured model holds canonical heading text. The ParseFailureResult error of a broken variant is byte-identical to list_sysrs(language=...)'s failed row for the same file. |
| get_sysrs_exampleA | Return a complete, valid sample System Requirements Specification document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example. |
| get_sysrs_schemaA | Return the SYSRS domain's generated JSON Schema (2020-12 dialect) as raw text -- the machine-readable, parsed-JSON view of the document structure, not the markdown view (call get_sysrs_template for the authoring starting point). Fetch it for constraint discovery, structural questions, or an unresolved validation error -- never as a mandatory pre-authoring fetch. Generated by specmgr schema and kept current by a pre-commit hook/CI step; includes a $comment schema-layout version marker for detecting a shape change without diffing the whole document. |
| get_sysrs_templateA | Return a SYSRS document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new System Requirements Specification. |
| list_sysrsA | Ids, titles, statuses, and refs of System Requirements Specifications in the configured System Requirements Specification base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_sysrs tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the System Requirements Specifications whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored. The optional language parameter (default 'en') selects the directory scanned: omitted/'en' = the flat docs/sysrs/ directory (the default behavior, unchanged); any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = only that language's docs/sysrs/{language}/ subdirectory, listing exactly the existing variants of that language (there is deliberately no 'all languages' mode). The language is shape-validated before any file access (an invalid-shaped value is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError. |
| parse_sysrsA | Parse a System Requirements Specification markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.sysrs.models.v1.SysrsDocument. 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 System Requirements Specification base directory: a file in the flat docs/sysrs/ directory parses canonical (no heading-mapping table); a file in a direct two-letter docs/sysrs/{language}/ subdirectory parses through that language's table (an actionable ValueError when no table exists for the language); any other location parses canonical. |
| create_txtA | Create a new free-form text document: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the free-form text base directory. A content-validation failure of the submitted body 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 (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. The structure reference is the get_txt_schema tool (the generated JSON Schema); the get_txt_template/get_txt_example tools return the authoring template and a complete sample. Returns the newly created document's frontmatter only (no body); use the corresponding get_txt tool to fetch the full document afterward. The optional language parameter (default 'en', feat-197-i18n) selects the language to create the document in: omitted/'en' = a new flat docs/txt/ document with a fresh id, exactly the default behavior (id must then be omitted); a non-default ISO 639-1-shaped lowercase two-letter code (e.g. 'de') creates a TRANSLATION of an existing free-form text document instead: id -- the shared id of the existing EN source document -- is then required (no fresh id is assigned; the variant carries the same id), the EN source must exist (else TxtNotFoundError), and the variant is written to docs/txt/{language}/ under the EN source's exact file name with status draft; content is validated through that language's heading-mapping table (translated headings are accepted) and persisted verbatim. An existing variant of that id and language is never overwritten (FileExistsError). A malformed language, one with no packaged heading-mapping table, a missing id for a non-default language, or an id given for the default language is a ValueError raised before any file access. |
| get_txtA | Read, parse, and return a full free-form text document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_txt -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str). The optional language parameter (default 'en') selects the language variant to read: omitted/'en' = the flat docs/txt/ document, exactly the default behavior; any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = that language's variant at docs/txt/{language}/ (the EN source's exact basename). The language is shape-validated before any file access (a path-injection-shaped payload is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError, also before any file access. A raw=True read of a variant returns the variant's on-disk body verbatim (translation preserved); a raw=False read parses it through the variant's heading table, so the structured model holds canonical heading text. The ParseFailureResult error of a broken variant is byte-identical to list_txt(language=...)'s failed row for the same file. |
| get_txt_exampleA | Return a complete, valid sample free-form text document as raw markdown -- frontmatter and body -- exercising the free-form body (free H2/H3 headings, a list, a free-floating reference line) and the mandatory ## Updates log with two ordered entries, for use as a learning example. |
| get_txt_schemaA | Return the TXT domain's generated JSON Schema (2020-12 dialect) as raw text -- the machine-readable, parsed-JSON view of the document structure, not the markdown view (call get_txt_template for the authoring starting point). Fetch it for constraint discovery, structural questions, or an unresolved validation error -- never as a mandatory pre-authoring fetch. Generated by specmgr schema and kept current by a pre-commit hook/CI step; includes a $comment schema-layout version marker for detecting a shape change without diffing the whole document. |
| get_txt_templateA | Return a TXT document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new free-form text document. |
| list_txtA | Ids, titles, statuses, and refs of free-form text documents in the configured free-form text base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_txt tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the free-form text documents whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored. The optional language parameter (default 'en') selects the directory scanned: omitted/'en' = the flat docs/txt/ directory (the default behavior, unchanged); any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = only that language's docs/txt/{language}/ subdirectory, listing exactly the existing variants of that language (there is deliberately no 'all languages' mode). The language is shape-validated before any file access (an invalid-shaped value is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError. |
| parse_txtA | Parse a free-form text markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.txt.models.v1.TxtDocument. 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 free-form text base directory: a file in the flat docs/txt/ directory parses canonical (no heading-mapping table); a file in a direct two-letter docs/txt/{language}/ subdirectory parses through that language's table (an actionable ValueError when no table exists for the language); any other location parses canonical. |
| create_ucA | Create a new use case: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the use-case base directory. A content-validation failure of the submitted body 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 (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. The structure reference is the get_uc_schema tool (the generated JSON Schema); the get_uc_template/get_uc_example tools return the authoring template and a complete sample. Returns the newly created document's frontmatter only (no body); use the corresponding get_uc tool to fetch the full document afterward. The optional language parameter (default 'en', feat-197-i18n) selects the language to create the document in: omitted/'en' = a new flat docs/uc/ document with a fresh id, exactly the default behavior (id must then be omitted); a non-default ISO 639-1-shaped lowercase two-letter code (e.g. 'de') creates a TRANSLATION of an existing use case instead: id -- the shared id of the existing EN source document -- is then required (no fresh id is assigned; the variant carries the same id), the EN source must exist (else UcNotFoundError), and the variant is written to docs/uc/{language}/ under the EN source's exact file name with status draft; content is validated through that language's heading-mapping table (translated headings are accepted) and persisted verbatim. An existing variant of that id and language is never overwritten (FileExistsError). A malformed language, one with no packaged heading-mapping table, a missing id for a non-default language, or an id given for the default language is a ValueError raised before any file access. |
| get_ucA | Read, parse, and return a full use-case document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_uc -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str). The optional language parameter (default 'en') selects the language variant to read: omitted/'en' = the flat docs/uc/ document, exactly the default behavior; any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = that language's variant at docs/uc/{language}/ (the EN source's exact basename). The language is shape-validated before any file access (a path-injection-shaped payload is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError, also before any file access. A raw=True read of a variant returns the variant's on-disk body verbatim (translation preserved); a raw=False read parses it through the variant's heading table, so the structured model holds canonical heading text. The ParseFailureResult error of a broken variant is byte-identical to list_uc(language=...)'s failed row for the same file. |
| get_uc_diagramA | Render and return the deterministic PlantUML usecase diagram for one use case (the frozen rulebook specmgr://uc/plantuml §2.5): one usecase node (title + level stereotype), one actor node per distinct cleaned actor label, plain associations. Read-only: the id is path-safety-guarded (a wrong-format id is a ValueError before any file access) and the document is read cache-aware; a document that exists but fails to parse returns the non-raising ParseFailureResult (error/path/id, the feat-150 precedent), and a truly absent id raises the domain's not-found error. Returns PlantUML source (not a specmgr document) -- run it through the validate_plantuml tool for a validation verdict. |
| get_uc_exampleA | Return a complete, valid sample use case document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example. |
| get_uc_plantuml_exampleA | Return the complete, fully attributed PlantUML sequence diagram for the packaged 'Buy Goods' example UC as raw PlantUML source, verbatim -- the model for the generate_uc_sequence_diagram prompt flow (rulebook §2.9 attribution, every UNATTRIBUTED marker resolved). The file is not markdown and not a specmgr document (no frontmatter, not validate-able). Reads the packaged data file fresh on every call. |
| get_uc_plantuml_templateA | Return the packaged PlantUML sequence-skeleton template (placeholder participants and mapping comments -- the shape get_uc_sequence_skeleton emits, rulebook §2.9) as raw PlantUML source, verbatim. The file is not markdown and not a specmgr document (no frontmatter, not validate-able). Reads the packaged data file fresh on every call. |
| get_uc_schemaA | Return the UC domain's generated JSON Schema (2020-12 dialect) as raw text -- the machine-readable, parsed-JSON view of the document structure, not the markdown view (call get_uc_template for the authoring starting point). Fetch it for constraint discovery, structural questions, or an unresolved validation error -- never as a mandatory pre-authoring fetch. Generated by specmgr schema and kept current by a pre-commit hook/CI step; includes a $comment schema-layout version marker for detecting a shape change without diffing the whole document. |
| get_uc_sequence_skeletonA | Render and return the deterministic PlantUML sequence-diagram skeleton for one use case (the frozen rulebook specmgr://uc/plantuml §2.9): participants, the preconditions note, the trigger (virtual step 0, receiver fixed to the system), the ordinal steps, the alt fragments, the final notes -- and every message the §2.9.3 attribution rule cannot pre-fill as one of the three frozen UNATTRIBUTED marker lines. Read-only: the id is path-safety-guarded (a wrong-format id is a ValueError before any file access) and the document is read cache-aware; a document that exists but fails to parse returns the non-raising ParseFailureResult (error/path/id, the feat-150 precedent), and a truly absent id raises the domain's not-found error. The skeleton is the starting point of the generate_uc_sequence_diagram prompt flow (the agent attributes the markers, validates via validate_plantuml, and writes the .puml file host-native; no specmgr tool writes .puml). |
| get_uc_templateA | Return a UC document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new use case. |
| list_ucA | Ids, titles, statuses, and refs of use cases in the configured use-case base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_uc tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the use cases whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored. The optional language parameter (default 'en') selects the directory scanned: omitted/'en' = the flat docs/uc/ directory (the default behavior, unchanged); any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = only that language's docs/uc/{language}/ subdirectory, listing exactly the existing variants of that language (there is deliberately no 'all languages' mode). The language is shape-validated before any file access (an invalid-shaped value is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError. |
| get_use_case_package_diagramA | Render and return the deterministic PlantUML package diagram for a set of use cases (the frozen rulebook specmgr://uc/plantuml §2.7): one usecase node per document in the given order, the deduplicated actor union, and the <<include>>/<<extend>>/superordinate edges from Related Use Cases. ids=None = every UC in list_uc order (list_uc failed rows -- existing-but-broken documents -- become skipped slots); an id missing on disk or existing-but-broken becomes the same skipped slot, and any reference that does not resolve to a parsed slot in the package (including legacy UC-NNN tokens) takes the deterministic 'Unresolved UC reference' note -- the render never fails on an id or a reference. Read-only: every given id is path-safety-guarded (a wrong-format id is a ValueError before any file access) and the documents are read cache-aware. Returns PlantUML source -- run it through the validate_plantuml tool for a validation verdict. |
| parse_ucA | Parse a use-case markdown file (YAML frontmatter + body) from disk into a structured document. 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 use case base directory: a file in the flat docs/uc/ directory parses canonical (no heading-mapping table); a file in a direct two-letter docs/uc/{language}/ subdirectory parses through that language's table (an actionable ValueError when no table exists for the language); any other location parses canonical. |
| plantuml_encodeA | Encode PlantUML (or any) text to the PlantUML classic URL encoding (custom-base64 0-9A-Za-z-_ over the raw-deflate stream of the text's UTF-8 bytes, no prefix -- the SoWkI... form, rulebook §5.1). Returns the encoding itself, i.e. the {enc} payload of GET {base}/svg/{enc} -- the tool takes no base URL, so prepend the configured server base (SPECMGR_PLANTUML_URL for the url source) to build the renderable URL. Fully offline: no source, subprocess, or network is involved. Decode it back with the library's decode_puml (round-trip lossless). |
| validate_plantumlA | Validate PlantUML diagram text through the strict validation chain (the frozen rulebook specmgr://uc/plantuml §3): the structure check always runs first (on a structure red the parser is never called -- no subprocess, no network), then the single configured source (the first set of SPECMGR_PLANTUML_JAR/SPECMGR_PLANTUML_BIN/SPECMGR_PLANTUML_URL; no fall-through -- a set-but-unavailable source is a hard failure with reason + fix hint), and the all-unset state degrades to the structure-only floor. A PlantUML server crash page (200 + the embedded Java-exception trace -- the recognised 1.2026.8 crash line of the rulebook §5.2 matrix, the known self-message/note-left shape bug) is a recognised INVALID row: valid=false with the line-0 crash finding carrying the exception class and a fix hint pointing at the rulebook §2.9 anchored notes. Content-based: pass the diagram text (a CLI reads the file and passes its text). Never raises for validation content -- returns the non-raising §3.6 result model: structure_ok, valid/rendered (None = not run, never run-and-failed), checked_by (jar/bin/url/structure), errors and warnings (1-based line + message + fix hint), source_state (ok/misconfigured/unavailable/inconclusive/none), available, reason, fix_hint. |
| create_vcrA | Create a new verification case record: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the verification case record base directory. A content-validation failure of the submitted body 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 (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. The structure reference is the get_vcr_schema tool (the generated JSON Schema); the get_vcr_template/get_vcr_example tools return the authoring template and a complete sample. Returns the newly created document's frontmatter only (no body); use the corresponding get_vcr tool to fetch the full document afterward. The optional language parameter (default 'en', feat-197-i18n) selects the language to create the document in: omitted/'en' = a new flat docs/vcr/ document with a fresh id, exactly the default behavior (id must then be omitted); a non-default ISO 639-1-shaped lowercase two-letter code (e.g. 'de') creates a TRANSLATION of an existing verification case record instead: id -- the shared id of the existing EN source document -- is then required (no fresh id is assigned; the variant carries the same id), the EN source must exist (else VcrNotFoundError), and the variant is written to docs/vcr/{language}/ under the EN source's exact file name with status draft; content is validated through that language's heading-mapping table (translated headings are accepted) and persisted verbatim. An existing variant of that id and language is never overwritten (FileExistsError). A malformed language, one with no packaged heading-mapping table, a missing id for a non-default language, or an id given for the default language is a ValueError raised before any file access. |
| get_vcrA | Read, parse, and return a full verification case record document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_vcr -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str). The optional language parameter (default 'en') selects the language variant to read: omitted/'en' = the flat docs/vcr/ document, exactly the default behavior; any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = that language's variant at docs/vcr/{language}/ (the EN source's exact basename). The language is shape-validated before any file access (a path-injection-shaped payload is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError, also before any file access. A raw=True read of a variant returns the variant's on-disk body verbatim (translation preserved); a raw=False read parses it through the variant's heading table, so the structured model holds canonical heading text. The ParseFailureResult error of a broken variant is byte-identical to list_vcr(language=...)'s failed row for the same file. |
| get_vcr_exampleA | Return a complete, valid sample verification case record document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example. |
| get_vcr_schemaA | Return the VCR domain's generated JSON Schema (2020-12 dialect) as raw text -- the machine-readable, parsed-JSON view of the document structure, not the markdown view (call get_vcr_template for the authoring starting point). Fetch it for constraint discovery, structural questions, or an unresolved validation error -- never as a mandatory pre-authoring fetch. Generated by specmgr schema and kept current by a pre-commit hook/CI step; includes a $comment schema-layout version marker for detecting a shape change without diffing the whole document. |
| get_vcr_templateA | Return a VCR document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new verification case record. |
| list_vcrA | Ids, titles, statuses, and refs of verification case records in the configured verification case record base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_vcr tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the verification case records whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored. The optional language parameter (default 'en') selects the directory scanned: omitted/'en' = the flat docs/vcr/ directory (the default behavior, unchanged); any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = only that language's docs/vcr/{language}/ subdirectory, listing exactly the existing variants of that language (there is deliberately no 'all languages' mode). The language is shape-validated before any file access (an invalid-shaped value is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError. |
| parse_vcrA | 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. |
| create_decA | Create a new decision: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the decision base directory. A content-validation failure of the submitted body 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 (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. The structure reference is the get_dec_schema tool (the generated JSON Schema); the get_dec_template/get_dec_example tools return the authoring template and a complete sample. Returns the newly created document's frontmatter only (no body); use the corresponding get_dec tool to fetch the full document afterward. The optional language parameter (default 'en', feat-197-i18n) selects the language to create the document in: omitted/'en' = a new flat docs/dec/ document with a fresh id, exactly the default behavior (id must then be omitted); a non-default ISO 639-1-shaped lowercase two-letter code (e.g. 'de') creates a TRANSLATION of an existing decision instead: id -- the shared id of the existing EN source document -- is then required (no fresh id is assigned; the variant carries the same id), the EN source must exist (else DecNotFoundError), and the variant is written to docs/dec/{language}/ under the EN source's exact file name with status draft; content is validated through that language's heading-mapping table (translated headings are accepted) and persisted verbatim. An existing variant of that id and language is never overwritten (FileExistsError). A malformed language, one with no packaged heading-mapping table, a missing id for a non-default language, or an id given for the default language is a ValueError raised before any file access. |
| get_decA | Read, parse, and return a full decision document (frontmatter and body) by its id. The optional language parameter (default 'en') selects the language variant to read: omitted/'en' = the flat docs/dec/ document, exactly the default behavior; any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = that language's variant at docs/dec/{language}/ (the EN source's exact basename). The language is shape-validated before any file access (a path-injection-shaped payload is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError, also before any file access. A raw=True read of a variant returns the variant's on-disk body verbatim (translation preserved); a raw=False read parses it through the variant's heading table, so the structured model holds canonical heading text. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c) -- for a language variant, against list_dec(language=...) on the same file. An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_dec -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str). |
| get_dec_exampleA | Return a complete, valid sample decision document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example. |
| get_dec_schemaA | Return the DEC domain's generated JSON Schema (2020-12 dialect) as raw text -- the machine-readable, parsed-JSON view of the document structure, not the markdown view (call get_dec_template for the authoring starting point). Fetch it for constraint discovery, structural questions, or an unresolved validation error -- never as a mandatory pre-authoring fetch. Generated by specmgr schema and kept current by a pre-commit hook/CI step; includes a $comment schema-layout version marker for detecting a shape change without diffing the whole document. |
| get_dec_templateA | Return a DEC document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new decision. |
| list_decA | Ids, titles, statuses, and refs of decisions in the configured decision base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_dec tool instead. The optional language parameter (default 'en') selects the directory scanned: omitted/'en' = the flat docs/dec/ directory (the default behavior, unchanged); any other ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = only that language's docs/dec/{language}/ subdirectory, listing exactly the existing variants of that language (there is deliberately no 'all languages' mode). The language is shape-validated before any file access (an invalid-shaped value is a ValueError, like an invalid id), and a shape-valid language without a packaged heading-mapping table is rejected up front with an actionable ValueError. An optional glob pattern (e.g. 'dead*') filters the listing to the decisions whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored. |
| parse_decA | Parse a decision markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.dec.models.v1.DecDocument. 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 decision base directory: a file in the flat docs/dec/ directory parses canonical (no heading-mapping table); a file in a direct two-letter docs/dec/{language}/ subdirectory parses through that language's table (an actionable ValueError when no table exists for the language); any other location parses canonical. |
| validateA | Disk-free, id-free dry run validating document content across the whole-body domains (type is one of req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs, txt; adr is not supported -- use validate_adr instead). full=False (default) validates body-only content (no frontmatter); full=True validates a complete document (frontmatter + body). Never raises for a content-validation failure: always returns {valid: bool, errors: list[{message: str}]} -- errors is empty when valid is True, and each message is truncated to at most _MAX_VALIDATE_ERROR_CHARS (300) characters (plus an "... (truncated)" suffix when truncation occurred) rather than returned verbatim without limit. A full/content-shape mismatch, or an unsupported type, is a caller-usage error and still raises ValueError before any validation runs. This is the sole validate entry point for these domains -- the former per-domain validate_<d> tools are removed; validate_adr remains a separate, unchanged, id-based tool. Each domain's structure reference is its own get_<d>_schema tool (the generated JSON Schema), with get_<d>_template/get_<d>_example as the authoring starting points. |
| create_featA | Create a new feature: assigns a fresh id (caller-chosen via the optional 'id' parameter, or defaulted to feat-0- when omitted -- no max+1 auto-generation), derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the feature base directory. A content-validation failure of the submitted body 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 (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. Content validation runs BEFORE the id-shape ValueError and already-existing-id/folder FileExistsError guards, so a compound failure (invalid content + a malformed or already-existing id) returns the ValidateResult and the guard never runs in that call; each guard still raises whenever the content is valid. The structure reference is the get_feat_schema tool (the generated JSON Schema); the get_feat_template/get_feat_example tools return the authoring template and a complete sample. Returns the newly created document's frontmatter only (no body); use the corresponding get_feat tool to fetch the full document afterward. |
| get_featA | Read, parse, and return a full feature document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; get_feat always fully parses, so its error text is the full-fidelity authority for this document -- byte-identical to list_feat's own failed-row error for the same file once list_feat's background warmup (or this very call) has fully parsed it; before that (or under SPECMGR_FEAT_WARMUP_DISABLED), list_feat's row may carry a transiently-healthy or dirty-stage-specific error instead (ADR 3982712a-a46b-4b2b-809f-9c6925a49b44, time-qualifying ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c for feat only; every other domain's list/get error byte-identity stays unconditional). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_feat -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str). |
| get_feat_exampleA | Return a complete, valid sample feature document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example. |
| get_feat_schemaA | Return the FEAT domain's generated JSON Schema (2020-12 dialect) as raw text -- the machine-readable, parsed-JSON view of the document structure, not the markdown view (call get_feat_template for the authoring starting point). Fetch it for constraint discovery, structural questions, or an unresolved validation error -- never as a mandatory pre-authoring fetch. Generated by specmgr schema and kept current by a pre-commit hook/CI step; includes a $comment schema-layout version marker for detecting a shape change without diffing the whole document. |
| get_feat_templateA | Return a FEAT document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new feature. |
| list_featA | Ids, titles, statuses, and refs of features in the configured feature base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_feat tool instead. An optional glob pattern (e.g. 'feat-7*') filters the listing to the features whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored. The request path never fully parses a document's body (GitHub issue #187): a folder's row is resolved from its frontmatter+H1 alone until a background warmup (or an on-demand get_feat read) has fully parsed it, so a body-level parse failure may transiently appear healthy, and a missing/wrong-shape H1's error text may transiently differ from get_feat's -- both converge to get_feat's exact error once that file has been fully parsed. Set SPECMGR_FEAT_WARMUP_DISABLED to turn the background warmup off entirely (convergence then depends solely on on-demand reads). |
| parse_featA | Parse a feature markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.feat.models.v1.FeatDocument. 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(). |
| set_feat_idA | Rename an existing feature's id: validates new_id's feat-NNN-slug shape, refuses if new_id's folder already exists, renames // to /<new_id>/, rewrites the README frontmatter id to new_id, bumps updated, and leaves the body byte-identical. Does not update or search for references to the old id in any other document. Returns the renamed document's frontmatter only (no body); use the corresponding get_feat tool to fetch the full document afterward. |
| deleteA | Permanently delete an existing document from disk across the whole-body domains (type is one of req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs, txt; adr is not supported). Resolves the document by id, takes the domain lock, and removes it: the single *.md file for every flat domain (every whole-body domain except feat), or the entire <base>/<id>/ folder for feat. Returns the deleted path as a string. An invalid id (path-injection attempt or wrong format) is a ValueError raised before any file access; a missing document is the domain's own XNotFoundError; an I/O failure is a DeleteError. This is the sole delete entry point -- the former per-domain delete_<d> tools are removed. The optional language parameter (default 'en', feat-197-i18n) selects the language variant to delete: omitted/'en' = the flat default-language document, exactly the default behavior; a non-default ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = that language's variant at docs//{language}/ (found by id-scan of that subdirectory), deleting that variant file ONLY -- the EN file stays untouched. Every whole-body type except feat supports a non-default language; for feat (always English) a non-default language raises a ValueError, as does a malformed language or one with no packaged heading-mapping table -- all raised before any file access. |
| editA | Surgical, exact-match string replacement of an existing document's frontmatter-stripped body across the whole-body domains (type is one of req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs, txt; adr is not supported -- an explicit pre-dispatch ValueError, unlike update's inherited KeyError). Read the current body via the corresponding get_<d>(id, raw=True) first -- the read-before-edit step is a client convention, not server-enforced. Use edit for a surgical string replacement within an existing body; use the generic update tool for a whole-body or line-range replacement instead. The YAML frontmatter is never addressable (body only). The edit is 2-fold: stage 1 requires old_str to match the on-disk body byte-exactly -- uniquely, unless replace_all is true, in which case every exact occurrence is rewritten -- and stage 2 validates the edited body as a whole document; the document is written to disk only if both stages pass, and nothing is written on any failure (the file stays byte-unchanged). An empty new_str is a pure deletion (legal iff stage 2 validates). Matching is pure byte-exact with no line-ending normalization (an old_str containing \n will not match a CRLF body), no BOM handling, and no fuzzy/regex fallback. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising the domain's not-found error -- its error text is byte-identical to the domain's list_<d> failed row's error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c) -- and a truly-absent id still raises the domain's not-found error. A stage-2 content-validation failure on the post-edit result returns a non-raising ValidateResult (valid=False, errors=[{message}]) with the message capped at 300 chars as the generic validate tool caps it, instead of raising AssertionError/pydantic.ValidationError (ADR b8c9bfea-6dcf-4158-bfc5-4ec17abb842f, GitHub issue #170 -- case 4 of the ADR 519d1206 non-raising-structured-result workaround chain). Stage-1's not-found/multiple-matches guards and every caller-usage ValueError (invalid id shape, unknown or adr type, identical input, empty old_str) still raise. An invalid id (path-injection attempt or wrong format for type) is a ValueError raised before any file access. Returns the updated frontmatter only (no body; updated bumped) on success; use the corresponding get_<d> tool to fetch the full document afterward. The optional language parameter (default 'en', feat-197-i18n) selects the language variant to edit: omitted/'en' = the flat default-language document, exactly the default behavior; a non-default ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = that language's variant at docs//{language}/ (found by id-scan of that subdirectory), matched against and written to that file ONLY -- the EN file's content and updated timestamp stay untouched -- with the stage-2 validation going through that language's heading-mapping table. Every whole-body type except feat supports a non-default language; for feat (always English) a non-default language raises a ValueError, as does a malformed language or one with no packaged heading-mapping table -- all raised before any file access. |
| find_relatedA | Find the documents most semantically related to an existing document, given its type/id, ranked by cosine similarity of local sentence embeddings (fastembed/bge-small, the similarity extra). By default every whole-body domain is searched (req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs, txt; adr is excluded structurally) -- restrict with target_types; the source document itself is excluded from the results. Returns up to top_k (default 10, validated 1..100) hits as {type, id, title, status, path, score} rows, sorted by score descending; min_score (default: no filter) is an inclusive cosine lower bound. An unparseable candidate still appears, embedded from its full raw text, with id = null and the <failed to parse> marker title/status. When the embedding feature is unavailable (SPECMGR_SIMILARITY_DISABLED present, or the backend/model fails to load), returns the structured {available: false, reason, message} result instead of raising. A bad type/id/target_types/top_k is a ValueError before any filesystem access; a missing source is the domain's own XNotFoundError. |
| find_similar_textA | Find the documents most semantically similar to a free-form query text (for pre-creation dedup/discovery checks), ranked by cosine similarity of local sentence embeddings (fastembed/bge-small, the similarity extra). By default every whole-body domain is searched (req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs, txt; adr is excluded structurally) -- restrict with target_types. Returns up to top_k (default 10, validated 1..100) hits as {type, id, title, status, path, score} rows, sorted by score descending; min_score (default: no filter) is an inclusive cosine lower bound. An unparseable candidate still appears, embedded from its full raw text, with id = null and the <failed to parse> marker title/status. When the embedding feature is unavailable (SPECMGR_SIMILARITY_DISABLED present, or the backend/model fails to load), returns the structured {available: false, reason, message} result instead of raising. A bad target_types/top_k is a ValueError before any filesystem access. |
| create_adrA | Create a new ADR: assigns a fresh id, derives a filename from the title, validates, renders, and writes the new document to the ADR base directory. There is deliberately no specmgr://adr/schema resource -- this tool's own typed input parameters (frontmatter: AdrFrontmatter, body: AdrBody) are the authoritative ADR structure reference. |
| get_adrB | Read, parse, and return a full ADR document (frontmatter and body) by its id. An invalid id (path-injection attempt or wrong format) is a ValueError raised before any file access. |
| list_adrA | Ids, titles, statuses, and refs of ADRs in the configured ADR base directory (SPECMGR_ADR_DIR), one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use get_adr with it instead. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored. |
| option_createB | Append a new 'Option N: ...' sub-section, returning its assigned full title. |
| option_deleteC | Remove the option named full_title, returning the remaining full titles. |
| option_listC | Full titles of every current 'Option N: ...' sub-section, in document order. |
| option_readC | Return the current content of the option named full_title. |
| option_updateB | Full-content replace of the option named full_title, returning the new content. |
| update_frontmatterA | Whole-object replace of an ADR's frontmatter, preserving its existing id. |
| update_sectionC | Whole-section replace/delete of one AdrBody field. |
| validate_adrB | Re-read and re-parse an ADR by id, letting the models' own Pydantic validators run. |
| get_reference_diagramA | Render and return the deterministic PlantUML component diagram of one source document's reference neighbourhood (the frozen rulebook specmgr://reference-graph §2–§5): one node per artifact (label = the document title, truncated to SPECMGR_DIAGRAM_MAX_TITLE, default 40), a stereotype + colour per artifact type, nodes grouped into per-domain curly-brace component groups (one per non-empty domain, closed with } -- the 2026-10-15 corrected form), one label-free edge per unique reference ({src} --> {dst}, the referenced item carries the incoming arrow), every edge lying on a cycle (SCC-based) drawn with the red label-free -[#red]-> arrow, and every reference whose target cannot be resolved on disk drawn as a top-level <<UNRESOLVED>> node. type is the source document's domain (one of adr, req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs, txt) and id the source's own identifier; depth (1..5, default 1) is the forward BFS depth; reverse=True is additive (the forward expansion to depth plus the direct incoming references to the source, direct-only on the incoming side); include_feat=False drops every FEAT node except the explicitly requested source (then every edge touching a dropped node); title overrides the diagram title (default: the source's H1; sanitized but never truncated). Guard order: id (path-injection attempt or wrong format -- for type="feat" the full feat-NNN-slug only; a bare feat-NNN is rejected, use list_feat to discover the exact id) and depth are both a ValueError raised before any filesystem access; a missing source raises the source domain's own XNotFoundError; an existing-but-broken source returns the non-raising ParseFailureResult (error/path/id, the error text byte-identical to the domain's list_<d> failed-row error for the same file (ADR 9080b37c) for the 13 whole-body domains -- time-qualified by ADR 3982712a for feat; for adr (whose list_adr carries no failed row: broken ADRs are skipped), the leg-read AdrParseError's own text). Returns PlantUML source (not a specmgr document) -- run it through specmgr plantuml-check (CLI) or the validate_plantuml tool for a validation verdict. |
| get_reference_diagram_allA | Render and return the deterministic PlantUML component diagram of the whole reference registry (the frozen rulebook specmgr://reference-graph §2–§5, the registry-wide construction of §3.3): one node per parseable document across all 14 domains (broken documents are skipped -- the render never fails for content), one label-free edge per unique reference ({src} --> {dst}, the referenced item carries the incoming arrow), every edge lying on a cycle (SCC-based) drawn with the red label-free -[#red]-> arrow, and every reference whose target cannot be resolved on disk drawn as a top-level <<UNRESOLVED>> node. Node labels are truncated to SPECMGR_DIAGRAM_MAX_TITLE (default 40). include_feat=False drops every FEAT node (then every edge touching a dropped node); title overrides the diagram title (default: Reference Graph; sanitized but never truncated). Returns PlantUML source (not a specmgr document) -- run it through specmgr plantuml-check (CLI) or the validate_plantuml tool for a validation verdict. |
| list_referencesA | Cross-references of one source document, resolved and paged. type is the source document's domain (one of adr, req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs, txt) and id the source's own identifier. The tool scans the source's frontmatter-stripped body for reference tags (the shared reference-tag vocabulary in general.tools._references: the UUID tags GOL/PRB/QA/UC/REQ/RSK/DEC/ADR/VCR/SYSRS/TXT, each carrying a canonical uuid id, plus FEAT, carrying the full feat-NNN-slug id or the bare feat-NNN number; case-insensitive tag, space/tab/dash separator, anywhere in a line), dedupes repeated occurrences (first-occurrence order preserved), and resolves each unique reference to the referenced document in its own target domain. Returns a PagedResult of one ReferenceRow per unique reference: type, id, title (the referenced document's H1), and path (the referenced document's resolved absolute file path). A reference that cannot be resolved on disk is a row with null title/path and the target domain's not-found message in error -- it never raises. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored. An invalid id (path-injection attempt or wrong format for type) is a ValueError raised before any file access; a missing source document is the source domain's own XNotFoundError. |
| mdformatA | Format a markdown file in place, preserving any YAML frontmatter. Returns True if the file was changed, False if already formatted. |
| set_classificationA | Replace the free-text classification frontmatter field of an existing document across the whole-body domains (type is one of req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs, txt; adr is not supported), also bumping updated and leaving the body and every other frontmatter field untouched. classification is fully free-text -- no closed vocabulary; a blank or whitespace-only value clears it back to None/absent. No create_* tool accepts a classification argument at all -- this is the sole classification-change entry point. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising the domain's not-found error (a truly-absent id still raises) -- its error text is byte-identical to the domain's list_<d> failed row's error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c; ADR b8c9bfea-6dcf-4158-bfc5-4ec17abb842f, GitHub issue #170 -- case 4 of the ADR 519d1206 non-raising-structured-result workaround chain). An invalid id (path-injection attempt or wrong format for type) or an unknown type is a ValueError raised before any file access; type="adr" passes the id validation (a well-formed UUID id) and raises the plain KeyError inherited from the dispatch-table lookup instead. Returns the updated frontmatter only (no body) on success; use the corresponding get_<d> tool to fetch the full document afterward. The optional language parameter (default 'en', feat-197-i18n) selects the language variant to act on: omitted/'en' = the flat default-language document, exactly the default behavior; a non-default ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = that language's variant at docs//{language}/ (found by id-scan of that subdirectory), acting on that file ONLY -- the EN file's content and updated timestamp stay untouched. Every whole-body type except feat supports a non-default language; for feat (always English) a non-default language raises a ValueError, as does a malformed language or one with no packaged heading-mapping table -- all raised before any file access. |
| set_statusA | Replace the status of an existing document across every domain (type is one of adr, req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs, txt), also bumping updated (the whole-body domains) and leaving the body untouched. When status (or, for type="adr" with superseded_by given, the composed "superseded by X" value) already equals the document's current status, this is a no-op -- no write, no updated bump -- and still returns the same value shape a changed-status call would (issue #109). The new status must be one of the domain's own closed vocabulary values (see the domain's XFrontmatter.status field); an out-of-vocabulary status does NOT raise -- it returns a structured, non-raising InvalidStatusResult ({valid: false, type, status, allowed_values, message}) instead, so the allowed-values detail survives MCP clients that truncate error content. superseded_by is accepted only for type="adr" -- it composes the status as "superseded by {superseded_by}"; with any other type it is a ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising the domain's not-found error (a truly-absent id still raises, and the out-of-vocabulary-status InvalidStatusResult check above still runs first, pre-lock/pre-load) -- its error text is byte-identical to the domain's list_<d> failed row's error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c; ADR b8c9bfea-6dcf-4158-bfc5-4ec17abb842f, GitHub issue #170 -- case 4 of the ADR 519d1206 non-raising-structured-result workaround chain). Neither create_* nor the generic update tool accepts a status argument at all -- this is the sole status-change entry point. An invalid id (path-injection attempt or wrong format for type) is a ValueError raised before any file access. Returns the updated frontmatter only (no body, except for the unchanged adr branch) on success; use the corresponding get_<d> tool to fetch the full document afterward. The optional language parameter (default 'en', feat-197-i18n) selects the language variant to act on: omitted/'en' = the flat default-language document, exactly the default behavior; a non-default ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = that language's variant at docs//{language}/ (found by id-scan of that subdirectory), acting on that file ONLY -- the EN file's content and updated timestamp stay untouched. Every whole-body type except feat supports a non-default language; for feat and adr (always English) a non-default language raises a ValueError, as does a malformed language or one with no packaged heading-mapping table -- all raised before any file access. |
| updateA | Whole-body or line-range replace of an existing document's content across the whole-body domains (type is one of req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs, txt), preserving its id/type/status/created/version; only updated changes. With no offset/limit, content is the full replacement body (body markdown only, no frontmatter block). With offset, content replaces the body line(s) starting at 1-based line offset of the current on-disk body: limit is the number of lines to replace (offset..offset+limit-1; limit omitted = through the last body line, limit=0 = pure insert), and offset=N+1 (one past the last body line) appends after it; the spliced result is validated as a whole document before anything is written. offset/limit address the frontmatter-stripped body, never the raw on-disk .md file: the YAML frontmatter block is variable-length, so a raw file read's line numbers are never the same as body-line coordinates -- the only safe source of coordinates is a get_<d>(id, raw=True) read, never a raw file read minus an assumed constant. A get_<d>(raw=True, numbered=True) read's numbered output must never be fed back verbatim into content -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str). status is never settable -- use the generic set_status tool. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising the domain's not-found error -- its error text is byte-identical to the domain's list_<d> failed row's error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c) -- and a truly-absent id still raises the domain's not-found error. A content-validation failure on the submitted new content (or, in range mode, on the spliced result) returns a non-raising ValidateResult (valid=False, errors=[{message}]) with the message capped at 300 chars as the generic validate tool caps it, instead of raising AssertionError/pydantic.ValidationError (ADR b8c9bfea-6dcf-4158-bfc5-4ec17abb842f, GitHub issue #170 -- case 4 of the ADR 519d1206 non-raising-structured-result workaround chain). An invalid id (path-injection attempt or wrong format for type) or misused range coordinates (limit without offset) is a ValueError raised before any file access. Each domain's structure reference is its own get_<d>_schema tool (the generated JSON Schema), with get_<d>_template/get_<d>_example as the authoring starting points. Returns an UpdateResult: frontmatter, the updated frontmatter (no body) of the dispatched domain, plus snippet -- in range mode, the before/after window of the touched range (dropped lines numbered pre-splice, inserted lines numbered post-splice, up to 2 unchanged context lines per side, each line <marker> <n>: <line text>); snippet is None in whole-body mode and for the whole-body-equivalent range (offset=1 with limit omitted). Use the corresponding get_<d> tool to fetch the full document afterward. The optional language parameter (default 'en', feat-197-i18n) selects the language variant to act on: omitted/'en' = the flat default-language document, exactly the default behavior; a non-default ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = that language's variant at docs//{language}/ (found by id-scan of that subdirectory), acting on that file ONLY -- the EN file's content and updated timestamp stay untouched -- with the submitted content validated through that language's heading-mapping table (translated headings are accepted). Every whole-body type except feat supports a non-default language; for feat (always English) a non-default language raises a ValueError, as does a malformed language or one with no packaged heading-mapping table -- all raised before any file access. |
| check_translation_driftA | Read-only. Compare a translated language variant with its source document (the 'en' source by default) and report both drift kinds in one structured, non-raising TranslationDriftResult. type is one of req, uc, tsk, qa, prb, gol, rsk, dec, sop, vcr, sysrs, txt (feat and adr documents are always English and are rejected with a ValueError); id the artifact's id (shared by both languages); language the translated variant (never 'en'); source_language (default 'en') the language compared against. STRUCTURAL drift: every section heading of both documents is mapped back to canonical English through the language's heading table (the free text of Option N:/Step N:/Extension N./AC-NNN (Method): headings is ignored, only the schema-constant token is compared; timestamp-led update entries are not compared) and structural lists each missing (a source section the variant lacks), extra (a variant section the source lacks) and reordered section with its canonical heading, path, level and positions; a document that fails to parse is an unparseable finding carrying the parse error (byte-identical to list_'s failure text), never raised. STALENESS: stale is true iff the source's frontmatter updated is strictly newer than the variant's (compared as offset-aware datetimes; equal is not stale), with both timestamps, the signed source_ahead_by_seconds, and staleness_error when a timestamp is missing or unparseable. in_sync is true iff there is no structural finding, the variant is not stale and staleness could be determined. Wording, prose, frontmatter values and prb's English problem_statement are never compared. A source or variant that does not exist at all raises the domain's not-found error; invalid type/id/language (path-injection, wrong shape, a language without a heading table, language 'en', equal languages) is a ValueError raised before any file access. It writes, creates and invalidates nothing; to translate or update a variant use the translate_artifact prompt. |
| list_languagesA | Read-only. Report the language codes one artifact currently exists in. type is one of req, uc, tsk, qa, prb, gol, rsk, dec, sop, vcr, sysrs, txt (feat and adr documents are always English and are rejected with a ValueError) and id the artifact's id, shared by every language variant. Returns a LanguageListResult: languages -- 'en' first when the EN source exists (it is never invented: an id with variants but no EN source lists no 'en'), then every other language holding a variant, sorted by code -- and one entries row per language with language, path (the resolved absolute file path), parseable, and error; a variant that exists but fails to parse is listed with parseable=false and the parse error (byte-identical to the domain's list_/get_ failure text for that file), never dropped and never raised. Only .md documents under docs/{type}/ (EN) and docs/{type}/{language}/ participate; non-.md siblings and directory names that are not a two-letter lowercase language code are ignored. An id that exists in no language raises the domain's own not-found error; an unknown type or a path-injection/wrong-format id is a ValueError raised before any file access. It writes, creates and invalidates nothing. To translate use the translate_artifact prompt; to compare a variant with its source use check_translation_drift. |