ace-runtime 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +58 -0
  3. data/README.md +9 -0
  4. data/docs/usage.md +123 -0
  5. data/lib/ace/runtime/molecules/cgroup_observation.rb +148 -0
  6. data/lib/ace/runtime/molecules/codex_runtime_installation.rb +130 -0
  7. data/lib/ace/runtime/molecules/execution_boot_baseline.rb +134 -0
  8. data/lib/ace/runtime/molecules/execution_network_selection.rb +85 -0
  9. data/lib/ace/runtime/molecules/execution_unit_installation.rb +663 -0
  10. data/lib/ace/runtime/molecules/kernel_view_topology.rb +133 -0
  11. data/lib/ace/runtime/molecules/linux_mount_info.rb +101 -0
  12. data/lib/ace/runtime/molecules/network_installation_evidence.rb +332 -0
  13. data/lib/ace/runtime/molecules/process_identity.rb +123 -0
  14. data/lib/ace/runtime/molecules/protected_artifact_set.rb +211 -0
  15. data/lib/ace/runtime/molecules/protected_linux.rb +118 -0
  16. data/lib/ace/runtime/molecules/protected_socket.rb +119 -0
  17. data/lib/ace/runtime/molecules/protected_task_context_entry.rb +162 -0
  18. data/lib/ace/runtime/molecules/protected_worker_entry.rb +32 -0
  19. data/lib/ace/runtime/molecules/readiness_configuration.rb +154 -0
  20. data/lib/ace/runtime/molecules/readiness_runtime.rb +94 -0
  21. data/lib/ace/runtime/molecules/server_resource_observation.rb +183 -0
  22. data/lib/ace/runtime/molecules/systemd_scope_manager.rb +411 -0
  23. data/lib/ace/runtime/testing/adapter_contract.rb +9 -0
  24. data/lib/ace/runtime/version.rb +1 -1
  25. data/lib/ace/runtime.rb +3 -0
  26. data/native/README.md +124 -0
  27. data/native/build-worker-gate +20 -0
  28. data/native/worker_gate.c +385 -0
  29. metadata +63 -2
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+ require "json"
3
+ require_relative "protected_artifact_set"
4
+
5
+ module Ace
6
+ module Runtime
7
+ module Molecules
8
+ # Current selection only. Original canonical bindings retain literal refs
9
+ # and authenticate through NetworkInstallationEvidence without this pointer.
10
+ class ExecutionNetworkSelection
11
+ LIMIT = 65_536
12
+ FIELDS = %w[installer_artifact policy_export profile report].freeze
13
+
14
+ def initialize(artifacts: ProtectedArtifactSet.new)
15
+ @artifacts = artifacts
16
+ end
17
+
18
+ # Shape validation confers no pointer access or network admission proof.
19
+ def self.validate_static!(selection, slot_id:)
20
+ new.send(:static!, selection, slot_id)
21
+ end
22
+
23
+ def select!(static_selection:, slot_id:)
24
+ static_selection = immutable(static_selection)
25
+ path = static!(static_selection, slot_id)
26
+ @artifacts.with do
27
+ bytes, = @artifacts.read_path!(path, limit: LIMIT)
28
+ bytes = bytes.dup.force_encoding(Encoding::UTF_8)
29
+ refuse! unless bytes.valid_encoding? && bytes.bytesize.between?(1, LIMIT)
30
+ pointer = JSON.parse(bytes, create_additions: false, max_nesting: 16, allow_duplicate_key: false, allow_comments: false)
31
+ object!(pointer, %w[schema selection slot_id])
32
+ refuse! unless pointer["schema"] == "ace.network-installation-selection/v1" && pointer["slot_id"] == slot_id
33
+ selection = pointer.fetch("selection")
34
+ object!(selection, FIELDS)
35
+ selection.each_value { |ref| reference!(ref) }
36
+ refuse! unless %w[profile installer_artifact].all? { |name| selection.fetch(name) == static_selection.fetch(name) }
37
+ selection.each_value { |ref| @artifacts.read!(ref) }
38
+ @artifacts.verify_unchanged!
39
+ immutable(selection)
40
+ end
41
+ rescue KeyError, TypeError, NoMethodError, ArgumentError, IOError, SystemCallError, JSON::ParserError, EncodingError
42
+ refuse!
43
+ end
44
+
45
+ private
46
+
47
+ def static!(selection, slot_id)
48
+ object!(selection, %w[current_selection_path installer_artifact profile])
49
+ refuse! unless slot_id.is_a?(String) && slot_id.match?(/\A[A-Za-z0-9][A-Za-z0-9._-]{0,127}\z/)
50
+ path = "/etc/ace/execution-slots/#{slot_id}/network-installation-selection.json"
51
+ refuse! unless selection.fetch("current_selection_path") == path
52
+ %w[profile installer_artifact].each { |name| reference!(selection.fetch(name)) }
53
+ path
54
+ rescue KeyError, TypeError, NoMethodError, ArgumentError
55
+ refuse!
56
+ end
57
+
58
+ def reference!(value)
59
+ object!(value, %w[bytes path sha256])
60
+ path = value.fetch("path")
61
+ refuse! unless path.is_a?(String) && path.bytesize.between?(1, 4096) && path.start_with?("/") &&
62
+ !path.include?("\0") && File.expand_path(path) == path && value["bytes"].is_a?(Integer) &&
63
+ value["bytes"].between?(1, ProtectedArtifactSet::LIMIT) && value["sha256"].is_a?(String) &&
64
+ value["sha256"].match?(/\A[0-9a-f]{64}\z/)
65
+ end
66
+
67
+ def object!(value, keys)
68
+ refuse! unless value.is_a?(Hash) && value.keys.sort == keys.sort
69
+ end
70
+
71
+ def immutable(value)
72
+ case value
73
+ when Hash then value.to_h { |key, item| [key.dup.freeze, immutable(item)] }.freeze
74
+ when String then value.dup.freeze
75
+ else value
76
+ end
77
+ end
78
+
79
+ def refuse!
80
+ raise RuntimeUnavailableError, "protected current network selection unavailable"
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end