<?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: Ammar</title>
    <description>The latest articles on DEV Community by Ammar (@ammarti).</description>
    <link>https://dev.to/ammarti</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%2F68337%2Fe359c9b6-833d-4002-a2c5-1ccc0700e851.jpeg</url>
      <title>DEV Community: Ammar</title>
      <link>https://dev.to/ammarti</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ammarti"/>
    <language>en</language>
    <item>
      <title>Your Agent Pipeline's Review Gate Should Be Code, Not a Prompt Convention</title>
      <dc:creator>Ammar</dc:creator>
      <pubDate>Tue, 25 Aug 2026 19:18:30 +0000</pubDate>
      <link>https://dev.to/ammarti/your-agent-pipelines-review-gate-should-be-code-not-a-prompt-convention-4pem</link>
      <guid>https://dev.to/ammarti/your-agent-pipelines-review-gate-should-be-code-not-a-prompt-convention-4pem</guid>
      <description>&lt;h1&gt;
  
  
  Your Agent Pipeline's Review Gate Should Be Code, Not a Prompt Convention
&lt;/h1&gt;

&lt;p&gt;ZOdyssey is a code-enforced orchestration pipeline for ZCode (for now — the pattern is harness-portable), and its center of gravity is not dispatch: it is getting the &lt;em&gt;plan&lt;/em&gt; right before any code moves. Acceptance criteria are executable and confirmed with the user; a plan-linted, nonce-bound review verdict is the only key that unlocks product code. Every code block below is quoted from the repo, with its source lines named.&lt;/p&gt;

&lt;p&gt;The pipeline shape is not the news — orchestrators already share it, learned from omo and credited. The news is that most leave planning and review as prompt conventions: the model is &lt;em&gt;told&lt;/em&gt; to plan carefully and not to edit before review passes, but nothing actually stops it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6ctvpc75dcyuk7wf51sp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6ctvpc75dcyuk7wf51sp.png" alt="ZOdyssey 8-phase pipeline: REVIEW is the enforced gate before EXECUTE" width="785" height="2115"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The 8-phase pipeline. The REVIEW node is the only door to EXECUTE — and the hook, not the prompt, holds it shut.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The failure that motivated it: a gate deleted twice
&lt;/h2&gt;

&lt;p&gt;The roadmap is blunt: the Bash write-gate was deleted twice — v0.2.0 replaced 170 lines with &lt;code&gt;if (isBash) exit(0);&lt;/code&gt; — and three independent external audits missed it (docs/ROADMAP.md:22-25). Audits verify the diff in front of them; none re-checks an invariant established two releases earlier (docs/ROADMAP.md:27-28).&lt;/p&gt;

&lt;p&gt;The regression suite now carries its justification in its header — skills/odyssey/hooks/pre-tool.bash-gate.test.mjs:4-17:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// WHY THIS FILE EXISTS: the Bash gate has been silently deleted TWICE.&lt;/span&gt;
&lt;span class="c1"&gt;//   v0.1.1 (5c99927) shipped it deleted — the author's local ZODYSSEY_UNGATE_BASH=1 copy was&lt;/span&gt;
&lt;span class="c1"&gt;//                    mirrored to the public repo verbatim.&lt;/span&gt;
&lt;span class="c1"&gt;//   v0.1.2 (433c037) restored it and wrote a public post-mortem.&lt;/span&gt;
&lt;span class="c1"&gt;//   v0.2.0 (e57b01b) deleted it AGAIN (-170 lines -&amp;gt; `if (isBash) exit(0);`), and three&lt;/span&gt;
&lt;span class="c1"&gt;//                    independent external audits did not notice, because each audit reviews the&lt;/span&gt;
&lt;span class="c1"&gt;//                    diff in front of it and none re-checks an invariant established two&lt;/span&gt;
&lt;span class="c1"&gt;//                    releases earlier.&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;// Audits verify that code matches its documentation locally. They are not a regression suite.&lt;/span&gt;
&lt;span class="c1"&gt;// This is the regression suite. If the gate is removed a third time, this file fails.&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;// Every assertion below is an invariant the README/DESIGN.md already CLAIM. Nothing here is new&lt;/span&gt;
&lt;span class="c1"&gt;// policy — it is the existing promises, made executable.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The pipeline is the part you already know
&lt;/h2&gt;

&lt;p&gt;Eight phases, nothing exotic, quoted from the README (README.md:82-91):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  -1  PRIME        prompt-master refines the raw task into a sharp brief;
                    measurable criteria get ONE user-confirmation round (never blocks)
   0  TRIAGE       trivial → just answer; standard → single-track; architecture → full pipeline
   1  CONSULT      metis classifies intent, surfaces questions/risks
   2  PLAN         prometheus writes &amp;lt;repo&amp;gt;/.zcode/plans/&amp;lt;slug&amp;gt;.md  (cannot edit product code)
   3  REVIEW       momus returns OKAY | REJECT + blockers   ←  THE ENFORCED GATE
   4  EXECUTE      sisyphus-junior per todo, parallel-by-default, scope-locked to the plan's Files:
   5  VERIFY       run each todo's executable acceptance criteria
      automatic   compact.mjs — fires at final entry for large runs; F1–F5 consume a brief, not the full doc set
   6  FINAL WAVE   F1 plan-compliance · F2 code-quality · F3 manual-QA · F4 scope-fidelity · F5 capability-routing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The delta is phase 3: elsewhere "momus returns OKAY" is an instruction; here it is a state field the hook reads.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accurate plans come before enforcement
&lt;/h2&gt;

&lt;p&gt;Everything upstream of review exists to make the plan &lt;em&gt;accurate&lt;/em&gt;, not just reviewed. In PRIME, measurable criteria get one user-confirmation round before planning starts. The plan is then linted by &lt;code&gt;scripts/parse-plan.mjs&lt;/code&gt; (DESIGN.md:445), and the review dispatch is gated on an evidence chain — nonce → momus-artifact → plan-sha → lint → verdict (docs/DESIGN.md:456). The verdict is nonce-bound to the exact reviewer dispatch, so it is unforgeable; REJECT loops are bounded (&lt;code&gt;max_rounds&lt;/code&gt;, default 3).&lt;/p&gt;

&lt;p&gt;Downstream, verification is not a claim: &lt;code&gt;record-verify&lt;/code&gt; executes each todo's acceptance criteria and records evidence per criterion; &lt;code&gt;record-todo&lt;/code&gt; refuses &lt;code&gt;done&lt;/code&gt; without those passing records (README.md:139). On its own launch: this run was REJECTED in round 1 — an invalid branch name and a diff-grep bug in one acceptance criterion — and 83 criteria were executed and recorded as evidence (.zcode/state/launch-v0-7-3.json).&lt;/p&gt;

&lt;h2&gt;
  
  
  What the hook actually checks
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuild7ssmyy8r7uomoj0m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuild7ssmyy8r7uomoj0m.png" alt="PreToolUse hook decision tree: first match wins, every other branch blocks" width="800" height="893"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The PreToolUse decision tree: first match wins, every other branch blocks.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The gate is a PreToolUse hook (skills/odyssey/hooks/pre-tool.mjs) reading state.json and the tool-call payload, blocking calls that would break an invariant — the review gate itself, pre-tool.mjs:876-884:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// Outside PROJECT_DIR entirely and not bookkeeping → treat as product code (gated).&lt;/span&gt;
  &lt;span class="c1"&gt;// Review gate: product-code edits require verdict == OKAY.&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;review&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;verdict&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;OKAY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;block&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="s2"&gt;`edits to product code are blocked until the plan passes review `&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
        &lt;span class="s2"&gt;`(current verdict: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;review&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;verdict&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, round &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;review&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;round&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;review&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;max_rounds&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;). `&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
        &lt;span class="s2"&gt;`Complete the review phase first. (slug=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the verdict is OKAY, supporting invariants take over: executors edit only the plan's &lt;code&gt;Files:&lt;/code&gt; union, fail-closed on unreadable plans (README.md:130); dispatches are ledger-counted, capped at 4 (README.md:132); write-capable Bash is gated like Edit (README.md:133).&lt;/p&gt;

&lt;p&gt;The subtle one is self-modification: the plan lives under &lt;code&gt;.zcode/plans/&lt;/code&gt;, agent-writable bookkeeping, so an executor could widen its scope by editing the plan after the verdict. An external audit (SEC-4) closed that — pre-tool.mjs:916-927 re-hashes the plan against the sha bound to the OKAY verdict; drift blocks the edit, and a plan edit must re-run review to re-bind the sha:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;boundSha&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;review&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;review&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;plan_sha256&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;boundSha&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;diskSha&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sha256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;planText&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;diskSha&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;boundSha&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nf"&gt;block&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s2"&gt;`PLAN TAMPERED: the on-disk plan (&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;planPath&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;) no longer matches the plan-sha bound to `&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s2"&gt;`the OKAY verdict (expected &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;boundSha&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;, got &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;diskSha&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;). `&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s2"&gt;`.zcode/plans/ is writable, so scope must be re-authorized by re-running momus + `&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s2"&gt;`record-review (which re-binds the sha). (slug=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;
          &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verdicts are read from the artifact, not assumed — ambiguous or absent fails (README.md:135). All of it is inert in normal editing: hooks are NO-OP unless a run is active (README.md:167).&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentation that fails the suite
&lt;/h2&gt;

&lt;p&gt;Documentation is lock-pinned too: every &lt;code&gt;file:line&lt;/code&gt; is range-checked and content-pinned in scripts/anchors.lock.json — 743 citations across 68 documents (README.md:143) — so a drifted anchor fails &lt;code&gt;npm test&lt;/code&gt;. The tool, scripts/check-anchors.mjs:46-49:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Usage:
//   check-anchors.mjs [--root &amp;lt;dir&amp;gt;] [--json]        verify against the lock
//   check-anchors.mjs [--root &amp;lt;dir&amp;gt;] --update        deliberate re-baseline
//   exit: 0 clean · 2 bad args · 4 zero citations discovered · 9 problems found
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the stated limit, kept on purpose: the lock proves &lt;em&gt;unchanged since seeding&lt;/em&gt;, never &lt;em&gt;correct&lt;/em&gt; (README.md:143).&lt;/p&gt;

&lt;h2&gt;
  
  
  The limits we kept on purpose
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The self-grading loop.&lt;/strong&gt; Absent the opt-in post-&lt;code&gt;done&lt;/code&gt; &lt;code&gt;/orchestrate-consult&lt;/code&gt;, the pipeline writes and grades its own exam (docs/ROADMAP.md:51-54).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The disarm window.&lt;/strong&gt; Hooks disarm during consult remediation because &lt;code&gt;done&lt;/code&gt; is terminal; &lt;code&gt;phase: "remediate"&lt;/code&gt; re-arms them (docs/DESIGN.md:298-302).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"What it is NOT."&lt;/strong&gt; A standing README section: not a replacement for normal agent operation, not multi-model, not harness-agnostic, not team-mode in v1 (README.md:253-258).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Registry inaction.&lt;/strong&gt; The reviewer-reliability registry flags an unreliable config at n=9; nothing acts on it (README.md:316).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model-routing honesty.&lt;/strong&gt; "It routes models, not agents" — one connected model in v1 (docs/DESIGN.md:356-359).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An orchestration layer that promised enforcement it did not have would repeat the failure that motivated it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the new version adds
&lt;/h2&gt;

&lt;p&gt;One thing: the external auditor's read-only window is verified, not promised. Every spawn window records a tri-state &lt;code&gt;readOnlyViolation&lt;/code&gt; — &lt;code&gt;true&lt;/code&gt; on any work-path change or HEAD move, &lt;code&gt;null&lt;/code&gt; fail-closed on unreadable git (README.md:152; CHANGELOG.md:7-12).&lt;/p&gt;

&lt;p&gt;Status, stated honestly: the changelog entry is dated 2026-08-24, but the newest tag is still v0.7.2 — available on GitHub, not a shipped release.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8u3ugp8kdc2dpj6faga4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8u3ugp8kdc2dpj6faga4.png" alt="Evidence a closed run leaves behind: plan, verdict, criteria, run report" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What a closed run leaves behind: plan, nonce-bound verdict, executed criteria, run report.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to look
&lt;/h2&gt;

&lt;p&gt;Repository: &lt;a href="https://github.com/amartinawi/zodyssey" rel="noopener noreferrer"&gt;https://github.com/amartinawi/zodyssey&lt;/a&gt;. docs/DESIGN.md carries the enforcement principle and state model; docs/ADAPT.md covers porting the delta to other hook-capable orchestrators. The gate is skills/odyssey/hooks/pre-tool.mjs — for ZCode, for now — crib freely.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>testing</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
