ek9_create_requirement

Writes the requirement nodes as flat markdown files under .ek9-ai/requirements/ (one atomic batch, each keyed by its frozen slug) and answers the editor envelope: status (applied | ready | conflicts), written, edits[] and summary naming the ids created.

Category: Editor · Compare: Requirement navigator → New Requirement… (planned)

When to use it

'Record a new requirement' is one call: {nodes:[{slug, title, body}]} for a root, add parentId:'REQ:x' for a child; several nodes naming each other make a whole subtree.

When not to use it

Details

Slug is FROZEN at creation ([a-z0-9-]+) and is the key every @Test and parentId joins on; a collision against the derived id-set is REFUSED, never auto-suffixed — pick a distinctive slug and re-call. prefix is the closed set REQ/CTRL/CAP/CON, immutable once set; timestamps, version and changelog are server-stamped, never caller-supplied. Atomic: one bad node (invalid-slug, slug-collision, duplicate-in-batch, parent-not-found, parent-retired, batch-cycle) blocks the whole batch, and only the child file is ever written — parents are never edited.

Arguments

ArgumentTypeRequiredWhat it is
dryRunbooleanWhen true nothing is written; the response shows the would-be edits with status:'ready'.
nodesarray of objectyesThe requirements to create, in intended order. A member's parentId may name an existing requirement OR another member of this same batch, which is what lets a whole subtree be created in one call.
tersebooleanRetained boolean alias for verbosity:'summary'.
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 4 recorded are shown.

Create requirement conflicts

Request

{
  "nodes" : [ {
    "authorKind" : "human",
    "authorName" : "Steve Limb",
    "body" : "# Intent\n\nFine.",
    "slug" : "perfectly-fine",
    "title" : "Fine"
  }, {
    "authorKind" : "human",
    "authorName" : "Steve Limb",
    "body" : "# Intent\n\nBad.",
    "slug" : "Not A Slug",
    "title" : "Bad"
  } ]
}

Response

{
  "conflicts" : [ {
    "detail" : "a slug must match [a-z0-9-]+ and the prefix must be from the closed registry",
    "kind" : "invalid-slug",
    "subject" : "Not A Slug"
  } ],
  "edits" : [ ],
  "meta" : {
    "serverMs" : "<timing>"
  },
  "risk" : {
    "crossesModuleBoundary" : false,
    "estimatedSeverity" : "trivial",
    "fileCount" : 0,
    "lineCount" : 0,
    "touchesPublicApi" : false,
    "touchesTests" : false
  },
  "status" : "conflicts",
  "summary" : "Would create nothing — 1 conflict(s); a create is atomic",
  "wouldBeDiagnostics" : [ ],
  "written" : false
}

Create requirement dry run

Request

{
  "dryRun" : true,
  "nodes" : [ {
    "authorKind" : "human",
    "authorName" : "Steve Limb",
    "body" : "# Intent\n\nWhy.",
    "slug" : "fraud-screening",
    "title" : "Screen payments"
  } ]
}

Response

{
  "conflicts" : [ ],
  "edits" : [ {
    "after" : "---\nreq_id: REQ:fraud-screening\ntitle: Screen payments\nretired: false\nversion: 0.1.0\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---\n\n# Intent\n\nWhy.\n",
    "file" : ".ek9-ai/requirements/REQ-fraud-screening.md",
    "type" : "create"
  } ],
  "meta" : {
    "serverMs" : "<timing>"
  },
  "risk" : {
    "crossesModuleBoundary" : false,
    "estimatedSeverity" : "trivial",
    "fileCount" : 1,
    "lineCount" : 0,
    "touchesPublicApi" : false,
    "touchesTests" : false
  },
  "status" : "ready",
  "summary" : "Would create 1 requirement (REQ:fraud-screening)",
  "wouldBeDiagnostics" : [ ],
  "written" : false
}

Create requirement root apply

Request

{
  "nodes" : [ {
    "authorKind" : "human",
    "authorName" : "Steve Limb",
    "body" : "# Intent\n\nEvery payment is screened.",
    "slug" : "fraud-screening",
    "title" : "Screen inbound payments for fraud"
  } ]
}

Response

{
  "conflicts" : [ ],
  "edits" : [ {
    "after" : "---\nreq_id: REQ:fraud-screening\ntitle: Screen inbound payments for fraud\nretired: false\nversion: 0.1.0\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---\n\n# Intent\n\nEvery payment is screened.\n",
    "file" : ".ek9-ai/requirements/REQ-fraud-screening.md",
    "type" : "create"
  } ],
  "meta" : {
    "serverMs" : "<timing>"
  },
  "risk" : {
    "crossesModuleBoundary" : false,
    "estimatedSeverity" : "trivial",
    "fileCount" : 1,
    "lineCount" : 0,
    "touchesPublicApi" : false,
    "touchesTests" : false
  },
  "status" : "applied",
  "summary" : "Created 1 requirement (REQ:fraud-screening)",
  "wouldBeDiagnostics" : [ ],
  "written" : true
}