agentinputlab 0.1.0a1__py3-none-any.whl
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.
- agentinputlab/__init__.py +28 -0
- agentinputlab/algorithms/__init__.py +6 -0
- agentinputlab/algorithms/acquire/__init__.py +145 -0
- agentinputlab/algorithms/acquire/adaptive_rag/__init__.py +43 -0
- agentinputlab/algorithms/acquire/adaptive_rag/replay.py +367 -0
- agentinputlab/algorithms/acquire/adaptive_rag/runtime.py +1202 -0
- agentinputlab/algorithms/acquire/adaptive_rag_common_support.py +542 -0
- agentinputlab/algorithms/acquire/hyde.py +296 -0
- agentinputlab/algorithms/acquire/hyde_controlled.py +200 -0
- agentinputlab/algorithms/acquire/hyde_external.py +148 -0
- agentinputlab/algorithms/acquire/ircot.py +28 -0
- agentinputlab/algorithms/acquire/ircot_common_support.py +478 -0
- agentinputlab/algorithms/acquire/ircot_native.py +355 -0
- agentinputlab/algorithms/acquire/ircot_replay.py +327 -0
- agentinputlab/algorithms/acquire/qrag/__init__.py +79 -0
- agentinputlab/algorithms/acquire/qrag/bridge.py +828 -0
- agentinputlab/algorithms/acquire/qrag/common_support.py +891 -0
- agentinputlab/algorithms/acquire/qrag/native_axis.py +71 -0
- agentinputlab/algorithms/acquire/qrag/reader_adapter.py +139 -0
- agentinputlab/algorithms/acquire/r2ag/__init__.py +57 -0
- agentinputlab/algorithms/acquire/r2ag/bridge.py +1312 -0
- agentinputlab/algorithms/acquire/r2ag/common_support.py +1029 -0
- agentinputlab/algorithms/acquire/r2ag/socket_runtime.py +255 -0
- agentinputlab/algorithms/clarify/__init__.py +61 -0
- agentinputlab/algorithms/clarify/_structured.py +64 -0
- agentinputlab/algorithms/clarify/active_task_disambiguation.py +371 -0
- agentinputlab/algorithms/clarify/ask_or_assume/__init__.py +17 -0
- agentinputlab/algorithms/clarify/ask_or_assume/monitor.py +410 -0
- agentinputlab/algorithms/clarify/future_turns.py +379 -0
- agentinputlab/algorithms/clarify/udcs.py +255 -0
- agentinputlab/algorithms/clarify/udcs_deterministic.py +196 -0
- agentinputlab/algorithms/curate/__init__.py +65 -0
- agentinputlab/algorithms/curate/acon/__init__.py +27 -0
- agentinputlab/algorithms/curate/acon/common.py +284 -0
- agentinputlab/algorithms/curate/acon/common_support.py +136 -0
- agentinputlab/algorithms/curate/acon/history_bridge.py +309 -0
- agentinputlab/algorithms/curate/acon/observation_bridge.py +290 -0
- agentinputlab/algorithms/curate/llmlingua/__init__.py +30 -0
- agentinputlab/algorithms/curate/llmlingua/adapters.py +537 -0
- agentinputlab/algorithms/curate/llmlingua/budget.py +48 -0
- agentinputlab/algorithms/curate/llmlingua/controlled.py +175 -0
- agentinputlab/algorithms/curate/llmlingua/multilingual.py +105 -0
- agentinputlab/algorithms/curate/llmlingua/span_map.py +167 -0
- agentinputlab/algorithms/curate/recomp/__init__.py +47 -0
- agentinputlab/algorithms/curate/recomp/external.py +1129 -0
- agentinputlab/algorithms/curate/recomp/selective.py +304 -0
- agentinputlab/algorithms/decompose/__init__.py +107 -0
- agentinputlab/algorithms/decompose/decomp/__init__.py +53 -0
- agentinputlab/algorithms/decompose/decomp/common_support.py +478 -0
- agentinputlab/algorithms/decompose/decomp/planner_component.py +199 -0
- agentinputlab/algorithms/decompose/decomp/worker_bridge.py +416 -0
- agentinputlab/algorithms/decompose/llm_compiler/__init__.py +35 -0
- agentinputlab/algorithms/decompose/llm_compiler/bridge.py +520 -0
- agentinputlab/algorithms/decompose/llm_compiler/common_support.py +504 -0
- agentinputlab/algorithms/decompose/plan_and_budget/__init__.py +43 -0
- agentinputlab/algorithms/decompose/plan_and_budget/cached_soft_budget.py +362 -0
- agentinputlab/algorithms/decompose/plan_and_budget/decomposer_component.py +107 -0
- agentinputlab/algorithms/decompose/plan_and_budget/full.py +205 -0
- agentinputlab/algorithms/decompose/plan_and_budget/hard_cap.py +246 -0
- agentinputlab/algorithms/decompose/plan_and_budget/regenerated_soft_budget.py +448 -0
- agentinputlab/algorithms/decompose/plan_and_solve/__init__.py +33 -0
- agentinputlab/algorithms/decompose/plan_and_solve/plan_component.py +192 -0
- agentinputlab/algorithms/decompose/plan_and_solve/ps_prompt.py +127 -0
- agentinputlab/algorithms/decompose/self_ask/__init__.py +27 -0
- agentinputlab/algorithms/decompose/self_ask/loop.py +362 -0
- agentinputlab/algorithms/decompose/self_ask/planner_component.py +117 -0
- agentinputlab/algorithms/reformulate/__init__.py +85 -0
- agentinputlab/algorithms/reformulate/infocqr/__init__.py +40 -0
- agentinputlab/algorithms/reformulate/infocqr/cache_replay.py +362 -0
- agentinputlab/algorithms/reformulate/infocqr/external.py +675 -0
- agentinputlab/algorithms/reformulate/infocqr/student.py +189 -0
- agentinputlab/algorithms/reformulate/query2doc/__init__.py +42 -0
- agentinputlab/algorithms/reformulate/query2doc/controlled_live.py +190 -0
- agentinputlab/algorithms/reformulate/query2doc/models.py +95 -0
- agentinputlab/algorithms/reformulate/query2doc/official_cached.py +335 -0
- agentinputlab/algorithms/reformulate/query2doc/querygym_bridge.py +223 -0
- agentinputlab/algorithms/reformulate/query2doc/querygym_runtime.py +326 -0
- agentinputlab/algorithms/reformulate/reformer/__init__.py +23 -0
- agentinputlab/algorithms/reformulate/reformer/external.py +417 -0
- agentinputlab/algorithms/reformulate/rrr.py +696 -0
- agentinputlab/annotation/__init__.py +5 -0
- agentinputlab/annotation/independent.py +428 -0
- agentinputlab/annotation/server.py +233 -0
- agentinputlab/annotation/static/app.js +121 -0
- agentinputlab/annotation/static/index.html +60 -0
- agentinputlab/annotation/static/review.css +2 -0
- agentinputlab/annotation/static/review.html +10 -0
- agentinputlab/annotation/static/review.js +11 -0
- agentinputlab/annotation/static/styles.css +55 -0
- agentinputlab/annotation/store.py +444 -0
- agentinputlab/api.py +368 -0
- agentinputlab/artifacts/__init__.py +15 -0
- agentinputlab/artifacts/json_file.py +104 -0
- agentinputlab/artifacts/manifest.py +98 -0
- agentinputlab/artifacts/store.py +157 -0
- agentinputlab/backends/__init__.py +98 -0
- agentinputlab/backends/embedding/__init__.py +25 -0
- agentinputlab/backends/embedding/base.py +145 -0
- agentinputlab/backends/embedding/callable.py +75 -0
- agentinputlab/backends/embedding/replay.py +129 -0
- agentinputlab/backends/llm/__init__.py +31 -0
- agentinputlab/backends/llm/base.py +149 -0
- agentinputlab/backends/llm/callable.py +108 -0
- agentinputlab/backends/llm/decomp_completion.py +88 -0
- agentinputlab/backends/llm/final_content_stop.py +72 -0
- agentinputlab/backends/llm/gpt_oss_final_channel.py +84 -0
- agentinputlab/backends/llm/openai_compatible.py +332 -0
- agentinputlab/backends/llm/transformers.py +171 -0
- agentinputlab/backends/retrieval/__init__.py +35 -0
- agentinputlab/backends/retrieval/base.py +50 -0
- agentinputlab/backends/retrieval/dense.py +777 -0
- agentinputlab/backends/retrieval/memory.py +119 -0
- agentinputlab/backends/retrieval/sqlite_fts.py +155 -0
- agentinputlab/backends/user/__init__.py +15 -0
- agentinputlab/backends/user/base.py +66 -0
- agentinputlab/backends/user/callable.py +54 -0
- agentinputlab/backends/user/replay.py +89 -0
- agentinputlab/backends/vector.py +38 -0
- agentinputlab/benchmarks/__init__.py +246 -0
- agentinputlab/benchmarks/acquisition.py +106 -0
- agentinputlab/benchmarks/ale.py +540 -0
- agentinputlab/benchmarks/appworld_ul.py +669 -0
- agentinputlab/benchmarks/assets.py +226 -0
- agentinputlab/benchmarks/base.py +68 -0
- agentinputlab/benchmarks/beir_archive.py +235 -0
- agentinputlab/benchmarks/beir_sample.py +269 -0
- agentinputlab/benchmarks/bfcl_native.py +245 -0
- agentinputlab/benchmarks/bfcl_v3.py +607 -0
- agentinputlab/benchmarks/cache.py +218 -0
- agentinputlab/benchmarks/clariq.py +203 -0
- agentinputlab/benchmarks/data/registry.json +321 -0
- agentinputlab/benchmarks/data/smoke_assets.json +511 -0
- agentinputlab/benchmarks/data/statebench_v0_8_1_task_ids.json +475 -0
- agentinputlab/benchmarks/data/toolsandbox_165848b_scenario_names.json +1 -0
- agentinputlab/benchmarks/execution.py +1111 -0
- agentinputlab/benchmarks/interactive.py +257 -0
- agentinputlab/benchmarks/ir_query.py +204 -0
- agentinputlab/benchmarks/longbench.py +203 -0
- agentinputlab/benchmarks/paired_replay.py +479 -0
- agentinputlab/benchmarks/preprocess.py +2313 -0
- agentinputlab/benchmarks/production.py +236 -0
- agentinputlab/benchmarks/qa.py +963 -0
- agentinputlab/benchmarks/registry.py +110 -0
- agentinputlab/benchmarks/retrieval.py +459 -0
- agentinputlab/benchmarks/runtime.py +509 -0
- agentinputlab/benchmarks/statebench.py +938 -0
- agentinputlab/benchmarks/tau3.py +725 -0
- agentinputlab/benchmarks/toolsandbox.py +626 -0
- agentinputlab/benchmarks/trec_dl_sample.py +263 -0
- agentinputlab/campaign.py +654 -0
- agentinputlab/campaign_runner.py +953 -0
- agentinputlab/cli/__init__.py +6 -0
- agentinputlab/cli/main.py +933 -0
- agentinputlab/connectors/__init__.py +46 -0
- agentinputlab/connectors/knowledge/__init__.py +4 -0
- agentinputlab/connectors/tools/__init__.py +30 -0
- agentinputlab/connectors/tools/base.py +57 -0
- agentinputlab/connectors/tools/mcp.py +222 -0
- agentinputlab/connectors/tools/memory.py +41 -0
- agentinputlab/connectors/tools/openapi.py +695 -0
- agentinputlab/connectors/tools/schema.py +102 -0
- agentinputlab/contracts/__init__.py +91 -0
- agentinputlab/contracts/availability.py +24 -0
- agentinputlab/contracts/dependency.py +58 -0
- agentinputlab/contracts/enums.py +82 -0
- agentinputlab/contracts/errors.py +63 -0
- agentinputlab/contracts/evidence.py +43 -0
- agentinputlab/contracts/intent.py +110 -0
- agentinputlab/contracts/lifecycle.py +164 -0
- agentinputlab/contracts/patch.py +167 -0
- agentinputlab/contracts/serialization.py +93 -0
- agentinputlab/contracts/state.py +127 -0
- agentinputlab/contracts/trace.py +59 -0
- agentinputlab/contracts/worker.py +42 -0
- agentinputlab/core/__init__.py +7 -0
- agentinputlab/data/__init__.py +32 -0
- agentinputlab/data/checksums.py +9 -0
- agentinputlab/data/downloader.py +235 -0
- agentinputlab/data/http.py +171 -0
- agentinputlab/data/index.py +21 -0
- agentinputlab/data/overlap.py +28 -0
- agentinputlab/data/preprocess.py +32 -0
- agentinputlab/data/storage.py +57 -0
- agentinputlab/data/trec_sample.py +427 -0
- agentinputlab/evaluation/__init__.py +5 -0
- agentinputlab/evaluation/outcomes.py +32 -0
- agentinputlab/experiments/__init__.py +278 -0
- agentinputlab/experiments/analysis.py +981 -0
- agentinputlab/experiments/artifacts.py +687 -0
- agentinputlab/experiments/automatic_measurement.py +678 -0
- agentinputlab/experiments/auxiliary_matrix.py +203 -0
- agentinputlab/experiments/bindings.py +430 -0
- agentinputlab/experiments/blueprints.py +147 -0
- agentinputlab/experiments/builders/__init__.py +45 -0
- agentinputlab/experiments/builders/executable_external_payload.py +423 -0
- agentinputlab/experiments/builders/external_process_arena.py +1018 -0
- agentinputlab/experiments/builders/registry_intervention.py +463 -0
- agentinputlab/experiments/cli.py +158 -0
- agentinputlab/experiments/controls.py +340 -0
- agentinputlab/experiments/driver_guard.py +205 -0
- agentinputlab/experiments/drivers/__init__.py +89 -0
- agentinputlab/experiments/drivers/external_arena.py +2908 -0
- agentinputlab/experiments/drivers/method_process.py +662 -0
- agentinputlab/experiments/drivers/parity_process.py +1484 -0
- agentinputlab/experiments/drivers/static_production.py +1574 -0
- agentinputlab/experiments/executor.py +448 -0
- agentinputlab/experiments/loader.py +605 -0
- agentinputlab/experiments/measurement.py +675 -0
- agentinputlab/experiments/paper_analysis.py +1818 -0
- agentinputlab/experiments/parity_identity.py +605 -0
- agentinputlab/experiments/plan.py +277 -0
- agentinputlab/experiments/production_builders.py +3739 -0
- agentinputlab/experiments/readiness.py +432 -0
- agentinputlab/experiments/schema.py +514 -0
- agentinputlab/experiments/secrets.py +177 -0
- agentinputlab/experiments/stateful_analysis.py +1738 -0
- agentinputlab/experiments/transfer_analysis.py +1316 -0
- agentinputlab/experiments/unseen_analysis.py +1025 -0
- agentinputlab/integrations/__init__.py +1 -0
- agentinputlab/integrations/action_space/__init__.py +1 -0
- agentinputlab/integrations/external_workers/__init__.py +76 -0
- agentinputlab/integrations/external_workers/ace.py +431 -0
- agentinputlab/integrations/external_workers/base.py +181 -0
- agentinputlab/integrations/external_workers/decomp_live.py +249 -0
- agentinputlab/integrations/external_workers/decomp_planner.py +30 -0
- agentinputlab/integrations/external_workers/infocqr_student.py +280 -0
- agentinputlab/integrations/external_workers/ircot.py +576 -0
- agentinputlab/integrations/external_workers/llmcompiler_live.py +360 -0
- agentinputlab/integrations/external_workers/longllmlingua.py +162 -0
- agentinputlab/integrations/external_workers/method.py +314 -0
- agentinputlab/integrations/external_workers/process.py +678 -0
- agentinputlab/integrations/external_workers/supervisor.py +1071 -0
- agentinputlab/integrations/full_architecture/__init__.py +1 -0
- agentinputlab/integrations/full_architecture/hyde.py +212 -0
- agentinputlab/integrations/full_architecture/plan_and_budget.py +188 -0
- agentinputlab/integrations/live_history.py +222 -0
- agentinputlab/integrations/prompt_optimization/__init__.py +1 -0
- agentinputlab/integrations/training/__init__.py +1 -0
- agentinputlab/metrics/__init__.py +50 -0
- agentinputlab/metrics/catalog.py +313 -0
- agentinputlab/metrics/harm.py +95 -0
- agentinputlab/metrics/paired.py +40 -0
- agentinputlab/metrics/qa.py +76 -0
- agentinputlab/metrics/text.py +33 -0
- agentinputlab/metrics/third_party.py +161 -0
- agentinputlab/models/__init__.py +4 -0
- agentinputlab/observability/__init__.py +56 -0
- agentinputlab/observability/budget.py +316 -0
- agentinputlab/observability/instrumentation.py +754 -0
- agentinputlab/observability/models.py +403 -0
- agentinputlab/observability/monitor.py +380 -0
- agentinputlab/optimizers/__init__.py +1 -0
- agentinputlab/optimizers/clarify/__init__.py +12 -0
- agentinputlab/optimizers/context/__init__.py +22 -0
- agentinputlab/optimizers/decompose/__init__.py +64 -0
- agentinputlab/optimizers/evidence/__init__.py +22 -0
- agentinputlab/optimizers/rewrite/__init__.py +30 -0
- agentinputlab/parity/__init__.py +5 -0
- agentinputlab/parity/base.py +206 -0
- agentinputlab/production_campaign.py +763 -0
- agentinputlab/py.typed +1 -0
- agentinputlab/recipes/__init__.py +333 -0
- agentinputlab/recipes/ace.py +418 -0
- agentinputlab/recipes/ace_bfcl.py +273 -0
- agentinputlab/recipes/ace_common_support.py +169 -0
- agentinputlab/recipes/ace_native_plan.py +322 -0
- agentinputlab/recipes/ace_online.py +711 -0
- agentinputlab/recipes/ace_retrieval.py +330 -0
- agentinputlab/recipes/ace_statebench.py +382 -0
- agentinputlab/recipes/ace_tau.py +463 -0
- agentinputlab/recipes/ace_toolsandbox.py +432 -0
- agentinputlab/recipes/acon_guideline.py +22 -0
- agentinputlab/recipes/adaptive_rag.py +822 -0
- agentinputlab/recipes/llmlingua2_inference.py +146 -0
- agentinputlab/recipes/llmlingua2_training.py +796 -0
- agentinputlab/recipes/mce.py +1486 -0
- agentinputlab/recipes/mce_final.py +335 -0
- agentinputlab/recipes/mce_text_fit.py +499 -0
- agentinputlab/recipes/mce_text_only.py +298 -0
- agentinputlab/recipes/qrag.py +729 -0
- agentinputlab/recipes/qrag_inference.py +364 -0
- agentinputlab/recipes/r2ag_features.py +236 -0
- agentinputlab/recipes/r2ag_inference.py +503 -0
- agentinputlab/recipes/r2ag_training.py +948 -0
- agentinputlab/recipes/recomp_abstractive.py +592 -0
- agentinputlab/recipes/recomp_extractive.py +525 -0
- agentinputlab/recipes/reformer.py +17 -0
- agentinputlab/recipes/rqrag.py +1516 -0
- agentinputlab/recipes/rqrag_common_support.py +193 -0
- agentinputlab/recipes/rqrag_completion.py +147 -0
- agentinputlab/recipes/skillopt.py +462 -0
- agentinputlab/recipes/skillopt_common_support.py +154 -0
- agentinputlab/recipes/skillopt_environment.py +165 -0
- agentinputlab/recipes/skillopt_environment_cli.py +5 -0
- agentinputlab/recipes/skillopt_retrieval.py +188 -0
- agentinputlab/recipes/smartsearch.py +897 -0
- agentinputlab/recipes/smartsearch_curriculum.py +283 -0
- agentinputlab/recipes/smartsearch_grpo_contracts.py +58 -0
- agentinputlab/recipes/smartsearch_grpo_data.py +314 -0
- agentinputlab/recipes/smartsearch_grpo_meter.py +324 -0
- agentinputlab/recipes/smartsearch_grpo_prefix.py +144 -0
- agentinputlab/recipes/smartsearch_grpo_rollout.py +119 -0
- agentinputlab/recipes/smartsearch_grpo_tools.py +364 -0
- agentinputlab/recipes/smartsearch_grpo_training.py +305 -0
- agentinputlab/recipes/smartsearch_grpo_transport.py +248 -0
- agentinputlab/recipes/smartsearch_grpo_worker.py +364 -0
- agentinputlab/recipes/smartsearch_inference.py +524 -0
- agentinputlab/recipes/smartsearch_native_data.py +172 -0
- agentinputlab/recipes/smartsearch_policy.py +616 -0
- agentinputlab/recipes/smartsearch_policy_worker.py +9 -0
- agentinputlab/recipes/smartsearch_sampling.py +232 -0
- agentinputlab/recipes/smartsearch_teacher.py +203 -0
- agentinputlab/recipes/smartsearch_training.py +265 -0
- agentinputlab/registry/__init__.py +46 -0
- agentinputlab/registry/beta.py +727 -0
- agentinputlab/registry/data/algorithms.json +1959 -0
- agentinputlab/registry/data/auxiliary_method_profiles.json +34 -0
- agentinputlab/registry/loader.py +100 -0
- agentinputlab/registry/result_manifest.py +184 -0
- agentinputlab/registry/runtime.py +195 -0
- agentinputlab/registry/schema.py +449 -0
- agentinputlab/runner/__init__.py +30 -0
- agentinputlab/runner/balance.py +248 -0
- agentinputlab/runner/cache.py +135 -0
- agentinputlab/runner/composite.py +130 -0
- agentinputlab/runner/engine.py +285 -0
- agentinputlab/runner/runtime_guard.py +268 -0
- agentinputlab/runner/worker.py +80 -0
- agentinputlab/runtime_bootstrap.py +288 -0
- agentinputlab/selectors/__init__.py +196 -0
- agentinputlab/selectors/advanced.py +1514 -0
- agentinputlab/selectors/artifacts.py +1087 -0
- agentinputlab/selectors/base.py +112 -0
- agentinputlab/selectors/campaigns.py +1893 -0
- agentinputlab/selectors/catalog.py +86 -0
- agentinputlab/selectors/discovery.py +1860 -0
- agentinputlab/selectors/evaluation.py +1348 -0
- agentinputlab/selectors/features.py +383 -0
- agentinputlab/selectors/learned.py +502 -0
- agentinputlab/selectors/no_op.py +28 -0
- agentinputlab/selectors/outcome_table.py +475 -0
- agentinputlab/selectors/producer.py +853 -0
- agentinputlab/selectors/rules.py +109 -0
- agentinputlab/selectors/runtime.py +420 -0
- agentinputlab/studies/__init__.py +16 -0
- agentinputlab/studies/design.py +165 -0
- agentinputlab/studies/paired.py +322 -0
- agentinputlab/studio/__init__.py +6 -0
- agentinputlab/studio/campaigns.py +819 -0
- agentinputlab/studio/engine.py +1408 -0
- agentinputlab/studio/model_backends.py +425 -0
- agentinputlab/studio/prepared.py +410 -0
- agentinputlab/studio/server.py +613 -0
- agentinputlab/studio/static/app.js +397 -0
- agentinputlab/studio/static/campaigns.html +175 -0
- agentinputlab/studio/static/campaigns.js +426 -0
- agentinputlab/studio/static/index.html +192 -0
- agentinputlab/studio/static/result.html +103 -0
- agentinputlab/studio/static/result.js +273 -0
- agentinputlab/studio/static/styles.css +467 -0
- agentinputlab-0.1.0a1.data/data/share/agentinputlab/CITATION.cff +22 -0
- agentinputlab-0.1.0a1.dist-info/METADATA +392 -0
- agentinputlab-0.1.0a1.dist-info/RECORD +469 -0
- agentinputlab-0.1.0a1.dist-info/WHEEL +5 -0
- agentinputlab-0.1.0a1.dist-info/entry_points.txt +6 -0
- agentinputlab-0.1.0a1.dist-info/licenses/LICENSE +21 -0
- agentinputlab-0.1.0a1.dist-info/licenses/NOTICE +31 -0
- agentinputlab-0.1.0a1.dist-info/licenses/THIRD_PARTY_NOTICES.md +94 -0
- agentinputlab-0.1.0a1.dist-info/top_level.txt +2 -0
- workers/README.md +94 -0
- workers/ace/README.md +261 -0
- workers/ace/__init__.py +1 -0
- workers/ace/compatibility_manifest.json +39 -0
- workers/ace/driver.py +1682 -0
- workers/acon/README.md +215 -0
- workers/acon/__init__.py +5 -0
- workers/acon/compatibility_manifest.json +93 -0
- workers/acon/driver.py +1859 -0
- workers/acon/fitted.py +395 -0
- workers/acon/guideline.py +470 -0
- workers/acon/guideline_source_manifest.json +20 -0
- workers/adaptive_rag/README.md +96 -0
- workers/adaptive_rag/__init__.py +15 -0
- workers/adaptive_rag/compatibility_manifest.json +61 -0
- workers/adaptive_rag/driver.py +1470 -0
- workers/adaptive_rag/fixture_runtime.py +163 -0
- workers/adaptive_rag/runtime.py +252 -0
- workers/ask_or_assume/README.md +124 -0
- workers/ask_or_assume/__init__.py +1 -0
- workers/ask_or_assume/compatibility_manifest.json +36 -0
- workers/ask_or_assume/driver.py +1227 -0
- workers/decomp/README.md +133 -0
- workers/decomp/UPSTREAM_LICENSE.Apache-2.0.txt +201 -0
- workers/decomp/__init__.py +5 -0
- workers/decomp/compatibility_manifest.json +205 -0
- workers/decomp/driver.py +1015 -0
- workers/decomp/live.py +137 -0
- workers/decomp/runtime.py +231 -0
- workers/infocqr/README.md +106 -0
- workers/infocqr/__init__.py +1 -0
- workers/infocqr/compatibility_manifest.json +84 -0
- workers/infocqr/driver.py +1766 -0
- workers/ircot/README.md +167 -0
- workers/ircot/__init__.py +7 -0
- workers/ircot/compatibility_manifest.json +121 -0
- workers/ircot/controlled.py +457 -0
- workers/ircot/driver.py +1373 -0
- workers/ircot/fixture_bindings.json +39 -0
- workers/ircot/fixture_config.json +48 -0
- workers/ircot/fixture_prompt.txt +2 -0
- workers/ircot/native_qa.py +398 -0
- workers/ircot/qa_compatibility_manifest.json +57 -0
- workers/ircot/runtime.py +97 -0
- workers/llmcompiler/README.md +160 -0
- workers/llmcompiler/__init__.py +1 -0
- workers/llmcompiler/compatibility_manifest.json +45 -0
- workers/llmcompiler/driver.py +1514 -0
- workers/llmcompiler/export_prompts.py +74 -0
- workers/llmcompiler/live.py +174 -0
- workers/llmcompiler/patch_manifest.json +147 -0
- workers/mce/README.md +198 -0
- workers/mce/__init__.py +29 -0
- workers/mce/compatibility_manifest.json +115 -0
- workers/mce/driver.py +2585 -0
- workers/mce/final_eval.py +173 -0
- workers/official_arenas/README.md +25 -0
- workers/official_arenas/__init__.py +1 -0
- workers/official_arenas/capture_records.py +110 -0
- workers/official_arenas/driver.py +619 -0
- workers/official_arenas/protocol.py +334 -0
- workers/official_arenas/providers/__init__.py +1 -0
- workers/official_arenas/providers/_live_history.py +228 -0
- workers/official_arenas/providers/_message_compat.py +77 -0
- workers/official_arenas/providers/appworld_ul.py +196 -0
- workers/official_arenas/providers/fixture.py +112 -0
- workers/official_arenas/providers/statebench.py +960 -0
- workers/official_arenas/providers/tau3.py +1672 -0
- workers/official_arenas/providers/tau_retail.py +586 -0
- workers/official_arenas/providers/toolsandbox.py +1321 -0
- workers/official_arenas/providers/tooltalk.py +699 -0
- workers/official_arenas/retail_capture.py +188 -0
- workers/official_arenas/retail_driver.py +275 -0
- workers/qrag/README.md +172 -0
- workers/qrag/__init__.py +1 -0
- workers/qrag/compatibility_manifest.json +64 -0
- workers/qrag/driver.py +673 -0
- workers/r2ag/README.md +154 -0
- workers/r2ag/__init__.py +5 -0
- workers/r2ag/compatibility_manifest.json +55 -0
- workers/r2ag/driver.py +1287 -0
- workers/r2ag/feature_schema.json +8 -0
- workers/r2ag/runtime.py +589 -0
- workers/recomp/README.md +120 -0
- workers/recomp/__init__.py +1 -0
- workers/recomp/compatibility_manifest.json +43 -0
- workers/recomp/driver.py +1653 -0
- workers/reformer/README.md +125 -0
- workers/reformer/__init__.py +1 -0
- workers/reformer/compatibility_manifest.json +68 -0
- workers/reformer/driver.py +1459 -0
- workers/reformer/induction.py +457 -0
- workers/rrr/README.md +126 -0
- workers/rrr/__init__.py +1 -0
- workers/rrr/compatibility_manifest.json +57 -0
- workers/rrr/driver.py +1133 -0
- workers/smartsearch/README.md +331 -0
- workers/smartsearch/__init__.py +1 -0
- workers/smartsearch/compatibility_manifest.json +41 -0
- workers/smartsearch/driver.py +1643 -0
workers/mce/driver.py
ADDED
|
@@ -0,0 +1,2585 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Attested v2 sidecar for Meta Context Engineering.
|
|
3
|
+
|
|
4
|
+
The sidecar is the trusted boundary around generated code. It binds a clean
|
|
5
|
+
source checkout, the environment and three model deployments, enforces model
|
|
6
|
+
and tool budgets before provider calls, keeps validation data outside the
|
|
7
|
+
generated workspace, and persists the selected artifact in a content-addressed
|
|
8
|
+
store. Only an opaque handle and a regular-file manifest cross back to the
|
|
9
|
+
AgentInputLab host.
|
|
10
|
+
|
|
11
|
+
The fixture runtime is deliberately explicit. It proves the protocol and an
|
|
12
|
+
L2 method path; it is not evidence of paper-result parity.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import asyncio
|
|
18
|
+
import hashlib
|
|
19
|
+
import importlib
|
|
20
|
+
import json
|
|
21
|
+
import logging
|
|
22
|
+
import math
|
|
23
|
+
import mimetypes
|
|
24
|
+
import os
|
|
25
|
+
import random
|
|
26
|
+
import shutil
|
|
27
|
+
import subprocess
|
|
28
|
+
import sys
|
|
29
|
+
import tempfile
|
|
30
|
+
import threading
|
|
31
|
+
import time
|
|
32
|
+
from collections.abc import Callable, Iterator, Mapping, Sequence
|
|
33
|
+
from contextlib import contextmanager
|
|
34
|
+
from dataclasses import dataclass
|
|
35
|
+
from functools import wraps
|
|
36
|
+
from pathlib import Path, PurePosixPath
|
|
37
|
+
from types import ModuleType
|
|
38
|
+
from typing import Any, Protocol, TextIO
|
|
39
|
+
|
|
40
|
+
UPSTREAM_COMMIT = "c4b7a7c2ce3ffc4bf4a74c52d2dd8a9a8fb14c30"
|
|
41
|
+
PROTOCOL = "agentinputlab.mce.v2"
|
|
42
|
+
RELEASE_ID = "recipe.mce.sandboxed_offline"
|
|
43
|
+
DEFAULT_MANIFEST = Path(__file__).with_name("compatibility_manifest.json")
|
|
44
|
+
HANDLE_PREFIX = "urn:agentinputlab:mce:sha256:"
|
|
45
|
+
UPSTREAM_MAIN_SHA256 = "769b9ea180ea468530c38893ad15178422d4ba0bbb23ff183d96bde86fdd8ffe"
|
|
46
|
+
UPSTREAM_EVAL_SHA256 = "20ed30d4271ac01ff56318ea89b1b55cc19f5ff8ffbc45361f6a86541ea6fe57"
|
|
47
|
+
SEED_MODE = "python_once_and_manager_logical_call_index_v1"
|
|
48
|
+
PROVIDER_SUBCALL_SEED_MODE = "sha256_logical_seed_and_stable_subcall_index_63bit_v1"
|
|
49
|
+
SEMANTIC_PATCH_MANIFEST = {
|
|
50
|
+
"schema": "agentinputlab.mce.semantic-patch.v2",
|
|
51
|
+
"patch_id": "agentinputlab.mce.semantic-patch.v2",
|
|
52
|
+
"upstream_commit": UPSTREAM_COMMIT,
|
|
53
|
+
"upstream_main_sha256": UPSTREAM_MAIN_SHA256,
|
|
54
|
+
"seams": {
|
|
55
|
+
"mce.main.run_meta_agent": "isolated_manager.run_agent.meta",
|
|
56
|
+
"mce.main.run_base_agent": "isolated_manager.run_agent.base",
|
|
57
|
+
"mce.main.load_interfaces": "isolated_manager.validate_interfaces_static",
|
|
58
|
+
"mce.main.batch_evaluate": "trusted_oracle_supervisor.batch_evaluate",
|
|
59
|
+
},
|
|
60
|
+
"seed_derivation": {
|
|
61
|
+
"python_random": "base_seed_once_per_run",
|
|
62
|
+
"manager_logical_call": "base_seed_plus_logical_call_index",
|
|
63
|
+
"provider_subcall": "sha256_canonical_logical_seed_and_stable_subcall_index_63bit",
|
|
64
|
+
},
|
|
65
|
+
"generated_code_imported_by_worker": False,
|
|
66
|
+
}
|
|
67
|
+
SEMANTIC_PATCH_MANIFEST_SHA256 = "18f5e2452d60db75d837ccccce61b13b0d3c5d7d3c9cb260250e215e8f9076ca"
|
|
68
|
+
EMPTY_INITIAL_CONTEXT = {
|
|
69
|
+
"schema": "agentinputlab.mce.initial-context.v1",
|
|
70
|
+
"files": (),
|
|
71
|
+
}
|
|
72
|
+
_HEX = frozenset("0123456789abcdef")
|
|
73
|
+
_CONTROL_KEYS = frozenset(
|
|
74
|
+
{
|
|
75
|
+
"iterations",
|
|
76
|
+
"train_batch_size",
|
|
77
|
+
"max_model_calls",
|
|
78
|
+
"max_tool_calls",
|
|
79
|
+
"max_wall_seconds",
|
|
80
|
+
"max_artifact_files",
|
|
81
|
+
"max_artifact_bytes",
|
|
82
|
+
"seed",
|
|
83
|
+
}
|
|
84
|
+
)
|
|
85
|
+
_MODEL_FINGERPRINT_FIELDS = frozenset({"provider", "model", "revision", "configuration_sha256"})
|
|
86
|
+
_EXAMPLE_KEYS = frozenset({"example_id", "input", "expected_output", "split", "metadata"})
|
|
87
|
+
_FORBIDDEN_EXAMPLE_KEYS = frozenset(
|
|
88
|
+
{"test_answer", "test_gold", "test_label", "test_reward", "test_target"}
|
|
89
|
+
)
|
|
90
|
+
_ALLOWED_ARTIFACT_PREFIXES = (
|
|
91
|
+
".claude/skills/learning-context/",
|
|
92
|
+
"context/",
|
|
93
|
+
"interfaces/",
|
|
94
|
+
)
|
|
95
|
+
_ALLOWED_ARTIFACT_FILES = frozenset({"retrieve_context.py"})
|
|
96
|
+
_MAX_JSONL_BYTES = 8 * 1024 * 1024
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class DriverError(RuntimeError):
|
|
100
|
+
"""Stable sidecar error, including trusted consumed usage when available."""
|
|
101
|
+
|
|
102
|
+
def __init__(
|
|
103
|
+
self,
|
|
104
|
+
code: str,
|
|
105
|
+
message: str,
|
|
106
|
+
*,
|
|
107
|
+
consumed: bool = False,
|
|
108
|
+
usage: Mapping[str, int | float] | None = None,
|
|
109
|
+
) -> None:
|
|
110
|
+
super().__init__(message)
|
|
111
|
+
self.code = code
|
|
112
|
+
self.public_message = message
|
|
113
|
+
self.consumed = consumed
|
|
114
|
+
self.usage = dict(usage or {})
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@dataclass(frozen=True, slots=True)
|
|
118
|
+
class MCEEvolutionIteration:
|
|
119
|
+
"""One generated iteration before trusted validation."""
|
|
120
|
+
|
|
121
|
+
index: int
|
|
122
|
+
artifact_root: Path
|
|
123
|
+
validation_score: float
|
|
124
|
+
|
|
125
|
+
def __post_init__(self) -> None:
|
|
126
|
+
if isinstance(self.index, bool) or not isinstance(self.index, int) or self.index < 0:
|
|
127
|
+
raise DriverError("RUNTIME_INVALID", "MCE iteration index is invalid", consumed=True)
|
|
128
|
+
artifact_root = Path(self.artifact_root)
|
|
129
|
+
if artifact_root.is_symlink():
|
|
130
|
+
raise DriverError(
|
|
131
|
+
"PATH_REJECTED",
|
|
132
|
+
"MCE iteration artifact root may not be a symlink",
|
|
133
|
+
consumed=True,
|
|
134
|
+
)
|
|
135
|
+
object.__setattr__(self, "artifact_root", artifact_root.resolve())
|
|
136
|
+
object.__setattr__(
|
|
137
|
+
self,
|
|
138
|
+
"validation_score",
|
|
139
|
+
_finite(self.validation_score, "MCE validation score"),
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@dataclass(frozen=True, slots=True)
|
|
144
|
+
class MCEEvolutionRun:
|
|
145
|
+
"""Generated candidates returned by the isolated upstream loop."""
|
|
146
|
+
|
|
147
|
+
iterations: tuple[MCEEvolutionIteration, ...]
|
|
148
|
+
official_run_iteration_called: bool = True
|
|
149
|
+
meta_agent_enabled: bool = True
|
|
150
|
+
base_agent_enabled: bool = True
|
|
151
|
+
|
|
152
|
+
def __post_init__(self) -> None:
|
|
153
|
+
object.__setattr__(self, "iterations", tuple(self.iterations))
|
|
154
|
+
if not self.iterations:
|
|
155
|
+
raise DriverError("RUNTIME_INVALID", "MCE returned no iterations", consumed=True)
|
|
156
|
+
for name in (
|
|
157
|
+
"official_run_iteration_called",
|
|
158
|
+
"meta_agent_enabled",
|
|
159
|
+
"base_agent_enabled",
|
|
160
|
+
):
|
|
161
|
+
if not isinstance(getattr(self, name), bool):
|
|
162
|
+
raise DriverError(
|
|
163
|
+
"RUNTIME_INVALID",
|
|
164
|
+
f"MCE runtime {name} must be boolean",
|
|
165
|
+
consumed=True,
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
class TrustedProviderSupervisor:
|
|
170
|
+
"""Provider-side meter that reserves each call before the side effect."""
|
|
171
|
+
|
|
172
|
+
def __init__(self, *, model_calls: int, tool_calls: int, wall_seconds: int) -> None:
|
|
173
|
+
self._model_limit = _positive_int_value(model_calls, "model_calls")
|
|
174
|
+
self._tool_limit = _positive_int_value(tool_calls, "tool_calls")
|
|
175
|
+
self._wall_limit = _positive_int_value(wall_seconds, "wall_seconds")
|
|
176
|
+
self._started = time.monotonic()
|
|
177
|
+
self._model_calls = 0
|
|
178
|
+
self._tool_calls = 0
|
|
179
|
+
self._input_tokens = 0
|
|
180
|
+
self._output_tokens = 0
|
|
181
|
+
self._unpriced_model_calls = 0
|
|
182
|
+
self._cost_usd = 0.0
|
|
183
|
+
self._accelerator_seconds = 0.0
|
|
184
|
+
self._seeded_model_calls = 0
|
|
185
|
+
self._next_subcall_index: dict[int, int] = {}
|
|
186
|
+
|
|
187
|
+
def before_model_call(self, *, input_tokens: int = 0) -> None:
|
|
188
|
+
"""Reserve one model call before invoking the provider."""
|
|
189
|
+
|
|
190
|
+
self._check_wall()
|
|
191
|
+
tokens = _nonnegative_int_value(input_tokens, "input_tokens")
|
|
192
|
+
if self._model_calls >= self._model_limit:
|
|
193
|
+
raise DriverError(
|
|
194
|
+
"BUDGET_EXCEEDED",
|
|
195
|
+
"MCE model-call budget exhausted before provider invocation",
|
|
196
|
+
consumed=self._model_calls > 0 or self._tool_calls > 0,
|
|
197
|
+
usage=self.usage(),
|
|
198
|
+
)
|
|
199
|
+
self._model_calls += 1
|
|
200
|
+
self._unpriced_model_calls += 1
|
|
201
|
+
self._input_tokens += tokens
|
|
202
|
+
|
|
203
|
+
def before_seeded_model_call(
|
|
204
|
+
self,
|
|
205
|
+
*,
|
|
206
|
+
logical_seed: int,
|
|
207
|
+
stable_subcall_index: int,
|
|
208
|
+
provider_seed: int,
|
|
209
|
+
input_tokens: int = 0,
|
|
210
|
+
) -> None:
|
|
211
|
+
"""Verify the manager's deterministic subcall seed, then reserve the call."""
|
|
212
|
+
|
|
213
|
+
expected = derive_provider_subcall_seed(logical_seed, stable_subcall_index)
|
|
214
|
+
expected_index = self._next_subcall_index.get(logical_seed, 0)
|
|
215
|
+
if stable_subcall_index != expected_index:
|
|
216
|
+
raise DriverError(
|
|
217
|
+
"SEED_INVALID",
|
|
218
|
+
"MCE provider subcall index is not stable and contiguous",
|
|
219
|
+
consumed=self._model_calls > 0 or self._tool_calls > 0,
|
|
220
|
+
usage=self.usage(),
|
|
221
|
+
)
|
|
222
|
+
if provider_seed != expected:
|
|
223
|
+
raise DriverError(
|
|
224
|
+
"SEED_INVALID",
|
|
225
|
+
"MCE provider subcall seed does not match the attested derivation",
|
|
226
|
+
consumed=self._model_calls > 0 or self._tool_calls > 0,
|
|
227
|
+
usage=self.usage(),
|
|
228
|
+
)
|
|
229
|
+
self.before_model_call(input_tokens=input_tokens)
|
|
230
|
+
self._next_subcall_index[logical_seed] = stable_subcall_index + 1
|
|
231
|
+
self._seeded_model_calls += 1
|
|
232
|
+
|
|
233
|
+
def verify_all_model_calls_seeded(self) -> None:
|
|
234
|
+
"""Fail closed when an attested manager bypassed seeded reservation."""
|
|
235
|
+
|
|
236
|
+
if self._seeded_model_calls != self._model_calls:
|
|
237
|
+
raise DriverError(
|
|
238
|
+
"SEED_INVALID",
|
|
239
|
+
"MCE manager reserved an unseeded provider model call",
|
|
240
|
+
consumed=self._model_calls > 0 or self._tool_calls > 0,
|
|
241
|
+
usage=self.usage(),
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
def after_model_call(
|
|
245
|
+
self,
|
|
246
|
+
*,
|
|
247
|
+
output_tokens: int = 0,
|
|
248
|
+
cost_usd: float | None = None,
|
|
249
|
+
accelerator_seconds: float = 0.0,
|
|
250
|
+
) -> None:
|
|
251
|
+
self._output_tokens += _nonnegative_int_value(output_tokens, "output_tokens")
|
|
252
|
+
self._accelerator_seconds += _nonnegative_float_value(
|
|
253
|
+
accelerator_seconds,
|
|
254
|
+
"accelerator_seconds",
|
|
255
|
+
)
|
|
256
|
+
if cost_usd is not None:
|
|
257
|
+
self._cost_usd += _nonnegative_float_value(cost_usd, "cost_usd")
|
|
258
|
+
if self._unpriced_model_calls:
|
|
259
|
+
self._unpriced_model_calls -= 1
|
|
260
|
+
|
|
261
|
+
def before_tool_call(self) -> None:
|
|
262
|
+
"""Reserve one tool call before invoking the tool provider."""
|
|
263
|
+
|
|
264
|
+
self._check_wall()
|
|
265
|
+
if self._tool_calls >= self._tool_limit:
|
|
266
|
+
raise DriverError(
|
|
267
|
+
"BUDGET_EXCEEDED",
|
|
268
|
+
"MCE tool-call budget exhausted before provider invocation",
|
|
269
|
+
consumed=self._model_calls > 0 or self._tool_calls > 0,
|
|
270
|
+
usage=self.usage(),
|
|
271
|
+
)
|
|
272
|
+
self._tool_calls += 1
|
|
273
|
+
|
|
274
|
+
def usage(self) -> Mapping[str, int | float]:
|
|
275
|
+
return {
|
|
276
|
+
"model_calls": self._model_calls,
|
|
277
|
+
"retrieval_calls": 0,
|
|
278
|
+
"tool_calls": self._tool_calls,
|
|
279
|
+
"embedding_calls": 0,
|
|
280
|
+
"unpriced_model_calls": self._unpriced_model_calls,
|
|
281
|
+
"input_tokens": self._input_tokens,
|
|
282
|
+
"output_tokens": self._output_tokens,
|
|
283
|
+
"cpu_seconds": 0.0,
|
|
284
|
+
"accelerator_seconds": self._accelerator_seconds,
|
|
285
|
+
"cost_usd": self._cost_usd,
|
|
286
|
+
"compute_cost_usd": 0.0,
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
def check_wall(self) -> None:
|
|
290
|
+
"""Reject a completed operation that crossed the configured deadline."""
|
|
291
|
+
|
|
292
|
+
self._check_wall()
|
|
293
|
+
|
|
294
|
+
def _check_wall(self) -> None:
|
|
295
|
+
if time.monotonic() - self._started > self._wall_limit:
|
|
296
|
+
raise DriverError(
|
|
297
|
+
"BUDGET_EXCEEDED",
|
|
298
|
+
"MCE wall budget exhausted before provider invocation",
|
|
299
|
+
consumed=self._model_calls > 0 or self._tool_calls > 0,
|
|
300
|
+
usage=self.usage(),
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
def _serialized_evaluation_meter(method: Callable[..., Any]) -> Callable[..., Any]:
|
|
305
|
+
@wraps(method)
|
|
306
|
+
def guarded(self: Any, *args: Any, **kwargs: Any) -> Any:
|
|
307
|
+
with self._evaluation_lock:
|
|
308
|
+
return method(self, *args, **kwargs)
|
|
309
|
+
return guarded
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
class TrustedEvaluationSupervisor(TrustedProviderSupervisor):
|
|
313
|
+
"""Reserve actual provider-request token caps before frozen-artifact use.
|
|
314
|
+
|
|
315
|
+
A returned reservation ID must accompany each provider response. Failed
|
|
316
|
+
requests with unknown token usage keep their reservation quarantined;
|
|
317
|
+
they are never treated as zero-cost calls or retried here.
|
|
318
|
+
"""
|
|
319
|
+
|
|
320
|
+
def __init__(
|
|
321
|
+
self,
|
|
322
|
+
*,
|
|
323
|
+
model_calls: int = 8,
|
|
324
|
+
tool_calls: int = 8,
|
|
325
|
+
wall_seconds: int = 3600,
|
|
326
|
+
output_tokens: int = 4096,
|
|
327
|
+
output_tokens_per_call: int = 512,
|
|
328
|
+
) -> None:
|
|
329
|
+
super().__init__(model_calls=model_calls, tool_calls=tool_calls, wall_seconds=wall_seconds)
|
|
330
|
+
self._output_limit = _positive_int_value(output_tokens, "output_tokens")
|
|
331
|
+
self._output_per_call = _positive_int_value(output_tokens_per_call, "output_tokens_per_call")
|
|
332
|
+
if self._output_per_call > self._output_limit:
|
|
333
|
+
raise DriverError("BUDGET_INVALID", "MCE per-call output cap exceeds the total cap")
|
|
334
|
+
self._reservations: dict[int, int] = {}
|
|
335
|
+
self._failed_unknown: set[int] = set()
|
|
336
|
+
self._responses = 0
|
|
337
|
+
self._evaluation_lock = threading.RLock()
|
|
338
|
+
|
|
339
|
+
def before_model_call(self, *, input_tokens: int = 0) -> None:
|
|
340
|
+
del input_tokens
|
|
341
|
+
raise DriverError("SEED_INVALID", "MCE final evaluation requires seeded token reservations")
|
|
342
|
+
|
|
343
|
+
@_serialized_evaluation_meter
|
|
344
|
+
def before_seeded_model_call(
|
|
345
|
+
self,
|
|
346
|
+
*,
|
|
347
|
+
logical_seed: int,
|
|
348
|
+
stable_subcall_index: int,
|
|
349
|
+
provider_seed: int,
|
|
350
|
+
requested_output_tokens: int,
|
|
351
|
+
input_tokens: int = 0,
|
|
352
|
+
) -> int:
|
|
353
|
+
requested = _positive_int_value(requested_output_tokens, "requested_output_tokens")
|
|
354
|
+
if (
|
|
355
|
+
requested > self._output_per_call
|
|
356
|
+
or self._output_tokens + sum(self._reservations.values()) + requested > self._output_limit
|
|
357
|
+
):
|
|
358
|
+
raise DriverError(
|
|
359
|
+
"BUDGET_EXCEEDED", "MCE output budget exhausted before provider invocation",
|
|
360
|
+
consumed=bool(self._model_calls), usage=self.usage(),
|
|
361
|
+
)
|
|
362
|
+
expected = derive_provider_subcall_seed(logical_seed, stable_subcall_index)
|
|
363
|
+
if (
|
|
364
|
+
stable_subcall_index != self._next_subcall_index.get(logical_seed, 0)
|
|
365
|
+
or provider_seed != expected
|
|
366
|
+
):
|
|
367
|
+
raise DriverError("SEED_INVALID", "MCE final-evaluation provider seed drifted")
|
|
368
|
+
TrustedProviderSupervisor.before_model_call(self, input_tokens=input_tokens)
|
|
369
|
+
self._next_subcall_index[logical_seed] = stable_subcall_index + 1
|
|
370
|
+
self._seeded_model_calls += 1
|
|
371
|
+
reservation_id = self._model_calls
|
|
372
|
+
self._reservations[reservation_id] = requested
|
|
373
|
+
return reservation_id
|
|
374
|
+
|
|
375
|
+
@_serialized_evaluation_meter
|
|
376
|
+
def after_model_call(
|
|
377
|
+
self,
|
|
378
|
+
*,
|
|
379
|
+
reservation_id: int,
|
|
380
|
+
output_tokens: int = 0,
|
|
381
|
+
cost_usd: float | None = None,
|
|
382
|
+
accelerator_seconds: float = 0.0,
|
|
383
|
+
) -> None:
|
|
384
|
+
reservation_id = _positive_int_value(reservation_id, "reservation_id")
|
|
385
|
+
if reservation_id not in self._reservations or reservation_id in self._failed_unknown:
|
|
386
|
+
raise DriverError("USAGE_INVALID", "MCE response has no open token reservation")
|
|
387
|
+
tokens = _nonnegative_int_value(output_tokens, "output_tokens")
|
|
388
|
+
cap = self._reservations[reservation_id]
|
|
389
|
+
# Validate all fields before changing the reservation/counters.
|
|
390
|
+
_nonnegative_float_value(accelerator_seconds, "accelerator_seconds")
|
|
391
|
+
if cost_usd is not None:
|
|
392
|
+
_nonnegative_float_value(cost_usd, "cost_usd")
|
|
393
|
+
super().after_model_call(
|
|
394
|
+
output_tokens=tokens, cost_usd=cost_usd, accelerator_seconds=accelerator_seconds,
|
|
395
|
+
)
|
|
396
|
+
del self._reservations[reservation_id]
|
|
397
|
+
self._responses += 1
|
|
398
|
+
if tokens > cap:
|
|
399
|
+
# Preserve measured overrun cost before rejecting the provider contract.
|
|
400
|
+
raise DriverError(
|
|
401
|
+
"BUDGET_EXCEEDED", "MCE provider exceeded its reserved output-token cap",
|
|
402
|
+
consumed=True, usage=self.usage(),
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
@_serialized_evaluation_meter
|
|
406
|
+
def failed_model_call(self, *, reservation_id: int) -> None:
|
|
407
|
+
reservation_id = _positive_int_value(reservation_id, "reservation_id")
|
|
408
|
+
if reservation_id not in self._reservations or reservation_id in self._failed_unknown:
|
|
409
|
+
raise DriverError("USAGE_INVALID", "MCE failure has no open token reservation")
|
|
410
|
+
self._failed_unknown.add(reservation_id)
|
|
411
|
+
|
|
412
|
+
@_serialized_evaluation_meter
|
|
413
|
+
def before_tool_call(self) -> None:
|
|
414
|
+
super().before_tool_call()
|
|
415
|
+
|
|
416
|
+
@_serialized_evaluation_meter
|
|
417
|
+
def usage(self) -> Mapping[str, int | float]:
|
|
418
|
+
return super().usage()
|
|
419
|
+
|
|
420
|
+
@_serialized_evaluation_meter
|
|
421
|
+
def output_budget_receipt(self) -> Mapping[str, Any]:
|
|
422
|
+
return {
|
|
423
|
+
"schema": "agentinputlab.mce.final-output-budget.v1",
|
|
424
|
+
"max_output_tokens": self._output_limit,
|
|
425
|
+
"max_output_tokens_per_call": self._output_per_call,
|
|
426
|
+
"actual_output_tokens": self._output_tokens,
|
|
427
|
+
"provider_responses": self._responses,
|
|
428
|
+
"pending_reservations": {
|
|
429
|
+
str(key): value for key, value in sorted(self._reservations.items())
|
|
430
|
+
if key not in self._failed_unknown
|
|
431
|
+
},
|
|
432
|
+
"failed_unknown_output_reservations": {
|
|
433
|
+
str(key): self._reservations[key] for key in sorted(self._failed_unknown)
|
|
434
|
+
},
|
|
435
|
+
"reserved_unknown_tokens_are_not_actual_usage": True,
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
class MCERuntime(Protocol):
|
|
440
|
+
"""Runtime seam executed inside the attested generated-code boundary."""
|
|
441
|
+
|
|
442
|
+
def evolve(
|
|
443
|
+
self,
|
|
444
|
+
*,
|
|
445
|
+
workspace: Path,
|
|
446
|
+
train_path: Path,
|
|
447
|
+
validation_path: Path,
|
|
448
|
+
controls: Mapping[str, int],
|
|
449
|
+
model_fingerprints: Mapping[str, Any],
|
|
450
|
+
supervisor: TrustedProviderSupervisor,
|
|
451
|
+
) -> MCEEvolutionRun: ...
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
def final_evaluation_manager_contract() -> Mapping[str, Any]:
|
|
455
|
+
"""Operator attestation for the frozen evaluator's provider/oracle boundary."""
|
|
456
|
+
return {
|
|
457
|
+
"schema": "agentinputlab.mce.final-evaluation-manager.v1",
|
|
458
|
+
"source_commit": UPSTREAM_COMMIT,
|
|
459
|
+
"upstream_eval_source_sha256": UPSTREAM_EVAL_SHA256,
|
|
460
|
+
"semantic_patch_manifest_sha256": SEMANTIC_PATCH_MANIFEST_SHA256,
|
|
461
|
+
"frozen_interfaces_only": True,
|
|
462
|
+
"adaptation_disabled": True,
|
|
463
|
+
"test_oracle_mode": "supervisor_only_hidden",
|
|
464
|
+
"output_token_guard": "actual_provider_request_pre_call_reservation_v1",
|
|
465
|
+
"response_reservation_ids": True,
|
|
466
|
+
"failed_unknown_output_budget_quarantined": True,
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
def _verify_generated_workspace_boundary(sandbox_manager: Any) -> Mapping[str, Any]:
|
|
471
|
+
"""Validate the exact operator-attested isolated-manager contract."""
|
|
472
|
+
|
|
473
|
+
fingerprint = getattr(sandbox_manager, "fingerprint", None)
|
|
474
|
+
if not callable(fingerprint):
|
|
475
|
+
raise DriverError(
|
|
476
|
+
"ATTESTATION_INVALID",
|
|
477
|
+
"MCE sandbox manager must expose a trusted fingerprint()",
|
|
478
|
+
)
|
|
479
|
+
try:
|
|
480
|
+
value = fingerprint()
|
|
481
|
+
except Exception as exc:
|
|
482
|
+
raise DriverError(
|
|
483
|
+
"ATTESTATION_INVALID",
|
|
484
|
+
"MCE sandbox manager fingerprint could not be read",
|
|
485
|
+
) from exc
|
|
486
|
+
expected = {
|
|
487
|
+
"schema": "agentinputlab.mce.isolated-manager.v1",
|
|
488
|
+
"generated_code_execution": "isolated_worker_only",
|
|
489
|
+
"oracle_mount_mode": "supervisor_only_hidden",
|
|
490
|
+
"oracle_process_boundary": "trusted_supervisor_out_of_process",
|
|
491
|
+
"generated_workspace_oracle_visible": False,
|
|
492
|
+
"provider_guard_mode": "provider_transport_pre_call",
|
|
493
|
+
"seed_mode": SEED_MODE,
|
|
494
|
+
"provider_subcall_seed_mode": PROVIDER_SUBCALL_SEED_MODE,
|
|
495
|
+
"validation_scoring_mode": "supervisor_only",
|
|
496
|
+
"run_agent_mode": "remote_only",
|
|
497
|
+
"interface_validation_mode": "remote_static_no_import",
|
|
498
|
+
"batch_evaluation_mode": "trusted_supervisor_no_generated_import",
|
|
499
|
+
"source_commit": UPSTREAM_COMMIT,
|
|
500
|
+
"upstream_main_sha256": UPSTREAM_MAIN_SHA256,
|
|
501
|
+
"semantic_patch_manifest_sha256": SEMANTIC_PATCH_MANIFEST_SHA256,
|
|
502
|
+
}
|
|
503
|
+
identity_keys = {
|
|
504
|
+
"generated_worker_identity_sha256",
|
|
505
|
+
"oracle_supervisor_identity_sha256",
|
|
506
|
+
"provider_proxy_identity_sha256",
|
|
507
|
+
}
|
|
508
|
+
if (
|
|
509
|
+
not isinstance(value, Mapping)
|
|
510
|
+
or set(value) != set(expected) | identity_keys
|
|
511
|
+
or any(value.get(key) != expected_value for key, expected_value in expected.items())
|
|
512
|
+
):
|
|
513
|
+
raise DriverError(
|
|
514
|
+
"ATTESTATION_INVALID",
|
|
515
|
+
"MCE sandbox manager fingerprint does not match the required boundary",
|
|
516
|
+
)
|
|
517
|
+
for key in identity_keys:
|
|
518
|
+
_require_sha256(value.get(key), f"sandbox manager {key}")
|
|
519
|
+
for method in (
|
|
520
|
+
"bind_run",
|
|
521
|
+
"run_agent",
|
|
522
|
+
"validate_interfaces_static",
|
|
523
|
+
"batch_evaluate",
|
|
524
|
+
"usage_receipt",
|
|
525
|
+
):
|
|
526
|
+
if not callable(getattr(sandbox_manager, method, None)):
|
|
527
|
+
raise DriverError(
|
|
528
|
+
"ATTESTATION_INVALID",
|
|
529
|
+
f"MCE sandbox manager lacks required {method}()",
|
|
530
|
+
)
|
|
531
|
+
return json.loads(_canonical_json(value))
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
@contextmanager
|
|
535
|
+
def _pinned_upstream_modules(
|
|
536
|
+
source_root: Path,
|
|
537
|
+
) -> Iterator[tuple[ModuleType, ModuleType]]:
|
|
538
|
+
"""Import the pinned upstream modules without accepting ``sys.modules`` injection."""
|
|
539
|
+
|
|
540
|
+
root = Path(source_root).resolve()
|
|
541
|
+
main_path = _safe_source_file(root, "mce/main.py")
|
|
542
|
+
if _sha256_file(main_path) != UPSTREAM_MAIN_SHA256:
|
|
543
|
+
raise DriverError("SOURCE_MISMATCH", "MCE upstream main.py hash drifted")
|
|
544
|
+
displaced = {
|
|
545
|
+
name: module
|
|
546
|
+
for name, module in tuple(sys.modules.items())
|
|
547
|
+
if name == "mce" or name.startswith("mce.") or name == "env" or name.startswith("env.")
|
|
548
|
+
}
|
|
549
|
+
for name in displaced:
|
|
550
|
+
sys.modules.pop(name, None)
|
|
551
|
+
original_path = list(sys.path)
|
|
552
|
+
original_bytecode = sys.dont_write_bytecode
|
|
553
|
+
sys.path.insert(0, str(root))
|
|
554
|
+
sys.dont_write_bytecode = True
|
|
555
|
+
importlib.invalidate_caches()
|
|
556
|
+
try:
|
|
557
|
+
upstream_main = importlib.import_module("mce.main")
|
|
558
|
+
upstream_utils = importlib.import_module("mce.utils")
|
|
559
|
+
for module, relative in (
|
|
560
|
+
(upstream_main, "mce/main.py"),
|
|
561
|
+
(upstream_utils, "mce/utils.py"),
|
|
562
|
+
):
|
|
563
|
+
origin = getattr(module, "__file__", None)
|
|
564
|
+
if not isinstance(origin, str):
|
|
565
|
+
raise DriverError(
|
|
566
|
+
"UPSTREAM_IMPORT_FAILED",
|
|
567
|
+
f"pinned MCE module lacks an origin: {module.__name__}",
|
|
568
|
+
)
|
|
569
|
+
try:
|
|
570
|
+
Path(origin).resolve(strict=True).relative_to(root)
|
|
571
|
+
except (FileNotFoundError, ValueError) as exc:
|
|
572
|
+
raise DriverError(
|
|
573
|
+
"UPSTREAM_IMPORT_FAILED",
|
|
574
|
+
f"MCE module resolved outside pinned source: {module.__name__}",
|
|
575
|
+
) from exc
|
|
576
|
+
if Path(origin).resolve() != (root / relative).resolve():
|
|
577
|
+
raise DriverError(
|
|
578
|
+
"UPSTREAM_IMPORT_FAILED",
|
|
579
|
+
f"MCE module origin drifted: {module.__name__}",
|
|
580
|
+
)
|
|
581
|
+
yield upstream_main, upstream_utils
|
|
582
|
+
except DriverError:
|
|
583
|
+
raise
|
|
584
|
+
except Exception as exc:
|
|
585
|
+
raise DriverError(
|
|
586
|
+
"UPSTREAM_IMPORT_FAILED",
|
|
587
|
+
"pinned MCE runtime could not be imported",
|
|
588
|
+
) from exc
|
|
589
|
+
finally:
|
|
590
|
+
for name in tuple(sys.modules):
|
|
591
|
+
if name == "mce" or name.startswith("mce.") or name == "env" or name.startswith("env."):
|
|
592
|
+
sys.modules.pop(name, None)
|
|
593
|
+
sys.modules.update(displaced)
|
|
594
|
+
sys.path[:] = original_path
|
|
595
|
+
sys.dont_write_bytecode = original_bytecode
|
|
596
|
+
importlib.invalidate_caches()
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
class MCEOfficialRuntime:
|
|
600
|
+
"""Run pinned orchestration with four narrowly scoped isolation patches."""
|
|
601
|
+
|
|
602
|
+
def __init__(
|
|
603
|
+
self,
|
|
604
|
+
*,
|
|
605
|
+
source_root: Path,
|
|
606
|
+
environment_name: str,
|
|
607
|
+
sandbox_manager: Any,
|
|
608
|
+
) -> None:
|
|
609
|
+
raw_source_root = Path(source_root)
|
|
610
|
+
if raw_source_root.is_symlink():
|
|
611
|
+
raise DriverError("PATH_REJECTED", "MCE source root may not be a symlink")
|
|
612
|
+
self.source_root = raw_source_root.resolve()
|
|
613
|
+
if not isinstance(environment_name, str) or not environment_name.strip():
|
|
614
|
+
raise DriverError("CONFIG_INVALID", "MCE environment name is required")
|
|
615
|
+
self.environment_name = environment_name
|
|
616
|
+
self.sandbox_manager = sandbox_manager
|
|
617
|
+
self.sandbox_manager_fingerprint = _verify_generated_workspace_boundary(sandbox_manager)
|
|
618
|
+
|
|
619
|
+
def fingerprint(self) -> Mapping[str, Any]:
|
|
620
|
+
return {
|
|
621
|
+
"schema": "agentinputlab.mce.official-runtime.v1",
|
|
622
|
+
"source_commit": UPSTREAM_COMMIT,
|
|
623
|
+
"upstream_main_sha256": UPSTREAM_MAIN_SHA256,
|
|
624
|
+
"semantic_patch_manifest": SEMANTIC_PATCH_MANIFEST,
|
|
625
|
+
"semantic_patch_manifest_sha256": SEMANTIC_PATCH_MANIFEST_SHA256,
|
|
626
|
+
"sandbox_manager": self.sandbox_manager_fingerprint,
|
|
627
|
+
"sandbox_manager_fingerprint_sha256": _content_hash(self.sandbox_manager_fingerprint),
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
def _bind_manager_run(
|
|
631
|
+
self,
|
|
632
|
+
*,
|
|
633
|
+
model_fingerprints: Mapping[str, Any],
|
|
634
|
+
seed: int,
|
|
635
|
+
max_wall_seconds: int,
|
|
636
|
+
supervisor: TrustedProviderSupervisor,
|
|
637
|
+
) -> None:
|
|
638
|
+
binding = self.sandbox_manager.bind_run(
|
|
639
|
+
supervisor=supervisor,
|
|
640
|
+
model_fingerprints=json.loads(_canonical_json(model_fingerprints)),
|
|
641
|
+
seed=seed,
|
|
642
|
+
seed_mode=SEED_MODE,
|
|
643
|
+
provider_subcall_seed_mode=PROVIDER_SUBCALL_SEED_MODE,
|
|
644
|
+
max_wall_seconds=max_wall_seconds,
|
|
645
|
+
semantic_patch_manifest=json.loads(_canonical_json(SEMANTIC_PATCH_MANIFEST)),
|
|
646
|
+
)
|
|
647
|
+
expected = {
|
|
648
|
+
"schema": "agentinputlab.mce.manager-binding.v1",
|
|
649
|
+
"semantic_patch_manifest_sha256": SEMANTIC_PATCH_MANIFEST_SHA256,
|
|
650
|
+
"model_fingerprints_sha256": _content_hash(model_fingerprints),
|
|
651
|
+
"seed": seed,
|
|
652
|
+
"seed_mode": SEED_MODE,
|
|
653
|
+
"provider_subcall_seed_mode": PROVIDER_SUBCALL_SEED_MODE,
|
|
654
|
+
"max_wall_seconds": max_wall_seconds,
|
|
655
|
+
"provider_guard_installed": True,
|
|
656
|
+
"provider_pre_call_reservation": True,
|
|
657
|
+
}
|
|
658
|
+
if not isinstance(binding, Mapping) or dict(binding) != expected:
|
|
659
|
+
raise DriverError(
|
|
660
|
+
"ATTESTATION_INVALID", "MCE isolated manager did not bind the run budget and identities",
|
|
661
|
+
)
|
|
662
|
+
|
|
663
|
+
def _verify_manager_usage(self, supervisor: TrustedProviderSupervisor) -> None:
|
|
664
|
+
supervisor.check_wall()
|
|
665
|
+
supervisor.verify_all_model_calls_seeded()
|
|
666
|
+
receipt = self.sandbox_manager.usage_receipt()
|
|
667
|
+
expected = {
|
|
668
|
+
"schema": "agentinputlab.mce.usage-receipt.v1",
|
|
669
|
+
"semantic_patch_manifest_sha256": SEMANTIC_PATCH_MANIFEST_SHA256,
|
|
670
|
+
"usage": supervisor.usage(),
|
|
671
|
+
}
|
|
672
|
+
if not isinstance(receipt, Mapping) or dict(receipt) != expected:
|
|
673
|
+
raise DriverError(
|
|
674
|
+
"USAGE_INVALID", "MCE isolated manager usage receipt does not match the trusted meter",
|
|
675
|
+
consumed=True, usage=supervisor.usage(),
|
|
676
|
+
)
|
|
677
|
+
|
|
678
|
+
def evolve(
|
|
679
|
+
self,
|
|
680
|
+
*,
|
|
681
|
+
workspace: Path,
|
|
682
|
+
train_path: Path,
|
|
683
|
+
validation_path: Path,
|
|
684
|
+
controls: Mapping[str, int],
|
|
685
|
+
model_fingerprints: Mapping[str, Any],
|
|
686
|
+
supervisor: TrustedProviderSupervisor,
|
|
687
|
+
) -> MCEEvolutionRun:
|
|
688
|
+
workspace = Path(workspace).resolve()
|
|
689
|
+
train_path = Path(train_path).resolve()
|
|
690
|
+
validation_path = Path(validation_path).resolve()
|
|
691
|
+
target = _mapping(model_fingerprints, "target")
|
|
692
|
+
target_model = _text(target, "model")
|
|
693
|
+
seed = controls["seed"]
|
|
694
|
+
logger = logging.getLogger(f"agentinputlab.mce.{id(self)}")
|
|
695
|
+
logger.handlers[:] = [logging.NullHandler()]
|
|
696
|
+
logger.propagate = False
|
|
697
|
+
run_dir = workspace / "logs" / "agentinputlab"
|
|
698
|
+
run_dir.mkdir(parents=True, exist_ok=True)
|
|
699
|
+
self._bind_manager_run(
|
|
700
|
+
supervisor=supervisor,
|
|
701
|
+
model_fingerprints=model_fingerprints,
|
|
702
|
+
seed=seed,
|
|
703
|
+
max_wall_seconds=controls["max_wall_seconds"],
|
|
704
|
+
)
|
|
705
|
+
|
|
706
|
+
with _pinned_upstream_modules(self.source_root) as (
|
|
707
|
+
upstream_main,
|
|
708
|
+
upstream_utils,
|
|
709
|
+
):
|
|
710
|
+
run_iteration = getattr(upstream_main, "run_iteration", None)
|
|
711
|
+
setup_reference = getattr(
|
|
712
|
+
upstream_utils,
|
|
713
|
+
"setup_meta_agent_reference",
|
|
714
|
+
None,
|
|
715
|
+
)
|
|
716
|
+
if not callable(run_iteration) or not callable(setup_reference):
|
|
717
|
+
raise DriverError(
|
|
718
|
+
"UPSTREAM_API_DRIFT",
|
|
719
|
+
"pinned MCE run_iteration/setup_meta_agent_reference is unavailable",
|
|
720
|
+
)
|
|
721
|
+
code = getattr(run_iteration, "__code__", None)
|
|
722
|
+
if (
|
|
723
|
+
code is None
|
|
724
|
+
or Path(code.co_filename).resolve()
|
|
725
|
+
!= (self.source_root / "mce" / "main.py").resolve()
|
|
726
|
+
):
|
|
727
|
+
raise DriverError(
|
|
728
|
+
"UPSTREAM_API_DRIFT",
|
|
729
|
+
"MCE run_iteration did not originate from pinned main.py",
|
|
730
|
+
)
|
|
731
|
+
patches = self._semantic_patches(
|
|
732
|
+
workspace=workspace,
|
|
733
|
+
model_fingerprints=model_fingerprints,
|
|
734
|
+
seed=seed,
|
|
735
|
+
)
|
|
736
|
+
for name, replacement in patches.items():
|
|
737
|
+
original = getattr(upstream_main, name, None)
|
|
738
|
+
if not callable(original):
|
|
739
|
+
raise DriverError(
|
|
740
|
+
"UPSTREAM_API_DRIFT",
|
|
741
|
+
f"MCE semantic-patch seam is unavailable: {name}",
|
|
742
|
+
)
|
|
743
|
+
setattr(upstream_main, name, replacement)
|
|
744
|
+
setup_reference(workspace, str(train_path), controls["train_limit"], logger)
|
|
745
|
+
|
|
746
|
+
async def execute() -> tuple[MCEEvolutionIteration, ...]:
|
|
747
|
+
iterations: list[MCEEvolutionIteration] = []
|
|
748
|
+
for index in range(controls["iterations"] + 1):
|
|
749
|
+
result = await run_iteration(
|
|
750
|
+
workspace_base=workspace,
|
|
751
|
+
iteration=index,
|
|
752
|
+
env_name=self.environment_name,
|
|
753
|
+
val_data_path=str(validation_path),
|
|
754
|
+
train_data_path=str(train_path),
|
|
755
|
+
train_limit=controls["train_limit"],
|
|
756
|
+
val_limit=controls["validation_limit"],
|
|
757
|
+
model=target_model,
|
|
758
|
+
logger=logger,
|
|
759
|
+
run_dir=run_dir,
|
|
760
|
+
e2b_sandbox_manager=self.sandbox_manager,
|
|
761
|
+
train_batch_size=controls["train_batch_size"],
|
|
762
|
+
skill_path=None,
|
|
763
|
+
no_meta_agent=False,
|
|
764
|
+
)
|
|
765
|
+
if not isinstance(result, Mapping) or "error" in result:
|
|
766
|
+
raise DriverError(
|
|
767
|
+
"UPSTREAM_EXECUTION_FAILED",
|
|
768
|
+
f"MCE upstream iteration {index} failed",
|
|
769
|
+
consumed=True,
|
|
770
|
+
usage=supervisor.usage(),
|
|
771
|
+
)
|
|
772
|
+
score = _finite(
|
|
773
|
+
result.get("val_primary_metric"),
|
|
774
|
+
"MCE upstream validation score",
|
|
775
|
+
)
|
|
776
|
+
if index == 0:
|
|
777
|
+
root = workspace / "iter0"
|
|
778
|
+
else:
|
|
779
|
+
sub_iterations = result.get("sub_iterations")
|
|
780
|
+
if (
|
|
781
|
+
isinstance(sub_iterations, (str, bytes))
|
|
782
|
+
or not isinstance(sub_iterations, Sequence)
|
|
783
|
+
or not sub_iterations
|
|
784
|
+
or not isinstance(sub_iterations[-1], Mapping)
|
|
785
|
+
):
|
|
786
|
+
raise DriverError(
|
|
787
|
+
"UPSTREAM_OUTPUT_INVALID",
|
|
788
|
+
"MCE final sub-iteration folder is missing",
|
|
789
|
+
consumed=True,
|
|
790
|
+
usage=supervisor.usage(),
|
|
791
|
+
)
|
|
792
|
+
root = Path(_text(sub_iterations[-1], "folder"))
|
|
793
|
+
iterations.append(
|
|
794
|
+
MCEEvolutionIteration(
|
|
795
|
+
index=index,
|
|
796
|
+
artifact_root=root,
|
|
797
|
+
validation_score=score,
|
|
798
|
+
)
|
|
799
|
+
)
|
|
800
|
+
return tuple(iterations)
|
|
801
|
+
|
|
802
|
+
random_state = random.getstate()
|
|
803
|
+
random.seed(seed)
|
|
804
|
+
try:
|
|
805
|
+
iterations = asyncio.run(
|
|
806
|
+
asyncio.wait_for(
|
|
807
|
+
execute(),
|
|
808
|
+
timeout=controls["max_wall_seconds"],
|
|
809
|
+
)
|
|
810
|
+
)
|
|
811
|
+
except asyncio.TimeoutError as exc:
|
|
812
|
+
raise DriverError(
|
|
813
|
+
"BUDGET_EXCEEDED",
|
|
814
|
+
"MCE wall budget expired during upstream orchestration",
|
|
815
|
+
consumed=bool(supervisor.usage()["model_calls"]),
|
|
816
|
+
usage=supervisor.usage(),
|
|
817
|
+
) from exc
|
|
818
|
+
except DriverError:
|
|
819
|
+
raise
|
|
820
|
+
except Exception as exc:
|
|
821
|
+
raise DriverError(
|
|
822
|
+
"UPSTREAM_EXECUTION_FAILED",
|
|
823
|
+
"MCE upstream evolution failed",
|
|
824
|
+
consumed=True,
|
|
825
|
+
usage=supervisor.usage(),
|
|
826
|
+
) from exc
|
|
827
|
+
finally:
|
|
828
|
+
random.setstate(random_state)
|
|
829
|
+
self._verify_manager_usage(supervisor)
|
|
830
|
+
return MCEEvolutionRun(iterations=iterations)
|
|
831
|
+
|
|
832
|
+
def evaluate_frozen(
|
|
833
|
+
self,
|
|
834
|
+
*,
|
|
835
|
+
workspace: Path,
|
|
836
|
+
artifact_root: Path,
|
|
837
|
+
selected_iteration: int,
|
|
838
|
+
test_path: Path,
|
|
839
|
+
controls: Mapping[str, int],
|
|
840
|
+
model_fingerprints: Mapping[str, Any],
|
|
841
|
+
supervisor: TrustedEvaluationSupervisor,
|
|
842
|
+
) -> Mapping[str, Any]:
|
|
843
|
+
"""Evaluate frozen interfaces through the same isolated native-task seam.
|
|
844
|
+
|
|
845
|
+
The caller must first verify the store handle and heldout split audit.
|
|
846
|
+
This runtime never evolves a skill or imports generated interfaces. The
|
|
847
|
+
manager performs native task evaluation in its attested boundary; it
|
|
848
|
+
must install token reservations at the actual provider transport.
|
|
849
|
+
"""
|
|
850
|
+
if not isinstance(supervisor, TrustedEvaluationSupervisor):
|
|
851
|
+
raise DriverError("BUDGET_INVALID", "MCE frozen evaluation requires an output-token guard")
|
|
852
|
+
if _sha256_file(_safe_source_file(self.source_root, "mce/eval.py")) != UPSTREAM_EVAL_SHA256:
|
|
853
|
+
raise DriverError("SOURCE_MISMATCH", "MCE native evaluation source hash drifted")
|
|
854
|
+
workspace = Path(workspace).resolve(strict=True)
|
|
855
|
+
root = _contained_directory(Path(artifact_root), workspace)
|
|
856
|
+
raw_test_path = Path(test_path)
|
|
857
|
+
if raw_test_path.is_symlink() or not raw_test_path.is_file():
|
|
858
|
+
raise DriverError("PATH_REJECTED", "MCE test oracle must be a regular file")
|
|
859
|
+
test_path = raw_test_path.resolve(strict=True)
|
|
860
|
+
if _paths_overlap(workspace, test_path):
|
|
861
|
+
raise DriverError("ISOLATION_INVALID", "MCE test oracle overlaps generated workspace")
|
|
862
|
+
_nonnegative_int_value(selected_iteration, "selected_iteration")
|
|
863
|
+
seed = _nonnegative_int(controls, "seed")
|
|
864
|
+
test_limit = _positive_int(controls, "test_limit")
|
|
865
|
+
wall = _positive_int(controls, "max_wall_seconds")
|
|
866
|
+
max_files = _positive_int(controls, "max_artifact_files")
|
|
867
|
+
max_bytes = _positive_int(controls, "max_artifact_bytes")
|
|
868
|
+
manifest_before = _frozen_artifact_manifest(root, max_files=max_files, max_bytes=max_bytes)
|
|
869
|
+
if selected_iteration == 0 and manifest_before:
|
|
870
|
+
raise DriverError("ARTIFACT_INVALID", "MCE frozen baseline must remain empty")
|
|
871
|
+
if selected_iteration > 0 and _skill_sha256(root) == EMPTY_SKILL_SHA256:
|
|
872
|
+
raise DriverError("ARTIFACT_INVALID", "MCE frozen evolved artifact lacks SKILL.md")
|
|
873
|
+
oracle_hash = _sha256_file(test_path)
|
|
874
|
+
contract = getattr(self.sandbox_manager, "final_evaluation_fingerprint", None)
|
|
875
|
+
if not callable(contract) or contract() != final_evaluation_manager_contract():
|
|
876
|
+
raise DriverError("ATTESTATION_INVALID", "MCE manager lacks frozen-evaluation token/oracle guards")
|
|
877
|
+
self._bind_manager_run(
|
|
878
|
+
model_fingerprints=model_fingerprints, seed=seed, max_wall_seconds=wall,
|
|
879
|
+
supervisor=supervisor,
|
|
880
|
+
)
|
|
881
|
+
run_dir = workspace / "final-evaluation-logs"
|
|
882
|
+
run_dir.mkdir(exist_ok=False)
|
|
883
|
+
random_state = random.getstate()
|
|
884
|
+
random.seed(seed)
|
|
885
|
+
try:
|
|
886
|
+
with _pinned_upstream_modules(self.source_root) as (upstream_main, _):
|
|
887
|
+
environment = upstream_main.EnvironmentRegistry.get(self.environment_name)
|
|
888
|
+
signatures = environment.get_interface_signatures()
|
|
889
|
+
samples = environment.load_samples(
|
|
890
|
+
path=str(test_path), limit=test_limit, random_sample=False,
|
|
891
|
+
)
|
|
892
|
+
if len(samples) != test_limit:
|
|
893
|
+
raise DriverError("SPLIT_IDENTITY_MISMATCH", "MCE native loader changed the heldout count")
|
|
894
|
+
seams = self._semantic_patches(
|
|
895
|
+
workspace=workspace, model_fingerprints=model_fingerprints, seed=seed,
|
|
896
|
+
)
|
|
897
|
+
interfaces = seams["load_interfaces"](root, signatures) if selected_iteration else {}
|
|
898
|
+
result = asyncio.run(asyncio.wait_for(
|
|
899
|
+
seams["batch_evaluate"](
|
|
900
|
+
interfaces=interfaces, samples=samples, env_name=self.environment_name,
|
|
901
|
+
iter_dir=root, log_dir=run_dir,
|
|
902
|
+
), timeout=wall,
|
|
903
|
+
))
|
|
904
|
+
self._verify_manager_usage(supervisor)
|
|
905
|
+
receipt = supervisor.output_budget_receipt()
|
|
906
|
+
if receipt["pending_reservations"]:
|
|
907
|
+
raise DriverError("USAGE_INVALID", "MCE final evaluation left provider calls in flight")
|
|
908
|
+
return {
|
|
909
|
+
"evaluation": result,
|
|
910
|
+
"output_budget": receipt,
|
|
911
|
+
"frozen_artifact_manifest_sha256": _content_hash(manifest_before),
|
|
912
|
+
"test_oracle_sha256": oracle_hash,
|
|
913
|
+
"upstream_eval_source_sha256": UPSTREAM_EVAL_SHA256,
|
|
914
|
+
"adaptation_performed": False,
|
|
915
|
+
"generated_code_imported_by_worker": False,
|
|
916
|
+
}
|
|
917
|
+
except asyncio.TimeoutError as exc:
|
|
918
|
+
raise DriverError(
|
|
919
|
+
"BUDGET_EXCEEDED", "MCE frozen evaluation exceeded its wall deadline",
|
|
920
|
+
consumed=bool(supervisor.usage()["model_calls"]), usage=supervisor.usage(),
|
|
921
|
+
) from exc
|
|
922
|
+
except DriverError:
|
|
923
|
+
raise
|
|
924
|
+
except Exception as exc:
|
|
925
|
+
raise DriverError(
|
|
926
|
+
"UPSTREAM_EXECUTION_FAILED", "MCE frozen native-task evaluation failed",
|
|
927
|
+
consumed=bool(supervisor.usage()["model_calls"]), usage=supervisor.usage(),
|
|
928
|
+
) from exc
|
|
929
|
+
finally:
|
|
930
|
+
random.setstate(random_state)
|
|
931
|
+
if (
|
|
932
|
+
_frozen_artifact_manifest(root, max_files=max_files, max_bytes=max_bytes) != manifest_before
|
|
933
|
+
or _sha256_file(test_path) != oracle_hash
|
|
934
|
+
):
|
|
935
|
+
raise DriverError(
|
|
936
|
+
"ARTIFACT_INVALID", "MCE frozen artifact or test oracle changed during evaluation",
|
|
937
|
+
consumed=bool(supervisor.usage()["model_calls"]), usage=supervisor.usage(),
|
|
938
|
+
)
|
|
939
|
+
|
|
940
|
+
def _semantic_patches(
|
|
941
|
+
self,
|
|
942
|
+
*,
|
|
943
|
+
workspace: Path,
|
|
944
|
+
model_fingerprints: Mapping[str, Any],
|
|
945
|
+
seed: int,
|
|
946
|
+
) -> Mapping[str, Callable[..., Any]]:
|
|
947
|
+
manager = self.sandbox_manager
|
|
948
|
+
next_logical_call_index = 0
|
|
949
|
+
|
|
950
|
+
def reserve_logical_seed() -> tuple[int, int]:
|
|
951
|
+
nonlocal next_logical_call_index
|
|
952
|
+
logical_call_index = next_logical_call_index
|
|
953
|
+
next_logical_call_index += 1
|
|
954
|
+
return logical_call_index, seed + logical_call_index
|
|
955
|
+
|
|
956
|
+
async def run_meta_agent(**kwargs: Any) -> Mapping[str, Any]:
|
|
957
|
+
logical_call_index, logical_seed = reserve_logical_seed()
|
|
958
|
+
return await _run_isolated_agent(
|
|
959
|
+
manager,
|
|
960
|
+
role="meta",
|
|
961
|
+
kwargs=kwargs,
|
|
962
|
+
workspace=workspace,
|
|
963
|
+
model_fingerprint=_mapping(model_fingerprints, "meta"),
|
|
964
|
+
logical_call_index=logical_call_index,
|
|
965
|
+
logical_seed=logical_seed,
|
|
966
|
+
)
|
|
967
|
+
|
|
968
|
+
async def run_base_agent(**kwargs: Any) -> Mapping[str, Any]:
|
|
969
|
+
logical_call_index, logical_seed = reserve_logical_seed()
|
|
970
|
+
return await _run_isolated_agent(
|
|
971
|
+
manager,
|
|
972
|
+
role="base",
|
|
973
|
+
kwargs=kwargs,
|
|
974
|
+
workspace=workspace,
|
|
975
|
+
model_fingerprint=_mapping(model_fingerprints, "base"),
|
|
976
|
+
logical_call_index=logical_call_index,
|
|
977
|
+
logical_seed=logical_seed,
|
|
978
|
+
)
|
|
979
|
+
|
|
980
|
+
def load_interfaces(
|
|
981
|
+
iter_dir: Path,
|
|
982
|
+
signatures: Sequence[Any],
|
|
983
|
+
) -> Mapping[str, Any]:
|
|
984
|
+
root = _contained_directory(Path(iter_dir), workspace)
|
|
985
|
+
signature_payload = _interface_signatures_payload(signatures)
|
|
986
|
+
result = manager.validate_interfaces_static(
|
|
987
|
+
iter_dir=root,
|
|
988
|
+
interface_signatures=signature_payload,
|
|
989
|
+
semantic_patch_manifest_sha256=SEMANTIC_PATCH_MANIFEST_SHA256,
|
|
990
|
+
)
|
|
991
|
+
return _validated_remote_interface_handle(
|
|
992
|
+
result,
|
|
993
|
+
iter_dir=root,
|
|
994
|
+
signatures=signature_payload,
|
|
995
|
+
)
|
|
996
|
+
|
|
997
|
+
async def batch_evaluate(
|
|
998
|
+
interfaces: Mapping[str, Any],
|
|
999
|
+
samples: Sequence[Any],
|
|
1000
|
+
env_name: str,
|
|
1001
|
+
llm: Any = None,
|
|
1002
|
+
iter_dir: Path | None = None,
|
|
1003
|
+
log_dir: Path | None = None,
|
|
1004
|
+
) -> Mapping[str, Any]:
|
|
1005
|
+
del llm
|
|
1006
|
+
root = _contained_directory(Path(iter_dir), workspace) if iter_dir is not None else None
|
|
1007
|
+
if interfaces:
|
|
1008
|
+
interface_handle: Mapping[str, Any] | None = _validated_remote_interface_handle(
|
|
1009
|
+
interfaces
|
|
1010
|
+
)
|
|
1011
|
+
else:
|
|
1012
|
+
interface_handle = None
|
|
1013
|
+
sample_rows = _sample_payload(samples)
|
|
1014
|
+
logical_call_index, logical_seed = reserve_logical_seed()
|
|
1015
|
+
result = await manager.batch_evaluate(
|
|
1016
|
+
interface_handle=interface_handle,
|
|
1017
|
+
samples=sample_rows,
|
|
1018
|
+
environment_name=env_name,
|
|
1019
|
+
iter_dir=root,
|
|
1020
|
+
log_dir=log_dir,
|
|
1021
|
+
model_fingerprint=json.loads(
|
|
1022
|
+
_canonical_json(_mapping(model_fingerprints, "target"))
|
|
1023
|
+
),
|
|
1024
|
+
seed=logical_seed,
|
|
1025
|
+
logical_call_index=logical_call_index,
|
|
1026
|
+
seed_mode=SEED_MODE,
|
|
1027
|
+
provider_subcall_seed_mode=PROVIDER_SUBCALL_SEED_MODE,
|
|
1028
|
+
semantic_patch_manifest_sha256=SEMANTIC_PATCH_MANIFEST_SHA256,
|
|
1029
|
+
)
|
|
1030
|
+
return _validated_batch_evaluation(result, len(sample_rows))
|
|
1031
|
+
|
|
1032
|
+
return {
|
|
1033
|
+
"run_meta_agent": run_meta_agent,
|
|
1034
|
+
"run_base_agent": run_base_agent,
|
|
1035
|
+
"load_interfaces": load_interfaces,
|
|
1036
|
+
"batch_evaluate": batch_evaluate,
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
|
|
1040
|
+
async def _run_isolated_agent(
|
|
1041
|
+
manager: Any,
|
|
1042
|
+
*,
|
|
1043
|
+
role: str,
|
|
1044
|
+
kwargs: Mapping[str, Any],
|
|
1045
|
+
workspace: Path,
|
|
1046
|
+
model_fingerprint: Mapping[str, Any],
|
|
1047
|
+
logical_call_index: int,
|
|
1048
|
+
logical_seed: int,
|
|
1049
|
+
) -> Mapping[str, Any]:
|
|
1050
|
+
if role not in {"meta", "base"}:
|
|
1051
|
+
raise DriverError("RUNTIME_INVALID", "MCE isolated-agent role is invalid")
|
|
1052
|
+
iter_dir = _contained_directory(Path(kwargs.get("iter_dir")), workspace)
|
|
1053
|
+
workspace_base = Path(kwargs.get("workspace_base", workspace)).resolve()
|
|
1054
|
+
if workspace_base != workspace:
|
|
1055
|
+
raise DriverError("PATH_REJECTED", "MCE agent workspace identity drifted")
|
|
1056
|
+
run_dir_value = kwargs.get("run_dir")
|
|
1057
|
+
run_dir = (
|
|
1058
|
+
_contained_directory(Path(run_dir_value), workspace) if run_dir_value is not None else None
|
|
1059
|
+
)
|
|
1060
|
+
task_instruction = kwargs.get("task_instruction")
|
|
1061
|
+
if not isinstance(task_instruction, str) or not task_instruction.strip():
|
|
1062
|
+
raise DriverError("RUNTIME_INVALID", "MCE agent task instruction is invalid")
|
|
1063
|
+
iteration = kwargs.get("iteration")
|
|
1064
|
+
if isinstance(iteration, bool) or not isinstance(iteration, int) or iteration < 1:
|
|
1065
|
+
raise DriverError("RUNTIME_INVALID", "MCE evolved agent iteration is invalid")
|
|
1066
|
+
signatures = _interface_signatures_payload(kwargs.get("interface_signatures", ()))
|
|
1067
|
+
result = await manager.run_agent(
|
|
1068
|
+
role=role,
|
|
1069
|
+
iter_dir=iter_dir,
|
|
1070
|
+
workspace_base=workspace,
|
|
1071
|
+
run_dir=run_dir,
|
|
1072
|
+
task_instruction=task_instruction,
|
|
1073
|
+
interface_signatures=signatures,
|
|
1074
|
+
iteration=iteration,
|
|
1075
|
+
initial_prompt=kwargs.get("initial_prompt"),
|
|
1076
|
+
model_fingerprint=json.loads(_canonical_json(model_fingerprint)),
|
|
1077
|
+
seed=logical_seed,
|
|
1078
|
+
logical_call_index=logical_call_index,
|
|
1079
|
+
seed_mode=SEED_MODE,
|
|
1080
|
+
provider_subcall_seed_mode=PROVIDER_SUBCALL_SEED_MODE,
|
|
1081
|
+
semantic_patch_manifest_sha256=SEMANTIC_PATCH_MANIFEST_SHA256,
|
|
1082
|
+
)
|
|
1083
|
+
if not isinstance(result, Mapping) or not isinstance(result.get("success"), bool):
|
|
1084
|
+
raise DriverError(
|
|
1085
|
+
"UPSTREAM_OUTPUT_INVALID",
|
|
1086
|
+
f"MCE isolated {role} agent returned an invalid receipt",
|
|
1087
|
+
consumed=True,
|
|
1088
|
+
)
|
|
1089
|
+
expected_keys = {"success"} if result["success"] else {"success", "error"}
|
|
1090
|
+
if set(result) != expected_keys:
|
|
1091
|
+
raise DriverError(
|
|
1092
|
+
"UPSTREAM_OUTPUT_INVALID",
|
|
1093
|
+
f"MCE isolated {role} agent receipt schema drifted",
|
|
1094
|
+
consumed=True,
|
|
1095
|
+
)
|
|
1096
|
+
if not result["success"] and (
|
|
1097
|
+
not isinstance(result.get("error"), str) or not result["error"].strip()
|
|
1098
|
+
):
|
|
1099
|
+
raise DriverError(
|
|
1100
|
+
"UPSTREAM_OUTPUT_INVALID",
|
|
1101
|
+
f"MCE isolated {role} agent error is invalid",
|
|
1102
|
+
consumed=True,
|
|
1103
|
+
)
|
|
1104
|
+
return dict(result)
|
|
1105
|
+
|
|
1106
|
+
|
|
1107
|
+
def _interface_signatures_payload(value: Any) -> tuple[Mapping[str, Any], ...]:
|
|
1108
|
+
if isinstance(value, (str, bytes)) or not isinstance(value, Sequence):
|
|
1109
|
+
raise DriverError("RUNTIME_INVALID", "MCE interface signatures are invalid")
|
|
1110
|
+
rows: list[Mapping[str, Any]] = []
|
|
1111
|
+
for signature in value:
|
|
1112
|
+
if isinstance(signature, Mapping):
|
|
1113
|
+
raw = dict(signature)
|
|
1114
|
+
else:
|
|
1115
|
+
raw = {
|
|
1116
|
+
"name": getattr(signature, "name", None),
|
|
1117
|
+
"inputs": getattr(signature, "inputs", None),
|
|
1118
|
+
"output": getattr(signature, "output", None),
|
|
1119
|
+
"description": getattr(signature, "description", None),
|
|
1120
|
+
}
|
|
1121
|
+
name = raw.get("name")
|
|
1122
|
+
description = raw.get("description")
|
|
1123
|
+
inputs = raw.get("inputs")
|
|
1124
|
+
output = raw.get("output")
|
|
1125
|
+
if (
|
|
1126
|
+
not isinstance(name, str)
|
|
1127
|
+
or not name.strip()
|
|
1128
|
+
or not isinstance(description, str)
|
|
1129
|
+
or isinstance(inputs, (str, bytes))
|
|
1130
|
+
or not isinstance(inputs, Sequence)
|
|
1131
|
+
or isinstance(output, (str, bytes))
|
|
1132
|
+
or not isinstance(output, Sequence)
|
|
1133
|
+
):
|
|
1134
|
+
raise DriverError("RUNTIME_INVALID", "MCE interface signature drifted")
|
|
1135
|
+
rows.append(
|
|
1136
|
+
json.loads(
|
|
1137
|
+
_canonical_json(
|
|
1138
|
+
{
|
|
1139
|
+
"name": name,
|
|
1140
|
+
"inputs": tuple(tuple(item) for item in inputs),
|
|
1141
|
+
"output": tuple(output),
|
|
1142
|
+
"description": description,
|
|
1143
|
+
}
|
|
1144
|
+
)
|
|
1145
|
+
)
|
|
1146
|
+
)
|
|
1147
|
+
return tuple(rows)
|
|
1148
|
+
|
|
1149
|
+
|
|
1150
|
+
def _interface_source_manifest(iter_dir: Path) -> tuple[Mapping[str, Any], ...]:
|
|
1151
|
+
interface_root = iter_dir / "interfaces"
|
|
1152
|
+
if interface_root.is_symlink():
|
|
1153
|
+
raise DriverError("PATH_REJECTED", "MCE interface directory may not be a symlink")
|
|
1154
|
+
if not interface_root.is_dir() or not (interface_root / "__init__.py").is_file():
|
|
1155
|
+
raise FileNotFoundError(f"MCE interfaces are unavailable in {iter_dir}")
|
|
1156
|
+
rows: list[Mapping[str, Any]] = []
|
|
1157
|
+
for path in sorted(interface_root.rglob("*.py")):
|
|
1158
|
+
if path.is_symlink():
|
|
1159
|
+
raise DriverError("PATH_REJECTED", "MCE interface source may not be a symlink")
|
|
1160
|
+
resolved = path.resolve(strict=True)
|
|
1161
|
+
try:
|
|
1162
|
+
resolved.relative_to(interface_root.resolve())
|
|
1163
|
+
except ValueError as exc:
|
|
1164
|
+
raise DriverError("PATH_REJECTED", "MCE interface source escapes its root") from exc
|
|
1165
|
+
rows.append(
|
|
1166
|
+
{
|
|
1167
|
+
"path": resolved.relative_to(iter_dir).as_posix(),
|
|
1168
|
+
"sha256": _sha256_file(resolved),
|
|
1169
|
+
"byte_size": resolved.stat().st_size,
|
|
1170
|
+
}
|
|
1171
|
+
)
|
|
1172
|
+
if not rows:
|
|
1173
|
+
raise FileNotFoundError(f"MCE interfaces are unavailable in {iter_dir}")
|
|
1174
|
+
return tuple(rows)
|
|
1175
|
+
|
|
1176
|
+
|
|
1177
|
+
def _validated_remote_interface_handle(
|
|
1178
|
+
value: Any,
|
|
1179
|
+
*,
|
|
1180
|
+
iter_dir: Path | None = None,
|
|
1181
|
+
signatures: Sequence[Mapping[str, Any]] | None = None,
|
|
1182
|
+
) -> Mapping[str, Any]:
|
|
1183
|
+
expected_keys = {
|
|
1184
|
+
"schema",
|
|
1185
|
+
"semantic_patch_manifest_sha256",
|
|
1186
|
+
"interface_signatures_sha256",
|
|
1187
|
+
"artifact_manifest_sha256",
|
|
1188
|
+
"interface_names",
|
|
1189
|
+
"validation_receipt_sha256",
|
|
1190
|
+
}
|
|
1191
|
+
if not isinstance(value, Mapping) or set(value) != expected_keys:
|
|
1192
|
+
raise DriverError(
|
|
1193
|
+
"UPSTREAM_OUTPUT_INVALID",
|
|
1194
|
+
"MCE remote interface handle schema drifted",
|
|
1195
|
+
consumed=True,
|
|
1196
|
+
)
|
|
1197
|
+
if value.get("schema") != "agentinputlab.mce.remote-interface-handle.v1":
|
|
1198
|
+
raise DriverError("UPSTREAM_OUTPUT_INVALID", "MCE interface handle schema is invalid")
|
|
1199
|
+
if value.get("semantic_patch_manifest_sha256") != SEMANTIC_PATCH_MANIFEST_SHA256:
|
|
1200
|
+
raise DriverError("UPSTREAM_OUTPUT_INVALID", "MCE interface patch identity drifted")
|
|
1201
|
+
names = value.get("interface_names")
|
|
1202
|
+
if isinstance(names, (str, bytes)) or not isinstance(names, Sequence):
|
|
1203
|
+
raise DriverError("UPSTREAM_OUTPUT_INVALID", "MCE interface names are invalid")
|
|
1204
|
+
names_tuple = tuple(names)
|
|
1205
|
+
if any(not isinstance(name, str) or not name for name in names_tuple):
|
|
1206
|
+
raise DriverError("UPSTREAM_OUTPUT_INVALID", "MCE interface names are invalid")
|
|
1207
|
+
if signatures is not None:
|
|
1208
|
+
expected_names = tuple(signature["name"] for signature in signatures)
|
|
1209
|
+
if names_tuple != expected_names:
|
|
1210
|
+
raise DriverError("UPSTREAM_OUTPUT_INVALID", "MCE interface names drifted")
|
|
1211
|
+
expected_signatures_sha256 = _content_hash(signatures)
|
|
1212
|
+
else:
|
|
1213
|
+
expected_signatures_sha256 = _require_sha256(
|
|
1214
|
+
value.get("interface_signatures_sha256"),
|
|
1215
|
+
"interface signatures",
|
|
1216
|
+
)
|
|
1217
|
+
if value.get("interface_signatures_sha256") != expected_signatures_sha256:
|
|
1218
|
+
raise DriverError("UPSTREAM_OUTPUT_INVALID", "MCE interface signature hash drifted")
|
|
1219
|
+
artifact_sha256 = _require_sha256(
|
|
1220
|
+
value.get("artifact_manifest_sha256"),
|
|
1221
|
+
"interface artifact manifest",
|
|
1222
|
+
)
|
|
1223
|
+
if iter_dir is not None:
|
|
1224
|
+
actual_artifact_sha256 = _content_hash(_interface_source_manifest(iter_dir))
|
|
1225
|
+
if artifact_sha256 != actual_artifact_sha256:
|
|
1226
|
+
raise DriverError("UPSTREAM_OUTPUT_INVALID", "MCE interface artifact hash drifted")
|
|
1227
|
+
receipt_body = {
|
|
1228
|
+
"schema": value["schema"],
|
|
1229
|
+
"semantic_patch_manifest_sha256": SEMANTIC_PATCH_MANIFEST_SHA256,
|
|
1230
|
+
"interface_signatures_sha256": expected_signatures_sha256,
|
|
1231
|
+
"artifact_manifest_sha256": artifact_sha256,
|
|
1232
|
+
"interface_names": names_tuple,
|
|
1233
|
+
}
|
|
1234
|
+
if value.get("validation_receipt_sha256") != _content_hash(receipt_body):
|
|
1235
|
+
raise DriverError("UPSTREAM_OUTPUT_INVALID", "MCE interface receipt hash drifted")
|
|
1236
|
+
return json.loads(_canonical_json(value))
|
|
1237
|
+
|
|
1238
|
+
|
|
1239
|
+
def _sample_payload(samples: Any) -> tuple[Mapping[str, Any], ...]:
|
|
1240
|
+
if isinstance(samples, (str, bytes)) or not isinstance(samples, Sequence):
|
|
1241
|
+
raise DriverError("RUNTIME_INVALID", "MCE evaluation samples are invalid")
|
|
1242
|
+
rows: list[Mapping[str, Any]] = []
|
|
1243
|
+
for sample in samples:
|
|
1244
|
+
to_dict = getattr(sample, "to_dict", None)
|
|
1245
|
+
raw = to_dict() if callable(to_dict) else sample
|
|
1246
|
+
if not isinstance(raw, Mapping):
|
|
1247
|
+
raise DriverError("RUNTIME_INVALID", "MCE evaluation sample is invalid")
|
|
1248
|
+
rows.append(json.loads(_canonical_json(raw)))
|
|
1249
|
+
return tuple(rows)
|
|
1250
|
+
|
|
1251
|
+
|
|
1252
|
+
def _validated_batch_evaluation(value: Any, expected_total: int) -> Mapping[str, Any]:
|
|
1253
|
+
if not isinstance(value, Mapping) or set(value) != {"summary", "errors", "results"}:
|
|
1254
|
+
raise DriverError(
|
|
1255
|
+
"UPSTREAM_OUTPUT_INVALID",
|
|
1256
|
+
"MCE trusted batch-evaluation schema drifted",
|
|
1257
|
+
consumed=True,
|
|
1258
|
+
)
|
|
1259
|
+
summary = value.get("summary")
|
|
1260
|
+
expected_summary_keys = {
|
|
1261
|
+
"metrics",
|
|
1262
|
+
"primary_metric",
|
|
1263
|
+
"primary_metric_value",
|
|
1264
|
+
"total",
|
|
1265
|
+
"successful",
|
|
1266
|
+
"errors",
|
|
1267
|
+
"environment",
|
|
1268
|
+
}
|
|
1269
|
+
if not isinstance(summary, Mapping) or set(summary) != expected_summary_keys:
|
|
1270
|
+
raise DriverError(
|
|
1271
|
+
"UPSTREAM_OUTPUT_INVALID",
|
|
1272
|
+
"MCE trusted evaluation summary schema drifted",
|
|
1273
|
+
consumed=True,
|
|
1274
|
+
)
|
|
1275
|
+
total = summary.get("total")
|
|
1276
|
+
successful = summary.get("successful")
|
|
1277
|
+
errors_count = summary.get("errors")
|
|
1278
|
+
if (
|
|
1279
|
+
isinstance(total, bool)
|
|
1280
|
+
or not isinstance(total, int)
|
|
1281
|
+
or total != expected_total
|
|
1282
|
+
or isinstance(successful, bool)
|
|
1283
|
+
or not isinstance(successful, int)
|
|
1284
|
+
or isinstance(errors_count, bool)
|
|
1285
|
+
or not isinstance(errors_count, int)
|
|
1286
|
+
or successful < 0
|
|
1287
|
+
or errors_count < 0
|
|
1288
|
+
or successful + errors_count != total
|
|
1289
|
+
):
|
|
1290
|
+
raise DriverError("UPSTREAM_OUTPUT_INVALID", "MCE evaluation counts drifted")
|
|
1291
|
+
if not isinstance(summary.get("primary_metric"), str) or not summary["primary_metric"]:
|
|
1292
|
+
raise DriverError("UPSTREAM_OUTPUT_INVALID", "MCE primary metric is invalid")
|
|
1293
|
+
_finite(summary.get("primary_metric_value"), "MCE primary metric")
|
|
1294
|
+
metrics = summary.get("metrics")
|
|
1295
|
+
if not isinstance(metrics, Mapping):
|
|
1296
|
+
raise DriverError("UPSTREAM_OUTPUT_INVALID", "MCE evaluation metrics are invalid")
|
|
1297
|
+
for metric_name, metric_value in metrics.items():
|
|
1298
|
+
if not isinstance(metric_name, str) or not metric_name:
|
|
1299
|
+
raise DriverError("UPSTREAM_OUTPUT_INVALID", "MCE metric name is invalid")
|
|
1300
|
+
_finite(metric_value, f"MCE metric {metric_name}")
|
|
1301
|
+
results = value.get("results")
|
|
1302
|
+
errors = value.get("errors")
|
|
1303
|
+
if (
|
|
1304
|
+
isinstance(results, (str, bytes))
|
|
1305
|
+
or not isinstance(results, Sequence)
|
|
1306
|
+
or len(results) != successful
|
|
1307
|
+
or isinstance(errors, (str, bytes))
|
|
1308
|
+
or not isinstance(errors, Sequence)
|
|
1309
|
+
or len(errors) != errors_count
|
|
1310
|
+
):
|
|
1311
|
+
raise DriverError("UPSTREAM_OUTPUT_INVALID", "MCE evaluation rows drifted")
|
|
1312
|
+
try:
|
|
1313
|
+
return json.loads(_canonical_json(value))
|
|
1314
|
+
except (TypeError, ValueError) as exc:
|
|
1315
|
+
raise DriverError(
|
|
1316
|
+
"UPSTREAM_OUTPUT_INVALID",
|
|
1317
|
+
"MCE evaluation result is not canonical JSON",
|
|
1318
|
+
) from exc
|
|
1319
|
+
|
|
1320
|
+
|
|
1321
|
+
class PersistentArtifactStore:
|
|
1322
|
+
"""Small persistent content-addressed store owned by the worker."""
|
|
1323
|
+
|
|
1324
|
+
def __init__(self, root: Path) -> None:
|
|
1325
|
+
raw_root = Path(root)
|
|
1326
|
+
if raw_root.is_symlink():
|
|
1327
|
+
raise DriverError("STORE_INVALID", "MCE artifact store may not be a symlink")
|
|
1328
|
+
self.root = raw_root.resolve()
|
|
1329
|
+
self.objects = self.root / "objects"
|
|
1330
|
+
self.objects.mkdir(parents=True, exist_ok=True)
|
|
1331
|
+
if self.root.is_symlink() or self.objects.is_symlink():
|
|
1332
|
+
raise DriverError("STORE_INVALID", "MCE artifact store may not be a symlink")
|
|
1333
|
+
|
|
1334
|
+
def fingerprint(self) -> Mapping[str, Any]:
|
|
1335
|
+
return {
|
|
1336
|
+
"mode": "content_addressed_v1",
|
|
1337
|
+
"persistent": True,
|
|
1338
|
+
"worker_resolve_supported": True,
|
|
1339
|
+
"root_identity_sha256": _content_hash(str(self.root)),
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
def put(
|
|
1343
|
+
self,
|
|
1344
|
+
bundle_sha256: str,
|
|
1345
|
+
*,
|
|
1346
|
+
artifact_root: Path,
|
|
1347
|
+
files: Sequence[Mapping[str, Any]],
|
|
1348
|
+
) -> str:
|
|
1349
|
+
digest = _require_sha256(bundle_sha256, "artifact bundle")
|
|
1350
|
+
destination = self.objects / digest
|
|
1351
|
+
manifest = {
|
|
1352
|
+
"schema": "agentinputlab.mce.stored-artifact.v1",
|
|
1353
|
+
"artifact_bundle_sha256": digest,
|
|
1354
|
+
"files": tuple(files),
|
|
1355
|
+
}
|
|
1356
|
+
if destination.exists():
|
|
1357
|
+
stored = self._verified_object(destination, digest)
|
|
1358
|
+
if stored != json.loads(_canonical_json(manifest)):
|
|
1359
|
+
raise DriverError("STORE_COLLISION", "MCE artifact-store collision")
|
|
1360
|
+
return f"{HANDLE_PREFIX}{digest}"
|
|
1361
|
+
staging = Path(tempfile.mkdtemp(prefix=".mce-stage-", dir=self.root))
|
|
1362
|
+
try:
|
|
1363
|
+
payload_root = staging / "payload"
|
|
1364
|
+
payload_root.mkdir()
|
|
1365
|
+
source_root = Path(artifact_root).resolve()
|
|
1366
|
+
for row in files:
|
|
1367
|
+
relative = _text(row, "path")
|
|
1368
|
+
source = _safe_artifact_file(source_root, relative)
|
|
1369
|
+
expected_sha256 = row.get("sha256")
|
|
1370
|
+
expected_size = row.get("byte_size")
|
|
1371
|
+
if (
|
|
1372
|
+
_sha256_file(source) != expected_sha256
|
|
1373
|
+
or source.stat().st_size != expected_size
|
|
1374
|
+
):
|
|
1375
|
+
raise DriverError("ARTIFACT_INVALID", "MCE artifact changed before storage")
|
|
1376
|
+
target = payload_root / relative
|
|
1377
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
1378
|
+
shutil.copyfile(source, target, follow_symlinks=False)
|
|
1379
|
+
if (
|
|
1380
|
+
target.is_symlink()
|
|
1381
|
+
or _sha256_file(target) != expected_sha256
|
|
1382
|
+
or target.stat().st_size != expected_size
|
|
1383
|
+
or _sha256_file(source) != expected_sha256
|
|
1384
|
+
or source.stat().st_size != expected_size
|
|
1385
|
+
):
|
|
1386
|
+
raise DriverError("ARTIFACT_INVALID", "MCE artifact changed during storage")
|
|
1387
|
+
(staging / "manifest.json").write_text(
|
|
1388
|
+
_canonical_json(manifest),
|
|
1389
|
+
encoding="utf-8",
|
|
1390
|
+
)
|
|
1391
|
+
os.replace(staging, destination)
|
|
1392
|
+
self._verified_object(destination, digest)
|
|
1393
|
+
except Exception:
|
|
1394
|
+
if staging.exists():
|
|
1395
|
+
shutil.rmtree(staging)
|
|
1396
|
+
raise
|
|
1397
|
+
return f"{HANDLE_PREFIX}{digest}"
|
|
1398
|
+
|
|
1399
|
+
def resolve(self, handle: str) -> Mapping[str, Any]:
|
|
1400
|
+
if not isinstance(handle, str) or not handle.startswith(HANDLE_PREFIX):
|
|
1401
|
+
raise DriverError("HANDLE_INVALID", "MCE artifact handle is invalid")
|
|
1402
|
+
digest = _require_sha256(handle[len(HANDLE_PREFIX) :], "artifact handle")
|
|
1403
|
+
return self._verified_object(self.objects / digest, digest)
|
|
1404
|
+
|
|
1405
|
+
def materialize(
|
|
1406
|
+
self,
|
|
1407
|
+
handle: str,
|
|
1408
|
+
*,
|
|
1409
|
+
workspace: Path,
|
|
1410
|
+
max_files: int = 128,
|
|
1411
|
+
max_bytes: int = 64 * 1024 * 1024,
|
|
1412
|
+
) -> Path:
|
|
1413
|
+
"""Copy a frozen selection into a fresh external-worker workspace.
|
|
1414
|
+
|
|
1415
|
+
This is byte transport for isolated final evaluation, not execution or
|
|
1416
|
+
an import. The caller still has to mount the returned directory inside
|
|
1417
|
+
its attested generated-code boundary. No oracle data is copied here.
|
|
1418
|
+
"""
|
|
1419
|
+
max_files = _positive_int_value(max_files, "max_files")
|
|
1420
|
+
max_bytes = _positive_int_value(max_bytes, "max_bytes")
|
|
1421
|
+
raw_workspace = Path(workspace)
|
|
1422
|
+
if raw_workspace.is_symlink() or not raw_workspace.is_dir():
|
|
1423
|
+
raise DriverError("PATH_REJECTED", "MCE evaluation workspace must be regular")
|
|
1424
|
+
workspace = raw_workspace.resolve()
|
|
1425
|
+
if _paths_overlap(workspace, self.root):
|
|
1426
|
+
raise DriverError("PATH_REJECTED", "MCE evaluation workspace overlaps the artifact store")
|
|
1427
|
+
manifest = self.resolve(handle)
|
|
1428
|
+
files = manifest["files"]
|
|
1429
|
+
if len(files) > max_files or sum(row["byte_size"] for row in files) > max_bytes:
|
|
1430
|
+
raise DriverError("ARTIFACT_LIMIT_EXCEEDED", "MCE frozen selection exceeds evaluation limits")
|
|
1431
|
+
digest = manifest["artifact_bundle_sha256"]
|
|
1432
|
+
source_root = self.objects / digest / "payload"
|
|
1433
|
+
destination = Path(tempfile.mkdtemp(prefix="mce-frozen-selection-", dir=workspace))
|
|
1434
|
+
try:
|
|
1435
|
+
for row in files:
|
|
1436
|
+
relative = row["path"]
|
|
1437
|
+
source = _safe_artifact_file(source_root, relative)
|
|
1438
|
+
if _sha256_file(source) != row["sha256"] or source.stat().st_size != row["byte_size"]:
|
|
1439
|
+
raise DriverError("ARTIFACT_INVALID", "MCE frozen selection changed before copy")
|
|
1440
|
+
target = destination / relative
|
|
1441
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
1442
|
+
with source.open("rb") as incoming, target.open("xb") as outgoing:
|
|
1443
|
+
shutil.copyfileobj(incoming, outgoing, length=1024 * 1024)
|
|
1444
|
+
target.chmod(0o700 if row["executable"] else 0o600)
|
|
1445
|
+
if (
|
|
1446
|
+
target.is_symlink()
|
|
1447
|
+
or _sha256_file(target) != row["sha256"]
|
|
1448
|
+
or target.stat().st_size != row["byte_size"]
|
|
1449
|
+
or _sha256_file(source) != row["sha256"]
|
|
1450
|
+
):
|
|
1451
|
+
raise DriverError("ARTIFACT_INVALID", "MCE frozen selection changed during copy")
|
|
1452
|
+
actual = {p.relative_to(destination).as_posix() for p in destination.rglob("*") if p.is_file()}
|
|
1453
|
+
if actual != {row["path"] for row in files} or self.resolve(handle) != manifest:
|
|
1454
|
+
raise DriverError("ARTIFACT_INVALID", "MCE frozen selection closure changed")
|
|
1455
|
+
return destination
|
|
1456
|
+
except Exception:
|
|
1457
|
+
# Only the freshly created, worker-owned temporary directory is removed.
|
|
1458
|
+
shutil.rmtree(destination)
|
|
1459
|
+
raise
|
|
1460
|
+
|
|
1461
|
+
def _verified_object(self, destination: Path, digest: str) -> Mapping[str, Any]:
|
|
1462
|
+
if destination.is_symlink() or not destination.is_dir():
|
|
1463
|
+
raise DriverError("HANDLE_INVALID", "MCE stored artifact object is invalid")
|
|
1464
|
+
manifest_path = destination / "manifest.json"
|
|
1465
|
+
if manifest_path.is_symlink():
|
|
1466
|
+
raise DriverError("HANDLE_INVALID", "MCE stored manifest may not be a symlink")
|
|
1467
|
+
manifest = _load_json(manifest_path, code="HANDLE_INVALID")
|
|
1468
|
+
if (
|
|
1469
|
+
set(manifest) != {"schema", "artifact_bundle_sha256", "files"}
|
|
1470
|
+
or manifest.get("schema") != "agentinputlab.mce.stored-artifact.v1"
|
|
1471
|
+
or manifest.get("artifact_bundle_sha256") != digest
|
|
1472
|
+
):
|
|
1473
|
+
raise DriverError("HANDLE_INVALID", "MCE stored artifact identity drifted")
|
|
1474
|
+
files = manifest.get("files")
|
|
1475
|
+
if isinstance(files, (str, bytes)) or not isinstance(files, Sequence):
|
|
1476
|
+
raise DriverError("HANDLE_INVALID", "MCE stored artifact files are invalid")
|
|
1477
|
+
payload_root = destination / "payload"
|
|
1478
|
+
if payload_root.is_symlink() or not payload_root.is_dir():
|
|
1479
|
+
raise DriverError("HANDLE_INVALID", "MCE stored payload is invalid")
|
|
1480
|
+
expected_paths: set[str] = set()
|
|
1481
|
+
for row in files:
|
|
1482
|
+
expected_row_keys = {
|
|
1483
|
+
"path",
|
|
1484
|
+
"sha256",
|
|
1485
|
+
"byte_size",
|
|
1486
|
+
"media_type",
|
|
1487
|
+
"file_type",
|
|
1488
|
+
"generated",
|
|
1489
|
+
"executable",
|
|
1490
|
+
}
|
|
1491
|
+
if not isinstance(row, Mapping) or set(row) != expected_row_keys:
|
|
1492
|
+
raise DriverError("HANDLE_INVALID", "MCE stored file manifest drifted")
|
|
1493
|
+
relative = _text(row, "path")
|
|
1494
|
+
if relative in expected_paths:
|
|
1495
|
+
raise DriverError("HANDLE_INVALID", "MCE stored file paths are duplicated")
|
|
1496
|
+
expected_paths.add(relative)
|
|
1497
|
+
path = _safe_artifact_file(payload_root, relative)
|
|
1498
|
+
if _sha256_file(path) != row.get("sha256") or path.stat().st_size != row.get(
|
|
1499
|
+
"byte_size"
|
|
1500
|
+
):
|
|
1501
|
+
raise DriverError("HANDLE_INVALID", "MCE stored payload hash drifted")
|
|
1502
|
+
actual_paths: set[str] = set()
|
|
1503
|
+
for path in payload_root.rglob("*"):
|
|
1504
|
+
if path.is_symlink():
|
|
1505
|
+
raise DriverError("HANDLE_INVALID", "MCE stored payload contains a symlink")
|
|
1506
|
+
if path.is_file():
|
|
1507
|
+
actual_paths.add(path.relative_to(payload_root).as_posix())
|
|
1508
|
+
if actual_paths != expected_paths:
|
|
1509
|
+
raise DriverError("HANDLE_INVALID", "MCE stored payload file set drifted")
|
|
1510
|
+
return manifest
|
|
1511
|
+
|
|
1512
|
+
|
|
1513
|
+
class MCEWorkerDriver:
|
|
1514
|
+
"""Verify, execute, validate, persist, and attest one MCE run."""
|
|
1515
|
+
|
|
1516
|
+
def __init__(
|
|
1517
|
+
self,
|
|
1518
|
+
*,
|
|
1519
|
+
source_root: Path,
|
|
1520
|
+
runtime: MCERuntime,
|
|
1521
|
+
artifact_store: PersistentArtifactStore,
|
|
1522
|
+
sandbox_attestation: Mapping[str, Any],
|
|
1523
|
+
interface_signature: Mapping[str, Any],
|
|
1524
|
+
initial_context_identity: Mapping[str, Any],
|
|
1525
|
+
environment_identity: Mapping[str, Any],
|
|
1526
|
+
model_fingerprints: Mapping[str, Any],
|
|
1527
|
+
manifest_path: Path = DEFAULT_MANIFEST,
|
|
1528
|
+
workspace_root: Path | None = None,
|
|
1529
|
+
oracle_root: Path | None = None,
|
|
1530
|
+
fixture_mode: bool = False,
|
|
1531
|
+
) -> None:
|
|
1532
|
+
raw_source_root = Path(source_root)
|
|
1533
|
+
raw_manifest_path = Path(manifest_path)
|
|
1534
|
+
raw_workspace_root = Path(workspace_root) if workspace_root else None
|
|
1535
|
+
raw_oracle_root = Path(oracle_root) if oracle_root else None
|
|
1536
|
+
for path, label in (
|
|
1537
|
+
(raw_source_root, "source root"),
|
|
1538
|
+
(raw_manifest_path, "compatibility manifest"),
|
|
1539
|
+
(raw_workspace_root, "workspace root"),
|
|
1540
|
+
(raw_oracle_root, "oracle root"),
|
|
1541
|
+
):
|
|
1542
|
+
if path is not None and path.is_symlink():
|
|
1543
|
+
raise DriverError("CONFIG_INVALID", f"MCE {label} may not be a symlink")
|
|
1544
|
+
self.source_root = raw_source_root.resolve()
|
|
1545
|
+
self.runtime = runtime
|
|
1546
|
+
self.artifact_store = artifact_store
|
|
1547
|
+
self.manifest_path = raw_manifest_path.resolve()
|
|
1548
|
+
self.manifest = _load_json(self.manifest_path)
|
|
1549
|
+
self.workspace_root = raw_workspace_root.resolve() if raw_workspace_root else None
|
|
1550
|
+
self.oracle_root = raw_oracle_root.resolve() if raw_oracle_root else None
|
|
1551
|
+
for root, label in (
|
|
1552
|
+
(self.workspace_root, "workspace root"),
|
|
1553
|
+
(self.oracle_root, "oracle root"),
|
|
1554
|
+
):
|
|
1555
|
+
if root is not None:
|
|
1556
|
+
root.mkdir(parents=True, exist_ok=True)
|
|
1557
|
+
if root.is_symlink():
|
|
1558
|
+
raise DriverError("CONFIG_INVALID", f"MCE {label} may not be a symlink")
|
|
1559
|
+
if (
|
|
1560
|
+
self.workspace_root is not None
|
|
1561
|
+
and self.oracle_root is not None
|
|
1562
|
+
and _paths_overlap(self.workspace_root, self.oracle_root)
|
|
1563
|
+
):
|
|
1564
|
+
raise DriverError(
|
|
1565
|
+
"CONFIG_INVALID",
|
|
1566
|
+
"MCE workspace and oracle roots must be disjoint",
|
|
1567
|
+
)
|
|
1568
|
+
self.fixture_mode = _strict_bool_value(fixture_mode, "fixture_mode")
|
|
1569
|
+
self.interface_signature = _canonical_mapping(interface_signature, "interface signature")
|
|
1570
|
+
self.initial_context_identity = _canonical_mapping(
|
|
1571
|
+
initial_context_identity,
|
|
1572
|
+
"initial context",
|
|
1573
|
+
)
|
|
1574
|
+
if self.initial_context_identity != json.loads(_canonical_json(EMPTY_INITIAL_CONTEXT)):
|
|
1575
|
+
raise DriverError(
|
|
1576
|
+
"CONFIG_INVALID",
|
|
1577
|
+
"MCE requires the canonical empty initial context",
|
|
1578
|
+
)
|
|
1579
|
+
self.environment_identity = _canonical_mapping(
|
|
1580
|
+
environment_identity,
|
|
1581
|
+
"environment identity",
|
|
1582
|
+
)
|
|
1583
|
+
self.model_fingerprints = _canonical_mapping(
|
|
1584
|
+
model_fingerprints,
|
|
1585
|
+
"model fingerprints",
|
|
1586
|
+
)
|
|
1587
|
+
_validate_model_fingerprints(self.model_fingerprints)
|
|
1588
|
+
self.source_manifest = _canonical_mapping(
|
|
1589
|
+
_mapping(self.manifest, "source"),
|
|
1590
|
+
"source manifest",
|
|
1591
|
+
)
|
|
1592
|
+
self.license_manifest = _canonical_mapping(
|
|
1593
|
+
_mapping(self.manifest, "license"),
|
|
1594
|
+
"license manifest",
|
|
1595
|
+
)
|
|
1596
|
+
self.provenance_manifest = _canonical_mapping(
|
|
1597
|
+
_mapping(self.manifest, "provenance"),
|
|
1598
|
+
"provenance manifest",
|
|
1599
|
+
)
|
|
1600
|
+
self.semantic_patch_manifest = _canonical_mapping(
|
|
1601
|
+
_mapping(self.manifest, "semantic_patch"),
|
|
1602
|
+
"semantic patch manifest",
|
|
1603
|
+
)
|
|
1604
|
+
self.semantic_patch_manifest_sha256 = _content_hash(self.semantic_patch_manifest)
|
|
1605
|
+
self.source_tree = _require_sha1(self.source_manifest.get("tree"), "source tree")
|
|
1606
|
+
if not self.fixture_mode and not isinstance(self.runtime, MCEOfficialRuntime):
|
|
1607
|
+
raise DriverError(
|
|
1608
|
+
"CONFIG_INVALID",
|
|
1609
|
+
"production MCE requires MCEOfficialRuntime",
|
|
1610
|
+
)
|
|
1611
|
+
self.store_identity = self.artifact_store.fingerprint()
|
|
1612
|
+
self.storage_fingerprint_sha256 = _content_hash(self.store_identity)
|
|
1613
|
+
self.sandbox_attestation = self._normalize_sandbox_attestation(sandbox_attestation)
|
|
1614
|
+
self._validate_sandbox_attestation()
|
|
1615
|
+
self._verify_manifest_contract()
|
|
1616
|
+
|
|
1617
|
+
def fingerprint(self) -> Mapping[str, Any]:
|
|
1618
|
+
return {
|
|
1619
|
+
"worker_id": "agentinputlab.mce.v2",
|
|
1620
|
+
"protocol_version": PROTOCOL,
|
|
1621
|
+
"upstream_commit": UPSTREAM_COMMIT,
|
|
1622
|
+
"source_tree": self.source_tree,
|
|
1623
|
+
"source_manifest": self.source_manifest,
|
|
1624
|
+
"source_manifest_sha256": _content_hash(self.source_manifest),
|
|
1625
|
+
"license_manifest": self.license_manifest,
|
|
1626
|
+
"license_manifest_sha256": _content_hash(self.license_manifest),
|
|
1627
|
+
"provenance_manifest": self.provenance_manifest,
|
|
1628
|
+
"provenance_manifest_sha256": _content_hash(self.provenance_manifest),
|
|
1629
|
+
"semantic_patch_manifest": self.semantic_patch_manifest,
|
|
1630
|
+
"semantic_patch_manifest_sha256": self.semantic_patch_manifest_sha256,
|
|
1631
|
+
"artifact_store": self.store_identity,
|
|
1632
|
+
"storage_fingerprint_sha256": self.storage_fingerprint_sha256,
|
|
1633
|
+
"interface_signature_sha256": _content_hash(self.interface_signature),
|
|
1634
|
+
"initial_context_sha256": _content_hash(self.initial_context_identity),
|
|
1635
|
+
"environment_identity_sha256": _content_hash(self.environment_identity),
|
|
1636
|
+
"model_fingerprints_sha256": _content_hash(self.model_fingerprints),
|
|
1637
|
+
"image_digest": self.sandbox_attestation["image_digest"],
|
|
1638
|
+
"fixture_mode": self.fixture_mode,
|
|
1639
|
+
"sandbox_attestation": self.sandbox_attestation,
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
def handle(self, request: Mapping[str, Any]) -> Mapping[str, Any]:
|
|
1643
|
+
try:
|
|
1644
|
+
return self._handle(request)
|
|
1645
|
+
except DriverError as exc:
|
|
1646
|
+
response: dict[str, Any] = {
|
|
1647
|
+
"status": "error",
|
|
1648
|
+
"failure_code": exc.code,
|
|
1649
|
+
"message": exc.public_message,
|
|
1650
|
+
"consumed": exc.consumed,
|
|
1651
|
+
}
|
|
1652
|
+
if exc.usage:
|
|
1653
|
+
response["usage"] = exc.usage
|
|
1654
|
+
return response
|
|
1655
|
+
|
|
1656
|
+
def _handle(self, request: Mapping[str, Any]) -> Mapping[str, Any]:
|
|
1657
|
+
if isinstance(request, Mapping) and request.get("release_id") == "recipe.mce.final_artifact_eval":
|
|
1658
|
+
from .final_eval import handle_final_evaluation
|
|
1659
|
+
return handle_final_evaluation(self, request)
|
|
1660
|
+
payload = _validate_envelope(request)
|
|
1661
|
+
self._verify_source()
|
|
1662
|
+
self._verify_request_identity(request, payload)
|
|
1663
|
+
controls = _validate_controls(_mapping(payload, "controls"))
|
|
1664
|
+
train = _examples(payload.get("train_examples"), expected_split="train")
|
|
1665
|
+
validation = _examples(
|
|
1666
|
+
payload.get("validation_examples"),
|
|
1667
|
+
expected_split="validation",
|
|
1668
|
+
)
|
|
1669
|
+
split_audit_sha256 = _validate_split_audit(train, validation)
|
|
1670
|
+
if request.get("state_hash") != split_audit_sha256:
|
|
1671
|
+
raise DriverError("SPLIT_IDENTITY_MISMATCH", "MCE state hash omitted full examples")
|
|
1672
|
+
if payload.get("split_audit_sha256") != split_audit_sha256:
|
|
1673
|
+
raise DriverError(
|
|
1674
|
+
"SPLIT_IDENTITY_MISMATCH",
|
|
1675
|
+
"MCE split audit omitted full examples",
|
|
1676
|
+
)
|
|
1677
|
+
pre_call_budget = _mapping(payload, "pre_call_budget")
|
|
1678
|
+
expected_budget = {
|
|
1679
|
+
"model_calls": controls["max_model_calls"],
|
|
1680
|
+
"tool_calls": controls["max_tool_calls"],
|
|
1681
|
+
"wall_seconds": controls["max_wall_seconds"],
|
|
1682
|
+
}
|
|
1683
|
+
if pre_call_budget != expected_budget:
|
|
1684
|
+
raise DriverError("BUDGET_INVALID", "MCE pre-call budget does not match controls")
|
|
1685
|
+
supervisor = TrustedProviderSupervisor(**expected_budget)
|
|
1686
|
+
|
|
1687
|
+
workspace_parent = self.workspace_root
|
|
1688
|
+
oracle_parent = self.oracle_root
|
|
1689
|
+
with (
|
|
1690
|
+
tempfile.TemporaryDirectory(
|
|
1691
|
+
prefix="agentinputlab-mce-workspace-",
|
|
1692
|
+
dir=str(workspace_parent) if workspace_parent else None,
|
|
1693
|
+
) as raw_workspace,
|
|
1694
|
+
tempfile.TemporaryDirectory(
|
|
1695
|
+
prefix="agentinputlab-mce-oracle-",
|
|
1696
|
+
dir=str(oracle_parent) if oracle_parent else None,
|
|
1697
|
+
) as raw_oracle,
|
|
1698
|
+
):
|
|
1699
|
+
workspace = Path(raw_workspace).resolve()
|
|
1700
|
+
oracle = Path(raw_oracle).resolve()
|
|
1701
|
+
if _paths_overlap(workspace, oracle):
|
|
1702
|
+
raise DriverError(
|
|
1703
|
+
"ISOLATION_INVALID",
|
|
1704
|
+
"MCE validation oracle overlaps the generated workspace",
|
|
1705
|
+
)
|
|
1706
|
+
train_path = workspace / "train.jsonl"
|
|
1707
|
+
validation_path = oracle / "validation.jsonl"
|
|
1708
|
+
_write_native_jsonl(train_path, train)
|
|
1709
|
+
_write_native_jsonl(validation_path, validation)
|
|
1710
|
+
runtime_controls = {
|
|
1711
|
+
**controls,
|
|
1712
|
+
"train_limit": len(train),
|
|
1713
|
+
"validation_limit": len(validation),
|
|
1714
|
+
}
|
|
1715
|
+
try:
|
|
1716
|
+
result = self.runtime.evolve(
|
|
1717
|
+
workspace=workspace,
|
|
1718
|
+
train_path=train_path,
|
|
1719
|
+
validation_path=validation_path,
|
|
1720
|
+
controls=runtime_controls,
|
|
1721
|
+
model_fingerprints=self.model_fingerprints,
|
|
1722
|
+
supervisor=supervisor,
|
|
1723
|
+
)
|
|
1724
|
+
except DriverError:
|
|
1725
|
+
raise
|
|
1726
|
+
except Exception as exc:
|
|
1727
|
+
raise DriverError(
|
|
1728
|
+
"UPSTREAM_EXECUTION_FAILED",
|
|
1729
|
+
"MCE isolated runtime failed",
|
|
1730
|
+
consumed=True,
|
|
1731
|
+
usage=supervisor.usage(),
|
|
1732
|
+
) from exc
|
|
1733
|
+
payload_out = self._materialize_response(
|
|
1734
|
+
result=result,
|
|
1735
|
+
workspace=workspace,
|
|
1736
|
+
request_payload=payload,
|
|
1737
|
+
controls=controls,
|
|
1738
|
+
split_audit_sha256=split_audit_sha256,
|
|
1739
|
+
usage=supervisor.usage(),
|
|
1740
|
+
)
|
|
1741
|
+
|
|
1742
|
+
return {
|
|
1743
|
+
"status": "ok",
|
|
1744
|
+
"request_id": request["request_id"],
|
|
1745
|
+
"upstream_commit": UPSTREAM_COMMIT,
|
|
1746
|
+
"protocol_version": PROTOCOL,
|
|
1747
|
+
"payload": payload_out,
|
|
1748
|
+
"usage": supervisor.usage(),
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
def _verify_request_identity(
|
|
1752
|
+
self,
|
|
1753
|
+
request: Mapping[str, Any],
|
|
1754
|
+
payload: Mapping[str, Any],
|
|
1755
|
+
) -> None:
|
|
1756
|
+
identity = self.fingerprint()
|
|
1757
|
+
expected = {
|
|
1758
|
+
"interface_signature_sha256": _content_hash(self.interface_signature),
|
|
1759
|
+
"initial_context_sha256": _content_hash(self.initial_context_identity),
|
|
1760
|
+
"environment_identity_sha256": _content_hash(self.environment_identity),
|
|
1761
|
+
"sandbox_attestation_id": self.sandbox_attestation["attestation_id"],
|
|
1762
|
+
"model_fingerprints_sha256": _content_hash(self.model_fingerprints),
|
|
1763
|
+
"source_tree": self.source_tree,
|
|
1764
|
+
"source_manifest_sha256": _content_hash(self.source_manifest),
|
|
1765
|
+
"license_manifest_sha256": _content_hash(self.license_manifest),
|
|
1766
|
+
"provenance_manifest_sha256": _content_hash(self.provenance_manifest),
|
|
1767
|
+
"semantic_patch_manifest_sha256": self.semantic_patch_manifest_sha256,
|
|
1768
|
+
"storage_fingerprint_sha256": self.storage_fingerprint_sha256,
|
|
1769
|
+
"worker_fingerprint_sha256": _content_hash(identity),
|
|
1770
|
+
"host_execution_allowed": False,
|
|
1771
|
+
"artifact_egress": "manifest_and_opaque_handle_only",
|
|
1772
|
+
}
|
|
1773
|
+
for key, value in expected.items():
|
|
1774
|
+
if payload.get(key) != value:
|
|
1775
|
+
raise DriverError("IDENTITY_MISMATCH", f"MCE request mismatch: {key}")
|
|
1776
|
+
body_expectations = {
|
|
1777
|
+
"interface_signature": self.interface_signature,
|
|
1778
|
+
"initial_context_identity": self.initial_context_identity,
|
|
1779
|
+
"environment_identity": self.environment_identity,
|
|
1780
|
+
"model_fingerprints": self.model_fingerprints,
|
|
1781
|
+
"semantic_patch_manifest": self.semantic_patch_manifest,
|
|
1782
|
+
}
|
|
1783
|
+
for key, value in body_expectations.items():
|
|
1784
|
+
if _canonical_json(payload.get(key)) != _canonical_json(value):
|
|
1785
|
+
raise DriverError("IDENTITY_MISMATCH", f"MCE request body mismatch: {key}")
|
|
1786
|
+
dependencies = request.get("dependency_fingerprints")
|
|
1787
|
+
if not isinstance(dependencies, Mapping) or _canonical_json(
|
|
1788
|
+
dependencies.get("worker")
|
|
1789
|
+
) != _canonical_json(identity):
|
|
1790
|
+
raise DriverError("IDENTITY_MISMATCH", "MCE worker dependency identity drifted")
|
|
1791
|
+
controls = _mapping(payload, "controls")
|
|
1792
|
+
expected_runtime_binding = _runtime_binding_sha256(
|
|
1793
|
+
controls=controls,
|
|
1794
|
+
split_audit_sha256=_text(payload, "split_audit_sha256"),
|
|
1795
|
+
interface_signature_sha256=expected["interface_signature_sha256"],
|
|
1796
|
+
initial_context_sha256=expected["initial_context_sha256"],
|
|
1797
|
+
environment_identity_sha256=expected["environment_identity_sha256"],
|
|
1798
|
+
model_fingerprints_sha256=expected["model_fingerprints_sha256"],
|
|
1799
|
+
source_tree=self.source_tree,
|
|
1800
|
+
source_manifest_sha256=expected["source_manifest_sha256"],
|
|
1801
|
+
semantic_patch_manifest_sha256=self.semantic_patch_manifest_sha256,
|
|
1802
|
+
)
|
|
1803
|
+
if payload.get("runtime_binding_sha256") != expected_runtime_binding:
|
|
1804
|
+
raise DriverError("IDENTITY_MISMATCH", "MCE runtime binding drifted")
|
|
1805
|
+
|
|
1806
|
+
def _materialize_response(
|
|
1807
|
+
self,
|
|
1808
|
+
*,
|
|
1809
|
+
result: MCEEvolutionRun,
|
|
1810
|
+
workspace: Path,
|
|
1811
|
+
request_payload: Mapping[str, Any],
|
|
1812
|
+
controls: Mapping[str, int],
|
|
1813
|
+
split_audit_sha256: str,
|
|
1814
|
+
usage: Mapping[str, int | float],
|
|
1815
|
+
) -> Mapping[str, Any]:
|
|
1816
|
+
if not isinstance(result, MCEEvolutionRun):
|
|
1817
|
+
raise DriverError(
|
|
1818
|
+
"RUNTIME_INVALID",
|
|
1819
|
+
"MCE runtime result is invalid",
|
|
1820
|
+
consumed=True,
|
|
1821
|
+
usage=usage,
|
|
1822
|
+
)
|
|
1823
|
+
expected_indices = tuple(range(controls["iterations"] + 1))
|
|
1824
|
+
if tuple(item.index for item in result.iterations) != expected_indices:
|
|
1825
|
+
raise DriverError(
|
|
1826
|
+
"RUNTIME_INVALID",
|
|
1827
|
+
"MCE runtime must return baseline zero through the configured iteration",
|
|
1828
|
+
consumed=True,
|
|
1829
|
+
usage=usage,
|
|
1830
|
+
)
|
|
1831
|
+
if not (
|
|
1832
|
+
result.official_run_iteration_called
|
|
1833
|
+
and result.meta_agent_enabled
|
|
1834
|
+
and result.base_agent_enabled
|
|
1835
|
+
):
|
|
1836
|
+
raise DriverError(
|
|
1837
|
+
"RUNTIME_INVALID",
|
|
1838
|
+
"MCE runtime omitted an official bi-level stage",
|
|
1839
|
+
consumed=True,
|
|
1840
|
+
usage=usage,
|
|
1841
|
+
)
|
|
1842
|
+
if int(usage["model_calls"]) < 1:
|
|
1843
|
+
raise DriverError(
|
|
1844
|
+
"USAGE_INVALID",
|
|
1845
|
+
"MCE runtime did not record a provider-side model call",
|
|
1846
|
+
consumed=True,
|
|
1847
|
+
usage=usage,
|
|
1848
|
+
)
|
|
1849
|
+
|
|
1850
|
+
iteration_rows: list[Mapping[str, Any]] = []
|
|
1851
|
+
manifests: dict[int, tuple[Mapping[str, Any], ...]] = {}
|
|
1852
|
+
roots: dict[int, Path] = {}
|
|
1853
|
+
for item in result.iterations:
|
|
1854
|
+
root = _contained_directory(item.artifact_root, workspace)
|
|
1855
|
+
files = _artifact_manifest(
|
|
1856
|
+
root,
|
|
1857
|
+
max_files=controls["max_artifact_files"],
|
|
1858
|
+
max_bytes=controls["max_artifact_bytes"],
|
|
1859
|
+
)
|
|
1860
|
+
skill_sha256 = _skill_sha256(root)
|
|
1861
|
+
if item.index == 0:
|
|
1862
|
+
if files or skill_sha256 != EMPTY_SKILL_SHA256:
|
|
1863
|
+
raise DriverError(
|
|
1864
|
+
"ARTIFACT_INVALID",
|
|
1865
|
+
"MCE baseline must be the canonical empty artifact",
|
|
1866
|
+
consumed=True,
|
|
1867
|
+
usage=usage,
|
|
1868
|
+
)
|
|
1869
|
+
elif skill_sha256 == EMPTY_SKILL_SHA256:
|
|
1870
|
+
raise DriverError(
|
|
1871
|
+
"ARTIFACT_INVALID",
|
|
1872
|
+
"every evolved MCE iteration must contain SKILL.md",
|
|
1873
|
+
consumed=True,
|
|
1874
|
+
usage=usage,
|
|
1875
|
+
)
|
|
1876
|
+
roots[item.index] = root
|
|
1877
|
+
manifests[item.index] = files
|
|
1878
|
+
iteration_rows.append(
|
|
1879
|
+
{
|
|
1880
|
+
"index": item.index,
|
|
1881
|
+
"skill_sha256": skill_sha256,
|
|
1882
|
+
"artifact_manifest_sha256": _content_hash(files),
|
|
1883
|
+
"validation_score": item.validation_score,
|
|
1884
|
+
}
|
|
1885
|
+
)
|
|
1886
|
+
selected_iteration = max(
|
|
1887
|
+
range(len(iteration_rows)),
|
|
1888
|
+
key=lambda index: iteration_rows[index]["validation_score"],
|
|
1889
|
+
)
|
|
1890
|
+
selected_files = manifests[selected_iteration]
|
|
1891
|
+
selected_row = iteration_rows[selected_iteration]
|
|
1892
|
+
runtime_binding_sha256 = _text(request_payload, "runtime_binding_sha256")
|
|
1893
|
+
bound = {
|
|
1894
|
+
"source_tree": self.source_tree,
|
|
1895
|
+
"source_manifest_sha256": _content_hash(self.source_manifest),
|
|
1896
|
+
"license_manifest_sha256": _content_hash(self.license_manifest),
|
|
1897
|
+
"provenance_manifest_sha256": _content_hash(self.provenance_manifest),
|
|
1898
|
+
"semantic_patch_manifest_sha256": self.semantic_patch_manifest_sha256,
|
|
1899
|
+
"storage_fingerprint_sha256": self.storage_fingerprint_sha256,
|
|
1900
|
+
}
|
|
1901
|
+
bundle = _artifact_bundle(
|
|
1902
|
+
files=selected_files,
|
|
1903
|
+
selected_iteration=selected_iteration,
|
|
1904
|
+
artifact_manifest_sha256=selected_row["artifact_manifest_sha256"],
|
|
1905
|
+
skill_sha256=selected_row["skill_sha256"],
|
|
1906
|
+
split_audit_sha256=split_audit_sha256,
|
|
1907
|
+
interface_signature_sha256=_content_hash(self.interface_signature),
|
|
1908
|
+
initial_context_sha256=_content_hash(self.initial_context_identity),
|
|
1909
|
+
environment_identity_sha256=_content_hash(self.environment_identity),
|
|
1910
|
+
model_fingerprints_sha256=_content_hash(self.model_fingerprints),
|
|
1911
|
+
controls_sha256=_content_hash(_mapping(request_payload, "controls")),
|
|
1912
|
+
runtime_binding_sha256=runtime_binding_sha256,
|
|
1913
|
+
semantic_patch_manifest_sha256=self.semantic_patch_manifest_sha256,
|
|
1914
|
+
bound=bound,
|
|
1915
|
+
)
|
|
1916
|
+
bundle_sha256 = _content_hash(bundle)
|
|
1917
|
+
artifact_handle = self.artifact_store.put(
|
|
1918
|
+
bundle_sha256,
|
|
1919
|
+
artifact_root=roots[selected_iteration],
|
|
1920
|
+
files=selected_files,
|
|
1921
|
+
)
|
|
1922
|
+
runtime_attestation = {
|
|
1923
|
+
"source_commit": UPSTREAM_COMMIT,
|
|
1924
|
+
"source_tree": self.source_tree,
|
|
1925
|
+
"source_manifest_sha256": bound["source_manifest_sha256"],
|
|
1926
|
+
"runtime_binding_sha256": runtime_binding_sha256,
|
|
1927
|
+
"semantic_patch_manifest_sha256": self.semantic_patch_manifest_sha256,
|
|
1928
|
+
"semantic_patch_applied": True,
|
|
1929
|
+
"upstream_run_iteration_source_sha256": UPSTREAM_MAIN_SHA256,
|
|
1930
|
+
"interface_validation_mode": "remote_static_no_import",
|
|
1931
|
+
"batch_evaluation_mode": "trusted_supervisor_no_generated_import",
|
|
1932
|
+
"official_run_iteration_called": True,
|
|
1933
|
+
"baseline_iteration_executed": True,
|
|
1934
|
+
"meta_agent_enabled": True,
|
|
1935
|
+
"base_agent_enabled": True,
|
|
1936
|
+
"validation_selection": "max_primary_metric_first_tie",
|
|
1937
|
+
"validation_oracle_mode": "evaluator_only",
|
|
1938
|
+
"oracle_mount_mode": "supervisor_only_hidden",
|
|
1939
|
+
"oracle_process_boundary": "trusted_supervisor_out_of_process",
|
|
1940
|
+
"generated_agents_validation_access": False,
|
|
1941
|
+
"generated_workspace_oracle_visible": False,
|
|
1942
|
+
"usage_accounting_mode": "trusted_supervisor_ipc",
|
|
1943
|
+
"provider_guard_mode": "provider_transport_pre_call",
|
|
1944
|
+
"pre_call_budget_enforced": True,
|
|
1945
|
+
"wall_timeout_enforced": True,
|
|
1946
|
+
"seed_mode": SEED_MODE,
|
|
1947
|
+
"provider_subcall_seed_mode": PROVIDER_SUBCALL_SEED_MODE,
|
|
1948
|
+
"generated_code_execution": "isolated_worker_only",
|
|
1949
|
+
"artifact_egress": "manifest_and_opaque_handle_only",
|
|
1950
|
+
"artifact_store_persistent": True,
|
|
1951
|
+
"host_code_executed": False,
|
|
1952
|
+
"test_split_used": False,
|
|
1953
|
+
"runtime_mode": "fixture" if self.fixture_mode else "production",
|
|
1954
|
+
}
|
|
1955
|
+
return {
|
|
1956
|
+
"sandbox_attestation_id": self.sandbox_attestation["attestation_id"],
|
|
1957
|
+
"host_code_executed": False,
|
|
1958
|
+
"artifact_egress": "manifest_and_opaque_handle_only",
|
|
1959
|
+
"split_audit_sha256": split_audit_sha256,
|
|
1960
|
+
"interface_signature_sha256": _content_hash(self.interface_signature),
|
|
1961
|
+
"initial_context_sha256": _content_hash(self.initial_context_identity),
|
|
1962
|
+
"environment_identity_sha256": _content_hash(self.environment_identity),
|
|
1963
|
+
"model_fingerprints_sha256": _content_hash(self.model_fingerprints),
|
|
1964
|
+
"runtime_binding_sha256": runtime_binding_sha256,
|
|
1965
|
+
"semantic_patch_manifest_sha256": self.semantic_patch_manifest_sha256,
|
|
1966
|
+
**bound,
|
|
1967
|
+
"files": selected_files,
|
|
1968
|
+
"artifact_manifest_sha256": selected_row["artifact_manifest_sha256"],
|
|
1969
|
+
"artifact_bundle_sha256": bundle_sha256,
|
|
1970
|
+
"artifact_handle": artifact_handle,
|
|
1971
|
+
"skill_sha256": selected_row["skill_sha256"],
|
|
1972
|
+
"iterations": tuple(iteration_rows),
|
|
1973
|
+
"selected_iteration": selected_iteration,
|
|
1974
|
+
"provenance_status": "generated_unreviewed",
|
|
1975
|
+
"runtime_attestation": runtime_attestation,
|
|
1976
|
+
}
|
|
1977
|
+
|
|
1978
|
+
def _verify_manifest_contract(self) -> None:
|
|
1979
|
+
if self.manifest.get("schema") != "agentinputlab.mce.compatibility.v2":
|
|
1980
|
+
raise DriverError("MANIFEST_INVALID", "MCE compatibility schema must be v2")
|
|
1981
|
+
source = self.source_manifest
|
|
1982
|
+
if source.get("commit") != UPSTREAM_COMMIT:
|
|
1983
|
+
raise DriverError("MANIFEST_INVALID", "MCE source commit drifted")
|
|
1984
|
+
if source.get("fixture") is not self.fixture_mode:
|
|
1985
|
+
raise DriverError("MANIFEST_INVALID", "MCE fixture/source mode mismatch")
|
|
1986
|
+
if self.license_manifest.get("license_id") != "MIT":
|
|
1987
|
+
raise DriverError("MANIFEST_INVALID", "MCE source license identity drifted")
|
|
1988
|
+
if self.provenance_manifest.get("paper_result_parity") is not False:
|
|
1989
|
+
raise DriverError("MANIFEST_INVALID", "MCE provenance must not claim L3 parity")
|
|
1990
|
+
if (
|
|
1991
|
+
self.semantic_patch_manifest != json.loads(_canonical_json(SEMANTIC_PATCH_MANIFEST))
|
|
1992
|
+
or self.semantic_patch_manifest_sha256 != SEMANTIC_PATCH_MANIFEST_SHA256
|
|
1993
|
+
):
|
|
1994
|
+
raise DriverError("MANIFEST_INVALID", "MCE semantic patch manifest drifted")
|
|
1995
|
+
closure = _mapping(source, "import_closure")
|
|
1996
|
+
required = _mapping(source, "required_files")
|
|
1997
|
+
if not closure or not set(closure).issubset(required):
|
|
1998
|
+
raise DriverError("MANIFEST_INVALID", "MCE import closure is incomplete")
|
|
1999
|
+
|
|
2000
|
+
def _verify_source(self) -> None:
|
|
2001
|
+
source = self.source_manifest
|
|
2002
|
+
for group in ("required_files", "import_closure"):
|
|
2003
|
+
for relative, expected in _mapping(source, group).items():
|
|
2004
|
+
path = _safe_source_file(self.source_root, relative)
|
|
2005
|
+
if _sha256_file(path) != expected:
|
|
2006
|
+
raise DriverError(
|
|
2007
|
+
"SOURCE_MISMATCH",
|
|
2008
|
+
f"MCE source hash mismatch: {relative}",
|
|
2009
|
+
)
|
|
2010
|
+
license_path = _safe_source_file(
|
|
2011
|
+
self.source_root,
|
|
2012
|
+
self.license_manifest.get("path"),
|
|
2013
|
+
)
|
|
2014
|
+
if _sha256_file(license_path) != self.license_manifest.get("sha256"):
|
|
2015
|
+
raise DriverError("SOURCE_MISMATCH", "MCE license hash mismatch")
|
|
2016
|
+
if self.fixture_mode:
|
|
2017
|
+
return
|
|
2018
|
+
head = _git(self.source_root, "rev-parse", "HEAD")
|
|
2019
|
+
tree = _git(self.source_root, "rev-parse", "HEAD^{tree}")
|
|
2020
|
+
dirty = _git(self.source_root, "status", "--porcelain", "--untracked-files=all")
|
|
2021
|
+
if head != UPSTREAM_COMMIT:
|
|
2022
|
+
raise DriverError("SOURCE_MISMATCH", "MCE source commit mismatch")
|
|
2023
|
+
if tree != self.source_tree:
|
|
2024
|
+
raise DriverError("SOURCE_MISMATCH", "MCE source tree mismatch")
|
|
2025
|
+
if dirty:
|
|
2026
|
+
raise DriverError("SOURCE_DIRTY", "MCE production checkout must be clean")
|
|
2027
|
+
|
|
2028
|
+
def _normalize_sandbox_attestation(
|
|
2029
|
+
self,
|
|
2030
|
+
value: Mapping[str, Any],
|
|
2031
|
+
) -> Mapping[str, Any]:
|
|
2032
|
+
result = _canonical_mapping(value, "sandbox attestation")
|
|
2033
|
+
expected = {
|
|
2034
|
+
"runtime_mode": "fixture" if self.fixture_mode else "production",
|
|
2035
|
+
"source_mode": "fixture" if self.fixture_mode else "git_checkout",
|
|
2036
|
+
"artifact_store_fingerprint_sha256": self.storage_fingerprint_sha256,
|
|
2037
|
+
}
|
|
2038
|
+
result = {**result, **expected}
|
|
2039
|
+
return json.loads(_canonical_json(result))
|
|
2040
|
+
|
|
2041
|
+
def _validate_sandbox_attestation(self) -> None:
|
|
2042
|
+
expected = {
|
|
2043
|
+
"validation_oracle_mode": "evaluator_only",
|
|
2044
|
+
"oracle_mount_mode": "supervisor_only_hidden",
|
|
2045
|
+
"oracle_process_boundary": "trusted_supervisor_out_of_process",
|
|
2046
|
+
"generated_agents_validation_access": False,
|
|
2047
|
+
"generated_workspace_oracle_visible": False,
|
|
2048
|
+
"usage_accounting_mode": "trusted_supervisor_ipc",
|
|
2049
|
+
"provider_guard_mode": "provider_transport_pre_call",
|
|
2050
|
+
"seed_mode": SEED_MODE,
|
|
2051
|
+
"provider_subcall_seed_mode": PROVIDER_SUBCALL_SEED_MODE,
|
|
2052
|
+
"pre_call_budget_enforced": True,
|
|
2053
|
+
"artifact_store_persistent": True,
|
|
2054
|
+
"semantic_patch_manifest_sha256": self.semantic_patch_manifest_sha256,
|
|
2055
|
+
"semantic_patch_applied": True,
|
|
2056
|
+
"upstream_run_iteration_source_sha256": UPSTREAM_MAIN_SHA256,
|
|
2057
|
+
"interface_validation_mode": "remote_static_no_import",
|
|
2058
|
+
"batch_evaluation_mode": "trusted_supervisor_no_generated_import",
|
|
2059
|
+
}
|
|
2060
|
+
for key, value in expected.items():
|
|
2061
|
+
if self.sandbox_attestation.get(key) != value:
|
|
2062
|
+
raise DriverError(
|
|
2063
|
+
"ATTESTATION_INVALID",
|
|
2064
|
+
f"MCE sandbox attestation mismatch: {key}",
|
|
2065
|
+
)
|
|
2066
|
+
required = self.sandbox_attestation.get("required_worker_contract")
|
|
2067
|
+
expected_contract = {
|
|
2068
|
+
"oracle_mount_mode": "supervisor_only_hidden",
|
|
2069
|
+
"oracle_process_boundary": "trusted_supervisor_out_of_process",
|
|
2070
|
+
"generated_workspace_oracle_visible": False,
|
|
2071
|
+
"provider_guard_mode": "provider_transport_pre_call",
|
|
2072
|
+
"seed_mode": SEED_MODE,
|
|
2073
|
+
"provider_subcall_seed_mode": PROVIDER_SUBCALL_SEED_MODE,
|
|
2074
|
+
"validation_scoring_mode": "supervisor_only",
|
|
2075
|
+
}
|
|
2076
|
+
if not isinstance(required, Mapping) or dict(required) != expected_contract:
|
|
2077
|
+
raise DriverError(
|
|
2078
|
+
"ATTESTATION_INVALID",
|
|
2079
|
+
"MCE sandbox required_worker_contract mismatch",
|
|
2080
|
+
)
|
|
2081
|
+
|
|
2082
|
+
|
|
2083
|
+
def _validate_envelope(
|
|
2084
|
+
request: Mapping[str, Any], *, release_id: str = RELEASE_ID,
|
|
2085
|
+
) -> Mapping[str, Any]:
|
|
2086
|
+
if not isinstance(request, Mapping):
|
|
2087
|
+
raise DriverError("REQUEST_INVALID", "MCE request must be a mapping")
|
|
2088
|
+
expected = {
|
|
2089
|
+
"method_id": "recipe.mce",
|
|
2090
|
+
"release_id": release_id,
|
|
2091
|
+
"upstream_commit": UPSTREAM_COMMIT,
|
|
2092
|
+
"protocol_version": PROTOCOL,
|
|
2093
|
+
}
|
|
2094
|
+
for key, value in expected.items():
|
|
2095
|
+
if request.get(key) != value:
|
|
2096
|
+
raise DriverError("IDENTITY_MISMATCH", f"MCE envelope mismatch: {key}")
|
|
2097
|
+
claimed = request.get("request_id")
|
|
2098
|
+
if not isinstance(claimed, str) or not claimed:
|
|
2099
|
+
raise DriverError("REQUEST_INVALID", "MCE request_id is required")
|
|
2100
|
+
identity = {key: value for key, value in request.items() if key != "request_id"}
|
|
2101
|
+
if _content_hash(identity) != claimed:
|
|
2102
|
+
raise DriverError("REQUEST_ID_MISMATCH", "MCE request_id does not bind the envelope")
|
|
2103
|
+
return _mapping(request, "payload")
|
|
2104
|
+
|
|
2105
|
+
|
|
2106
|
+
def _validate_controls(value: Mapping[str, Any]) -> Mapping[str, int]:
|
|
2107
|
+
if set(value) != _CONTROL_KEYS:
|
|
2108
|
+
raise DriverError("REQUEST_INVALID", "MCE controls do not match the frozen profile")
|
|
2109
|
+
result = {key: _positive_int(value, key) for key in _CONTROL_KEYS if key != "seed"}
|
|
2110
|
+
result["seed"] = _nonnegative_int(value, "seed")
|
|
2111
|
+
return result
|
|
2112
|
+
|
|
2113
|
+
|
|
2114
|
+
def _examples(value: Any, *, expected_split: str) -> tuple[Mapping[str, Any], ...]:
|
|
2115
|
+
if isinstance(value, (str, bytes)) or not isinstance(value, Sequence) or not value:
|
|
2116
|
+
raise DriverError("REQUEST_INVALID", f"MCE {expected_split} examples must be non-empty")
|
|
2117
|
+
rows: list[Mapping[str, Any]] = []
|
|
2118
|
+
for raw in value:
|
|
2119
|
+
if not isinstance(raw, Mapping) or set(raw) != _EXAMPLE_KEYS:
|
|
2120
|
+
raise DriverError("REQUEST_INVALID", "MCE example schema drifted")
|
|
2121
|
+
if raw.get("split") != expected_split:
|
|
2122
|
+
raise DriverError("SPLIT_LEAKAGE", "MCE example split label mismatch")
|
|
2123
|
+
identifier = raw.get("example_id")
|
|
2124
|
+
metadata = raw.get("metadata")
|
|
2125
|
+
if not isinstance(identifier, str) or not identifier:
|
|
2126
|
+
raise DriverError("REQUEST_INVALID", "MCE example_id is required")
|
|
2127
|
+
if not isinstance(metadata, Mapping):
|
|
2128
|
+
raise DriverError("REQUEST_INVALID", "MCE example metadata must be a mapping")
|
|
2129
|
+
lowered = {str(key).lower() for key in metadata}
|
|
2130
|
+
if lowered & _FORBIDDEN_EXAMPLE_KEYS:
|
|
2131
|
+
raise DriverError("SPLIT_LEAKAGE", "MCE example contains test-only metadata")
|
|
2132
|
+
_canonical_json(raw)
|
|
2133
|
+
rows.append(json.loads(_canonical_json(raw)))
|
|
2134
|
+
return tuple(rows)
|
|
2135
|
+
|
|
2136
|
+
|
|
2137
|
+
def _validate_split_audit(
|
|
2138
|
+
train: tuple[Mapping[str, Any], ...],
|
|
2139
|
+
validation: tuple[Mapping[str, Any], ...],
|
|
2140
|
+
) -> str:
|
|
2141
|
+
groups = {"train": train, "validation": validation}
|
|
2142
|
+
result: dict[str, tuple[str, ...]] = {}
|
|
2143
|
+
for split, rows in groups.items():
|
|
2144
|
+
ids = tuple(str(row["example_id"]) for row in rows)
|
|
2145
|
+
input_hashes = tuple(_content_hash(row["input"]) for row in rows)
|
|
2146
|
+
example_hashes = tuple(_content_hash(row) for row in rows)
|
|
2147
|
+
if len(ids) != len(set(ids)):
|
|
2148
|
+
raise DriverError("SPLIT_LEAKAGE", f"MCE {split} contains duplicate IDs")
|
|
2149
|
+
if len(input_hashes) != len(set(input_hashes)):
|
|
2150
|
+
raise DriverError("SPLIT_LEAKAGE", f"MCE {split} contains duplicate inputs")
|
|
2151
|
+
if len(example_hashes) != len(set(example_hashes)):
|
|
2152
|
+
raise DriverError("SPLIT_LEAKAGE", f"MCE {split} contains duplicate examples")
|
|
2153
|
+
result[f"{split}_ids"] = ids
|
|
2154
|
+
result[f"{split}_input_hashes"] = input_hashes
|
|
2155
|
+
result[f"{split}_example_hashes"] = example_hashes
|
|
2156
|
+
if set(result["train_ids"]) & set(result["validation_ids"]):
|
|
2157
|
+
raise DriverError("SPLIT_LEAKAGE", "MCE train/validation IDs overlap")
|
|
2158
|
+
if set(result["train_input_hashes"]) & set(result["validation_input_hashes"]):
|
|
2159
|
+
raise DriverError("SPLIT_LEAKAGE", "MCE train/validation inputs overlap")
|
|
2160
|
+
return _content_hash(result)
|
|
2161
|
+
|
|
2162
|
+
|
|
2163
|
+
def _write_native_jsonl(path: Path, examples: Sequence[Mapping[str, Any]]) -> None:
|
|
2164
|
+
with path.open("x", encoding="utf-8") as handle:
|
|
2165
|
+
for example in examples:
|
|
2166
|
+
input_value = example["input"]
|
|
2167
|
+
if not isinstance(input_value, Mapping):
|
|
2168
|
+
raise DriverError(
|
|
2169
|
+
"REQUEST_INVALID",
|
|
2170
|
+
"MCE official runtime requires mapping-shaped native inputs",
|
|
2171
|
+
)
|
|
2172
|
+
record = dict(input_value)
|
|
2173
|
+
if {"id", "ground_truth"} & set(record):
|
|
2174
|
+
raise DriverError(
|
|
2175
|
+
"REQUEST_INVALID",
|
|
2176
|
+
"MCE native input may not override id or ground_truth",
|
|
2177
|
+
)
|
|
2178
|
+
record["id"] = example["example_id"]
|
|
2179
|
+
record["ground_truth"] = example["expected_output"]
|
|
2180
|
+
record["_agentinputlab_metadata"] = dict(example["metadata"])
|
|
2181
|
+
handle.write(_canonical_json(record) + "\n")
|
|
2182
|
+
|
|
2183
|
+
|
|
2184
|
+
def _frozen_artifact_manifest(
|
|
2185
|
+
root: Path, *, max_files: int, max_bytes: int,
|
|
2186
|
+
) -> tuple[Mapping[str, Any], ...]:
|
|
2187
|
+
files = _artifact_manifest(root, max_files=max_files, max_bytes=max_bytes)
|
|
2188
|
+
if {path.relative_to(root).as_posix() for path in root.rglob("*") if path.is_file()} != {
|
|
2189
|
+
row["path"] for row in files
|
|
2190
|
+
}:
|
|
2191
|
+
raise DriverError("ARTIFACT_INVALID", "MCE frozen selection contains an unbound file")
|
|
2192
|
+
return files
|
|
2193
|
+
|
|
2194
|
+
|
|
2195
|
+
def _artifact_manifest(
|
|
2196
|
+
root: Path,
|
|
2197
|
+
*,
|
|
2198
|
+
max_files: int,
|
|
2199
|
+
max_bytes: int,
|
|
2200
|
+
) -> tuple[Mapping[str, Any], ...]:
|
|
2201
|
+
rows: list[Mapping[str, Any]] = []
|
|
2202
|
+
total_bytes = 0
|
|
2203
|
+
for path in sorted(root.rglob("*")):
|
|
2204
|
+
if path.is_symlink():
|
|
2205
|
+
raise DriverError("ARTIFACT_INVALID", "MCE artifact may not contain symlinks")
|
|
2206
|
+
if not path.is_file():
|
|
2207
|
+
continue
|
|
2208
|
+
relative = path.relative_to(root).as_posix()
|
|
2209
|
+
if not _allowed_artifact_path(relative):
|
|
2210
|
+
continue
|
|
2211
|
+
size = path.stat().st_size
|
|
2212
|
+
total_bytes += size
|
|
2213
|
+
if len(rows) + 1 > max_files or total_bytes > max_bytes:
|
|
2214
|
+
raise DriverError("ARTIFACT_LIMIT_EXCEEDED", "MCE artifact limits exceeded")
|
|
2215
|
+
rows.append(
|
|
2216
|
+
{
|
|
2217
|
+
"path": relative,
|
|
2218
|
+
"sha256": _sha256_file(path),
|
|
2219
|
+
"byte_size": size,
|
|
2220
|
+
"media_type": mimetypes.guess_type(relative)[0] or "application/octet-stream",
|
|
2221
|
+
"file_type": "regular",
|
|
2222
|
+
"generated": True,
|
|
2223
|
+
"executable": bool(path.stat().st_mode & 0o111),
|
|
2224
|
+
}
|
|
2225
|
+
)
|
|
2226
|
+
return tuple(rows)
|
|
2227
|
+
|
|
2228
|
+
|
|
2229
|
+
def _skill_sha256(root: Path) -> str:
|
|
2230
|
+
skill = root / ".claude" / "skills" / "learning-context" / "SKILL.md"
|
|
2231
|
+
if skill.is_symlink():
|
|
2232
|
+
raise DriverError("ARTIFACT_INVALID", "MCE skill may not be a symlink")
|
|
2233
|
+
return _sha256_file(skill) if skill.is_file() else EMPTY_SKILL_SHA256
|
|
2234
|
+
|
|
2235
|
+
|
|
2236
|
+
def _artifact_bundle(
|
|
2237
|
+
*,
|
|
2238
|
+
files: Sequence[Mapping[str, Any]],
|
|
2239
|
+
selected_iteration: int,
|
|
2240
|
+
artifact_manifest_sha256: str,
|
|
2241
|
+
skill_sha256: str,
|
|
2242
|
+
split_audit_sha256: str,
|
|
2243
|
+
interface_signature_sha256: str,
|
|
2244
|
+
initial_context_sha256: str,
|
|
2245
|
+
environment_identity_sha256: str,
|
|
2246
|
+
model_fingerprints_sha256: str,
|
|
2247
|
+
controls_sha256: str,
|
|
2248
|
+
runtime_binding_sha256: str,
|
|
2249
|
+
semantic_patch_manifest_sha256: str,
|
|
2250
|
+
bound: Mapping[str, str],
|
|
2251
|
+
) -> Mapping[str, Any]:
|
|
2252
|
+
return {
|
|
2253
|
+
"schema": "agentinputlab.mce.bundle.v2",
|
|
2254
|
+
"files": tuple(files),
|
|
2255
|
+
"selected_iteration": selected_iteration,
|
|
2256
|
+
"artifact_manifest_sha256": artifact_manifest_sha256,
|
|
2257
|
+
"skill_sha256": skill_sha256,
|
|
2258
|
+
"source_commit": UPSTREAM_COMMIT,
|
|
2259
|
+
"source_tree": bound["source_tree"],
|
|
2260
|
+
"source_manifest_sha256": bound["source_manifest_sha256"],
|
|
2261
|
+
"license_manifest_sha256": bound["license_manifest_sha256"],
|
|
2262
|
+
"provenance_manifest_sha256": bound["provenance_manifest_sha256"],
|
|
2263
|
+
"semantic_patch_manifest_sha256": semantic_patch_manifest_sha256,
|
|
2264
|
+
"storage_fingerprint_sha256": bound["storage_fingerprint_sha256"],
|
|
2265
|
+
"split_audit_sha256": split_audit_sha256,
|
|
2266
|
+
"interface_signature_sha256": interface_signature_sha256,
|
|
2267
|
+
"initial_context_sha256": initial_context_sha256,
|
|
2268
|
+
"environment_identity_sha256": environment_identity_sha256,
|
|
2269
|
+
"model_fingerprints_sha256": model_fingerprints_sha256,
|
|
2270
|
+
"controls_sha256": controls_sha256,
|
|
2271
|
+
"runtime_binding_sha256": runtime_binding_sha256,
|
|
2272
|
+
}
|
|
2273
|
+
|
|
2274
|
+
|
|
2275
|
+
def _runtime_binding_sha256(
|
|
2276
|
+
*,
|
|
2277
|
+
controls: Mapping[str, Any],
|
|
2278
|
+
split_audit_sha256: str,
|
|
2279
|
+
interface_signature_sha256: str,
|
|
2280
|
+
initial_context_sha256: str,
|
|
2281
|
+
environment_identity_sha256: str,
|
|
2282
|
+
model_fingerprints_sha256: str,
|
|
2283
|
+
source_tree: str,
|
|
2284
|
+
source_manifest_sha256: str,
|
|
2285
|
+
semantic_patch_manifest_sha256: str,
|
|
2286
|
+
) -> str:
|
|
2287
|
+
return _content_hash(
|
|
2288
|
+
{
|
|
2289
|
+
"schema": "agentinputlab.mce.runtime-binding.v2",
|
|
2290
|
+
"source_commit": UPSTREAM_COMMIT,
|
|
2291
|
+
"source_tree": source_tree,
|
|
2292
|
+
"source_manifest_sha256": source_manifest_sha256,
|
|
2293
|
+
"semantic_patch_manifest_sha256": semantic_patch_manifest_sha256,
|
|
2294
|
+
"split_audit_sha256": split_audit_sha256,
|
|
2295
|
+
"interface_signature_sha256": interface_signature_sha256,
|
|
2296
|
+
"initial_context_sha256": initial_context_sha256,
|
|
2297
|
+
"environment_identity_sha256": environment_identity_sha256,
|
|
2298
|
+
"model_fingerprints_sha256": model_fingerprints_sha256,
|
|
2299
|
+
"controls_sha256": _content_hash(controls),
|
|
2300
|
+
}
|
|
2301
|
+
)
|
|
2302
|
+
|
|
2303
|
+
|
|
2304
|
+
def _validate_model_fingerprints(value: Mapping[str, Any]) -> None:
|
|
2305
|
+
if set(value) != {"target", "meta", "base"}:
|
|
2306
|
+
raise DriverError("CONFIG_INVALID", "MCE requires target/meta/base model identities")
|
|
2307
|
+
for role in ("target", "meta", "base"):
|
|
2308
|
+
model = _mapping(value, role)
|
|
2309
|
+
if set(model) != _MODEL_FINGERPRINT_FIELDS:
|
|
2310
|
+
raise DriverError(
|
|
2311
|
+
"CONFIG_INVALID",
|
|
2312
|
+
f"MCE {role} model identity fields drifted",
|
|
2313
|
+
)
|
|
2314
|
+
for key in ("provider", "model", "revision", "configuration_sha256"):
|
|
2315
|
+
_text(model, key)
|
|
2316
|
+
_require_sha256(model["configuration_sha256"], f"{role} configuration")
|
|
2317
|
+
|
|
2318
|
+
|
|
2319
|
+
def _contained_directory(path: Path, workspace: Path) -> Path:
|
|
2320
|
+
if path.is_symlink():
|
|
2321
|
+
raise DriverError("PATH_REJECTED", "MCE artifact root may not be a symlink")
|
|
2322
|
+
try:
|
|
2323
|
+
resolved = path.resolve(strict=True)
|
|
2324
|
+
resolved.relative_to(workspace)
|
|
2325
|
+
except (FileNotFoundError, ValueError) as exc:
|
|
2326
|
+
raise DriverError("PATH_REJECTED", "MCE artifact root escapes the workspace") from exc
|
|
2327
|
+
if not resolved.is_dir():
|
|
2328
|
+
raise DriverError("PATH_REJECTED", "MCE artifact root must be a directory")
|
|
2329
|
+
return resolved
|
|
2330
|
+
|
|
2331
|
+
|
|
2332
|
+
def _safe_source_file(root: Path, relative: Any) -> Path:
|
|
2333
|
+
if not isinstance(relative, str) or not relative or Path(relative).is_absolute():
|
|
2334
|
+
raise DriverError("PATH_REJECTED", "MCE source path is invalid")
|
|
2335
|
+
path = root / relative
|
|
2336
|
+
if path.is_symlink():
|
|
2337
|
+
raise DriverError("PATH_REJECTED", "MCE source symlinks are forbidden")
|
|
2338
|
+
try:
|
|
2339
|
+
resolved = path.resolve(strict=True)
|
|
2340
|
+
resolved.relative_to(root)
|
|
2341
|
+
except (FileNotFoundError, ValueError) as exc:
|
|
2342
|
+
raise DriverError("PATH_REJECTED", "MCE source path escapes or is missing") from exc
|
|
2343
|
+
if not resolved.is_file():
|
|
2344
|
+
raise DriverError("PATH_REJECTED", "MCE source path must be a file")
|
|
2345
|
+
return resolved
|
|
2346
|
+
|
|
2347
|
+
|
|
2348
|
+
def _safe_artifact_file(root: Path, relative: str) -> Path:
|
|
2349
|
+
if not _allowed_artifact_path(relative):
|
|
2350
|
+
raise DriverError("ARTIFACT_INVALID", "MCE stored artifact path is invalid")
|
|
2351
|
+
path = root / relative
|
|
2352
|
+
if path.is_symlink():
|
|
2353
|
+
raise DriverError("ARTIFACT_INVALID", "MCE stored artifact may not be a symlink")
|
|
2354
|
+
try:
|
|
2355
|
+
resolved = path.resolve(strict=True)
|
|
2356
|
+
resolved.relative_to(root)
|
|
2357
|
+
except (FileNotFoundError, ValueError) as exc:
|
|
2358
|
+
raise DriverError("ARTIFACT_INVALID", "MCE stored artifact escapes its root") from exc
|
|
2359
|
+
return resolved
|
|
2360
|
+
|
|
2361
|
+
|
|
2362
|
+
def _allowed_artifact_path(relative: str) -> bool:
|
|
2363
|
+
parsed = PurePosixPath(relative)
|
|
2364
|
+
if parsed.is_absolute() or any(part in {"", ".", ".."} for part in parsed.parts):
|
|
2365
|
+
return False
|
|
2366
|
+
return relative in _ALLOWED_ARTIFACT_FILES or relative.startswith(_ALLOWED_ARTIFACT_PREFIXES)
|
|
2367
|
+
|
|
2368
|
+
|
|
2369
|
+
def _paths_overlap(first: Path, second: Path) -> bool:
|
|
2370
|
+
try:
|
|
2371
|
+
first.relative_to(second)
|
|
2372
|
+
return True
|
|
2373
|
+
except ValueError:
|
|
2374
|
+
pass
|
|
2375
|
+
try:
|
|
2376
|
+
second.relative_to(first)
|
|
2377
|
+
return True
|
|
2378
|
+
except ValueError:
|
|
2379
|
+
return False
|
|
2380
|
+
|
|
2381
|
+
|
|
2382
|
+
def _git(root: Path, *args: str) -> str:
|
|
2383
|
+
try:
|
|
2384
|
+
completed = subprocess.run(
|
|
2385
|
+
["git", "-C", str(root), *args],
|
|
2386
|
+
check=False,
|
|
2387
|
+
capture_output=True,
|
|
2388
|
+
text=True,
|
|
2389
|
+
timeout=10,
|
|
2390
|
+
env={"PATH": os.environ.get("PATH", "")},
|
|
2391
|
+
)
|
|
2392
|
+
except (OSError, subprocess.SubprocessError) as exc:
|
|
2393
|
+
raise DriverError("SOURCE_MISMATCH", "MCE Git verification failed") from exc
|
|
2394
|
+
if completed.returncode:
|
|
2395
|
+
raise DriverError("SOURCE_MISMATCH", "MCE Git verification failed")
|
|
2396
|
+
return completed.stdout.strip()
|
|
2397
|
+
|
|
2398
|
+
|
|
2399
|
+
def _load_json(path: Path, *, code: str = "MANIFEST_INVALID") -> Mapping[str, Any]:
|
|
2400
|
+
try:
|
|
2401
|
+
value = json.loads(path.read_text(encoding="utf-8"))
|
|
2402
|
+
except (OSError, UnicodeDecodeError, json.JSONDecodeError) as exc:
|
|
2403
|
+
raise DriverError(code, "MCE JSON manifest is unreadable") from exc
|
|
2404
|
+
if not isinstance(value, Mapping):
|
|
2405
|
+
raise DriverError(code, "MCE JSON manifest must be an object")
|
|
2406
|
+
return value
|
|
2407
|
+
|
|
2408
|
+
|
|
2409
|
+
def _canonical_mapping(value: Any, label: str) -> Mapping[str, Any]:
|
|
2410
|
+
if not isinstance(value, Mapping):
|
|
2411
|
+
raise DriverError("CONFIG_INVALID", f"MCE {label} must be a mapping")
|
|
2412
|
+
try:
|
|
2413
|
+
result = json.loads(_canonical_json(value))
|
|
2414
|
+
except (TypeError, ValueError) as exc:
|
|
2415
|
+
raise DriverError("CONFIG_INVALID", f"MCE {label} is not canonical") from exc
|
|
2416
|
+
if not isinstance(result, Mapping) or not result:
|
|
2417
|
+
raise DriverError("CONFIG_INVALID", f"MCE {label} must not be empty")
|
|
2418
|
+
return result
|
|
2419
|
+
|
|
2420
|
+
|
|
2421
|
+
def _mapping(value: Mapping[str, Any], key: str) -> Mapping[str, Any]:
|
|
2422
|
+
result = value.get(key)
|
|
2423
|
+
if not isinstance(result, Mapping):
|
|
2424
|
+
raise DriverError("REQUEST_INVALID", f"MCE {key} must be a mapping")
|
|
2425
|
+
return result
|
|
2426
|
+
|
|
2427
|
+
|
|
2428
|
+
def _text(value: Mapping[str, Any], key: str) -> str:
|
|
2429
|
+
result = value.get(key)
|
|
2430
|
+
if not isinstance(result, str) or not result.strip():
|
|
2431
|
+
raise DriverError("REQUEST_INVALID", f"MCE {key} must be non-empty text")
|
|
2432
|
+
return result
|
|
2433
|
+
|
|
2434
|
+
|
|
2435
|
+
def _positive_int(value: Mapping[str, Any], key: str) -> int:
|
|
2436
|
+
return _positive_int_value(value.get(key), key)
|
|
2437
|
+
|
|
2438
|
+
|
|
2439
|
+
def _positive_int_value(value: Any, label: str) -> int:
|
|
2440
|
+
if isinstance(value, bool) or not isinstance(value, int) or value < 1:
|
|
2441
|
+
raise DriverError("REQUEST_INVALID", f"MCE {label} must be a positive integer")
|
|
2442
|
+
return value
|
|
2443
|
+
|
|
2444
|
+
|
|
2445
|
+
def _nonnegative_int(value: Mapping[str, Any], key: str) -> int:
|
|
2446
|
+
return _nonnegative_int_value(value.get(key), key)
|
|
2447
|
+
|
|
2448
|
+
|
|
2449
|
+
def _nonnegative_int_value(value: Any, label: str) -> int:
|
|
2450
|
+
if isinstance(value, bool) or not isinstance(value, int) or value < 0:
|
|
2451
|
+
raise DriverError("REQUEST_INVALID", f"MCE {label} must be non-negative")
|
|
2452
|
+
return value
|
|
2453
|
+
|
|
2454
|
+
|
|
2455
|
+
def derive_provider_subcall_seed(logical_seed: int, stable_subcall_index: int) -> int:
|
|
2456
|
+
"""Derive the manager's provider seed from a logical-call namespace."""
|
|
2457
|
+
|
|
2458
|
+
base = _nonnegative_int_value(logical_seed, "logical_seed")
|
|
2459
|
+
index = _nonnegative_int_value(stable_subcall_index, "stable_subcall_index")
|
|
2460
|
+
payload = {
|
|
2461
|
+
"mode": PROVIDER_SUBCALL_SEED_MODE,
|
|
2462
|
+
"logical_seed": base,
|
|
2463
|
+
"stable_subcall_index": index,
|
|
2464
|
+
}
|
|
2465
|
+
digest = hashlib.sha256(_canonical_json(payload).encode("utf-8")).digest()
|
|
2466
|
+
return int.from_bytes(digest[:8], "big") & ((1 << 63) - 1)
|
|
2467
|
+
|
|
2468
|
+
|
|
2469
|
+
def _nonnegative_float_value(value: Any, label: str) -> float:
|
|
2470
|
+
result = _finite(value, f"MCE {label}")
|
|
2471
|
+
if result < 0:
|
|
2472
|
+
raise DriverError("USAGE_INVALID", f"MCE {label} must be non-negative")
|
|
2473
|
+
return result
|
|
2474
|
+
|
|
2475
|
+
|
|
2476
|
+
def _finite(value: Any, label: str) -> float:
|
|
2477
|
+
if (
|
|
2478
|
+
isinstance(value, bool)
|
|
2479
|
+
or not isinstance(value, (int, float))
|
|
2480
|
+
or not math.isfinite(float(value))
|
|
2481
|
+
):
|
|
2482
|
+
raise DriverError("RUNTIME_INVALID", f"{label} must be finite", consumed=True)
|
|
2483
|
+
return float(value)
|
|
2484
|
+
|
|
2485
|
+
|
|
2486
|
+
def _strict_bool_value(value: Any, label: str) -> bool:
|
|
2487
|
+
if not isinstance(value, bool):
|
|
2488
|
+
raise DriverError("CONFIG_INVALID", f"MCE {label} must be boolean")
|
|
2489
|
+
return value
|
|
2490
|
+
|
|
2491
|
+
|
|
2492
|
+
def _require_sha1(value: Any, label: str) -> str:
|
|
2493
|
+
if (
|
|
2494
|
+
not isinstance(value, str)
|
|
2495
|
+
or len(value) != 40
|
|
2496
|
+
or any(character not in _HEX for character in value)
|
|
2497
|
+
):
|
|
2498
|
+
raise DriverError("MANIFEST_INVALID", f"MCE {label} must be a Git tree SHA-1")
|
|
2499
|
+
return value
|
|
2500
|
+
|
|
2501
|
+
|
|
2502
|
+
def _require_sha256(value: Any, label: str) -> str:
|
|
2503
|
+
if (
|
|
2504
|
+
not isinstance(value, str)
|
|
2505
|
+
or len(value) != 64
|
|
2506
|
+
or any(character not in _HEX for character in value)
|
|
2507
|
+
):
|
|
2508
|
+
raise DriverError("CONFIG_INVALID", f"MCE {label} must be a SHA-256 digest")
|
|
2509
|
+
return value
|
|
2510
|
+
|
|
2511
|
+
|
|
2512
|
+
def _sha256_file(path: Path) -> str:
|
|
2513
|
+
digest = hashlib.sha256()
|
|
2514
|
+
with path.open("rb") as handle:
|
|
2515
|
+
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
|
|
2516
|
+
digest.update(chunk)
|
|
2517
|
+
return digest.hexdigest()
|
|
2518
|
+
|
|
2519
|
+
|
|
2520
|
+
def _canonical_json(value: Any) -> str:
|
|
2521
|
+
return json.dumps(
|
|
2522
|
+
value,
|
|
2523
|
+
ensure_ascii=False,
|
|
2524
|
+
sort_keys=True,
|
|
2525
|
+
separators=(",", ":"),
|
|
2526
|
+
allow_nan=False,
|
|
2527
|
+
)
|
|
2528
|
+
|
|
2529
|
+
|
|
2530
|
+
def _content_hash(value: Any) -> str:
|
|
2531
|
+
return hashlib.sha256(_canonical_json(value).encode("utf-8")).hexdigest()
|
|
2532
|
+
|
|
2533
|
+
|
|
2534
|
+
EMPTY_SKILL_SHA256 = _content_hash("")
|
|
2535
|
+
|
|
2536
|
+
|
|
2537
|
+
def serve_jsonl(
|
|
2538
|
+
driver: MCEWorkerDriver,
|
|
2539
|
+
input_stream: TextIO,
|
|
2540
|
+
output_stream: TextIO,
|
|
2541
|
+
) -> int:
|
|
2542
|
+
"""Serve an operator-constructed, attested driver over strict JSONL."""
|
|
2543
|
+
|
|
2544
|
+
for raw_line in input_stream:
|
|
2545
|
+
if not raw_line.strip():
|
|
2546
|
+
continue
|
|
2547
|
+
try:
|
|
2548
|
+
if len(raw_line.encode("utf-8")) > _MAX_JSONL_BYTES:
|
|
2549
|
+
raise DriverError("REQUEST_TOO_LARGE", "MCE JSONL request is too large")
|
|
2550
|
+
request = json.loads(raw_line)
|
|
2551
|
+
if not isinstance(request, Mapping):
|
|
2552
|
+
raise DriverError("REQUEST_INVALID", "MCE JSONL request must be an object")
|
|
2553
|
+
response = driver.handle(request)
|
|
2554
|
+
except json.JSONDecodeError:
|
|
2555
|
+
response = {
|
|
2556
|
+
"status": "error",
|
|
2557
|
+
"failure_code": "REQUEST_INVALID",
|
|
2558
|
+
"message": "MCE JSONL request is not valid JSON",
|
|
2559
|
+
"consumed": False,
|
|
2560
|
+
}
|
|
2561
|
+
except DriverError as exc:
|
|
2562
|
+
response = {
|
|
2563
|
+
"status": "error",
|
|
2564
|
+
"failure_code": exc.code,
|
|
2565
|
+
"message": exc.public_message,
|
|
2566
|
+
"consumed": exc.consumed,
|
|
2567
|
+
}
|
|
2568
|
+
if exc.usage:
|
|
2569
|
+
response["usage"] = exc.usage
|
|
2570
|
+
output_stream.write(_canonical_json(response) + "\n")
|
|
2571
|
+
output_stream.flush()
|
|
2572
|
+
return 0
|
|
2573
|
+
|
|
2574
|
+
|
|
2575
|
+
def main() -> int:
|
|
2576
|
+
print(
|
|
2577
|
+
"Instantiate MCEWorkerDriver inside an attested sidecar; "
|
|
2578
|
+
"fixture mode is disabled by default.",
|
|
2579
|
+
file=sys.stderr,
|
|
2580
|
+
)
|
|
2581
|
+
return 2
|
|
2582
|
+
|
|
2583
|
+
|
|
2584
|
+
if __name__ == "__main__": # pragma: no cover
|
|
2585
|
+
raise SystemExit(main())
|