# Jira Attachment Inputs

## Current Design

- Jira issue fetches already include raw `attachment` metadata.
- `src/image-inputs.ts` is the only materialization path. It keeps only image
  MIME types/extensions, selects at most four candidates, writes
  `input/image-manifest.json`, and stores files under `input/images/`.
- `src/runner.ts` reads only that image manifest and passes available files as
  `local_image` inputs. TXT/HTML attachments are neither downloaded nor named
  in the workspace, so the model cannot deterministically discover them.
- The analysis prompt refers only to `input/image-manifest.json`.

## Risks

- Customers can provide complete execution plans in TXT/HTML while the draft
  incorrectly asks for the same evidence again.
- Increasing the image cap alone does not create a text-attachment input path.
- Raw HTML may contain scripts, active markup, or instruction-like text and
  must not be treated as executable/trusted instructions.
- Support-authored or future replay attachments must not bypass the existing
  reply-safe comment boundary.
- Separate image and attachment manifests would create competing sources of
  truth and make the total limit ambiguous.

## Target Contract

- `input/attachment-manifest.json` is the single canonical attachment source;
  it records the selected items, total candidate count, and omitted count.
- At most 10 available/skipped attachment candidates are selected in one hard
  total budget; images count toward the same limit and configuration cannot
  raise the cap above 10.
- Supported inputs are PNG/JPEG/GIF/WebP plus TXT and HTML/HTM. Other image,
  text, archive, document, and binary types fail closed.
- Only attachments referenced from the description or reply-safe visible
  comments are candidates. Customer-uploaded Jira attachments are eligible
  when structured author identity is `customer` or stably matches the
  reporter. Unknown/support/app uploaders fail closed. Dry-run also excludes
  attachments created after the replay target.
- Images are stored under `input/attachments/` and passed as `local_image`.
  Text is UTF-8 normalized; HTML is converted to inert plain text before being
  stored under the same directory. The model reads text files from the
  workspace according to the manifest and prompt.
- Visible description/comment image references remain supported. Duplicate
  Jira attachments and references consume only one slot.
- Each file and the whole run have byte caps. Jira Basic auth is sent only to
  the Jira origin; bounded redirects may reach Atlassian media without auth.
  Oversized, unsupported, missing, or failed downloads remain explicit
  manifest entries and are never silently treated as available evidence or
  expose signed download URLs.

## Non-Goals

- Do not support arbitrary binary archives, Office files, PDFs, or executable
  HTML/browser rendering in this change.
- Do not let attachment contents override system instructions or source
  boundaries.
- Do not change comment visibility, coverage gates, Jira writes, model, or
  reasoning effort.
- Do not enable or modify production automation.

## Implementation Steps

1. Replace the image-only module/type/manifest with one attachment contract.
2. Select reply-safe Jira attachments and visible image references under one
   deterministic 10-file budget.
3. Download images and readable text, normalize HTML to plain text, and write a
   canonical manifest plus local files.
4. Update dry/live prompts and runner input construction to consume the new
   manifest; pass only images as `local_image` while requiring local text files
   to be read before asking for missing evidence.
5. Add contract tests for TXT, HTML, images, the shared cap, deduplication,
   unsupported/oversized inputs, unsafe uploader identity, replay cutoff,
   filename safety, and runner inputs.
6. Run typecheck/full tests and independent review, then merge and deploy to
   staging.
7. Regenerate a read-only NAID-12133 workspace and verify both execution plans
   and all six images are present within the 10-file budget.

## Verification Checklist

- [x] TXT and HTML execution plans materialize as readable local text.
- [x] HTML active content is removed and markup is converted to inert text.
- [x] Images still reach Codex as `local_image` inputs.
- [x] Text files are discoverable through the prompt and canonical manifest.
- [x] The combined attachment/image candidate budget is 10.
- [x] Duplicates consume one slot.
- [x] Unknown/support/app uploaders and future replay attachments are excluded.
- [x] Unsupported, oversized, and failed inputs have explicit manifest status.
- [x] Typecheck and full tests pass after rebasing onto current `main` (175/175).
- [ ] Staging runs the merged image with existing model/reasoning settings.
- [ ] NAID-12133 workspace contains two execution plans and six images.
