8,662 karma · joined March 18, 2011
Yet the powerful continue to insist on "papers, please" anonymity-rending personal authentication over anonymous authorization. It's not often that the villains of history so clearly identify themselves.
My bunch is that the people driving this stuff were unaware that age verification could be privacy-preserving and can't exactly back down now.
I don't know why everyone is acting like sandboxing tool uses is contrary to the laws of God and man and therefore we must adopt devcontainers and VMs and such to run agents.
... Sandboxes work JUST FINE. Seatbelt on macOS is okay. Namespaces/seccomp/etc. work on Linux even better. We already have all the technology we need to do the isolation people are talking about here, and Codex in particular has 99% of the code needed to solve the bug TFA talks about. I have a local patch that solves 100% of it.
>_ OpenAI Codex (v0.0.0)
model: gpt-5.5 xhigh /model to change
directory: ...
Ran sudo whoami
sudo: The "no new privileges" flag is set, which prevents sudo from running as root.
sudo: If sudo is running in a container, you may need to adjust the container configuration to
disable the flag.You run everything the model wants to do inside an OS-enforced sandbox of the sort browsers have used for decades to isolate tabs. It's already implemented and works fine. Codex just needs a few minor tweaks to make it apply its already-implemented sandboxing policy to a few situations it misses today.
> People just need to learn how to use the tools their system already provides them. i.e., chmod
I'm not running my agent as a separate POSIX user. Fortunately, my OS provides all the tools I need to free my having to do so.
I love when I do something in a few hours and people later call it impossible.
That's quite inconvenient. I want to run my coding agent in a restricted version of my regular user context, not something that drives like a separate machine.
> What if the model runs "rg foo", and one of those files contains the string "foo"? It uploads the tool output, which includes the file contents.
You have codex run rg in the sandbox, and the sandbox can't read foo. Why is this model so difficult to understand? Codex already runs a variety of commands under a bwrap/seatbelt/etc. sandbox. I've merely extended Codex to run everything in a sandbox. Escalation isn't a matter of whether to run a command in a sandbox or not: it's a matter of which sandbox policy to apply to whatever it is the model asked to do.
> the only solution is to make it so the codex process is unable to access those files
That's not true. Restrictions need apply only to the tools the model runs, not the Codex process itself. You can always insert a process-and-sandbox boundary between the harness and its tools. Codex inserts this boundary most of the time anyway. I've extended my Codex to do it all the time, even for things like the read-a-file tool.
Works fine.
> I imagine this isn't resolved primarily because people expect it to apply to bash tool use,
Yeah? Applying it to the shell tool [1] is trivial. It's actually harder to apply the sandbox to non-shell tools. It just isn't hard conceptually: you define a sandbox policy, writing down what's allowed and not, and just filter everything the model does through this policy via OS-level lightweight sandboxing tools.
Seriously. It's not that hard. And you don't have to sandbox the Codex process itself. I honestly have no idea why people think it's necessary to do so. The model has no ability to make Codex-the-POSIX-process do arbitrary things.
[1] I refuse to call it the "bash tool" when most users are running zsh in it. Name things appropriately.
[sandbox.always.filesystem]
"~/.config" = "none"
"~/.config/git" = "read"
(In other words, "other configuration notwithstanding, disallow reads under ~/.config, but do allow reads under ~/.config/git")I then force-merge the restrictions in this sandbox profile into all other sandbox profiles. I also added a new tiered sandboxing mode: now escalated commands, like regular commands, also run in a sandbox: just a more liberal one still subject to sandbox.always.filesystem rules. I added a new menu option to escalate (manually, one-shot) to truly-outside-sandbox mode for those few commands that aren't happy under any bwrap user namespace.
For simplicity, I also rewrote the built-in tools to just work through executing commands in the sandbox. Why is ReadFile something separate from cat-in-sandbox? why do we have two rule-enforcement systems, one for shell commands and one for tools? Well, now we don't.
Took me a few hours while I was doing other stuff. I love free software. I don't understand why you'd run Codex and not customize it locally.
I feel a bit guilty about not sending the patch upstream. It's just so much easier to fix software locally than get improvements landed upstream, especially now that LLMs make carrying patches forward easy.
1) What?
Only programmers are expected to use grep? What? That's absolute nonsense. Even programmers aren't programmers during every waking hour. My being a programmer in general doesn't make me a developer of your project, and I shouldn't have to become one by git cloning it to figure out how to write a config file.
Google Sheets and Excel have a REGEXMATCH. Do I have to be a programmer to use a spreadsheet? And even if so, do I need to guess the implementation language? No, because Google and Microsoft document their regular expression dialects (RE2 and PCRE, respectively), so you don't have to guess.
> If the software were meant to be used by people who can't [develop]...the documentation would be getting written by a non-developer
2) What?
No, that's also nonsense. Developers write programs for non-developers ALL THE TIME without some kind of technical writer intermediary. If the developer is any good, he'll realize that "regex" in documentation is ambiguous and write down the specific language he means.
No, I think GC is the way to control latency of memory handling. Plenty of work on real-time GC shows that you can construct a GC such that if the mutator allocates less than X MB/second you can achieve reclaim latencies under Y ms. The nice thing about these guarantees is that they're global: it doesn't matter how you allocate. All that matters is how much you allocate. It's a metric you can measure and optimize, IMHO, more easily than you can try to bound heap-manager contention and free-SCC size.
Granted, you can come back and point out that it's hard for me to prove I don't have allocation-rate spikes just like it's hard for you to prove you don't have lumpy free()s and malloc pool contention. But IME, it's a lot easier to bound latency rates, because we have good allocation profilers and in many cases you can prove allocation caps. IMHO, it's much harder to reason about long-range interactions of threads touching heaps.
The one primitive I wish we had but (outside BEAM) don't is object coloring. In a GC system, I should be able to allocate objects from different heaps and GC them independently .This way, a can write a subroutine that I can prove locally obeys the allocation-rate rule for my latency target and doesn't do any global allocations without giving up the use of the global heap for other purposes. They'd be a bit like the explicit arenas your tribe uses. (Your child heap would count as one "object" for purposes of parent-heap retention.) You could probably adapt existing multi-pool systems like MPS and ART's GC pretty easily too.
But even absent QoL features like these, modern GC is plenty suitable for programs that need to be responsive.
That said: 1ms? 1ms is getting into the sorts of latency the OS and hardware impose on your program no matter what it does. For example, on x86, a SMI can take 300us, or 1000us if you're unlucky. I've seen softirqs for shitty wifi chips take a hundred milliseconds! And God help you if you take a hard page fault:
You're worried about 1ms latencies, right? So you're mlock()ing all memory? Running RT threads pinned to cores? Carefully using PI and static priorities to avoid inversions? Avoiding blocking IO everywhere, not even for graphics page-flipping? Managing thermal headroom to avoid involuntary clock collapses? And it should go without saying, but I have to ask: you're running a PREEMPT_RT kernel, right?
No? You're not doing any of these things? Then why are you worried about 1ms in GC?
https://wiki.openjdk.org/spaces/zgc/pages/34668579/Main
> ZGC performs all expensive work concurrently, without stopping the execution of application threads for more than a millisecond. It is suitable for applications which require low latency. Pause times are independent of the heap size that is being used. ZGC works well with heap sizes from a few hundred megabytes to 16TB.
Go's GC is also very good: https://go.dev/blog/greenteagc.
V8's Orinoco is also pretty good now. It's improved a lot over the past decade and is now mostly-parallel. (A decade is about how long one of these things takes: high-performance GC is hard.)
I'm also a fan of MPS: it's a big of dark horse because it's more a GC construction kit than a ready-to-go GC, but it's fast and flexible, and I'd start with it any day over Boehm if I were making a VM from scratch.
I just can't take seriously this spate of languages that ignore the past 30 years of research into automatic memory management. We have multiple open-source pauseless miracles GCs right there before our eyes, yet it's the trendy thing in language design to foist memory management on users.
You don't even have to use a big VM if you want good GC. Go use MPS. Lots of options out there, even if you want to implement your own VM.
Other approaches are possible. I'm particularly keen on ones that treat attestations as anonymous digital currency and use cryptographic penalties like slashing to discourage copying post-hoc instead of relying on EU-style implementation certification.
There's a huge literature on the subject I don't want to reproduce here. The point is that yes, we do have the technology to do attestation without sacrificing privacy, which makes all the calls for non-privacy-preserving attestation awfully curious.
I think it'd depend on whether we discover new physics. The imaginative gaps you mention were downstream of ignorance of certain physical possibilities. Once it became clear that electrical communication at a distance is possible, people imagined global information networks. Once it became clear that sufficiently energetic fuels were possible, people elaborated on the possibilities of space travel. (Tsiolkovsky was very early! He was sketching O'Neill-style cylindrical space colonies back in 1903!)
Unfortunately, we might not be in store for new physics. So what's left is our failing to appreciate the details of how technologies will develop. Everyone predicted an internet; nobody predicted our internet, not exactly. What will be the impacts of, say, good brain-computer interfaces? Or of clinical immortality? We can imagine them in broad strokes, but we're going to be surprised by the details.
Keep in mind that a minuscule fraction of literary work survived, and most of that heavily biased towards what medieval monks found pious or (occasionally) interesting. The whole surviving corpus can fit on a few large bookshelves. The literacy was pretty high for an ancient society too. People wrote and consumed novels regularly. Bathhouses had attached libraries ordinary people could use.
The impression you get is that the classical world was full of people who thought about the world is a much more modern way than in the intervening 1500 years between that time and modernity.
They'd be more compatible with AC if not required by law to be incompatible. Places like NYC and Boston weren't built with AC either and adopted the technology just fine.
... actually works just fine. How do you think mass AC adoption in the US happened? Window units work just fine. Fancy splits and central ducting can come later.
Don't let perfect be the enemy of the good.
Keep in mind that optimizing the call doesn't optimize the marshaling: even with an AOT-compiled FFI trampoline, if you're, say, sending a string from one place to another, you usually need to transform the string in some manner (copy it, change encoding, add/remove length prefixes, etc.) and JITing the libffi parameter passing won't help you do the string stuff any faster.
In fact, trying to AOT the connections can make your program worse, both by bloating it (causing some likely small, but still, cache pressure) and by complicating your build and deployment process.
libffi bytecode is good. I wouldn't bother with native code until I had a profile in hand showing the bytecode to be the bottleneck, and even then, I'd check it a three or four times to make sure I didn't get the profiling wrong. FFI is just seldom the problem in real-world systems.
Notably, the COM bytecode covers not only procedure-level argument-passing, but data structure transformations themselves. It's a nice setup.
And yeah, nothing wrong with using ELF for the vDSO. People have strange intuitions about what's expensive and what's cheap.
But sure, keep using SYSCALL, THE DEPENDENCY MUTILATOR. It's got what containers crave!
If, instead, as on OpenBSD, the kernel enforced the rule that all system calls had to go through libc (or perhaps a big ntdll.dll-like VDSO), then the whole problem the linked article tries in vain to solve would disappear. If you wanted to hook a system call, you'd just change the libc/VDSO dispatch. No need to rewrite any instructions.
If I were Linus, I'd make a new rule: starting today, all new system calls must go through VDSO. No exceptions. SYSCALL from anywhere else? SIGKILL.
This way, you can just LD_PRELOAD in front of the VDSO and system call interception in userspace Just Works.
Does Herb Sutter strike you as extreme?
https://herbsutter.com/2013/02/11/atomic-weapons-the-c-memor...