ek9_update_requirement

Rewrites one existing requirement node's markdown file (body, title, meta, position, retirement) or deletes it, and answers the editor envelope: status (applied | ready | conflicts), written, edits[] and summary naming the mode applied.

Category: Editor · Compare: Requirement navigator → right-click Edit / Retire / Reparent (planned)

When to use it

'Change requirement X' is one call: {mode:'edit-body-text', requirementId:'REQ:x', text, authorKind, authorName}; modes cover title, meta, reparent, retire and delete.

When not to use it

Details

Modes: edit-body-text (authored why; a vertical-drift trigger — clears intent confirmation on confirmed descendants, advisory only, nothing becomes undeveloped), edit-title, edit-meta (empty value removes the key; unnamed attrs left alone), retire / un-retire (retire in place, optional supersededBy successor that must already exist), reparent (own parentId + optional rankKey; refused with kind would-create-cycle if it would make the node its own ancestor), confirm-intent (re-stamp confirmed_at), delete (the only gated mode — kind still-referenced while children/anchors remain). Other conflict kinds: target-not-found, target-retired (un-retire first), missing-value, parent-not-found, parent-retired. rename-slug is refused (a partial rename leaves dangling @Test anchors) - create the replacement and retire this node with supersededBy instead; each edit is a whole-file rewrite (no line range).

Arguments

ArgumentTypeRequiredWhat it is
authorKindstring: human | personayesWho is making the change - recorded in the changelog, the same attribution ek9_create_requirement records. Required here: an edit is never attributed by inheritance (only a created child inherits its parent's author).
authorNamestringyesThe changing identity's name; paired with authorKind.
dryRunbooleanWhen true nothing is written; the response shows the would-be edits with status:'ready'.
metaobjectFor edit-meta: attributes to set. An empty value removes the key. Attributes not named are left alone.
modestring: edit-body-text | edit-title | edit-meta | retire | un-retire | reparent | confirm-intent | deleteyesWhat to change.
parentIdstringFor reparent: the new parent's requirement id. Omit to promote the requirement to a root.
rankKeystringFor reparent: position among the new siblings.
requirementIdstringyesThe requirement to change, e.g. REQ:fraud-screening.
supersededBystringFor retire: the successor requirement that replaces this one. It must already exist.
tersebooleanRetained boolean alias for verbosity:'summary'.
textstringThe new body (edit-body-text) or the new title (edit-title).
verbositystring: full | summary | noneResponse size: full (default) carries each edit's full content; summary drops the edit bodies; none collapses edits[] to a count.

Recorded calls

Real calls, recorded against small projects and checked on every build - a changed answer fails it. 3 of the 5 recorded are shown.

Update requirement delete refused

Request

{
  "authorKind" : "human",
  "authorName" : "Steve Limb",
  "mode" : "delete",
  "requirementId" : "REQ:payments"
}

Response

{
  "conflicts" : [ {
    "detail" : "1 thing(s) still reference this - reparent or remove them first: REQ:fraud",
    "kind" : "still-referenced",
    "subject" : "REQ:payments"
  } ],
  "edits" : [ ],
  "meta" : {
    "serverMs" : "<timing>"
  },
  "risk" : {
    "crossesModuleBoundary" : false,
    "estimatedSeverity" : "trivial",
    "fileCount" : 0,
    "lineCount" : 0,
    "touchesPublicApi" : false,
    "touchesTests" : false
  },
  "status" : "conflicts",
  "summary" : "Would change nothing — 1 conflict(s)",
  "wouldBeDiagnostics" : [ ],
  "written" : false
}

Update requirement cycle refused

Request

{
  "authorKind" : "human",
  "authorName" : "Steve Limb",
  "mode" : "reparent",
  "parentId" : "REQ:fraud",
  "requirementId" : "REQ:payments"
}

Response

{
  "conflicts" : [ {
    "detail" : "REQ:fraud sits beneath REQ:payments, so this would make it its own ancestor",
    "kind" : "would-create-cycle",
    "subject" : "REQ:payments"
  } ],
  "edits" : [ ],
  "meta" : {
    "serverMs" : "<timing>"
  },
  "risk" : {
    "crossesModuleBoundary" : false,
    "estimatedSeverity" : "trivial",
    "fileCount" : 0,
    "lineCount" : 0,
    "touchesPublicApi" : false,
    "touchesTests" : false
  },
  "status" : "conflicts",
  "summary" : "Would change nothing — 1 conflict(s)",
  "wouldBeDiagnostics" : [ ],
  "written" : false
}

Update requirement dry run

Request

{
  "authorKind" : "human",
  "authorName" : "Steve Limb",
  "dryRun" : true,
  "mode" : "edit-title",
  "requirementId" : "REQ:fraud",
  "text" : "Changed"
}

Response

{
  "conflicts" : [ ],
  "edits" : [ {
    "after" : "---\nreq_id: REQ:fraud\ntitle: Changed\nretired: false\nversion: 0.1.1\nparent_ref: null\nrank_key: V\nsuperseded_by: null\nconfirmed_at: null\ncreated_at: <instant>\nupdated_at: <instant>\nrule_anchors: []\nown_anchors: []\nabout_concepts: []\nmeta: {}\nauthors:\n  - {kind: human, name: Steve Limb}\nchangelog:\n  - {at: <instant>, by: human::Steve Limb, action: create}\n  - {at: <instant>, by: human::Steve Limb, action: edit-title}\n---\n\n# Intent\n\nOriginal prose.\n",
    "file" : ".ek9-ai/requirements/REQ-fraud.md",
    "type" : "replace"
  } ],
  "meta" : {
    "serverMs" : "<timing>"
  },
  "risk" : {
    "crossesModuleBoundary" : false,
    "estimatedSeverity" : "trivial",
    "fileCount" : 1,
    "lineCount" : 0,
    "touchesPublicApi" : false,
    "touchesTests" : false
  },
  "status" : "ready",
  "summary" : "Would apply edit-title to REQ:fraud",
  "wouldBeDiagnostics" : [ ],
  "written" : false
}