# Phase 21: Autotask Triage Note - Discussion Log

> **Audit trail only.** Do not use as input to planning, research, or execution agents.
> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.

**Date:** 2026-07-16
**Phase:** 21-autotask-triage-note
**Areas discussed:** Ticket scoping, Trigger point, Re-trigger behavior, Note content, Write-failure fallback, Partial-failure response shape

---

## Ticket Scoping

| Option | Description | Selected |
|--------|-------------|----------|
| All linked tickets | Post the same note to every report's ticket_id in the campaign | ✓ |
| Most recent report's ticket | Post only to the most-recently-reported duplicate's ticket | |
| Original (first) report's ticket | Post only to the earliest report's ticket | |
| Operator specifies the ticket | Endpoint takes a ticket_id param, operator controls target | |

**User's choice:** All linked tickets
**Notes:** A campaign groups multiple duplicate-report tickets (`campaigns`→`reports` is 1-to-many). Every duplicate-report ticket gets the same note so whoever looks at any of them sees the full picture, at the cost of N Autotask writes per trigger.

---

## Trigger Point

| Option | Description | Selected |
|--------|-------------|----------|
| New on-demand endpoint | Operator explicitly triggers, matches classify/approve/remediate pattern | ✓ |
| Auto-fire after classify | Fires automatically as a side effect of a successful /classify call | |

**User's choice:** New on-demand endpoint
**Notes:** Matches Phase 19 D-02's precedent of keeping classification (and by extension every state-changing/reporting action this milestone) operator-initiated, not an automatic cascade.

---

## Re-trigger Behavior (follow-up on Ticket Scoping)

| Option | Description | Selected |
|--------|-------------|----------|
| Always post fresh | Every call posts a new note reflecting current state to every linked ticket | ✓ |
| Skip tickets that already have a note from this exact classification | Track (campaign, classification_id, ticket_id) combos and skip duplicates | |

**User's choice:** Always post fresh
**Notes:** Duplicate Autotask notes across repeated calls are acceptable — same posture as Phase 19 D-02 allowing repeated `/classify` calls.

---

## Note Content

| Option | Description | Selected |
|--------|-------------|----------|
| Full picture: verdict + evidence + blast radius + current remediation state | Note reflects present truth, not just the classifier's frozen recommendation | ✓ |
| Classification + blast radius only, no remediation section | Simpler, but conflicts with the phase's own success criteria wording | |

**User's choice:** Full picture
**Notes:** Directly satisfies the phase's success criteria ("recommended actions") while staying accurate after approval/remediation has actually happened.

---

## Write-Failure Fallback

| Option | Description | Selected |
|--------|-------------|----------|
| Fall back to returning note text via API response | Matches "never a silent no-op" — operator gets text to paste manually | ✓ |
| Return an explicit error, no fallback | Simpler, but operator gets nothing usable back for that request | |

**User's choice:** Fall back to returning note text via API response
**Notes:** This is the actual scope of NOTE-01's "otherwise return via API" branch — a per-ticket runtime write failure, not a general capability gate (the safe write path already exists, confirmed by direct code inspection of `workflow-engine.ts`).

---

## Partial Failure (follow-up on multi-ticket writes)

| Option | Description | Selected |
|--------|-------------|----------|
| Per-ticket status + note text always included | Response lists each ticket's outcome and always includes the note text | ✓ |
| All-or-nothing: any failure fails the whole request | Simpler semantics, but can't actually un-post already-successful writes | |

**User's choice:** Per-ticket status + note text always included
**Notes:** A conceptual "rollback" isn't real here — a note already posted to one ticket stays posted even if a sibling ticket's write fails in the same call.

---

## Claude's Discretion

- Exact sanitization rules beyond "no raw secrets/tokens/full malicious URL query strings"
- Exact `noteType`/`publish` values passed to `createEntity('TicketNotes', ...)`
- Exact note text format/template (prose structure)
- Whether the endpoint requires `phishing:approve` or `phishing:analyze` permission tier
- Response envelope naming details (camelCase convention applies)

## Deferred Ideas

- Persisting sent-note history (a table tracking which notes were posted, when) — not requested, Autotask itself is the record of truth
- Dedup/skip-if-unchanged logic — explicitly rejected in favor of "always post fresh"
