feat(FN-3392): implement follow-up suggestion contract and policy system

Merges the evaluator follow-up suggestion system (FN-3392, Steps 1–5), which adds a normalized contract, provenance tracking, and lifecycle documentation for AI-generated follow-up tasks, alongside chat UI improvements including unread indicators in header and mobile nav, corrected message routing,

Fusion-Task-Id: FN-3392
This commit is contained in:
Fusion
2026-05-06 19:34:27 -07:00
committed by gsxdsm
parent c95517af31
commit 52c673a4cb
11 changed files with 594 additions and 15 deletions

View File

@@ -99,10 +99,51 @@ Stored references include task/run identifiers and source-specific drill-down fi
`packages/engine/src/evaluator.ts` injects the normalized bundle under a dedicated `## Evidence` prompt section. The evaluator is instructed to cite evidence IDs/labels from this section instead of inventing unsupported claims.
## Follow-up Suggestion Policy
Evaluator follow-ups are normalized into structured `followUps[]` records on each eval result (no freeform-only suggestions).
Each suggestion includes:
- stable `suggestionId` + `dedupeKey`
- `title`, `description`, `priority`, `severity`
- `rationale` and `evidenceRefs[]`
- policy recommendation (`shouldCreate`, `policyQualified`, `reason`)
- lifecycle state: `suggested` | `suppressed` | `created`
- suppression/debug fields when applicable: `suppressedReason`, `matchedTaskId`, `matchedSuggestionId`
- creation linkage when applicable: `createdTaskId`
### Policy modes
Backend policy modes used by evaluator orchestration:
- `persist_only`: persist normalized suggestions for manual review only
- `auto_create_qualified`: auto-create only policy-qualified suggestions
- `create_all_non_duplicates`: auto-create all non-suppressed, non-duplicate suggestions
Current project settings mapping:
- `taskEvaluationFollowUpPolicy = "off" | "suggest"``persist_only`
- `taskEvaluationFollowUpPolicy = "create"``auto_create_qualified`
### Dedupe + suppression guardrails
Suggestions are suppressed when they are:
- empty/generic (`empty_or_generic`)
- missing strong signal (`insufficient_signal`)
- duplicates of an already-open board task (`duplicate_open_task`)
- duplicates of a prior eval suggestion for the same parent task (`duplicate_prior_suggestion`)
Suppression reasons and matched IDs are persisted on the suggestion for auditability.
### Task creation provenance
When policy permits creation, evaluator code uses `TaskStore.createTask()` (no ad hoc file writes). Created tasks:
- are created in `triage`
- set `sourceParentTaskId` to the evaluated task
- set `sourceMetadata` with eval provenance (`type=eval_follow_up`, `runId`, `suggestionId`, `policyMode`, `dedupeKey`)
- include actionable context (problem summary, expected outcome, score/severity, rationale, evidence refs)
## Non-Goals
This contract does not define:
- follow-up task creation policy
- eval settings UX
- eval dashboard/list rendering