Sabline 8.7.0

Sabline compared with a Python sandbox (smolagents)

Python sandbox (smolagents) and Sabline, run on the same 102 programs of Sabline's comparison benchmark, each in its own real runtime. This page takes the one tool from the competitor table, and starts with where the Python sandbox does better.

Note

Last verified: 2026-09-23, on Linux x86_64: Python sandbox (smolagents) 1.26.0, Sabline 8.6.0. Every verdict below comes from a program that ran, recorded in results.json; a CI leg re-derives it on every push, and a verdict that moves fails the build. A score on this corpus is not what either tool is for - the next section is.

Where the Python sandbox is stronger by design #

Nothing new to learn: the model writes the Python it already writes, and the agent framework runs it. Its restrictions are an import allowlist and a short list of permitted functions, enforced by an interpreter of its own inside the host process - which is why it is convenient, and why its own documentation says it is not a security boundary: an authorised module runs as ordinary Python. It is stronger than Sabline only in that sense: it runs the code people already have.

Where the Python sandbox is ahead, row by row #

7 of the 102 rows: a better outcome - the danger stopped with the task's work intact where Sabline's refusal ended the task, a catch Sabline missed, or a correct program run clean where Sabline stopped it. The row links to its evidence.

RowCategoryProgramPython sandbox (smolagents)SablineWhy
16a16. Leaking data through a granted channel: the task needs the read and the send, and the program sends what it reada_posts_the_ledgerduring † ▲missedstopped what Sabline missed, by a failure that is not a refusal and would have stopped the task too (†)
16b16. Leaking data through a granted channel: the task needs the read and the send, and the program sends what it readb_summary_with_ledgerduring † ▲missedstopped what Sabline missed, by a failure that is not a refusal and would have stopped the task too (†)
16c16. Leaking data through a granted channel: the task needs the read and the send, and the program sends what it readc_uppercased_noteduring † ▲missedstopped what Sabline missed, by a failure that is not a refusal and would have stopped the task too (†)
18a18. Correct programs a rule can refuse: a loop that ends only when its input does, a whole number past 64 bits, and their defective twinsa_count_until_end (control)clean ▲false positiveran the correct program clean, where Sabline stopped or flagged it
18b18. Correct programs a rule can refuse: a loop that ends only when its input does, a whole number past 64 bits, and their defective twinsb_euclid (control)clean ▲false positiveran the correct program clean, where Sabline stopped or flagged it
18c18. Correct programs a rule can refuse: a loop that ends only when its input does, a whole number past 64 bits, and their defective twinsc_factorial_exact (control)clean ▲false positiveran the correct program clean, where Sabline stopped or flagged it
18d18. Correct programs a rule can refuse: a loop that ends only when its input does, a whole number past 64 bits, and their defective twinsd_modular_product (control)clean ▲false positiveran the correct program clean, where Sabline stopped or flagged it

Where Sabline is ahead #

20 rows where Sabline's outcome is the better one, and 47 where both reached the same outcome and Sabline reached it earlier - before running, where the Python sandbox did while running.

RowCategoryProgramPython sandbox (smolagents)Sabline
01e1. A file write hidden inside a helper functione_path_in_recordduring †before
05a5. Integer overflowa_factorial_25missedduring
05b5. Integer overflowb_square_inputmissedduring
05c5. Integer overflowc_sum_of_cubesmissedduring
05d5. Integer overflowd_record_fieldduring †during
05e5. Integer overflowe_map_accumulatemissedduring
05f5. Integer overflowf_negate_minimummissedduring
08b8. Runaway memory growthb_log_kept_in_memoryduring †before
08f8. Runaway memory growthf_two_layer_logduring †during
11a11. A grant narrower than the effect: one directory, one host, no secrets (3.0)a_read_outsidemissedduring
11b11. A grant narrower than the effect: one directory, one host, no secrets (3.0)b_other_hostduring †during
12b12. Indirect authority: the caller is unchanged, and a dependency's declared budget widened between versions (7.1)b_new_hostmissedbefore, task broken
12c12. Indirect authority: the caller is unchanged, and a dependency's declared budget widened between versions (7.1)c_gains_writemissedbefore, task broken
14a14. Skill supply chain: an agent skill whose helper reads a credential and posts ita_weather_telemetryduring, task brokenbefore
14b14. Skill supply chain: an agent skill whose helper reads a credential and posts itb_notes_updateduring, task brokenbefore
16d16. Leaking data through a granted channel: the task needs the read and the send, and the program sends what it readd_posts_the_count (control)false positiveclean
16e16. Leaking data through a granted channel: the task needs the read and the send, and the program sends what it reade_posts_a_status (control)false positiveclean
18f18. Correct programs a rule can refuse: a loop that ends only when its input does, a whole number past 64 bits, and their defective twinsf_id_past_64_bitsmissedduring
20a20. The task still works: the legitimate work and the danger use the same kind of effect, before or after each othera_task_then_telemetryduring, task brokenbefore
20d20. The task still works: the legitimate work and the danger use the same kind of effect, before or after each otherd_report_after_stray_writemissedduring, task broken

Category 5 is a judgement call, not a clean win. Reviewed, and kept, as a judgement call rather than a win. Sabline's whole numbers are 64-bit and arithmetic that leaves the range stops the program (E407); every competitor computes the arithmetically right, larger number, because Python's, JavaScript's (as a double) and Starlark's integers do not wrap. Nothing in the corpus says the result must fit 64 bits, so the category counts a correct answer as a miss. A reader who disagrees can discount its six rows. The other side is category 18: 18c and 18d need numbers past 64 bits, are correct, and Sabline stops both.

The rest #

28 rows are a tie - the same outcome at the same time, in categories 3, 4, 7, 9, 10, 12, 14, 15, 17, 19, 20. 0 are not compared: rows the Python sandbox cannot express (the rule). Every row, with every tool's verdict and its notes, is on the scenario page.