HN user

igregoryca

58 karma
Posts1
Comments29
View on HN

It seems "Mythos is really good at finding vulnerabilities" has been what people took away from the Project Glassing announcement, which makes sense. Unfortunately for Anthropic, most seem to have forgotten the best argument Anthropic had for holding Mythos back from the general public, "it's crazy good at crafting exploits". Then, without that context, the tinfoil hats came out.

I know this is a tangent, but

Introduce and enforce structs for passing context and input shapes around. So as to stop fighting with NULLs, lack of keys in maps and other maddening cases that inflate your coding lines for no other reason than programming languages not having higher-order constructs on well-researched and mostly resolved computer science problems

Amen to that.

Some type theory, some abstract algebra...

Communication skills, teamwork skills...

How to cook better, maintain relationships better, keep a tidier space...

Not perfect! But time well spent.

Once upon a time, I thought I wanted to learn cursive handwriting. Except this version of me was already in his 20s, would be out of school in a matter of months, and quickly realized the skill would be of such marginal utility in the future that it wasn't worth the hours spent tracing out giant letters like a kindergartener every day.

One could learn this skill in their 20s or beyond, but there's an opportunity cost – why not something else that would actually improve work performance, or that you enjoy doing?

I still wish I'd been taught in elementary school, though, because it would've been really useful as a student. Some of our teachers discreetly handed out practice booklets to students who'd "expressed interest" (their parents taught them the basics and teacher noticed); most of us were not so lucky.

Claude Fable 5 1 month ago

Does "applying knowledge" necessitate human-like intentionality and theory of mind? If you insist it does, and this is a category error, then we need a new category.

By analogy, consider that many have referred to classical, deterministic computing as some kind of "thinking" for the last half century+. Does this stop being kosher when the computer has an uncanny propensity for human language? Perhaps, but the computer is still clearly chewing through problems that would have required a lot of human thinking (e.g., arithmetic) in ages past.

I haven't seen any genuine proposals for words to replace the human mind analogues, let alone proposals that the anglosphere would plausibly adopt en masse.

Claude in general probably increases observed bugs in rsync, because it can churn out vulnerability reports that necessitate tons of changes to software that people are accustomed to working flawlessly in non-pathological use cases.

I don't have empirical evidence for this claim, but best I can tell, security patches are the principal source of observed bugs in software of a certain vintage, because they cause churn. (Just think of Windows updates that break drivers.)

Postinstall scripts have remained an effective attack vector for quite a while – which, ironically, has meant the worm's authors had little incentive to try something else, so it was easier to inoculate yourself. Alas, you're right, it should be pretty simple to bypass this kind of protection, if they haven't already (and seems like they have).

Can't speak for intelligent autocomplete writ large, but I treat it as an ergonomic feature, and Cursor's implementation is pretty good (though I'm not sure it's improved all that much in the past year).

It constantly takes whatever is currently visible in your editor to feed its context. If you get a nonsense/hallucinated suggestion, you can accept it, get it to read the error message from LSP diagnostics, undo, and then it'll correct itself next time. Or if you need to make changes in 5 places, and the next 4 changes are easy to guess after seeing the first one, it'll guess the next 4 for you.

I still use standard IDE features extensively. The intelligent autocomplete is just another tool to reduce typing when the next change is easy to guess.

Oh, and I turn it off when I'm writing prose or need to actually think deeply. Then it really does hurt more then help.

(Worth noting: I currently work primarily in Go, which is a language that's ridiculously verbose and has lots of repetitive patterns. YMMV for more expressive languages.)

Article:

To avoid this, you will probably need to intentionally write in a very different style than you usually do (or to have AIs rewrite all your prose for you, but, ugh, that’s not a world I look forward to living in).

I agree. The amount of vague and cliche'd AI writing I read on the daily is already exhausting enough.

It would be interesting if you could train a model to sprinkle random red herrings throughout your text in a minimally disruptive way. But I fear you might have to stretch the definition of "minimally disruptive" to make it robust against detection.

The (shift+)cmd+` order also resets to match the window z-order whenever you switch apps. So if the order is windows A, B, C, then you select window B, cmd+tab away, then cmd+tab back, the order will now be B, A, C.

I've developed an intuitive understanding of this, but I had to experiment just now to describe the behavior precisely. And my intuition is still wrong sometimes (like if the app has windows on multiple monitors, it's hard to predict the z-order).

if I Slack open in Firefox in workspace 1 and Outlook open in Firefox in workspace 2, there is no way to switch between Slack and Outlook

My local maximum is to never use workspaces – just cmd+tab, cmd+`, and sometimes cmd+h to reduce screen clutter.

What can Bank X do to stop phone malware from scraping the user's session token from the Bank X app or website?

Yes, banks should (and sometimes do) double- and triple-check with you before allowing large transfers/withdrawals, but scammers know how to coach their victims past this. Speaking from experience.

(I also don't fully agree this is Google's responsibility, and I am not happy about this development. But there are legitimate points in favor of outsourcing the question of "will this software do nefarious things" to some kind of trusted signing authority.)

Wood is edible when processed correctly, but it's not legally considered "food" because there are a bunch of nontrivial steps to get it into that state. Likewise, any reasonable interpretation of "general purpose computer" in this context by a judge would not include your microwave oven just because someone with skill and finesse could transform it into a cursed Doom arcade machine.

Laws are interpreted by people trained to fill in the blanks[1] with a best guess of the legislative body's intent. And the intent here seems pretty clear: to regulate computing devices that let end users easily install software from a centralized catalog.

[1] which we all do subconsciously in day-to-day speech, because all language is ultimately subjective

The lack of a "refresh" option has been a problem with iCloud for years. Back in the iOS 8/9 days, I'd write in Pages on an iPad and then try to open the document on a Mac or the Pages web app. Pages itself was (and is) pretty nice, but iCloud sync was constantly broken. Things didn't appear when I needed them to.

Some designers say that refresh buttons shouldn't exist because the interface should always reflect the current state of reality. They're right, but until the day we get 100% bug-free bidirectional sync with perfect conflict resolution that instantly polls the network whenever it reconnects, refresh buttons are a necessary evil.

I think most people struggle to one-shot Lisp parens. Visual guides or structured editing are sorta necessary. LLMs don't have that kind of UI (yet?)

The only languages that eliminate logic bugs are formally verified ones, as the article points out. (And even then, your program is only as correct as your specification.) Ordinary Rust code is not formally verified. Anyone who claims Rust eliminates errors is either very naive or lying.

Type-safe Rust code is free from certain classes of errors. But that goes out the window the moment you parse input from the outside, because Rust types can enforce invariants (i.e. internal consistency), but input has no invariants. Rust doesn't ban you from crashing the program if you see input that violates an invariant. I don't know of any mainstream language that forbids crashing the program. (Maybe something like Ada? Not sure.)

I don't understand why you bemoan that Rust hasn't solved this problem, because it seems nigh unsolvable.

Some people appreciate it when terminal output is easier to read.

If chalk emits sequences that aren't supported by your terminal, then that's a deficiency in chalk, not the programs that wanted to produce colored output. It's easier to fix chalk than to fix 50,000 separate would-be dependents of chalk.

Most of your supply chain attack surface is social engineering attack surface. Doesn't really matter if I use Lodash, or 20 different single-function libraries, if I end up trusting the exact same people to not backdoor my server.

Of course, small libraries get a bad rap because they're often maintained by tons of different people, especially in less centralized ecosystems like npm. That's usually a fair assessment. But a single author will sometimes maintain 5, 10, or 20 different popular libraries, and adding another library of theirs won't really increase your social attack surface.

So you're right about "pull[ing] in universes [of package maintainers]". I just don't think complexity or number of packages are the metrics we should be optimizing. They are correlates, though.

(And more complex code can certainly contain more vulnerabilities, but that can be dealt with in the traditional ways. Complexity begets simplicity, yadda yadda; complexity that only begets complexity should obviously be eliminated)

1) Null pointer derefs can sometimes lead to privilege escalation (look up "mapping the zero page", for instance). 2) As I understand it (could be off base), if you're already doing static checking for other memory bugs, eliminating null derefs comes "cheap". In other words, it follows pretty naturally from the systems that provide other memory safety guarantees (such as the famous "borrow checker" employed by Rust).

Discovering and using private APIs is not a walk in the park. I doubt "laziness" is a common motivation for doing so. Lack of knowledge or bad docs, perhaps. But there's often no officially sanctioned way to do something that people want (and perhaps will pay for) - most private API usage I've seen falls into this third bucket.

Hm. You and parent comment have made me realize something: as much as I dislike how many useful abstractions are missing from Go, async for blocking syscalls is not one of them, since the "green thread" model effectively makes all functions async for the purposes of blocking syscalls. So I retract my "you have to do it manually" comment in this case. I guess that's part of why people love Go's concurrency.

Of course, as you said, stackful coroutines come with runtime overhead. But that's the tradeoff, and I'm sure they are substantially more efficient (modulo FFI calls) than the equivalent async-everywhere code would be in typical JS or Python runtimes.

My "you have to do it manually" comment comes from some other peeves I have with Go. I guess the language designers were just hyper-focused on syscall concurrency and memory management (traditionally hard problems in server code), because Go does fare well on those specific fronts.

the sync/async function coloring nightmare

I'm with you that function "coloring" (monads in the type system) can be unergonomic and painful.

... isn't that what Go is? I think out of all languages I use extensively, Go is the only one that doesn't suffer from the […] coloring nightmare.

Because it doesn't have Future/Promise/async as a built-in abstraction?

If my function returns data via a channel, that's still incompatible with an alternate version of the function that returns data normally. The channel version doesn't block the caller, but the caller has to wait for results explicitly; meanwhile, the regular version would block the caller, but once it's done, consuming the result is trivial.

Much of the simplicity of Go comes at the expense of doing everything (awaiting results, handling errors, …) manually, every damn time, because there's no language facility for it and the type system isn't powerful enough to make your own monadic abstractions. I know proponents of Go tend to argue this is a good thing, and it has merits. But making colorful functions wear a black-and-white trenchcoat in public doesn't solve the underlying problem.

(goroutines are nice, though.)

I do think it's likely more passive than active. People at Google aren't deviously plotting to hide buttons from the user.

This is important, thank you for mentioning it: actions have consequences besides those that motivated the action. I don't like when people say "<actor> did <action>, and it leads to this nefarious outcome, therefore look how evil <actor> must be". Yes, there is always a chance that <actor> really is a scheming, cartoonish villain who intended that outcome all along. But how likely is it that <actor> is just naive, or careless, or overly optimistic?

Of course, the truth is almost certainly somewhere in the middle: familiarity with a hard-to-learn UI as a point of friction that promotes lock-in may not be a goal, but when it manifests, it doesn't hurt the business, so no one does anything about it. Does that mean the designers should be called out for it? If the effect is damaging enough to the collective interest, then maybe yes. But we needn't assume nefarious intentions to do so.

Then again, everyone thinks their own actions are justified within their own value system, and corporate values do tend toward the common denominator (usually involving profit-making). Maybe the world just has way more cartoonish villains than I give it credit for.

This aligns nicely with how things look in the "small-step" flavour of PL theory / lambda calculus.

In the lingo, expressions are evaluated by repeatedly getting "rewritten", according to rules called reduction rules. e.g., (1 + 2) + 4 might get rewritten to 3 + 4, which would then get rewritten to 7.

There are two sorts of these rules. There are "congruence" rules, which direct where work is to be done ("which subexpression to evaluate next?"); and then there are "computation" rules (as Pierce [1] calls them), which actually rewrite the expression, and thus change the program state.

"Strict"/"non-lazy" languages (virtually every popular general-purpose language? except Haskell) are full of congruence rules – all subexpressions must be fully evaluated before a parent expression can be evaluated. The important exceptions are special constructs like conditionals and indefinite loops.

For conditionals in particular, a computation rule will kick in before congruence rules direct all subexpressions to be evaluated. This prunes the expression tree, now in a very literal sense.

[1]: Benjamin C. Pierce, Types and Programming Languages (recommended!)