sig
  module File_cache :
    sig
      type feedback = [ `File_cache_need_copy of B0_std.Fpath.t ]
      val pp_feedback : B00.File_cache.feedback B0_std.Fmt.t
      type key = string
      type t
      val create :
        ?feedback:(B00.File_cache.feedback -> unit) ->
        B0_std.Fpath.t -> (B00.File_cache.t, string) Stdlib.result
      val dir : B00.File_cache.t -> B0_std.Fpath.t
      val need_copy : B00.File_cache.t -> B0_std.Fpath.t option
      val mem : B00.File_cache.t -> B00.File_cache.key -> bool
      val add :
        B00.File_cache.t ->
        B00.File_cache.key ->
        string -> B0_std.Fpath.t list -> (bool, string) Stdlib.result
      val rem :
        B00.File_cache.t ->
        B00.File_cache.key -> (bool, string) Stdlib.result
      val find :
        B00.File_cache.t ->
        B00.File_cache.key ->
        ((B0_std.Fpath.t * B0_std.Fpath.t list) option, string) Stdlib.result
      val revive :
        B00.File_cache.t ->
        B00.File_cache.key ->
        B0_std.Fpath.t list ->
        ((string * B0_std.Fpath.t list) option, string) Stdlib.result
      val fold :
        B00.File_cache.t ->
        (B00.File_cache.key ->
         B0_std.Fpath.t -> B0_std.Fpath.t list -> '-> 'a) ->
        '-> ('a, string) Stdlib.result
      val keys :
        B00.File_cache.t -> (B00.File_cache.key list, string) Stdlib.result
      val is_unused :
        B00.File_cache.t ->
        B00.File_cache.key -> (bool, string) Stdlib.result
      val delete_unused : B00.File_cache.t -> (unit, string) Stdlib.result
      val trim_size :
        B00.File_cache.t ->
        max_byte_size:int -> pct:int -> (unit, string) Stdlib.result
      module Stats :
        sig
          type keys
          val keys_count : B00.File_cache.Stats.keys -> int
          val keys_file_count : B00.File_cache.Stats.keys -> int
          val keys_byte_size : B00.File_cache.Stats.keys -> int
          val keys_zero : B00.File_cache.Stats.keys
          val keys_sub :
            B00.File_cache.Stats.keys ->
            B00.File_cache.Stats.keys -> B00.File_cache.Stats.keys
          val pp_keys : B00.File_cache.Stats.keys B0_std.Fmt.t
          val of_keys :
            B00.File_cache.t ->
            B00.File_cache.key list ->
            (B00.File_cache.Stats.keys, string) Stdlib.result
          type cache
          val all_keys :
            B00.File_cache.Stats.cache -> B00.File_cache.Stats.keys
          val unused_keys :
            B00.File_cache.Stats.cache -> B00.File_cache.Stats.keys
          val pp : B00.File_cache.Stats.cache B0_std.Fmt.t
          val of_cache :
            B00.File_cache.t ->
            (B00.File_cache.Stats.cache, string) Stdlib.result
        end
    end
  module Op :
    sig
      module Spawn :
        sig
          type stdo =
              [ `File of B0_std.Fpath.t | `Tee of B0_std.Fpath.t | `Ui ]
          type success_exits = int list
          type t
          val env : B00.Op.Spawn.t -> B0_std.Os.Env.assignments
          val relevant_env : B00.Op.Spawn.t -> B0_std.Os.Env.assignments
          val cwd : B00.Op.Spawn.t -> B0_std.Fpath.t
          val stdin : B00.Op.Spawn.t -> B0_std.Fpath.t option
          val stdout : B00.Op.Spawn.t -> B00.Op.Spawn.stdo
          val stderr : B00.Op.Spawn.t -> B00.Op.Spawn.stdo
          val success_exits : B00.Op.Spawn.t -> B00.Op.Spawn.success_exits
          val tool : B00.Op.Spawn.t -> B0_std.Cmd.tool
          val args : B00.Op.Spawn.t -> B0_std.Cmd.t
          val stdo_ui :
            B00.Op.Spawn.t -> (string, string) Stdlib.result option
          val set_stdo_ui :
            B00.Op.Spawn.t -> (string, string) Stdlib.result option -> unit
          val result :
            B00.Op.Spawn.t -> (B0_std.Os.Cmd.status, string) Stdlib.result
          val set_result :
            B00.Op.Spawn.t ->
            (B0_std.Os.Cmd.status, string) Stdlib.result -> unit
          val pp_success_exits : int list B0_std.Fmt.t
          val pp_cmd : B00.Op.Spawn.t B0_std.Fmt.t
          val pp_stdo_ui : elide:bool -> B00.Op.Spawn.t B0_std.Fmt.t
          val pp_result :
            (B0_std.Os.Cmd.status, string) Stdlib.result B0_std.Fmt.t
          val pp : B00.Op.Spawn.t B0_std.Fmt.t
        end
      module Read :
        sig
          type t
          val file : B00.Op.Read.t -> B0_std.Fpath.t
          val result : B00.Op.Read.t -> (string, string) Stdlib.result
          val set_result :
            B00.Op.Read.t -> (string, string) Stdlib.result -> unit
          val pp_result : (string, string) Stdlib.result B0_std.Fmt.t
          val pp : B00.Op.Read.t B0_std.Fmt.t
        end
      module Write :
        sig
          type t
          val salt : B00.Op.Write.t -> string
          val mode : B00.Op.Write.t -> int
          val file : B00.Op.Write.t -> B0_std.Fpath.t
          val data : B00.Op.Write.t -> unit -> (string, string) Stdlib.result
          val result : B00.Op.Write.t -> (unit, string) Stdlib.result
          val set_result :
            B00.Op.Write.t -> (unit, string) Stdlib.result -> unit
          val pp_result : (unit, string) Stdlib.result B0_std.Fmt.t
          val pp : B00.Op.Write.t B0_std.Fmt.t
        end
      module Mkdir :
        sig
          type t
          val dir : B00.Op.Mkdir.t -> B0_std.Fpath.t
          val result : B00.Op.Mkdir.t -> (unit, string) Stdlib.result
          val set_result :
            B00.Op.Mkdir.t -> (unit, string) Stdlib.result -> unit
          val pp_result : (unit, string) Stdlib.result B0_std.Fmt.t
          val pp : B00.Op.Mkdir.t B0_std.Fmt.t
        end
      type kind =
          Spawn of B00.Op.Spawn.t
        | Read of B00.Op.Read.t
        | Write of B00.Op.Write.t
        | Mkdir of B00.Op.Mkdir.t
        | Wait_files
      val kind_name : B00.Op.kind -> string
      type status = Waiting | Executed | Cached | Failed | Aborted
      val pp_status : B00.Op.status B0_std.Fmt.t
      type id = int
      type t
      val id : B00.Op.t -> B00.Op.id
      val creation_time : B00.Op.t -> B0_std.Time.span
      val exec_start_time : B00.Op.t -> B0_std.Time.span
      val exec_end_time : B00.Op.t -> B0_std.Time.span
      val exec_duration : B00.Op.t -> B0_std.Time.span
      val status : B00.Op.t -> B00.Op.status
      val reads : B00.Op.t -> B0_std.Fpath.t list
      val writes : B00.Op.t -> B0_std.Fpath.t list
      val did_not_write : B00.Op.t -> B0_std.Fpath.t list
      val hash : B00.Op.t -> B0_std.Hash.t
      val kind : B00.Op.t -> B00.Op.kind
      val get_spawn : B00.Op.t -> B00.Op.Spawn.t
      val get_read : B00.Op.t -> B00.Op.Read.t
      val get_write : B00.Op.t -> B00.Op.Write.t
      val get_mkdir : B00.Op.t -> B00.Op.Mkdir.t
      val equal : B00.Op.t -> B00.Op.t -> bool
      val compare : B00.Op.t -> B00.Op.t -> int
      val pp : B00.Op.t B0_std.Fmt.t
      val pp_short : B00.Op.t B0_std.Fmt.t
      val pp_did_not_write : (B00.Op.t * B0_std.Fpath.t list) B0_std.Fmt.t
      val pp_spawn_status_fail : B00.Op.t B0_std.Fmt.t
      val set_exec_start_time : B00.Op.t -> B0_std.Time.span -> unit
      val set_exec_end_time : B00.Op.t -> B0_std.Time.span -> unit
      val set_status : B00.Op.t -> B00.Op.status -> unit
      val set_reads : B00.Op.t -> B0_std.Fpath.t list -> unit
      val set_writes : B00.Op.t -> B0_std.Fpath.t list -> unit
      val set_hash : B00.Op.t -> B0_std.Hash.t -> unit
      val spawn :
        id:B00.Op.id ->
        B0_std.Time.span ->
        reads:B0_std.Fpath.t list ->
        writes:B0_std.Fpath.t list ->
        env:B0_std.Os.Env.assignments ->
        relevant_env:B0_std.Os.Env.assignments ->
        cwd:B0_std.Fpath.t ->
        stdin:B0_std.Fpath.t option ->
        stdout:B00.Op.Spawn.stdo ->
        stderr:B00.Op.Spawn.stdo ->
        success_exits:B00.Op.Spawn.success_exits ->
        B0_std.Cmd.tool -> B0_std.Cmd.t -> B00.Op.t
      val read :
        id:B00.Op.id -> B0_std.Time.span -> B0_std.Fpath.t -> B00.Op.t
      val write :
        id:B00.Op.id ->
        B0_std.Time.span ->
        salt:string ->
        reads:B0_std.Fpath.t list ->
        mode:int ->
        write:B0_std.Fpath.t ->
        (unit -> (string, string) Stdlib.result) -> B00.Op.t
      val mkdir :
        id:B00.Op.id -> B0_std.Time.span -> B0_std.Fpath.t -> B00.Op.t
      val wait_files :
        id:B00.Op.id -> B0_std.Time.span -> B0_std.Fpath.t list -> B00.Op.t
      module Set :
        sig
          type t
          val empty : t
          val is_empty : t -> bool
          val mem : t -> t -> bool
          val add : t -> t -> t
          val singleton : t -> t
          val remove : t -> t -> t
          val union : t -> t -> t
          val inter : t -> t -> t
          val diff : t -> t -> t
          val compare : t -> t -> int
          val equal : t -> t -> bool
          val subset : t -> t -> bool
          val iter : (t -> unit) -> t -> unit
          val map : (t -> t) -> t -> t
          val fold : (t -> '-> 'a) -> t -> '-> 'a
          val for_all : (t -> bool) -> t -> bool
          val exists : (t -> bool) -> t -> bool
          val filter : (t -> bool) -> t -> t
          val partition : (t -> bool) -> t -> t * t
          val cardinal : t -> int
          val elements : t -> t list
          val min_elt : t -> t
          val min_elt_opt : t -> t option
          val max_elt : t -> t
          val max_elt_opt : t -> t option
          val choose : t -> t
          val choose_opt : t -> t option
          val split : t -> t -> t * bool * t
          val find : t -> t -> t
          val find_opt : t -> t -> t option
          val find_first : (t -> bool) -> t -> t
          val find_first_opt : (t -> bool) -> t -> t option
          val find_last : (t -> bool) -> t -> t
          val find_last_opt : (t -> bool) -> t -> t option
          val of_list : t list -> t
          val to_seq_from : t -> t -> t Seq.t
          val to_seq : t -> t Seq.t
          val add_seq : t Seq.t -> t -> t
          val of_seq : t Seq.t -> t
        end
      module Map :
        sig
          type +'a t
          val empty : 'a t
          val is_empty : 'a t -> bool
          val mem : t -> 'a t -> bool
          val add : t -> '-> 'a t -> 'a t
          val update : t -> ('a option -> 'a option) -> 'a t -> 'a t
          val singleton : t -> '-> 'a t
          val remove : t -> 'a t -> 'a t
          val merge :
            (t -> 'a option -> 'b option -> 'c option) ->
            'a t -> 'b t -> 'c t
          val union : (t -> '-> '-> 'a option) -> 'a t -> 'a t -> 'a t
          val compare : ('-> '-> int) -> 'a t -> 'a t -> int
          val equal : ('-> '-> bool) -> 'a t -> 'a t -> bool
          val iter : (t -> '-> unit) -> 'a t -> unit
          val fold : (t -> '-> '-> 'b) -> 'a t -> '-> 'b
          val for_all : (t -> '-> bool) -> 'a t -> bool
          val exists : (t -> '-> bool) -> 'a t -> bool
          val filter : (t -> '-> bool) -> 'a t -> 'a t
          val partition : (t -> '-> bool) -> 'a t -> 'a t * 'a t
          val cardinal : 'a t -> int
          val bindings : 'a t -> (t * 'a) list
          val min_binding : 'a t -> t * 'a
          val min_binding_opt : 'a t -> (t * 'a) option
          val max_binding : 'a t -> t * 'a
          val max_binding_opt : 'a t -> (t * 'a) option
          val choose : 'a t -> t * 'a
          val choose_opt : 'a t -> (t * 'a) option
          val split : t -> 'a t -> 'a t * 'a option * 'a t
          val find : t -> 'a t -> 'a
          val find_opt : t -> 'a t -> 'a option
          val find_first : (t -> bool) -> 'a t -> t * 'a
          val find_first_opt : (t -> bool) -> 'a t -> (t * 'a) option
          val find_last : (t -> bool) -> 'a t -> t * 'a
          val find_last_opt : (t -> bool) -> 'a t -> (t * 'a) option
          val map : ('-> 'b) -> 'a t -> 'b t
          val mapi : (t -> '-> 'b) -> 'a t -> 'b t
          val to_seq : 'a t -> (t * 'a) Seq.t
          val to_seq_from : t -> 'a t -> (t * 'a) Seq.t
          val add_seq : (t * 'a) Seq.t -> 'a t -> 'a t
          val of_seq : (t * 'a) Seq.t -> 'a t
        end
    end
  module Op_cache :
    sig
      type t
      val create :
        ?clock:B0_std.Time.counter ->
        ?hash_fun:(module B0_std.Hash.T->
        B00.File_cache.t -> B00.Op_cache.t
      val set_op_hash :
        B00.Op_cache.t -> B00.Op.t -> (unit, string) Stdlib.result
      val revive :
        B00.Op_cache.t ->
        B00.Op.t -> (B0_std.Fpath.t list option, string) Stdlib.result
      val add : B00.Op_cache.t -> B00.Op.t -> (bool, string) Stdlib.result
      val hash_fun : B00.Op_cache.t -> (module B0_std.Hash.T)
      val file_hashes : B00.Op_cache.t -> B0_std.Hash.t B0_std.Fpath.Map.t
      val file_hash_dur : B00.Op_cache.t -> B0_std.Time.span
    end
  module Guard :
    sig
      type feedback =
          [ `File_status_repeat of B0_std.Fpath.t
          | `File_status_unstable of B0_std.Fpath.t ]
      type t
      val create :
        ?feedback:(B00.Guard.feedback -> unit) -> unit -> B00.Guard.t
      val set_file_ready : B00.Guard.t -> B0_std.Fpath.t -> unit
      val set_file_never : B00.Guard.t -> B0_std.Fpath.t -> unit
      val add : B00.Guard.t -> B00.Op.t -> unit
      val allowed : B00.Guard.t -> B00.Op.t option
      val guarded_ops : B00.Guard.t -> B00.Op.t list
      val ready_files : B00.Guard.t -> B0_std.Fpath.Set.t
      val never_files : B00.Guard.t -> B0_std.Fpath.Set.t
      val undecided_files : B00.Guard.t -> B0_std.Fpath.Set.t
      val root_undecided_files : B00.Guard.t -> B0_std.Fpath.Set.t
    end
  module Exec :
    sig
      type feedback = [ `Exec_submit of B0_std.Os.Cmd.pid option * B00.Op.t ]
      val pp_feedback : B00.Exec.feedback B0_std.Fmt.t
      type t
      val create :
        ?clock:B0_std.Time.counter ->
        ?rand:Stdlib.Random.State.t ->
        ?tmp_dir:B0_std.Fpath.t ->
        ?feedback:(B00.Exec.feedback -> unit) ->
        max_spawn:int -> unit -> B00.Exec.t
      val schedule : B00.Exec.t -> B00.Op.t -> unit
      val collect : B00.Exec.t -> block:bool -> B00.Op.t option
    end
  module Env :
    sig
      type tool_lookup =
          B0_std.Cmd.tool -> (B0_std.Fpath.t, string) Stdlib.result
      val env_tool_lookup :
        ?sep:string -> ?var:string -> B0_std.Os.Env.t -> B00.Env.tool_lookup
      type t
      val v :
        ?lookup:B00.Env.tool_lookup ->
        ?forced_env:B0_std.Os.Env.t -> B0_std.Os.Env.t -> B00.Env.t
      val env : B00.Env.t -> B0_std.Os.Env.t
      val forced_env : B00.Env.t -> B0_std.Os.Env.t
      val tool :
        B00.Env.t ->
        B0_std.Cmd.tool -> (B0_std.Fpath.t, string) Stdlib.result
    end
  module Tool :
    sig
      type env_vars = string list
      val tmp_vars : B00.Tool.env_vars
      type response_file
      val response_file_of :
        (B0_std.Cmd.t -> string) ->
        (B0_std.Fpath.t -> B0_std.Cmd.t) -> B00.Tool.response_file
      val args0 : B00.Tool.response_file
      type t
      val v :
        ?response_file:B00.Tool.response_file ->
        ?shielded_vars:B00.Tool.env_vars ->
        ?vars:B00.Tool.env_vars -> B0_std.Cmd.tool -> B00.Tool.t
      val by_name :
        ?response_file:B00.Tool.response_file ->
        ?shielded_vars:B00.Tool.env_vars ->
        ?vars:B00.Tool.env_vars -> string -> B00.Tool.t
      val name : B00.Tool.t -> B0_std.Cmd.tool
      val vars : B00.Tool.t -> B00.Tool.env_vars
      val shielded_vars : B00.Tool.t -> B00.Tool.env_vars
      val response_file : B00.Tool.t -> B00.Tool.response_file option
      val read_env :
        B00.Tool.t -> B0_std.Os.Env.t -> B0_std.Os.Env.t * B0_std.Os.Env.t
    end
  module Memo :
    sig
      type feedback =
          [ `Fiber_exn of exn * Stdlib.Printexc.raw_backtrace
          | `Fiber_fail of string
          | `Miss_tool of B00.Tool.t * string
          | `Op_cache_error of B00.Op.t * string
          | `Op_complete of
              B00.Op.t * [ `Did_not_write of B0_std.Fpath.t list ] ]
      val pp_feedback : B00.Memo.feedback B0_std.Fmt.t
      type t
      val create :
        ?clock:B0_std.Time.counter ->
        ?cpu_clock:B0_std.Time.cpu_counter ->
        feedback:(B00.Memo.feedback -> unit) ->
        cwd:B0_std.Fpath.t ->
        B00.Env.t ->
        B00.Guard.t -> B00.Op_cache.t -> B00.Exec.t -> B00.Memo.t
      val memo :
        ?hash_fun:(module B0_std.Hash.T->
        ?env:B0_std.Os.Env.t ->
        ?cwd:B0_std.Fpath.t ->
        ?cachedir:B0_std.Fpath.t ->
        ?max_spawn:int ->
        ?feedback:([ `Exec_submit of B0_std.Os.Cmd.pid option * B00.Op.t
                   | `Fiber_exn of exn * Stdlib.Printexc.raw_backtrace
                   | `Fiber_fail of string
                   | `File_cache_need_copy of B0_std.Fpath.t
                   | `Miss_tool of B00.Tool.t * string
                   | `Op_cache_error of B00.Op.t * string
                   | `Op_complete of
                       B00.Op.t * [ `Did_not_write of B0_std.Fpath.t list ] ] ->
                   unit) ->
        unit -> (B00.Memo.t, string) Stdlib.result
      val clock : B00.Memo.t -> B0_std.Time.counter
      val cpu_clock : B00.Memo.t -> B0_std.Time.cpu_counter
      val env : B00.Memo.t -> B00.Env.t
      val op_cache : B00.Memo.t -> B00.Op_cache.t
      val guard : B00.Memo.t -> B00.Guard.t
      val exec : B00.Memo.t -> B00.Exec.t
      val hash_fun : B00.Memo.t -> (module B0_std.Hash.T)
      val stir : block:bool -> B00.Memo.t -> unit
      val finish : B00.Memo.t -> (unit, B0_std.Fpath.Set.t) Stdlib.result
      val ops : B00.Memo.t -> B00.Op.t list
      type 'a fiber = ('-> unit) -> unit
      val fail : ('b, Stdlib.Format.formatter, unit, 'a) Stdlib.format4 -> 'b
      val fail_error : ('a, string) Stdlib.result -> 'a
      val file_ready : B00.Memo.t -> B0_std.Fpath.t -> unit
      val wait_files :
        B00.Memo.t -> B0_std.Fpath.t list -> unit B00.Memo.fiber
      val read : B00.Memo.t -> B0_std.Fpath.t -> string B00.Memo.fiber
      val write :
        B00.Memo.t ->
        ?salt:string ->
        ?reads:B0_std.Fpath.t list ->
        ?mode:int ->
        B0_std.Fpath.t -> (unit -> (string, string) Stdlib.result) -> unit
      val mkdir : B00.Memo.t -> B0_std.Fpath.t -> unit B00.Memo.fiber
      type tool
      type cmd
      val tool : B00.Memo.t -> B00.Tool.t -> B0_std.Cmd.t -> B00.Memo.cmd
      val spawn :
        B00.Memo.t ->
        ?reads:B0_std.Fpath.t list ->
        ?writes:B0_std.Fpath.t list ->
        ?env:B0_std.Os.Env.t ->
        ?cwd:B0_std.Fpath.t ->
        ?stdin:B0_std.Fpath.t ->
        ?stdout:B00.Op.Spawn.stdo ->
        ?stderr:B00.Op.Spawn.stdo ->
        ?success_exits:B00.Op.Spawn.success_exits ->
        ?k:(int -> unit) -> B00.Memo.cmd -> unit
      module Fut :
        sig
          type 'a set
          val set : 'B00.Memo.Fut.set -> '-> unit
          type memo = B00.Memo.t
          type 'a t
          val create :
            B00.Memo.Fut.memo -> 'B00.Memo.Fut.t * 'B00.Memo.Fut.set
          val value : 'B00.Memo.Fut.t -> 'a option
          val wait : 'B00.Memo.Fut.t -> 'B00.Memo.fiber
        end
    end
end