HackerTrans
TopNewTrendsCommentsPastAskShowJobs

Diggsey

2,809 karmajoined há 12 anos

comments

Diggsey
·há 3 dias·discuss
Yes - I think the proof of the pudding will be whether they put in the effort to eliminate these unsafe blocks. The conversion to Rust is the starting point that makes this possible, but it's definitely not "done" at this point.
Diggsey
·há 19 dias·discuss
1. Seems hard but doable (assuming there is some way to inject "inputs" into the build process, that can be recorded). However, I'm not sure exactly what you mean by a build here? Many package managers do not distribute binaries at all, so what is being reproduced?

2. Codegen is extremely common (serialisation, reflection, bindings, etc.) to the extent that even requiring a whitelist of packages that can do code-gen seems like a non-starter (because everyone will just whitelist everything). Sandboxing build-time execution seems like a more practical approach than denying it.

3. It's not clear to me that this distinction is meaningful for many package managers. Crates.io for example distributes a packaged set of sources. What are you comparing these against? There's no requirement that the original sources be hosted anywhere public, and I definitely don't think it should be mandating use of GitHub or anything.

4. Needs to be a whitelist rather than mandatory, but yes.

5. Yes, with the caveat below.

6. What do you mean by "locked"? You cannot lock transitive dependencies and still have a usable package infrastructure. If I have packages A and B that both depend on C, then it's critical that the version of C used is maximally flexible, otherwise it becomes impossible for downstream packages to find a version of A and B that are inter-compatible.

In my experience there's a danger for security experts to neglect the practical consequences of the limitations they enforce. This is because they incorrectly place security as the most important requirement, when by definition it cannot be:

Without a product, there is nothing to secure. When a policy becomes too onerous, people don't simply stop doing their work, they work around it. It's a mistake to judge a security policy on what it prevents: a security policy should be judged on what it allows, because an unused or bypassed security policy is less effective than a weak one.

This is why I think thinks like sandboxed execution far more effective than trying to blanket deny things: it enables people to work in a more secure way rather than pushing them towards less secure alternatives. It's why the best way to get people to use secure cryptographic libraries is not just to berate them for doing things themselves, it's to build secure libraries that they want to use because they work well and are ergonomic.
Diggsey
·mês passado·discuss
> Yes, and the amount of study and knowledge required had a tendency to filter out people with the inclination to do such things. The Venn diagrams weren't completely empty, but they were close, which is why such incidents were rare.

People do exercise their freedom and do terrible things all the time - it's not rare. There are lots of ways to cause harm that don't require any study or knowledge at all, we just seem hyper-focused on the possible "sci-fi" consequences of AI for some reason.

I would argue the reason people don't go and kill someone (or worse...) even more often than they do is not because it's difficult but because most people have no desire to cause that kind of harm, and because of the consequences to themselves of doing so.

So yes: technical difficulty put some kinds of harm out of reach of people, and AI can lower that barrier somewhat, but in the grand scale of "harm people can do" I think it's receiving undue attention.

And from a practical standpoint: how do you get from there to arguing that we should set some impossible-to-define threshold of "frontier" at which point it becomes so evil that we need to forcefully delete it from existence? Don't you see the problem with trying to put such black and white restrictions on something that's so inherently amorphous and slippery? (And by definition, if you delete the "frontier" model from existence then the next best model is now "frontier" ad infinitum...)

On top of that you have the issue that model weights are just information, so in some sense you're legislating the knowledge that is allowed to exist. That's quite a bit more draconian that current laws which usually focus on what knowledge you can share.
Diggsey
·há 3 meses·discuss
You would have had to run `jj edit` in order for this to happen, so I think it's a stretch to say you didn't ask for the edit?

This is the main difference though: in git files can be `staged`, `unstaged` or `committed`, so at any one time there are 3 entire snapshots of the repo "active".

In `jj` there is only one kind of snapshot (a change) and only one is "active" (the current working directory). When you make changes to the working directory you are modifying that "change".

As others have mentioned, the equivalent to `git checkout` would be `jj new`, which ensures a new empty change exists above the one you are checking out, so that any changes you make go into that new change rather than affecting the existing one.
Diggsey
·há 3 meses·discuss
> git was originally implemented as a handful of low level binaries stitched together with shell scripts.

A bunch of low level binaries stitched together with shell scripts is a lot faster than python, so not really sure what the point of this comparison is.

Python is an extremely versatile language, but if what you're doing is computing hashes and diffs, and generally doing entirely CPU-bound work, then it's objectively the wrong tool, unless you can delegate that to a fast, native kernel, in which case you're not actually using Python anymore.
Diggsey
·há 3 meses·discuss
Which works for about 5 minutes until someone leaks a manufacturer's private key or extracts it from a device...
Diggsey
·há 4 meses·discuss
Yes this stood out to me as well...
Diggsey
·há 5 meses·discuss
Stored procedures don't eliminate serialization anomalies unless they are run inside a transaction that is itself SERIALIZABLE.

There's essentially no difference between putting the logic in the app vs a stored procedure (other than round trip time)
Diggsey
·há 6 meses·discuss
This is completely untrue. While the index only stores the hashes, the table itself stores the full value and postgres requires both the hash and the full value to match before rejecting the new row. Ie. Duplicate hashes are fine.
Diggsey
·há 6 meses·discuss
It's also `position: fixed` which breaks all scroll optimizations and makes scrolling feel terrible.
Diggsey
·há 8 meses·discuss
There were two things I think went extremely poorly here:

1) Lack of validation of the configuration file.

Rolling out a config file across the global network every 5 minutes is extremely high risk. Even without hindsight, surely one would see then need for very careful validation of this file before taking on that risk?

There were several things "obviously" wrong with the file that validation should have caught:

- It was much bigger than expected.

- It had duplicate entries.

- Most importantly, when loaded into the FL2 proxy, the proxy would panic on every request. At the very least, part of the validation should involve loading the file into the proxy and serving a request?

2) Very long time to identify and then fix such a critical issue.

I can't understand the complete lack of monitoring or reporting? A panic in Rust code, especially from an unwrap, is the application screaming that there's a logic error! I don't understand how that can be conflated with a DDoS attack. How are your logs not filled with backtraces pointing to the exact "unwrap" in question?

Then, once identified, why was it so hard to revert to a known good version of the configuration file? How did noone foresee the need to roll back this file when designing a feature that deploys a new one globally every 5 minutes?
Diggsey
·há 8 meses·discuss
IMO, safety and "idiomatic-ness" of Rust code are two separate concerns, with the former being easier to automate.

In most C code I've read, the lifetimes of pointers are not that complicated. They can't be that complicated, because complex lifetimes are too error prone without automated checking. That means those lifetimes can be easily expressed.

In that sense, a fairly direct C to Rust translation that doesn't try to generate idomatic Rust, but does accurately encode the lifetimes into the type system (ie. replacing pointers with references and Box) is already a huge safety win, since you gain automatic checking of the rules you were already implicitly following.

Here's an example of the kind of unidiomatic-but-safe Rust code I mean: https://play.rust-lang.org/?version=stable&mode=debug&editio...

If that can be automated (which seems increasingly plausible) then the need to do such a translation incrementally also goes away.

Making it idiomatic would be a case of recognising higher level patterns that couldn't be abstracted away in C, but can be turned into abstractions in Rust, and creating those abstractions. That is a more creative process that would require something like an LLM to drive, but that can be done incrementally, and provides a different kind of value from the basic safety checks.
Diggsey
·há 9 meses·discuss
I've found Gemini to be much better at completing tasks and following instructions. For example, let's say I want to extract all the questions from a word document and output them as a CSV.

If I ask ChatGPT to do this, it will do one of two things:

1) Extract the first ~10-20 questions perfectly, and then either just give up, or else hallucinate a bunch of stuff.

2) Write code that tries to use regex to extract the questions, which then fails because the questions are too free-form to be reliably matched by a regex.

If I ask Gemini to do the same thing, it will just do it and output a perfectly formed and most importantly complete CSV.
Diggsey
·há 9 meses·discuss
That would be because package version flexibility is an entirely orthogonal concept to lock files, and to conflate them shows a lack of understanding.

pyproject.toml describes the supported dependency versions. Those dependencies are then resolved to some specific versions, and the output of that resolution is the lock file. This allows someone else to install the same dependencies in a reproducible way. It doesn't prevent someone resolving pyproject.toml to a different set of dependency versions.

If you are building a library, downstream users of your library won't use your lockfile. Lockfiles can still be useful for a library: one can use multiple lockfiles to try to validate its dependency specifications. For example you might generate a lockfile using minimum-supported-versions of all dependencies and then run your test suite against that, in addition to running the test suite against the default set of resolved dependencies.
Diggsey
·há 9 meses·discuss
Agree, but I think there is a point to be made here: Go as a language has more subtle runtime invariants that must be upheld compared to other languages, and this has led to a relatively large number of really nasty bugs (eg. there have also been several bugs relating to native function calling due to stack space issues and calling convention differences). By "nasty" I mean ones that are really hard to track down if you don't have the resources that a company like CF does.

To me this points to a lack of verification, testing, and most importantly awareness of the invariants that are relied on. If the GC relies on the stack pointer being valid at all times, then the IR needs a way to guarantee that modifications to it are not split into multiple instructions during lowering. It means that there should be explicit testing of each kind of stack layout, and tests that look at the real generated code and step through it instruction by instruction to verify that these invariants are never broken...
Diggsey
·há 10 meses·discuss
Essentially zero as a fraction of global concrete usage...
Diggsey
·há 10 meses·discuss
They are different:

    "0": ">=0.0.0, <1.0.0"
    "0.9": ">=0.9.0, <1.0.0"
    "0.9.3": ">=0.9.3, <1.0.0"
Notice how the the minimum bound changes while the upper bound is the same for all of them.

The reason for this is that unless otherwise specified, the ^ operator is used, so "0.9" is actually "^0.9", which then gets translated into the kind of range specifier I showed above.

There are other operators you can use, these are the common ones:

    (default) ^ Semver compatible, as described above
    >= Inclusive lower bound only
    < Exclusive upper bound bound
Note that while an exact bound will force that exact version to be used, it still doesn't allow two semver compatible versions of a crate to exist together. For example. If cargo can't find a single version that satisfies all constraints, it will just error.

For this reason, if you are writing a library, you should in almost all cases stick to regular semver-compatible dependency specifications.

For binaries, it is more common to want exact control over versions and you don't have downstream consumers for whom your exact constraints would be a nightmare.
Diggsey
·há 10 meses·discuss
Within a crate graph, for any given major version of a crate (eg. D v1) only a single minor version can exist. So if B depends on D v1.x, and C depends on D v2.x, then two versions of D will exist. If B depends on Dv1.2 and C depends on Dv1.3, then only Dv1.3 will exist.

I'm over-simplifying a few things here:

1. Semver has special treatment of 0.x versions. For these crates the minor version depends like the major version and the patch version behaves like the minor version. So technically you could have v0.1 and v0.2 of a crate in the same crate graph.

2. I'm assuming all dependencies are specified "the default way", ie. as just a number. When a dependency looks like "1.3", cargo actually treats this as "^1.3", ie. the version must be at least 1.3, but can be any semver compatible version (eg. 1.4). When you specify an exact dependency like "=1.3" instead, the rules above still apply (you still can't have 1.3 and 1.4 in the same crate graph) but cargo will error if no version can be found that satisfies all constraints, instead of just picking a version that's compatible with all dependents.
Diggsey
·há 10 meses·discuss
It doesn't link two versions of `rand-core`. That's not even possible with rust (you can only link two semver-incompatible versions of the same crate). And dependency specifications in Rust don't work like that - unless you explicitly override it, all dependencies are semver constraints, so "0.9.0" will happily match "0.9.3".
Diggsey
·há 3 anos·discuss
I think they're probably right about the AI-sharpening using specific knowledge about the moon... However, they are wrong about the detail being gone in the gaussian-blurred image.

If they applied a perfect digital gaussian-blur, then that is reversible (except at the edges of the image, which are black in this case anyway). You still lose some detail due to rounding errors, but not nearly as much as you might expect.

A gaussian blur (and several other kinds of blur) are a convolution of the image with a specific blur function. A convolution is equivalent to simply multiplying pointwise the two functions in frequency space. As long as you know the blur function exactly, you can divide the final image by the gaussian function in frequency space and get the original image back (modulo rounding errors).

It is not totally inconceivable that the AI model could have learned to do this deconvolution with the Gaussian blur function, in order to recover more detail from the image.