Edit document
editReplace an exact string in a specification document's body while leaving YAML frontmatter unchanged. The result is validated as a whole and saved only if matching and validation succeed.
Instructions
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; 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.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| type | Yes | ||
| new_str | Yes | ||
| old_str | Yes | ||
| replace_all | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |