Feedback learning channel
When the user modifies Cortex's draft before approving — tweaks the tone, swaps a recipient, shifts a meeting time — that modification is the single most valuable per-counterparty learning signal available. The feedback learning channel captures the delta and feeds it into the trust state machine + rule-candidate pipeline. Substantive deltas demote trust; cosmetic deltas emit a low-confidence voice-style candidate without trust impact.
Two ingress paths, one learning hook
Path 1: trigger.complete executed_modified outcome (ADR-0019 amendment)
When your handler executes a Cortex trigger but the user modified the draft before approving, report outcome="executed_modified" with an applied_payload field carrying the delta:
POST /v1/triggers/trg_01HX.../complete
{
"outcome": "executed_modified",
"executed_at": "2026-06-15T19:24:00Z",
"applied_payload": {
"to": "marcus@example.com",
"subject": "Re: Project timeline",
"body_draft": "Hey Marcus — sounds good. Let's sync Thursday afternoon instead.",
"tone": "casual"
},
"external_ref": "msg_abc123"
}applied_payload has the same JSON shape as the original envelope payload field. The substrate computes the delta on its side; you don't need to compute or send a diff. This is the primary, recommended path.
Path 2: feedback.signal
For explicit customer-side feedback affordances that don't fit the dispatch round-trip (e.g., a “this rule is wrong” button in your settings UI), feedback.signal takes atarget_id (decision_id / action_id / rule_id / trigger_id), a signal_kind, and a payload. MVP supports signal_kind="modification_delta"; other kinds return feature_not_available.
The modification-delta classifier
The learning hook (packages/feedback-learning/) doesn't treat every modification as a correction. It runs the delta through a classifier — Sonnet-routed, structured output, deterministic at temperature 0, sandbox-friendly — that splits the delta into substantive vs cosmetic:
- Substantive — counterparty change, intent change, payload-class change, recipient swap, semantic content rewrite. Writes a negative trust-survival signal for the
(user × action_class × counterparty)triple; emits a rule candidate referencing the source rule + the substantive delta; consolidation reviews and proposes a refinement. - Cosmetic — whitespace, polite-tone padding, ordering, casing, minor tone shift. Emits a low-confidence voice-style rule candidate (
counterparty_voicefamily); no trust impact. The substantive trust ladder is untouched.
What the substrate does with the signal
Over time, Cortex's drafts for each (user × counterparty × action class) converge on the user's voice without anyone authoring an explicit rule. The mechanism:
- User modifies draft → your handler reports
executed_modifiedwithapplied_payload. - Classifier splits the delta. Substantive deltas emit a rule candidate (visible via
patterns.list). - Consolidation Phase 2 reviews recurring deltas and proposes a refinement to the source rule via the existing rule-candidate ceremony.
- Next time Cortex drafts for the same triple, the refined rule produces a draft closer to the user's actual voice.
Cross-references
- Concept: Counterparty depth — the per-counterparty intelligence loop the feedback channel closes.
- Concept: Explainability — track rule-candidate proposals via
decision.history+meta.what_rules_fired. - Dispatch protocol (ADR-0019, amended) — the
trigger.completecallback path is where Path 1 lands. - ADR-0019 amendment (additive
executed_modifiedoutcome); ADR-0021 §learning-channel; Architecture §4a.11; Pattern §5.16 (Modification Learning Pattern).