about summary refs log tree commit diff
path: root/tvix/eval/src
AgeCommit message (Collapse)AuthorFilesLines
2022-09-08 r/4754 refactor(tvix/eval): refactor locals to use an enum for phantomsVincent Ambo2-22/+48
Instead of using sentinel values and an additional bool, this tracks the identifier of a local as an enum that is either a statically known name, or a phantom. To make this work correctly some more locals related logic has been encapsulated in the `scope` module, which is a good thing (that's the goal). Phantom values are now not initialised by default, but the only current call site of phantoms (`with` expression compilation) performs the initialisation right away. This commit changes no actual functionality right now, but paves the way for fixing an issue related to `let` bodies. Change-Id: I679f93a59a4daeacfe40f4012263cfb7bc05034e Reviewed-on: https://cl.tvl.fyi/c/depot/+/6421 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-08 r/4753 refactor(tvix/eval): always pass slot to compiler methodsVincent Ambo2-33/+32
The slot is now always known (at the root of the file it is simply stack slot 0 once the scope drops back down to 0), so it does not need to be wrapped in an `Option` and accessed in cumbersome ways anymore. Change-Id: I46bf67a4cf5cb96e4874dffd0e3fb07c551d44f0 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6420 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-08 r/4752 refactor(tvix/eval): implement much clearer disassembler outputVincent Ambo2-26/+50
With this change the runtime trace contains much more exact information about the context of the computation (entering/exiting calls etc.) This is in large part due to moving the tracer to be a field on the VM itself, which enables consistent ordering of traces across the execution, and tracing an execution with its *input* instead of *output* stack. Change-Id: Ibe525e6e7d869756501e52bef1a441619ce7332c Reviewed-on: https://cl.tvl.fyi/c/depot/+/6419 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-08 r/4751 chore(tvix/eval): print value when panicking on internalsVincent Ambo1-1/+3
This makes it much easier to figure out what happened while debugging this sort of thing. Change-Id: I2e0e8096709adc647d63c04f213c547c415e5f44 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6418 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-08 r/4750 fix(tvix/eval): force argument of builtins.lengthVincent Ambo1-1/+4
Change-Id: Iaf94dfc7cb058f5c1c311066d92e01512e09cf71 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6417 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-08 r/4749 fix(tvix/eval): don't panic when printing a black holeVincent Ambo1-2/+6
This could occur when the disassembler is enabled and tracing the runtime while a thunk is being evaluated, as it would not be possible for the *tracer* to borrow the thunk at this exact moment. However, we know that if the borrowing fails here we are dealing with a not-fully evaluated thunk (blackhole), which should just print the internal representation. Change-Id: I4bdb4f17818d55795368e3d28842048f488f0a91 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6416 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-08 r/4748 refactor(tvix/eval): return call frame result from VM::callVincent Ambo2-14/+22
Previously, "calling" (setting up the VM run loop for executing a call frame) and "running" (running this loop to completion) were separate operations. This was basically an attempt to avoid nesting `VM::run` invocations. However, doing things this way introduced some tricky bugs for exiting out of the call frames of thunks vs. builtins & closures. For now, we unify the two operations and always return the value to the caller directly. For now this makes calls a little less effective, but it gives us a chance to nail down some other strange behaviours and then re-optimise this afterwards. To make sure we tackle this again further down I've added it to the list of known possible optimisations. Change-Id: I96828ab6a628136e0bac1bf03555faa4e6b74ece Reviewed-on: https://cl.tvl.fyi/c/depot/+/6415 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-08 r/4747 feat(tvix/eval): thread codemap through to disassemblerVincent Ambo4-5/+47
If the disassembler feature is enabled, make sure that an Rc of the codemap is available through the chunk. Change-Id: I700f27ab665a704f73457b19bd2d7efc93828a16 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6414 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-08 r/4745 refactor(tvix/eval): add macros for generating Value castersVincent Ambo3-76/+56
The casting methods of `Value` are pretty verbose, and actually incorrect before this commit as they did not account for inner thunk values. To address this, we first attempt to make them correct by introducing a standard macro to generate them and traverse the inner thunk(s) if necessary. This is likely to be a performance hit as it will now involve more cloning of values. We can do multiple things to alleviate this, but should do some measurements first. Change-Id: If315d6e2afe7b69db727df535bc6cbfb89a691aa Reviewed-on: https://cl.tvl.fyi/c/depot/+/6412 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-08 r/4744 refactor(tvix/eval): pass a VM reference to builtinsVincent Ambo3-24/+34
This makes it possible for builtins to force values on their own, without the VM having to apply a strictness mask to the arguments first. Change-Id: Ib49a94e56ca2a8d515c39647381ab55a727766e3 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6411 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-08 r/4743 fix(tvix/eval): inherit scope poisoning data in nested contextsVincent Ambo4-4/+36
Scope poisoning must be inherited across lambda context boundaries, e.g. if an outer scope has a poisoned `null`, any lambdas defined on the same level must reference that poisoned identifier correctly. Change-Id: I1aac64e1c048a6f3bacadb6d78ed295fa439e8b4 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6410 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-08 r/4742 fix(tvix/eval): thread thunk forcing errors through correctlyVincent Ambo2-3/+7
With this, if an error occurs while forcing a thunk (which is very likely) it is threaded through to the top by wrapping it in the ErrorKind::ThunkForce variant. We could use this to generate "stacktrace-like" error output if we wanted, or simply jump through and discard everything except the innermost error. Change-Id: I3c1c8708c2f73ae062815adf490ce935b1979da8 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6409 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-08 r/4741 feat(tvix/eval): ensure all errors always carry a spanVincent Ambo9-141/+149
Previously error spans were optional because the information about code spans was not available at runtime. Now that this information has been added, the error type will always carry a span. This change is very invasive all throughout the codebase. This is due to the fact that many functions that are called *by* the VM expected to return `EvalResult`, but this no longer works as the span information is not available to those functions - only to the VM itself. To work around this the majority of these functions have been changed to return `Result<T, ErrorKind>` instead and an accompanying macro in the VM constructs the "real" error. Note that this implementatino currently has a bug where errors occuring within thunks will yield the location at which the thunk was forced, not the location at which the error occured within the code. This will be fixed soon, but the commit is large enough as is. Change-Id: Ib1ecb81a4d09d464a95ea7ea9e589f3bd08d5202 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6408 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-07 r/4740 feat(tvix/eval): Support builtins.lengthWilliam Carroll5-0/+24
Get the length of a list Change-Id: I41d91e96d833269541a1b3c23b7cc879f96d1e5a Reviewed-on: https://cl.tvl.fyi/c/depot/+/6407 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4739 feat(tvix/eval): Support builtins.{mul,div}William Carroll5-0/+28
Multiplication and division :) Change-Id: I79e76f3b55b7e9b8d1eb09b3d9741140b4d75742 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6406 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4738 feat(tvix/eval): Support builtins.{add,sub}William Carroll6-0/+29
First pass at supporting `builtins` for tvix. The following tests appear to be WAI: ```shell $ cd tvix/eval $ cargo build $ cargo test ``` Change-Id: I27cce23d503b17a886d1109e285e8b4be4264977 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6405 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4737 refactor(tvix/eval): store spans instead of nodes in Warning/ErrorVincent Ambo5-89/+91
Another step towards being able to report accurate errors. The codemap spans contain strictly more accessible information, as they now retain information about which input file something came from. This required some shuffling around in the compiler to thread all the right information to the right places. Change-Id: I18ccfb20f07b0c33e1c4f51ca00cd09f7b2d19c6 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6404 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-07 r/4736 feat(tvix/eval): track source spans for builtin accessVincent Ambo2-26/+9
As of this commit, the source spans of all emitted bytecode are fully tracked. Change-Id: I4c83deee0fc3f5e6fd6acad5a39047aec693b388 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6403 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-07 r/4735 feat(tvix/eval): track source spans for `OpForce` instructionsVincent Ambo1-23/+23
These source spans will always point to the *value* that is being forced, not the instruction that caused the force to be emitted. This makes sense so that errors during forcing point at the value and not the surrounding expression. Change-Id: I4694414a3281a0de878f71634105b92148ec61f6 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6402 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-07 r/4734 feat(tvix/eval): track source spans for scopesVincent Ambo1-6/+6
Change-Id: Iaedb0742940e4c2b9f4210579ed28e6deb32d5c8 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6401 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-07 r/4733 feat(tvix/eval): track source spans for upvaluesVincent Ambo2-17/+43
With this change, the upvalue data instructions used by finalisers for thunks and closures track the source span of the first identifier that created the upvalue (if the same value is closed over multiple times the upvalue will be reused, hence only the first one). To do this the upvalue struct used by the compiler's scope now carries an identifier node, which had to be threaded through quite a few places. Change-Id: I15a5fcb4c8abbd48544a2325f297a5ad14ec06ae Reviewed-on: https://cl.tvl.fyi/c/depot/+/6400 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-07 r/4732 refactor(tvix/eval): split out Upvalue struct & UpvalueKind enumVincent Ambo2-14/+19
This separation makes it possible to annotate the upvalue itself with the span that created it, which (due to upvalue reuse) is only the first one for an instance of the given UpvalueKind. Change-Id: I9a991da6a3e8d71a92f981314bed900bcf434d44 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6399 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-07 r/4731 feat(tvix/eval): track source spans for thunksVincent Ambo1-8/+11
Change-Id: I73f13c914d84e052a43b4eddb09db1acd8a7076a Reviewed-on: https://cl.tvl.fyi/c/depot/+/6398 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-07 r/4730 feat(tvix/eval): track source spans for function callsVincent Ambo1-1/+1
Change-Id: If1bb463026414597acd561dc2032549fdb70f986 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6397 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-07 r/4729 feat(tvix/eval): track source spans for lambdasVincent Ambo1-2/+5
Change-Id: I2f420fc915b6bfc5b197e9d0c128b539c4bc7467 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6396 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-07 r/4728 feat(tvix/eval): track source spans for `with` expressionsVincent Ambo1-2/+2
Change-Id: I1d58ce548b5b47e967928e85bb64acf5ed69ecc8 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6395 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-07 r/4727 feat(tvix/eval): track source spans for identifier accessVincent Ambo1-10/+8
Change-Id: I8e6ec0a84430d6e417fc7fd3e722a588913e4d18 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6394 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-07 r/4726 feat(tvix/eval): track source spans for `let` bindingsVincent Ambo1-2/+2
Change-Id: I9457917277a7fdd8bdbe227a567b28969312d06e Reviewed-on: https://cl.tvl.fyi/c/depot/+/6393 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-07 r/4725 feat(tvix/eval): track source spans for `if` expressionsVincent Ambo1-4/+7
These are again a bit tricky in terms of emitted errors. The main error is that the condition is not a boolean, which means that the jump inspecting the condition must derive from the condition itself to return an error at the correct position. For other parts of the expression, it is simply the node itself. Change-Id: I72411630e5d57dfc199f4c3c48afe443fe966322 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6392 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4724 feat(tvix/eval): track source spans for `assert`Vincent Ambo1-1/+1
Change-Id: I5415f63ddde388847a261da4ce9a8d8235657535 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6391 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4723 feat(tvix/eval): track source spans for `or` operatorVincent Ambo1-7/+4
This one is tricky, specifically the span used for the final jump. I decided that it makes sense to use the attrpath node, as the final jump is the one that jumps *over* the default value, so the effect of this is more closely related to the selector than the default. It might be more correct to pass through the `or` token itself and point to this for the jumps, but it depends a bit on what shape of errors we could end up producing from this. Change-Id: I29fbc97ba6b9e14e1a0e5f3a7759ddc299dd9c0c Reviewed-on: https://cl.tvl.fyi/c/depot/+/6390 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4722 feat(tvix/eval): track source spans for attribute selectsVincent Ambo1-1/+1
Change-Id: Ifa8b0e7905f9d2746f83d6503ef0e8d42ce20f9c Reviewed-on: https://cl.tvl.fyi/c/depot/+/6389 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4721 feat(tvix/eval): track source spans for attrsetsVincent Ambo1-3/+6
Change-Id: I0fcb07146b5a38c67bc46ed3f67533b056858390 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6388 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4720 feat(tvix/eval): track source spans for listsVincent Ambo1-1/+1
Change-Id: Icfd057ee29180cac17264bb3299c67eae0051aee Reviewed-on: https://cl.tvl.fyi/c/depot/+/6387 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4719 feat(tvix/eval): track source spans for literal identifiersVincent Ambo1-1/+4
Change-Id: I7ca08c6c0124f653e55fcc86413a847f0a4c50c5 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6386 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4718 feat(tvix/eval): track source spans for `?` operatorVincent Ambo1-2/+2
Change-Id: Idb842fb20fab14150455a81ea6c947e75b314d8a Reviewed-on: https://cl.tvl.fyi/c/depot/+/6385 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4717 feat(tvix/eval): track source spans for binary operatorsVincent Ambo1-23/+23
Change-Id: I43e433ff3094232b244d38335d31e56a79ca70c1 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6384 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4716 feat(tvix/eval): track source spans for unary operatorsVincent Ambo1-1/+1
Change-Id: I79034a4aa04aea66ec598e33e6eab35e1e19c0d0 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6383 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4715 feat(tvix/eval): track source spans for stringsVincent Ambo1-2/+2
Change-Id: I29e6c7f9e25d1b2e6bafa602c463eb9ccee2131b Reviewed-on: https://cl.tvl.fyi/c/depot/+/6382 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4714 feat(tvix/eval): track source spans for pathsVincent Ambo1-1/+1
Change-Id: I42fbd0bb6c2a8feb520e262a25f59ff27dcd035c Reviewed-on: https://cl.tvl.fyi/c/depot/+/6381 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4713 feat(tvix/eval): track source spans for literalsVincent Ambo1-3/+3
Change-Id: Icfe77f85c4f65b6bf28b8752c2795419e8e396ce Reviewed-on: https://cl.tvl.fyi/c/depot/+/6380 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4712 feat(tvix/eval): add methods for emitting code with tracked spansVincent Ambo2-80/+111
These are not actually used yet; this is in preparation for a multi-commit chain for emitting all the right spans in the right locations. Change-Id: Ie99d6add2696c1cc0acb9ab928917a10237159de Reviewed-on: https://cl.tvl.fyi/c/depot/+/6379 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4711 chore(tvix/eval): thread a codemap::File reference to the compilerVincent Ambo2-5/+21
This instantiates a codemap outside of the compiler and passes a reference to the file currently under compilation to it. Note that the "file" might just be a REPL line. Change-Id: I131ae1ddb6d718e1374750da9ba0b99608c6058d Reviewed-on: https://cl.tvl.fyi/c/depot/+/6378 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4710 refactor(tvix/eval): add and use Compiler::push_op methodVincent Ambo1-60/+65
This is currently just a wrapper around Chunk::push_op, but will gain the span resolution logic in a moment. Change-Id: I862bf9ecff0932f8da6708401ea044b9442c5d5b Reviewed-on: https://cl.tvl.fyi/c/depot/+/6377 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4709 feat(tvix/eval): add data structures for tracking spans in chunksVincent Ambo1-0/+50
This adds a new vector to the chunk data structure which tracks spans into a codemap. The compiler will emit this information to the chunk when adding instructions. The internal representation of the spans is slightly optimised to avoid storing duplicate spans, as there are cases where many instructions might be derived from the same span. Change-Id: I336f8c912e7eb50ea02ed71e6164f651ca3ca790 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6376 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4706 fix(tvix/eval): address current clippy lintsVincent Ambo4-5/+5
Note that I've allowed `needless_lifetimes` for the attribute set iterator, as I find the type easier to understand with these annotations present. Change-Id: I33abb17837ee4813076cdb9a87f54bac4a37044e Reviewed-on: https://cl.tvl.fyi/c/depot/+/6373 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-07 r/4705 feat(tvix/eval): semi-strictly evaluate output values of the VMVincent Ambo3-4/+36
This essentially makes the VM behave like `nix-instantiate --eval --strict`, i.e. data structures are traversed strictly and thunks are forced. Thunks embedded in closures are not forced. This allows us to re-enable tests that were disabled because they needed to output nested thunk contents, but is overall a behaviour that must be configurable later on, as it is not cmopatible with e.g. an evaluation of nixpkgs. Change-Id: I5303a5c8e4322feab1384fdb7712fecb950afca5 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6372 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-07 r/4704 feat(tvix/eval): implement NixList::iterVincent Ambo1-0/+4
This does not require a custom iterator type (for now?) Change-Id: I5beb194bd8629571bd4040c69c977c27149807fa Reviewed-on: https://cl.tvl.fyi/c/depot/+/6371 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-07 r/4703 fix(tvix/eval): thread Display & PartialEq through to thunk valuesVincent Ambo2-1/+21
If a thunk is already evaluated, there are cases where due to the memoisation implementation something might observe a value wrapped in a thunk. In these cases, the implementation of `Display` and `PartialEq` must delegate to the underlying value. Note that there are a handful of other cases like these which we need to cover. It is a little tricky to write integration tests for these directly, especially as some of the open-upvalue optimisations coming down the pipe will reduce the number of observable thunks. One test that covers a part of this behaviour is currently disabled (needs some more machinery), but it's being brought back in the next commits. Change-Id: Iaa8cd338c12236af844bbc99d8cec2205f0d0095 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6370 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-07 r/4702 feat(tvix/eval): implement NixAttrs::iter()Vincent Ambo2-1/+121
Implementing iteration over NixAttrs requires a custom iterator type in order to encapsulate the different representations. The BTreeMap for example has its own iterator type which needs to be encapsulated. This is mostly boilerplate code, but for a change some simple unit tests have been added in. Change-Id: Ie13b063241d461b810876f95f53878388e918ef2 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6367 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>