<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alessandro</title>
    <description>The latest articles on DEV Community by Alessandro (@deste04).</description>
    <link>https://dev.to/deste04</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4192374%2Fae7a695c-591c-456f-b6c6-1f00b5b9ee9f.png</url>
      <title>DEV Community: Alessandro</title>
      <link>https://dev.to/deste04</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/deste04"/>
    <language>en</language>
    <item>
      <title>See who's vouched or denounced across GitHub projects</title>
      <dc:creator>Alessandro</dc:creator>
      <pubDate>Sun, 18 Oct 2026 15:39:58 +0000</pubDate>
      <link>https://dev.to/deste04/see-whos-vouched-or-denounced-across-github-projects-5go4</link>
      <guid>https://dev.to/deste04/see-whos-vouched-or-denounced-across-github-projects-5go4</guid>
      <description>&lt;p&gt;During a hackathon, we created a platform that uses a graph to show which repositories a user has contributed to; if those repositories contain a &lt;code&gt;vouched.td&lt;/code&gt; file, it is possible to determine whether the user is trustworthy or not. &lt;br&gt;
&lt;a href="https://vouchexplorer.vercel.app/" rel="noopener noreferrer"&gt;Check out the tool&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Vouch Explorer
&lt;/h1&gt;

&lt;p&gt;Trust graph for open-source maintainers. It reads public &lt;a href="https://github.com/mitchellh/vouch" rel="noopener noreferrer"&gt;Vouch&lt;/a&gt; lists from GitHub, shows who is vouched for or denounced across projects, and uses AI to explain the evidence. It never gives a score.&lt;/p&gt;
&lt;h2&gt;
  
  
  The idea
&lt;/h2&gt;

&lt;p&gt;AI-generated pull requests and issues are flooding maintainers. Many projects now answer with explicit trust: with Vouch, a repo keeps a plain-text &lt;code&gt;VOUCHED.td&lt;/code&gt; file listing who is vouched for and who is denounced.&lt;/p&gt;

&lt;p&gt;Each list only covers its own repo. A maintainer can't see that a newcomer is already trusted, or already denounced, somewhere else. A contributor vouched in five projects starts from zero in the sixth.&lt;/p&gt;

&lt;p&gt;Vouch Explorer joins those lists into one graph. Look up a person or a repo and you see every project that has vouched for or denounced them, who made each decision, and a short AI summary of their public work. The tool shows the evidence, and the maintainer makes the decision.&lt;/p&gt;
&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Find the lists.&lt;/strong&gt; For a repo, the app reads &lt;code&gt;VOUCHED.td&lt;/code&gt; or &lt;code&gt;.github/VOUCHED.td&lt;/code&gt; straight from &lt;code&gt;raw.githubusercontent.com&lt;/code&gt;. For a person, GitHub code search finds every list that mentions them. Copies in other paths, such as &lt;code&gt;vendor/ghostty/.github/VOUCHED.td&lt;/code&gt;, are skipped so one project's decisions aren't credited to another.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parse them.&lt;/strong&gt; The parser handles optional &lt;code&gt;platform:&lt;/code&gt; prefixes, notes, and the &lt;code&gt;+ handle&lt;/code&gt; / &lt;code&gt;- handle&lt;/code&gt; style. It has unit tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Find the voucher.&lt;/strong&gt; Each line is attributed to the commit that last added or changed it, within the file's last 30 commits. The voucher is that commit's author, but only when GitHub links the commit to an account. Otherwise it stays "unknown"; it is never guessed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Draw the graph.&lt;/strong&gt; Cytoscape.js draws the result. Green solid edges are vouches, denounced users sit on a red inner ring, and dashed edges mean the voucher is unknown. Click a node to re-centre on it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write the brief.&lt;/strong&gt; The profile page sends the person's public PRs, reviews and issues to an LLM and asks for a contribution brief. The model cites short IDs (&lt;code&gt;c3&lt;/code&gt;, &lt;code&gt;a1&lt;/code&gt;, &lt;code&gt;i42&lt;/code&gt;) instead of URLs, and the server maps them back to real links, so every piece of evidence points at something that exists. The vouch facts next to the brief ("Denounced in 7 indexed projects with the note “Bad AI etiquette”") come from the data, not from the model.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Screens
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Screen&lt;/th&gt;
&lt;th&gt;What it shows&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Explore&lt;/strong&gt; &lt;code&gt;/&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;The trust graph for a GitHub user or an &lt;code&gt;owner/repo&lt;/code&gt;, with fullscreen, fit, and a link to the profile.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Profile&lt;/strong&gt; &lt;code&gt;/u/:handle&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;The AI contribution brief with linked evidence, the vouch facts, and activity per project.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;MCP&lt;/strong&gt; &lt;code&gt;/mcp&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;How to connect the MCP server to an AI chat, and what its tools return.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  AI rules
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;No auto-vouch, no auto-denounce, no reputation score.&lt;/li&gt;
&lt;li&gt;Every prompt says: use only the data provided; if evidence is missing, say so; do not rate the person; do not recommend vouching or denouncing.&lt;/li&gt;
&lt;li&gt;Output is constrained by a JSON schema and validated with zod.&lt;/li&gt;
&lt;li&gt;Only public data: public &lt;code&gt;VOUCHED.td&lt;/code&gt; files and public GitHub activity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The default model is &lt;code&gt;openai/gpt-oss-120b&lt;/code&gt; on &lt;a href="https://groq.com" rel="noopener noreferrer"&gt;Groq&lt;/a&gt;. Any Groq model with JSON-schema output works through &lt;code&gt;GROQ_MODEL&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js 16&lt;/strong&gt; (App Router, server actions, route handlers for cancellable AI calls)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TanStack Query&lt;/strong&gt; for loading, error and cancel states&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Octokit&lt;/strong&gt; for code search, file history, users and contributions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Groq&lt;/strong&gt; for the model, with one first-in-first-out queue and abortable requests&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cytoscape.js&lt;/strong&gt; for the graph, &lt;strong&gt;&lt;a href="https://uiarc.dev" rel="noopener noreferrer"&gt;Arc UI&lt;/a&gt;&lt;/strong&gt; components, &lt;strong&gt;vitest&lt;/strong&gt; for tests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is no database yet. Data is read live from GitHub and cached in memory with Next's &lt;code&gt;"use cache"&lt;/code&gt;, so it is lost on restart.&lt;/p&gt;
&lt;h2&gt;
  
  
  Run it
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env    &lt;span class="c"&gt;# GROQ_API_KEY; GITHUB_TOKEN (falls back to `gh auth token`) turns on person search&lt;/span&gt;
npm ci
npm run dev             &lt;span class="c"&gt;# http://localhost:3000&lt;/span&gt;
npm &lt;span class="nb"&gt;test&lt;/span&gt;                &lt;span class="c"&gt;# parser and AI grounding tests&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Repo lookups (&lt;code&gt;owner/repo&lt;/code&gt;) work without a token. Person lookups need &lt;code&gt;GITHUB_TOKEN&lt;/code&gt;, because GitHub code search refuses anonymous calls.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /api/trust?q=&amp;lt;handle|owner/repo&amp;gt;&lt;/code&gt; returns the same data as JSON.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Use it from an AI chat (MCP)
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;/api/mcp&lt;/code&gt; is an &lt;a href="https://modelcontextprotocol.io" rel="noopener noreferrer"&gt;MCP&lt;/a&gt; server (Streamable HTTP, stateless, read-only). Add &lt;code&gt;https://vouchexplorer.vercel.app/api/mcp&lt;/code&gt; as a custom connector in Claude, ChatGPT, Cursor or any MCP client (setup for each is on the &lt;a href="https://vouchexplorer.vercel.app/mcp" rel="noopener noreferrer"&gt;MCP page&lt;/a&gt;), then ask things like "has anyone denounced &lt;a class="mentioned-user" href="https://dev.to/foo"&gt;@foo&lt;/a&gt;?" or "who vouched for people in ghostty-org/ghostty?".&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Returns&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;trust_lookup&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Vouch list entries for a person or an &lt;code&gt;owner/repo&lt;/code&gt;, with voucher, note and commit URL. Optional &lt;code&gt;status&lt;/code&gt; filter.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;contributor_activity&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Public profile, contributions per repo with vouch status, and recent PRs, reviews and issues with their URLs.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The chat's own model writes the answer, so no Groq call is made. The server's instructions carry the same AI rules: no score, no recommendation, only the URLs the tools return. Calls read GitHub with the server's &lt;code&gt;GITHUB_TOKEN&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add &lt;span class="nt"&gt;--transport&lt;/span&gt; http vouch-explorer https://vouchexplorer.vercel.app/api/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Limits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Forks that keep the original list inflate some counts.&lt;/li&gt;
&lt;li&gt;A person search covers at most the first 12 repos code search returns, and GitHub doesn't index every repo (forks, for one).&lt;/li&gt;
&lt;li&gt;Without a database there is no history, so "Recently vouched" is empty for now.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A database with GitHub login&lt;/li&gt;
&lt;li&gt;Repos that match your profile, and a feed of recent vouches&lt;/li&gt;
&lt;li&gt;Writing maintainer decisions back to &lt;code&gt;VOUCHED.td&lt;/code&gt; as pull requests&lt;/li&gt;
&lt;li&gt;Excluding forks from counts&lt;/li&gt;
&lt;li&gt;Other forges (GitLab, Codeberg)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Contributors
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Alessandro De Stefano&lt;/strong&gt; (&lt;a href="https://github.com/deste04" rel="noopener noreferrer"&gt;@deste04&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alessandro La Conca&lt;/strong&gt; (&lt;a href="https://github.com/Calonca" rel="noopener noreferrer"&gt;@Calonca&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fabian&lt;/strong&gt; (&lt;a href="https://github.com/fabianhogger" rel="noopener noreferrer"&gt;@fabianhogger&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vouch and the &lt;code&gt;VOUCHED.td&lt;/code&gt; format are by &lt;a href="https://github.com/mitchellh/vouch" rel="noopener noreferrer"&gt;Mitchell Hashimoto&lt;/a&gt;; this project only reads them.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>github</category>
      <category>vouched</category>
    </item>
  </channel>
</rss>
