diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,16 @@
 
 ## [Unreleased]
 
+## 0.21.0.0 — 2026-10-14
+
+### Bug Fixes
+
+- Schema verification no longer warns about, or refuses mutations because of, the
+  `keiro.external_read_<function>_binding` view that Keiro creates for an all-rows
+  external-read contract. Binding views recorded with `managed_by = 'keiro'` are allowed runtime
+  additions when verification can read the registry; `--allow-schema-drift` is again reserved for schemas this
+  binary was not built for. Fixed in `keiro-migrations`; no `keiro-ops` source change.
+
 ## 0.20.0.0 — 2026-10-12
 
 ### Breaking Changes
diff --git a/keiro-ops.cabal b/keiro-ops.cabal
--- a/keiro-ops.cabal
+++ b/keiro-ops.cabal
@@ -1,6 +1,6 @@
 cabal-version: 3.0
 name: keiro-ops
-version: 0.20.0.0
+version: 0.21.0.0
 synopsis: Operational command-line interface for Keiro deployments
 description:
   A standalone database-only console and embeddable command tree for inspecting
@@ -73,9 +73,9 @@
     effectful >=2.6 && <2.8,
     effectful-core >=2.6 && <2.7 || >=2.7.1.1 && <2.8,
     hasql >=1.10 && <1.11,
-    keiro ^>=0.20.0.0,
-    keiro-migrations ^>=0.20.0.0,
-    keiro-pgmq ^>=0.20.0.0,
+    keiro ^>=0.21.0.0,
+    keiro-migrations ^>=0.21.0.0,
+    keiro-pgmq ^>=0.21.0.0,
     kiroku-store ^>=0.11.0.0,
     optparse-applicative >=0.18 && <0.20,
     text >=2.1 && <2.2,
@@ -117,10 +117,10 @@
     hasql >=1.10 && <1.11,
     hasql-transaction >=1.1 && <1.3,
     hspec >=2.11,
-    keiro ^>=0.20.0.0,
+    keiro ^>=0.21.0.0,
     keiro-ops,
-    keiro-pgmq ^>=0.20.0.0,
-    keiro-test-support ^>=0.20.0.0,
+    keiro-pgmq ^>=0.21.0.0,
+    keiro-test-support ^>=0.21.0.0,
     kiroku-store ^>=0.11.0.0,
     optparse-applicative >=0.18 && <0.20,
     pgmq-migration >=0.6.1.1 && <0.7,
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE MultilineStrings #-}
+
 module Main (main) where
 
 import Control.Exception (bracket)
@@ -751,6 +753,45 @@
           ""
       mutationExit `shouldBe` ExitFailure 1
       mutationError `shouldSatisfy` Text.isInfixOf "refusing mutation" . Text.pack
+
+    it "does not treat a registered binding view as schema drift" $ \connectionString -> do
+      executable <- keiroOpsExecutable
+      executeSql
+        connectionString
+        """
+        CREATE VIEW keiro.external_read_demo_v1_binding
+          WITH (security_barrier = true, security_invoker = false)
+          AS SELECT 1::bigint AS id, 10::bigint AS total;
+        INSERT INTO keiro.keiro_managed_read_objects
+          (object_schema, object_name, object_kind, object_signature,
+           managed_by, definition_hash, surface_generation, state)
+        VALUES ('keiro', 'external_read_demo_v1_binding', 'binding-view', '',
+                'keiro', 'test-definition', 1, 'active');
+        """
+      (listExit, _, listError) <-
+        readProcessWithExitCode
+          executable
+          ["--database-url", Text.unpack connectionString, "wf", "list", "--json"]
+          ""
+      listExit `shouldBe` ExitSuccess
+      listError `shouldBe` ""
+      (mutationExit, _, mutationError) <-
+        readProcessWithExitCode
+          executable
+          [ "--database-url",
+            Text.unpack connectionString,
+            "wf",
+            "gc",
+            "run-once",
+            "--retention",
+            "0s",
+            "--force",
+            "--json"
+          ]
+          ""
+      mutationExit `shouldBe` ExitSuccess
+      mutationError `shouldSatisfy` not . Text.isInfixOf "schema drift" . Text.pack
+      mutationError `shouldSatisfy` not . Text.isInfixOf "refusing mutation" . Text.pack
 
   describe "workflow handlers" $ around (withFreshStore fixture) do
     it "previews and runs one bounded application-registry resume pass" $ \store -> do
