function createIssueOutbox({ storage, fetchJson, coordinator, backgroundSync, getOwnerLogin = () => '', createOperationId, now = () => Date.now(), maxItems = 20 }) {
  const storageKey = 'stackchain.issue-outbox.v1';
  const operationId = createOperationId || (() =>
    globalThis.crypto?.randomUUID?.() || String(Date.now()) + '-' + Math.random().toString(16).slice(2)
  );
  const pending = new Map();

  function captureAttachment(value) {
    const contentType = String(value?.contentType || '');
    const filename = String(value?.filename || '').slice(0, 255);
    const blob = value?.blob;
    const data = String(value?.data || '');
    if (!filename || !['image/png', 'image/jpeg', 'image/webp'].includes(contentType)) return undefined;
    const note = String(value?.note || '').replace(/\s+/g, ' ').trim().slice(0, 240);
    const noteValue = note ? { note } : {};
    if (blob) return { filename, contentType, blob, ...noteValue };
    if (!data && value?.stored === true) return { filename, contentType, stored: true, ...noteValue };
    if (!data) return undefined;
    return { filename, contentType, data, ...noteValue };
  }

  function captureAttachments(values) {
    if (!Array.isArray(values)) return undefined;
    if (values.length > 5) throw new Error('You can attach up to 5 screenshots.');
    const attachments = values.map(captureAttachment);
    if (attachments.some(value => !value)) {
      throw new Error('Some screenshots are unavailable. Choose them again before queueing.');
    }
    return attachments.length ? attachments : undefined;
  }

  function captureBlockers(values) {
    if (!Array.isArray(values)) return undefined;
    const seen = new Set();
    const blockers = [];
    for (const value of values) {
      const repository = String(value?.repository || '').trim();
      const number = Number(value?.number);
      const key = repository + '#' + number;
      if (!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(repository) ||
          !Number.isInteger(number) || number < 1 || seen.has(key)) continue;
      seen.add(key);
      blockers.push({
        repository, number,
        title: String(value?.title || '').replace(/\s+/g, ' ').trim().slice(0, 255),
      });
      if (blockers.length === 5) break;
    }
    return blockers.length ? blockers : undefined;
  }

  function captureEstimate(value) {
    const estimate = Number(value);
    return Number.isInteger(estimate) && estimate >= 5 && estimate <= 1440 ? estimate : undefined;
  }

  function captureRelatedDraft(value) {
    const repository = String(value?.repository || '');
    if (!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(repository)) return undefined;
    const plan = {
      repository, title:'', body:String(value?.body || '').slice(0, 9000),
      labelIds:Array.from(new Set((Array.isArray(value?.labelIds) ? value.labelIds : [])
        .filter(id => Number.isInteger(id) && id > 0))).slice(0, 20),
    };
    const milestoneId = Number(value?.milestoneId);
    if (Number.isInteger(milestoneId) && milestoneId > 0) plan.milestoneId = milestoneId;
    if (/^\d{4}-\d{2}-\d{2}$/.test(String(value?.dueDate || ''))) plan.dueDate = String(value.dueDate);
    if (value?.unassigned === true) plan.unassigned = true;
    else if (/^[A-Za-z0-9_.-]+$/.test(String(value?.assignee || ''))) {
      plan.assignee = String(value.assignee);
      plan.assigneeName = String(value.assigneeName || value.assignee).replace(/\s+/g, ' ').trim().slice(0, 255);
    }
    const templateId = String(value?.templateId || '').slice(0, 80);
    if (templateId) {
      plan.templateId = templateId;
      plan.templateName = String(value?.templateName || 'Issue template').trim().slice(0, 80);
      plan.capturedBody = '';
    }
    const promotion = value?.checklistPromotion;
    if (promotion?.repository && promotion?.number && promotion?.url && promotion?.updatedAt) {
      plan.checklistPromotion = {
        repository:String(promotion.repository), number:Number(promotion.number), url:String(promotion.url),
        title:String(promotion.title || ''), body:String(promotion.body || '').slice(0, 10000),
        updatedAt:String(promotion.updatedAt), taskIndex:Number(promotion.taskIndex),
      };
    }
    return plan;
  }

  function read() {
    try {
      const record = JSON.parse(storage?.getItem(storageKey) || 'null');
      if (![1, 2, 3].includes(record?.version) || !Array.isArray(record.items)) return [];
      return record.items.filter(item => item && typeof item === 'object');
    } catch (_error) { return []; }
  }

  function write(items, mirror = true) {
    storage?.setItem(storageKey, JSON.stringify({ version: 3, items }));
    coordinator?.notify('issue');
    if (mirror && backgroundSync?.reconcile) {
      Promise.resolve(backgroundSync.reconcile(items))
        .then(() => items.length ? backgroundSync.requestSync?.() : undefined)
        .catch(() => { /* Foreground reconnect remains the compatibility fallback. */ });
    }
  }

  function prepareItem(draft) {
    const ownerLogin = String(getOwnerLogin() || '').trim();
    if (!ownerLogin) throw new Error('Confirm your Gitea account before queueing an issue.');
    const items = read();
    if (items.length >= maxItems) throw new Error('Issue outbox is full. Send or discard a queued issue first.');
    const item = {
      id: String(operationId()).slice(0, 128),
      operationId: '',
      repository: String(draft?.repository || ''),
      title: String(draft?.title || ''),
      body: String(draft?.body || ''),
      labelIds: Array.isArray(draft?.labelIds) ? draft.labelIds.filter(Number.isInteger).slice(0, 20) : [],
      ownerLogin,
      status: 'queued',
      queuedAt: Number(now()),
    };
    const assignee = /^[A-Za-z0-9_.-]+$/.test(String(draft?.assignee || ''))
      ? String(draft.assignee) : '';
    if (assignee) {
      item.assignee = assignee;
      item.assigneeName = String(draft?.assigneeName || assignee).replace(/\s+/g, ' ').trim().slice(0, 255);
    }
    if (draft?.unassigned === true) item.unassigned = true;
    const sourceCaptureId = String(draft?.sourceCaptureId || '').trim().slice(0, 128);
    if (sourceCaptureId) item.sourceCaptureId = sourceCaptureId;
    if (draft?.completionIntent === 'create-and-start' && !assignee && !item.unassigned) {
      item.completionIntent = 'create-and-start';
      item.estimateMinutes = captureEstimate(draft?.estimateMinutes);
    }
    const attachment = captureAttachment(draft?.attachment);
    if (attachment) item.attachment = attachment;
    const attachments = captureAttachments(draft?.attachments);
    if (attachments) item.attachments = attachments;
    const blockers = captureBlockers(draft?.blockers);
    if (blockers) item.blockers = blockers;
    const relatedDraft = captureRelatedDraft(draft?.relatedDraft);
    if (relatedDraft) item.relatedDraft = relatedDraft;

    item.operationId = item.id;
    if (Number.isInteger(Number(draft?.milestoneId)) && Number(draft.milestoneId) > 0) {
      item.milestoneId = Number(draft.milestoneId);
    }
    if (/^\d{4}-\d{2}-\d{2}$/.test(String(draft?.dueDate || ''))) item.dueDate = String(draft.dueDate);
    return item;
  }

  function localIndexItem(item) {
    const hasAttachmentBytes = item?.attachment?.data || item?.attachment?.blob;
    const hasBundleBytes = Array.isArray(item?.attachments) &&
      item.attachments.some(value => value?.data || value?.blob);
    if (!hasAttachmentBytes && !hasBundleBytes) return item;
    return {
      ...item,
      ...(hasAttachmentBytes ? {attachment: {
        filename: item.attachment.filename,
        contentType: item.attachment.contentType,
        stored: true,
      }} : {}),
      ...(Array.isArray(item.attachments) ? {attachments:item.attachments.map(value => ({
        filename:value.filename, contentType:value.contentType, stored:true,
        ...(value.note ? {note:value.note} : {}),
      }))} : {}),
    };
  }

  function enqueue(draft, mirror = true) {
    const items = read();
    const sourceCaptureId = String(draft?.sourceCaptureId || '').trim().slice(0, 128);
    const existing = sourceCaptureId && items.find(item => item.sourceCaptureId === sourceCaptureId);
    if (existing) return { ...existing };
    const item = prepareItem(draft);
    items.push(item);
    write(items, mirror);
    return item;
  }

  async function enqueueDurably(draft) {
    const sourceCaptureId = String(draft?.sourceCaptureId || '').trim().slice(0, 128);
    const existing = sourceCaptureId && read().find(item => item.sourceCaptureId === sourceCaptureId);
    if (existing) {
      if (!backgroundSync?.reconcile || !backgroundSync?.requestSync) {
        return { item: { ...existing }, background: false, durability: 'foreground-only', reused: true };
      }
      await backgroundSync.reconcile(read());
      await backgroundSync.requestSync();
      return { item: { ...existing }, background: true, durability: 'background', reused: true };
    }
    if (!backgroundSync?.reconcile || !backgroundSync?.requestSync) {
      const item = enqueue(draft, false);
      return { item, background: false, durability: 'foreground-only' };
    }
    const item = prepareItem(draft);
    const current = read();
    try {
      await backgroundSync.reconcile([...current, item]);
      const localItem = localIndexItem(item);
      write([...current, item].map(localIndexItem), false);
      await backgroundSync.requestSync();
      return { item: localItem, background: true, durability: 'background' };
    } catch (error) {
      const persisted = read().find(candidate => candidate.id === item.id);
      if (!persisted) throw error;
      return { item: persisted, background: false, durability: 'foreground-only', error };
    }
  }

  async function hydrateForEdit(id) {
    const item = read().find(candidate => candidate.id === id);
    if (!item) return null;
    const storedBundle = Array.isArray(item.attachments) && item.attachments.some(value => value?.stored);
    const storedAttachment = item.attachment?.stored && !item.attachment.data && !item.attachment.blob;
    if (!storedAttachment && !storedBundle) return { ...item };
    if (!backgroundSync?.get) {
      throw new Error('The saved screenshot is unavailable. Retry before editing this issue.');
    }
    const durable = await backgroundSync.get(id);
    const attachment = captureAttachment(durable?.attachment);
    const attachments = captureAttachments(durable?.attachments);
    if (durable?.operationId !== item.operationId ||
        (storedAttachment && (!attachment?.data && !attachment?.blob)) ||
        (storedBundle && (!attachments || attachments.length !== item.attachments.length))) {
      throw new Error('The saved screenshot is unavailable. Retry before editing this issue.');
    }
    return {
      ...item,
      ...(attachment ? {attachment} : {}),
      ...(attachments ? {attachments} : {}),
    };
  }

  function prepareUpdate(id, draft) {
    let updated = null;
    const items = read().map(item => {
      if (item.id !== id) return item;
      const repository = String(draft?.repository || '');
      const title = String(draft?.title || '');
      const body = String(draft?.body || '');
      const labelIds = Array.isArray(draft?.labelIds) ? draft.labelIds.filter(Number.isInteger).slice(0, 20) : [];
      const unassigned = draft?.unassigned === true;
      const assignee = !unassigned && /^[A-Za-z0-9_.-]+$/.test(String(draft?.assignee || ''))
        ? String(draft.assignee) : undefined;
      const assigneeName = assignee
        ? String(draft?.assigneeName || assignee).replace(/\s+/g, ' ').trim().slice(0, 255)
        : undefined;
      const milestoneId = Number.isInteger(Number(draft?.milestoneId)) && Number(draft.milestoneId) > 0
        ? Number(draft.milestoneId) : undefined;
      const dueDate = /^\d{4}-\d{2}-\d{2}$/.test(String(draft?.dueDate || ''))
        ? String(draft.dueDate) : undefined;
      const attachment = captureAttachment(draft?.attachment);
      const attachments = captureAttachments(draft?.attachments);
      const blockers = captureBlockers(draft?.blockers);
      const relatedDraft = captureRelatedDraft(draft?.relatedDraft);
      const attachmentChanged = JSON.stringify(item.attachment || null) !== JSON.stringify(attachment || null) ||
        JSON.stringify(item.attachments || null) !== JSON.stringify(attachments || null);
      const changed = item.repository !== repository || item.title !== title || item.body !== body
        || JSON.stringify(item.labelIds || []) !== JSON.stringify(labelIds)
        || Boolean(item.unassigned) !== unassigned
        || item.assignee !== assignee || item.assigneeName !== assigneeName
        || item.milestoneId !== milestoneId || item.dueDate !== dueDate
        || item.estimateMinutes !== captureEstimate(draft?.estimateMinutes)
        || attachmentChanged || JSON.stringify(item.blockers || null) !== JSON.stringify(blockers || null)
        || JSON.stringify(item.relatedDraft || null) !== JSON.stringify(relatedDraft || null);
      updated = {
        ...item,
        repository, title, body, labelIds,
        unassigned: unassigned || undefined,
        assignee, assigneeName, milestoneId, dueDate,
        attachment, attachments, blockers, relatedDraft,
        operationId: changed ? String(operationId()).slice(0, 128) : item.operationId,
        status: 'queued',
      };
      if (draft?.completionIntent === 'create-and-start' && !assignee && !unassigned) {
        updated.completionIntent = 'create-and-start';
        updated.estimateMinutes = captureEstimate(draft?.estimateMinutes);
      } else {
        delete updated.completionIntent;
        delete updated.estimateMinutes;
      }
      if (assignee === undefined) {
        delete updated.assignee;
        delete updated.assigneeName;
      }
      if (!unassigned) delete updated.unassigned;
      if (milestoneId === undefined) delete updated.milestoneId;
      if (dueDate === undefined) delete updated.dueDate;
      if (attachment === undefined) delete updated.attachment;
      if (attachments === undefined) delete updated.attachments;
      if (blockers === undefined) delete updated.blockers;
      if (relatedDraft === undefined) delete updated.relatedDraft;
      if (attachmentChanged) {
        delete updated.attachmentMarkdown;
        delete updated.attachmentMarkdowns;
      }
      delete updated.error;
      delete updated.deliveryState;
      return updated;
    });
    return { items, updated };
  }

  function update(id, draft, mirror = true) {
    const { items, updated } = prepareUpdate(id, draft);
    write(items, mirror);
    return updated;
  }

  async function updateDurably(id, draft) {
    if (!backgroundSync?.reconcile || !backgroundSync?.requestSync) {
      const item = update(id, draft, false);
      return { item, background: false, durability: 'foreground-only' };
    }
    const { items, updated: item } = prepareUpdate(id, draft);
    if (!item) return { item, background: false, durability: 'foreground-only' };
    try {
      await backgroundSync.reconcile(items);
      const localItems = items.map(localIndexItem);
      write(localItems, false);
      await backgroundSync.requestSync();
      return { item: localIndexItem(item), background: true, durability: 'background' };
    } catch (error) {
      const persisted = read().find(candidate => candidate.id === id);
      if (!persisted || persisted.operationId !== item.operationId) throw error;
      return { item: persisted, background: false, durability: 'foreground-only', error };
    }
  }

  function discard(id) {
    const items = read();
    if (!items.some(item => item.id === id)) return false;
    write(items.filter(item => item.id !== id));
    return true;
  }

  function persistDeliveryStage(id, stage) {
    write(read().map(item => item.id === id ? { ...item, ...stage } : item));
  }

  function stageOperationId(operationId, stage) {
    const suffix = ':' + stage;
    return String(operationId || '').slice(0, 128 - suffix.length) + suffix;
  }

  function evidenceMarkdown(attachment, markdown, index) {
    const note = String(attachment?.note || '').replace(/\s+/g, ' ').trim().slice(0, 240);
    if (!note) return markdown;
    const escaped = note.replace(/([\\`*_[\]{}()<>#+\-.!|])/g, '\\$1');
    return '**Screenshot ' + (index + 1) + ' — ' + escaped + '**\n\n' + markdown;
  }

  function attachmentMultipart(attachment) {
    let blob = attachment?.blob;
    if (!blob && attachment?.data) {
      const binary = atob(String(attachment.data));
      const bytes = Uint8Array.from(binary, character => character.charCodeAt(0));
      blob = new Blob([bytes], { type: String(attachment.contentType || '') });
    }
    if (!blob) throw new Error('The saved screenshot is unavailable. Retry before sending.');
    const form = new FormData();
    form.append('file', blob, String(attachment.filename || 'screenshot'));
    return form;
  }

  async function sendDirect(item, repository) {
    let issue = item.deliveredIssue;
    if (!issue) {
      issue = await fetchJson('api/v1/repos/' + repository + '/issues', {
        method: 'POST',
        headers: {
          Accept: 'application/json', 'Content-Type': 'application/json',
          'Idempotency-Key': item.operationId,
        },
        body: JSON.stringify({
          title: item.title, body: item.body, label_ids: item.labelIds,
          ...(item.unassigned ? { unassigned: true } : {}),
          ...(item.assignee ? { assignee: item.assignee } : {}),
          ...(item.milestoneId ? { milestone_id: item.milestoneId } : {}),
          ...(item.dueDate ? { due_date: item.dueDate + 'T23:59:59Z' } : {}),
        }),
      });
      if (item.attachment || item.attachments || item.blockers?.length) {
        persistDeliveryStage(item.id, { deliveredIssue: issue });
      }
    }
    const blockers = Array.isArray(item.blockers) ? item.blockers : [];
    let deliveredBlockers = Math.min(Number(item.deliveredBlockers) || 0, blockers.length);
    for (let index = deliveredBlockers; index < blockers.length; index += 1) {
      const blocker = blockers[index];
      await fetchJson(
        'api/v1/repos/' + repository + '/issues/' + encodeURIComponent(issue.number) + '/blockers',
        {
          method: 'PATCH',
          headers: {
            Accept: 'application/json', 'Content-Type': 'application/json',
            'Idempotency-Key': stageOperationId(item.operationId, 'blocker-' + index),
          },
          body: JSON.stringify({repository:blocker.repository, number:blocker.number, present:true}),
        },
      );
      deliveredBlockers = index + 1;
      persistDeliveryStage(item.id, { deliveredIssue:issue, deliveredBlockers });
    }
    const attachments = Array.isArray(item.attachments) ? item.attachments :
      (item.attachment ? [item.attachment] : []);
    if (!attachments.length) return issue;
    const markdowns = Array.isArray(item.attachmentMarkdowns)
      ? item.attachmentMarkdowns.slice(0, attachments.length)
      : (item.attachmentMarkdown ? [item.attachmentMarkdown] : []);
    for (let index = markdowns.length; index < attachments.length; index += 1) {
      const uploaded = await fetchJson(
        'api/v1/repos/' + repository + '/issues/' + encodeURIComponent(issue.number) + '/attachments',
        {
          method: 'POST',
          headers: {
            Accept: 'application/json',
            'Idempotency-Key': stageOperationId(
              item.operationId, attachments.length === 1 ? 'attachment' : 'attachment-' + index,
            ),
          },
          body: attachmentMultipart(attachments[index]),
        },
      );
      const markdown = String(uploaded?.markdown || '');
      if (!markdown) {
        const error = new Error('The server did not confirm the screenshot upload.');
        error.status = 422;
        throw error;
      }
      markdowns.push(markdown);
      persistDeliveryStage(item.id, {
        deliveredIssue: issue, attachmentMarkdowns:markdowns.slice(),
        ...(attachments.length === 1 ? {attachmentMarkdown:markdown} : {}),
      });
    }
    const markdown = markdowns.map((value, index) =>
      evidenceMarkdown(attachments[index], value, index)).join('\n\n');
    await fetchJson(
      'api/v1/repos/' + repository + '/issues/' + encodeURIComponent(issue.number) + '/comments',
      {
        method: 'POST',
        headers: {
          Accept: 'application/json', 'Content-Type': 'application/json',
          'Idempotency-Key': stageOperationId(item.operationId, 'attachment-comment'),
        },
        body: JSON.stringify({ body: markdown }),
      },
    );
    return issue;
  }

  async function sendItem(item, currentLogin) {
    if (!currentLogin || item.ownerLogin !== currentLogin) return { blocked: true };
    if (pending.has(item.id)) return pending.get(item.id);
    const attemptAt = Number(now());
    write(read().map(candidate => candidate.id === item.id ? {
      ...candidate, status:'sending', lastAttemptAt:attemptAt,
    } : candidate), false);
    const repository = item.repository.split('/').map(encodeURIComponent).join('/');
    const request = (async () => {
      try {
        let issue;
        if (backgroundSync?.send) {
          const delivery = await backgroundSync.send(item, currentLogin);
          if (delivery.attention) {
            const error = delivery.error || new Error('Issue needs attention');
            error.status = Number(error.status || 422);
            throw error;
          }
          issue = delivery.issue;
        } else {
          issue = await sendDirect(item, repository);
        }
        if (!issue) return { blocked: true };
        discard(item.id);
        return { issue, item };
      } catch (error) {
        const status = Number(error?.status || 0);
        const attemptError = String(error.message || 'Delivery failed').slice(0, 240);
        if (status >= 400 && status < 500) {
          write(read().map(candidate => candidate.id === item.id ? {
            ...candidate, status: 'attention', error: String(error.message || 'Issue needs attention').slice(0, 240),
            lastAttemptAt: attemptAt, lastAttemptError: attemptError,
            ...(error.code === 'delivery_uncertain' ? { deliveryState: 'uncertain' } : {}),
          } : candidate));
        } else {
          write(read().map(candidate => candidate.id === item.id ? {
            ...candidate, status:'queued', lastAttemptAt:attemptAt, lastAttemptError:attemptError,
          } : candidate));
        }
        return { error, transient: !(status >= 400 && status < 500) };
      }
    })();
    pending.set(item.id, request);
    try { return await request; }
    finally { if (pending.get(item.id) === request) pending.delete(item.id); }
  }

  async function flushQueue(currentLogin) {
    const confirmed = [];
    const completions = [];
    const filings = [];

    let blocked = 0;
    currentLogin = String(currentLogin || '').trim();
    for (const item of read()) {
      if (item.status === 'attention' || item.status === 'completion') continue;
      if (!currentLogin || item.ownerLogin !== currentLogin) { blocked += 1; continue; }
      const result = await sendItem(item, currentLogin);
      if (result.issue) {
        confirmed.push(result.issue);
        if (result.item?.relatedDraft) filings.push({issue:result.issue, relatedDraft:result.item.relatedDraft});

        if (result.item?.completionIntent) completions.push({
          id: result.item.id,
          intent: result.item.completionIntent,
          ownerLogin: result.item.ownerLogin,
          operationId: result.item.operationId,
          estimateMinutes: result.item.estimateMinutes,
          issue: result.issue,
        });
      }
      if (result.transient) break;
    }
    return { confirmed, completions, filings, remaining: read(), blocked };
  }

  async function flush(currentLogin) {
    if (coordinator) return coordinator.runExclusive('issue', () => flushQueue(currentLogin));
    return flushQueue(currentLogin);
  }

  async function retryItem(id, currentLogin) {
    const item = read().find(candidate => candidate.id === id);
    if (!item) return { confirmed: [], remaining: read() };
    currentLogin = String(currentLogin || '').trim();
    if (!currentLogin || item.ownerLogin !== currentLogin) {
      return { confirmed: [], remaining: read(), blocked: 1 };
    }
    let queued = item;
    if (item.status === 'attention') {
      queued = {
        ...item,
        operationId: String(operationId()).slice(0, 128),
        status: 'queued',
      };
      delete queued.error;
      delete queued.deliveryState;
      write(read().map(candidate => candidate.id === id ? queued : candidate));
    }
    const result = await sendItem(queued, currentLogin);
    return {
      confirmed: result.issue ? [result.issue] : [],
      filings: result.issue && result.item?.relatedDraft ? [{issue:result.issue, relatedDraft:result.item.relatedDraft}] : [],

      completions: result.issue && result.item?.completionIntent ? [{
        id: result.item.id,
        intent: result.item.completionIntent,
        ownerLogin: result.item.ownerLogin,
        operationId: result.item.operationId,
        estimateMinutes: result.item.estimateMinutes,
        issue: result.issue,
      }] : [],
      remaining: read(), blocked: 0,
    };
  }

  async function retry(id, currentLogin) {
    if (coordinator) return coordinator.runExclusive('issue', () => retryItem(id, currentLogin));
    return retryItem(id, currentLogin);
  }

  function reconcileBackground(records) {
    const statuses = new Map((records || []).map(item => [item.id, item]));
    const items = read().flatMap(item => {
      const background = statuses.get(item.id);
      const deliveryStage = {
        ...(background?.deliveredIssue ? { deliveredIssue: background.deliveredIssue } : {}),
        ...(background?.attachmentMarkdown ? { attachmentMarkdown: background.attachmentMarkdown } : {}),
      };
      if (background?.status === 'sent') {
        if (item.completionIntent === 'create-and-start' && background.deliveredIssue) return [{
          ...item, status: 'completion', deliveredIssue: background.deliveredIssue,
        }];
        return [];
      }
      if (background?.status === 'attention') return [{
        ...localIndexItem(item), ...deliveryStage, status: 'attention', error: String(background.error || 'Issue needs attention').slice(0, 240),
        ...(background.deliveryState ? { deliveryState: background.deliveryState } : {}),
      }];
      return [{ ...localIndexItem(item), ...deliveryStage }];
    });
    write(items);
    return items;
  }

  function pendingCompletions(currentLogin) {
    const login = String(currentLogin || '').trim();
    if (!login) return [];
    return read().filter(item => item.status === 'completion' && item.ownerLogin === login &&
      item.completionIntent === 'create-and-start' && item.deliveredIssue).map(item => ({
        id: item.id,
        intent: item.completionIntent,
        ownerLogin: item.ownerLogin,
        operationId: item.operationId,
        estimateMinutes: item.estimateMinutes,
        issue: item.deliveredIssue,
      }));
  }

  function completeIntent(id, currentLogin) {
    const login = String(currentLogin || '').trim();
    const items = read();
    const matched = items.some(item => item.id === id && item.status === 'completion' && item.ownerLogin === login);
    if (!matched) return false;
    write(items.filter(item => item.id !== id));
    return true;
  }

  return {
    enqueue, enqueueDurably, hydrateForEdit, update, updateDurably, discard, flush, retry, reconcileBackground,
    pendingCompletions, completeIntent, list: () => read().map(item => ({ ...item })),
  };
}

if (typeof module !== 'undefined' && module.exports) module.exports = createIssueOutbox;
