<?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: Preflight AI</title>
    <description>The latest articles on DEV Community by Preflight AI (@tamara_preflight).</description>
    <link>https://dev.to/tamara_preflight</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%2F4155714%2Fa5f9de4f-340a-43b6-bbae-28cbc0299cab.png</url>
      <title>DEV Community: Preflight AI</title>
      <link>https://dev.to/tamara_preflight</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tamara_preflight"/>
    <language>en</language>
    <item>
      <title>How to require human approval before a Node.js AI agent creates a GitHub issue</title>
      <dc:creator>Preflight AI</dc:creator>
      <pubDate>Thu, 01 Oct 2026 20:22:30 +0000</pubDate>
      <link>https://dev.to/tamara_preflight/preflight-human-approval-for-nodejs-github-agents-2hh</link>
      <guid>https://dev.to/tamara_preflight/preflight-human-approval-for-nodejs-github-agents-2hh</guid>
      <description>&lt;p&gt;An AI agent proposes a GitHub issue. A human approves it. What happens if the title changes before execution, or the same approved request is submitted twice?&lt;/p&gt;

&lt;p&gt;Preflight Action Gate is a downloadable local kit for Node.js agents that need a separate human approval step before creating GitHub issues. It binds approval to the exact repository, title and body, rejects changed intent and blocks repeat execution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start with the &lt;a href="https://preflight-action-gate.temoode32.chatgpt.site/?source=dev-showdev#availability" rel="noopener noreferrer"&gt;free local evaluation&lt;/a&gt;. No account or card is needed for the default trial.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Run the trial
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Install Node.js 22 or newer if you do not already have it.&lt;/li&gt;
&lt;li&gt;Download and extract the evaluation ZIP.&lt;/li&gt;
&lt;li&gt;Open a terminal in the extracted folder and run:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node scripts/buyer-demo.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command calls a real local Preflight server with synthetic actions. It creates no external GitHub issue and needs no npm install, GitHub token, database or AI key.&lt;/p&gt;

&lt;p&gt;A successful run ends with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Successful use: 13 checks passed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The checks include rejection of unauthorized calls, enforcement of BLOCK and REVIEW, separation of agent and reviewer roles, rejection of changed intent and repeat execution, persisted execution state and verification of the signed local audit chain. These are local checks, not production certification.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try a separate human approval
&lt;/h2&gt;

&lt;p&gt;In one terminal, start the local server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node scripts/local-kit.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In another terminal, in the same extracted folder, propose an issue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node examples/self-service-issue.js propose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A separate reviewer inspects the returned request ID. Replace REQUEST_ID with the actual value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node scripts/local-review.js REQUEST_ID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inspection alone does not approve the request. After checking the exact repository, title and body, the reviewer explicitly confirms the displayed intent hash. Replace both placeholders:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node scripts/local-review.js REQUEST_ID &lt;span class="nt"&gt;--approve&lt;/span&gt; EXACT_INTENT_HASH
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run the dry-run execution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node examples/self-service-issue.js execute
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the execution command again to check replay rejection. The default workflow above does not write to GitHub.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting your Node.js agent
&lt;/h2&gt;

&lt;p&gt;The archive includes a reusable SDK, an issue example and local reviewer commands. The local API uses separate agent and reviewer credentials with these routes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;POST /simulate proposes the action for a decision.&lt;/li&gt;
&lt;li&gt;POST /approve records approval for the exact stored intent.&lt;/li&gt;
&lt;li&gt;POST /execute attempts the approved action.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Only GitHub issue creation is included as a supplied live connector. Optional live mode requires a repository-scoped GitHub credential held by the trusted server and an exact repository allowlist. Follow the live GitHub guide inside the archive; keep write credentials out of the agent process.&lt;/p&gt;

&lt;p&gt;An owner-guided direct-token test created a real GitHub issue and rejected a repeated execution. An independent customer's setup has not yet been validated.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you get for $49
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://temoode.gumroad.com/l/tkbmjk" rel="noopener noreferrer"&gt;Buy the internal-use license on Gumroad: $49 once&lt;/a&gt;.&lt;/strong&gt; Applicable checkout taxes may be added.&lt;/p&gt;

&lt;p&gt;The download includes the local software kit, SDK, examples, setup guides and a license for ongoing internal use of the purchased version by one organization, within the supplied single-host Node.js/GitHub issue workflow.&lt;/p&gt;

&lt;p&gt;The free evaluation and paid edition use the same runtime. The evaluation license permits local testing; payment grants ongoing internal-use rights. There is no hidden feature unlock. This is proprietary software, not an open-source framework.&lt;/p&gt;

&lt;p&gt;Hosting, custom integration, a production SLA and future updates are not included. Read the license and product description before buying. The intellectual property remains with its owner.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limits to check before using it
&lt;/h2&gt;

&lt;p&gt;An agent with independent GitHub write credentials or access to operator secrets can bypass the gate. Separate OS permissions are necessary; this kit does not provide that isolation for you.&lt;/p&gt;

&lt;p&gt;Local state and audit writes are separate, and GitHub is not part of an atomic transaction. A timeout may mean an issue already exists. Uncertain outcomes need reconciliation, not automatic retries. There is no exactly-once guarantee.&lt;/p&gt;

&lt;p&gt;The signed local audit trail depends on protecting its signing key. It is not independent external custody or certified compliance evidence.&lt;/p&gt;

&lt;p&gt;This kit is not a general prompt-injection defense, MCP firewall or approval layer for arbitrary tools. If your framework's existing approval controls already cover your needs, use them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next step: &lt;a href="https://preflight-action-gate.temoode32.chatgpt.site/?source=dev-showdev#availability" rel="noopener noreferrer"&gt;run the free evaluation&lt;/a&gt;. If the workflow fits your internal use, the &lt;a href="https://temoode.gumroad.com/l/tkbmjk" rel="noopener noreferrer"&gt;one-time license is available here&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>node</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
