Skip to content

fix(master): load per-challenge embed.env into isolated child env - #48

Merged
echobt merged 1 commit into
mainfrom
fix/master-embed-ac-env-file
Jul 27, 2026
Merged

fix(master): load per-challenge embed.env into isolated child env#48
echobt merged 1 commit into
mainfrom
fix/master-embed-ac-env-file

Conversation

@echobt

@echobt echobt commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Embedded challenges start under env -i, and the passed-through variable list was hardcoded with no extension point, so every operator-supplied setting was silently dropped.
  • Agent Challenge therefore booted with phala_attestation_enabled=False and attested_review_enabled=False even though the operator env file enabled both.
  • Adds the supported extension point: a per-challenge embed.env merged into the isolated child environment, without weakening cross-challenge isolation.

Why this matters (production impact)

Observed on the live master before this fix:

Symptom Observed
AC Phala flags in the running process False / False (env file said true)
AC submissions 11, all score=0.0, attested=None
Raw weight snapshot for the epoch none → source_challenges.agent-challenge ok:false error:"missing"
Sealed vector withheld → fell back to burn uids:[0] weights:[1.0]

Root cause is exactly one line of intent: env -i "${ac_env[@]}" wipes the ambient
environment, and the allowlist below it never included the attestation switches.
The isolation itself is correct and is kept — only the missing extension point is added.

Changes

  • docker/master-entrypoint.sh
    • New load_challenge_env_file() merges allowlisted KEY=VALUE lines into a child env array.
    • Env file per challenge, default <data-dir>/embed.env, overridable via
      BASE_MASTER_AC_ENV_FILE / BASE_MASTER_PRISM_ENV_FILE.
    • Applied after the built-in defaults, so operator values win.
    • Prefixes stay disjoint (CHALLENGE_/BASE_CHALLENGE_ for AC, PRISM_ for Prism;
      PHALA_, DSTACK_, OPENROUTER_API_KEY shared) so isolation is preserved.
    • Ignores comments, blanks, malformed keys and non-allowlisted keys; strips one layer
      of quotes; missing file is non-fatal; unreadable file fails loudly.
    • Values are never logged — key names only (secrets hygiene).
  • tests/unit/test_master_embed_env_file.py — new behavioural coverage.

Test plan

Tests execute the real entrypoint with a stubbed uvicorn that dumps its isolated
child environment, so this asserts actual runtime behaviour rather than script text.

  • test_ac_env_file_supplies_phala_settings_to_isolated_child — Phala switches + key reach AC
  • test_ac_env_file_does_not_leak_into_prism_child — isolation preserved
  • test_ac_env_file_overrides_builtin_default — file wins over defaults
  • test_missing_env_file_is_not_fatal — unchanged behaviour when absent
  • test_env_file_ignores_comments_blanks_and_malformed_keys — parser hardening

RED→GREEN verified against this PR's exact base (origin/main @ a13d42a6):

# pristine entrypoint from main
3 failed, 2 passed
# with this patch
5 passed

Regression + lint:

pytest tests/unit/test_master_embed_env_file.py \
       tests/unit/test_master_embed_challenges.py \
       tests/unit/test_master_embed_docs_seal.py   -> 23 passed
ruff check tests/unit/test_master_embed_env_file.py -> All checks passed
bash -n docker/master-entrypoint.sh                 -> OK

CI

  • Waiting for required checks to go green on this head SHA.

Notes

  • No behaviour change when no embed.env exists — existing deployments are unaffected.
  • Does not weaken any fail-closed gate: attestation still has to be enabled explicitly by the operator file; this only stops the value from being discarded.
  • No master set_weights path touched; sealer/aggregation untouched.
  • Follow-up (not in this PR): restart the live master on an image containing this entrypoint, then verify both Phala flags report True and an attested score lands before re-enabling emissions.

Summary by CodeRabbit

  • New Features

    • Added optional per-challenge environment configuration files.
    • Supported settings can now override built-in defaults when launching embedded challenges.
    • Configuration remains isolated between challenges, with unsupported or malformed entries ignored.
    • Missing configuration files no longer prevent challenge startup.
  • Tests

    • Added coverage for overrides, isolation, missing files, and environment-file parsing.

Embedded challenges start under `env -i` so Prism never inherits
CHALLENGE_* and agent-challenge never inherits PRISM_*. That isolation is
deliberate, but the passed-through list was hardcoded with no extension
point, so every operator setting was silently dropped -- including
CHALLENGE_PHALA_ATTESTATION_ENABLED and CHALLENGE_ATTESTED_REVIEW_ENABLED.

Agent Challenge therefore booted with attestation off even though the
operator env file enabled it, producing unattested zero scores, no raw
weight snapshot, and a withheld epoch that fell back to burn.

Add the supported extension point: a per-challenge env file (default
<data-dir>/embed.env, overridable via BASE_MASTER_AC_ENV_FILE and
BASE_MASTER_PRISM_ENV_FILE) whose allowlisted keys are appended after the
built-in defaults, so operator values win. Prefixes stay disjoint per
challenge, preserving cross-challenge isolation. Values are never logged.
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The entrypoint now loads optional per-challenge embed.env overrides, filters them by allowlisted prefixes, and applies them to isolated Prism and agent-challenge environments. Contract tests cover parsing, overrides, missing files, and cross-challenge isolation.

Changes

Challenge environment overrides

Layer / File(s) Summary
Environment file parser and override paths
docker/master-entrypoint.sh
Adds default env-file locations and parses valid, quoted, allowlisted KEY=VALUE entries while ignoring invalid or unrelated lines.
Isolated startup wiring and contract tests
docker/master-entrypoint.sh, tests/unit/test_master_embed_env_file.py
Applies challenge-specific overrides after defaults while preserving env -i isolation; tests validate loading, precedence, missing files, parsing, and cross-challenge separation.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Operator
  participant master-entrypoint.sh
  participant load_challenge_env_file
  participant Prism
  participant agent-challenge

  Operator->>master-entrypoint.sh: provide optional embed.env files
  master-entrypoint.sh->>load_challenge_env_file: parse Prism overrides
  load_challenge_env_file->>Prism: apply allowlisted environment
  master-entrypoint.sh->>load_challenge_env_file: parse agent-challenge overrides
  load_challenge_env_file->>agent-challenge: apply allowlisted environment
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: loading per-challenge embed.env files into isolated child environments.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/master-embed-ac-env-file

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/unit/test_master_embed_env_file.py (1)

48-91: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a Prism-side env-file contract test.

All cases populate only the AC file, so PRISM_ENV_FILE parsing and precedence are untested. Extend the helper with an optional Prism file body and verify a PRISM_* override reaches Prism only and replaces its default.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/test_master_embed_env_file.py` around lines 48 - 91, Extend
_run_entrypoint with an optional Prism env-file body, create the Prism env file
when provided, and pass the corresponding configuration into the subprocess
environment. Add or update a contract test to define a PRISM_* override in that
file and assert it appears in the Prism dump, does not appear in the AC dump,
and replaces the default value.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/unit/test_master_embed_env_file.py`:
- Around line 25-36: The test fake uvicorn must not persist raw API-key values.
In tests/unit/test_master_embed_env_file.py lines 25-36, redact or hash
sensitive environment values before writing dumps; at lines 94-115, replace the
raw PHALA_CLOUD_API_KEY fixture and assertion with a SHA/digest-based value; and
at lines 118-128, remove the raw API-key fixture from the isolation test while
preserving propagation and isolation coverage.

---

Nitpick comments:
In `@tests/unit/test_master_embed_env_file.py`:
- Around line 48-91: Extend _run_entrypoint with an optional Prism env-file
body, create the Prism env file when provided, and pass the corresponding
configuration into the subprocess environment. Add or update a contract test to
define a PRISM_* override in that file and assert it appears in the Prism dump,
does not appear in the AC dump, and replaces the default value.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 456959b7-5d58-47da-af63-56e14f1ec1e6

📥 Commits

Reviewing files that changed from the base of the PR and between a13d42a and 2cfd265.

📒 Files selected for processing (2)
  • docker/master-entrypoint.sh
  • tests/unit/test_master_embed_env_file.py

Comment on lines +25 to +36
FAKE_UVICORN = """#!/usr/bin/env bash
# Dump the isolated child environment so the test can assert on it.
# The dump path is baked in: `env -i` strips DUMP_DIR from the child env.
target="unknown"
for arg in "$@"; do
case "${arg}" in
prism_challenge.app:app) target="prism" ;;
agent_challenge.app:app) target="ac" ;;
esac
done
env > "__DUMP_DIR__/${target}.env"
"""

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Do not persist raw API-key values in test artifacts.

The fake uvicorn dumps the full child environment, including the raw PHALA_CLOUD_API_KEY; the related fixtures and assertions also retain that value. Redact or hash sensitive variables in the dump, and use a SHA/digest fixture when validating propagation.

  • tests/unit/test_master_embed_env_file.py#L25-L36: redact/hash sensitive environment values before writing the dump.
  • tests/unit/test_master_embed_env_file.py#L94-L115: replace the raw API-key fixture/assertion with a digest-based value.
  • tests/unit/test_master_embed_env_file.py#L118-L128: remove the raw API-key fixture from the isolation test.

As per coding guidelines: “Never log, document, or include evidence containing private keys, wallet mnemonics, API tokens, or full secret values; only names, digests, and SHAs are permitted.”

📍 Affects 1 file
  • tests/unit/test_master_embed_env_file.py#L25-L36 (this comment)
  • tests/unit/test_master_embed_env_file.py#L94-L115
  • tests/unit/test_master_embed_env_file.py#L118-L128
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/test_master_embed_env_file.py` around lines 25 - 36, The test fake
uvicorn must not persist raw API-key values. In
tests/unit/test_master_embed_env_file.py lines 25-36, redact or hash sensitive
environment values before writing dumps; at lines 94-115, replace the raw
PHALA_CLOUD_API_KEY fixture and assertion with a SHA/digest-based value; and at
lines 118-128, remove the raw API-key fixture from the isolation test while
preserving propagation and isolation coverage.

Source: Coding guidelines

@echobt
echobt merged commit ba16811 into main Jul 27, 2026
27 checks passed
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.

1 participant