docs(18): add research findings + EML-parsing scope decision
This commit is contained in:
parent
4ccd379dc3
commit
e05d34640c
2 changed files with 32 additions and 2 deletions
|
|
@ -84,6 +84,36 @@ phishing endpoint (Phases 19-21) must also follow.
|
|||
browsing — it wires the fine-grained check through now rather than
|
||||
retrofitting it later.
|
||||
|
||||
### Automatic-Path EML Parsing Scope
|
||||
- **D-07 (added post-research):** Research found that `parseAndStoreMessage()`
|
||||
(Phase 16's `.eml` parser — the only writer of `messages`/`indicators` rows,
|
||||
i.e. the only source of Message-ID and attachment-hash/URL data) has zero
|
||||
callers anywhere in the codebase; Phase 16's own plan doc explicitly
|
||||
earmarked this phase's `/analyze` endpoint as its first real caller.
|
||||
Decision: do **NOT** wire `parseAndStoreMessage()` into the automatic
|
||||
webhook/cron path in this phase. The automatic path (webhook `ticket.created`
|
||||
+ cron sweep) calls `groupReportIntoCampaign()` using only whatever
|
||||
`reports`/`contacts` data already exists — which means Tier 1 (Message-ID)
|
||||
and Tier 2 (attachment-hash/URL-domain) can only ever match for a ticket
|
||||
that has already been through an explicit `POST /analyze` call at least
|
||||
once; the automatic path effectively only reaches **Tier 3**
|
||||
(sender+normalized-subject+client+time-window) until then. This must be
|
||||
documented explicitly in code comments (not silently built around) since it
|
||||
changes what "grouped automatically" means in practice versus D-01's
|
||||
original framing. Rationale: matches Phase 16's explicit design intent and
|
||||
keeps the automatic webhook/cron path cheap — no extra Autotask
|
||||
attachment-content fetch + optional B2 upload firing on every single
|
||||
`ticket.created` event, most of which aren't reviewed by anyone.
|
||||
- **D-08 (added post-research):** `groupReportIntoCampaign()` short-circuits
|
||||
immediately (does nothing) if `reports.campaign_id IS NOT NULL` when called
|
||||
from the automatic webhook/cron path — avoids redundant tier-query work on
|
||||
every 7-day cron sweep pass for reports already grouped. The `/analyze`
|
||||
route calls the function WITHOUT this short-circuit (always re-runs full
|
||||
tiered matching) — an explicit operator request may follow a fresh
|
||||
`/analyze` call that just populated `messages`/`indicators` for the first
|
||||
time, and deserves the chance to upgrade an existing Tier-3-only grouping
|
||||
to a Tier-1 match if a shared Message-ID is now available.
|
||||
|
||||
### Claude's Discretion (explicitly deferred to research + planner)
|
||||
- **Exact SQL/query shape for `GET /api/phishing/campaigns/{id}`'s nested
|
||||
response** (linked reports, messages, indicators, classification history)
|
||||
|
|
|
|||
|
|
@ -538,7 +538,7 @@ assumptions about how this codebase "probably" works.
|
|||
|
||||
## Open Questions
|
||||
|
||||
1. **Should this phase also wire `parseAndStoreMessage()` into the automatic
|
||||
1. **(RESOLVED: see CONTEXT.md D-07 — do NOT auto-wire, document Tier-3-only automatic-path limitation)** Should this phase also wire `parseAndStoreMessage()` into the automatic
|
||||
webhook/cron path, or leave it reachable only via the on-demand `/analyze` endpoint?**
|
||||
- What we know: `parseAndStoreMessage` has zero callers today outside its test file.
|
||||
Phase 16's own plan doc explicitly earmarked "the live on-demand trigger" (this
|
||||
|
|
@ -560,7 +560,7 @@ assumptions about how this codebase "probably" works.
|
|||
around it — it changes what "automatically grouped" means in practice for success
|
||||
criterion #1.
|
||||
|
||||
2. **Does `groupReportIntoCampaign` re-run for a report already linked to a campaign?**
|
||||
2. **(RESOLVED: see CONTEXT.md D-08 — short-circuit on automatic path, always re-run on /analyze)** Does `groupReportIntoCampaign` re-run for a report already linked to a campaign?**
|
||||
- What we know: `detectPhishingTicket`'s idempotency guard (content-hash unchanged)
|
||||
still refreshes the `evidence` JSONB on every call — so it's called repeatedly over
|
||||
a ticket's lifetime (every webhook re-fire, every cron sweep pass within the 7-day
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue