Follow-ups from the fresh-context review of PR #2494 (#1987 backend slice), MEDIUM + LOW, non-blocking.
MEDIUM — pre-migration LLM-triage rows withhold a truthful recorded model. ProvenanceQueryService.MapMetadata returns empty metadata whenever Provider is null. A proposal triaged through the live OpenAI leg before migration 20260904030926_AddProposalProvenanceProducerTriple has ModelId = "gpt-5.6-luna" (real) but Provider = null (column did not exist), so GET /automation/proposals/{id}/provenance/metadata returns {null,null,null} and the Review footnote stays silent for a proposal whose model is genuinely recorded. Fail-closed is defensible (there is no reliable way to tell a real model id from the queue/chat-tools/manual origin sentinels without an allow-list), but it is not stated: UPGRADING.md says pre-upgrade rows "keep null in both" without saying an already-recorded model id will now be withheld. Options: (a) one clarifying clause in UPGRADING.md and the STATUS block; (b) a small, explicit sentinel allow-list so a non-sentinel ModelId with null Provider still surfaces as model only; (c) a one-off backfill that sets Provider from the LLM request row where it is recoverable.
LOW — only capture triage stamps the triple. InboxTriageAssistant, InboxTriageDigestAgent, AutomationPlannerService, ChatService and MCP WriteTools construct CreateProposalDto without ProvenanceProvider/ProvenancePromptVersion, so the endpoint reports no producer for every non-capture proposal (honest silence, not a lie). The frontend slice (PR 2 of #1987) must not assume coverage; extend stamping producer by producer.
LOW — cosmetic: four pre-existing test files gained a UTF-8 BOM on line 1 in #2494 (AutomationProposalsApiTests.cs, AutomationProposalServiceTests.cs, ProvenanceQueryServiceTests.cs, ProposalProvenanceTests.cs). Strip when next touched.
Refs #1987, #1284, #2315.
Follow-ups from the fresh-context review of PR #2494 (#1987 backend slice), MEDIUM + LOW, non-blocking.
MEDIUM — pre-migration LLM-triage rows withhold a truthful recorded model.
ProvenanceQueryService.MapMetadatareturns empty metadata wheneverProvideris null. A proposal triaged through the live OpenAI leg before migration20260904030926_AddProposalProvenanceProducerTriplehasModelId = "gpt-5.6-luna"(real) butProvider = null(column did not exist), soGET /automation/proposals/{id}/provenance/metadatareturns{null,null,null}and the Review footnote stays silent for a proposal whose model is genuinely recorded. Fail-closed is defensible (there is no reliable way to tell a real model id from thequeue/chat-tools/manualorigin sentinels without an allow-list), but it is not stated:UPGRADING.mdsays pre-upgrade rows "keep null in both" without saying an already-recorded model id will now be withheld. Options: (a) one clarifying clause in UPGRADING.md and the STATUS block; (b) a small, explicit sentinel allow-list so a non-sentinelModelIdwith nullProviderstill surfaces asmodelonly; (c) a one-off backfill that setsProviderfrom the LLM request row where it is recoverable.LOW — only capture triage stamps the triple.
InboxTriageAssistant,InboxTriageDigestAgent,AutomationPlannerService,ChatServiceand MCPWriteToolsconstructCreateProposalDtowithoutProvenanceProvider/ProvenancePromptVersion, so the endpoint reports no producer for every non-capture proposal (honest silence, not a lie). The frontend slice (PR 2 of #1987) must not assume coverage; extend stamping producer by producer.LOW — cosmetic: four pre-existing test files gained a UTF-8 BOM on line 1 in #2494 (
AutomationProposalsApiTests.cs,AutomationProposalServiceTests.cs,ProvenanceQueryServiceTests.cs,ProposalProvenanceTests.cs). Strip when next touched.Refs #1987, #1284, #2315.