<?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: 杨志夷</title>
    <description>The latest articles on DEV Community by 杨志夷 (@_bd5920067a3b17eb27eb0).</description>
    <link>https://dev.to/_bd5920067a3b17eb27eb0</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%2F4095530%2Fe8179682-9b48-463b-b167-27f14f51fd55.png</url>
      <title>DEV Community: 杨志夷</title>
      <link>https://dev.to/_bd5920067a3b17eb27eb0</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/_bd5920067a3b17eb27eb0"/>
    <language>en</language>
    <item>
      <title>ProofBid: An Autonomous Tender-Prep Agent That Refuses to Fabricate</title>
      <dc:creator>杨志夷</dc:creator>
      <pubDate>Wed, 26 Aug 2026 10:40:31 +0000</pubDate>
      <link>https://dev.to/_bd5920067a3b17eb27eb0/proofbid-an-autonomous-tender-prep-agent-that-refuses-to-fabricate-nj9</link>
      <guid>https://dev.to/_bd5920067a3b17eb27eb0/proofbid-an-autonomous-tender-prep-agent-that-refuses-to-fabricate-nj9</guid>
      <description>&lt;p&gt;&lt;em&gt;I built ProofBid, and wrote this article, for the purposes of entering the &lt;strong&gt;All Things Agentic Hackathon&lt;/strong&gt; (Google × Devpost, August 2026). Everything described below was implemented and verified during the submission period.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The friction I brought
&lt;/h2&gt;

&lt;p&gt;The hackathon's Taskmaster track has a "Bring Your Own Friction" mandate: find a messy, multi-step chore in your own job and build an agent that actually finishes it. Mine was easy to pick. My day job is business operations in the enterprise-equipment channel, and preparing the bid package for an equipment procurement tender is the most stressful recurring chore I know.&lt;/p&gt;

&lt;p&gt;The pain is not writing text. It is assembly under proof obligations: requirements arrive scattered across documents; every qualification and product claim needs a specific piece of evidence behind it; pricing must stay consistent across the quotation, the bill of materials, and the summary; and one missing project-specific manufacturer authorization can invalidate an otherwise perfect package.&lt;/p&gt;

&lt;p&gt;A chat assistant can summarize this work. It cannot be trusted to finish it, because "finished" means files a reviewer can sign off on—and a language model left in charge of facts will eventually paper over a gap with something plausible. That failure mode is disqualifying in tendering.&lt;/p&gt;

&lt;h2&gt;
  
  
  What ProofBid does
&lt;/h2&gt;

&lt;p&gt;ProofBid turns one tender event into a complete, reviewable preparation package—or an honest refusal.&lt;/p&gt;

&lt;p&gt;One click in a public React workbench fires the event. FastAPI on &lt;strong&gt;Cloud Run&lt;/strong&gt; accepts it and returns 202. A &lt;strong&gt;Cloud Run Job&lt;/strong&gt; executes the agent in the background. &lt;strong&gt;Cloud Storage&lt;/strong&gt; holds task state, receipts, and deliverables. The workbench polls status, shows a live tool timeline, and offers the final ZIP only after integrity validation passes.&lt;/p&gt;

&lt;p&gt;Two synthetic public cases differ by exactly one variable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Green:&lt;/strong&gt; all evidence present. The run ends &lt;code&gt;completed&lt;/code&gt;, with 12/12 requirements matched against 63 evidence references and a validated Word/Excel/JSON/Trace/ZIP package. Both readiness flags are true.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blocked:&lt;/strong&gt; the same tender and catalog, with only the project authorization removed. The run ends &lt;code&gt;blocked&lt;/code&gt; with exactly one missing item, the stable reason code &lt;code&gt;PROJECT_AUTHORIZATION_MISSING&lt;/code&gt;, both readiness flags false—and it still delivers a validated evidence ledger and remediation package.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nothing is fabricated to make a result look complete. Signing, pricing freeze, sending, and submission are locked: &lt;code&gt;submission_executed=false&lt;/code&gt; and &lt;code&gt;high_risk_actions_locked=true&lt;/code&gt; are invariant contract fields in every result.&lt;/p&gt;

&lt;h2&gt;
  
  
  The architecture decision that matters: routing vs. authority
&lt;/h2&gt;

&lt;p&gt;The obvious critique of a safety-first agent is "isn't the model just a thin wrapper around a pipeline?" ProofBid's answer is to make the division of power explicit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gemini 3.5 Flash&lt;/strong&gt; (through Vertex AI) drives the run via &lt;strong&gt;Google ADK&lt;/strong&gt; &lt;code&gt;FunctionTool&lt;/code&gt;s, and its decision rights are real: it chooses the order of registered tools within enforced dependencies, decides when analysis is sufficient, chooses the correct terminal branch—complete versus blocked—and may choose exactly one legal retry after a transient renderer failure. In verified runs those are ten FunctionTool calls per task, each with a real ADK &lt;code&gt;function_call_id&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Deterministic Python code owns everything a bid reviewer must be able to trust: requirement extraction, evidence matching, BOM and pricing arithmetic, readiness gates, document rendering (python-docx, openpyxl), and cross-artifact validation.&lt;/p&gt;

&lt;p&gt;The seam between the two is a server-side state machine. The model receives no paths, shell, SQL, URLs, prices, or business facts as parameters. The runtime enforces a tool allowlist, call budgets, input digests, dependency order, idempotency, and bounded retry. Unknown tools, input drift, duplicate terminal actions, provider errors, and schema errors all fail closed. &lt;code&gt;finalize_complete&lt;/code&gt; is unreachable until the domain and delivery validators pass; a business evidence gap must end at &lt;code&gt;finalize_blocked&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Every tool call lands in a SHA-256-chained receipt (&lt;code&gt;tool_receipts.jsonl&lt;/code&gt;), packaged with an exact-set manifest, so anyone can audit which decisions the model actually made.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "verified" means here
&lt;/h2&gt;

&lt;p&gt;I tried to hold the project to evidence standards similar to the domain it serves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;69 Python tests plus a 50-case synthetic Eval matrix (structure, missing evidence, product/pricing, prompt injection, bounded recovery) at 50/50 on local runs;&lt;/li&gt;
&lt;li&gt;Playwright desktop and mobile checks against the real built frontend;&lt;/li&gt;
&lt;li&gt;real Cloud Run Job executions for green, blocked, and one admin-only recovery route, each reconciled across the Gemini provider receipt, structured logs, Cloud Run revision and image digest, and matching ZIP SHA-256 hashes in Cloud Storage and the public service;&lt;/li&gt;
&lt;li&gt;a clean-clone gate: a fresh public HTTPS clone must pass installs, tests, Eval, frontend build, Playwright, a Docker build, and a container run end to end.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All public data is synthetic by design. Real tender documents are confidential, and a fixed single-variable pair of cases lets a reviewer verify that completion and blocking are driven by evidence rather than prompt luck. Real-document parsing is the next product step—behind human approval receipts, not automated signing or sending.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Agent autonomy is strongest when its decision rights are explicit.&lt;/strong&gt; A constrained tool router is still meaningfully agentic if it owns recovery and terminal-branch decisions, while typed deterministic tools protect professional truth.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A truthful blocker is a feature, not a failure.&lt;/strong&gt; Distinguishing a business blocker from a technical failure—and still shipping a validated remediation package—turned the "sad path" into the most convincing part of the demo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Receipts beat claims.&lt;/strong&gt; Chained digests, provider receipts, and reconciled cloud evidence made every demo statement checkable, which changed how I built everything upstream of the video.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Demo video (4 min): &lt;a href="https://youtu.be/E4Ke_cWLFus" rel="noopener noreferrer"&gt;https://youtu.be/E4Ke_cWLFus&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Live workbench (two synthetic cases): &lt;a href="https://proofbid-um2t63h7ha-uc.a.run.app" rel="noopener noreferrer"&gt;https://proofbid-um2t63h7ha-uc.a.run.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Source (Apache-2.0): &lt;a href="https://github.com/yyswordsman-CN/proofbid" rel="noopener noreferrer"&gt;https://github.com/yyswordsman-CN/proofbid&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Built solo with Gemini 3.5 Flash, Google ADK, Cloud Run, and Cloud Storage for the All Things Agentic Hackathon. #AllThingsAgenticHackathon&lt;/em&gt;&lt;/p&gt;

</description>
      <category>googlecloud</category>
      <category>ai</category>
      <category>agents</category>
      <category>gemini</category>
    </item>
    <item>
      <title>ProofBid: An Autonomous Tender-Prep Agent That Refuses to Fabricate" published: true tags: googlecloud, ai, agents, gemini</title>
      <dc:creator>杨志夷</dc:creator>
      <pubDate>Wed, 26 Aug 2026 10:25:55 +0000</pubDate>
      <link>https://dev.to/_bd5920067a3b17eb27eb0/proofbid-an-autonomous-tender-prep-agent-that-refuses-to-fabricate-published-true-tags-31gk</link>
      <guid>https://dev.to/_bd5920067a3b17eb27eb0/proofbid-an-autonomous-tender-prep-agent-that-refuses-to-fabricate-published-true-tags-31gk</guid>
      <description>&lt;p&gt;I built ProofBid, and wrote this article, for the purposes of entering the All Things Agentic Hackathon (Google × Devpost, August 2026). Everything described below was implemented and verified during the submission period.&lt;/p&gt;

&lt;p&gt;The friction I brought&lt;br&gt;
The hackathon's Taskmaster track has a "Bring Your Own Friction" mandate: find a messy, multi-step chore in your own job and build an agent that actually finishes it. Mine was easy to pick. My day job is business operations in the enterprise-equipment channel, and preparing the bid package for an equipment procurement tender is the most stressful recurring chore I know.&lt;/p&gt;

&lt;p&gt;The pain is not writing text. It is assembly under proof obligations: requirements arrive scattered across documents; every qualification and product claim needs a specific piece of evidence behind it; pricing must stay consistent across the quotation, the bill of materials, and the summary; and one missing project-specific manufacturer authorization can invalidate an otherwise perfect package.&lt;/p&gt;

&lt;p&gt;A chat assistant can summarize this work. It cannot be trusted to finish it, because "finished" means files a reviewer can sign off on—and a language model left in charge of facts will eventually paper over a gap with something plausible. That failure mode is disqualifying in tendering.&lt;/p&gt;

&lt;p&gt;What ProofBid does&lt;br&gt;
ProofBid turns one tender event into a complete, reviewable preparation package—or an honest refusal.&lt;/p&gt;

&lt;p&gt;One click in a public React workbench fires the event. FastAPI on Cloud Run accepts it and returns 202. A Cloud Run Job executes the agent in the background. Cloud Storage holds task state, receipts, and deliverables. The workbench polls status, shows a live tool timeline, and offers the final ZIP only after integrity validation passes.&lt;/p&gt;

&lt;p&gt;Two synthetic public cases differ by exactly one variable:&lt;/p&gt;

&lt;p&gt;Green: all evidence present. The run ends completed, with 12/12 requirements matched against 63 evidence references and a validated Word/Excel/JSON/Trace/ZIP package. Both readiness flags are true.&lt;br&gt;
Blocked: the same tender and catalog, with only the project authorization removed. The run ends blocked with exactly one missing item, the stable reason code PROJECT_AUTHORIZATION_MISSING, both readiness flags false—and it still delivers a validated evidence ledger and remediation package.&lt;br&gt;
Nothing is fabricated to make a result look complete. Signing, pricing freeze, sending, and submission are locked: submission_executed=false and high_risk_actions_locked=true are invariant contract fields in every result.&lt;/p&gt;

&lt;p&gt;The architecture decision that matters: routing vs. authority&lt;br&gt;
The obvious critique of a safety-first agent is "isn't the model just a thin wrapper around a pipeline?" ProofBid's answer is to make the division of power explicit.&lt;/p&gt;

&lt;p&gt;Gemini 3.5 Flash (through Vertex AI) drives the run via Google ADK FunctionTools, and its decision rights are real: it chooses the order of registered tools within enforced dependencies, decides when analysis is sufficient, chooses the correct terminal branch—complete versus blocked—and may choose exactly one legal retry after a transient renderer failure. In verified runs those are ten FunctionTool calls per task, each with a real ADK function_call_id.&lt;/p&gt;

&lt;p&gt;Deterministic Python code owns everything a bid reviewer must be able to trust: requirement extraction, evidence matching, BOM and pricing arithmetic, readiness gates, document rendering (python-docx, openpyxl), and cross-artifact validation.&lt;/p&gt;

&lt;p&gt;The seam between the two is a server-side state machine. The model receives no paths, shell, SQL, URLs, prices, or business facts as parameters. The runtime enforces a tool allowlist, call budgets, input digests, dependency order, idempotency, and bounded retry. Unknown tools, input drift, duplicate terminal actions, provider errors, and schema errors all fail closed. finalize_complete is unreachable until the domain and delivery validators pass; a business evidence gap must end at finalize_blocked.&lt;/p&gt;

&lt;p&gt;Every tool call lands in a SHA-256-chained receipt (tool_receipts.jsonl), packaged with an exact-set manifest, so anyone can audit which decisions the model actually made.&lt;/p&gt;

&lt;p&gt;What "verified" means here&lt;br&gt;
I tried to hold the project to evidence standards similar to the domain it serves:&lt;/p&gt;

&lt;p&gt;69 Python tests plus a 50-case synthetic Eval matrix (structure, missing evidence, product/pricing, prompt injection, bounded recovery) at 50/50 on local runs;&lt;br&gt;
Playwright desktop and mobile checks against the real built frontend;&lt;br&gt;
real Cloud Run Job executions for green, blocked, and one admin-only recovery route, each reconciled across the Gemini provider receipt, structured logs, Cloud Run revision and image digest, and matching ZIP SHA-256 hashes in Cloud Storage and the public service;&lt;br&gt;
a clean-clone gate: a fresh public HTTPS clone must pass installs, tests, Eval, frontend build, Playwright, a Docker build, and a container run end to end.&lt;br&gt;
All public data is synthetic by design. Real tender documents are confidential, and a fixed single-variable pair of cases lets a reviewer verify that completion and blocking are driven by evidence rather than prompt luck. Real-document parsing is the next product step—behind human approval receipts, not automated signing or sending.&lt;/p&gt;

&lt;p&gt;What I learned&lt;br&gt;
Agent autonomy is strongest when its decision rights are explicit. A constrained tool router is still meaningfully agentic if it owns recovery and terminal-branch decisions, while typed deterministic tools protect professional truth.&lt;br&gt;
A truthful blocker is a feature, not a failure. Distinguishing a business blocker from a technical failure—and still shipping a validated remediation package—turned the "sad path" into the most convincing part of the demo.&lt;br&gt;
Receipts beat claims. Chained digests, provider receipts, and reconciled cloud evidence made every demo statement checkable, which changed how I built everything upstream of the video.&lt;br&gt;
Links&lt;br&gt;
Demo video (4 min): &lt;a href="https://youtu.be/E4Ke_cWLFus" rel="noopener noreferrer"&gt;https://youtu.be/E4Ke_cWLFus&lt;/a&gt;&lt;br&gt;
Live workbench (two synthetic cases): &lt;a href="https://proofbid-um2t63h7ha-uc.a.run.app" rel="noopener noreferrer"&gt;https://proofbid-um2t63h7ha-uc.a.run.app&lt;/a&gt;&lt;br&gt;
Source (Apache-2.0): &lt;a href="https://github.com/yyswordsman-CN/proofbid" rel="noopener noreferrer"&gt;https://github.com/yyswordsman-CN/proofbid&lt;/a&gt;&lt;br&gt;
Built solo with Gemini 3.5 Flash, Google ADK, Cloud Run, and Cloud Storage for the All Things Agentic Hackathon. #AllThingsAgenticHackathon&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>gemini</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
