Render the recorded provenance triple in Paper Review from the proposal endpoint - #2511
Conversation
… endpoint Adds proposalDeepReviewApi.getProvenanceMetadata and makes the proposal-scoped, board-authorized endpoint the primary source of the Paper Review producer footnote, keeping the capture-detail path as a fallback for proposals stamped before the triple existed. Closes #1987
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Review gate (Codex credits exhausted, SC-9): one fresh-context reviewer confirmed no client-supplied or synthesized producer-claim path (both render paths funnel through resolveProvenanceMetadata; the backend never emits a model without a provider and the client mapper re-checks), that every abort bumps fetchGeneration before aborting so a slow response for proposal A cannot overwrite B, and that expectedStatuses only suppresses logging (401 re-auth intact, no toast). Verdict SHIP. MEDIUM noted, not blocking (narrows pre-existing behaviour): a 403 on the proposal-scoped read is normalized to 'unrecorded' so the owner-only capture fallback can still render the caller's own capture provenance under a proposal whose read was refused — tracked under #2315 state 2/3 (already cited in the code comment). LOWs declined: settled-key refresh passes no signal (guard discards the result); +1 request per selected capture-less proposal (cached); no composed spec for 403->fallback. Merging when CI green. |
Summary
Frontend half of #1987, on top of the backend contract landed in #2494. The Paper Review provenance footnote and drawer now render the proposal-scoped, server-recorded producer triple.
api/proposalDeepReviewApi.tsgainsgetProvenanceMetadata(proposalId, options?)forGET /automation/proposals/{id}/provenance/metadata, typed as{ provider: string | null, model: string | null, promptVersion: string | null }.composables/usePaperReviewSelectors.tsmakes that endpoint the primary source ofprovenanceMetadataData. The PR Surface capture provenance metadata in Review #2310 capture-detail path stays as a fallback, consulted only when the endpoint recorded nothing and the proposal carries a capture link.This is a source swap at the two existing settle sites, not new machinery. The proposal-scoped read is added into the existing
Promise.allSettledthat already carried the capture lookup, so it inherits the current generation/abort/settled-key guards unchanged. No new request generation, no change to polling, abort, or revision-lock code — those belong to the in-flight Review race-state work (#2455 / #2457 / #2458 / #2464).Behavioral consequences:
captureApi.getItemis never called for that case.403/404from the endpoint is normalized to the same all-null shape rather than thrown; every other failure (5xx, network, abort) rejects intoallSettledand also renders as no claim. On a trust surface, saying nothing beats guessing ([Frontend][Trust] Review provenance footnote claims a "deterministic offline extractor" while captures are triaged by a live LLM provider #1963).Coverage caveat (Refs #2499)
Only capture-triage proposals carry the triple today:
CaptureTriageServiceis the sole writer of the trustedProvenanceProvider/ProvenancePromptVersioninputs. Chat- and Manual-origin proposals, and every proposal created before #2494, still record no producer and therefore still render no claim — correctly, but silently. The wiring in this PR is what makes those cases renderable once something stamps them.Test plan
Base
65c77a53f; heada57195276(branchissue-1987/provenance-frontend). All fromfrontend/taskdeck-web/.npx vitest --run --maxWorkers=2 src/tests/composables/usePaperReviewSelectors.spec.ts src/tests/api/proposalDeepReviewApi.spec.ts src/tests/views/paper/review/PaperReviewView.spec.tsnpx vitest --run --maxWorkers=2 src/tests/views/paper/review/npm run typechecknpm run buildnpx eslinton all 8 changed filesgit diff --check origin/main...HEADNew coverage —
tests/api/proposalDeepReviewApi.spec.ts(7 cases): URL andexpectedStatuses: [403, 404], abort-signal passthrough, all-null payload returned verbatim,403and404normalized to no-recorded-producer, 5xx and transport failures still rejecting, id encoding.tests/composables/usePaperReviewSelectors.spec.ts(6 cases): server value renders with no capture link and no capture read; server value wins over a conflicting capture payload; fallback engages only when the endpoint recorded nothing; neither source recording anything renders no claim; a failed lookup renders no claim without stalling the core batch; a pending metadata read does not delayloadinggoing false.Four sibling specs (
PaperReviewView.spec.ts,PaperReviewActiveProposalStability.spec.ts,PaperReviewMembershipFilter.spec.ts,PaperReviewView.language.spec.ts) gain the new method on theirproposalDeepReviewApimock, defaulted to the all-null payload so their existing capture-detail expectations are unchanged.Documentation
docs/STATUS.md— intentionally untouched; the shipped-reality note for the provenance footnote belongs to the coordinator's STATUS block.docs/IMPLEMENTATION_MASTERPLAN.md— no sequencing change.Risks
usePaperReviewSelectors.tsis actively being edited by [Frontend][Review] Preserve known revision state after definite save rejection #2455 / [Frontend][A11y] Restore Review focus after cancelling a pending revision open #2457 / [Frontend][Review] Keep revision metadata truthful across overlapping A1 and A2 saves #2458 / [Frontend][Inbox] Capture write generation residuals: batchTriage bump and explicit-list-load drop #2464. This diff deliberately stays inside the two metadata settle callbacks and adds one array element to an existingPromise.allSettled; it does not touch generation counters, abort controllers,settledCoreKey, or revision-lock reasons. A textual conflict is still plausible around lines ~500 and ~660 and should be resolved in favor of the race work's structure, keeping only the metadata source choice from here.403/404renders identically to "genuinely not recorded". Both are honest no-claim outcomes, and telling them apart is explicitly [Backend][Frontend][Review] Make proposal provenance metadata lifecycle- and authorization-safe #2315 state 2, left tracked.Closes #1987
Refs #1284
Refs #2315
Refs #2499