Skip to content

feat(eval): add isolated ROCm sanitizer plugins - #78

Open
irvineoy wants to merge 5 commits into
codex/quality-loop-agentfrom
codex/eval-tools-sanitizers
Open

feat(eval): add isolated ROCm sanitizer plugins#78
irvineoy wants to merge 5 commits into
codex/quality-loop-agentfrom
codex/eval-tools-sanitizers

Conversation

@irvineoy

@irvineoy irvineoy commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

This is a stacked Draft PR on #76 (codex/quality-loop-agent). It adds an opt-in evaluation-tool stage after compilation/correctness and before performance measurement, while retaining the existing MI355X scoring runtime unchanged.

  • Adds typed evaluator contracts, task profiling, capability resolution, stable reports, plan fingerprints, advisory/required policy, and an explicit built-in plugin registry.
  • Adds isolated sidecar runtimes for Triton FpSan, ROCm GPU ASan, rocJITsu, and HIP-FpSan with per-tool dependency/source locks and startup positive controls.
  • Keeps lmsysorg/sglang-rocm:v0.5.14-rocm720-mi35x-20260705, FlyDSL 0.2.2, and AITER 0.1.17.dev110+g9127c94a1 unchanged.
  • Adds candidate build attestations, immutable submission evidence, bounded process/log handling, fail-closed parsing, and a strict support matrix.
  • Adds trusted single-dispatch gfx950 rocJITsu replay capsules for Triton and FlyDSL HSACO. Whole-Python JIT wrapping remains unsupported.
  • Integrates the same manager into normal evaluation and the quality loop, plus a disabled-by-default example and detailed operator documentation.

Isolation and runtime identity

  • The known scoring manifest reference and the selected scoring reference must resolve to the same local Docker config ID; scoring launches by that ID.
  • Each tool reference is likewise resolved once, and the sidecar plus rocJITsu passwd probe launch by the same immutable config ID recorded in the plan.
  • Sidecars use network=none, read-only root filesystems, host UID, cap-drop=ALL, no-new-privileges, bounded scratch/logs, read-only repository input, one writable per-tool socket directory, and one narrow per-worker artifact directory.
  • Scoring overlays the top-level .eval-tool-artifacts namespace read-only and only the current worker child read/write, preventing cross-worker writable aliases through the broad repository mount.
  • Worker, helper, and probe code is baked under /opt/aka-eval-tools; runtime health attests the worker/probe hashes and startup positive-control result before publishing the socket.

Current support boundary

Kernel path Current status
Editable Triton JIT Triton FpSan ready with comparison/instrumentation attestation; GPU ASan ready with dedicated fresh-JIT adapter; rocJITsu only through trusted triton_aot capsule replay.
HIP source GPU ASan ready after gfx950:xnack+ recompilation and attestation; rocJITsu ready with a native launcher; HIP-FpSan requires an explicit source port and comparison adapter.
FlyDSL 0.2.2 GPU ASan and Triton FpSan unsupported; rocJITsu works through trusted flydsl_aot capsule replay.
AITER / precompiled HSACO GPU ASan unsupported unless the exact source is rebuilt and instrumented; current AITER Python rocJITsu path unsupported.
rocBLAS/RCCL internals Out of scope; do not enable as a general library-kernel check.
gfx942 Unverified and rejected by the sidecar runner.

No bundled task is claimed as production-qualified. Automatic evaluator-owned AOT capsule capture and binding to the exact correctness dispatch, post-agent phase separation/authenticated RPC, and top-level resume fingerprint enforcement remain follow-up work; keep rollout advisory until each task/tool pair is qualified.

Real MI355X (gfx950) validation

Final sidecar image IDs:

  • Triton FpSan: sha256:f28991cbfc462c2fb4d08ac6d92b8e23170f0d79a37dae1abb4ec2c1437f9c7c
  • GPU ASan: sha256:1b48d325d5601581d378059c0bd3c2339efc4a52640d4ca94a2887b292cd1ed4
  • rocJITsu: sha256:e2b71a80fc3ec998e277e86ad4705234e30fc9b0c465f98bf20496a38fb24261
  • HIP-FpSan: sha256:6e6e7a834f43936a0a494be0b9acf24e7f858f57b302da80e6ea7a16e9d1fb52

All four final images passed their integrated hardware startup controls. Final manager-to-sidecar candidate fixtures produced:

Tool / language Safe fixture Seeded bug
Triton FpSan / Triton clean semantic mismatch found
GPU ASan / HIP clean OOB found
GPU ASan / Triton clean OOB found
HIP-FpSan / explicitly ported HIP clean wrong expression found
rocJITsu / Triton AOT clean; dispatch, replay, capsule attested
rocJITsu / FlyDSL AOT LDS missing-barrier race found; dispatch, replay, capsule attested

Additional negative qualification confirmed that runtime preload alone does not cover an uninstrumented HSACO, FlyDSL does not currently receive GPU ASan instrumentation, and the AITER Python rocJITsu path fails in the current runtime. Those paths remain fail-closed in the matrix.

Tests

  • 214 passed, 2 skipped, 3 subtests passed in the pinned scoring image (pytest -q tests).
  • tests/test_docker_benchmark.sh passes, including immutable-image, socket, artifact containment, and cross-worker mount assertions.
  • Real Docker bind topology: current worker RW; sibling worker and artifact namespace RO.
  • Sphinx HTML build succeeds (one pre-existing ROCm external-project configuration warning).
  • Four locked images rebuild successfully from the committed source and pass final hardware startup controls.
  • Three independent read-only audits found no remaining P0/P1 issue after the immutable-launch and cross-worker-mount fixes.

@irvineoy
irvineoy marked this pull request as ready for review August 5, 2026 21:26

@amd-vivekag amd-vivekag left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review summary

Verdict: fix-before-ship

The architecture is thoughtful: immutable image-ID launch, image-owned worker provenance, narrow mounts, explicit plugin registration, bounded logs, and separate execution/finding states are all strong choices. A deeper full-diff pass nevertheless found several reproducible fail-closed violations where a failed or incomplete analysis can become clean, plus control-plane and provenance gaps that should be fixed before merge. I did not re-raise the PR's explicitly documented phase-isolation, capsule-origin, or top-level resume limitations as new findings.

Findings: 7 High · 7 Medium · 0 Low

High items:

  • Detached descendants can escape process-group timeout cleanup and survive or wedge the sequential worker.
  • FpSan can return clean after a failed harness.
  • Multiple FpSan records are last-wins, so a later clean record can hide an earlier mismatch.
  • A configured rocJITsu race_report can suppress a real current stderr race.
  • Misspelled config keys can silently weaken required to the default advisory policy.
  • Reused artifact directories allow stale attestations to satisfy a later invocation.
  • Replay launch geometry accepts lossy/out-of-range values that can reduce the dispatched workload.

Verification performed locally at 844761c: tests/test_docker_benchmark.sh passed; Python compile checks passed; 15 quality-loop tests passed; focused reproductions confirmed the fail-clean, detached-child, symlink-fingerprint, timeout, and replay-marker cases. The full pytest suite could not be rerun on the host because pytest is not installed; Docker image rebuilds and MI355X hardware qualification were not repeated.

else:
# A launcher may exit after spawning a daemon that inherited our pipes.
# Evaluation commands are not allowed to leave background descendants.
if _group_alive(process_group):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[High] A detached child can escape timeout cleanup.

Cleanup only targets the leader's original process group. A child using setsid()/start_new_session=True survives; reproduced with termination=none and a live child, while inherited pipes can also wedge the sequential worker past its timeout.

Fix: run each invocation in a dedicated cgroup/PID namespace and kill that containment unit; add an escaped-descendant regression test.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 25c3ddcd. The sidecar worker now enables Linux PR_SET_CHILD_SUBREAPER, snapshots descendant PID/start-time identities before each sequential request, and cleans every newly created/adopted descendant with TERM/KILL plus reaping, including setsid() and double-fork escapees. Any such cleanup sets cleanup_required, so the typed client forces returncode=None; if survivors cannot be removed, PID 1 exits to tear down the container PID namespace. Added test_detached_descendant_is_killed_by_worker_containment and test_typed_client_never_maps_containment_cleanup_to_success for the reproduced detached-child case.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved — thanks.

Comment thread src/eval_tools/plugins/parsers.py Outdated
for line in combined.splitlines():
if line.startswith(_FPSAN_PREFIX):
try:
payload = json.loads(line[len(_FPSAN_PREFIX) :])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[High] Multiple FpSan records are silently last-wins.

Each marker overwrites payload; a mismatch record followed by an equal record reproduced PASS, despite the documented one-record contract.

Fix: collect records and return TOOL_ERROR unless exactly one valid AKA_FPSAN_RESULT is present.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 25c3ddcd. parse_fpsan_comparison now collects every AKA_FPSAN_RESULT record instead of overwriting a single payload, rejects invalid/non-finite JSON, and returns TOOL_ERROR with fpsan_multiple_results unless the one-record contract is satisfied. Added test_fpsan_parser_rejects_multiple_result_records, including mismatch-then-equal ordering.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved — thanks.

Comment thread src/eval_tools/plugins/parsers.py Outdated
reason_code="fpsan_instrumentation_not_attested",
details="FPSan outputs are meaningful only when both compared kernels were instrumented.",
)
if returncode != 0 and payload is None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[High] A failed FpSan harness can be reported clean.

The nonzero guard applies only when no payload exists; matching digests plus return code 139 reproduced PASS and would satisfy a required gate.

Fix: require returncode == 0 before returning PASS (while preserving a genuine mismatch finding if desired), and test nonzero/None return codes with valid payloads.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 25c3ddcd. FpSan now checks returncode != 0 before any digest comparison can return PASS; this also treats None as TOOL_ERROR. Added test_fpsan_parser_never_reports_clean_after_process_failure, covering valid matching payloads with both return code 139 and None. The HIP-FpSan positive control now also requires both probe processes to exit zero.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved — thanks.

Comment thread src/eval_tools/plugins/rocjitsu.py Outdated
# rocJITsu is configured with both stderr and file sinks. Once the
# evaluator-owned report exists it is the authoritative race stream;
# parsing stderr as well would duplicate every structured finding.
"" if report else execution.stderr,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[High] A configured race_report can hide a current stderr race.

Any non-empty report makes parsing discard stderr. A stale clean report plus a real current stderr race reproduced completed/clean.

Fix: always parse both current sinks with deduplication, or remove/constrain race_report to the evaluator-owned sink and truncate it before every invocation.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 25c3ddcd. rocJITsu now uses an evaluator-owned race.log below the fresh invocation artifact directory, truncates it before every launch, enables both stderr and file sinks, and parses both sinks together with finding deduplication. AOT replay rejects a configurable report sink. Added test_rocjitsu_current_stderr_race_is_not_hidden_by_clean_file and test_rocjitsu_aot_does_not_duplicate_file_and_stderr_race.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved — thanks.

Comment thread src/eval_tools/config.py Outdated
return cls.disabled()
if not isinstance(config, Mapping):
raise ValueError("evaluation tools config must be a mapping")
section: Any = config.get("evaluation_tools", config)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[High] Misspelled keys can silently weaken required policy.

Unknown keys are ignored, so polciy: required parses as the default advisory and permits performance after tool failure.

Fix: validate run-level and per-tool mappings against explicit key allowlists before applying defaults; add typo tests for policy and identity fields.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 25c3ddcd. Run-level and per-tool mappings are now validated against explicit allowlists before defaults are applied, so polciy and other unknown fields raise instead of silently falling back to advisory behavior. The parser also rejects unknown enabled tools, conflicting runtime identity fields, and duplicate normalized tool names. Added test_unknown_run_and_tool_fields_fail_closed plus related identity/normalization coverage.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved — thanks.

--socket "${EVAL_TOOL_SOCKET_CONTAINER_DIR}/${tool}.sock"
--input-root "$EVAL_TOOL_INPUT_CONTAINER_DIR"
--scratch-root "$EVAL_TOOL_SCRATCH_CONTAINER_DIR"
--artifact-root "$EVAL_TOOL_ARTIFACT_CONTAINER_DIR"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Medium] Valid configuration can exceed the worker's hidden timeout ceiling.

EvalToolsConfig accepts timeout_s=7200, but the runner never passes --max-timeout-s, so workers keep the 3600-second default and reject every such request.

Fix: pass a validated configured maximum when starting each worker, or reject values above 3600 in config and document the ceiling.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 25c3ddcd using the second suggested option: configuration now shares the worker ceiling of 3600 seconds. Run and per-tool timeouts must be exact integers in [1, 3600], and task/tool overrides cannot exceed the run timeout, so a config accepted by the evaluator cannot exceed the hidden worker cap. Added test_run_timeout_must_match_worker_contract and documented the limit.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved — thanks.

Comment thread src/eval_tools/worker.py Outdated
number = float(value)
except (TypeError, ValueError) as error:
raise RequestValidationError(f"{field} must be a positive number") from error
if number <= 0 or number > maximum:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Medium] NaN bypasses timing validation and can remove the deadline.

Python JSON accepts NaN, and all range comparisons here are false for it. Popen.wait(timeout=NaN) waits for process completion, so an unbounded child can wedge the sequential worker.

Fix: reject non-finite values with math.isfinite, reject non-finite JSON constants, and add NaN tests for timeout and grace fields.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 25c3ddcd. The worker recursively rejects non-finite JSON values and _positive_number/_nonnegative_number explicitly require math.isfinite for timeout and grace fields. --max-timeout-s is validated the same way at startup. Added parameterized test_non_finite_timing_values_are_rejected for timeout_s, term_grace_s, and kill_grace_s.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved — thanks.

Comment thread src/eval_tools/plugins/attestation.py Outdated
return False, "attestation_tool_mismatch"
if not self.instrumented:
return False, "artifact_not_instrumented"
command_text = " ".join(self.build_command)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Medium] Required compiler flags are validated by substring.

Arguments such as -DNOTE=-fsanitize=address or --not-shared-libsan satisfy these checks without enabling instrumentation.

Fix: validate normalized argv tokens structurally and exactly, with explicit handling only for legitimate joined forms such as -I/path; add near-match negative tests.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 25c3ddcd. Required build flags are now matched as exact argv tokens, with narrowly supported structural equivalents only for legitimate split -I/-L and --option value forms. Substrings such as -DNOTE=-fsanitize=address and --not-shared-libsan no longer attest instrumentation. Added near-match negative tests and a split-include positive test.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved — thanks.

Comment thread src/eval_tools/plugins/gpu_asan.py Outdated
"gpu_asan_flydsl_no_device_instrumentation",
"FlyDSL 0.2.x does not insert the AMDGPU AddressSanitizer pass.",
)
elif profile.framework in {"aiter", "rocblas", "rccl"} or profile.artifact_kind == ArtifactKind.HSACO_PRECOMPILED:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Medium] rocBLAS/RCCL profiles can become GPU-ASan ready despite the strict matrix.

Setting HIP source available plus rebuilt_from_source=true takes the ready branch for rocblas and rccl, although the docs say their internal kernels are out of scope.

Fix: keep rocBLAS/RCCL unconditionally unsupported until dedicated qualified adapters exist; scope the rebuild exception only to explicitly supported lanes.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 25c3ddcd. GPU-ASan capability assessment now rejects rocblas and rccl up front as gpu_asan_library_kernel_out_of_scope, regardless of rebuilt_from_source or generic HIP recompilation evidence. Added parameterized test_library_kernel_gpu_asan_stays_unsupported_after_source_rebuild for both frameworks.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved — thanks.

Comment thread src/eval_tools/plugins/gpu_asan.py Outdated
str(hip_runtime),
inherited=env.get("LD_PRELOAD", ""),
)
env["AKA_BUILD_ATTESTATION_PATH"] = str(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Medium] The documented attestation_path option is disconnected from where the command writes.

The invocation always injects the default path, while parsing honors a configured path. An adapter following AKA_BUILD_ATTESTATION_PATH therefore writes one file and the parser reads another; the same split exists in both FpSan plugins.

Fix: resolve one artifact-contained path and reuse it for environment, metadata, and parsing, or remove the configurable option.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 25c3ddcd. GPU-ASan, Triton-FpSan, and HIP-FpSan now resolve one artifact-contained attestation path and reuse that exact value for AKA_BUILD_ATTESTATION_PATH, invocation metadata, and parsing; the parent is created before launch and path escape is rejected. Added parameterized test_configured_attestation_path_is_shared_by_invocation_and_parser plus test_attestation_path_cannot_escape_invocation_artifacts.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved — thanks.

@irvineoy

Copy link
Copy Markdown
Collaborator Author

Implemented and pushed the Waitcheck/ConSan follow-up in e8d594a and 7ba42fe.

What changed

  • Added rocjitsu_waitcheck as a CPU-only static sidecar. It accepts an evaluator-selected raw HSACO, binds the exact SHA-256, kernel name, and text entry offset, inventories the selected kernel, and returns structured findings through the pinned Waitcheck C API bridge.
  • Added rocjitsu_consan as a gfx950 GPU sidecar. It binds the exact HSACO by SHA-256 and rocJITsu FNV-1a64 identity, runs a focused native launcher under strict record-replay instrumentation, then runs a separate uninstrumented correctness oracle.
  • Added fail-closed parsing for patch, coverage, dispatch-token, dynamic-report, process-verdict, diagnostic, artifact-identity, and oracle evidence. Embedded Waitcheck output from ConSan remains preflight metadata and is not reported twice.
  • Added pinned source/dependency locks and shared rocJITsu sanitizer image targets, plus startup positive controls for a known missing wait and a known LDS race.
  • Bound configured code_object content into the plan fingerprint and updated runner isolation so Waitcheck receives no GPU device mounts while ConSan does.
  • Updated config/API/compatibility/release documentation. TSAN and LLVM UBSAN are documented in the module README as planned future integrations and are not represented as currently available.

Important scope boundary

These are evaluator plugins implemented as isolated sidecars over the existing Unix-socket RPC. They are not skills or MCP servers, and they do not automatically inspect every optimized kernel. A task must explicitly provide the candidate-specific code object and adapter options. Waitcheck and ConSan are currently qualified only for advisory pilots; broad AITER, rocBLAS, and RCCL ConSan launch paths remain unsupported until dedicated adapters are qualified.

Validation

  • Evaluation-tool unit suite: 186 passed
  • Full repository suite: 267 passed, 2 skipped, 3 subtests passed
  • Runner runtime/agent-selection/sidecar-isolation shell suite: PASS
  • Final images built successfully:
    • Waitcheck: sha256:537ac0272e0ed4b11f151c6bc879d699b0727d7a8485e40827cfaa0040d8c19e
    • ConSan: sha256:32195ba197a013836de99988236472e85ab999597c0f5ab2044c56c97eb01eec
  • Combined physical gfx950 startup smoke: both sidecars ready; Waitcheck distinguished safe vs missing-wait fixtures, and ConSan distinguished safe vs seeded-race fixtures under strict record-replay.
  • Direct adapter/protocol validation on generated raw HSCOs passed. Waitcheck produced clean vs structured hazard results. ConSan plus the production parser returned pass for the safe object and finding with 128 conflict records for the racy object, with matching SHA/FNV identity and passing independent oracles.
  • git diff --check and bash syntax validation passed.

GitHub CI and Read the Docs were queued/pending when this comment was posted.

@amd-vivekag amd-vivekag left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review summary

Verdict: fix-before-ship

All 14 findings from the previous review are fixed correctly. A full current-diff and gap-sweep pass found one remaining false-clean path in native HIP rocJITsu plus two startup-control gaps in the new Waitcheck/ConSan lanes. No bot reviews or comments were present.

Findings: 1 High · 2 Medium · 0 Low

High items:

  • Native HIP rocJITsu accepts candidate-spoofable, unstructured dispatch text as a clean simulated run.

Verification: 186 eval-tools tests passed; tests/test_docker_benchmark.sh passed; git diff --check passed; a focused reproduction confirmed the spoofed rocjitsu_clean result. The full host suite could not collect under the host's older Python, while this repository documents Docker as the supported test path.

Comment thread src/eval_tools/plugins/rocjitsu.py Outdated
else:
expected_kernel = context.options.get("expected_kernel")
if expected_kernel:
dispatch_seen = f'Kernel dispatch: "{expected_kernel}"' in combined

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[High] Candidate output can spoof dispatch attestation and produce a false clean.

This unanchored substring is taken from the wrapped launcher's combined output; Kernel dispatch: "hip_kernel" plus any rocjitsu text reaches rocjitsu_clean without a structured [rocjitsu] Kernel dispatch record.

Fix: derive attestation from _KERNEL_RE, require the configured kernel among those matches, and make the parser require at least one structured dispatch; add a spoofed-launcher-output regression test.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in ea0d0812.

  • Added rocjitsu_dispatch_kernels() as the single canonical _KERNEL_RE-based dispatch extractor.
  • Native HIP clean attestation now comes only from structured records in the rocJITsu report sink and requires the configured expected_kernel; candidate stdout/stderr cannot attest a clean run.
  • parse_rocjitsu() now returns rocjitsu_no_dispatch_observed when no structured dispatch exists.
  • Added regressions for both the original unanchored spoof and a candidate printing the complete [rocjitsu] Kernel dispatch: ... line, while preserving genuine report-sink and AOT clean behavior.

The focused spoof/preservation tests pass, as do the full eval-tools suite (192 tests), full repository suite (273 passed, 2 skipped, 3 subtests), and the six-sidecar gfx950 smoke. The native lane remains documented as advisory rather than a secure reward boundary.

Comment thread src/eval_tools/worker.py Outdated
):
steps["safe"] = _run_probe_step(
"safe",
[binary, str(safe), "--target", "gfx950"],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Medium] Waitcheck's required positive control skips the production C API path.

A broken aka-waitcheck-capi or entrypoint can still report a ready sidecar here, then make every real evaluation fail closed.

Fix: run the production entrypoint/C-API chain on the safe fixture and validate one clean AKA_WAITCHECK_RESULT; keep the direct hazard check as a second lane.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in ea0d0812.

Waitcheck startup now:

  1. compiles raw safe and hazardous gfx950 HSACOs and inventories the exact kernel entry;
  2. runs the image-owned production waitcheck_entrypoint.py and aka-waitcheck-capi chain for both fixtures with exact SHA/kernel/entry binding;
  3. validates the emitted AKA_WAITCHECK_RESULT through the production parser (PASS for safe, FINDING for hazard); and
  4. retains the direct CLI hazard check as an independent second lane.

I also added a regression proving a broken production entrypoint makes the positive control fail/degrade. The physical gfx950 startup smoke exercised the real C API path and reported the sidecar ready.

Comment thread src/eval_tools/worker.py Outdated
):
steps["safe"] = _run_probe_step(
"safe",
[str(safe)],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Medium] ConSan's startup control bypasses the production entrypoint and oracle split.

This proves the hook works, but not argument forwarding, oracle environment scrubbing, or the AKA_CONSAN_RUN contract used by real evaluations.

Fix: run consan_entrypoint.py for the startup fixtures with separate instrumented/oracle argv and validate its structured clean/finding outcomes.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in ea0d0812.

ConSan startup now compiles raw safe/racy HSACOs plus an image-owned HIP module launcher, then invokes the real consan_entrypoint.py with separate instrumented --command-arg and clean --oracle-arg vectors. The launcher requires the ConSan hook environment in instrumented mode and explicitly rejects HSA_TOOLS_*/RJ_CONSAN_* leakage in oracle mode. Startup also binds exact SHA-256/FNV identities, requires the unique AKA_CONSAN_RUN contract, and validates the structured outcomes through the production parser (PASS for safe, FINDING for racy).

The unit orchestration test and physical gfx950 smoke both passed; the smoke observed CONSAN_INSTRUMENTED_LAUNCH_COMPLETED and CONSAN_ORACLE_ENV_CLEAN for both fixtures.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants