Delivery Factory · Part 2 · Integration

The Jira part has no opinion.

The first stage of every run needs the ticket. The plugin that fetches it is built so small that every claim about it can be checked in the code: where the token goes, who says pass or fail, and who decides what the ticket means. Repo: agentic-jira

Checked in Code

Everything on this page was read in the plugin's scripts, skills and manifest, not only in its README. Paths are relative to plugins/jira/ unless said otherwise.

Who decides what1200 × 627
DELIVERY FACTORY · PART 2 The Jira part reports. The stage decides what it means. STAGE · JUDGES SKILL · NO BRANCH SCRIPT · PASS OR FAIL JIRA intake turns the ticket into facts the later stages can use fetch-item runs the script and passes its output on, unchanged fetch-item.sh checks, calls, writes a file, prints pass or fail Jira Cloud REST API ## Result · 5 lines JIRA_API_TOKEN from the environment handed over on stdin command line never used for the token .ai/tracker/fetch-item-ABC-123.json the raw ticket, written by the script, read by intake Only the stage on the left is allowed to say what the ticket asks for.
Three layers, three jobs. The script is the only code that talks to Jira. The skill around it passes its answer on without reading it. The intake stage is the first place where the ticket's content is interpreted.

The parts

Four pieces, one job each

The Jira plugin plays one role in the pipeline: the tracker. These are all the parts it has.

Six operations, the same shape each time: fetch an item, post a note, attach a file, list types, update an item, create an item.

The token

Working says nothing about what it exposes

A call that puts the token on the command line works. It also leaves the token where other programs can read it.

Token on the command line

Every call goes through

  • The token is part of the process arguments.
  • Anything that lists running programs can read it, and so can shell history and logs.
  • Nothing in the result tells you.
Token handed over privately

The same call, nothing to see

  • The script reads the token from the environment.
  • It gives curl a config block on standard input, -K -.
  • The command line only shows flags and an output file.
# skills/fetch-item/scripts/fetch-item.sh:51
curl -sS -K - -o "$OUT_FILE" -w '%{http_code}' <<EOF
url = "https://${JIRA_SITE}/rest/api/3/issue/${ITEM_ID}"
user = "${JIRA_EMAIL}:${JIRA_API_TOKEN}"
header = "Accept: application/json"
EOF

All six scripts in the plugin call curl this way. The ticket key is checked against ^[A-Za-z][A-Za-z0-9_]*-[0-9]+$ before it goes into that block. The comment above the check gives the reason: a key with a line break in it could add its own url = or user = line.

If any of the three variables is missing, there is no crash. The script prints a fail that names them.

The script

What fetch-item does, in order

One file, about eighty lines, read top to bottom.

  1. No ticket key given: usage error, exit 2. This is the only exit that is not 0.
  2. JIRA_SITE, JIRA_EMAIL or JIRA_API_TOKEN missing: fail, naming them.
  3. Ticket key not shaped like ABC-123, or the site not a bare hostname: fail.
  4. Call Jira with the token on standard input.
  5. curl error, or any HTTP status other than 200: fail, naming the status.
  6. Otherwise: write the ticket to .ai/tracker/fetch-item-<key>.json and print a pass with its type and status.
## Result
verdict: pass
summary: Fetched item ABC-123 (type=Story status=To Do) and wrote its fields to disk.
artifacts:
  - .ai/tracker/fetch-item-ABC-123.json
next_action: none

The shape of a pass, filled with an example key. The type and status are read from the response. The script does not look at the description, the acceptance criteria, or anything else in the ticket.

Intake reads that file next. A separate script on its side decides which design keywords and headings matched. That is the first point where the ticket's content counts for anything.

What it doesn't solve

A ticket that arrives fine

A clean fetch proves the ticket exists and the call was safe. It says nothing about whether anyone can build from it.