Stop the coder crashing, confabulating, and calling failures successes
Five defects a live-execution audit found by driving the agent rather than
reading it (openagents#89).
**A panic that killed the process.** `tools.rs` bounded tool output with
`&combined[..OUTPUT_LIMIT]`, a byte index into a `String`. The first time a
command printed a non-ASCII character straddling byte 30,000 the slice panicked
and took the whole agent with it, before the thread could be revoked. Any `git
log`, test run, or accented file past 30 kB did it. It steps back to a
character boundary now.
**The model could not see what it said.** `run_tools` records an assistant turn
only when that turn called a tool, so a turn that simply answered never joined
`self.messages` — and the session is reused across turns. Asked in turn two
what it said in turn one, it confabulated: "invent a codeword" gave QORVEN,
"what was the codeword?" gave ZORBEX. The answer is recorded now, in both the
hosted and the local loop.
**Exhausting the step budget returned success.** `final_answer` was assigned
only on a step with no tool calls, so thirty tool-calling steps fell out of the
loop and returned `Ok("")` — printed as `Turn result:` and a blank line, exit 0.
It refuses instead.
**Failed tools were reported as successes.** Every `shell` and `openagents`
result carried `is_error: false`, including a non-zero exit, a timeout, and a
CLI that could not be spawned, so a failing build read like a passing one and
the model carried on. Both helpers return the outcome with the text now.
**A cancelled fan-out orphaned its shell commands.** The `/bin/sh` spawn had no
process group, so the shell's children survived and reparented to init;
`delegate.rs`, `computer.rs` and `acp.rs` all already did this and `tools.rs`
was the exception. It gets `process_group(0)` and `kill_on_drop`.
Each fix has a test that fails against the old behaviour, verified by reverting
the fix and watching it fail — including the confabulation one, which asserts
the second turn's request body carries the first turn's answer. A test that
asked the model to recall something from the *user's* prompt would have passed
against the defect, because user messages were always recorded.
Stop the coder crashing, confabulating, and calling failures successes
Deploy story
What this commit did to the running system — joined from the forge receipt chain, the part a commit page elsewhere cannot show.
Not deployed through the forge lane
No push, promotion, build, or deploy receipt references this commit (receipts are scanned over a bounded recent window). Changes shipped by full node replacement carry their proof in the release gate receipt instead.
Changed files
-
modified
crates/openagents-cli/src/runtime.rs -
modified
crates/openagents-cli/src/tools.rs -
modified
crates/openagents-cli/tests/runtime_test.rs
Diff
3 files changed, +234 -17
crates/openagents-cli/src/runtime.rs modified +56
@@ -742,6 +742,9 @@ impl CoderRuntimeSession {
| 742 | 742 |
|
| 743 | 743 |
|
| 744 | 744 |
|
| 745 |
|
|
| 746 |
|
|
| 747 |
|
|
| 745 | 748 |
|
| 746 | 749 |
|
| 747 | 750 |
|
@@ -822,11 +825,36 @@ impl CoderRuntimeSession {
| 822 | 825 |
|
| 823 | 826 |
|
| 824 | 827 |
|
| 828 |
|
|
| 829 |
|
|
| 830 |
|
|
| 831 |
|
|
| 832 |
|
|
| 833 |
|
|
| 834 |
|
|
| 835 |
|
|
| 836 |
|
|
| 837 |
|
|
| 838 |
|
|
| 839 |
|
|
| 840 |
|
|
| 841 |
|
|
| 842 |
|
|
| 843 |
|
|
| 844 |
|
|
| 845 |
|
|
| 825 | 846 |
|
| 826 | 847 |
|
| 827 | 848 |
|
| 828 | 849 |
|
| 829 | 850 |
|
| 851 |
|
|
| 852 |
|
|
| 853 |
|
|
| 854 |
|
|
| 855 |
|
|
| 856 |
|
|
| 857 |
|
|
| 830 | 858 |
|
| 831 | 859 |
|
| 832 | 860 |
|
@@ -973,6 +1001,9 @@ impl CoderRuntimeSession {
| 973 | 1001 |
|
| 974 | 1002 |
|
| 975 | 1003 |
|
| 1004 |
|
|
| 1005 |
|
|
| 1006 |
|
|
| 976 | 1007 |
|
| 977 | 1008 |
|
| 978 | 1009 |
|
@@ -1036,11 +1067,36 @@ impl CoderRuntimeSession {
| 1036 | 1067 |
|
| 1037 | 1068 |
|
| 1038 | 1069 |
|
| 1070 |
|
|
| 1071 |
|
|
| 1072 |
|
|
| 1073 |
|
|
| 1074 |
|
|
| 1075 |
|
|
| 1076 |
|
|
| 1077 |
|
|
| 1078 |
|
|
| 1079 |
|
|
| 1080 |
|
|
| 1081 |
|
|
| 1082 |
|
|
| 1083 |
|
|
| 1084 |
|
|
| 1085 |
|
|
| 1086 |
|
|
| 1087 |
|
|
| 1039 | 1088 |
|
| 1040 | 1089 |
|
| 1041 | 1090 |
|
| 1042 | 1091 |
|
| 1043 | 1092 |
|
| 1093 |
|
|
| 1094 |
|
|
| 1095 |
|
|
| 1096 |
|
|
| 1097 |
|
|
| 1098 |
|
|
| 1099 |
|
|
| 1044 | 1100 |
|
| 1045 | 1101 |
|
| 1046 | 1102 |
|
crates/openagents-cli/src/tools.rs modified +123 -17
@@ -36,6 +36,26 @@ use crate::plugins::{
| 36 | 36 |
|
| 37 | 37 |
|
| 38 | 38 |
|
| 39 |
|
|
| 40 |
|
|
| 41 |
|
|
| 42 |
|
|
| 43 |
|
|
| 44 |
|
|
| 45 |
|
|
| 46 |
|
|
| 47 |
|
|
| 48 |
|
|
| 49 |
|
|
| 50 |
|
|
| 51 |
|
|
| 52 |
|
|
| 53 |
|
|
| 54 |
|
|
| 55 |
|
|
| 56 |
|
|
| 57 |
|
|
| 58 |
|
|
| 39 | 59 |
|
| 40 | 60 |
|
| 41 | 61 |
|
@@ -373,11 +393,11 @@ impl HarnessToolRegistry {
| 373 | 393 |
|
| 374 | 394 |
|
| 375 | 395 |
|
| 376 |
|
|
| 396 |
|
|
| 377 | 397 |
|
| 378 | 398 |
|
| 379 | 399 |
|
| 380 |
|
|
| 400 |
|
|
| 381 | 401 |
|
| 382 | 402 |
|
| 383 | 403 |
|
@@ -402,11 +422,11 @@ impl HarnessToolRegistry {
| 402 | 422 |
|
| 403 | 423 |
|
| 404 | 424 |
|
| 405 |
|
|
| 425 |
|
|
| 406 | 426 |
|
| 407 | 427 |
|
| 408 | 428 |
|
| 409 |
|
|
| 429 |
|
|
| 410 | 430 |
|
| 411 | 431 |
|
| 412 | 432 |
|
@@ -770,17 +790,30 @@ pub fn check_shell_refusal(cmd: &str) -> Option<String> {
| 770 | 790 |
|
| 771 | 791 |
|
| 772 | 792 |
|
| 773 |
|
|
| 774 |
|
|
| 793 |
|
|
| 794 |
|
|
| 795 |
|
|
| 796 |
|
|
| 797 |
|
|
| 798 |
|
|
| 799 |
|
|
| 800 |
|
|
| 775 | 801 |
|
| 776 | 802 |
|
| 777 | 803 |
|
| 778 | 804 |
|
| 779 | 805 |
|
| 780 |
|
|
| 806 |
|
|
| 807 |
|
|
| 808 |
|
|
| 809 |
|
|
| 810 |
|
|
| 811 |
|
|
| 812 |
|
|
| 813 |
|
|
| 781 | 814 |
|
| 782 | 815 |
|
| 783 |
|
|
| 816 |
|
|
| 784 | 817 |
|
| 785 | 818 |
|
| 786 | 819 |
|
@@ -792,28 +825,41 @@ async fn run_real_shell(cmd: &str, cwd: &Path, timeout_secs: u64) -> String {
| 792 | 825 |
|
| 793 | 826 |
|
| 794 | 827 |
|
| 795 |
|
|
| 828 |
|
|
| 829 |
|
|
| 830 |
|
|
| 831 |
|
|
| 832 |
|
|
| 833 |
|
|
| 796 | 834 |
|
| 797 | 835 |
|
| 798 | 836 |
|
| 799 | 837 |
|
| 800 | 838 |
|
| 801 | 839 |
|
| 802 |
|
|
| 840 |
|
|
| 803 | 841 |
|
| 804 |
|
|
| 842 |
|
|
| 805 | 843 |
|
| 806 | 844 |
|
| 807 | 845 |
|
| 808 |
|
|
| 846 |
|
|
| 847 |
|
|
| 848 |
|
|
| 849 |
|
|
| 809 | 850 |
|
| 810 | 851 |
|
| 811 |
|
|
| 812 |
|
|
| 852 |
|
|
| 853 |
|
|
| 854 |
|
|
| 855 |
|
|
| 856 |
|
|
| 813 | 857 |
|
| 814 | 858 |
|
| 815 | 859 |
|
| 816 |
|
|
| 860 |
|
|
| 861 |
|
|
| 862 |
|
|
| 817 | 863 |
|
| 818 | 864 |
|
| 819 | 865 |
|
@@ -824,9 +870,9 @@ async fn run_openagents_cli(args: &[String]) -> String {
| 824 | 870 |
|
| 825 | 871 |
|
| 826 | 872 |
|
| 827 |
|
|
| 873 |
|
|
| 828 | 874 |
|
| 829 |
|
|
| 875 |
|
|
| 830 | 876 |
|
| 831 | 877 |
|
| 832 | 878 |
|
@@ -1181,3 +1227,63 @@ mod tests {
| 1181 | 1227 |
|
| 1182 | 1228 |
|
| 1183 | 1229 |
|
| 1230 |
|
|
| 1231 |
|
|
| 1232 |
|
|
| 1233 |
|
|
| 1234 |
|
|
| 1235 |
|
|
| 1236 |
|
|
| 1237 |
|
|
| 1238 |
|
|
| 1239 |
|
|
| 1240 |
|
|
| 1241 |
|
|
| 1242 |
|
|
| 1243 |
|
|
| 1244 |
|
|
| 1245 |
|
|
| 1246 |
|
|
| 1247 |
|
|
| 1248 |
|
|
| 1249 |
|
|
| 1250 |
|
|
| 1251 |
|
|
| 1252 |
|
|
| 1253 |
|
|
| 1254 |
|
|
| 1255 |
|
|
| 1256 |
|
|
| 1257 |
|
|
| 1258 |
|
|
| 1259 |
|
|
| 1260 |
|
|
| 1261 |
|
|
| 1262 |
|
|
| 1263 |
|
|
| 1264 |
|
|
| 1265 |
|
|
| 1266 |
|
|
| 1267 |
|
|
| 1268 |
|
|
| 1269 |
|
|
| 1270 |
|
|
| 1271 |
|
|
| 1272 |
|
|
| 1273 |
|
|
| 1274 |
|
|
| 1275 |
|
|
| 1276 |
|
|
| 1277 |
|
|
| 1278 |
|
|
| 1279 |
|
|
| 1280 |
|
|
| 1281 |
|
|
| 1282 |
|
|
| 1283 |
|
|
| 1284 |
|
|
| 1285 |
|
|
| 1286 |
|
|
| 1287 |
|
|
| 1288 |
|
|
| 1289 |
|
crates/openagents-cli/tests/runtime_test.rs modified +55
@@ -874,3 +874,58 @@ async fn the_local_lane_runs_tools_and_feeds_the_result_back() {
| 874 | 874 |
|
| 875 | 875 |
|
| 876 | 876 |
|
| 877 |
|
|
| 878 |
|
|
| 879 |
|
|
| 880 |
|
|
| 881 |
|
|
| 882 |
|
|
| 883 |
|
|
| 884 |
|
|
| 885 |
|
|
| 886 |
|
|
| 887 |
|
|
| 888 |
|
|
| 889 |
|
|
| 890 |
|
|
| 891 |
|
|
| 892 |
|
|
| 893 |
|
|
| 894 |
|
|
| 895 |
|
|
| 896 |
|
|
| 897 |
|
|
| 898 |
|
|
| 899 |
|
|
| 900 |
|
|
| 901 |
|
|
| 902 |
|
|
| 903 |
|
|
| 904 |
|
|
| 905 |
|
|
| 906 |
|
|
| 907 |
|
|
| 908 |
|
|
| 909 |
|
|
| 910 |
|
|
| 911 |
|
|
| 912 |
|
|
| 913 |
|
|
| 914 |
|
|
| 915 |
|
|
| 916 |
|
|
| 917 |
|
|
| 918 |
|
|
| 919 |
|
|
| 920 |
|
|
| 921 |
|
|
| 922 |
|
|
| 923 |
|
|
| 924 |
|
|
| 925 |
|
|
| 926 |
|
|
| 927 |
|
|
| 928 |
|
|
| 929 |
|
|
| 930 |
|
|
| 931 |
|