Commit graph

616 commits

Author SHA1 Message Date
8630fd5151 feat(16-02): add EML_OBJECT_KEY_REGEX + parameterize B2 key validation (D-05)
- New EML_OBJECT_KEY_REGEX enforces phishing/<id>/<id>.eml, rejects traversal
- presignDownload/presignUpload/downloadToBuffer take optional keyRegex,
  defaulting to OBJECT_KEY_REGEX so existing LogLift call sites are unchanged
- OBJECT_KEY_REGEX itself left untouched (skill-doc rule)
2026-07-15 10:23:19 -04:00
6de92a507b test(16-02): add failing tests for EML_OBJECT_KEY_REGEX + parameterized B2 key validation
- EML_OBJECT_KEY_REGEX must match phishing/<id>/<id>.eml and reject traversal/wrong-ext/LogLift shapes
- presignUpload must accept an optional keyRegex arg, defaulting to OBJECT_KEY_REGEX
2026-07-15 10:22:46 -04:00
9b65de72dc feat(16-02): add AutotaskClient.getAttachmentContent()
- Fetches Tickets/{id}/Attachments/{attachmentId}, reads response.items?.[0]
- Confirmed live: per-attachment-ID GET is list-shaped, not {item:...}
2026-07-15 10:22:03 -04:00
8be10db6e0 test(16-02): add failing test for AutotaskClient.getAttachmentContent
- Asserts items[0] convention for per-attachment-ID GET
- Asserts {item:...}-shaped response yields null (guards against regression)
2026-07-15 10:22:01 -04:00
32fcf3b9f6 docs(16): create phase plan 2026-07-15 10:17:13 -04:00
d63b9adadf fix(16): revise plans based on checker feedback 2026-07-15 10:13:30 -04:00
00b8afc546 docs(16): create phase plan (3 plans, 2 waves) 2026-07-15 10:04:31 -04:00
94b53c11d0 docs(16): add pattern map 2026-07-15 09:55:39 -04:00
91bac62dd8 docs(phase-16): add validation strategy 2026-07-15 09:52:28 -04:00
dc273c002d docs(16): research phase domain 2026-07-15 09:50:36 -04:00
d3e24d968b docs(state): record phase 16 context session 2026-07-15 09:26:22 -04:00
4857a35629 docs(16): capture phase context 2026-07-15 09:26:15 -04:00
d7b8c6b72d docs(15): add pattern map 2026-07-15 08:23:34 -04:00
c33f52b435 docs(phase-15): evolve PROJECT.md after phase completion 2026-07-15 08:23:10 -04:00
664dfcb763 docs(phase-15): complete phase execution 2026-07-15 08:22:05 -04:00
c33b6615c9 test(15): persist verification report 2026-07-15 08:21:58 -04:00
502e0b95a7 docs(15): re-review after code-review fixes 2026-07-15 08:17:36 -04:00
9c4584d428 fix(15): exclude soft-deleted notes/time entries from phishing evidence
ticket_notes and time_entries both carry an is_deleted soft-delete flag
(per CLAUDE.md audit-column convention); gatherTicketEvidence was reading
both without filtering it, so retracted notes and reversed time entries
showed up as evidence for every phishing report. Found during code-review
re-verification of the Phase 15 CR-01/WR-01/WR-02 fixes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012wWroM6FXkQJiH3JgYcony
2026-07-15 08:17:07 -04:00
cb9d5af784 docs(15): add code review fix report 2026-07-15 08:09:49 -04:00
7c63c5f76d fix(15): WR-02 refresh evidence snapshot even when content_hash unchanged 2026-07-15 08:08:20 -04:00
c875081275 fix(15): WR-01 use shared getAutotaskClient factory in phishing-detector 2026-07-15 08:07:45 -04:00
ecc34b4bad fix(15): CR-01 fix webhook-triggered phishing detection reading from unpopulated payload.entity 2026-07-15 08:05:30 -04:00
e94482bd0b docs(15): add code review report 2026-07-15 07:58:33 -04:00
35339a62b8 docs(phase-15): update tracking after wave 3 2026-07-15 07:51:46 -04:00
86d6c63207 chore: merge executor worktree (worktree-agent-aec0d43efe5a155a3) 2026-07-15 07:50:30 -04:00
315a804fc3 docs(15-03): record self-check results in summary
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012wWroM6FXkQJiH3JgYcony
2026-07-15 07:50:09 -04:00
63b4aabc5e docs(15-03): add plan execution summary
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012wWroM6FXkQJiH3JgYcony
2026-07-15 07:49:51 -04:00
b199d9991c feat(15-03): register phishing-sweep schedule + migration 098
- extend sync_type union with 'phishing-sweep'
- add defaultSchedules entry (disabled by default, daily 5am cron)
- dispatch branch dynamically imports and calls sweepPhishingTickets
- migrations/098_phishing_sweep_schedule.sql seeds the row for existing installs
2026-07-15 07:49:01 -04:00
194b58b196 feat(15-03): fire-and-forget phishing detection on ticket.created webhook
- triggerPhishingDetection() mirrors triggerWorkflowEngine's payload.entity-first shape
- reads createdByContactID (Autotask field) into created_by_contact_id, per entity-mapper.ts:211
- called alongside the existing workflow-engine trigger, not awaited in the request path
2026-07-15 07:48:17 -04:00
dbd2ebe63c feat(15-03): add bounded phishing sweep service
- sweepPhishingTickets() queries recently-modified tickets (7d window, LIMIT 500)
- delegates each ticket to shared detectPhishingTicket (no duplicated match/hash logic)
- per-row try/catch increments errors without aborting the loop
2026-07-15 07:47:08 -04:00
191a8c7210 docs(phase-15): update tracking after wave 2 2026-07-15 07:45:47 -04:00
829cdd4d1d chore: merge executor worktree (worktree-agent-a4899913938a2f6e7) 2026-07-15 07:44:22 -04:00
d629679f71 docs(15-02): append self-check results to summary
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-15 07:43:58 -04:00
92ed5c0e5e docs(15-02): add plan 02 summary
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-15 07:43:43 -04:00
15d0caa20d feat(15-02): add evidence capture + detectPhishingTicket orchestration
- gatherTicketEvidence: company_name, ticket_notes, time_entries (all
  parameterized $1 queries), and Autotask attachment metadata only
  (fullPath/title/contentType, never base64 data); Autotask call wrapped in
  try/catch so a failure degrades to an empty attachments array
- detectPhishingTicket: matches, hashes, checks D-04 idempotency guard
  (skips re-gathering/writing when content_hash is unchanged), then upserts
  one reports row via ON CONFLICT (ticket_id) DO UPDATE ... RETURNING id
- requester_contact_id binds from ticket.contact_id, created_by_contact_id
  from ticket.created_by_contact_id per interfaces contract
2026-07-15 07:42:59 -04:00
aabf5322e9 feat(15-02): implement phishing pattern matcher + content hash
- KNOWN_PHISHING_PATTERNS: the 8 locked DETECT-01 strings
- matchesPhishingPatterns: case-insensitive substring match (toLowerCase +
  includes only, no RegExp/eval), mirrors robotic-classifier.evaluateContains
- computePhishingContentHash: sha256 over title+description only (D-04),
  excludes bump-prone fields like status/last_activity_date
2026-07-15 07:42:14 -04:00
0e7daf9a6a test(15-02): add failing tests for phishing pattern matcher + content hash
- Covers all 8 locked DETECT-01 patterns individually, negative case,
  case-insensitivity, and content-hash stability/change/null-normalization
2026-07-15 07:41:14 -04:00
6dffb7b358 docs(phase-15): update tracking after wave 1 2026-07-15 07:39:39 -04:00
6787308c04 chore: merge executor worktree (worktree-agent-aa19352a908fc6624) 2026-07-15 07:37:11 -04:00
8084997bfe docs(15-01): append self-check results to summary 2026-07-15 07:36:40 -04:00
15d8a691a7 docs(15-01): complete phishing triage schema foundation plan
- Migration 097 applied and verified in dev DB (7 tables, idempotent re-run confirmed)
- SUMMARY.md documents schema design decisions and worktree-path caveat with scripts/apply-migrations.sh
2026-07-15 07:36:29 -04:00
84a37e20be feat(15-01): add phishing-triage schema migration 097
- 7-table schema: campaigns, reports, messages, indicators, classifications, remediation_actions, audit_events
- reports table fully designed with ticket_id FK, content_hash (D-04 idempotency), matched_patterns, evidence (EVID-01) columns
- All tables/indexes use IF NOT EXISTS for idempotent re-application
- Remaining 6 tables are stubs for Phases 16-21
2026-07-15 07:35:10 -04:00
13208b3a92 docs(15): create phase plan 2026-07-15 07:31:25 -04:00
3f8e8dc826 docs(phase-15): create phase plan
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012wWroM6FXkQJiH3JgYcony
2026-07-15 07:17:10 -04:00
7fa94cb6a5 docs(state): record phase 15 context session 2026-07-15 06:56:47 -04:00
d3ff9d088b docs(15): capture phase context 2026-07-15 06:56:37 -04:00
0228639f24 docs: create milestone v3.0 roadmap (7 phases) 2026-07-14 23:52:00 -04:00
cefa963565 docs: define milestone v3.0 requirements 2026-07-14 23:38:23 -04:00
149bd08bd6 chore: clear v2.0 phase directories for v3.0 milestone start
Phase artifacts remain in git history (v2.0 PAX8 Integration); .planning/phases/
is cleared for the new v3.0 Phishing Triage Automation phase numbering.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-14 23:34:37 -04:00
93d2715fe7 docs: start milestone v3.0 Phishing Triage Automation 2026-07-14 23:34:19 -04:00