Reduce local verified first-draft reasoning

ober

e12ddd8429f595a0b112ab88744d0567f178c4b9

diff --git a/src/jcode/core/verified-run.ss b/src/jcode/core/verified-run.ss
index 8c1141b..46a2ba4 100644
--- a/src/jcode/core/verified-run.ss
+++ b/src/jcode/core/verified-run.ss
@@ -7114,7 +7114,7 @@
 	            (number->string local-pre-edit-inspection-limit)
 	            " substantive read/shell/MCP inspections. Do not inspect external Jerboa sources unless one exact API fact blocks the implementation. Write the first complete draft within these budgets. After a failed verify, use at most "
 	            (number->string local-inspection-after-failed-verify-limit)
-	            " focused inspections before editing the diagnosed span. Code written in reasoning, analysis, markdown fences, or prose does not change files and will be discarded; put the implementation directly in an edit/write/line_edit/replace_def/replace_range tool call. For the first implementation draft, use one edit/write tool call with the complete file content instead of drafting the file in reasoning. For larger app/game/TUI tasks, write the smallest acceptance-complete vertical slice first: satisfy the verifier's required modes and source hooks, verify it, then add only behavior the verifier proves is missing. Local replace_range edits are transactional: a syntactically broken result is rejected and leaves the on-disk file unchanged.\n")
+	            " focused inspections before editing the diagnosed span. Code written in reasoning, analysis, markdown fences, or prose does not change files and will be discarded; put the implementation directly in an edit/write/line_edit/replace_def/replace_range tool call. For the first implementation draft, use one edit/write tool call with the complete file content instead of drafting the file in reasoning. If you need to plan, keep it brief and emit the edit/write tool call in the same response; a reasoning-only implementation turn makes no progress. For larger app/game/TUI tasks, write the smallest acceptance-complete vertical slice first: satisfy the verifier's required modes and source hooks, verify it, then add only behavior the verifier proves is missing. Local replace_range edits are transactional: a syntactically broken result is rejected and leaves the on-disk file unchanged.\n")
 	          "")
 	        (if run-aliases?
 	          (string-append
diff --git a/src/jcode/provider/provider.ss b/src/jcode/provider/provider.ss
index 83b1f37..a042804 100644
--- a/src/jcode/provider/provider.ss
+++ b/src/jcode/provider/provider.ss
@@ -1104,13 +1104,16 @@
         (when v (hash-put! body field v))))
     *openai-provider-request-fields*))
 
-(def (apply-local-forced-tool-overrides! body provider)
-  ;; Local reasoning models can spend a forced tool turn drafting code in
-  ;; reasoning_content before they emit the required function call. When jcode
-  ;; has already narrowed the schema and set tool_choice, ask for low reasoning
-  ;; effort unless the provider config made an explicit choice.
+(def (apply-local-verified-overrides! body provider)
+  ;; Local reasoning models can spend a forced tool turn or verified first
+  ;; draft drafting code in reasoning_content before they emit the required
+  ;; function call. Verified local runs bind current-max-tokens-floor/cap; use
+  ;; that as the provider-layer signal to keep reasoning short unless the
+  ;; provider config made an explicit choice.
   (when (and (local-provider? (provider-name provider))
-             (current-tool-choice-override)
+             (or (current-tool-choice-override)
+                 (current-max-tokens-floor)
+                 (current-max-tokens-cap))
              (not (hash-get body "reasoning_effort")))
     (hash-put! body "reasoning_effort" "low")))
 
@@ -1595,7 +1598,7 @@
     (hash-put! body "max_tokens" (openai-max-tokens provider))
     (apply-sampling-to-body! body (provider-model provider) (provider-name provider))
     (apply-openai-provider-overrides! body provider)
-    (apply-local-forced-tool-overrides! body provider)
+    (apply-local-verified-overrides! body provider)
     (maybe-apply-logprobs! body provider tools)
     (apply-prompt-cache-controls! body provider)
     (hash-put! body "messages" (map (lambda (m) (openai-message->json provider m)) messages))
@@ -2333,7 +2336,7 @@
     (hash-put! body "max_tokens" (openai-max-tokens provider))
     (apply-sampling-to-body! body (provider-model provider) (provider-name provider))
     (apply-openai-provider-overrides! body provider)
-    (apply-local-forced-tool-overrides! body provider)
+    (apply-local-verified-overrides! body provider)
     (maybe-apply-logprobs! body provider tools)
     (apply-prompt-cache-controls! body provider)
     ;; Request usage data in stream
diff --git a/test/run.ss b/test/run.ss
index d705c91..2757fb1 100644
--- a/test/run.ss
+++ b/test/run.ss
@@ -5024,6 +5024,12 @@
 	      (and (not (str-contains? s "External MCP tools are available"))
 	           (str-contains? s
 	             "MCP tools are unavailable in local-model verified sessions"))))
+	  (check-pred! "verified-run: local prompt forbids reasoning-only first draft"
+	    first-history
+	    (lambda (s)
+	      (and (str-contains? s "emit the edit/write tool call in the same response")
+	           (str-contains? s
+	             "a reasoning-only implementation turn makes no progress"))))
 	  (check-pred! "verified-run: stale local full rewrite is rejected"
 	    (reverse tool-results)
 	    (lambda (xs)
@@ -12696,7 +12702,9 @@
                   (provider-chat p (list (make-user-message "hi")) '()))]
              [req (vector-ref captured 0)])
         (check! "mlx local verified floor raises configured max_tokens"
-                (and req (str-contains? req "\"max_tokens\":8192")) #t)))
+                (and req (str-contains? req "\"max_tokens\":8192")) #t)
+        (check! "mlx local verified first draft defaults reasoning_effort low"
+                (and req (str-contains? req "\"reasoning_effort\":\"low\"")) #t)))
     (lambda ()
       (putenv "JCODE_MAX_TOKENS" (or old-max-tokens ""))
       (tcp-close srv))))