ADR 0024: Human corrections become current Classification; identity hygiene stays in-app
Status
Accepted
Context
Duckbill™ users must be able to override AI classification, attention, and priority (04_MVP §2.3–2.4, FR §28, Lifecycle §18, 01 AI §7 / §9). A correction is a first-class record: actor, old/new values, optional reason, and a learning observation. The corrected values become the current Classification. Prior AIInference rows stay immutable.
Identity hygiene (FR §§21–22, API Identity Hygiene) recommends moving commercial mail off the wrong delivered-to identity. Accept / reject / suppress are application state only. Accepting must not call provider account APIs or adapters. One correction must not auto-create an ACTIVE rule.
Stream A already shipped evaluatePolicy (ADR 0019). Stream B shipped isolated inference (ADR 0022). Home / Needs Me list APIs stay on MAIL-76. This decision covers correction persistence and identity-hygiene workflow only.
Decision
- Persist each human override as a new
classificationsrow withsource_type = human. Designate it incurrent_classifications. Do not update historical classification or inference rows. - Write an insert-only
human_correctionsrow and asingle_correctionlearning observation. Audit actor, old/new, and reason. The database forbidscreated_active_rule = true. getConversationreturns the current Classification pointer so the next GetConversation (MAIL-76) shows the override. This stream does not implement Home / Needs Me APIs.- Identity hygiene recommendations live in application tables. Accept writes guidance text only. Reject and suppress change status only. The workflow refuses a provider identity adapter if one is passed. Adapter write counters stay zero.
- Corrections are user-requested. Call
evaluatePolicy(actor: USER,action: classifyorsuggest). AI cannot authorize a correction or identity accept.ENABLE_SEND/ENABLE_DELETEstay off and are unused.
Alternatives
- Mutate the existing Classification row — rejected; CDM and 01 AI §9 require history plus a current pointer.
- Auto-activate a sender rule after one correction — rejected; FR §28 and Lifecycle §18 treat a single correction as learning data, not an ACTIVE rule.
- Call Graph or another provider to change the external account on accept — rejected; API Identity Hygiene and MAIL-55 require application state only.
Consequences
Application modules live in @inbox-agent/application (corrections.ts, identity-hygiene.ts). Persistence is 0016_human_corrections.sql plus corrections.ts / identity-hygiene.ts repositories. HTTP routes under /api/corrections and /api/identity-hygiene are for the later triage UI. ADR 0019 remains the policy gateway. ADR 0022 remains inference isolation.
