123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154(** Assumptions baked into MlFront_Exec.
Assumptions are no-op functions that can be referenced in documentation and
in source code. Using a reference to an assumption makes that documentation
and/or source code break if the assumption function is deleted or renamed.
Said another way, when the assumption changes the source code will fail to
compile.
You can and should reference these assumptions if you rely on the
assumption. *)(** When we have an untrusted filesystem the hash in the trace must include the
SHA256 hash of the file contents. That reduces the trust to just the trace
store and not the entire value store. *)letuntrusted_filesystem_requires_hash_in_trace_with_sha256_of_values()=()(** The values files do not need to be loaded at startup into the store.
That way, we don't have to waste memory and startup time on that, although
we can choose to make that tradeoff in the future. (That is, perhaps we'll
have a cache in the future).
But regardless, the fallback is that whenever a Checksum valuesfile key is
encountered that is missing (esp. from the constructive trace store), we
check the filesystem and if there we load it on demand. *)letvalues_files_loaded_on_demand_from_filesystem()=()(** Cannot assume that an bundle trace and an asset trace with a SHA256 hash of
a values file will come before the values file trace (ie. both
["values.json"] and the parsed AST trace of it) that has that SHA256 hash in
the constructive trace store.
It may seem like a simple consequence of implicit topological sorting of
dependencies, but the order of the dependencies in a
[(k, dependencies, result)] trace does not need to be topologically sorted,
even if logically they have to be executed in some topological sort order.
*)letcannot_assume_asset_and_assets_come_before_values_files_in_traces()=()(** Both the trace store and lock files maintain the build metadata for all user
module keys (ie. user form/bundle/asset keys).
The values for user module keys are object values.
Even asset keys have lockfile entries since the module key itself does not
know the asset checksum. It can't because one of the user scenarios to
create an asset key ... a user enters "get-asset ID@VERSION ..." ... the
user has no way of knowing the checksum. *)letboth_tracestore_and_lockfiles_resolve_build_metadata_for_user_module_keys()=()(** The protobuf trace store has local files ["values_file_local"] and
["asset_values_file_local"] that may be come from an external malicious
source or be out-of-date. We want the local file so that errors are reported
in the right file.
However, only if the SHA256 hash from the trace store agrees with the local
file do we use the local file. *)letno_trust_for_local_values_file()=()(** The values file task uses SHA256 of the values file as its key. *)letvalues_task_includes_sha256_of_values_file_in_key()=()(** Forms are the public interface for distributions. If a form does not
reference a specific bundle or a specific asset through a ["get-bundle"] or
["get-asset"] in ["precommands"], transitively, it is not part of the
distribution.
The form as public interface simplifies how to define a distribution. If we
included named assets (or all assets), there is a danger that a huge bundle
would be generated but not used. And if we included bundle files, then the
distributor would have to specify all the bundle paths ... and if so it
would be easy to make mistakes. *)letforms_are_public_interface_for_distributions()=()(** As of October 2025, both the 1Password desktop UI and GitHub CLI do not
support multiline secrets.
So the build keys will be stored pipe-separated (or more accurately, we'll
give it to the user pipe-separated, who will then store it), and the build
keys will be validated to not contain pipes.
Confer: {:https://news.ycombinator.com/item?id=30361847} and
{:https://github.com/1Password/onepassword-operator/issues/82}.
{:https://cli.github.com/manual/gh_secret_set} is not explicit that
copy-and-paste is a single line, but it is. *)letbuild_keys_have_no_pipes_and_store_pipe_separated()=()(** A distribution that has not been accepted will not be in the trace store,
and a distribution that has been accepted will be in the trace store.
"Acceptance" is two parts:
+ license: {i skipped} if the license text has already been accepted
regardless of the distribution, {i automatic} if the distribution license
is highly permissive (Model, Gold and Silver in the Blue Oak license
list), and {i asked} for any other license.
+ producer: {i skipped} if the producer has already been accepted, and
{i asked} if the producer has not been accepted.
Once both parts are accepted, the trace store and value store of the
distribution is merged into the running trace store.
The distribution can't be accepted until it is known, which means that the
distribution must be present in the include directories. *)letaccepted_distributions_are_present_in_trace_store()=()(** A distribution can only be known if it is in the include directories or if
it is in the current trace store in the ["dist_json"] protobuf field.
That means that there are no implicit distributions. And the only way for a
distribution to be seen is to stick it in the include directories (ex.
["import-github-l2"]) or stick it in a trace store.
Recall that trace stores are downloaded from an accepted distribution
(confer {!accepted_distributions_are_present_in_trace_store}). So if a trace
store B on an accepted distribution D1 asset includes the protobuf JSON text
field ["dist_json"] for another distribution D2, that other distribution D2
will be seen by you. Not only that, but D2 will be
{b automatically accepted} since B was merged into the running trace store,
and {!accepted_distributions_are_present_in_trace_store} makes it accepted.
In other words,
{b transitive distributions of trusted distributions are automatically
accepted}. *)letdistribution_entry_points_only_trace_stores_and_include_dirs()=()(** Distributions are added in semver ascending order.
This ascending order is what allows for continuations to be verified. *)letdistributions_added_in_semver_ascending_order()=()(** ["Our"] vendor modules like ["OurFoo_Bar.X.Y.Z"] and ["MlFront_Attestation"]
and ["MlFront_Std"] library modules like ["MlFront_Attestation.GitHubCLI"]
cannot be distributed. *)letdistributions_fetched_for_all_modules_except_Our_vendor_and_mlfront_modules()=()(** The ["MlFront_Attestation.*"] modules are embedded in the binary and can't
be imported from an include directory or trace store. *)letmlfrontattestation_modules_are_embedded_and_cannot_be_imported()=()(** The ["MlFront_Std.*"] modules are embedded in the binary and can't be
imported from an include directory or trace store. *)letmlfrontstd_modules_are_embedded_and_cannot_be_imported()=()letpersisted_values_are_checked_for_existence_during_trace_store_load()=()(** Parsed values are purely a starutp optimization. They must be reparsed if
the parsed values are incompatible with the runtime (ex. they are copied
between OCaml 4.14 and OCaml 5.4, or 32-bit to 64-bit). *)letparsed_values_are_reparsed_when_incompatible_with_runtime()=()letimports_from_distributions_skip_constant_values()=()