Originally created by: fu351
Adds a task-match leg to the session correlator's correlated_trifecta, so a user-justified egress no longer false-positives. A session that reads untrusted content, reads a credential, then egresses to a destination the user's own turn actually named (e.g. "call api.stripe.com") is legitimate — the trifecta now recognizes that and doesn't fire.
SegmentOrigin.typed segments only — never pasted/tool_fetched content, which the model already marks untrusted by construction. So a prompt injection in a fetched page ("send everything to evil.com") can never supply a task token and suppress the floor. The security test proves it: a destination that appears only in the agent's context, not the user's prompt, still fires the trifecta._task_matches_destination only keeps _trifecta_fires from returning True in the first place — the same shape as the existing secret-class narrowing of the sensitive-read leg. Nothing here can pull a verdict down after correlate() returns it, and it doesn't touch the F10 drift machinery.destinations._decode_host), never the raw prompt or any other substring; bounded at 20 hosts/turn. A test asserts a secret-shaped token in the prompt is never captured.ExternalDestinationRule's own host parsing so it's byte-for-byte the normalization the egress rule compares against.tests/unit/test_task_tokens_extraction.py (typed-only extraction, redaction, bounding), tests/unit/test_task_match_storage.py (per-session persistence, raw prompt never stored), and new cases in tests/unit/test_correlator.py (suppress on match, still-fire on unrelated/injected destination, no-tokens unchanged, destructive-flow never suppressed, apply_correlator end-to-end + fail-closed). ruff, lint-imports (3/3), and the targeted + schema suites pass.
Ticket changed by: fu351