3"""Cross-language source policy for the devcontainer image selftest harness."""
5from __future__
import annotations
7import hil_convergence_safety_image_process_analysis
as image_process_analysis
9_IMAGE_PROCESS_ANALYSIS_MODULE =
"hil_convergence_safety_image_process_analysis"
10_IMAGE_PROCESS_ANALYSIS_IMPORT = (
11 "import " + _IMAGE_PROCESS_ANALYSIS_MODULE +
" as image_process_analysis"
13ModuleSpec = tuple[str, str, tuple[str, ...]]
16def _exact_shell_token_errors(source: str, label: str, tokens: tuple[str, ...]) -> list[str]:
17 """Require each security-sensitive shell token exactly once."""
19 f
"{label}: required process-authority token is not unique: {token}"
21 if source.count(token) != 1
25def _image_lifecycle_process_errors(lifecycle: str, bound_exit: str) -> list[str]:
26 """Require exact lifecycle allocation and child-process authorities."""
27 return _exact_shell_token_errors(
28 f
"{lifecycle}\n{bound_exit}",
29 "devcontainer image lifecycle selftest",
31 "live_child_jobspec() {",
32 "done < <(jobs -r -l)",
33 'builtin kill -"$signal" "$child"',
34 "selftest_suite_root_is_safe() {",
35 "selftest_suite_anchor_is_safe() {",
36 "selftest_suite_path_is_safe() {",
37 "configure_selftest_suite_authority() {",
38 "configure_bound_exit_nested_suite() {",
39 "publish_bound_exit_nested_root() {",
40 "establish_selftest_suite_root() {",
41 "set_selftest_shell_identity() {",
42 'local destination="$1" value="$$:${BASH_SUBSHELL:-0}"',
43 "SELFTEST_DEADLINE_STEPS=200",
44 ': "$SELFTEST_DEADLINE_STEPS"',
45 "od -An -N16 -tx1 /dev/urandom",
46 'if (umask 077 && mkdir -m 0700 -- "$candidate"); then',
47 '"$suffix" =~ ^[0-9a-f]{32}$ && ! -L "$canonical"',
48 '"$(file_identity "$anchor")" == "$SELFTEST_SUITE_ANCHOR_IDENTITY"',
49 '"$SELFTEST_SUITE_ROOT_OWNER_UID" == "$SELFTEST_SUITE_ANCHOR_OWNER_UID"',
50 "run_bound_exit_supervisor() {",
51 'RA8_SELFTEST_BOUND_ENTRY="$1"',
52 '"${BASH_SOURCE[1]:-missing}" -ef "$SELFTEST_HELPER_PARENT"',
53 '"${DEVCONTAINER_SELFTEST_PARENT:-}" == '
54 '"$SELFTEST_HELPER_PARENT_DIR/devcontainer_image.sh"',
55 "selftest_descriptor_bound_entry() {",
56 'RA8_SELFTEST_BOUND_ENTRY="$wrong_entry"',
57 'RA8_SELFTEST_BOUND_ENTRY="$SCRIPT_DIR/devcontainer_image.sh"',
58 'select_selftest_group_id "$tmp" "$rejected" >/dev/null 2>&1 && return 1\n'
60 "write_supervisor_stall_fixture() {",
61 ' "exec -a \\"\\$0\\" /bin/sleep 30" >"$destination") || return 1',
62 "selftest_bound_exit_supervisor_failures() {",
63 'run_bound_exit_supervisor --selftest-parent-death "$stall_entry" "$tmp"',
64 'run_bound_exit_supervisor --selftest-watchdog-expiry "$stall_entry" "$tmp"',
65 'run_bound_exit_supervisor --selftest-closed-death-fd "$stall_entry" "$tmp"',
66 'run_bound_exit_supervisor --selftest-closed-entry-fd "$stall_entry" "$tmp"',
67 'run_bound_exit_supervisor --selftest-hardlink-bound "$stall_entry" "$tmp"',
68 'RA8_SELFTEST_NESTED_PARENT_IDENTITY="$SELFTEST_TMP_IDENTITY"',
69 'RA8_SELFTEST_NESTED_ROOT_RECEIPT="$nested_receipt"',
70 'run_bound_exit_supervisor "$stall_entry" "$bound" "$outer"',
71 'run_bound_exit_supervisor --selftest-missing-entry "$tmp"',
72 'run_bound_exit_supervisor --selftest-entry-binding "$tmp"',
77def _image_cases_process_errors(cases: str) -> list[str]:
78 """Require exact case-controller authorities."""
79 errors = _exact_shell_token_errors(
81 "devcontainer image cases selftest",
83 "configure_bound_exit_nested_suite || die",
84 "publish_bound_exit_nested_root || die",
85 'selftest_pre_isolation_exit_refusal "$tmp" ||',
86 'signal_owned_live_child KILL "$child" ||',
87 "stale allocation child PID retained signal authority",
88 'establish_selftest_suite_root || die "selftest: could not bind its suite root"',
89 'clear_selftest_suite_root || die "selftest: suite-root cleanup did not complete"',
90 '--selftest-allocation-checkpoint-child "$phase" "$receipt"',
91 '"${BASH_SOURCE[1]:-missing}" -ef "$SELFTEST_CASES_PARENT"',
92 '"${DEVCONTAINER_SELFTEST_PARENT:-}" == '
93 '"$SELFTEST_CASES_PARENT_DIR/devcontainer_image.sh"',
94 "selftest_temp_root_is_safe() {",
95 '"$SELFTEST_TMP_ROOT" == "$(cd -P /tmp && pwd)" &&',
96 '"$(file_special_mode "$SELFTEST_TMP_ROOT")" == "1777" ]]',
97 '"$SELFTEST_TMP_ROOT" == "$SELFTEST_SUITE_ROOT" &&',
99 '"$SELFTEST_TMP_ROOT_IDENTITY" == "$SELFTEST_SUITE_ROOT_IDENTITY" ]] &&\n'
100 " selftest_suite_root_is_safe"
102 'selftest_temp_root_is_safe || die "selftest: allocation parent authority is unsafe"',
103 'selftest_descriptor_bound_entry "$tmp" ||',
104 'selftest_controller_persisted_ps_failure "$tmp"',
107 errors += _exact_shell_token_errors(
108 cases,
"devcontainer image cases selftest", (
'selftest_ps_failure_cleanup "$tmp"',)
113def _image_signal_process_errors(signal_source: str) -> list[str]:
114 """Require exact isolated signal-controller authorities."""
115 return _exact_shell_token_errors(
117 "devcontainer image signal selftest",
119 'local launcher_mode="${5:-}" controller_pid pending '
120 'ready="$3/controller-launcher.ready"',
121 '--selftest-case-signal-child "$signal" "$tmp" "$SELFTEST_TMP_IDENTITY"',
122 'signal_owned_live_child TERM "$controller_pid" || controller_bound_spawn_signal 1',
123 "selftest_pre_isolation_exit_refusal() {",
124 '! signal_owned_live_child TERM "$child" || controller_bound_spawn_signal 1',
125 "signal_owned_controller_group() {",
126 'controller_group_signal_is_authorized "$controller" || return 1',
127 'builtin kill -"$signal" -- "-$controller"',
128 'signal_owned_controller_group "$signal" "$controller" ||',
129 'signal_owned_controller_group TERM "$controller" ||',
130 '"${BASH_SOURCE[1]:-missing}" -ef "$SELFTEST_SIGNAL_PARENT"',
131 '"${DEVCONTAINER_SELFTEST_PARENT:-}" == '
132 '"$SELFTEST_SIGNAL_PARENT_DIR/devcontainer_image.sh"',
133 'kill -KILL -- "-$controller" 2>/dev/null || bounded_group_gone "$controller"',
138def _image_lock_process_errors(
139 lifecycle: str, cases: str, signal_source: str, lock: str
141 """Reject unsafe lock-helper PID and portability fallbacks."""
142 errors = _exact_shell_token_errors(
144 "devcontainer image-lock selftest",
146 "worker_group_signal_is_authorized() {",
147 "image_lock_ps_group_snapshot() {",
148 'signal_owned_controller_group TERM "$controller"',
149 "SELFTEST_CONTROLLER_CLEANUP_STEPS=1600",
150 'wait_for_worker_ack "$case_dir" "$$" || exit 124',
151 'if wait "$SELFTEST_BOUND_DIRECT_CHILD"; then child_status=0; else child_status=$?; fi',
152 "rebound numeric process group gained signal authority",
153 "pre-ready-hang | signal-controller | post-ready-build-hang) trap '' HUP INT TERM ;;",
154 "repeated ps failure left a signal-ignoring descendant",
155 '"${BASH_SOURCE[1]:-missing}" -ef "$SELFTEST_LOCK_HELPER_PARENT"',
156 '"${DEVCONTAINER_SELFTEST_PARENT:-}" == '
157 '"$SELFTEST_LOCK_HELPER_PARENT_DIR/devcontainer_image.sh"',
161 'kill -TERM "$controller"',
162 'kill -KILL "$controller"',
163 'signal_owned_live_child KILL "$controller"',
164 'signal_owned_live_child TERM "$controller"',
165 'kill -TERM "$SELFTEST_WORKER_PID"',
167 if any(token
in lock
for token
in forbidden):
168 errors.append(
"devcontainer image-lock selftest: bare PID signal fallback returned")
169 if 'mktemp -d "$SELFTEST_TMP_ROOT/' in lifecycle:
170 errors.append(
"devcontainer image lifecycle selftest: allocation-before-binding returned")
171 if any(
"BASHPID" in source
for source
in (lifecycle, cases, signal_source, lock)):
172 errors.append(
"devcontainer image selftest: macOS Bash 3.2 BASHPID dependency returned")
176def _image_supervisor_token_errors(
177 supervisor: str, cases_source: str, process_source: str
179 """Delegate Python process-authority checking to its focused module."""
180 return image_process_analysis.supervisor_errors(supervisor, cases_source, process_source)
183def _semantic_aggregator_errors(source: str) -> list[str]:
184 """Require every split runtime selftest to remain imported and dispatched."""
185 return _exact_shell_token_errors(
187 "hil convergence semantic selftest",
189 "import hil_convergence_safety_process_mutations as process_mutations",
190 _IMAGE_PROCESS_ANALYSIS_IMPORT,
191 "import hil_convergence_safety_raw_digest_runtime as raw_digest_runtime",
192 "import hil_convergence_safety_runtime_cleanup as runtime_cleanup",
193 "import hil_convergence_safety_runtime_escape as runtime_escape",
194 "import hil_convergence_safety_runtime_mutations as runtime_mutations",
195 "process_mutations.process_authority_mutations()",
196 "image_process_analysis.semantic_process_findings(label)",
197 "raw_digest_runtime.cases(inputs)",
198 "runtime_cleanup.cases(inputs)",
199 "runtime_escape.cases(inputs)",
200 "runtime_mutations.runtime_cases(inputs)",
205def _runtime_module_specs(inputs: dict[str, str]) -> tuple[ModuleSpec, ...]:
206 """Return runtime cleanup, loader, mutation, and escape bindings."""
210 inputs[
"runtime_cleanup"],
212 "import hil_convergence_safety_runtime_loader as runtime_loader",
213 "runtime_loader.cases(inputs)",
218 inputs[
"runtime_loader"],
220 "import hil_convergence_safety_runtime_loader_harness as loader_harness",
221 "loader_harness.run(",
226 inputs[
"runtime_mutations"],
228 "import hil_convergence_safety_runtime_launcher as runtime_launcher",
229 "import hil_convergence_safety_runtime_sources as runtime_sources",
230 "import hil_convergence_safety_runtime_root_swap as runtime_root_swap",
231 "_write_sources = runtime_sources.publish",
232 "runtime_launcher.launch(",
237 inputs[
"runtime_escape"],
238 (
"from hil_convergence_safety_runtime_mutations import (",),
243def _image_module_specs(inputs: dict[str, str]) -> tuple[ModuleSpec, ...]:
244 """Return image analysis, harness, and mutation-catalog bindings."""
247 "image process analysis",
248 inputs[
"image_process_analysis"],
250 "import hil_convergence_safety_image_process_policy as catalog",
251 "import hil_convergence_safety_image_subreaper_policy as subreaper_policy",
252 "CROSS_LANGUAGE_SCOPED_TOKENS = catalog.CROSS_LANGUAGE_SCOPED_TOKENS",
253 "subreaper_policy.errors(supervisor, process_source)",
257 "image harness policy",
258 inputs[
"image_harness_policy"],
260 _IMAGE_PROCESS_ANALYSIS_IMPORT,
261 "image_process_analysis."
263 "supervisor, cases_source, process_source)",
264 "image_process_analysis." +
"source_errors(inputs)",
268 "process mutation catalog",
269 inputs[
"process_mutations"],
271 "import hil_convergence_safety_process_source_fixtures as process_source_fixtures",
272 "import hil_convergence_safety_runtime_fixtures as runtime_fixtures",
273 "import hil_convergence_safety_source_fixtures as source_fixtures",
274 "process_source_fixtures.process_authority_mutations()",
275 "runtime_fixtures.process_authority_mutations()",
276 "*source_fixtures.process_authority_mutations(),",
282def _image_dispatch_specs(inputs: dict[str, str]) -> tuple[ModuleSpec, ...]:
283 """Return the public checker and authenticated shell-loader bindings."""
286 "image harness consumer",
287 inputs[
"hil_convergence_entry"],
289 "import hil_convergence_safety_image_harness_policy as image_harness_policy",
290 "image_harness_policy.errors(inputs)",
294 "bound-exit helper loader",
295 inputs[
"devcontainer_image"],
297 "SELFTEST_BOUND_EXIT_RAW_SHA256=",
298 'source_approved_selftest_helper "$SCRIPT_DIR/'
299 'devcontainer_image_bound_exit_selftest.bash"',
300 '"$SELFTEST_BOUND_EXIT_RAW_SHA256"',
306def _split_runtime_module_errors(inputs: dict[str, str]) -> list[str]:
307 """Bind every focused split helper to one exact production consumer."""
309 *_runtime_module_specs(inputs),
310 *_image_module_specs(inputs),
311 *_image_dispatch_specs(inputs),
314 for label, source, tokens
in specifications:
315 errors.extend(_exact_shell_token_errors(source, label, tokens))
319def errors(inputs: dict[str, str]) -> list[str]:
320 """Bind signal cleanup to live jobs and bounded process-enumeration failure."""
321 lifecycle = inputs[
"devcontainer_image_selftest"]
322 bound_exit = inputs[
"devcontainer_image_bound_exit_selftest"]
323 cases = inputs[
"devcontainer_image_selftest_cases"]
324 signal_source = inputs[
"devcontainer_image_signal_selftest"]
325 lock = inputs[
"devcontainer_image_lock_selftest"]
326 supervisor = inputs[
"devcontainer_image_selftest_supervisor"]
327 supervisor_cases = inputs[
"devcontainer_image_selftest_supervisor_cases"]
328 supervisor_process = inputs[
"devcontainer_image_selftest_process"]
330 _image_lifecycle_process_errors(lifecycle, bound_exit)
331 + _image_cases_process_errors(cases)
332 + _image_signal_process_errors(signal_source)
333 + _image_lock_process_errors(lifecycle, cases, signal_source, lock)
334 + _image_supervisor_token_errors(supervisor, supervisor_cases, supervisor_process)
335 + image_process_analysis.source_errors(inputs)
336 + _semantic_aggregator_errors(inputs[
"semantic_mutations"])
337 + _split_runtime_module_errors(inputs)