<.breadcrumbs id="finding-breadcrumb"> <:crumb navigate={~p"/"}>registry <:crumb navigate={TarakanWeb.RepositoryPaths.repository_security_path(@repository)}> {@repository.owner}/{@repository.name} <:crumb>finding <%!-- Status + trust chips --%> <% canonical = @finding.canonical_finding %> <% cwe_url = canonical && TarakanWeb.FindingPresentation.cwe_url(canonical.cwe_id) %> <% cve_url = canonical && TarakanWeb.FindingPresentation.cve_url(canonical.cve_id) %> <%!-- Chips are reserved for the two things that rank this finding against every other one: how bad it is, and whether anyone has confirmed it. Everything else - trust signals, references, run counts - is evidence, and evidence reads better as a line than as a wall of badges. --%>
<.notch_badge id="finding-severity" class="bg-signal text-ground"> {@finding.severity} <.notch_badge :if={@finding.canonical_finding && @finding.canonical_finding.status == "verified"} id="finding-verified-badge" class="bg-ink text-ground" > Verified <.notch_badge :if={ @finding.canonical_finding && @finding.canonical_finding.status not in [nil, "verified"] } class="text-ink-muted" > {@finding.canonical_finding.status} <.notch_badge :if={canonical && canonical.reproductions_count > 0} id="finding-reproduced-badge" class="bg-ink text-ground" > Reproduced <.notch_badge id="finding-disclosure-badge" class="bg-ink text-ground"> {TarakanWeb.FindingPresentation.disclosure_badge(@scan.visibility, @scan.provenance)}
<%!-- The submitter's severity claim and a rubric-scored second opinion are different statements. Showing only one of them hides a disagreement that is itself information about the submitter. --%>

submitter said {@finding.severity} · rescored {canonical.calibrated_severity} ({canonical.severity_rubric})

{review_kind_label(@scan.review_kind)} {TarakanWeb.FindingPresentation.status_blurb(@scan.review_status)} detected in {@finding.canonical_finding.detections_count} {if @finding.canonical_finding.detections_count == 1, do: "run", else: "runs"} agent reproduced agent disputed human checked 0} id="finding-reproductions"> reproduced {canonical.reproductions_count} {if canonical.reproductions_count == 1, do: "time", else: "times"} <%!-- Surviving attacks is a stronger claim than collecting agreements, so it is reported as attempts survived rather than as a confirmation. --%> 0} id="finding-refutations"> survived {canonical.survived_refutations_count} of {canonical.refutations_count} {if canonical.refutations_count == 1, do: "attack", else: "attacks"} <.link :if={cwe_url} id="finding-cwe-badge" href={cwe_url} target="_blank" rel="noopener" class="text-ink-muted underline decoration-rule underline-offset-2 transition hover:text-signal" > {canonical.cwe_id} <.link :if={cve_url} id="finding-cve-badge" href={cve_url} target="_blank" rel="noopener" class="text-ink-muted underline decoration-rule underline-offset-2 transition hover:text-signal" > {canonical.cve_id}

<%!-- Title + vote --%>
<.vote_control subject_type="canonical_finding" subject_id={@finding.canonical_finding.id} summary={@finding_votes} can_vote={@can_vote} class="mt-1 shrink-0" />

{@finding.title}

<.link id="finding-source-link" navigate={~p"/findings/#{@finding.public_id}/code"} class="inline-flex max-w-full min-w-0 items-center gap-1.5 border border-strong bg-panel px-3 py-2 font-mono text-xs text-ink transition hover:border-signal hover:text-signal" aria-label={"Open #{@finding.file_path} at the finding's pinned commit"} > {@finding.file_path}{finding_lines(@finding)} <.icon name="hero-arrow-right" class="size-3.5 shrink-0" /> @ {String.slice(@scan.commit_sha || "", 0, 7)}

{@public_url}

<%!-- What / why (main content) --%> <% structured = TarakanWeb.FindingPresentation.structure_description(@finding.description) %>

What & why

{structured.lead}

{label}

{body}

{@finding.description}

Reproduction

{canonical.reproduction_steps}

Affected versions

{canonical.affected_versions}

<%!-- At a glance meta --%>

At a glance

Commit

{String.slice(@scan.commit_sha || "", 0, 12)}

{record_time(@scan.commit_committed_at)}

How made

{TarakanWeb.FindingPresentation.how_made_label(@scan.provenance)} (claim)

{@scan.model} · {@scan.prompt_version}

Submitted

<.handle_link handle={@scan.submitted_by.handle} />

{record_time(@scan.inserted_at)}

<%!-- One first finder per issue, permanently. Later reports corroborate it but never displace the credit. --%>

First found by

<.handle_link handle={@first_finder.handle} />

{record_time(@first_finder.reported_at)} · {String.slice( @first_finder.commit_sha || "", 0, 7 )}

Checks

{@finding.canonical_finding.confirmations_count} confirmed · {@finding.canonical_finding.disputes_count} disputed

status {@finding.canonical_finding.status}

Stake {@review_stake.amount} · {stake_label(@review_stake.status)}

Disclosed {record_time(@scan.reviewed_at)}

Report summary

<% notes = TarakanWeb.FindingPresentation.humanize_notes(@scan.notes) %>

{notes.count} {if notes.count == 1, do: "finding", else: "findings"} in this report.

  1. {top}

{notes.text}

<%!-- Lifecycle timeline --%> <% events = TarakanWeb.FindingPresentation.timeline_events(canonical, @finding_checks) %>

Lifecycle

  1. {event.title} · {event.detail}

    {record_time(event.at)}

<.form :if={@can_record_vendor_notification} for={@vendor_form} id="finding-vendor-form" phx-submit="record_vendor_notification" class="mt-4 flex flex-wrap items-end gap-2 border border-strong bg-panel px-4 py-3" > <.input field={@vendor_form[:notified_on]} type="date" label="Vendor notified on (empty clears)" class="border border-strong bg-ground px-3 py-2 font-mono text-xs text-ink placeholder:text-ink-faint focus:border-signal focus:outline-none" /> <.button size="sm">Record
<%!-- Independent checks --%>

Checks

<%!-- Hidden duplicate for tests that query counts only inside verification; primary counts live in glance grid --%>

No checks at this commit yet.

<.handle_link handle={check.account.handle} class="font-mono text-xs font-semibold" /> {check.verdict} · {provenance_label(check.provenance)} · {record_time(check.inserted_at)} {if check.counts_toward_quorum, do: "counts toward quorum", else: "corroboration only"}

{check.notes}

Evidence
{check.evidence}
<%!-- Queue an agent instead of doing it yourself. Each of these asks for a different kind of evidence than "somebody agreed": an attack that failed, a reproduction that ran, a score against a rubric. --%>
Open a job <.button id="finding-job-refute" type="button" size="sm" phx-click="open_finding_job" phx-value-kind="refute_finding" > Refute <.button id="finding-job-reproduce" type="button" size="sm" phx-click="open_finding_job" phx-value-kind="reproduce_finding" > Reproduce <.button id="finding-job-calibrate" type="button" size="sm" phx-click="open_finding_job" phx-value-kind="calibrate_severity" > Re-score

Record a check

<.button name="verdict" value="confirmed" size="sm">Confirm <.button name="verdict" value="disputed" variant="danger" size="sm"> Dispute <.button name="verdict" value="fixed" size="sm">Fixed
<.link :if={is_nil(@current_scope) or is_nil(@current_scope.account)} id="finding-verify-login" navigate={~p"/accounts/log-in"} class="mt-4 block font-mono text-xs text-signal hover:underline" > Sign in to confirm or dispute this finding.
<%!-- Discussion --%>

Discussion

{@comment_count} {if @comment_count == 1, do: "comment", else: "comments"}
<.button variant="primary" size="sm">Post comment
<.link :if={is_nil(@current_scope) or is_nil(@current_scope.account)} id="finding-comment-login" navigate={~p"/accounts/log-in"} class="block font-mono text-xs text-signal hover:underline" > Sign in to join the discussion.

No comments yet.

<.comment_thread :for={comment <- @comments} comment={comment} reply_to={@reply_to} can_reply={!is_nil(@current_scope) and !is_nil(@current_scope.account)} can_moderate={@can_moderate_comments} can_vote={@can_vote} votes={@comment_votes} />
<%!-- Technical dump last --%>
Technical · raw report JSON full report, not only this finding
{raw_report(@scan)}

<.link id="finding-record-link" navigate={TarakanWeb.RepositoryPaths.repository_security_path(@repository)} class="text-signal transition hover:underline" > ← All findings for {@repository.owner}/{@repository.name}