> ## Documentation Index
> Fetch the complete documentation index at: https://anvil.servicetitan.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Evidence Disclosure

> Evidence disclosure is an agent's justification for its conclusion.

export const LiveCode = ({children, customHeight, clickToLoad, example, fullWidth, fullHeight, hideCodeInLiveCode, screenshot, screenshotOnly, showCode: showCodeProp}) => {
  const SCREENSHOTS_BASE = "https://servicetitan.github.io/anvil2-docs-live-code/screenshots";
  const STACKBLITZ_BASE = "https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples";
  const [showCodeBlock, setShowCodeBlock] = useState(showCodeProp ?? false);
  const [isLocalOverride, setIsLocalOverride] = useState(false);
  useEffect(() => {
    const examplePath = `/images/live-code-screenshots-tmp/${example}.png`;
    fetch(examplePath, {
      method: "HEAD"
    }).then(r => {
      if (r.ok) setIsLocalOverride(true);
    }).catch(() => {});
  }, [example]);
  const screenshotBase = isLocalOverride ? "/images/live-code-screenshots-tmp" : SCREENSHOTS_BASE;
  if (screenshotOnly) {
    return <Frame className="flex flex-col">
        <div className="flex dark:hidden" style={{
      justifyContent: "center",
      alignItems: "center",
      width: fullWidth ? "100%" : "50%",
      minHeight: fullHeight ? "284px" : undefined,
      background: "#FFFFFF"
    }}>
          <img srcset={`${screenshotBase}/${example}.png, ${screenshotBase}/${example}-2x.png 2x`} src={`${screenshotBase}/${example}.png`} alt={example} noZoom />
        </div>
        <div className="hidden dark:flex" style={{
      justifyContent: "center",
      alignItems: "center",
      width: fullWidth ? "100%" : "50%",
      minHeight: fullHeight ? "284px" : undefined,
      background: "#141414"
    }}>
          <img srcset={`${screenshotBase}/${example}-dark.png, ${screenshotBase}/${example}-dark-2x.png 2x`} src={`${screenshotBase}/${example}-dark.png`} alt={example} noZoom />
        </div>
      </Frame>;
  }
  if (screenshot) {
    return <Frame className="flex flex-col -mb-2">
        <div className="flex dark:hidden bg-white dark:bg-codeblock border border-gray-950/10 dark:border-white/10 dark:twoslash-dark rounded-2xl overflow-hidden" style={{
      justifyContent: "center",
      alignItems: "center",
      width: fullWidth ? "100%" : "50%",
      minHeight: fullHeight ? "284px" : undefined
    }}>
          <img srcset={`${screenshotBase}/${example}.png, ${screenshotBase}/${example}-2x.png 2x`} src={`${screenshotBase}/${example}.png`} alt={example} noZoom />
        </div>

        <div className="hidden dark:flex bg-white dark:bg-codeblock border border-gray-950/10 dark:border-white/10 dark:twoslash-dark rounded-2xl overflow-hidden" style={{
      background: "#141414",
      justifyContent: "center",
      alignItems: "center",
      width: fullWidth ? "100%" : "50%",
      minHeight: fullHeight ? "284px" : undefined
    }}>
          <img srcset={`${screenshotBase}/${example}-dark.png, ${screenshotBase}/${example}-dark-2x.png 2x`} src={`${screenshotBase}/${example}-dark.png`} alt={example} noZoom />
        </div>

        <div className="flex justify-end items-center text-xs py-2 px-1 gap-4">
          {!showCodeProp ? <button className="inline-flex justify-end items-center text-gray-700 dark:text-gray-50 hover:text-blue-500 dark:hover:text-blue-300 transition-colors group self-end gap-1 cursor-pointer" onClick={() => setShowCodeBlock(!showCodeBlock)} style={{
      appearance: "none"
    }}>
              <Icon icon="code" size="12px" className="group-hover:bg-blue-500 dark:group-hover:bg-blue-300" />
              <span>{showCodeBlock ? "Hide code" : "Show code"}</span>
            </button> : null}

          <a className="inline-flex justify-end items-center hover:text-blue-500 dark:hover:text-blue-300 transition-colors group self-end gap-1" href={`${STACKBLITZ_BASE}/${example}?file=src/App.tsx`} target="_blank" rel="noreferrer">
            <Icon icon="bolt" size="12px" className="group-hover:bg-blue-500 dark:group-hover:bg-blue-300" />
            <span>StackBlitz demo</span>
          </a>
        </div>

        <div className="grid transition-[grid-template-rows] duration-300 ease-in-out overflow-auto overflow-y-hidden overflow-x-auto" style={showCodeBlock ? {
      gridTemplateRows: "1fr"
    } : {
      gridTemplateRows: "0fr"
    }}>
          <div style={{
      minHeight: 0,
      overflowX: "auto",
      overflowY: "hidden",
      marginBlockStart: "-1.25rem",
      marginBlockEnd: "-1.5rem"
    }}>
            {children}
          </div>
        </div>
      </Frame>;
  } else {
    return <div style={{
      display: "flex",
      width: fullWidth ? "100%" : "50%",
      minHeight: customHeight ? customHeight : "316px",
      resize: "vertical",
      overflow: "auto"
    }}>
        <iframe title={example} style={{
      flex: 1,
      width: fullWidth ? "100%" : "50%",
      minHeight: customHeight ? customHeight : "316px"
    }} src={`${STACKBLITZ_BASE}/${example}?embed=1&hideNavigation=1&hideExplorer=1&terminalHeight=0&file=src/App.tsx${clickToLoad ? "&ctl=1" : ""}${hideCodeInLiveCode ? "&view=preview" : ""}`} allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts" />
      </div>;
  }
};

export const DoDont = ({text, type, children}) => {
  return <>
      {type === "do" && <div className="do-dont do">
          {children && <div className="do-dont-content">{children}</div>}
          <Check>
            <p>
              <strong>Do</strong>
              {text && <span className="m-inline-start-1">{text}</span>}
            </p>
          </Check>
        </div>}
      {type === "dont" && <div className="do-dont dont">
          {children && <div className="do-dont-content">{children}</div>}
          <Danger>
            <p>
              <strong>Don't</strong>
              {text && <span className="m-inline-start-1">{text}</span>}
            </p>
          </Danger>
        </div>}
      {type === "caution" && <div className="do-dont caution">
          {children && <div className="do-dont-content">{children}</div>}
          <Warning>
            <p>
              <strong>Caution</strong>
              {text && <span className="m-inline-start-1">{text}</span>}
            </p>
          </Warning>
        </div>}
    </>;
};

Evidence disclosure is a type of progressive disclosure. What's being presented with evidence disclosure is trust-making material: the evidence a user would want in order to verify the AI didn't make something up.

This is part of the [Reasoning](/docs/kits/ai-kit/ai-ux/ux-and-the-five-parts-of-a-moment#2-reason) aspect of AI UX.

## Why evidence disclosure helps users

* Users report that seeing citations increases their confidence in an AI answer. However, users rarely actually click through to check them. The value of the disclosure is in the offer, not the click-through rate.

* Reasoning content is qualitatively different from output content—it may contain errors, false starts, or dead ends, and should be visually distinguished from the final answer rather than presented with the same confidence.

## Types of evidence disclosure

Evidence disclosure falls into two main categories:

* **Reasoning trace/extended thinking**—This typically appears above an agent response with a label like "Thought for \[x] seconds" and a chevron that allows the user to click into the reasoning that led the agent to the answer it gave. It always has different styling from the chat itself to make it clear it's categorically different from the styling of the agent responses themselves.
* **Citations**—These are pills that appear with an agent response that cite the agent's sources.

## Getting Started

Evidence Disclosure is composed from existing Carto components rather than a single dedicated component. Pick the building blocks that match what evidence you're disclosing.

| Component                                                        | When to Use                                                                               |
| ---------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| **[Citation](/docs/kits/ai-kit/components/citation/design)**     | Attribute a specific claim in agent text to a source, inline or at the end of a response. |
| **[Action Log](/docs/kits/ai-kit/components/action-log/design)** | Shows the user how the agent arrived as its conclusion.                                   |

## Dos and Don'ts

<Columns cols={2} className="gap-4">
  <DoDont type="do" text="Provide the agent response first, with reasoning one click away.">
    <LiveCode example="carto-evidence-disclosure-response-first-do" screenshot fullWidth>
      ```tsx lines theme={null}
      import { useState } from "react";
      import {
        CartoTheme,
        ChatLayout,
        PromptBar,
        AgentMessage,
        Text,
        ActionLog,
      } from "@servicetitan/carto-react-kit";
      import "@servicetitan/carto-react-kit/styles.css";

      function App() {
        const [value, setValue] = useState("");

        return (
          <CartoTheme>
            <div
              style={{
                height: 420,
                border: "1px solid #e0e0e0",
                borderRadius: 8,
                overflow: "hidden",
              }}
            >
              <ChatLayout
                conversation={
                  <>
                    <AgentMessage
                      timestamp={new Date(2026, 3, 1, 16, 41)}
                      content={
                        <>
                          <ActionLog
                            defaultExpanded={false}
                            steps={[
                              {
                                id: "a",
                                title: "Looked up the customer account",
                                status: "success",
                              },
                              {
                                id: "b",
                                title:
                                  "Checked the last 20 invoices for overdue balances",
                                status: "success",
                              },
                            ]}
                          />
                          <Text text="Your account is in good standing—no overdue balances on the last 20 invoices." />
                        </>
                      }
                    />
                  </>
                }
                prompt={
                  <PromptBar
                    value={value}
                    onChange={setValue}
                    placeholder="Ask anything…"
                  />
                }
              />
            </div>
          </CartoTheme>
        );
      }

      export default App;
      ```
    </LiveCode>
  </DoDont>

  <DoDont type="dont" text="Put the reasoning trace or a source list at the end of the message.">
    <LiveCode example="carto-evidence-disclosure-response-first-dont" screenshot fullWidth>
      ```tsx lines theme={null}
      import { useState } from "react";
      import {
        CartoTheme,
        ChatLayout,
        PromptBar,
        AgentMessage,
        Text,
        ActionLog,
      } from "@servicetitan/carto-react-kit";
      import "@servicetitan/carto-react-kit/styles.css";

      function App() {
        const [value, setValue] = useState("");

        return (
          <CartoTheme>
            <div
              style={{
                height: 420,
                border: "1px solid #e0e0e0",
                borderRadius: 8,
                overflow: "hidden",
              }}
            >
              <ChatLayout
                conversation={
                  <>
                    <AgentMessage
                      timestamp={new Date(2026, 3, 1, 16, 41)}
                      content={
                        <>
                          <Text text="Your account is in good standing—no overdue balances on the last 20 invoices." />
                          <ActionLog
                            defaultExpanded={false}
                            steps={[
                              {
                                id: "a",
                                title: "Looked up the customer account",
                                status: "success",
                              },
                              {
                                id: "b",
                                title:
                                  "Checked the last 20 invoices for overdue balances",
                                status: "success",
                              },
                            ]}
                          />
                        </>
                      }
                    />
                  </>
                }
                prompt={
                  <PromptBar
                    value={value}
                    onChange={setValue}
                    placeholder="Ask anything…"
                  />
                }
              />
            </div>
          </CartoTheme>
        );
      }

      export default App;
      ```
    </LiveCode>
  </DoDont>

  <DoDont type="do" text={`Always provide some sort of label for an Evidence Disclosure marker. "View reasoning," "3 sources," "Thought for 12s," "Show steps"—something that tells the user what's behind it.`}>
    <LiveCode example="carto-evidence-disclosure-labeled-do" screenshot fullWidth>
      ```tsx lines theme={null}
      import { useState } from "react";
      import {
        CartoTheme,
        ChatLayout,
        PromptBar,
        AgentMessage,
        ActionLog,
        Text,
      } from "@servicetitan/carto-react-kit";
      import "@servicetitan/carto-react-kit/styles.css";

      function App() {
        const [value, setValue] = useState("");

        return (
          <CartoTheme>
            <div
              style={{
                height: 420,
                border: "1px solid #e0e0e0",
                borderRadius: 8,
                overflow: "hidden",
              }}
            >
              <ChatLayout
                conversation={
                  <AgentMessage
                    timestamp={new Date(2026, 3, 1, 16, 41)}
                    content={
                      <>
                        <ActionLog
                          defaultExpanded={false}
                          steps={[
                            {
                              id: "a",
                              title: "Looked up the customer account",
                              status: "success",
                            },
                            {
                              id: "b",
                              title:
                                "Checked the last 20 invoices for overdue balances",
                              status: "success",
                            },
                          ]}
                        />
                        <Text text="Your account is in good standing—no overdue balances on the last 20 invoices." />
                      </>
                    }
                  />
                }
                prompt={
                  <PromptBar
                    value={value}
                    onChange={setValue}
                    placeholder="Ask anything…"
                  />
                }
              />
            </div>
          </CartoTheme>
        );
      }

      export default App;
      ```
    </LiveCode>
  </DoDont>

  <DoDont type="dont" text="Use an icon or an ellipsis that gives no hint as to what's inside the dropdown or link.">
    <LiveCode example="carto-evidence-disclosure-labeled-dont" screenshot fullWidth>
      ```tsx lines theme={null}
      import { useState } from "react";
      import {
        CartoTheme,
        ChatLayout,
        PromptBar,
        Text,
        AgentMessage,
      } from "@servicetitan/carto-react-kit";
      import "@servicetitan/carto-react-kit/styles.css";

      function App() {
        const [value, setValue] = useState("");

        return (
          <CartoTheme>
            <div
              style={{
                height: 420,
                border: "1px solid #e0e0e0",
                borderRadius: 8,
                overflow: "hidden",
              }}
            >
              <ChatLayout
                conversation={
                  <AgentMessage
                    timestamp={new Date(2026, 3, 1, 16, 41)}
                    content={
                      <>
                        <div
                          style={{
                            display: "flex",
                            alignItems: "center",
                            gap: 16,
                          }}
                        >
                          <button
                            type="button"
                            style={{
                              border: "none",
                              background: "none",
                              cursor: "pointer",
                              fontSize: 20,
                              lineHeight: 1,
                              padding: 4,
                            }}
                          >
                            ⋯
                          </button>
                        </div>
                        <Text text="Your account is in good standing—no overdue balances on the last 20 invoices." />
                      </>
                    }
                  />
                }
                prompt={
                  <PromptBar
                    value={value}
                    onChange={setValue}
                    placeholder="Ask anything…"
                  />
                }
              />
            </div>
          </CartoTheme>
        );
      }

      export default App;
      ```
    </LiveCode>
  </DoDont>

  <DoDont type="do" text="Provide one click to find the reasoning.">
    <LiveCode example="carto-evidence-disclosure-one-click-do" screenshot fullWidth>
      ```tsx lines theme={null}
      import { useState } from "react";
      import {
        CartoTheme,
        ChatLayout,
        PromptBar,
        AgentMessage,
        ActionLog,
        Text,
      } from "@servicetitan/carto-react-kit";
      import "@servicetitan/carto-react-kit/styles.css";

      function App() {
        const [value, setValue] = useState("");

        return (
          <CartoTheme>
            <div
              style={{
                height: 420,
                border: "1px solid #e0e0e0",
                borderRadius: 8,
                overflow: "hidden",
              }}
            >
              <ChatLayout
                conversation={
                  <AgentMessage
                    timestamp={new Date(2026, 3, 1, 16, 41)}
                    content={
                      <>
                        <ActionLog
                          defaultExpanded={false}
                          steps={[
                            {
                              id: "a",
                              title: "Looked up the customer account",
                              status: "success",
                            },
                            {
                              id: "b",
                              title:
                                "Checked the last 20 invoices for overdue balances",
                              status: "success",
                            },
                          ]}
                        />
                        <Text text="Your account is in good standing—no overdue balances on the last 20 invoices." />
                      </>
                    }
                  />
                }
                prompt={
                  <PromptBar
                    value={value}
                    onChange={setValue}
                    placeholder="Ask anything…"
                  />
                }
              />
            </div>
          </CartoTheme>
        );
      }

      export default App;
      ```
    </LiveCode>
  </DoDont>

  <DoDont type="dont" text="Make reasoning a hunt. Evidence disclosure fails if the detail lives in a separate tab, settings screen, or requires a follow-up question to surface.">
    <LiveCode example="carto-evidence-disclosure-one-click-dont" screenshot fullWidth>
      ```tsx lines theme={null}
      import { useState } from "react";
      import {
        CartoTheme,
        ChatLayout,
        PromptBar,
        AgentMessage,
        Link,
        Text,
      } from "@servicetitan/carto-react-kit";
      import "@servicetitan/carto-react-kit/styles.css";

      function App() {
        const [value, setValue] = useState("");

        return (
          <CartoTheme>
            <div
              style={{
                height: 420,
                border: "1px solid #e0e0e0",
                borderRadius: 8,
                overflow: "hidden",
              }}
            >
              <ChatLayout
                conversation={
                  <AgentMessage
                    timestamp={new Date(2026, 3, 1, 16, 41)}
                    content={
                      <>
                        <Text text="Your account is in good standing—no overdue balances on the last 20 invoices." />
                        <Link href="#" text="See reasoning" />
                      </>
                    }
                  />
                }
                prompt={
                  <PromptBar
                    value={value}
                    onChange={setValue}
                    placeholder="Ask anything…"
                  />
                }
              />
            </div>
          </CartoTheme>
        );
      }

      export default App;
      ```
    </LiveCode>
  </DoDont>
</Columns>
