Align verified retry nudges with visible tools

ober

fbb6007bd6096d8be50e717db56735964d9409ae

diff --git a/src/jcode/core/workflow-runner.ss b/src/jcode/core/workflow-runner.ss
index 9361722..bffe634 100644
--- a/src/jcode/core/workflow-runner.ss
+++ b/src/jcode/core/workflow-runner.ss
@@ -418,16 +418,38 @@
        (verified-workflow? workflow)
        (not (forced-first-edit-retry? content))))
 
-(def (forced-first-edit-retry-message)
-  (string-append
-    "VERIFIED WORKFLOW REQUIRES A STRUCTURED TOOL CALL NOW. "
-    "The previous turn attempted a hidden inspection while only edit/write "
-    "were available. The original system prompt tool list is superseded for "
-    "this turn; read, list, balance, verify, done, shell, MCP, and every "
-    "other non-edit/write tool are unavailable right now. Do not explain, "
-    "summarize, or ask questions. Next response must be exactly one "
-    "structured edit(path=<scoped target file>, content=<complete file>) or "
-    "write(path=<scoped target file>, content=<complete file>) tool call."))
+(def (forced-first-edit-next-tool-text visible-tool-names)
+  (let ((names (if (pair? visible-tool-names) visible-tool-names '())))
+    (cond
+      ((and (member "edit" names) (member "write" names))
+       "Next response should be one structured edit(...) or write(...) tool call.")
+      ((member "line_edit" names)
+       "Next response should repair the reported span with line_edit(...) or another available structured repair tool.")
+      ((member "balance" names)
+       "Next response should be one structured balance(path=\"...\") call if the reported span is ambiguous.")
+      ((pair? names)
+       (string-append
+         "Next response must use one currently available structured tool: "
+         (string-join names ", ")
+         "."))
+      (else
+       "Next response must be exactly one valid structured tool call."))))
+
+(def (forced-first-edit-retry-message visible-tool-names)
+  (let ((names (if (pair? visible-tool-names) visible-tool-names '())))
+    (string-append
+      "VERIFIED WORKFLOW REQUIRES A STRUCTURED TOOL CALL NOW. "
+      "The previous turn attempted prose or a hidden/unavailable action instead "
+      "of a valid structured tool call. The original system prompt tool list is "
+      "superseded for this turn. "
+      (if (pair? names)
+        (string-append
+          "Currently available structured tools: "
+          (string-join names ", ")
+          ". Do not call tools outside this list. ")
+        "")
+      "Do not explain, summarize, or ask questions. "
+      (forced-first-edit-next-tool-text names))))
 
 (def (verified-text-retry-message workflow enforcer messages raw retry-count)
   (let* ((completed (step-enforcer-completed enforcer))
@@ -621,7 +643,8 @@
 	                          content))
 	                      (emit! (make-user-message
 	                               (if forced-first-edit-retry
-                                     (forced-first-edit-retry-message)
+                                     (forced-first-edit-retry-message
+                                       (tool-spec-name-list visible-tool-specs))
 	                                 (text-retry-message
 	                                   workflow enforcer messages content
                                    (error-tracker-consecutive-retries
diff --git a/test/run.ss b/test/run.ss
index aa91524..d705c91 100644
--- a/test/run.ss
+++ b/test/run.ss
@@ -1592,7 +1592,9 @@
                 (str-contains? (message-content (car ys))
                                "original system prompt tool list is superseded")
                 (str-contains? (message-content (car ys))
-                               "every other non-edit/write tool are unavailable"))
+                               "Currently available structured tools: search, lookup, answer")
+                (not (str-contains? (message-content (car ys))
+                                    "non-edit/write tool are unavailable")))
            #t]
           [else (loop (cdr ys))])))))
 
@@ -6841,7 +6843,7 @@
                    #t]
                   [else (loop (cdr xs))]))
               #f)
-      (check-pred! "verified-run: forced first-edit retry recommends edit only"
+      (check-pred! "verified-run: forced first-edit retry names visible edit tools"
         seen-messages
         (lambda (xs)
           (let loop ([ys xs])
@@ -6849,9 +6851,13 @@
               [(null? ys) #f]
               [(and (equal? (message-role (car ys)) "user")
                     (str-contains? (message-content (car ys))
-                                   "only edit/write")
+                                   "Currently available structured tools:")
                     (str-contains? (message-content (car ys))
-                                   "one structured edit")
+                                   "edit, write")
+                    (str-contains? (message-content (car ys))
+                                   "edit(...) or write(...)")
+                    (not (str-contains? (message-content (car ys))
+                                        "only edit/write"))
                     (not (str-contains? (message-content (car ys))
                                         "Invalid previous text excerpt")))
                #t]