Skip to content

fix(prism): unattested execution + master-epoch raw weight push - #56

Merged
echobt merged 5 commits into
mainfrom
fix/prism-unattested-lium-weights
Jul 29, 2026
Merged

fix(prism): unattested execution + master-epoch raw weight push#56
echobt merged 5 commits into
mainfrom
fix/prism-unattested-lium-weights

Conversation

@echobt

@echobt echobt commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Land unattested PRISM execution path (unattested_execution.py + ingestion gate) with embed env allowlist for CHALLENGE_UNATTESTED_EXECUTION / NO_PHALA.
  • Default admission_requires_worker=false for unattested ship.
  • Align raw-weight push epoch identity with master seal interval (360s) and advance past ledger last_epoch when wall clock lags force-advanced open epochs.

Prod context

  • Emergency hotpatch already live on chain.joinbase.ai; this PR is the durable source for GHCR replace.
  • Weights un-withheld non-burn observed (epochs 4959205–4959207) with both agent-challenge + prism sources.

Test plan

  • pytest packages/challenges/prism/tests/test_unattested_*.py tests/unit/test_master_embed_env_file.py
  • pytest packages/challenges/prism/tests/test_raw_weight_push.py (7 passed)
  • CI green
  • GHCR base-master digest roll + drop interim hotpatch binds
  • F2 PRISM submit smoke under admission=false (not 403 NO_ACTIVE_WORKER)
  • Lium lifecycle idle 0 pods OK with BASE_LIUM_TRAINING__ENABLED=true

Mandate

  • Unattested only — no TEE claims
  • Never touch keyrelease/
  • Never print secrets

Summary by CodeRabbit

  • New Features

    • Added an optional “unattested execution” mode for Prism, including host-trust/NO_PHALA behavior.
    • In this mode, missing constation bundles can be admitted without promoting constation tier status, while still enforcing proof and infrastructure checks.
    • Prism now stamps attestation fields to prevent miner-supplied attestation/TEE claims from being reflected as trusted.
    • Added support for Prism-specific embedded environment overrides in the entrypoint.
  • Bug Fixes

    • Improved raw weight push epoch bucketing and added monotonic progression based on stored ledger state.
    • Prism worker admission now defaults to disabled requirements.
  • Tests

    • Added coverage for unattested gating, attestation stamping, and epoch/override behavior.

echobt added 2 commits July 29, 2026 01:27
Admit missing constation bundles only when CHALLENGE_UNATTESTED_EXECUTION
(or NO_PHALA aliases) is on; stamp accepted results unattested (T19-T22).
Forward unattested flags into prism embed.env; default admission_requires_worker
to false for the host-trust path.
Use master epoch interval (default 360s) for seal identity instead of
challenge scoring epoch_seconds, and advance past ledger last_epoch when
wall clock lags force-advanced open epochs so continuous push stays
eligible for master ingress.
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@echobt, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 50 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 250b66cd-6e17-4019-ab14-8309aa3d1c5e

📥 Commits

Reviewing files that changed from the base of the PR and between a3d50dc and 024a4bd.

📒 Files selected for processing (1)
  • tests/unit/test_master_entrypoint_prism_policy.py
📝 Walkthrough

Walkthrough

Changes

The Prism challenge adds configurable unattested execution handling, including server-side attestation projection and a narrowly scoped missing-constation admission path. Embedded Prism environment forwarding is expanded, raw-weight epochs become monotonic with a separate master interval, and tests cover validation, isolation, and epoch behavior.

Prism execution and epoch changes

Layer / File(s) Summary
Embedded Prism environment wiring
docker/master-entrypoint.sh, tests/unit/test_master_embed_env_file.py
Prism defaults and environment allowlists now forward unattested-related keys while keeping them isolated from AC.
Unattested result projection
packages/challenges/prism/src/prism_challenge/unattested_execution.py, packages/challenges/prism/src/prism_challenge/ingestion.py, packages/challenges/prism/tests/test_unattested_mark_unforgeable.py
Unattested mode resolves environment flags, strips TEE claims, and forces response attestation fields to the unattested projection.
Conditional constation admission and validation
packages/challenges/prism/src/prism_challenge/ingestion.py, packages/challenges/prism/tests/test_unattested_constation_gate.py, packages/challenges/prism/tests/test_unattested_no_bypass.py
Missing constation bundles may admit scoring only in unattested mode; proof, envelope, infrastructure, and present-bundle failures remain rejected.
Monotonic raw-weight epochs
packages/challenges/prism/src/prism_challenge/raw_weight_push.py, packages/challenges/prism/tests/test_raw_weight_push.py
Raw-weight pushing uses a separate master epoch interval and advances beyond the last acknowledged ledger epoch when necessary.

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

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Ingestion
  participant ConstationGate
  participant CoordinatorDB
  Client->>Ingestion: submit proof and result envelope
  Ingestion->>ConstationGate: evaluate validation and constation state
  ConstationGate-->>Ingestion: admission decision
  Ingestion->>CoordinatorDB: persist accepted score
  Ingestion-->>Client: return projected response
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 56.06% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the two main changes: unattested execution and master-epoch raw weight push.
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 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/prism-unattested-lium-weights

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: 3

🧹 Nitpick comments (7)
packages/challenges/prism/tests/test_unattested_no_bypass.py (2)

712-731: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

This test asserts against its own literal and can never fail.

enforced is defined inline, so MISSING not in enforced and len(enforced) >= 4 are tautologies — it documents intent but locks nothing. To make it a real structural lock, derive the set from the collected test ids/expected codes in this module, or drop it.

🤖 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 `@packages/challenges/prism/tests/test_unattested_no_bypass.py` around lines
712 - 731, Update test_matrix_documents_enforced_validations to derive enforced
validation codes from the module’s collected test IDs or expected-code data
instead of defining the set inline. Keep assertions that MISSING is excluded,
missing_constation_bundle maps to MISSING via miner_fault_reason, and at least
four distinct validations are covered.

52-132: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

~90 lines of fixtures duplicated across three new test modules.

TINY_ARCH, TINY_TRAIN, _SHARD, _stage_train, _zip_bytes/_zip_b64, and _settings are byte-identical (modulo WORKER_KEY/DIGEST) in test_unattested_constation_gate.py and test_unattested_mark_unforgeable.py. Moving them into a shared conftest.py keeps the three suites from drifting.

🤖 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 `@packages/challenges/prism/tests/test_unattested_no_bypass.py` around lines 52
- 132, The test fixtures are duplicated across the three unattested test
modules. Move TINY_ARCH, TINY_TRAIN, _SHARD, _stage_train, the archive encoding
helpers (_zip_bytes/_zip_b64), and _settings into the shared conftest.py,
preserving module-specific WORKER_KEY/DIGEST inputs through parameters or
existing fixture mechanisms, then update each test module to reuse those shared
definitions.
packages/challenges/prism/tests/test_unattested_constation_gate.py (2)

132-138: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

_clear_unattested_env is copied three ways, and only one copy scrubs stray CHALLENGE_* vars. test_unattested_mark_unforgeable.py Lines 139-146 deletes unknown CHALLENGE_* keys before create_app, noting that PrismSettings rejects them and that conftest/host env can leak them; the other two copies omit that sweep while running the same HTTP flow, so they are ambient-environment dependent.

  • packages/challenges/prism/tests/test_unattested_constation_gate.py#L132-L138: replace the local helper with the shared version that also removes unknown CHALLENGE_* keys.
  • packages/challenges/prism/tests/test_unattested_no_bypass.py#L148-L154: same — drop the local copy and use the shared helper so _enable_unattested inherits the sweep.

Extracting the single helper into a package-level conftest.py fixes both at once.

🤖 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 `@packages/challenges/prism/tests/test_unattested_constation_gate.py` around
lines 132 - 138, Extract _clear_unattested_env into the package-level
conftest.py, extending it to delete unknown CHALLENGE_* environment variables in
addition to the three named keys. Remove the local helper definitions from
packages/challenges/prism/tests/test_unattested_constation_gate.py lines 132-138
and packages/challenges/prism/tests/test_unattested_no_bypass.py lines 148-154,
and update both test modules to use the shared helper.

377-389: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Branching assertion accepts almost any outcome.

Any 422 whose code merely differs from MISSING passes, so a regression that breaks the unattested path with an unrelated fault would go unnoticed. Since DockerExecutor.run is stubbed deterministically, pin the expected status/payload instead of accepting either branch.

🤖 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 `@packages/challenges/prism/tests/test_unattested_constation_gate.py` around
lines 377 - 389, Update the assertions following the
/internal/v1/work_units/result request in the unattested-path test to require
the deterministic expected status and response payload from the stubbed
DockerExecutor.run. Remove the branch that accepts any non-MISSING 422, and
assert the exact successful or specifically expected response fields, including
the unattested tier behavior.
packages/challenges/prism/tests/test_unattested_mark_unforgeable.py (1)

136-146: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use the exported constant instead of the literal "CHALLENGE_NO_PHALA".

The sibling test files import CHALLENGE_NO_PHALA_ENV; hardcoding it here silently stops clearing the alias if the constant is ever renamed.

♻️ Proposed change
 from prism_challenge.unattested_execution import (
     ATTESTATION_STATUS_UNATTESTED,
+    CHALLENGE_NO_PHALA_ENV,
     CHALLENGE_UNATTESTED_EXECUTION_ENV,
-    for key in (CHALLENGE_UNATTESTED_EXECUTION_ENV, "CHALLENGE_NO_PHALA", NO_PHALA_ENV):
+    for key in (CHALLENGE_UNATTESTED_EXECUTION_ENV, CHALLENGE_NO_PHALA_ENV, NO_PHALA_ENV):
         monkeypatch.delenv(key, raising=False)
🤖 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 `@packages/challenges/prism/tests/test_unattested_mark_unforgeable.py` around
lines 136 - 146, Update _clear_unattested_env to use the imported
CHALLENGE_NO_PHALA_ENV constant in the environment-key tuple instead of the
literal "CHALLENGE_NO_PHALA", preserving clearing of all relevant variables if
the constant is renamed.
tests/unit/test_master_embed_env_file.py (1)

219-236: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Test is close to vacuous — AC never reads an env file here.

With ac_env_file_body=None, the AC child has no env file at all, so these assertions hold even if the prism/AC allowlists were swapped. Passing a distinct AC body (with its own marker key) would make the isolation claim meaningful.

🤖 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 219 - 236, Update
test_prism_unattested_flags_do_not_leak_into_ac to provide a distinct
ac_env_file_body containing a marker key, then assert that the marker is present
in the AC environment while CHALLENGE_UNATTESTED_EXECUTION and NO_PHALA from the
Prism file remain absent. Keep the existing Prism-only inputs and isolation
assertions so the test verifies the AC file is actually read and the allowlists
are not swapped.
packages/challenges/prism/src/prism_challenge/unattested_execution.py (1)

129-151: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Drop the unused argument and collapse the duplicate returns

project_public_attestation() has no callers, stored is only deleted, and the two return branches differ only by execution_mode. Remove the parameter and return a single dict with the mode computed from is_un attested_execution_enabled(), or defer the helper until a caller exists.

🤖 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 `@packages/challenges/prism/src/prism_challenge/unattested_execution.py` around
lines 129 - 151, Update project_public_attestation to remove the unused stored
parameter and delete the corresponding del statement. Collapse the duplicate
return dictionaries into one, computing execution mode from
is_unattested_execution_enabled() while preserving the existing attestation
fields and mode values.
🤖 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 `@docker/master-entrypoint.sh`:
- Around line 212-215: Update the defaulting logic for
PRISM_WORKER_PLANE__ADMISSION_REQUIRES_WORKER in the master entrypoint so it is
false only for unattested/NO_PHALA deployments and remains worker-gated for
attested deployments when the variable is unset. Preserve explicit environment
overrides and the existing CPU_REEXEC_TEST_MODE behavior.

In `@packages/challenges/prism/src/prism_challenge/ingestion.py`:
- Around line 171-177: Thread the per-app unattested setting from create_app’s
PrismSettings into ingestion instead of reading live environment state. Add a
settings-backed flag to the ingestion flow and pass it as settings_flag to both
the response-marking check around mark_result_unattested and
_evaluate_constation_gate, preserving the configured mode for the app instance
throughout its lifetime.

In `@packages/challenges/prism/src/prism_challenge/raw_weight_push.py`:
- Around line 662-663: Update the epoch calculation condition in
packages/challenges/prism/src/prism_challenge/raw_weight_push.py#L662-L663 to
advance only when wall < last, preserving the current epoch when they are equal.
Add an acknowledged epoch=wall case in
packages/challenges/prism/tests/test_raw_weight_push.py#L347-L366 and assert
epoch_fn() == wall.

---

Nitpick comments:
In `@packages/challenges/prism/src/prism_challenge/unattested_execution.py`:
- Around line 129-151: Update project_public_attestation to remove the unused
stored parameter and delete the corresponding del statement. Collapse the
duplicate return dictionaries into one, computing execution mode from
is_unattested_execution_enabled() while preserving the existing attestation
fields and mode values.

In `@packages/challenges/prism/tests/test_unattested_constation_gate.py`:
- Around line 132-138: Extract _clear_unattested_env into the package-level
conftest.py, extending it to delete unknown CHALLENGE_* environment variables in
addition to the three named keys. Remove the local helper definitions from
packages/challenges/prism/tests/test_unattested_constation_gate.py lines 132-138
and packages/challenges/prism/tests/test_unattested_no_bypass.py lines 148-154,
and update both test modules to use the shared helper.
- Around line 377-389: Update the assertions following the
/internal/v1/work_units/result request in the unattested-path test to require
the deterministic expected status and response payload from the stubbed
DockerExecutor.run. Remove the branch that accepts any non-MISSING 422, and
assert the exact successful or specifically expected response fields, including
the unattested tier behavior.

In `@packages/challenges/prism/tests/test_unattested_mark_unforgeable.py`:
- Around line 136-146: Update _clear_unattested_env to use the imported
CHALLENGE_NO_PHALA_ENV constant in the environment-key tuple instead of the
literal "CHALLENGE_NO_PHALA", preserving clearing of all relevant variables if
the constant is renamed.

In `@packages/challenges/prism/tests/test_unattested_no_bypass.py`:
- Around line 712-731: Update test_matrix_documents_enforced_validations to
derive enforced validation codes from the module’s collected test IDs or
expected-code data instead of defining the set inline. Keep assertions that
MISSING is excluded, missing_constation_bundle maps to MISSING via
miner_fault_reason, and at least four distinct validations are covered.
- Around line 52-132: The test fixtures are duplicated across the three
unattested test modules. Move TINY_ARCH, TINY_TRAIN, _SHARD, _stage_train, the
archive encoding helpers (_zip_bytes/_zip_b64), and _settings into the shared
conftest.py, preserving module-specific WORKER_KEY/DIGEST inputs through
parameters or existing fixture mechanisms, then update each test module to reuse
those shared definitions.

In `@tests/unit/test_master_embed_env_file.py`:
- Around line 219-236: Update test_prism_unattested_flags_do_not_leak_into_ac to
provide a distinct ac_env_file_body containing a marker key, then assert that
the marker is present in the AC environment while CHALLENGE_UNATTESTED_EXECUTION
and NO_PHALA from the Prism file remain absent. Keep the existing Prism-only
inputs and isolation assertions so the test verifies the AC file is actually
read and the allowlists are not swapped.
🪄 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: 2a67660a-2027-43f5-a44a-9de4d9991a49

📥 Commits

Reviewing files that changed from the base of the PR and between 22b2448 and 2c1065e.

📒 Files selected for processing (9)
  • docker/master-entrypoint.sh
  • packages/challenges/prism/src/prism_challenge/ingestion.py
  • packages/challenges/prism/src/prism_challenge/raw_weight_push.py
  • packages/challenges/prism/src/prism_challenge/unattested_execution.py
  • packages/challenges/prism/tests/test_raw_weight_push.py
  • packages/challenges/prism/tests/test_unattested_constation_gate.py
  • packages/challenges/prism/tests/test_unattested_mark_unforgeable.py
  • packages/challenges/prism/tests/test_unattested_no_bypass.py
  • tests/unit/test_master_embed_env_file.py

Comment on lines 212 to +215
# PROD POLICY: Prism eval never runs on master — CPU_REEXEC must stay false;
# miners supply Lium pods; admission_requires_worker must stay true.
# miners supply Lium pods; admission_requires_worker default false (unattested/host path).
"PRISM_WORKER_PLANE__CPU_REEXEC_TEST_MODE=${PRISM_WORKER_PLANE__CPU_REEXEC_TEST_MODE:-false}"
"PRISM_WORKER_PLANE__ADMISSION_REQUIRES_WORKER=${PRISM_WORKER_PLANE__ADMISSION_REQUIRES_WORKER:-true}"
"PRISM_WORKER_PLANE__ADMISSION_REQUIRES_WORKER=${PRISM_WORKER_PLANE__ADMISSION_REQUIRES_WORKER:-false}"

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 | 🏗️ Heavy lift

Confirm the admission_requires_worker=false default is intentional for prod, not just the unattested rollout.

This flips embedded Prism from worker-gated admission to open admission for every deployment that doesn't explicitly set the var, including ones running with the unattested flag off. Consider defaulting from the unattested flag instead (e.g. false only when CHALLENGE_UNATTESTED_EXECUTION/NO_PHALA is on) so the attested path keeps its previous guarantee.

🤖 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 `@docker/master-entrypoint.sh` around lines 212 - 215, Update the defaulting
logic for PRISM_WORKER_PLANE__ADMISSION_REQUIRES_WORKER in the master entrypoint
so it is false only for unattested/NO_PHALA deployments and remains worker-gated
for attested deployments when the variable is unset. Preserve explicit
environment overrides and the existing CPU_REEXEC_TEST_MODE behavior.

Comment thread packages/challenges/prism/src/prism_challenge/ingestion.py
Comment thread packages/challenges/prism/src/prism_challenge/raw_weight_push.py
Unattested ship sets entrypoint default to :-false; align the
worker-plane policy landmine with docker/master-entrypoint.sh.
@echobt
echobt merged commit 81b7987 into main Jul 29, 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