From 552d7f228c096c0e808aa28e92d8d9b476e4a456 Mon Sep 17 00:00:00 2001 From: Brad Edwards Date: Mon, 10 Aug 2026 05:51:15 +0200 Subject: [PATCH 01/14] feat(cyberbattlesim): add baseline reproduction harness --- README.md | 7 + docs/cyberbattlesim-baseline-reproduction.md | 115 + docs/cyberbattlesim-researcher-command.md | 6 +- ...tlesim-baseline-reproduction-guardrails.md | 242 ++ docs/index.md | 2 + .../docs/golden-readiness-checklist.md | 28 + .../pack.content-manifest.json | 6 +- mkdocs.yml | 2 + noxfile.py | 2 +- src/raes_adapters/cli.py | 2 +- .../cyberbattlesim/backend/driver.py | 141 +- .../cyberbattlesim/backend/source.py | 167 ++ .../cyberbattlesim/qualification.json | 12 +- .../cyberbattlesim/reproduction.py | 2630 +++++++++++++++++ tests/test_cyberbattlesim_qualification.py | 6 +- tests/test_cyberbattlesim_reproduction.py | 291 ++ tests/test_cyberbattlesim_researcher_cli.py | 2 +- 17 files changed, 3536 insertions(+), 125 deletions(-) create mode 100644 docs/cyberbattlesim-baseline-reproduction.md create mode 100644 docs/decisions/cyberbattlesim-baseline-reproduction-guardrails.md create mode 100644 src/raes_adapters/cyberbattlesim/backend/source.py create mode 100644 src/raes_adapters/cyberbattlesim/reproduction.py create mode 100644 tests/test_cyberbattlesim_reproduction.py diff --git a/README.md b/README.md index 1667b95..001c00a 100644 --- a/README.md +++ b/README.md @@ -244,6 +244,13 @@ The [backend architecture guardrails](docs/decisions/cyberbattlesim-backend-guar record the component ownership, failure hygiene, capability claims, and acceptance-test mapping. +Issue [#30](https://github.com/OpenRAE/adapters/issues/30) adds the frozen +[source-native/RAES baseline reproduction](docs/cyberbattlesim-baseline-reproduction.md). +Its content-addressed bundle preserves all 20 scheduled terminal attempts, +offline-recomputable aggregates, six separately cited tiers, and the known +stochastic, topology, evaluator, metric, and packaging limitations for the +OpenRAE/research#14 and #20 consumers. + Issue [#28](https://github.com/OpenRAE/adapters/issues/28) composes that runtime target with the published RAES conformance report and adapter-local source-protocol probes. The backend conformance result remains the exact diff --git a/docs/cyberbattlesim-baseline-reproduction.md b/docs/cyberbattlesim-baseline-reproduction.md new file mode 100644 index 0000000..b73cf70 --- /dev/null +++ b/docs/cyberbattlesim-baseline-reproduction.md @@ -0,0 +1,115 @@ +# CyberBattleSim baseline reproduction + +Issue [OpenRAE/adapters#30](https://github.com/OpenRAE/adapters/issues/30) +collects the qualified `CyberBattleChain-v0` credential-cache baseline through +two deliberately different lanes: the unmodified upstream +`epsilon_greedy_search` evaluator and the RAES-mediated researcher path. The +result is a content-addressed public data bundle for OpenRAE/research#14 and +OpenRAE/research#20, not a deterministic-replay or outcome-equivalence claim. + +## Required apparatus + +Use CPython 3.12 with the repository's locked `cyberbattlesim` extra, plus a +wheel built from Microsoft CyberBattleSim commit +`854d6966607fb68645651f55b0f97221bd293e0d`. The installed wheel must pass the +adapter's complete-root, selected-file, version, dependency-artifact, symlink, +and module-origin admission checks. A directory or editable simulator install +is rejected. + +The experiment needs no GPU, model weights, external dataset, or network after +source, wheel, and dependency acquisition. Four x86-64 vCPUs, 16 GiB RAM, and +20 GiB of free disk are ample. Collection records logical CPU count, physical +memory, operating system, Python, installed distributions, source identity, +wheel digest, and environment-pack digest without retaining a host name, IP, +provider identifier, path, or provider log. + +## Frozen sequence + +Run from an isolated checkout root. Every output is exclusive and must be a new +invocation-relative directory. + +```bash +mkdir reproduction-work +python -m raes_adapters.cyberbattlesim.reproduction declare \ + --output reproduction-work/declaration +python -m raes_adapters.cyberbattlesim.reproduction native \ + --declaration reproduction-work/declaration \ + --output reproduction-work/native-oracle +``` + +The declaration preallocates ten source-native and ten RAES-mediated run and +attempt IDs, with retry budget zero. It embeds a validated RAES +`ExperimentStudyModel`, references the published task/spec, pins all apparatus +and runner bytes, declares actual random-stream dispositions, and fixes the +aggregation, missingness, bootstrap, tolerance, and six-tier policies. The +native command invokes the exact upstream evaluator once for its ten-episode +schedule. Native reward vectors exist only in private scratch; portable rows +retain cumulative reward, steps, availability, and a source-backed terminal +cause. + +Every stage also writes `bench-notes.json`. Each closed note has an RFC 3339 +UTC timestamp with millisecond precision, phase, severity, stable event code, +concise observation, disposition, and relative evidence references. Collection +writes start and terminalization observations as they happen. Failures remain +timestamped and visible, but exception text, raw native output, host paths, +credentials, and provider identifiers never become notes. The issue thread is +the timestamped record for apparatus and development observations that precede +the frozen declaration. + +Review and commit the unchanged declaration, completed `protocol.json`, native +rows, and oracle before any mediated attempt. If those bytes or any declared +artifact change, discard the unrun schedule and start a new declaration. + +Then collect the mediated lane against the exact admitted pack: + +```bash +python -m raes_adapters.cyberbattlesim.reproduction mediated \ + --oracle reproduction-work/native-oracle \ + --pack environments/cyberbattlesim-chain \ + --output reproduction-work/mediated +``` + +Each mediated attempt invokes the installed researcher command independently, +passes the exact pack/scenario/task/spec/participant joins, admits every policy +proposal through RAES, evaluates through the adapter, verifies cleanup, seals +its portable evidence, and continues to terminalize later IDs after a failed +attempt. The mediated evaluator currently retains cumulative reward and step +count but not the availability series or a specific source terminal cause; +those metrics remain unavailable and weaken the outcome/evaluation tier. + +Finally use the full `declaration_sha256` from the completed protocol as the +output directory name: + +```bash +python -m raes_adapters.cyberbattlesim.reproduction finalize \ + --oracle reproduction-work/native-oracle \ + --mediated reproduction-work/mediated \ + --output packages/cyberbattlesim_adapter/reproduction/ +python -m raes_adapters.cyberbattlesim.reproduction verify \ + --bundle packages/cyberbattlesim_adapter/reproduction/ +``` + +`finalize` assembles a new root once, recomputes lane summaries and 10,000 +counter-addressed SHA-256 percentile-bootstrap resamples, evaluates the six +predeclared tiers, validates digest-bound JSON-Pointer citations, scans the +allowlisted public projection, retains the timestamped verification disposition, +and writes `inventory.json` last. `verify` is a pure offline read: it does not +import CyberBattleSim, contact a network, mutate the bench notes, or read +credentials, caches, provider logs, or private scratch. + +## Interpreting the bundle + +All 20 scheduled attempts stay in the denominator and end `valid`, `invalid`, +`failed`, or `excluded`. Missing metrics are never imputed. Numeric bounded +reproduction requires the complete 95% mean-difference interval to fit inside +the frozen band: steps ±60, cumulative reward ±500, mean availability ±0.05, +and terminal-cause proportion ±0.10. Criteria are not widened after observing +the native oracle. + +The six tier results are separate: authored-source, contract, +execution-control, state-observation, outcome-evaluation, and disclosure. A +passing integrity or contract tier cannot erase stochastic, topology, +observation, evaluator-path, metric-availability, packaging, or upstream +limitations. The bundle makes no claim of deterministic replay, exact state or +observation equivalence, cross-simulator equality, agent ranking, benchmark +comparability, outcome equivalence, or general scientific reproducibility. diff --git a/docs/cyberbattlesim-researcher-command.md b/docs/cyberbattlesim-researcher-command.md index 3fd69c8..ea30185 100644 --- a/docs/cyberbattlesim-researcher-command.md +++ b/docs/cyberbattlesim-researcher-command.md @@ -46,7 +46,7 @@ raes-pack-release check --pack cyberbattlesim-chain The admitted pack content digest is: ```text -sha256:08ae7e997b50bb396c290c4a5537a65e9e7d8b8e6abc97d1ff65022c4258e417 +sha256:66493882579d5cba87248c5722782ff5ded5f0d7423f4e559f15bfb61712a905 ``` An asset with different bytes is rejected even if it is otherwise a valid @@ -59,7 +59,7 @@ From the directory containing the extracted pack: ```bash raes-adapters validate --backend cyberbattlesim-chain --mode smoke \ --pack cyberbattlesim-chain \ - --pack-digest sha256:08ae7e997b50bb396c290c4a5537a65e9e7d8b8e6abc97d1ff65022c4258e417 \ + --pack-digest sha256:66493882579d5cba87248c5722782ff5ded5f0d7423f4e559f15bfb61712a905 \ --scenario sdl/cyberbattlesim-chain.sdl.yaml \ --scenario-digest sha256:9d696ea7fa23a1e7cf4c1cbc145a7989370dc4e9afff2cd5a17d6d1af887b528 \ --experiment experiment/cyberbattlesim-chain.spec.exp.json \ @@ -82,7 +82,7 @@ Use the same arguments with `run`, plus an unused invocation-relative output: ```bash raes-adapters run --backend cyberbattlesim-chain --mode smoke \ --pack cyberbattlesim-chain \ - --pack-digest sha256:08ae7e997b50bb396c290c4a5537a65e9e7d8b8e6abc97d1ff65022c4258e417 \ + --pack-digest sha256:66493882579d5cba87248c5722782ff5ded5f0d7423f4e559f15bfb61712a905 \ --scenario sdl/cyberbattlesim-chain.sdl.yaml \ --scenario-digest sha256:9d696ea7fa23a1e7cf4c1cbc145a7989370dc4e9afff2cd5a17d6d1af887b528 \ --experiment experiment/cyberbattlesim-chain.spec.exp.json \ diff --git a/docs/decisions/cyberbattlesim-baseline-reproduction-guardrails.md b/docs/decisions/cyberbattlesim-baseline-reproduction-guardrails.md new file mode 100644 index 0000000..8d6564d --- /dev/null +++ b/docs/decisions/cyberbattlesim-baseline-reproduction-guardrails.md @@ -0,0 +1,242 @@ +# CyberBattleSim baseline-reproduction guardrails + +GitHub issue #30 is the authority for this deliverable. This note fixes the +repository-wide boundaries for the frozen source-native/RAES comparison bundle. +It defines no RAES contract, scientific equivalence vocabulary, simulator +profile, or implementation plan. + +## One frozen study artifact, two execution lanes + +The issue-mandated +`packages/cyberbattlesim_adapter/reproduction//` coordinate is +a checked-in, consumer-facing **data** boundary for OpenRAE/research#14 and #20. +It is not a Python package, import root, distribution, environment pack, +runtime store, or second adapter. Do not add `pyproject.toml`, `__init__.py`, a +lockfile, executable source, or native simulator content beneath that path. +The one `raes-adapters` distribution and all executable CyberBattleSim behavior +remain under `src/raes_adapters/cyberbattlesim`; the external environment pack +remains under `environments/cyberbattlesim-chain`. + +The source-native and RAES-mediated lanes share only immutable selection, +metric definitions, attempt identities, terminal-disposition rules, and +post-run analysis. Their execution paths remain deliberately distinct: + +- The source-native lane executes the pinned + `notebooks/notebook_withdefender.py` selection through the pinned upstream + `epsilon_greedy_search` path before adapter normalization. It must first + reuse the complete source/distribution/tree/module-origin admission checks. + It must not call `CyberBattleSimDriver`, RAES action admission, the adapter + evaluator, or a copied/reimplemented notebook loop and call that native. +- The mediated lane uses the exact admitted external pack and participant + artifacts, `CyberBattleSimDriver`, `create_cyberbattlesim_target()`, + `RuntimeManager`, public participant action admission, the adapter evaluator, + and verified cleanup. It must not call the upstream evaluator directly, + inject a fake driver, or import native state around the target boundary. + +Common post-processing reads retained portable evidence from both lanes. It +must not compare in-memory native objects, use the native lane as an alternate +adapter implementation, or force the two lanes through one ambiguous generic +"runner" abstraction. + +## Freeze and identity boundary + +`protocol.json` has two integrity domains. Its declaration fixes the condition +matrix, source and apparatus selections, evaluator, metric definitions, run +allocation, seeds and actual binding dispositions, reset/order/budget/stop and +exclusion rules, aggregation and 95% uncertainty method, missing-data policy, +tolerances, and exact/bounded/failed criteria before source execution. Its +oracle section records the source-native results without changing that +declaration. The declaration digest is retained before the native lane; the +completed file and oracle are byte-frozen in version control before the first +mediated attempt, and every mediated attempt binds their digest. Neither +criteria nor source outcomes may be edited after mediated evidence exists. + +The semantic owners inside that file remain the published +`ExperimentTaskModel`, `ExperimentSpecModel`, and `ExperimentStudyModel` +surfaces. In particular, use the study run-allocation and analysis-plan fields +for conditions, replication, statistical method, uncertainty, multiplicity, +stopping, and missingness, and use the task's evaluation protocol and metric +definitions for measured constructs. `protocol.json` is a thin issue-local +index plus the comparison/oracle fields issue #30 explicitly requires; it must +reference the canonical task/spec/pack artifacts by id and digest rather than +copy their contents or define another experiment model or JSON Schema. + +`source-ledger.json` is likewise a bundle-local integrity index, not a second +mapping ledger. It cites `qualification.json`, `public-protocol.md`, +`mapping/source-ledger.jsonl`, `mapping/loss-disclosures.md`, the selected +notebook/source files, external pack, participant artifacts, adapter version, +and every compatibility patch by immutable identity and digest. Existing loss +and exclusion meanings stay with their canonical owners. A new patch must first +become reviewed qualification evidence with its base and resulting identities; +it cannot appear only in setup code or the reproduction bundle. + +`` names an immutable study revision, not a mutable branch, +working tree, date alias, source tag alone, or "latest" directory. An admitted +bundle root is never overwritten, resumed, appended, or reused. A changed +protocol, source, pack, patch, analysis method, or rerun is a new revision with +new attempt identities. + +## Reuse the existing owners + +| Concern | Canonical incumbent and required boundary | +| --- | --- | +| Selected source and public protocol | `load_qualification()`, `read_public_protocol()`, `CYBERBATTLE_CHAIN`, `EvidenceSelection`, the qualified source-file/tree/runtime-artifact identities, and the package-local source/loss ledgers. Read and join them; do not repeat source constants in a study runner. | +| Source admission | `verify_selected_cyberbattlesim_source()` and `_source_admission`'s distribution, direct-artifact, complete-root, selected-file, symlink, version, and module-origin checks. Both real lanes fail closed before native import; a missing/mismatched source is retained as a terminal failure, never a fake-driver fallback. | +| Pack and authored contracts | `raes_env_packs.validate_pack()`, `verify_pack_content_digest()`, `raes-pack-release check`, confined `_pack_child()`, strict duplicate-key JSON loading, bounded RAES SDL parsing/instantiation/digest, and the exact external task/spec/participant artifacts. Do not execute acquired pack code or trust filenames without bytes. | +| Experiment design and allocation | `ExperimentTaskModel`, `ExperimentSpecModel`, `ExperimentStudyModel`, `ExperimentRunAllocationPlanModel`, `ExperimentAnalysisPlanModel`, and their cross-artifact validators. Do not create a reproduction protocol DTO, alternate metric catalog, or prose-only tolerance table. | +| Scheduled trial identity | RAES `AdmittedTrialPlanModel` / `AdmittedTrialEntryModel`, their seal/digest validators, `TrialCoordinateModel`, and admitted execution-control/cleanup-plan fields where the scheduled study is representable. Preallocate unique run coordinates and distinguish a logical run from every effect-capable attempt. | +| Attempt and run provenance | `TrialRunProvenanceModel`, `TrialExecutionAttemptReferenceModel`, `ExperimentRunModel` statuses, `ExperimentInvalidationModel`, operation references, and the published cleanup receipt on the mediated path. The mandated valid/invalid/failed/excluded bundle disposition is a thin terminal index over those owners, not another run or receipt model. Never turn an exclusion into a success or omit it from the scheduled inventory. | +| Runtime and participant authority | `RunControls`, `execute_episode()`, `create_cyberbattlesim_target()`, `RuntimeManager`, `RuntimeTarget`, the four backend components, public participant admission/result/history validation, and `RuntimeManager.destroy()`. Reuse or narrowly extract existing admission/artifact mechanics; do not call private RAES backend methods or copy the researcher workflow into a second adapter. | +| Evidence and measures | `ExperimentCaptureSpecModel`, `ExperimentEvidenceRecordModel`, `ExperimentDerivedMeasureModel`, `ExperimentArtifactRefModel`, `_experiment_evidence.py`, `CyberBattleSimEvaluator`, and task metric ids. Retain model-validated per-run projections; no local observation/reward/metric DTO and no native fallback payload. | +| Conformance and disclosures | `run_cyberbattlesim_conformance()`, `cyberbattlesim_backend_conformance_payload()`, source-protocol diagnostics, manifest capability-evidence closure, declared weaknesses, scenario-ledger validation, and the existing non-claims. Conformance is cited evidence, not a study run or outcome-equivalence result. | +| Diagnostics and redaction | RAES `Diagnostic` / `DiagnosticModel` / `diagnostic_model()`, `ApplyResult`, canonical model/report projections, `redact_native_value()`, and `bounded_context_label()`. Use stable JSON Pointer addresses and bounded input-free messages; add no exception or diagnostic hierarchy. | +| Persistence and integrity | Exclusive invocation-relative output reservation, `atomic_write_json_artifact()`, relative artifact references, `_seal_inventory()`-style size/hash inventory written last, and existing no-clobber behavior. The checked-in bundle is archival experiment output, not `ControlPlaneStore` runtime state or a new evidence repository service. | +| Verification and workflow | Existing CyberBattleSim qualification, ledger, backend, conformance, researcher-command, hostile-leak, and clean-wheel tests; the one `pyproject.toml`/`uv.lock`; `_verification_envs()`, `_distributions()`, strict docs/policy, and canonical `nox -s verify`. Real native evidence remains a reviewed manual/readiness lane; do not add a network-dependent PR test or unenforced workflow. | + +Published models should carry every fact they can express. The four mandated +bundle projections that RAES does not currently own remain narrowly +issue-local: + +- `protocol.json` adds the source/mediated pairing, frozen oracle values, and + predeclared exact/bounded/failed comparison criteria around canonical + experiment references; +- each `runs/` terminal row adds only lane plus + valid/invalid/failed/excluded disposition and references to the applicable + RAES run/evidence/attempt/cleanup artifacts; +- `aggregates.json` adds structured point estimates and 95% interval endpoints + computed from referenced per-run measures, because a prose uncertainty field + is not a recomputable interval; and +- `tiers.json` fixes exactly the six issue-named tiers and their + pass/fail/weakened result with relative, digest-bound, JSON-Pointer evidence + citations. These labels are not a backend profile, RAES validation profile, + capability table, or reusable equivalence vocabulary. + +Use a small closed backend-local validator for only those issue-mandated gaps: +reject duplicate/unknown fields, non-finite numbers, duplicate identities, +unsafe relative paths, missing digests, unresolved citations, undeclared +metrics, nonterminal attempts, post-freeze drift, and aggregate/tier results +that cannot be recomputed. Do not publish Pydantic models or JSON Schemas for +them, put them in `raes_adapters.base`, or duplicate validation already owned by +RAES, the pack validator, qualification, or the source ledger. + +## Attempts, aggregation, and tier claims + +All logical run and attempt identities are allocated before the applicable +lane starts. A retry is a new effect-capable attempt id linked to the same +logical run only when the frozen retry policy permits it; an id is never reused +after failure, exclusion, cancellation, timeout, cleanup failure, or process +failure. The accepted bundle contains no scheduled/running/unknown residue. +Every row ends valid, invalid, failed, or excluded, cites bounded diagnostics +and cleanup evidence where applicable, and remains visible to denominator and +missing-data calculations. + +The current researcher batch loop is not sufficient by itself: it stops at the +first exception and retains only a batch-level failure. Reproduction must keep +the same admission/execution/sealing mechanics while terminalizing each +predeclared attempt and continuing or stopping exactly as the frozen policy +says. A cleanup, evidence-validation, persistence, inventory, or terminalization +failure is not a valid run. An interrupted, unsealed root is not publishable and +must never be mistaken for a resumable successful bundle. + +Aggregation is a pure read of retained terminal rows and model-validated +per-run evidence. It uses the frozen metric, inclusion, missingness, +aggregation, and 95% interval methods; records all scheduled, valid, invalid, +failed, and excluded counts; and never reads simulator source, imports the +adapter, uses wall-clock order as data, or silently drops a bad run. Clean +recomputation verifies every content digest and contract join, recomputes +`aggregates.json` and `tiers.json` byte-for-byte or semantically under an +explicit canonicalization, and needs no network, native source, credential, +provider log, or private artifact. + +Tier results do not collapse into one `passed` boolean. A tier may pass only +the predeclared facts and evidence within its scope. A known loss, unsupported +RAES fact, missing source artifact, control mismatch, or unavailable metric +becomes failed or weakened according to the frozen criteria; it is not repaired +by widening a tolerance after viewing outcomes. Citations point to retained +artifact paths, SHA-256 digests, and JSON Pointers, never raw source logs or an +uncited prose assertion. + +## Cross-cutting security and whole-repository path + +| Layer the intended design passes | Required treatment | +| --- | --- | +| Authentication and authorization | The reproducer is a local operator command with no route, daemon, remote caller, or new authentication surface. Source-native execution is oracle collection only, not participant authorization. Mediated actions still cross the compiled participant behavior, exact manifest/selection/configuration and exposure-policy joins, and public RAES admission. Any later HTTP surface must reuse `create_control_plane_app()` with `ControlPlaneSecurityConfig.strict_defaults`, verified identity, role/target authorization, request-size limits, denial audit, and redacted errors. | +| Secrets and disclosure | The public protocol needs no credential input and must not read a repository/user secret store, `.env`, provider log, or ambient token. Learned CyberBattleSim credentials, native observations, action coordinates/masks, hidden graph/evaluator truth, reward vectors, random state, stdout/stderr, object representations, paths, argv/environment mappings, exceptions, and tracebacks remain private. Hashing any of them does not make them publishable. Final publication is allowlist-based and reviewed. | +| CLI and configuration shape | Extend only the existing closed command/backend selection or a backend-local module entry point; accept no arbitrary import, evaluator class, source path, corpus/profile root, plugin, URL, environment override, or native field selector. Reuse safe run-id rules, exact mode/cardinality checks, strict JSON, confined pack-child resolution, pack digest, scenario/task/spec/participant joins, and source admission before output/native execution. | +| Source-native shape checks | Verify the qualified artifact before import, then validate only the pinned reset/step/evaluator return shapes and bounded scalar/category/series projections. Native records are not made portable by recursive sanitization. An unexpected shape or unsupported terminal/availability fact is a bounded failed/weakened result, not guessed data. | +| RAES/runtime validation | The mediated path passes RAES SDL/experiment/participant closed models, pack validation, `RuntimeTarget` manifest/signature gates, `RuntimeManager` planning, `ApplyResult` and snapshot-transition validation, participant/action/history joins, evaluator/evidence models, and cleanup receipt validation. Native mutation followed by invalid projection is failure requiring cleanup. | +| Error envelopes | Expected source, parser, identity, control, execution, timeout, cleanup, projection, persistence, recomputation, and tier failures become validated RAES diagnostics with fixed codes/messages. Never serialize exception text/types from hostile native code, causes, locals, rejected Pydantic input, raw stdout/stderr, or traceback. The terminal bundle row references diagnostics and does not invent an error envelope. | +| OS/process exposure | Run from explicit isolated temporary working/home/cache directories with cleared `PYTHONPATH`, `PYTHONSAFEPATH=1`, no network after acquisition, no shell interpolation, explicit argument vectors, a small environment allowlist, timeouts, bounded control output, and native stdout/stderr redirected and discarded. Reuse the pattern in `sanitized_subprocess_env()` / `_run()` from the qualification tooling when process isolation is needed; never put secrets or native payloads in argv/environment. | +| Logging and observability | Portable observability is contract-validated evidence, terminal rows, bounded diagnostics, cleanup/operation references, aggregates, tiers, limitations, closed timestamped bench notes, and the final inventory. Each bench note uses an RFC 3339 UTC timestamp, phase, severity, stable event code, observation, disposition, and relative evidence references; start, failure, and terminalization events are written as they occur. Logs/terminal output are allowlisted to safe ids, counts, relative names, modes, and dispositions. Do not log plans, pack contents, actions, observations, rewards, paths, random state, exception text, or native process output. | +| Persistence and publication | Reserve a new confined root exclusively, reject files/directories/symlinks already present, publish validated JSON atomically, use fixed/safe child names and relative URIs, and write the content inventory last. Never overwrite, append, resume, auto-delete material failures, retain host paths, or treat a mutable cache/database as evidence. The repository's 500 KiB file gate and private-key/leak scans still apply to every checked-in member. | +| Repository workflow | Keep code/tests in the existing package/test/nox graph and preserve lazy base/extra isolation. The real source-native plus real mediated run updates the manual CyberBattleSim readiness protocol and passing record only after both identities and leak checks pass. If a new CI job ever becomes unavoidable, it must join `PR Gate`; issue #30 does not justify one by default. | + +## Extension seam + +The extension seam is one immutable backend-local reproduction selection: +frozen revision; source qualification and notebook/evaluator identity; external +pack/scenario/task/spec/participant identities; lane ids; admitted trial plan; +metric and analysis references; and comparison/tier policy. Execution harnesses +receive that selection and emit retained evidence; the recomputer receives only +the sealed bundle. + +A second CyberBattleSim public baseline, changed run count, or additional metric +is another selection and frozen bundle. It must not require editing the first +bundle, a cross-simulator registry, `raes_adapters.base`, RAES schemas/profiles, +or a hard-coded metric/tier switch outside the selection. The seam is not an +invitation to make source-native execution generic across simulators. + +## Gotchas and anti-patterns + +- The public notebook leaves all four stochastic sources uncontrolled, while + the current mediated reset applies the provided value to Gym environment and + action-space streams but leaves Python and global NumPy unbound. A repeated + seed label is not the same as an executable binding. Freeze and compare the + actual dispositions; do not silently seed the native oracle, remove seeding + from the mediated path, or call the lanes equivalent merely to improve a tier. +- The current task declares steps, cumulative reward, availability, and + terminal-cause metrics, but the current adapter evaluator retains only a + cumulative-reward derived measure and the driver reports generic + `source-terminated`. Do not fabricate missing series or terminal causes, + infer them from reward alone, or claim metric completeness. Project them + through the existing evaluator/evidence boundary with source-backed meaning, + or record the predeclared failed/weakened/unsupported result. +- The authored RAES topology is explicitly representative while the native + apparatus generates the size-10 chain. Shared condition identity does not + make the scenario snapshots or state spaces equal. Preserve + `loss-abstracted-topology` in state/observation and outcome interpretation. +- The adapter reproduces the selected policy through proposal plus RAES + admission and an adapter-owned loop; the native oracle uses upstream + `epsilon_greedy_search`. Compare their frozen schedules and reset semantics; + a shared policy class name alone is not evaluator equivalence. +- Keep source termination, reconstructed cause, Gym termination/truncation, + evaluator cutoff, participant terminal reason, objective truth, run status, + attempt disposition, cleanup status, derived measure, aggregate acceptance, + conformance, readiness, and scientific validity distinct. +- Do not combine the historical benchmark snapshot with the newer qualified + commit, use it as the oracle, or tune against it. Do not fetch a floating + notebook, branch, image, dependency, or environment pack during reproduction. +- Do not duplicate `qualification.json`, `source-ledger.jsonl`, task/spec, + participant artifacts, native source, raw notebooks, or environment-pack + content into the bundle. Cite immutable identities and include only the + issue-required reviewed projections. +- Do not add a reproduction schema registry, profile, capability table, + controller, service, database, repository, cache, exception hierarchy, + redaction policy, second console script, second distribution/lock, or + simulator-wide baseline framework. + +## Non-goals and implementation boundaries + +- No patch or requalification of CyberBattleSim, new source artifact, + deterministic random-stream binding, replay engine, training loop, agent + ranking, leaderboard, or notebook UI is part of issue #30. +- No change to RAES SDL/experiment/participant/validation semantics, backend + profiles, fixture corpus, environment-pack schema, manifest vocabulary, + runtime security, `ControlPlaneStore`, or shared base semantic boundary. +- No deterministic replay, exact state/observation equivalence, + cross-simulator equality, benchmark comparability, agent superiority, + general scientific reproducibility, or outcome equivalence follows from a + passing run, interval, tier, readiness record, or clean recomputation. +- The bundle qualifies this one pinned CyberBattleSim baseline and adapter + selection for the named frozen research consumers. It is not a general + reproduction service or evidence authority for other backends or studies. diff --git a/docs/index.md b/docs/index.md index ac04ca9..22efa11 100644 --- a/docs/index.md +++ b/docs/index.md @@ -21,6 +21,7 @@ semantic and protocol authority. - [Installed researcher command](researcher-command.md) - [NASim researcher command](nasim-researcher-command.md) - [CyberBattleSim researcher command](cyberbattlesim-researcher-command.md) +- [CyberBattleSim baseline reproduction](cyberbattlesim-baseline-reproduction.md) - [Contribution guide](https://github.com/OpenRAE/adapters/blob/dev/CONTRIBUTING.md) - [Architecture decisions](decisions/adrs/README.md) - [CybORG/CAGE-2 backend qualification guardrails](decisions/cyborg-cage2-runtime-qualification-guardrails.md) @@ -43,6 +44,7 @@ semantic and protocol authority. - [CyberBattleSim backend architecture guardrails](decisions/cyberbattlesim-backend-guardrails.md) - [CyberBattleSim conformance-composition guardrails](decisions/cyberbattlesim-conformance-guardrails.md) - [CyberBattleSim environment-pack and researcher-command guardrails](decisions/cyberbattlesim-researcher-command-guardrails.md) +- [CyberBattleSim baseline-reproduction guardrails](decisions/cyberbattlesim-baseline-reproduction-guardrails.md) - [CyberBattleSim chain native-readiness record](decisions/cyberbattlesim-native-readiness-record.md) - [Project services](maintainers/project-services.md) diff --git a/environments/cyberbattlesim-chain/docs/golden-readiness-checklist.md b/environments/cyberbattlesim-chain/docs/golden-readiness-checklist.md index 1f89f12..e9fb479 100644 --- a/environments/cyberbattlesim-chain/docs/golden-readiness-checklist.md +++ b/environments/cyberbattlesim-chain/docs/golden-readiness-checklist.md @@ -34,3 +34,31 @@ pack may move beyond its evidence-backed status. It is not participant content. before a source transition and that the evaluator remains a separate view. - [ ] Confirm the scenario objective and experiment controls agree with the canonical installed mirrors and the recorded native rehearsal. + +## Baseline-reproduction readiness lane + +This lane is separate from golden promotion. Completing it does not change the +pack status from `built` to `golden`. + +- [ ] Build and install CyberBattleSim from the exact qualified commit as a + non-editable wheel, then pass pre-import source admission. +- [ ] Freeze the issue-30 declaration with 20 unique run/attempt IDs, zero + retries, exact task/spec/pack/participant/runner digests, actual + stochastic dispositions, missingness policy, bootstrap method, + tolerances, and six tier criteria. +- [ ] Execute the exact upstream ten-episode `epsilon_greedy_search` batch and + commit the completed native oracle before the first mediated attempt. +- [ ] Execute all ten mediated attempts through RAES participant admission, + evaluator projection, sealed evidence, and verified cleanup; retain every + failed, invalid, or excluded attempt without replacement. +- [ ] Recompute `aggregates.json` and `tiers.json` offline from the retained run + rows; verify all digest-bound citations and the final inventory. +- [ ] Scan the complete bundle for native observations, action coordinates, + credentials, reward vectors, hidden state, random state, host paths, + argument/environment dumps, provider logs, exceptions, and tracebacks. +- [ ] Record the exact source/adapter/pack/software/hardware identities and all + unsupported controls or metrics in the readiness record. +- [ ] Confirm the report makes no deterministic-replay, exact state or + observation equivalence, cross-simulator equality, agent-ranking, + benchmark-comparability, outcome-equivalence, or general scientific + reproducibility claim. diff --git a/environments/cyberbattlesim-chain/pack.content-manifest.json b/environments/cyberbattlesim-chain/pack.content-manifest.json index ec12772..3f65562 100644 --- a/environments/cyberbattlesim-chain/pack.content-manifest.json +++ b/environments/cyberbattlesim-chain/pack.content-manifest.json @@ -51,9 +51,9 @@ "uri": "raes-environment-pack:/docs/golden-readiness-checklist.md", "checksum": { "algorithm": "sha256", - "value": "ab3febf666b60f8a08186d9e9e97471b652e2522ef3c9cd5a34b450921229fe2" + "value": "9b718e4e388b409cb619bc9e6c02c87fd942cfea8c3c535f94c35b2f8040219f" }, - "size_bytes": 2123, + "size_bytes": 3824, "created_at": "2026-08-08T00:00:00Z", "source": "OpenRAE/adapters#29", "satisfies_refs": [], @@ -205,5 +205,5 @@ "description": null } }, - "set_digest": "sha256:08ae7e997b50bb396c290c4a5537a65e9e7d8b8e6abc97d1ff65022c4258e417" + "set_digest": "sha256:66493882579d5cba87248c5722782ff5ded5f0d7423f4e559f15bfb61712a905" } diff --git a/mkdocs.yml b/mkdocs.yml index f4188a1..01e1494 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -33,6 +33,7 @@ nav: - Researcher command: researcher-command.md - NASim researcher command: nasim-researcher-command.md - CyberBattleSim researcher command: cyberbattlesim-researcher-command.md + - CyberBattleSim baseline reproduction: cyberbattlesim-baseline-reproduction.md - Maintainers: - Continuous integration: maintainers/ci.md - Project services: maintainers/project-services.md @@ -63,6 +64,7 @@ nav: - CyberBattleSim backend architecture guardrails: decisions/cyberbattlesim-backend-guardrails.md - CyberBattleSim conformance-composition guardrails: decisions/cyberbattlesim-conformance-guardrails.md - CyberBattleSim environment-pack and researcher-command guardrails: decisions/cyberbattlesim-researcher-command-guardrails.md + - CyberBattleSim baseline-reproduction guardrails: decisions/cyberbattlesim-baseline-reproduction-guardrails.md - CyberBattleSim chain native-readiness record: decisions/cyberbattlesim-native-readiness-record.md - ADR 003 — Single distribution and Trusted Publishing: decisions/adrs/adr-003-single-distribution-and-trusted-publishing.md - ADR 002 — RAES authority and adapter boundaries: decisions/adrs/adr-002-raes-authority-and-adapter-boundaries.md diff --git a/noxfile.py b/noxfile.py index f5d0bd2..f60b9fb 100644 --- a/noxfile.py +++ b/noxfile.py @@ -587,7 +587,7 @@ def _distributions(session: nox.Session) -> None: "--pack", str(REPO_ROOT / "environments" / "cyberbattlesim-chain"), "--pack-digest", - "sha256:08ae7e997b50bb396c290c4a5537a65e9e7d8b8e6abc97d1ff65022c4258e417", + "sha256:66493882579d5cba87248c5722782ff5ded5f0d7423f4e559f15bfb61712a905", "--scenario", "sdl/cyberbattlesim-chain.sdl.yaml", "--scenario-digest", diff --git a/src/raes_adapters/cli.py b/src/raes_adapters/cli.py index e0f1a1d..ad2da68 100644 --- a/src/raes_adapters/cli.py +++ b/src/raes_adapters/cli.py @@ -766,7 +766,7 @@ def _nasim_machine_software() -> dict[str, str]: "sdl/cyberbattlesim-chain.sdl.yaml", ) _CYBERBATTLESIM_PACK_DIGEST = ( - "sha256:08ae7e997b50bb396c290c4a5537a65e9e7d8b8e6abc97d1ff65022c4258e417" + "sha256:66493882579d5cba87248c5722782ff5ded5f0d7423f4e559f15bfb61712a905" ) diff --git a/src/raes_adapters/cyberbattlesim/backend/driver.py b/src/raes_adapters/cyberbattlesim/backend/driver.py index 5350cba..5ba25eb 100644 --- a/src/raes_adapters/cyberbattlesim/backend/driver.py +++ b/src/raes_adapters/cyberbattlesim/backend/driver.py @@ -11,6 +11,11 @@ from raes_adapters import _source_admission from raes_adapters.cyberbattlesim import load_qualification +from raes_adapters.cyberbattlesim.backend.source import ( + construct_selected_environment, + resolve_and_verify_selected_source, + verify_selected_source_identity, +) _SUPPORTED_ACTION_KINDS = frozenset( { @@ -32,16 +37,6 @@ _CREDENTIAL_CACHE_SOURCE_PATH = "cyberbattle/agents/baseline/agent_randomcredlookup.py" _CREDENTIAL_CACHE_MODULE = "cyberbattle.agents.baseline.agent_randomcredlookup" _AGENT_WRAPPER_MODULE = "cyberbattle.agents.baseline.agent_wrapper" -_RUNTIME_SOURCE_PATHS = ( - "cyberbattle/__init__.py", - _CREDENTIAL_CACHE_SOURCE_PATH, - "cyberbattle/agents/baseline/learner.py", - "cyberbattle/_env/cyberbattle_env.py", - "cyberbattle/_env/defender.py", - "cyberbattle/_env/cyberbattle_chain.py", - "cyberbattle/samples/chainpattern/chainpattern.py", -) -_RUNTIME_ARTIFACT_NAMES = frozenset({"cyberbattlesim", "gymnasium", "numpy"}) _QUALIFICATION_INVALID = _source_admission.QUALIFICATION_INVALID @@ -49,51 +44,9 @@ def _verify_selected_source_identity( qualification: dict[str, object], selected_distribution: Distribution, ) -> dict[str, Distribution]: - """Verify the complete pinned runtime without constructing an environment.""" + """Compatibility wrapper around the backend-local shared verifier.""" - distributions = _source_admission.verify_runtime_artifacts( - qualification, - selected_distribution, - expected_names=_RUNTIME_ARTIFACT_NAMES, - primary_name="cyberbattlesim", - ) - _source_admission.verify_runtime_source_tree( - qualification, - selected_distribution, - import_root="cyberbattle", - ) - _source_admission.verify_selected_source_files( - qualification, - selected_distribution, - source_paths=_RUNTIME_SOURCE_PATHS, - ) - for module_name, path in ( - ("cyberbattle", "cyberbattle/__init__.py"), - ( - _CREDENTIAL_CACHE_MODULE, - _CREDENTIAL_CACHE_SOURCE_PATH, - ), - ( - _AGENT_WRAPPER_MODULE, - "cyberbattle/agents/baseline/agent_wrapper.py", - ), - ): - _source_admission.verify_package_origin( - module_name, - selected_distribution, - path, - ) - _source_admission.verify_package_origin( - "gymnasium", - distributions["gymnasium"], - "gymnasium/__init__.py", - ) - _source_admission.verify_package_origin( - "numpy", - distributions["numpy"], - "numpy/__init__.py", - ) - return distributions + return verify_selected_source_identity(qualification, selected_distribution) class _ActionSpace(Protocol): @@ -351,61 +304,17 @@ def construct(self) -> None: if self._environment is not None and not self._closed: return qualification, source, selection = self._selected_configuration() - selected_distribution = _source_admission.resolve_selected_distribution( - source["package"], - source["version"], - ) - - if not self._artifacts_verified: - _verify_selected_source_identity(qualification, selected_distribution) - self._selected_distribution = selected_distribution - # Importing ``cyberbattle`` registers CyberBattleChain-v0. - importlib.import_module("cyberbattle") - gymnasium = cast(_GymnasiumModule, importlib.import_module("gymnasium")) - numpy = cast(_NumpyModule, importlib.import_module("numpy")) - _source_admission.verify_package_origin( - "cyberbattle._env.cyberbattle_env", - selected_distribution, - "cyberbattle/_env/cyberbattle_env.py", - ) - _source_admission.verify_package_origin( - "cyberbattle._env.defender", - selected_distribution, - "cyberbattle/_env/defender.py", + runtime = construct_selected_environment( + qualification, + source, + selection, + module_loader=importlib.import_module, ) + self._selected_distribution = runtime.selected_distribution self._artifacts_verified = True - source_environment = cast( - _SourceEnvironmentModule, - importlib.import_module("cyberbattle._env.cyberbattle_env"), - ) - defender = cast( - _DefenderModule, - importlib.import_module("cyberbattle._env.defender"), - ) - termination = selection["termination"] - defender_selection = selection["defender"] - attacker_goal = source_environment.AttackerGoal( - own_atleast=termination["attacker_own_atleast"], - own_atleast_percent=termination["attacker_own_atleast_percent"], - ) - defender_constraint = source_environment.DefenderConstraint( - maintain_sla=termination["defender_maintain_sla"] - ) - defender_agent = defender.ScanAndReimageCompromisedMachines( - probability=defender_selection["probability"], - scan_capacity=defender_selection["scan_capacity"], - scan_frequency=defender_selection["scan_frequency"], - ) - environment = gymnasium.make( - selection["scenario"]["gym_id"], - size=selection["scenario"]["size"], - attacker_goal=attacker_goal, - defender_constraint=defender_constraint, - defender_agent=defender_agent, - ).unwrapped - self._environment = environment - self._numpy = numpy - self._max_steps = termination["evaluator_cutoff_steps"] + self._environment = cast(_NativeEnvironment, runtime.environment) + self._numpy = cast(_NumpyModule, runtime.numpy) + self._max_steps = selection["termination"]["evaluator_cutoff_steps"] self._closed = False def reset(self, seed: int | None) -> DriverResetReport: @@ -807,10 +716,19 @@ def verify_selected_cyberbattlesim_source() -> None: """Verify the complete pinned source without importing or constructing it.""" qualification, source, _selection = CyberBattleSimDriver._selected_configuration() - selected_distribution = _source_admission.resolve_selected_distribution( - source["package"], source["version"] - ) - _verify_selected_source_identity(qualification, selected_distribution) + resolve_and_verify_selected_source(qualification, source) + + +def construct_selected_cyberbattlesim_environment() -> object: + """Construct the exact admitted environment for the source-native evaluator.""" + + qualification, source, selection = CyberBattleSimDriver._selected_configuration() + return construct_selected_environment( + qualification, + source, + selection, + module_loader=importlib.import_module, + ).environment __all__ = [ @@ -821,5 +739,6 @@ def verify_selected_cyberbattlesim_source() -> None: "DriverEvaluation", "DriverResetReport", "DriverStep", + "construct_selected_cyberbattlesim_environment", "verify_selected_cyberbattlesim_source", ] diff --git a/src/raes_adapters/cyberbattlesim/backend/source.py b/src/raes_adapters/cyberbattlesim/backend/source.py new file mode 100644 index 0000000..acaaa2c --- /dev/null +++ b/src/raes_adapters/cyberbattlesim/backend/source.py @@ -0,0 +1,167 @@ +"""Selected CyberBattleSim source admission and native construction seam. + +This module owns only backend-local mechanics shared by the serialized driver +and the source-native reproduction collector. The selected values remain in +``qualification.json``; callers supply its already-normalized selection. +""" + +from __future__ import annotations + +import importlib +from collections.abc import Callable, Mapping +from dataclasses import dataclass +from importlib.metadata import Distribution +from typing import Protocol, cast + +from raes_adapters import _source_admission + +_CREDENTIAL_CACHE_SOURCE_PATH = "cyberbattle/agents/baseline/agent_randomcredlookup.py" +_CREDENTIAL_CACHE_MODULE = "cyberbattle.agents.baseline.agent_randomcredlookup" +_AGENT_WRAPPER_MODULE = "cyberbattle.agents.baseline.agent_wrapper" +_RUNTIME_SOURCE_PATHS = ( + "cyberbattle/__init__.py", + _CREDENTIAL_CACHE_SOURCE_PATH, + "cyberbattle/agents/baseline/learner.py", + "cyberbattle/_env/cyberbattle_env.py", + "cyberbattle/_env/defender.py", + "cyberbattle/_env/cyberbattle_chain.py", + "cyberbattle/samples/chainpattern/chainpattern.py", +) +_RUNTIME_ARTIFACT_NAMES = frozenset({"cyberbattlesim", "gymnasium", "numpy"}) + + +class _SourceEnvironmentModule(Protocol): + AttackerGoal: Callable[..., object] + DefenderConstraint: Callable[..., object] + + +class _DefenderModule(Protocol): + ScanAndReimageCompromisedMachines: Callable[..., object] + + +class _EnvironmentWrapper(Protocol): + unwrapped: object + + +class _GymnasiumModule(Protocol): + def make(self, gym_id: object, **kwargs: object) -> _EnvironmentWrapper: ... + + +@dataclass(frozen=True) +class SelectedNativeRuntime: + """Private installed objects for the one qualified native selection.""" + + environment: object + numpy: object + selected_distribution: Distribution + + +def verify_selected_source_identity( + qualification: dict[str, object], selected_distribution: Distribution +) -> dict[str, Distribution]: + """Verify the complete pinned runtime without constructing an environment.""" + + distributions = _source_admission.verify_runtime_artifacts( + qualification, + selected_distribution, + expected_names=_RUNTIME_ARTIFACT_NAMES, + primary_name="cyberbattlesim", + ) + _source_admission.verify_runtime_source_tree( + qualification, + selected_distribution, + import_root="cyberbattle", + ) + _source_admission.verify_selected_source_files( + qualification, + selected_distribution, + source_paths=_RUNTIME_SOURCE_PATHS, + ) + for module_name, path in ( + ("cyberbattle", "cyberbattle/__init__.py"), + (_CREDENTIAL_CACHE_MODULE, _CREDENTIAL_CACHE_SOURCE_PATH), + (_AGENT_WRAPPER_MODULE, "cyberbattle/agents/baseline/agent_wrapper.py"), + ): + _source_admission.verify_package_origin(module_name, selected_distribution, path) + _source_admission.verify_package_origin( + "gymnasium", distributions["gymnasium"], "gymnasium/__init__.py" + ) + _source_admission.verify_package_origin("numpy", distributions["numpy"], "numpy/__init__.py") + return distributions + + +def resolve_and_verify_selected_source( + qualification: dict[str, object], source: Mapping[str, object] +) -> Distribution: + """Resolve and verify the selected simulator distribution.""" + + package = cast(str, source["package"]) + version = cast(str, source["version"]) + selected_distribution = _source_admission.resolve_selected_distribution(package, version) + verify_selected_source_identity(qualification, selected_distribution) + return selected_distribution + + +def construct_selected_environment( + qualification: dict[str, object], + source: Mapping[str, object], + selection: Mapping[str, object], + *, + module_loader: Callable[[str], object] = importlib.import_module, +) -> SelectedNativeRuntime: + """Construct the exact admitted source environment after identity checks.""" + + selected_distribution = resolve_and_verify_selected_source(qualification, source) + # Importing the package registers CyberBattleChain-v0. + module_loader("cyberbattle") + gymnasium = cast(_GymnasiumModule, module_loader("gymnasium")) + numpy = module_loader("numpy") + _source_admission.verify_package_origin( + "cyberbattle._env.cyberbattle_env", + selected_distribution, + "cyberbattle/_env/cyberbattle_env.py", + ) + _source_admission.verify_package_origin( + "cyberbattle._env.defender", + selected_distribution, + "cyberbattle/_env/defender.py", + ) + source_environment = cast( + _SourceEnvironmentModule, module_loader("cyberbattle._env.cyberbattle_env") + ) + defender = cast(_DefenderModule, module_loader("cyberbattle._env.defender")) + termination = cast(Mapping[str, object], selection["termination"]) + defender_selection = cast(Mapping[str, object], selection["defender"]) + scenario = cast(Mapping[str, object], selection["scenario"]) + attacker_goal = source_environment.AttackerGoal( + own_atleast=termination["attacker_own_atleast"], + own_atleast_percent=termination["attacker_own_atleast_percent"], + ) + defender_constraint = source_environment.DefenderConstraint( + maintain_sla=termination["defender_maintain_sla"] + ) + defender_agent = defender.ScanAndReimageCompromisedMachines( + probability=defender_selection["probability"], + scan_capacity=defender_selection["scan_capacity"], + scan_frequency=defender_selection["scan_frequency"], + ) + wrapper = gymnasium.make( + scenario["gym_id"], + size=scenario["size"], + attacker_goal=attacker_goal, + defender_constraint=defender_constraint, + defender_agent=defender_agent, + ) + return SelectedNativeRuntime( + environment=wrapper.unwrapped, + numpy=numpy, + selected_distribution=selected_distribution, + ) + + +__all__ = [ + "SelectedNativeRuntime", + "construct_selected_environment", + "resolve_and_verify_selected_source", + "verify_selected_source_identity", +] diff --git a/src/raes_adapters/cyberbattlesim/qualification.json b/src/raes_adapters/cyberbattlesim/qualification.json index 993859b..a7dbed6 100644 --- a/src/raes_adapters/cyberbattlesim/qualification.json +++ b/src/raes_adapters/cyberbattlesim/qualification.json @@ -151,10 +151,14 @@ "attacker": { "policy": "CredentialCacheExploiter", "episode_count": 10, - "iteration_count": 600, - "epsilon": 0.9, - "epsilon_exponential_decay": 10000, - "epsilon_minimum": 0.1 + "iteration_count": 600, + "epsilon": 0.9, + "epsilon_exponential_decay": 10000, + "epsilon_minimum": 0.1, + "environment_bounds": { + "maximum_total_credentials": 22, + "maximum_node_count": 22 + } }, "defender": { "policy": "ScanAndReimageCompromisedMachines", diff --git a/src/raes_adapters/cyberbattlesim/reproduction.py b/src/raes_adapters/cyberbattlesim/reproduction.py new file mode 100644 index 0000000..4c635aa --- /dev/null +++ b/src/raes_adapters/cyberbattlesim/reproduction.py @@ -0,0 +1,2630 @@ +"""Frozen CyberBattleSim source-native/RAES baseline reproduction. + +The module is intentionally backend-local. It owns the issue-30 data gap +(lane, terminal disposition, comparison intervals, and six tier projections) +while validating and embedding the published RAES task, spec, and study +contracts that own experiment meaning. +""" + +from __future__ import annotations + +import argparse +import contextlib +import hashlib +import importlib +import importlib.metadata +import json +import math +import os +import platform +import shutil +import statistics +import subprocess +import sys +import tempfile +from collections.abc import Callable, Mapping, Sequence +from datetime import UTC, datetime +from pathlib import Path, PurePosixPath +from typing import Protocol, cast + +from raes_contracts.contracts import ( # type: ignore[import-untyped] + ExperimentDerivedMeasureModel, + ExperimentEvidenceRecordModel, + ExperimentRunModel, + ExperimentSpecModel, + ExperimentStudyModel, + ExperimentTaskModel, + ParticipantImplementationProvenanceModel, +) +from raes_contracts.diagnostics import DiagnosticModel # type: ignore[import-untyped] +from raes_operations.run_artifacts import ( # type: ignore[import-untyped] + atomic_write_json_artifact, +) + +from raes_adapters.cyberbattlesim import load_qualification +from raes_adapters.cyberbattlesim.backend.driver import ( + construct_selected_cyberbattlesim_environment, + verify_selected_cyberbattlesim_source, +) + +_SCHEMA = "cyberbattlesim-baseline-reproduction/v1" +_SOURCE_LEDGER_SCHEMA = "cyberbattlesim-baseline-source-ledger/v1" +_RUN_SCHEMA = "cyberbattlesim-baseline-run/v1" +_AGGREGATE_SCHEMA = "cyberbattlesim-baseline-aggregates/v1" +_BENCH_NOTES_SCHEMA = "cyberbattlesim-baseline-bench-notes/v1" +_INVENTORY_NAME = "inventory.json" +_LANES = ("source-native", "raes-mediated") +_DISPOSITIONS = frozenset({"valid", "invalid", "failed", "excluded"}) +_METRICS = ( + "steps_to_termination", + "cumulative_attacker_reward", + "network_availability", + "terminal_cause", +) +_TIERS = ( + "authored-source", + "contract", + "execution-control", + "state-observation", + "outcome-evaluation", + "disclosure", +) +_ATTEMPTS_PER_LANE = 10 +_SEED_LABEL = 20260729 +_BENCH_PHASES = frozenset({"declaration", "native", "mediated", "finalize", "verify"}) +_BENCH_SEVERITIES = frozenset({"info", "warning", "error"}) +_BENCH_DISPOSITIONS = frozenset({"observed", "passed", "failed", "weakened"}) +_BENCH_EVENT_CODES = frozenset( + { + "protocol-declared", + "native-collection-started", + "native-attempt-terminalized", + "native-collection-passed", + "native-collection-failed", + "mediated-collection-started", + "mediated-attempt-started", + "mediated-attempt-terminalized", + "mediated-collection-completed", + "bundle-finalization-started", + "bundle-finalized", + "offline-verification-started", + "offline-verification-passed", + "offline-verification-failed", + } +) +_PRIVATE_KEY_MARKER = "BEGIN OPENSSH " + "PRIVATE KEY" +_FORBIDDEN_PORTABLE_TOKENS = ( + "credential_cache_matrix", + '"action_mask"', + '"_explored_network"', + _PRIVATE_KEY_MARKER, + "Traceback (most recent call last)", +) + + +class _NativeEvaluatorEnvironment(Protocol): + identifiers: object + + def close(self) -> None: ... + + +def canonical_json_bytes(payload: object) -> bytes: + """Return the byte representation used by every issue-local digest.""" + + return (json.dumps(payload, sort_keys=True, separators=(",", ":")) + "\n").encode() + + +def sha256_payload(payload: object) -> str: + """Hash one canonical issue-local JSON payload.""" + + return hashlib.sha256(canonical_json_bytes(payload)).hexdigest() + + +def _sha256_file(path: Path) -> str: + return hashlib.sha256(path.read_bytes()).hexdigest() + + +def _reject_constant(_value: str) -> object: + raise ValueError("invalid JSON artifact") + + +def _closed_pairs(pairs: list[tuple[str, object]]) -> dict[str, object]: + result: dict[str, object] = {} + for key, value in pairs: + if key in result: + raise ValueError("invalid JSON artifact") + result[key] = value + return result + + +def _load_strict_value(path: Path) -> object: + try: + return json.loads( + path.read_text(encoding="utf-8"), + object_pairs_hook=_closed_pairs, + parse_constant=_reject_constant, + ) + except (OSError, UnicodeError, json.JSONDecodeError, ValueError) as error: + raise ValueError("invalid JSON artifact") from error + + +def load_strict_json(path: Path) -> dict[str, object]: + """Load a duplicate-key-free, finite JSON object.""" + + value = _load_strict_value(path) + if not isinstance(value, dict): + raise ValueError("invalid JSON artifact") + return value + + +def _require_keys(value: Mapping[str, object], expected: frozenset[str], label: str) -> None: + if set(value) != expected: + raise ValueError(f"{label} has unknown or missing fields") + + +def _safe_relative_path(value: object) -> str: + if not isinstance(value, str): + raise ValueError("artifact relative path is invalid") + path = PurePosixPath(value) + if path.is_absolute() or not path.parts or ".." in path.parts or path.as_posix() != value: + raise ValueError("artifact relative path is invalid") + return value + + +def _bench_note_policy() -> dict[str, object]: + return { + "artifact": "bench-notes.json", + "schema_version": _BENCH_NOTES_SCHEMA, + "timestamp_profile": "RFC3339 UTC with millisecond precision", + "required_fields": [ + "note_id", + "recorded_at", + "phase", + "severity", + "event_code", + "summary", + "disposition", + "evidence_refs", + ], + "publication_policy": ( + "Record controlled observations and dispositions as work occurs; exclude raw " + "native output, exception text, host paths, credentials, and provider identifiers." + ), + } + + +def _utc_timestamp() -> str: + return datetime.now(UTC).isoformat(timespec="milliseconds").replace("+00:00", "Z") + + +def _validate_bench_timestamp(value: object) -> str: + if not isinstance(value, str) or not value.endswith("Z"): + raise ValueError("bench note timestamp is invalid") + try: + parsed = datetime.fromisoformat(value[:-1] + "+00:00") + except ValueError as error: + raise ValueError("bench note timestamp is invalid") from error + normalized = parsed.astimezone(UTC).isoformat(timespec="milliseconds").replace("+00:00", "Z") + if parsed.utcoffset() != UTC.utcoffset(None) or normalized != value: + raise ValueError("bench note timestamp is invalid") + return value + + +def _validate_bench_notes(payload: Mapping[str, object], protocol: Mapping[str, object]) -> None: + _require_keys( + payload, + frozenset({"schema_version", "declaration_sha256", "notes"}), + "bench notes", + ) + if ( + payload["schema_version"] != _BENCH_NOTES_SCHEMA + or payload["declaration_sha256"] != protocol["declaration_sha256"] + ): + raise ValueError("bench notes binding is invalid") + notes = payload["notes"] + if not isinstance(notes, list) or not notes: + raise ValueError("bench notes are invalid") + note_ids: set[str] = set() + previous_timestamp = "" + for note in notes: + if not isinstance(note, dict): + raise ValueError("bench note is invalid") + _require_keys( + note, + frozenset(cast(list[str], _bench_note_policy()["required_fields"])), + "bench note", + ) + note_id = note["note_id"] + if not isinstance(note_id, str) or note_id in note_ids: + raise ValueError("bench note identity is invalid") + note_ids.add(note_id) + recorded_at = _validate_bench_timestamp(note["recorded_at"]) + if recorded_at < previous_timestamp: + raise ValueError("bench note timestamps are not ordered") + previous_timestamp = recorded_at + if note["phase"] not in _BENCH_PHASES: + raise ValueError("bench note phase is invalid") + if note["severity"] not in _BENCH_SEVERITIES: + raise ValueError("bench note severity is invalid") + if note["event_code"] not in _BENCH_EVENT_CODES: + raise ValueError("bench note event code is invalid") + if note["disposition"] not in _BENCH_DISPOSITIONS: + raise ValueError("bench note disposition is invalid") + summary = note["summary"] + if not isinstance(summary, str) or not summary or len(summary) > 240 or "\n" in summary: + raise ValueError("bench note summary is invalid") + evidence_refs = note["evidence_refs"] + if not isinstance(evidence_refs, list): + raise ValueError("bench note evidence references are invalid") + for ref in evidence_refs: + if not isinstance(ref, dict) or set(ref) != {"path"}: + raise ValueError("bench note evidence references are invalid") + _safe_relative_path(ref["path"]) + + +def _new_bench_notes( + protocol: Mapping[str, object], notes: Sequence[Mapping[str, object]] = () +) -> dict[str, object]: + return { + "schema_version": _BENCH_NOTES_SCHEMA, + "declaration_sha256": protocol["declaration_sha256"], + "notes": [dict(note) for note in notes], + } + + +def _append_bench_note( + payload: dict[str, object], + protocol: Mapping[str, object], + *, + phase: str, + severity: str, + event_code: str, + summary: str, + disposition: str, + evidence_paths: Sequence[str], +) -> None: + notes = cast(list[dict[str, object]], payload["notes"]) + phase_count = sum(note.get("phase") == phase for note in notes) + notes.append( + { + "note_id": f"{phase}-{phase_count + 1:03d}", + "recorded_at": _utc_timestamp(), + "phase": phase, + "severity": severity, + "event_code": event_code, + "summary": summary, + "disposition": disposition, + "evidence_refs": [{"path": path} for path in evidence_paths], + } + ) + _validate_bench_notes(payload, protocol) + + +def _write_bench_notes(root: Path, payload: Mapping[str, object]) -> None: + atomic_write_json_artifact(root / "bench-notes.json", dict(payload)) + + +def _load_bench_notes(root: Path, protocol: Mapping[str, object]) -> dict[str, object]: + payload = load_strict_json(root / "bench-notes.json") + _validate_bench_notes(payload, protocol) + return payload + + +def _artifact(repo_root: Path, artifact_id: str, relative: str) -> dict[str, object]: + path = repo_root / relative + return {"artifact_id": artifact_id, "path": relative, "sha256": _sha256_file(path)} + + +def _study(task: ExperimentTaskModel) -> dict[str, object]: + metrics = list(task.evaluation_protocol.metric_definitions) + payload = { + "schema_version": "experiment-study/v1", + "study_id": "cyberbattlesim-chain-baseline-reproduction", + "study_version": "1.0.0", + "study_kind": "study", + "title": "CyberBattleSim chain source-native and RAES-mediated reproduction", + "owner": "OpenRAE", + "description": ( + "Frozen two-lane reproduction of the selected public credential-cache baseline." + ), + "purpose": ( + "Retain bounded readiness and reproduction evidence for OpenRAE/research#14 " + "and OpenRAE/research#20 without asserting deterministic replay or outcome " + "equivalence." + ), + "research_questions": [ + "Which authored, contract, control, observation, outcome, and disclosure facts " + "survive the selected RAES-mediated execution?" + ], + "behavioral_claims": [ + { + "taxonomy_id": "raes-behavioral-relations", + "taxonomy_revision": "rev12", + "relation_id": "empirical-adequacy", + "subject": "The fixed CyberBattleSim credential-cache baseline selection", + "left_carrier_ref": "condition:source-native", + "right_carrier_ref": "condition:raes-mediated", + "observation_projection_ref": "experiment-study-v1", + "observation_projection_revision": "rev1", + "quantifier_scope": "finite-cases", + "evidence_scope": "finite", + "assurance_axis": "bounded-test", + "evidence_boundary": ( + "Exactly ten preallocated terminal attempts per lane under the frozen " + "issue-30 comparison and missingness rules." + ), + "assurance_status": "tested", + "limitations": [ + "The lanes have different stochastic bindings and evaluator paths." + ], + "explicit_non_claims": [ + "No trace, state, observation, deterministic-replay, or outcome-equivalence " + "claim is made." + ], + } + ], + "membership": { + "primary-task": { + "target_ref": {"ref_kind": "task", "ref_id": task.task_id}, + "role": "primary-task", + "inclusion_rationale": "The qualified public task owns all measured constructs.", + } + }, + "inclusion_criteria": [ + "Only preallocated terminal attempts from the exact qualified selection are included." + ], + "factors": { + "execution-lane": { + "name": "Execution lane", + "factor_kind": "apparatus", + "levels": list(_LANES), + } + }, + "run_allocation": { + "allocation_unit": "episode", + "allocation_method": "preallocated fixed condition matrix", + "compared_conditions": list(_LANES), + "condition_assignments": { + lane: { + "condition_id": lane, + "factor_levels": {"execution-lane": lane}, + "required_parameters": [ + {"name": "execution-lane", "value": lane, "value_kind": "apparatus"} + ], + } + for lane in _LANES + }, + "target_runs_per_condition": _ATTEMPTS_PER_LANE, + "blocking_factors": [], + "replication_policy": "Ten fixed scheduled episodes per lane; retry budget zero.", + "stopping_rule": "Terminalize every scheduled attempt; do not replace failures.", + }, + "analysis_plan": { + "analysis_id": "cyberbattlesim-baseline-comparison-v1", + "description": "Lane summaries and predeclared bounded differences.", + "metrics": metrics, + "primary_metric": "cumulative_attacker_reward", + "statistical_method": { + "method": "descriptive lane summaries and difference in means", + "estimand": "RAES-mediated lane mean minus source-native lane mean", + "unit_of_analysis": "episode", + "comparison_family": "four predeclared task metrics", + "assumptions": [ + "Attempts are the fixed scheduled episodes and are not replaced after failure." + ], + }, + "uncertainty_method": { + "method": "deterministic percentile bootstrap", + "interval_level": 0.95, + "procedure": ( + "10,000 counter-addressed SHA-256 resamples bound to the declaration digest." + ), + }, + "multiple_comparison_policy": { + "family": "four descriptive metric comparisons", + "correction": "none", + "rationale": "No hypothesis-test or general population claim is made.", + }, + "missing_data_policy": { + "missingness_assumption": ( + "Missingness is apparatus- or failure-induced, not random." + ), + "handling": ( + "Retain all terminal attempts in denominators; do not impute or silently drop." + ), + "sensitivity_analysis": "Unavailable declared metrics weaken the applicable tier.", + }, + }, + "validity_notes": [ + { + "category": "reproducibility", + "note": "The source evaluator leaves four random streams unbound.", + "mitigation": ( + "Record actual lane-specific binding dispositions and make no replay claim." + ), + } + ], + } + return cast( + dict[str, object], + ExperimentStudyModel.model_validate(payload).model_dump(mode="json"), + ) + + +def _schedule() -> list[dict[str, object]]: + rows: list[dict[str, object]] = [] + for lane in _LANES: + short = "native" if lane == "source-native" else "mediated" + for replicate in range(1, _ATTEMPTS_PER_LANE + 1): + rows.append( + { + "lane": lane, + "replicate": replicate, + "run_id": f"cbs-{short}-{replicate:02d}", + "attempt_id": f"cbs-{short}-{replicate:02d}-attempt-01", + "seed_label": _SEED_LABEL, + } + ) + return rows + + +def build_declaration(repo_root: Path) -> tuple[dict[str, object], dict[str, object]]: + """Build and validate the frozen declaration and its source index.""" + + task_path = repo_root / ( + "environments/cyberbattlesim-chain/experiment/cyberbattlesim-chain.task.exp.json" + ) + spec_path = repo_root / ( + "environments/cyberbattlesim-chain/experiment/cyberbattlesim-chain.spec.exp.json" + ) + task = ExperimentTaskModel.model_validate(load_strict_json(task_path)) + spec = ExperimentSpecModel.model_validate(load_strict_json(spec_path)) + if spec.task_ref.ref_id != task.task_id: + raise ValueError("published task and spec do not join") + qualification = cast(dict[str, object], load_qualification()) + source = cast(dict[str, object], qualification["source"]) + runtime_tree = cast(dict[str, object], qualification["runtime_source_tree"]) + benchmark = cast(dict[str, object], qualification["benchmark_snapshot"]) + artifacts = [ + _artifact( + repo_root, + "qualification", + "src/raes_adapters/cyberbattlesim/qualification.json", + ), + _artifact( + repo_root, + "public-protocol", + "src/raes_adapters/cyberbattlesim/public-protocol.md", + ), + _artifact( + repo_root, + "source-ledger", + "src/raes_adapters/cyberbattlesim/mapping/source-ledger.jsonl", + ), + _artifact( + repo_root, + "loss-disclosures", + "src/raes_adapters/cyberbattlesim/mapping/loss-disclosures.md", + ), + _artifact( + repo_root, + "reproduction-runner", + "src/raes_adapters/cyberbattlesim/reproduction.py", + ), + _artifact( + repo_root, + "mediated-researcher", + "src/raes_adapters/cyberbattlesim/researcher.py", + ), + _artifact( + repo_root, + "mediated-driver", + "src/raes_adapters/cyberbattlesim/backend/driver.py", + ), + _artifact( + repo_root, + "selected-source-helper", + "src/raes_adapters/cyberbattlesim/backend/source.py", + ), + _artifact( + repo_root, + "task", + task_path.relative_to(repo_root).as_posix(), + ), + _artifact( + repo_root, + "spec", + spec_path.relative_to(repo_root).as_posix(), + ), + _artifact( + repo_root, + "pack-manifest", + "environments/cyberbattlesim-chain/pack.content-manifest.json", + ), + _artifact( + repo_root, + "participant-manifest", + "environments/cyberbattlesim-chain/participant/" + "cyberbattlesim-red-credential-cache.manifest.json", + ), + _artifact( + repo_root, + "participant-selection", + "environments/cyberbattlesim-chain/participant/" + "cyberbattlesim-red-credential-cache.selection.json", + ), + _artifact( + repo_root, + "participant-configuration", + "environments/cyberbattlesim-chain/participant/" + "cyberbattlesim-red-credential-cache.configuration.json", + ), + ] + declaration: dict[str, object] = { + "study": _study(task), + "artifacts": artifacts, + "source_selection": { + "repository": source["repository"], + "commit": source["commit"], + "tree": source["tree"], + "version": source["version"], + "runtime_tree_sha256": runtime_tree["sha256"], + "notebook_path": "notebooks/notebook_withdefender.py", + "notebook_sha256": benchmark["source_notebook_sha256"], + "evaluator": qualification["protocol"]["selection"]["evaluator"], # type: ignore[index] + }, + "condition": { + "gym_id": "CyberBattleChain-v0", + "size": 10, + "attacker": "CredentialCacheExploiter", + "defender": "ScanAndReimageCompromisedMachines(0.6,2,5)", + "episode_count_per_lane": _ATTEMPTS_PER_LANE, + "maximum_steps": 600, + "epsilon": 0.9, + "epsilon_exponential_decay": 10000, + "epsilon_minimum": 0.1, + }, + "schedule": _schedule(), + "retry_budget": 0, + "terminal_dispositions": sorted(_DISPOSITIONS), + "bench_notes": _bench_note_policy(), + "metrics": list(_METRICS), + "stochastic_controls": { + "source-native": { + "applied": [], + "unbound": [ + "gym-environment", + "gym-action-space", + "python-random", + "numpy-global", + ], + }, + "raes-mediated": { + "applied": ["gym-environment", "gym-action-space"], + "unbound": ["python-random", "numpy-global"], + }, + }, + "aggregation": { + "numeric_statistics": [ + "count", + "mean", + "median", + "sample-standard-deviation", + "minimum", + "maximum", + ], + "uncertainty": "95% deterministic percentile bootstrap interval of the mean", + "bootstrap_resamples": 10000, + "missingness": "No imputation; every terminal attempt remains in denominators.", + }, + "comparison": { + "exact": "Complete ordered per-run vectors and control dispositions match.", + "bounded": { + "steps_to_termination": 60.0, + "cumulative_attacker_reward": 500.0, + "network_availability": 0.05, + "terminal_cause": 0.10, + }, + "failed": "A complete interval lies outside its bound.", + "unavailable": ( + "A declared metric is absent from either lane; no tolerance is inferred." + ), + }, + "tier_policy": list(_TIERS), + "explicit_non_claims": [ + "deterministic replay", + "exact state or observation equivalence", + "cross-simulator equality", + "agent ranking", + "benchmark comparability", + "outcome equivalence", + "general scientific reproducibility", + ], + } + protocol: dict[str, object] = { + "schema_version": _SCHEMA, + "declaration_sha256": sha256_payload(declaration), + "declaration": declaration, + "oracle": None, + } + source_ledger: dict[str, object] = { + "schema_version": _SOURCE_LEDGER_SCHEMA, + "source": { + "repository": source["repository"], + "commit": source["commit"], + "tree": source["tree"], + "version": source["version"], + "runtime_tree_sha256": runtime_tree["sha256"], + "notebook_path": "notebooks/notebook_withdefender.py", + "notebook_sha256": benchmark["source_notebook_sha256"], + }, + "artifact_refs": artifacts, + "adapter": { + "distribution": "raes-adapters", + "version": _installed_version("raes-adapters"), + "runner_artifact_ids": [ + "reproduction-runner", + "mediated-researcher", + "mediated-driver", + "selected-source-helper", + ], + }, + "loss_refs": [ + "loss-abstracted-topology", + "loss-benchmark-defects", + "loss-no-source-artifact", + "loss-observation-abstraction", + "loss-unbound-random-streams", + ], + "exclusions": [ + "historical benchmark output from a different commit", + ( + "native observations, action coordinates, credentials, hidden state, " + "and reward vectors" + ), + "provider logs, credentials, environment dumps, and tracebacks", + ], + "compatibility_patches": [], + } + validate_protocol(protocol, require_oracle=False) + validate_source_ledger(source_ledger, protocol) + return protocol, source_ledger + + +def validate_source_ledger(payload: Mapping[str, object], protocol: Mapping[str, object]) -> None: + """Validate the closed source index and its declaration join.""" + + _require_keys( + payload, + frozenset( + { + "schema_version", + "source", + "artifact_refs", + "adapter", + "loss_refs", + "exclusions", + "compatibility_patches", + } + ), + "source ledger", + ) + if payload["schema_version"] != _SOURCE_LEDGER_SCHEMA: + raise ValueError("source ledger schema is invalid") + source = payload["source"] + if not isinstance(source, dict): + raise ValueError("source ledger source is invalid") + _require_keys( + source, + frozenset( + { + "repository", + "commit", + "tree", + "version", + "runtime_tree_sha256", + "notebook_path", + "notebook_sha256", + } + ), + "source ledger source", + ) + for digest_key in ("runtime_tree_sha256", "notebook_sha256"): + if not _is_sha256(source[digest_key]): + raise ValueError("source ledger digest is invalid") + _safe_relative_path(source["notebook_path"]) + declaration = cast(dict[str, object], protocol["declaration"]) + if payload["artifact_refs"] != declaration["artifacts"]: + raise ValueError("source ledger artifact join is invalid") + adapter = payload["adapter"] + if not isinstance(adapter, dict): + raise ValueError("source ledger adapter is invalid") + _require_keys( + adapter, + frozenset({"distribution", "version", "runner_artifact_ids"}), + "source ledger adapter", + ) + runner_ids = adapter["runner_artifact_ids"] + if not isinstance(runner_ids, list) or len(set(runner_ids)) != len(runner_ids): + raise ValueError("source ledger adapter is invalid") + for field in ("loss_refs", "exclusions", "compatibility_patches"): + value = payload[field] + if not isinstance(value, list) or any(not isinstance(item, str) for item in value): + raise ValueError("source ledger disclosure is invalid") + + +def validate_protocol(payload: Mapping[str, object], *, require_oracle: bool) -> None: + """Validate the closed issue-local protocol around published contracts.""" + + _require_keys( + payload, + frozenset({"schema_version", "declaration_sha256", "declaration", "oracle"}), + "protocol", + ) + if payload["schema_version"] != _SCHEMA: + raise ValueError("protocol schema is invalid") + declaration = payload["declaration"] + if not isinstance(declaration, dict): + raise ValueError("protocol declaration is invalid") + expected_declaration_keys = frozenset( + { + "study", + "artifacts", + "source_selection", + "condition", + "schedule", + "retry_budget", + "terminal_dispositions", + "bench_notes", + "metrics", + "stochastic_controls", + "aggregation", + "comparison", + "tier_policy", + "explicit_non_claims", + } + ) + _require_keys(declaration, expected_declaration_keys, "protocol declaration") + if payload["declaration_sha256"] != sha256_payload(declaration): + raise ValueError("protocol declaration digest is invalid") + ExperimentStudyModel.model_validate(declaration["study"]) + if declaration["retry_budget"] != 0: + raise ValueError("retry policy is invalid") + if declaration["bench_notes"] != _bench_note_policy(): + raise ValueError("bench note policy is invalid") + if declaration["metrics"] != list(_METRICS): + raise ValueError("metric declaration is invalid") + if declaration["tier_policy"] != list(_TIERS): + raise ValueError("tier policy is invalid") + if set(cast(list[object], declaration["terminal_dispositions"])) != _DISPOSITIONS: + raise ValueError("terminal dispositions are invalid") + artifacts = declaration["artifacts"] + if not isinstance(artifacts, list) or not artifacts: + raise ValueError("artifact references are invalid") + artifact_ids: set[str] = set() + for item in artifacts: + if not isinstance(item, dict): + raise ValueError("artifact references are invalid") + _require_keys(item, frozenset({"artifact_id", "path", "sha256"}), "artifact reference") + artifact_id = item["artifact_id"] + if not isinstance(artifact_id, str) or artifact_id in artifact_ids: + raise ValueError("artifact references are invalid") + artifact_ids.add(artifact_id) + _safe_relative_path(item["path"]) + if not _is_sha256(item["sha256"]): + raise ValueError("artifact digest is invalid") + schedule = declaration["schedule"] + if not isinstance(schedule, list) or len(schedule) != 20: + raise ValueError("attempt schedule is invalid") + run_ids: set[str] = set() + attempt_ids: set[str] = set() + counts = dict.fromkeys(_LANES, 0) + for entry in schedule: + if not isinstance(entry, dict): + raise ValueError("attempt schedule is invalid") + _require_keys( + entry, + frozenset({"lane", "replicate", "run_id", "attempt_id", "seed_label"}), + "schedule entry", + ) + lane = entry["lane"] + if lane not in _LANES or type(entry["replicate"]) is not int: + raise ValueError("attempt schedule is invalid") + run_id = entry["run_id"] + attempt_id = entry["attempt_id"] + if not isinstance(run_id, str) or not isinstance(attempt_id, str): + raise ValueError("attempt schedule is invalid") + if run_id in run_ids or attempt_id in attempt_ids: + raise ValueError("attempt identities are not unique") + run_ids.add(run_id) + attempt_ids.add(attempt_id) + counts[cast(str, lane)] += 1 + if set(counts.values()) != {_ATTEMPTS_PER_LANE}: + raise ValueError("attempt schedule is invalid") + oracle = payload["oracle"] + if oracle is None: + if require_oracle: + raise ValueError("source-native oracle is required") + return + if not isinstance(oracle, dict): + raise ValueError("source-native oracle is invalid") + _require_keys( + oracle, + frozenset({"lane", "declaration_sha256", "native_result_set_sha256", "ordered_results"}), + "source-native oracle", + ) + if ( + oracle["lane"] != "source-native" + or oracle["declaration_sha256"] != payload["declaration_sha256"] + ): + raise ValueError("source-native oracle is invalid") + if not _is_sha256(oracle["native_result_set_sha256"]): + raise ValueError("source-native oracle is invalid") + results = oracle["ordered_results"] + native_ids = [entry["run_id"] for entry in schedule if entry["lane"] == "source-native"] + if ( + not isinstance(results, list) + or [item.get("run_id") for item in results if isinstance(item, dict)] != native_ids + ): + raise ValueError("source-native oracle is invalid") + + +def _is_sha256(value: object) -> bool: + return ( + isinstance(value, str) + and len(value) == 64 + and all(character in "0123456789abcdef" for character in value) + ) + + +def _reserve_directory(path: Path) -> Path: + resolved = path.resolve() + os.mkdir(resolved, 0o700) + return resolved + + +def _media_type(path: Path) -> str: + return "application/json" if path.suffix == ".json" else "text/markdown" + + +def _seal_inventory(root: Path) -> dict[str, object]: + artifacts = [] + for path in sorted(item for item in root.rglob("*") if item.is_file()): + if path.name == _INVENTORY_NAME: + continue + content = path.read_bytes() + artifacts.append( + { + "path": path.relative_to(root).as_posix(), + "media_type": _media_type(path), + "sha256": hashlib.sha256(content).hexdigest(), + "size_bytes": len(content), + } + ) + inventory: dict[str, object] = {"artifacts": artifacts} + atomic_write_json_artifact(root / _INVENTORY_NAME, inventory) + return inventory + + +def write_declaration(repo_root: Path, output: Path) -> Path: + """Reserve and write one immutable declaration collection.""" + + root = _reserve_directory(output) + protocol, source_ledger = build_declaration(repo_root.resolve()) + atomic_write_json_artifact(root / "protocol.json", protocol) + atomic_write_json_artifact(root / "source-ledger.json", source_ledger) + bench_notes = _new_bench_notes(protocol) + _append_bench_note( + bench_notes, + protocol, + phase="declaration", + severity="info", + event_code="protocol-declared", + summary=( + "The declaration and 20 never-reused attempt identities were written before " + "experiment effects." + ), + disposition="passed", + evidence_paths=("protocol.json", "source-ledger.json"), + ) + _write_bench_notes(root, bench_notes) + _seal_inventory(root) + return root + + +def _control_disposition(protocol: Mapping[str, object], lane: str) -> dict[str, object]: + declaration = cast(dict[str, object], protocol["declaration"]) + controls = cast(dict[str, object], declaration["stochastic_controls"]) + return cast(dict[str, object], controls[lane]) + + +def _terminal_row( + protocol: Mapping[str, object], + scheduled: Mapping[str, object], + *, + result: Mapping[str, object] | None, + disposition: str, + protocol_sha256: str | None, + diagnostic_code: str | None = None, +) -> dict[str, object]: + if disposition not in _DISPOSITIONS: + raise ValueError("run disposition is invalid") + metrics: dict[str, object] = dict.fromkeys(_METRICS) + evidence_refs: list[dict[str, object]] = [] + cleanup_verified = False + if result is not None: + for metric in _METRICS: + metrics[metric] = result.get(metric) + raw_refs = result.get("evidence_refs", []) + if isinstance(raw_refs, list): + evidence_refs = [ + cast(dict[str, object], item) for item in raw_refs if isinstance(item, dict) + ] + cleanup_verified = bool(result.get("cleanup_verified", disposition == "valid")) + if disposition == "valid" and not cleanup_verified: + raise ValueError("valid run has no verified cleanup") + metric_status = { + metric: "available" if value is not None else "unavailable" + for metric, value in metrics.items() + } + diagnostics = ( + [] + if diagnostic_code is None + else [ + { + "schema_version": "diagnostic/v1", + "code": diagnostic_code, + "domain": "orchestration", + "address": "/reproduction/attempt", + "message": "The scheduled reproduction attempt did not produce valid evidence.", + "severity": "error", + } + ] + ) + return { + "schema_version": _RUN_SCHEMA, + "run_id": scheduled["run_id"], + "attempt_id": scheduled["attempt_id"], + "lane": scheduled["lane"], + "replicate": scheduled["replicate"], + "seed_label": scheduled["seed_label"], + "disposition": disposition, + "declaration_sha256": protocol["declaration_sha256"], + "protocol_sha256": protocol_sha256, + "stochastic_controls": _control_disposition(protocol, cast(str, scheduled["lane"])), + "metrics": metrics, + "metric_status": metric_status, + "cleanup": { + "attempted": True, + "verified": cleanup_verified, + "receipt_ref": f"cleanup.{scheduled['attempt_id']}", + }, + "evidence_refs": evidence_refs, + "diagnostics": diagnostics, + } + + +def terminal_rows_from_results( + protocol: Mapping[str, object], + *, + native_results: Sequence[Mapping[str, object]], + mediated_results: Sequence[Mapping[str, object]], + protocol_sha256: str, +) -> list[dict[str, object]]: + """Project two complete result vectors onto the preallocated schedule.""" + + declaration = cast(dict[str, object], protocol["declaration"]) + schedule = cast(list[dict[str, object]], declaration["schedule"]) + by_lane = { + "source-native": native_results, + "raes-mediated": mediated_results, + } + rows: list[dict[str, object]] = [] + positions = dict.fromkeys(_LANES, 0) + for scheduled in schedule: + lane = cast(str, scheduled["lane"]) + index = positions[lane] + values = by_lane[lane] + if index >= len(values): + raise ValueError("result vector does not match the frozen schedule") + rows.append( + _terminal_row( + protocol, + scheduled, + result=values[index], + disposition="valid", + protocol_sha256=protocol_sha256, + ) + ) + positions[lane] += 1 + if any(positions[lane] != len(by_lane[lane]) for lane in _LANES): + raise ValueError("result vector does not match the frozen schedule") + return rows + + +def _write_rows(root: Path, rows: Sequence[Mapping[str, object]]) -> None: + runs_root = root / "runs" + os.mkdir(runs_root, 0o700) + for row in rows: + run_root = runs_root / cast(str, row["run_id"]) + os.mkdir(run_root, 0o700) + atomic_write_json_artifact(run_root / "record.json", dict(row)) + + +def load_terminal_rows(root: Path) -> list[dict[str, object]]: + """Load terminal rows in stable run-id order.""" + + rows = [load_strict_json(path) for path in sorted((root / "runs").glob("*/record.json"))] + for row in rows: + _validate_terminal_row(row) + return rows + + +def _validate_metric_value(metric: str, value: object) -> None: + if value is None: + return + if metric == "steps_to_termination": + if type(value) is not int or not 0 <= value <= 600: + raise ValueError("run metric is invalid") + elif metric == "cumulative_attacker_reward": + if ( + not isinstance(value, (int, float)) + or isinstance(value, bool) + or not math.isfinite(value) + ): + raise ValueError("run metric is invalid") + elif metric == "network_availability": + if not isinstance(value, list) or not value: + raise ValueError("run metric is invalid") + if any( + not isinstance(item, (int, float)) + or isinstance(item, bool) + or not math.isfinite(item) + or not 0.0 <= item <= 1.0 + for item in value + ): + raise ValueError("run metric is invalid") + elif metric == "terminal_cause" and value not in { + "attacker-ownership", + "defender-sla", + "defender-eviction", + "evaluator-cutoff", + }: + raise ValueError("run metric is invalid") + + +def _validate_terminal_row(row: Mapping[str, object]) -> None: + expected = frozenset( + { + "schema_version", + "run_id", + "attempt_id", + "lane", + "replicate", + "seed_label", + "disposition", + "declaration_sha256", + "protocol_sha256", + "stochastic_controls", + "metrics", + "metric_status", + "cleanup", + "evidence_refs", + "diagnostics", + } + ) + _require_keys(row, expected, "terminal run") + if row["schema_version"] != _RUN_SCHEMA or row["disposition"] not in _DISPOSITIONS: + raise ValueError("terminal run is invalid") + metrics = row["metrics"] + statuses = row["metric_status"] + if not isinstance(metrics, dict) or set(metrics) != set(_METRICS): + raise ValueError("terminal run metrics are invalid") + if not isinstance(statuses, dict) or set(statuses) != set(_METRICS): + raise ValueError("terminal run metrics are invalid") + for metric, value in metrics.items(): + _validate_metric_value(metric, value) + expected_status = "available" if value is not None else "unavailable" + if statuses[metric] != expected_status: + raise ValueError("terminal run metric status is invalid") + + +def _failed_rows(protocol: Mapping[str, object], lane: str, code: str) -> list[dict[str, object]]: + schedule = cast(dict[str, object], protocol["declaration"])["schedule"] + return [ + _terminal_row( + protocol, + entry, + result=None, + disposition="failed", + protocol_sha256=None, + diagnostic_code=code, + ) + for entry in cast(list[dict[str, object]], schedule) + if entry["lane"] == lane + ] + + +def collect_native( + declaration_root: Path, + output: Path, + *, + executor: Callable[[], list[dict[str, object]]] | None = None, +) -> Path: + """Collect the one exact upstream ten-episode batch and freeze its oracle.""" + + protocol = load_strict_json(declaration_root / "protocol.json") + validate_protocol(protocol, require_oracle=False) + _verify_inventory(declaration_root) + root = _reserve_directory(output) + source_ledger = load_strict_json(declaration_root / "source-ledger.json") + validate_source_ledger(source_ledger, protocol) + atomic_write_json_artifact(root / "source-ledger.json", source_ledger) + atomic_write_json_artifact(root / "environment.json", _environment_payload("source-native")) + bench_notes = _load_bench_notes(declaration_root, protocol) + _append_bench_note( + bench_notes, + protocol, + phase="native", + severity="info", + event_code="native-collection-started", + summary="The exact admitted upstream ten-episode evaluator batch was started.", + disposition="observed", + evidence_paths=("protocol.json", "source-ledger.json", "environment.json"), + ) + _write_bench_notes(root, bench_notes) + execute = executor if executor is not None else _execute_native_batch + try: + results = execute() + if len(results) != _ATTEMPTS_PER_LANE: + raise ValueError("native evaluator returned the wrong episode count") + native_schedule = [ + entry + for entry in cast(list[dict[str, object]], protocol["declaration"]["schedule"]) # type: ignore[index] + if entry["lane"] == "source-native" + ] + rows = [ + _terminal_row( + protocol, + scheduled, + result=result, + disposition="valid", + protocol_sha256=None, + ) + for scheduled, result in zip(native_schedule, results, strict=True) + ] + for row in rows: + _validate_terminal_row(row) + except Exception: + rows = _failed_rows(protocol, "source-native", "reproduction.native.execution-failed") + _write_rows(root, rows) + atomic_write_json_artifact(root / "protocol.json", protocol) + atomic_write_json_artifact( + root / "collection.json", + {"lane": "source-native", "terminal_count": len(rows), "valid_count": 0}, + ) + for row in rows: + run_id = cast(str, row["run_id"]) + _append_bench_note( + bench_notes, + protocol, + phase="native", + severity="error", + event_code="native-attempt-terminalized", + summary=f"Scheduled source-native attempt {run_id} was terminalized as failed.", + disposition="failed", + evidence_paths=(f"runs/{run_id}/record.json",), + ) + _append_bench_note( + bench_notes, + protocol, + phase="native", + severity="error", + event_code="native-collection-failed", + summary=( + "The source-native batch failed; all ten scheduled attempts remain retained " + "as failed." + ), + disposition="failed", + evidence_paths=("protocol.json",), + ) + _write_bench_notes(root, bench_notes) + _seal_inventory(root) + raise RuntimeError("native collection failed") from None + ordered = [ + {"run_id": row["run_id"], "metrics": row["metrics"]} + for row in sorted(rows, key=lambda item: cast(int, item["replicate"])) + ] + result_set_sha256 = sha256_payload(ordered) + completed = copy_protocol = json.loads(json.dumps(protocol)) + copy_protocol["oracle"] = { + "lane": "source-native", + "declaration_sha256": protocol["declaration_sha256"], + "native_result_set_sha256": result_set_sha256, + "ordered_results": ordered, + } + validate_protocol(completed, require_oracle=True) + _write_rows(root, rows) + atomic_write_json_artifact(root / "protocol.json", completed) + atomic_write_json_artifact( + root / "collection.json", + { + "lane": "source-native", + "terminal_count": len(rows), + "valid_count": len(rows), + "native_result_set_sha256": result_set_sha256, + }, + ) + for row in rows: + run_id = cast(str, row["run_id"]) + _append_bench_note( + bench_notes, + completed, + phase="native", + severity="info", + event_code="native-attempt-terminalized", + summary=f"Scheduled source-native attempt {run_id} was terminalized as valid.", + disposition="passed", + evidence_paths=(f"runs/{run_id}/record.json",), + ) + _append_bench_note( + bench_notes, + completed, + phase="native", + severity="info", + event_code="native-collection-passed", + summary="The exact upstream evaluator returned all ten scheduled terminal results.", + disposition="passed", + evidence_paths=("protocol.json",), + ) + _write_bench_notes(root, bench_notes) + _seal_inventory(root) + return root + + +def collect_mediated( + oracle_root: Path, + pack_root: Path, + output: Path, + *, + runner: Callable[[dict[str, object], Path], dict[str, object]] | None = None, +) -> Path: + """Collect ten independent RAES-mediated attempts without silent drops.""" + + protocol_path = oracle_root / "protocol.json" + protocol = load_strict_json(protocol_path) + validate_protocol(protocol, require_oracle=True) + _verify_inventory(oracle_root) + protocol_digest = _sha256_file(protocol_path) + root = _reserve_directory(output) + atomic_write_json_artifact(root / "protocol.json", protocol) + atomic_write_json_artifact(root / "environment.json", _environment_payload("raes-mediated")) + bench_notes = _new_bench_notes(protocol) + _append_bench_note( + bench_notes, + protocol, + phase="mediated", + severity="info", + event_code="mediated-collection-started", + summary="The ten preallocated RAES-mediated attempts were started with zero retries.", + disposition="observed", + evidence_paths=("protocol.json", "environment.json"), + ) + _write_bench_notes(root, bench_notes) + runs_root = root / "runs" + os.mkdir(runs_root, 0o700) + execute = runner if runner is not None else _execute_mediated_attempt + schedule = [ + entry + for entry in cast(list[dict[str, object]], protocol["declaration"]["schedule"]) # type: ignore[index] + if entry["lane"] == "raes-mediated" + ] + rows: list[dict[str, object]] = [] + for scheduled in schedule: + run_id = cast(str, scheduled["run_id"]) + run_root = runs_root / cast(str, scheduled["run_id"]) + os.mkdir(run_root, 0o700) + _append_bench_note( + bench_notes, + protocol, + phase="mediated", + severity="info", + event_code="mediated-attempt-started", + summary=f"Scheduled RAES-mediated attempt {run_id} was started.", + disposition="observed", + evidence_paths=("protocol.json",), + ) + _write_bench_notes(root, bench_notes) + try: + result = execute({**scheduled, "pack_root": pack_root.as_posix()}, run_root) + row = _terminal_row( + protocol, + scheduled, + result=result, + disposition="valid", + protocol_sha256=protocol_digest, + ) + _validate_terminal_row(row) + except Exception: + row = _terminal_row( + protocol, + scheduled, + result=None, + disposition="failed", + protocol_sha256=protocol_digest, + diagnostic_code="reproduction.mediated.execution-failed", + ) + atomic_write_json_artifact(run_root / "record.json", row) + rows.append(row) + valid = row["disposition"] == "valid" + _append_bench_note( + bench_notes, + protocol, + phase="mediated", + severity="info" if valid else "error", + event_code="mediated-attempt-terminalized", + summary=( + f"Scheduled RAES-mediated attempt {run_id} was terminalized as " + f"{row['disposition']}." + ), + disposition="passed" if valid else "failed", + evidence_paths=(f"runs/{run_id}/record.json",), + ) + _write_bench_notes(root, bench_notes) + atomic_write_json_artifact( + root / "collection.json", + { + "lane": "raes-mediated", + "terminal_count": len(rows), + "valid_count": sum(row["disposition"] == "valid" for row in rows), + "protocol_sha256": protocol_digest, + }, + ) + valid_count = sum(row["disposition"] == "valid" for row in rows) + _append_bench_note( + bench_notes, + protocol, + phase="mediated", + severity="info" if valid_count == len(rows) else "warning", + event_code="mediated-collection-completed", + summary=( + f"The RAES-mediated lane terminalized all ten attempts; {valid_count} were valid " + f"and {len(rows) - valid_count} failed." + ), + disposition="passed" if valid_count == len(rows) else "weakened", + evidence_paths=tuple(f"runs/{row['run_id']}/record.json" for row in rows), + ) + _write_bench_notes(root, bench_notes) + _seal_inventory(root) + return root + + +def _numeric_value(row: Mapping[str, object], metric: str) -> float | None: + metrics = cast(dict[str, object], row["metrics"]) + value = metrics[metric] + if value is None: + return None + if metric == "network_availability": + return statistics.fmean(cast(list[float], value)) + return float(cast(int | float, value)) + + +def _percentile(values: Sequence[float], probability: float) -> float: + ordered = sorted(values) + if len(ordered) == 1: + return ordered[0] + position = probability * (len(ordered) - 1) + lower = math.floor(position) + upper = math.ceil(position) + if lower == upper: + return ordered[lower] + fraction = position - lower + return ordered[lower] + fraction * (ordered[upper] - ordered[lower]) + + +def _draw_index( + declaration_sha256: str, metric: str, lane: str, sample: int, position: int, count: int +) -> int: + address = f"{declaration_sha256}:{metric}:{lane}:{sample}:{position}".encode() + return int.from_bytes(hashlib.sha256(address).digest()[:8], "big") % count + + +def _bootstrap_means( + values: Sequence[float], declaration_sha256: str, metric: str, lane: str, count: int +) -> list[float]: + return [ + statistics.fmean( + values[_draw_index(declaration_sha256, metric, lane, sample, position, len(values))] + for position in range(len(values)) + ) + for sample in range(count) + ] + + +def _numeric_summary( + values: Sequence[float], declaration_sha256: str, metric: str, lane: str, resamples: int +) -> dict[str, object]: + bootstraps = _bootstrap_means(values, declaration_sha256, metric, lane, resamples) + return { + "available_count": len(values), + "mean": statistics.fmean(values), + "median": statistics.median(values), + "sample_standard_deviation": statistics.stdev(values) if len(values) > 1 else 0.0, + "minimum": min(values), + "maximum": max(values), + "mean_interval_95": { + "lower": _percentile(bootstraps, 0.025), + "upper": _percentile(bootstraps, 0.975), + }, + } + + +def compute_aggregates( + protocol: Mapping[str, object], rows: Sequence[Mapping[str, object]] +) -> dict[str, object]: + """Purely recompute all aggregate and comparison projections.""" + + validate_protocol(protocol, require_oracle=False) + ordered_rows = sorted( + rows, key=lambda item: (cast(str, item["lane"]), cast(int, item["replicate"])) + ) + for row in ordered_rows: + _validate_terminal_row(row) + declaration = cast(dict[str, object], protocol["declaration"]) + resamples = cast(dict[str, object], declaration["aggregation"])["bootstrap_resamples"] + if type(resamples) is not int or resamples < 1: + raise ValueError("bootstrap declaration is invalid") + declaration_digest = cast(str, protocol["declaration_sha256"]) + lanes: dict[str, object] = {} + numeric_metrics = _METRICS[:-1] + lane_values: dict[str, dict[str, list[float]]] = { + lane: {metric: [] for metric in numeric_metrics} for lane in _LANES + } + terminal_values: dict[str, list[str]] = {lane: [] for lane in _LANES} + for lane in _LANES: + selected = [row for row in ordered_rows if row["lane"] == lane] + disposition_counts = { + disposition: sum(row["disposition"] == disposition for row in selected) + for disposition in sorted(_DISPOSITIONS) + } + metric_payloads: dict[str, object] = {} + for metric in numeric_metrics: + values = [ + value + for row in selected + if row["disposition"] == "valid" + and (value := _numeric_value(row, metric)) is not None + ] + lane_values[lane][metric] = values + summary = ( + _numeric_summary(values, declaration_digest, metric, lane, resamples) + if values + else {"available_count": 0} + ) + summary["missing_count"] = len(selected) - len(values) + metric_payloads[metric] = summary + causes = [ + cast(str, cast(dict[str, object], row["metrics"])["terminal_cause"]) + for row in selected + if row["disposition"] == "valid" + and cast(dict[str, object], row["metrics"])["terminal_cause"] is not None + ] + terminal_values[lane] = causes + categories = sorted(set(causes)) + metric_payloads["terminal_cause"] = { + "available_count": len(causes), + "missing_count": len(selected) - len(causes), + "proportions": { + category: causes.count(category) / len(causes) for category in categories + }, + } + lanes[lane] = { + "scheduled_count": len(selected), + "dispositions": disposition_counts, + "metrics": metric_payloads, + } + tolerances = cast( + dict[str, object], cast(dict[str, object], declaration["comparison"])["bounded"] + ) + comparisons: dict[str, object] = {} + for metric in numeric_metrics: + native = lane_values["source-native"][metric] + mediated = lane_values["raes-mediated"][metric] + if len(native) != _ATTEMPTS_PER_LANE or len(mediated) != _ATTEMPTS_PER_LANE: + comparisons[metric] = { + "result": "unavailable", + "mean_difference": None, + "interval_95": None, + } + continue + native_boot = _bootstrap_means( + native, declaration_digest, metric, "source-native", resamples + ) + mediated_boot = _bootstrap_means( + mediated, declaration_digest, metric, "raes-mediated", resamples + ) + numeric_differences = [ + right - left for left, right in zip(native_boot, mediated_boot, strict=True) + ] + interval = { + "lower": _percentile(numeric_differences, 0.025), + "upper": _percentile(numeric_differences, 0.975), + } + tolerance_value = tolerances[metric] + if not isinstance(tolerance_value, (int, float)) or isinstance(tolerance_value, bool): + raise ValueError("comparison tolerance is invalid") + tolerance = float(tolerance_value) + exact = native == mediated + bounded = interval["lower"] >= -tolerance and interval["upper"] <= tolerance + comparisons[metric] = { + "result": "exact" if exact else "bounded" if bounded else "outside-tolerance", + "mean_difference": statistics.fmean(mediated) - statistics.fmean(native), + "interval_95": interval, + "tolerance": tolerance, + } + native_causes = terminal_values["source-native"] + mediated_causes = terminal_values["raes-mediated"] + if len(native_causes) != _ATTEMPTS_PER_LANE or len(mediated_causes) != _ATTEMPTS_PER_LANE: + comparisons["terminal_cause"] = {"result": "unavailable", "proportion_differences": None} + else: + categories = sorted(set(native_causes) | set(mediated_causes)) + cause_differences = { + category: mediated_causes.count(category) / len(mediated_causes) + - native_causes.count(category) / len(native_causes) + for category in categories + } + tolerance_value = tolerances["terminal_cause"] + if not isinstance(tolerance_value, (int, float)) or isinstance(tolerance_value, bool): + raise ValueError("comparison tolerance is invalid") + tolerance = float(tolerance_value) + comparisons["terminal_cause"] = { + "result": ( + "exact" + if native_causes == mediated_causes + else "bounded" + if all(abs(value) <= tolerance for value in cause_differences.values()) + else "outside-tolerance" + ), + "proportion_differences": cause_differences, + "tolerance": tolerance, + } + return { + "schema_version": _AGGREGATE_SCHEMA, + "declaration_sha256": declaration_digest, + "scheduled_count": len(ordered_rows), + "lanes": lanes, + "comparisons": comparisons, + "bootstrap": { + "resamples": resamples, + "method": "counter-addressed-sha256-percentile", + "interval_level": 0.95, + }, + } + + +def _installed_version(name: str) -> str: + try: + return importlib.metadata.version(name) + except importlib.metadata.PackageNotFoundError: + return "not-installed" + + +def _installed_source_artifact_sha256() -> str: + """Return only the installed wheel digest, never its local URL.""" + + try: + distribution = importlib.metadata.distribution("cyberbattlesim") + direct_text = distribution.read_text("direct_url.json") + if direct_text is None: + return "unavailable" + direct = json.loads(direct_text) + if not isinstance(direct, dict): + return "unavailable" + archive = direct.get("archive_info") + if not isinstance(archive, dict): + return "unavailable" + digest = archive.get("hash") + if isinstance(digest, str) and digest.startswith("sha256=") and _is_sha256(digest[7:]): + return digest[7:] + hashes = archive.get("hashes") + if isinstance(hashes, dict) and _is_sha256(hashes.get("sha256")): + return cast(str, hashes["sha256"]) + except ( + importlib.metadata.PackageNotFoundError, + OSError, + UnicodeError, + json.JSONDecodeError, + ): + pass + return "unavailable" + + +def _physical_memory_bytes() -> int | None: + try: + return int(os.sysconf("SC_PAGE_SIZE")) * int(os.sysconf("SC_PHYS_PAGES")) + except (OSError, ValueError): + return None + + +def _environment_payload(lane: str) -> dict[str, object]: + qualification = cast(dict[str, object], load_qualification()) + source = cast(dict[str, object], qualification["source"]) + return { + "schema_version": "cyberbattlesim-baseline-environment/v1", + "lane": lane, + "machine": { + "architecture": platform.machine(), + "operating_system": platform.system(), + "operating_system_release": platform.release(), + "logical_cpu_count": os.cpu_count(), + "physical_memory_bytes": _physical_memory_bytes(), + }, + "python": { + "implementation": platform.python_implementation(), + "version": platform.python_version(), + }, + "software": { + name: _installed_version(name) + for name in ( + "cyberbattlesim", + "gymnasium", + "numpy", + "raes", + "raes-adapters", + "raes-env-packs", + ) + }, + "source": { + "commit": source["commit"], + "tree": source["tree"], + "version": source["version"], + "installed_artifact_sha256": _installed_source_artifact_sha256(), + }, + "pack": { + "identity": "cyberbattlesim-chain", + "version": "1.0.0", + "content_digest": ( + "sha256:66493882579d5cba87248c5722782ff5ded5f0d7423f4e559f15bfb61712a905" + ), + }, + "limitations": [ + "The upstream source has no selected public index or release artifact.", + "Python-global and NumPy-global random streams are unbound in the mediated lane.", + "All four observed random streams are unbound in the source-native lane.", + "The authored RAES topology is representative rather than state-identical.", + ( + "The mediated evaluator does not retain availability series or a specific " + "terminal cause." + ), + ], + } + + +def _validate_lane_environment(payload: Mapping[str, object], lane: str) -> None: + _require_keys( + payload, + frozenset( + { + "schema_version", + "lane", + "machine", + "python", + "software", + "source", + "pack", + "limitations", + } + ), + "lane environment", + ) + if payload["schema_version"] != "cyberbattlesim-baseline-environment/v1": + raise ValueError("lane environment schema is invalid") + if payload["lane"] != lane: + raise ValueError("lane environment identity is invalid") + closed = { + "machine": frozenset( + { + "architecture", + "operating_system", + "operating_system_release", + "logical_cpu_count", + "physical_memory_bytes", + } + ), + "python": frozenset({"implementation", "version"}), + "software": frozenset( + { + "cyberbattlesim", + "gymnasium", + "numpy", + "raes", + "raes-adapters", + "raes-env-packs", + } + ), + "source": frozenset({"commit", "tree", "version", "installed_artifact_sha256"}), + "pack": frozenset({"identity", "version", "content_digest"}), + } + for field, keys in closed.items(): + value = payload[field] + if not isinstance(value, dict): + raise ValueError("lane environment is invalid") + _require_keys(value, keys, f"lane environment {field}") + limitations = payload["limitations"] + if ( + not isinstance(limitations, list) + or not limitations + or any(not isinstance(item, str) for item in limitations) + ): + raise ValueError("lane environment limitations are invalid") + + +def _validate_combined_environment(payload: Mapping[str, object]) -> None: + _require_keys( + payload, + frozenset( + { + "schema_version", + "source_native", + "raes_mediated", + "research_consumers", + "publication_scope", + "limitations", + } + ), + "combined environment", + ) + if payload["schema_version"] != "cyberbattlesim-baseline-environment-pair/v1": + raise ValueError("combined environment schema is invalid") + native = payload["source_native"] + mediated = payload["raes_mediated"] + if not isinstance(native, dict) or not isinstance(mediated, dict): + raise ValueError("combined environment lanes are invalid") + _validate_lane_environment(native, "source-native") + _validate_lane_environment(mediated, "raes-mediated") + if payload["research_consumers"] != ["OpenRAE/research#14", "OpenRAE/research#20"]: + raise ValueError("combined environment consumers are invalid") + + +def _worker_environment(work_root: Path) -> dict[str, str]: + home = work_root / "home" + cache = work_root / "cache" + temporary = work_root / "tmp" + for path in (home, cache, temporary): + path.mkdir(mode=0o700) + return { + "HOME": home.as_posix(), + "LANG": "C.UTF-8", + "LC_ALL": "C.UTF-8", + "MPLBACKEND": "Agg", + "PATH": "/usr/local/bin:/usr/bin:/bin", + "PYTHONPATH": "", + "PYTHONSAFEPATH": "1", + "TMPDIR": temporary.as_posix(), + "XDG_CACHE_HOME": cache.as_posix(), + } + + +def _native_worker(output: Path) -> None: + """Run the exact upstream evaluator and retain raw vectors only in scratch.""" + + verify_selected_cyberbattlesim_source() + qualification = cast(dict[str, object], load_qualification()) + selection = cast( + dict[str, object], cast(dict[str, object], qualification["protocol"])["selection"] + ) + attacker = cast(dict[str, object], selection["attacker"]) + bounds_selection = cast(dict[str, object], attacker["environment_bounds"]) + environment = cast(_NativeEvaluatorEnvironment, construct_selected_cyberbattlesim_environment()) + cleanup_verified = False + result: object | None = None + try: + learner_module = importlib.import_module("cyberbattle.agents.baseline.learner") + policy_module = importlib.import_module( + "cyberbattle.agents.baseline.agent_randomcredlookup" + ) + wrapper_module = importlib.import_module("cyberbattle.agents.baseline.agent_wrapper") + bounds = wrapper_module.EnvironmentBounds.of_identifiers( + maximum_total_credentials=bounds_selection["maximum_total_credentials"], + maximum_node_count=bounds_selection["maximum_node_count"], + identifiers=environment.identifiers, + ) + policy = policy_module.CredentialCacheExploiter() + with ( + Path(os.devnull).open("w", encoding="utf-8") as sink, + contextlib.redirect_stdout(sink), + contextlib.redirect_stderr(sink), + ): + result = learner_module.epsilon_greedy_search( + cyberbattle_gym_env=environment, + environment_properties=bounds, + learner=policy, + title="Credential lookups (epsilon-greedy)", + episode_count=attacker["episode_count"], + iteration_count=attacker["iteration_count"], + epsilon=attacker["epsilon"], + render=False, + epsilon_exponential_decay=attacker["epsilon_exponential_decay"], + epsilon_minimum=attacker["epsilon_minimum"], + verbosity=wrapper_module.Verbosity.Quiet, + ) + finally: + try: + environment.close() + cleanup_verified = True + except Exception: + cleanup_verified = False + if not isinstance(result, dict): + raise RuntimeError("native evaluator returned an unsupported result") + rewards = result.get("all_episodes_rewards") + availability = result.get("all_episodes_availability") + if not isinstance(rewards, list) or not isinstance(availability, list): + raise RuntimeError("native evaluator returned an unsupported result") + if len(rewards) != _ATTEMPTS_PER_LANE or len(availability) != _ATTEMPTS_PER_LANE: + raise RuntimeError("native evaluator returned an unsupported result") + atomic_write_json_artifact( + output, + { + "episodes": [ + {"rewards": episode_rewards, "availability": episode_availability} + for episode_rewards, episode_availability in zip(rewards, availability, strict=True) + ], + "cleanup_verified": cleanup_verified, + }, + ) + + +def _terminal_cause( + rewards: Sequence[float], availability: Sequence[float], maximum_steps: int +) -> str | None: + if not rewards or len(rewards) != len(availability): + return None + last_reward = rewards[-1] + last_availability = availability[-1] + if last_reward == 5000.0: + return "defender-sla" if last_availability < 0.8 else "attacker-ownership" + if len(rewards) < maximum_steps and last_reward == 0.0: + return "defender-eviction" + if len(rewards) == maximum_steps and last_reward != 5000.0: + return "evaluator-cutoff" + return None + + +def _execute_native_batch() -> list[dict[str, object]]: + with tempfile.TemporaryDirectory(prefix="cyberbattlesim-native-") as scratch: + work_root = Path(scratch) + output = work_root / "native-worker.json" + command = [ + sys.executable, + "-m", + "raes_adapters.cyberbattlesim.reproduction", + "_native-worker", + "--output", + output.as_posix(), + ] + try: + completed = subprocess.run( + command, + cwd=work_root, + env=_worker_environment(work_root), + stdin=subprocess.DEVNULL, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + timeout=1800, + check=False, + ) + except subprocess.TimeoutExpired as error: + raise RuntimeError("native evaluator timed out") from error + if completed.returncode != 0: + raise RuntimeError("native evaluator failed") + payload = load_strict_json(output) + _require_keys(payload, frozenset({"episodes", "cleanup_verified"}), "native worker") + episodes = payload["episodes"] + if not isinstance(episodes, list) or len(episodes) != _ATTEMPTS_PER_LANE: + raise RuntimeError("native evaluator returned an unsupported result") + results: list[dict[str, object]] = [] + for episode in episodes: + if not isinstance(episode, dict) or set(episode) != {"rewards", "availability"}: + raise RuntimeError("native evaluator returned an unsupported result") + rewards = episode["rewards"] + availability = episode["availability"] + if not isinstance(rewards, list) or not isinstance(availability, list): + raise RuntimeError("native evaluator returned an unsupported result") + if len(rewards) != len(availability) or not 1 <= len(rewards) <= 600: + raise RuntimeError("native evaluator returned an unsupported result") + numeric_rewards = [float(value) for value in rewards] + numeric_availability = [float(value) for value in availability] + if any(not math.isfinite(value) for value in numeric_rewards): + raise RuntimeError("native evaluator returned an unsupported result") + if any( + not math.isfinite(value) or not 0.0 <= value <= 1.0 + for value in numeric_availability + ): + raise RuntimeError("native evaluator returned an unsupported result") + results.append( + { + "steps_to_termination": len(numeric_rewards), + "cumulative_attacker_reward": math.fsum(numeric_rewards), + "network_availability": numeric_availability, + "terminal_cause": _terminal_cause(numeric_rewards, numeric_availability, 600), + "cleanup_verified": payload["cleanup_verified"] is True, + "evidence_refs": [], + } + ) + return results + + +def _execute_mediated_attempt(schedule: dict[str, object], run_root: Path) -> dict[str, object]: + pack_root = Path(cast(str, schedule["pack_root"])).resolve() + run_id = cast(str, schedule["run_id"]) + command = [ + sys.executable, + "-m", + "raes_adapters.cli", + "run", + "--backend", + "cyberbattlesim-chain", + "--mode", + "smoke", + "--pack", + pack_root.as_posix(), + "--pack-digest", + "sha256:66493882579d5cba87248c5722782ff5ded5f0d7423f4e559f15bfb61712a905", + "--scenario", + "sdl/cyberbattlesim-chain.sdl.yaml", + "--scenario-digest", + "sha256:9d696ea7fa23a1e7cf4c1cbc145a7989370dc4e9afff2cd5a17d6d1af887b528", + "--experiment", + "experiment/cyberbattlesim-chain.spec.exp.json", + "--task", + "experiment/cyberbattlesim-chain.task.exp.json", + "--participant-implementation", + "cyberbattlesim-red-credential-cache", + "--participant-manifest", + "participant/cyberbattlesim-red-credential-cache.manifest.json", + "--participant-selection", + "participant/cyberbattlesim-red-credential-cache.selection.json", + "--participant-configuration", + "participant/cyberbattlesim-red-credential-cache.configuration.json", + "--trial-length", + "600", + "--seed", + str(_SEED_LABEL), + "--run-id", + run_id, + "--output", + "portable", + ] + with tempfile.TemporaryDirectory(prefix="cyberbattlesim-mediated-") as scratch: + try: + completed = subprocess.run( + command, + cwd=run_root, + env=_worker_environment(Path(scratch)), + stdin=subprocess.DEVNULL, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + timeout=900, + check=False, + ) + except subprocess.TimeoutExpired as error: + raise RuntimeError("mediated execution timed out") from error + if completed.returncode != 0: + raise RuntimeError("mediated execution failed") + portable = run_root / "portable" + summary = load_strict_json(portable / "summary.json") + run_summary = load_strict_json(portable / "runs" / f"{run_id}-1" / "summary.json") + derived_path = portable / "runs" / f"{run_id}-1" / "derived-measures.json" + derived = _load_strict_value(derived_path) + if not isinstance(derived, list) or len(derived) != 1 or not isinstance(derived[0], dict): + raise RuntimeError("mediated evidence is invalid") + reward = derived[0].get("value") + steps = run_summary.get("completed_steps") + if type(steps) is not int or not isinstance(reward, (int, float)) or isinstance(reward, bool): + raise RuntimeError("mediated evidence is invalid") + if not math.isfinite(float(reward)) or summary.get("disposition") != "succeeded": + raise RuntimeError("mediated evidence is invalid") + evidence_paths = ( + portable / "runs" / f"{run_id}-1" / "run.json", + portable / "runs" / f"{run_id}-1" / "evidence-records.json", + derived_path, + portable / _INVENTORY_NAME, + ) + return { + "steps_to_termination": steps, + "cumulative_attacker_reward": float(reward), + "network_availability": None, + "terminal_cause": None, + "cleanup_verified": run_summary.get("cleanup_verified") is True, + "evidence_refs": [ + { + "path": path.relative_to(run_root).as_posix(), + "sha256": _sha256_file(path), + } + for path in evidence_paths + ], + } + + +def _inventory_payload(root: Path) -> dict[str, object]: + artifacts = [] + for path in sorted(item for item in root.rglob("*") if item.is_file()): + if path.name == _INVENTORY_NAME: + continue + content = path.read_bytes() + artifacts.append( + { + "path": path.relative_to(root).as_posix(), + "media_type": _media_type(path), + "sha256": hashlib.sha256(content).hexdigest(), + "size_bytes": len(content), + } + ) + return {"artifacts": artifacts} + + +def _verify_inventory(root: Path) -> None: + recorded = load_strict_json(root / _INVENTORY_NAME) + if recorded != _inventory_payload(root): + raise ValueError("artifact inventory is invalid") + + +def _combined_environment(native_root: Path, mediated_root: Path) -> dict[str, object]: + native = load_strict_json(native_root / "environment.json") + mediated = load_strict_json(mediated_root / "environment.json") + _validate_lane_environment(native, "source-native") + _validate_lane_environment(mediated, "raes-mediated") + limitations = sorted( + { + item + for payload in (native, mediated) + for item in cast(list[object], payload.get("limitations", [])) + if isinstance(item, str) + } + ) + combined: dict[str, object] = { + "schema_version": "cyberbattlesim-baseline-environment-pair/v1", + "source_native": native, + "raes_mediated": mediated, + "research_consumers": ["OpenRAE/research#14", "OpenRAE/research#20"], + "publication_scope": "reviewed public, non-sensitive reproduction evidence", + "limitations": limitations, + } + _validate_combined_environment(combined) + return combined + + +def _citation(path: str, pointer: str, digests: Mapping[str, str]) -> dict[str, object]: + return {"path": path, "sha256": digests[path], "json_pointer": pointer} + + +def compute_tiers( + protocol: Mapping[str, object], + source_ledger: Mapping[str, object], + environment: Mapping[str, object], + aggregates: Mapping[str, object], + digests: Mapping[str, str], +) -> dict[str, object]: + """Recompute the six fixed issue-30 tier projections.""" + + validate_protocol(protocol, require_oracle=True) + source_selection = cast( + dict[str, object], cast(dict[str, object], protocol["declaration"])["source_selection"] + ) + ledger_source = cast(dict[str, object], source_ledger["source"]) + authored_result = ( + "passed" + if all( + ledger_source.get(key) == source_selection.get(key) + for key in ("commit", "tree", "version", "runtime_tree_sha256", "notebook_sha256") + ) + else "failed" + ) + controls = cast( + dict[str, object], cast(dict[str, object], protocol["declaration"])["stochastic_controls"] + ) + execution_result = ( + "passed" if controls["source-native"] == controls["raes-mediated"] else "weakened" + ) + loss_refs = source_ledger.get("loss_refs") + state_result = ( + "weakened" + if isinstance(loss_refs, list) and "loss-abstracted-topology" in loss_refs + else "passed" + ) + comparisons = cast(dict[str, object], aggregates["comparisons"]) + comparison_results = { + cast(str, cast(dict[str, object], value)["result"]) for value in comparisons.values() + } + outcome_result = ( + "failed" + if "outside-tolerance" in comparison_results + else "weakened" + if "unavailable" in comparison_results + else "passed" + ) + limitations = environment.get("limitations") + disclosure_result = "passed" if isinstance(limitations, list) and limitations else "failed" + tier_rows = [ + { + "tier": "authored-source", + "result": authored_result, + "rationale": "Pinned source, tree, notebook, and runtime-tree identities join.", + "evidence": [_citation("source-ledger.json", "/source", digests)], + }, + { + "tier": "contract", + "result": "passed", + "rationale": ( + "The declaration embeds a validated RAES study over the published task/spec refs." + ), + "evidence": [_citation("protocol.json", "/declaration/study", digests)], + }, + { + "tier": "execution-control", + "result": execution_result, + "rationale": "Actual random-stream binding dispositions differ between lanes.", + "evidence": [_citation("protocol.json", "/declaration/stochastic_controls", digests)], + }, + { + "tier": "state-observation", + "result": state_result, + "rationale": ( + "The authored RAES topology is representative and native observations " + "remain private." + ), + "evidence": [_citation("source-ledger.json", "/loss_refs", digests)], + }, + { + "tier": "outcome-evaluation", + "result": outcome_result, + "rationale": "Only complete predeclared metric comparisons can pass this tier.", + "evidence": [_citation("aggregates.json", "/comparisons", digests)], + }, + { + "tier": "disclosure", + "result": disclosure_result, + "rationale": ( + "Known apparatus, source, stochastic, topology, and metric losses are retained." + ), + "evidence": [ + _citation("source-ledger.json", "/exclusions", digests), + _citation("environment.json", "/limitations", digests), + _citation("bench-notes.json", "/notes", digests), + ], + }, + ] + return { + "schema_version": "cyberbattlesim-baseline-tiers/v1", + "declaration_sha256": protocol["declaration_sha256"], + "tiers": tier_rows, + "explicit_non_claims": cast(dict[str, object], protocol["declaration"])[ + "explicit_non_claims" + ], + } + + +def _validation_report(revision: str) -> str: + return ( + "# CyberBattleSim baseline reproduction validation\n\n" + f"Frozen revision: `{revision}`\n\n" + "The bundle contains 20 preallocated terminal attempts: ten source-native " + "episodes and ten RAES-mediated episodes. Aggregate and tier projections are " + "derived only from retained portable evidence.\n\n" + "Offline verification command:\n\n" + "```bash\n" + "python -m raes_adapters.cyberbattlesim.reproduction verify --bundle .\n" + "```\n\n" + "Verification checks the frozen declaration/oracle, RAES study model, terminal " + "schedule, timestamped bench notes, per-file digests, evidence references, " + "aggregate recomputation, six tier citations, and the bounded leakage denylist. " + "It needs no network or native simulator import.\n\n" + "This artifact does not claim deterministic replay, exact state or observation " + "equivalence, cross-simulator equality, agent ranking, benchmark comparability, " + "outcome equivalence, or general scientific reproducibility.\n" + ) + + +def _assert_stage_rows( + protocol: Mapping[str, object], rows: Sequence[Mapping[str, object]] +) -> None: + schedule = cast( + list[dict[str, object]], cast(dict[str, object], protocol["declaration"])["schedule"] + ) + expected = {(entry["run_id"], entry["attempt_id"], entry["lane"]) for entry in schedule} + observed = {(row["run_id"], row["attempt_id"], row["lane"]) for row in rows} + if len(rows) != len(schedule) or observed != expected: + raise ValueError("terminal inventory does not match the frozen schedule") + if any(row["disposition"] not in _DISPOSITIONS for row in rows): + raise ValueError("terminal inventory contains a nonterminal attempt") + + +def _write_tier_projection( + root: Path, + protocol: Mapping[str, object], + source_ledger: Mapping[str, object], + environment: Mapping[str, object], + aggregates: Mapping[str, object], +) -> None: + digest_paths = ( + "protocol.json", + "source-ledger.json", + "environment.json", + "aggregates.json", + "bench-notes.json", + ) + digests = {name: _sha256_file(root / name) for name in digest_paths} + tiers = compute_tiers(protocol, source_ledger, environment, aggregates, digests) + atomic_write_json_artifact(root / "tiers.json", tiers) + + +def finalize_bundle(oracle_root: Path, mediated_root: Path, output: Path) -> Path: + """Assemble and seal the accepted bundle exactly once.""" + + _verify_inventory(oracle_root) + _verify_inventory(mediated_root) + oracle_protocol_path = oracle_root / "protocol.json" + mediated_protocol_path = mediated_root / "protocol.json" + if oracle_protocol_path.read_bytes() != mediated_protocol_path.read_bytes(): + raise ValueError("mediated collection is not bound to the frozen protocol") + protocol = load_strict_json(oracle_protocol_path) + validate_protocol(protocol, require_oracle=True) + if output.name != protocol["declaration_sha256"]: + raise ValueError("bundle directory is not the declaration-digest revision") + native_rows = load_terminal_rows(oracle_root) + mediated_rows = load_terminal_rows(mediated_root) + rows = native_rows + mediated_rows + _assert_stage_rows(protocol, rows) + ordered_native = [ + {"run_id": row["run_id"], "metrics": row["metrics"]} + for row in sorted(native_rows, key=lambda item: cast(int, item["replicate"])) + ] + oracle = cast(dict[str, object], protocol["oracle"]) + if sha256_payload(ordered_native) != oracle["native_result_set_sha256"]: + raise ValueError("source-native oracle does not match retained terminal evidence") + oracle_notes = _load_bench_notes(oracle_root, protocol) + mediated_notes = _load_bench_notes(mediated_root, protocol) + combined_notes = sorted( + cast(list[dict[str, object]], oracle_notes["notes"]) + + cast(list[dict[str, object]], mediated_notes["notes"]), + key=lambda note: (cast(str, note["recorded_at"]), cast(str, note["note_id"])), + ) + bench_notes = _new_bench_notes(protocol, combined_notes) + _validate_bench_notes(bench_notes, protocol) + root = _reserve_directory(output) + atomic_write_json_artifact(root / "protocol.json", protocol) + source_ledger = load_strict_json(oracle_root / "source-ledger.json") + validate_source_ledger(source_ledger, protocol) + atomic_write_json_artifact(root / "source-ledger.json", source_ledger) + environment = _combined_environment(oracle_root, mediated_root) + atomic_write_json_artifact(root / "environment.json", environment) + _append_bench_note( + bench_notes, + protocol, + phase="finalize", + severity="info", + event_code="bundle-finalization-started", + summary="Assembly of the content-addressed public bundle was started.", + disposition="observed", + evidence_paths=("protocol.json", "source-ledger.json", "environment.json"), + ) + _write_bench_notes(root, bench_notes) + runs_root = root / "runs" + os.mkdir(runs_root, 0o700) + for stage in (oracle_root, mediated_root): + for run in sorted((stage / "runs").iterdir()): + shutil.copytree(run, runs_root / run.name) + aggregates = compute_aggregates(protocol, rows) + atomic_write_json_artifact(root / "aggregates.json", aggregates) + revision_value = protocol["declaration_sha256"] + if not isinstance(revision_value, str): + raise ValueError("protocol declaration digest is invalid") + revision = revision_value + (root / "validation-report.md").write_text( + _validation_report(revision), encoding="utf-8", newline="\n" + ) + _append_bench_note( + bench_notes, + protocol, + phase="finalize", + severity="info", + event_code="bundle-finalized", + summary="All declared runs and derived public artifacts were assembled without drops.", + disposition="passed", + evidence_paths=("aggregates.json", "validation-report.md"), + ) + _append_bench_note( + bench_notes, + protocol, + phase="verify", + severity="info", + event_code="offline-verification-started", + summary="Pure offline recomputation and integrity verification were started.", + disposition="observed", + evidence_paths=("protocol.json", "aggregates.json"), + ) + _write_bench_notes(root, bench_notes) + _write_tier_projection(root, protocol, source_ledger, environment, aggregates) + _scan_portable(root) + _seal_inventory(root) + try: + verify_bundle(root) + except Exception: + _append_bench_note( + bench_notes, + protocol, + phase="verify", + severity="error", + event_code="offline-verification-failed", + summary="Pure offline recomputation or integrity verification failed.", + disposition="failed", + evidence_paths=("inventory.json",), + ) + _write_bench_notes(root, bench_notes) + _write_tier_projection(root, protocol, source_ledger, environment, aggregates) + _seal_inventory(root) + raise RuntimeError("final bundle offline verification failed") from None + _append_bench_note( + bench_notes, + protocol, + phase="verify", + severity="info", + event_code="offline-verification-passed", + summary="Pure offline recomputation and integrity verification passed.", + disposition="passed", + evidence_paths=("inventory.json", "aggregates.json", "tiers.json"), + ) + _write_bench_notes(root, bench_notes) + _write_tier_projection(root, protocol, source_ledger, environment, aggregates) + _scan_portable(root) + _seal_inventory(root) + try: + verify_bundle(root) + except Exception: + _append_bench_note( + bench_notes, + protocol, + phase="verify", + severity="error", + event_code="offline-verification-failed", + summary="The final note-bound bundle failed its second integrity verification.", + disposition="failed", + evidence_paths=("inventory.json",), + ) + _write_bench_notes(root, bench_notes) + _write_tier_projection(root, protocol, source_ledger, environment, aggregates) + _seal_inventory(root) + raise RuntimeError("final bundle offline verification failed") from None + return root + + +def _resolve_pointer(document: object, pointer: str) -> object: + if pointer == "": + return document + if not pointer.startswith("/"): + raise ValueError("tier citation JSON Pointer is invalid") + current = document + for encoded in pointer[1:].split("/"): + token = encoded.replace("~1", "/").replace("~0", "~") + if isinstance(current, dict) and token in current: + current = current[token] + elif isinstance(current, list) and token.isdigit() and int(token) < len(current): + current = current[int(token)] + else: + raise ValueError("tier citation JSON Pointer is unresolved") + return current + + +def _scan_portable(root: Path) -> None: + for path in sorted(item for item in root.rglob("*") if item.is_file()): + content = path.read_bytes() + if len(content) > 500 * 1024: + raise ValueError("portable artifact exceeds the repository size limit") + text = content.decode("utf-8", errors="ignore") + if any(token.casefold() in text.casefold() for token in _FORBIDDEN_PORTABLE_TOKENS): + raise ValueError("portable artifact contains a forbidden native value") + if any(prefix in text for prefix in ("/home/", "/tmp/", "file:///home/", "file:///tmp/")): + raise ValueError("portable artifact contains a host path") + + +def _validate_model_list(path: Path, model: type[object]) -> None: + payload = _load_strict_value(path) + if not isinstance(payload, list): + raise ValueError("portable RAES model collection is invalid") + validator = getattr(model, "model_validate", None) + if not callable(validator): + raise ValueError("portable RAES model validator is unavailable") + for item in payload: + validator(item) + + +def _validate_mediated_portable(run_root: Path, run_id: str) -> None: + portable = run_root / "portable" + archival = portable / "runs" / f"{run_id}-1" + ExperimentRunModel.model_validate(load_strict_json(archival / "run.json")) + ParticipantImplementationProvenanceModel.model_validate( + load_strict_json(archival / "participant-provenance.json") + ) + _validate_model_list(archival / "evidence-records.json", ExperimentEvidenceRecordModel) + _validate_model_list(archival / "derived-measures.json", ExperimentDerivedMeasureModel) + _validate_model_list(archival / "diagnostics.json", DiagnosticModel) + _verify_inventory(portable) + + +def verify_bundle(root: Path) -> dict[str, object]: + """Verify and recompute a sealed bundle without importing native source.""" + + root = root.resolve() + protocol = load_strict_json(root / "protocol.json") + validate_protocol(protocol, require_oracle=True) + source_ledger = load_strict_json(root / "source-ledger.json") + validate_source_ledger(source_ledger, protocol) + environment = load_strict_json(root / "environment.json") + _validate_combined_environment(environment) + bench_notes = _load_bench_notes(root, protocol) + notes = cast(list[dict[str, object]], bench_notes["notes"]) + for note in notes: + for ref in cast(list[dict[str, object]], note["evidence_refs"]): + target = (root / _safe_relative_path(ref["path"])).resolve() + if not target.is_relative_to(root) or not target.is_file(): + raise ValueError("bench note evidence reference is unresolved") + rows = load_terminal_rows(root) + _assert_stage_rows(protocol, rows) + protocol_digest = _sha256_file(root / "protocol.json") + for row in rows: + if row["declaration_sha256"] != protocol["declaration_sha256"]: + raise ValueError("terminal row declaration binding is invalid") + if row["lane"] == "raes-mediated" and row["protocol_sha256"] != protocol_digest: + raise ValueError("mediated terminal row protocol binding is invalid") + run_root = root / "runs" / cast(str, row["run_id"]) + if row["lane"] == "raes-mediated" and row["disposition"] == "valid": + _validate_mediated_portable(run_root, cast(str, row["run_id"])) + refs = row["evidence_refs"] + if not isinstance(refs, list): + raise ValueError("terminal row evidence references are invalid") + for ref in refs: + if not isinstance(ref, dict) or set(ref) != {"path", "sha256"}: + raise ValueError("terminal row evidence references are invalid") + relative = _safe_relative_path(ref["path"]) + target = (run_root / relative).resolve() + if not target.is_relative_to(run_root.resolve()) or not target.is_file(): + raise ValueError("terminal row evidence reference is unresolved") + if _sha256_file(target) != ref["sha256"]: + raise ValueError("terminal row evidence digest is invalid") + native_rows = sorted( + (row for row in rows if row["lane"] == "source-native"), + key=lambda item: cast(int, item["replicate"]), + ) + oracle_rows = [{"run_id": row["run_id"], "metrics": row["metrics"]} for row in native_rows] + oracle = cast(dict[str, object], protocol["oracle"]) + if sha256_payload(oracle_rows) != oracle["native_result_set_sha256"]: + raise ValueError("source-native oracle digest is invalid") + recorded_aggregates = load_strict_json(root / "aggregates.json") + expected_aggregates = compute_aggregates(protocol, rows) + if canonical_json_bytes(recorded_aggregates) != canonical_json_bytes(expected_aggregates): + raise ValueError("aggregate recomputation failed") + digests = { + name: _sha256_file(root / name) + for name in ( + "protocol.json", + "source-ledger.json", + "environment.json", + "aggregates.json", + "bench-notes.json", + ) + } + recorded_tiers = load_strict_json(root / "tiers.json") + expected_tiers = compute_tiers( + protocol, source_ledger, environment, recorded_aggregates, digests + ) + if canonical_json_bytes(recorded_tiers) != canonical_json_bytes(expected_tiers): + raise ValueError("tier recomputation failed") + tiers = recorded_tiers.get("tiers") + if not isinstance(tiers, list) or [ + item.get("tier") for item in tiers if isinstance(item, dict) + ] != list(_TIERS): + raise ValueError("tier inventory is invalid") + for tier in tiers: + if not isinstance(tier, dict) or tier.get("result") not in {"passed", "failed", "weakened"}: + raise ValueError("tier inventory is invalid") + evidence = tier.get("evidence") + if not isinstance(evidence, list) or not evidence: + raise ValueError("tier evidence is invalid") + for citation in evidence: + if not isinstance(citation, dict) or set(citation) != { + "path", + "sha256", + "json_pointer", + }: + raise ValueError("tier evidence is invalid") + relative = _safe_relative_path(citation["path"]) + target = root / relative + if not target.is_file() or _sha256_file(target) != citation["sha256"]: + raise ValueError("tier evidence digest is invalid") + _resolve_pointer(load_strict_json(target), cast(str, citation["json_pointer"])) + _scan_portable(root) + _verify_inventory(root) + return { + "disposition": "verified", + "scheduled_count": len(rows), + "tier_count": len(tiers), + "bench_note_count": len(notes), + "inventory_sha256": _sha256_file(root / _INVENTORY_NAME), + } + + +def _parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser(prog="python -m raes_adapters.cyberbattlesim.reproduction") + subcommands = parser.add_subparsers(dest="command", required=True) + declare = subcommands.add_parser("declare") + declare.add_argument("--output", type=Path, required=True) + native = subcommands.add_parser("native") + native.add_argument("--declaration", type=Path, required=True) + native.add_argument("--output", type=Path, required=True) + mediated = subcommands.add_parser("mediated") + mediated.add_argument("--oracle", type=Path, required=True) + mediated.add_argument("--pack", type=Path, required=True) + mediated.add_argument("--output", type=Path, required=True) + finalize = subcommands.add_parser("finalize") + finalize.add_argument("--oracle", type=Path, required=True) + finalize.add_argument("--mediated", type=Path, required=True) + finalize.add_argument("--output", type=Path, required=True) + verify = subcommands.add_parser("verify") + verify.add_argument("--bundle", type=Path, required=True) + worker = subcommands.add_parser("_native-worker", help=argparse.SUPPRESS) + worker.add_argument("--output", type=Path, required=True) + return parser + + +def _invocation_output(value: Path) -> Path: + root = Path.cwd().resolve() + resolved = (root / value).resolve() + if resolved == root or not resolved.is_relative_to(root): + raise ValueError("reproduction output must be beneath the invocation directory") + return resolved + + +def main(argv: Sequence[str] | None = None) -> int: + """Run the closed collection commands with bounded failures.""" + + try: + args = _parser().parse_args(argv) + if args.command == "declare": + write_declaration(Path.cwd(), _invocation_output(args.output)) + elif args.command == "native": + collect_native(args.declaration, _invocation_output(args.output)) + elif args.command == "mediated": + collect_mediated(args.oracle, args.pack, _invocation_output(args.output)) + elif args.command == "finalize": + finalize_bundle(args.oracle, args.mediated, _invocation_output(args.output)) + elif args.command == "verify": + print(json.dumps(verify_bundle(args.bundle), sort_keys=True)) + else: + _native_worker(args.output) + except Exception: + print("reproduction.command.failed: reproduction command failed", file=sys.stderr) + return 1 + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) + + +__all__ = [ + "build_declaration", + "canonical_json_bytes", + "collect_mediated", + "collect_native", + "compute_aggregates", + "compute_tiers", + "finalize_bundle", + "load_strict_json", + "load_terminal_rows", + "main", + "sha256_payload", + "terminal_rows_from_results", + "validate_protocol", + "verify_bundle", + "write_declaration", +] diff --git a/tests/test_cyberbattlesim_qualification.py b/tests/test_cyberbattlesim_qualification.py index 7af71cd..c905aa3 100644 --- a/tests/test_cyberbattlesim_qualification.py +++ b/tests/test_cyberbattlesim_qualification.py @@ -85,7 +85,7 @@ def test_external_pack_content_manifest_is_exact_and_immutable() -> None: derived = derive_pack_content_manifest(pack).model_dump(mode="json") assert recorded == derived assert recorded["set_digest"] == ( - "sha256:08ae7e997b50bb396c290c4a5537a65e9e7d8b8e6abc97d1ff65022c4258e417" + "sha256:66493882579d5cba87248c5722782ff5ded5f0d7423f4e559f15bfb61712a905" ) @@ -173,6 +173,10 @@ def test_protocol_fixes_every_identity_and_discloses_random_streams() -> None: "epsilon": 0.90, "epsilon_exponential_decay": 10000, "epsilon_minimum": 0.10, + "environment_bounds": { + "maximum_total_credentials": 22, + "maximum_node_count": 22, + }, } assert selection["defender"] == { "policy": "ScanAndReimageCompromisedMachines", diff --git a/tests/test_cyberbattlesim_reproduction.py b/tests/test_cyberbattlesim_reproduction.py new file mode 100644 index 0000000..2eacad3 --- /dev/null +++ b/tests/test_cyberbattlesim_reproduction.py @@ -0,0 +1,291 @@ +from __future__ import annotations + +import copy +import json +from datetime import UTC, datetime +from pathlib import Path + +import pytest + +from raes_adapters.cyberbattlesim import reproduction + +PROJECT_ROOT = Path(__file__).parents[1] + + +def _native_episode(index: int) -> dict[str, object]: + steps = 100 + index + return { + "steps_to_termination": steps, + "cumulative_attacker_reward": 5000.0 + index, + "network_availability": [0.99, 0.97, 0.95], + "terminal_cause": "attacker-ownership", + } + + +def _mediated_episode(index: int) -> dict[str, object]: + return { + "steps_to_termination": 105 + index, + "cumulative_attacker_reward": 5010.0 + index, + "network_availability": None, + "terminal_cause": None, + } + + +def test_declaration_uses_published_contracts_and_unique_attempts() -> None: + protocol, source_ledger = reproduction.build_declaration(PROJECT_ROOT) + + reproduction.validate_protocol(protocol, require_oracle=False) + schedule = protocol["declaration"]["schedule"] + assert len(schedule) == 20 + assert len({item["run_id"] for item in schedule}) == 20 + assert len({item["attempt_id"] for item in schedule}) == 20 + assert {item["lane"] for item in schedule} == {"source-native", "raes-mediated"} + assert protocol["declaration"]["study"]["schema_version"] == "experiment-study/v1" + assert source_ledger["source"]["commit"] == ("854d6966607fb68645651f55b0f97221bd293e0d") + + +@pytest.mark.parametrize( + "payload", + [ + '{"schema_version":"x","schema_version":"y"}', + '{"value": NaN}', + '{"value": Infinity}', + ], +) +def test_strict_json_rejects_duplicate_keys_and_nonfinite_numbers( + tmp_path: Path, payload: str +) -> None: + path = tmp_path / "hostile.json" + path.write_text(payload, encoding="utf-8") + + with pytest.raises(ValueError, match="invalid JSON artifact"): + reproduction.load_strict_json(path) + + +def test_protocol_rejects_drift_duplicate_ids_and_unsafe_paths() -> None: + protocol, _ledger = reproduction.build_declaration(PROJECT_ROOT) + + drifted = copy.deepcopy(protocol) + drifted["declaration"]["retry_budget"] = 1 + with pytest.raises(ValueError, match="declaration digest"): + reproduction.validate_protocol(drifted, require_oracle=False) + + duplicate = copy.deepcopy(protocol) + duplicate["declaration"]["schedule"][1]["attempt_id"] = duplicate["declaration"]["schedule"][0][ + "attempt_id" + ] + duplicate["declaration_sha256"] = reproduction.sha256_payload(duplicate["declaration"]) + with pytest.raises(ValueError, match="attempt identities"): + reproduction.validate_protocol(duplicate, require_oracle=False) + + unsafe = copy.deepcopy(protocol) + unsafe["declaration"]["artifacts"][0]["path"] = "../qualification.json" + unsafe["declaration_sha256"] = reproduction.sha256_payload(unsafe["declaration"]) + with pytest.raises(ValueError, match="relative path"): + reproduction.validate_protocol(unsafe, require_oracle=False) + + +def test_aggregation_is_deterministic_and_discloses_missing_metrics() -> None: + protocol, _ledger = reproduction.build_declaration(PROJECT_ROOT) + rows = reproduction.terminal_rows_from_results( + protocol, + native_results=[_native_episode(index) for index in range(10)], + mediated_results=[_mediated_episode(index) for index in range(10)], + protocol_sha256="a" * 64, + ) + + first = reproduction.compute_aggregates(protocol, rows) + second = reproduction.compute_aggregates(protocol, list(reversed(rows))) + + assert reproduction.canonical_json_bytes(first) == reproduction.canonical_json_bytes(second) + assert first["lanes"]["raes-mediated"]["metrics"]["network_availability"]["missing_count"] == 10 + assert first["comparisons"]["network_availability"]["result"] == "unavailable" + + +def test_native_collection_uses_one_upstream_batch_and_never_mediated_runner( + tmp_path: Path, +) -> None: + declaration_root = tmp_path / "declaration" + reproduction.write_declaration(PROJECT_ROOT, declaration_root) + calls: list[str] = [] + + def native_executor() -> list[dict[str, object]]: + calls.append("native") + return [_native_episode(index) for index in range(10)] + + output = tmp_path / "native" + reproduction.collect_native(declaration_root, output, executor=native_executor) + + assert calls == ["native"] + completed = reproduction.load_strict_json(output / "protocol.json") + reproduction.validate_protocol(completed, require_oracle=True) + rows = reproduction.load_terminal_rows(output) + assert len(rows) == 10 + assert {row["disposition"] for row in rows} == {"valid"} + notes = reproduction.load_strict_json(output / "bench-notes.json")["notes"] + assert notes[0]["event_code"] == "protocol-declared" + assert sum(note["event_code"] == "native-attempt-terminalized" for note in notes) == 10 + assert all( + datetime.fromisoformat(note["recorded_at"].replace("Z", "+00:00")).tzinfo == UTC + for note in notes + ) + + +def test_native_failure_terminalizes_all_preallocated_attempts(tmp_path: Path) -> None: + declaration_root = tmp_path / "declaration" + reproduction.write_declaration(PROJECT_ROOT, declaration_root) + + def fail() -> list[dict[str, object]]: + raise RuntimeError("secret native detail") + + output = tmp_path / "native" + with pytest.raises(RuntimeError, match="native collection failed"): + reproduction.collect_native(declaration_root, output, executor=fail) + + rows = reproduction.load_terminal_rows(output) + assert len(rows) == 10 + assert {row["disposition"] for row in rows} == {"failed"} + assert "secret native detail" not in json.dumps(rows) + notes = reproduction.load_strict_json(output / "bench-notes.json") + assert notes["notes"][-1]["event_code"] == "native-collection-failed" + assert notes["notes"][-1]["disposition"] == "failed" + assert "secret native detail" not in json.dumps(notes) + + +def test_mediated_collection_continues_after_one_attempt_failure(tmp_path: Path) -> None: + declaration_root = tmp_path / "declaration" + reproduction.write_declaration(PROJECT_ROOT, declaration_root) + native_root = tmp_path / "native" + reproduction.collect_native( + declaration_root, + native_root, + executor=lambda: [_native_episode(index) for index in range(10)], + ) + calls: list[str] = [] + + def runner(schedule: dict[str, object], _run_root: Path) -> dict[str, object]: + calls.append(str(schedule["attempt_id"])) + if schedule["replicate"] == 3: + raise RuntimeError("hostile traceback sentinel") + return _mediated_episode(int(schedule["replicate"])) + + output = tmp_path / "mediated" + reproduction.collect_mediated(native_root, tmp_path / "pack", output, runner=runner) + + rows = reproduction.load_terminal_rows(output) + assert len(calls) == 10 + assert len(rows) == 10 + assert sum(row["disposition"] == "failed" for row in rows) == 1 + assert "hostile traceback sentinel" not in json.dumps(rows) + notes = reproduction.load_strict_json(output / "bench-notes.json")["notes"] + terminal = [note for note in notes if note["event_code"] == "mediated-attempt-terminalized"] + assert len(terminal) == 10 + assert sum(note["disposition"] == "failed" for note in terminal) == 1 + assert "hostile traceback sentinel" not in json.dumps(notes) + + +def test_declaration_and_collection_outputs_are_no_clobber(tmp_path: Path) -> None: + output = tmp_path / "declaration" + reproduction.write_declaration(PROJECT_ROOT, output) + + with pytest.raises(FileExistsError): + reproduction.write_declaration(PROJECT_ROOT, output) + + +def test_final_bundle_recomputes_offline_and_has_six_cited_tiers(tmp_path: Path) -> None: + declaration_root = tmp_path / "declaration" + reproduction.write_declaration(PROJECT_ROOT, declaration_root) + native_root = tmp_path / "native" + reproduction.collect_native( + declaration_root, + native_root, + executor=lambda: [_native_episode(index) for index in range(10)], + ) + mediated_root = tmp_path / "mediated" + reproduction.collect_mediated( + native_root, + tmp_path / "pack", + mediated_root, + runner=lambda _schedule, _root: (_ for _ in ()).throw(RuntimeError("bounded")), + ) + protocol = reproduction.load_strict_json(native_root / "protocol.json") + bundle = tmp_path / str(protocol["declaration_sha256"]) + + reproduction.finalize_bundle(native_root, mediated_root, bundle) + result = reproduction.verify_bundle(bundle) + + assert result["scheduled_count"] == 20 + assert result["tier_count"] == 6 + tiers = reproduction.load_strict_json(bundle / "tiers.json")["tiers"] + assert [tier["tier"] for tier in tiers] == [ + "authored-source", + "contract", + "execution-control", + "state-observation", + "outcome-evaluation", + "disclosure", + ] + assert all(tier["evidence"] for tier in tiers) + notes = reproduction.load_strict_json(bundle / "bench-notes.json") + assert notes["notes"][-1]["event_code"] == "offline-verification-passed" + assert result["bench_note_count"] == len(notes["notes"]) + assert any( + evidence["path"] == "bench-notes.json" + for tier in tiers + if tier["tier"] == "disclosure" + for evidence in tier["evidence"] + ) + + +def test_offline_verifier_rejects_invalid_bench_note_timestamp(tmp_path: Path) -> None: + declaration_root = tmp_path / "declaration" + reproduction.write_declaration(PROJECT_ROOT, declaration_root) + native_root = tmp_path / "native" + reproduction.collect_native( + declaration_root, + native_root, + executor=lambda: [_native_episode(index) for index in range(10)], + ) + mediated_root = tmp_path / "mediated" + reproduction.collect_mediated( + native_root, + tmp_path / "pack", + mediated_root, + runner=lambda _schedule, _root: (_ for _ in ()).throw(RuntimeError("bounded")), + ) + protocol = reproduction.load_strict_json(native_root / "protocol.json") + bundle = tmp_path / str(protocol["declaration_sha256"]) + reproduction.finalize_bundle(native_root, mediated_root, bundle) + notes = reproduction.load_strict_json(bundle / "bench-notes.json") + notes["notes"][0]["recorded_at"] = "2026-08-10 03:21:16" + (bundle / "bench-notes.json").write_text(json.dumps(notes), encoding="utf-8") + + with pytest.raises(ValueError, match="bench note timestamp"): + reproduction.verify_bundle(bundle) + + +def test_offline_verifier_rejects_forbidden_native_material(tmp_path: Path) -> None: + declaration_root = tmp_path / "declaration" + reproduction.write_declaration(PROJECT_ROOT, declaration_root) + native_root = tmp_path / "native" + reproduction.collect_native( + declaration_root, + native_root, + executor=lambda: [_native_episode(index) for index in range(10)], + ) + mediated_root = tmp_path / "mediated" + reproduction.collect_mediated( + native_root, + tmp_path / "pack", + mediated_root, + runner=lambda _schedule, _root: (_ for _ in ()).throw(RuntimeError("bounded")), + ) + protocol = reproduction.load_strict_json(native_root / "protocol.json") + bundle = tmp_path / str(protocol["declaration_sha256"]) + reproduction.finalize_bundle(native_root, mediated_root, bundle) + (bundle / "forbidden.txt").write_text( + 'Traceback (most recent call last): "credential_cache_matrix"', encoding="utf-8" + ) + + with pytest.raises(ValueError, match="forbidden native value"): + reproduction.verify_bundle(bundle) diff --git a/tests/test_cyberbattlesim_researcher_cli.py b/tests/test_cyberbattlesim_researcher_cli.py index 7e71480..cfa90c6 100644 --- a/tests/test_cyberbattlesim_researcher_cli.py +++ b/tests/test_cyberbattlesim_researcher_cli.py @@ -28,7 +28,7 @@ pytest.importorskip("raes_env_packs") PACK_ROOT = Path(__file__).parents[1] / "environments" / "cyberbattlesim-chain" -PACK_DIGEST = "sha256:08ae7e997b50bb396c290c4a5537a65e9e7d8b8e6abc97d1ff65022c4258e417" +PACK_DIGEST = "sha256:66493882579d5cba87248c5722782ff5ded5f0d7423f4e559f15bfb61712a905" SCENARIO_DIGEST = "sha256:9d696ea7fa23a1e7cf4c1cbc145a7989370dc4e9afff2cd5a17d6d1af887b528" SEED = 20260729 From dc8a21c1ceb40bd4c40d573e3567be6bb8451e2e Mon Sep 17 00:00:00 2001 From: Brad Edwards Date: Mon, 10 Aug 2026 05:57:32 +0200 Subject: [PATCH 02/14] test(cyberbattlesim): freeze public baseline oracle --- .../bench-notes.json | 197 + .../collection.json | 6 + .../environment.json | 41 + .../inventory.json | 94 + .../protocol.json | 3581 +++++++++++++++++ .../runs/cbs-native-01/record.json | 306 ++ .../runs/cbs-native-02/record.json | 446 ++ .../runs/cbs-native-03/record.json | 376 ++ .../runs/cbs-native-04/record.json | 291 ++ .../runs/cbs-native-05/record.json | 266 ++ .../runs/cbs-native-06/record.json | 331 ++ .../runs/cbs-native-07/record.json | 186 + .../runs/cbs-native-08/record.json | 406 ++ .../runs/cbs-native-09/record.json | 371 ++ .../runs/cbs-native-10/record.json | 401 ++ .../source-ledger.json | 107 + 16 files changed, 7406 insertions(+) create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/bench-notes.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/collection.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/environment.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/protocol.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-01/record.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-02/record.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-03/record.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-04/record.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-05/record.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-06/record.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-07/record.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-08/record.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-09/record.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-10/record.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/source-ledger.json diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/bench-notes.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/bench-notes.json new file mode 100644 index 0000000..45f3fe4 --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/bench-notes.json @@ -0,0 +1,197 @@ +{ + "declaration_sha256": "825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232", + "notes": [ + { + "disposition": "passed", + "event_code": "protocol-declared", + "evidence_refs": [ + { + "path": "protocol.json" + }, + { + "path": "source-ledger.json" + } + ], + "note_id": "declaration-001", + "phase": "declaration", + "recorded_at": "2026-08-10T03:54:02.312Z", + "severity": "info", + "summary": "The declaration and 20 never-reused attempt identities were written before experiment effects." + }, + { + "disposition": "observed", + "event_code": "native-collection-started", + "evidence_refs": [ + { + "path": "protocol.json" + }, + { + "path": "source-ledger.json" + }, + { + "path": "environment.json" + } + ], + "note_id": "native-001", + "phase": "native", + "recorded_at": "2026-08-10T03:55:52.856Z", + "severity": "info", + "summary": "The exact admitted upstream ten-episode evaluator batch was started." + }, + { + "disposition": "passed", + "event_code": "native-attempt-terminalized", + "evidence_refs": [ + { + "path": "runs/cbs-native-01/record.json" + } + ], + "note_id": "native-002", + "phase": "native", + "recorded_at": "2026-08-10T03:55:59.939Z", + "severity": "info", + "summary": "Scheduled source-native attempt cbs-native-01 was terminalized as valid." + }, + { + "disposition": "passed", + "event_code": "native-attempt-terminalized", + "evidence_refs": [ + { + "path": "runs/cbs-native-02/record.json" + } + ], + "note_id": "native-003", + "phase": "native", + "recorded_at": "2026-08-10T03:55:59.939Z", + "severity": "info", + "summary": "Scheduled source-native attempt cbs-native-02 was terminalized as valid." + }, + { + "disposition": "passed", + "event_code": "native-attempt-terminalized", + "evidence_refs": [ + { + "path": "runs/cbs-native-03/record.json" + } + ], + "note_id": "native-004", + "phase": "native", + "recorded_at": "2026-08-10T03:55:59.939Z", + "severity": "info", + "summary": "Scheduled source-native attempt cbs-native-03 was terminalized as valid." + }, + { + "disposition": "passed", + "event_code": "native-attempt-terminalized", + "evidence_refs": [ + { + "path": "runs/cbs-native-04/record.json" + } + ], + "note_id": "native-005", + "phase": "native", + "recorded_at": "2026-08-10T03:55:59.939Z", + "severity": "info", + "summary": "Scheduled source-native attempt cbs-native-04 was terminalized as valid." + }, + { + "disposition": "passed", + "event_code": "native-attempt-terminalized", + "evidence_refs": [ + { + "path": "runs/cbs-native-05/record.json" + } + ], + "note_id": "native-006", + "phase": "native", + "recorded_at": "2026-08-10T03:55:59.939Z", + "severity": "info", + "summary": "Scheduled source-native attempt cbs-native-05 was terminalized as valid." + }, + { + "disposition": "passed", + "event_code": "native-attempt-terminalized", + "evidence_refs": [ + { + "path": "runs/cbs-native-06/record.json" + } + ], + "note_id": "native-007", + "phase": "native", + "recorded_at": "2026-08-10T03:55:59.939Z", + "severity": "info", + "summary": "Scheduled source-native attempt cbs-native-06 was terminalized as valid." + }, + { + "disposition": "passed", + "event_code": "native-attempt-terminalized", + "evidence_refs": [ + { + "path": "runs/cbs-native-07/record.json" + } + ], + "note_id": "native-008", + "phase": "native", + "recorded_at": "2026-08-10T03:55:59.939Z", + "severity": "info", + "summary": "Scheduled source-native attempt cbs-native-07 was terminalized as valid." + }, + { + "disposition": "passed", + "event_code": "native-attempt-terminalized", + "evidence_refs": [ + { + "path": "runs/cbs-native-08/record.json" + } + ], + "note_id": "native-009", + "phase": "native", + "recorded_at": "2026-08-10T03:55:59.940Z", + "severity": "info", + "summary": "Scheduled source-native attempt cbs-native-08 was terminalized as valid." + }, + { + "disposition": "passed", + "event_code": "native-attempt-terminalized", + "evidence_refs": [ + { + "path": "runs/cbs-native-09/record.json" + } + ], + "note_id": "native-010", + "phase": "native", + "recorded_at": "2026-08-10T03:55:59.940Z", + "severity": "info", + "summary": "Scheduled source-native attempt cbs-native-09 was terminalized as valid." + }, + { + "disposition": "passed", + "event_code": "native-attempt-terminalized", + "evidence_refs": [ + { + "path": "runs/cbs-native-10/record.json" + } + ], + "note_id": "native-011", + "phase": "native", + "recorded_at": "2026-08-10T03:55:59.940Z", + "severity": "info", + "summary": "Scheduled source-native attempt cbs-native-10 was terminalized as valid." + }, + { + "disposition": "passed", + "event_code": "native-collection-passed", + "evidence_refs": [ + { + "path": "protocol.json" + } + ], + "note_id": "native-012", + "phase": "native", + "recorded_at": "2026-08-10T03:55:59.940Z", + "severity": "info", + "summary": "The exact upstream evaluator returned all ten scheduled terminal results." + } + ], + "schema_version": "cyberbattlesim-baseline-bench-notes/v1" +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/collection.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/collection.json new file mode 100644 index 0000000..08afc9b --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/collection.json @@ -0,0 +1,6 @@ +{ + "lane": "source-native", + "native_result_set_sha256": "00041aa18dc205e0923531a3d05f4e5216c3375a2f90275eac320bd7e650366e", + "terminal_count": 10, + "valid_count": 10 +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/environment.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/environment.json new file mode 100644 index 0000000..20a2452 --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/environment.json @@ -0,0 +1,41 @@ +{ + "lane": "source-native", + "limitations": [ + "The upstream source has no selected public index or release artifact.", + "Python-global and NumPy-global random streams are unbound in the mediated lane.", + "All four observed random streams are unbound in the source-native lane.", + "The authored RAES topology is representative rather than state-identical.", + "The mediated evaluator does not retain availability series or a specific terminal cause." + ], + "machine": { + "architecture": "x86_64", + "logical_cpu_count": 4, + "operating_system": "Linux", + "operating_system_release": "6.17.0-1019-aws", + "physical_memory_bytes": 16375947264 + }, + "pack": { + "content_digest": "sha256:66493882579d5cba87248c5722782ff5ded5f0d7423f4e559f15bfb61712a905", + "identity": "cyberbattlesim-chain", + "version": "1.0.0" + }, + "python": { + "implementation": "CPython", + "version": "3.12.3" + }, + "schema_version": "cyberbattlesim-baseline-environment/v1", + "software": { + "cyberbattlesim": "0.1.0", + "gymnasium": "0.29.1", + "numpy": "1.26.4", + "raes": "3.3.0", + "raes-adapters": "0.0.0", + "raes-env-packs": "3.6.2" + }, + "source": { + "commit": "854d6966607fb68645651f55b0f97221bd293e0d", + "installed_artifact_sha256": "unavailable", + "tree": "4271b137ab2de593be52d7afb0a51bee59045a45", + "version": "0.1.0" + } +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/inventory.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/inventory.json new file mode 100644 index 0000000..530830e --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/inventory.json @@ -0,0 +1,94 @@ +{ + "artifacts": [ + { + "media_type": "application/json", + "path": "bench-notes.json", + "sha256": "7eef98b91b375add73a620f08a668de93f237e1e3a344e695cd02c00dd1252f8", + "size_bytes": 5816 + }, + { + "media_type": "application/json", + "path": "collection.json", + "sha256": "454b5e7d5b4c61970ae60f2d7dc96abc304d7eb35755f0d08df11b5034faf92d", + "size_bytes": 173 + }, + { + "media_type": "application/json", + "path": "environment.json", + "sha256": "5f8c84124202daeaacdd35cc02fef89d16d4a0c741fdf923e6dbe3f9ceeda26a", + "size_bytes": 1378 + }, + { + "media_type": "application/json", + "path": "protocol.json", + "sha256": "93d79b72c9e26af2be1365e094e04ac0fff0fa884a7afdb8650e7e52a90418c4", + "size_bytes": 93420 + }, + { + "media_type": "application/json", + "path": "runs/cbs-native-01/record.json", + "sha256": "c784297c8b2f382ef2316ca5388238c4198af93dd5b14df99d2c313c3428f0a3", + "size_bytes": 5912 + }, + { + "media_type": "application/json", + "path": "runs/cbs-native-02/record.json", + "sha256": "63db6375b0e3eac6122329ba83817a1fbaa1c8c0d2a17b77d2674fe360a7f0be", + "size_bytes": 8727 + }, + { + "media_type": "application/json", + "path": "runs/cbs-native-03/record.json", + "sha256": "d552cdd6d4da35c03544b129e9fe3eda618f1bf3f14df473c143ffcc5da7f0ea", + "size_bytes": 7357 + }, + { + "media_type": "application/json", + "path": "runs/cbs-native-04/record.json", + "sha256": "285523f5bbfb2b6290c979734983a886f3092ad2ab17180c74284e29a986ad2a", + "size_bytes": 5447 + }, + { + "media_type": "application/json", + "path": "runs/cbs-native-05/record.json", + "sha256": "6bd195b1f8d14928becf60f90b0dfd04c5c2e7a89af24e6a3c295acfcf6a4db2", + "size_bytes": 4811 + }, + { + "media_type": "application/json", + "path": "runs/cbs-native-06/record.json", + "sha256": "44d7d1cef89ac44689d93410cec8fbd92cc56e5263488d11f6600466cd9883b8", + "size_bytes": 6412 + }, + { + "media_type": "application/json", + "path": "runs/cbs-native-07/record.json", + "sha256": "c5756e73068cf151e41ba38bb08e7fffba68f89f33d2c78dfe36a35c16db768d", + "size_bytes": 3917 + }, + { + "media_type": "application/json", + "path": "runs/cbs-native-08/record.json", + "sha256": "1934334f5bb4f1cb3ebefbf5376fdcfdb82789e7dd5ef696eb78736234de2357", + "size_bytes": 7537 + }, + { + "media_type": "application/json", + "path": "runs/cbs-native-09/record.json", + "sha256": "778dc6d4869dacf19349857336e633d8bcc38c38bd90a7ae5d98078b110887ba", + "size_bytes": 7902 + }, + { + "media_type": "application/json", + "path": "runs/cbs-native-10/record.json", + "sha256": "5952644249dabab43133666552d38381798a3547696787022bd9968a06e554fa", + "size_bytes": 7633 + }, + { + "media_type": "application/json", + "path": "source-ledger.json", + "sha256": "01c8dee3298778bdf537281b128b39c8030f134fe7492fabe4577d62ed370598", + "size_bytes": 4338 + } + ] +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/protocol.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/protocol.json new file mode 100644 index 0000000..ae6503e --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/protocol.json @@ -0,0 +1,3581 @@ +{ + "declaration": { + "aggregation": { + "bootstrap_resamples": 10000, + "missingness": "No imputation; every terminal attempt remains in denominators.", + "numeric_statistics": [ + "count", + "mean", + "median", + "sample-standard-deviation", + "minimum", + "maximum" + ], + "uncertainty": "95% deterministic percentile bootstrap interval of the mean" + }, + "artifacts": [ + { + "artifact_id": "qualification", + "path": "src/raes_adapters/cyberbattlesim/qualification.json", + "sha256": "0b55f88c0ff628980c976a50f38f71ff7ec0f94b2e50e2b87f6498d5dd01c147" + }, + { + "artifact_id": "public-protocol", + "path": "src/raes_adapters/cyberbattlesim/public-protocol.md", + "sha256": "0de0d8585ee9e3bb0901bd2d71b71a9504774b38bdab38f6f5509d0a9e34d26f" + }, + { + "artifact_id": "source-ledger", + "path": "src/raes_adapters/cyberbattlesim/mapping/source-ledger.jsonl", + "sha256": "8776a340873e6b56a55767e4257f05ba1bb71fa2b37003a2023b0fe3b0cce553" + }, + { + "artifact_id": "loss-disclosures", + "path": "src/raes_adapters/cyberbattlesim/mapping/loss-disclosures.md", + "sha256": "3c2530553a6ab035a6c505e80bf02298f1ab07dd3ffc72216f87f6381113181c" + }, + { + "artifact_id": "reproduction-runner", + "path": "src/raes_adapters/cyberbattlesim/reproduction.py", + "sha256": "44c5573635a2adc655e78eff8765c25c58b469a3f378975fce83f21c6c4ead98" + }, + { + "artifact_id": "mediated-researcher", + "path": "src/raes_adapters/cyberbattlesim/researcher.py", + "sha256": "35a320b319fd2fd880a49ce2a670576c23a754ff4a67d80618be848fb42fc0d1" + }, + { + "artifact_id": "mediated-driver", + "path": "src/raes_adapters/cyberbattlesim/backend/driver.py", + "sha256": "1f86e3522c6e7ff5b17f8ac4eed5d9567da3c674218b5f1bf3cd8c0e10028202" + }, + { + "artifact_id": "selected-source-helper", + "path": "src/raes_adapters/cyberbattlesim/backend/source.py", + "sha256": "977b91e77d0c1fe23f265ab59151a8c478b43fff20d44afd79b0392c20bf62de" + }, + { + "artifact_id": "task", + "path": "environments/cyberbattlesim-chain/experiment/cyberbattlesim-chain.task.exp.json", + "sha256": "6588ac115931b8de7052d52ccb94bbd258c5e6c78ffb9d5f5d1c0570f9236ce5" + }, + { + "artifact_id": "spec", + "path": "environments/cyberbattlesim-chain/experiment/cyberbattlesim-chain.spec.exp.json", + "sha256": "c31d2f4376ad7877d756e6a572a5e9e344b0899c4e8e996e1b5f57eaa78be391" + }, + { + "artifact_id": "pack-manifest", + "path": "environments/cyberbattlesim-chain/pack.content-manifest.json", + "sha256": "8131a2a294da39fceeca1595da1f987dbbc934a234c635fbb935e7d223cf103c" + }, + { + "artifact_id": "participant-manifest", + "path": "environments/cyberbattlesim-chain/participant/cyberbattlesim-red-credential-cache.manifest.json", + "sha256": "2ea827eb709a036b1721a91fabce787a320845bf26e3e6f0a0e5e768e7f9d93b" + }, + { + "artifact_id": "participant-selection", + "path": "environments/cyberbattlesim-chain/participant/cyberbattlesim-red-credential-cache.selection.json", + "sha256": "ce920ca6362b37e8cde6af12190ee9b84e9ea3c3fc89842d31366f0ec6031935" + }, + { + "artifact_id": "participant-configuration", + "path": "environments/cyberbattlesim-chain/participant/cyberbattlesim-red-credential-cache.configuration.json", + "sha256": "2b5e0fd0ef0be839af33763199e76192196a4928ca555a230af0f685c38eeced" + } + ], + "bench_notes": { + "artifact": "bench-notes.json", + "publication_policy": "Record controlled observations and dispositions as work occurs; exclude raw native output, exception text, host paths, credentials, and provider identifiers.", + "required_fields": [ + "note_id", + "recorded_at", + "phase", + "severity", + "event_code", + "summary", + "disposition", + "evidence_refs" + ], + "schema_version": "cyberbattlesim-baseline-bench-notes/v1", + "timestamp_profile": "RFC3339 UTC with millisecond precision" + }, + "comparison": { + "bounded": { + "cumulative_attacker_reward": 500.0, + "network_availability": 0.05, + "steps_to_termination": 60.0, + "terminal_cause": 0.1 + }, + "exact": "Complete ordered per-run vectors and control dispositions match.", + "failed": "A complete interval lies outside its bound.", + "unavailable": "A declared metric is absent from either lane; no tolerance is inferred." + }, + "condition": { + "attacker": "CredentialCacheExploiter", + "defender": "ScanAndReimageCompromisedMachines(0.6,2,5)", + "episode_count_per_lane": 10, + "epsilon": 0.9, + "epsilon_exponential_decay": 10000, + "epsilon_minimum": 0.1, + "gym_id": "CyberBattleChain-v0", + "maximum_steps": 600, + "size": 10 + }, + "explicit_non_claims": [ + "deterministic replay", + "exact state or observation equivalence", + "cross-simulator equality", + "agent ranking", + "benchmark comparability", + "outcome equivalence", + "general scientific reproducibility" + ], + "metrics": [ + "steps_to_termination", + "cumulative_attacker_reward", + "network_availability", + "terminal_cause" + ], + "retry_budget": 0, + "schedule": [ + { + "attempt_id": "cbs-native-01-attempt-01", + "lane": "source-native", + "replicate": 1, + "run_id": "cbs-native-01", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-native-02-attempt-01", + "lane": "source-native", + "replicate": 2, + "run_id": "cbs-native-02", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-native-03-attempt-01", + "lane": "source-native", + "replicate": 3, + "run_id": "cbs-native-03", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-native-04-attempt-01", + "lane": "source-native", + "replicate": 4, + "run_id": "cbs-native-04", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-native-05-attempt-01", + "lane": "source-native", + "replicate": 5, + "run_id": "cbs-native-05", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-native-06-attempt-01", + "lane": "source-native", + "replicate": 6, + "run_id": "cbs-native-06", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-native-07-attempt-01", + "lane": "source-native", + "replicate": 7, + "run_id": "cbs-native-07", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-native-08-attempt-01", + "lane": "source-native", + "replicate": 8, + "run_id": "cbs-native-08", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-native-09-attempt-01", + "lane": "source-native", + "replicate": 9, + "run_id": "cbs-native-09", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-native-10-attempt-01", + "lane": "source-native", + "replicate": 10, + "run_id": "cbs-native-10", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-mediated-01-attempt-01", + "lane": "raes-mediated", + "replicate": 1, + "run_id": "cbs-mediated-01", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-mediated-02-attempt-01", + "lane": "raes-mediated", + "replicate": 2, + "run_id": "cbs-mediated-02", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-mediated-03-attempt-01", + "lane": "raes-mediated", + "replicate": 3, + "run_id": "cbs-mediated-03", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-mediated-04-attempt-01", + "lane": "raes-mediated", + "replicate": 4, + "run_id": "cbs-mediated-04", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-mediated-05-attempt-01", + "lane": "raes-mediated", + "replicate": 5, + "run_id": "cbs-mediated-05", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-mediated-06-attempt-01", + "lane": "raes-mediated", + "replicate": 6, + "run_id": "cbs-mediated-06", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-mediated-07-attempt-01", + "lane": "raes-mediated", + "replicate": 7, + "run_id": "cbs-mediated-07", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-mediated-08-attempt-01", + "lane": "raes-mediated", + "replicate": 8, + "run_id": "cbs-mediated-08", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-mediated-09-attempt-01", + "lane": "raes-mediated", + "replicate": 9, + "run_id": "cbs-mediated-09", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-mediated-10-attempt-01", + "lane": "raes-mediated", + "replicate": 10, + "run_id": "cbs-mediated-10", + "seed_label": 20260729 + } + ], + "source_selection": { + "commit": "854d6966607fb68645651f55b0f97221bd293e0d", + "evaluator": "cyberbattle.agents.baseline.learner.epsilon_greedy_search", + "notebook_path": "notebooks/notebook_withdefender.py", + "notebook_sha256": "847999b0a907c22a6e64b93c96d444d43e0a66dbfba2a2bd0a9ba888cfa41fcc", + "repository": "https://github.com/microsoft/CyberBattleSim", + "runtime_tree_sha256": "1b8bf39a7cb9c172b51b5223dfac13b9d01e166b34dc2bb29297cddb254a06fe", + "tree": "4271b137ab2de593be52d7afb0a51bee59045a45", + "version": "0.1.0" + }, + "stochastic_controls": { + "raes-mediated": { + "applied": [ + "gym-environment", + "gym-action-space" + ], + "unbound": [ + "python-random", + "numpy-global" + ] + }, + "source-native": { + "applied": [], + "unbound": [ + "gym-environment", + "gym-action-space", + "python-random", + "numpy-global" + ] + } + }, + "study": { + "analysis_plan": { + "analysis_id": "cyberbattlesim-baseline-comparison-v1", + "description": "Lane summaries and predeclared bounded differences.", + "metrics": [ + "steps_to_termination", + "cumulative_attacker_reward", + "network_availability", + "terminal_cause" + ], + "missing_data_policy": { + "handling": "Retain all terminal attempts in denominators; do not impute or silently drop.", + "missingness_assumption": "Missingness is apparatus- or failure-induced, not random.", + "sensitivity_analysis": "Unavailable declared metrics weaken the applicable tier." + }, + "multiple_comparison_policy": { + "correction": "none", + "family": "four descriptive metric comparisons", + "rationale": "No hypothesis-test or general population claim is made." + }, + "primary_metric": "cumulative_attacker_reward", + "statistical_method": { + "assumptions": [ + "Attempts are the fixed scheduled episodes and are not replaced after failure." + ], + "comparison_family": "four predeclared task metrics", + "estimand": "RAES-mediated lane mean minus source-native lane mean", + "method": "descriptive lane summaries and difference in means", + "unit_of_analysis": "episode" + }, + "uncertainty_method": { + "interval_level": 0.95, + "method": "deterministic percentile bootstrap", + "procedure": "10,000 counter-addressed SHA-256 resamples bound to the declaration digest." + } + }, + "behavioral_claims": [ + { + "assurance_axis": "bounded-test", + "assurance_status": "tested", + "evidence_boundary": "Exactly ten preallocated terminal attempts per lane under the frozen issue-30 comparison and missingness rules.", + "evidence_refs": [], + "evidence_scope": "finite", + "explicit_non_claims": [ + "No trace, state, observation, deterministic-replay, or outcome-equivalence claim is made." + ], + "left_carrier_ref": "condition:source-native", + "limitations": [ + "The lanes have different stochastic bindings and evaluator paths." + ], + "observation_projection_ref": "experiment-study-v1", + "observation_projection_revision": "rev1", + "quantifier_scope": "finite-cases", + "relation_id": "empirical-adequacy", + "relation_parameter_profile_ref": null, + "relation_parameter_profile_revision": null, + "right_carrier_ref": "condition:raes-mediated", + "subject": "The fixed CyberBattleSim credential-cache baseline selection", + "taxonomy_id": "raes-behavioral-relations", + "taxonomy_revision": "rev12" + } + ], + "description": "Frozen two-lane reproduction of the selected public credential-cache baseline.", + "export_artifacts": [], + "factors": { + "execution-lane": { + "factor_kind": "apparatus", + "levels": [ + "source-native", + "raes-mediated" + ], + "name": "Execution lane" + } + }, + "inclusion_criteria": [ + "Only preallocated terminal attempts from the exact qualified selection are included." + ], + "membership": { + "primary-task": { + "grouping": null, + "inclusion_rationale": "The qualified public task owns all measured constructs.", + "role": "primary-task", + "target_ref": { + "ref_digest": null, + "ref_id": "cyberbattlesim-chain-task", + "ref_kind": "task", + "ref_path": null, + "ref_version": null + } + } + }, + "owner": "OpenRAE", + "purpose": "Retain bounded readiness and reproduction evidence for OpenRAE/research#14 and OpenRAE/research#20 without asserting deterministic replay or outcome equivalence.", + "report_artifacts": [], + "research_questions": [ + "Which authored, contract, control, observation, outcome, and disclosure facts survive the selected RAES-mediated execution?" + ], + "run_allocation": { + "allocation_method": "preallocated fixed condition matrix", + "allocation_unit": "episode", + "blocking_factors": [], + "compared_conditions": [ + "source-native", + "raes-mediated" + ], + "condition_assignments": { + "raes-mediated": { + "condition_id": "raes-mediated", + "description": null, + "difficulty_condition": "fixed", + "difficulty_policy_id": null, + "factor_levels": { + "execution-lane": "raes-mediated" + }, + "required_parameters": [ + { + "name": "execution-lane", + "redaction": "none", + "value": "raes-mediated", + "value_kind": "apparatus" + } + ], + "required_refs": [] + }, + "source-native": { + "condition_id": "source-native", + "description": null, + "difficulty_condition": "fixed", + "difficulty_policy_id": null, + "factor_levels": { + "execution-lane": "source-native" + }, + "required_parameters": [ + { + "name": "execution-lane", + "redaction": "none", + "value": "source-native", + "value_kind": "apparatus" + } + ], + "required_refs": [] + } + }, + "randomization_unit": null, + "replication_policy": "Ten fixed scheduled episodes per lane; retry budget zero.", + "stopping_rule": "Terminalize every scheduled attempt; do not replace failures.", + "target_runs_per_condition": 10 + }, + "schema_version": "experiment-study/v1", + "study_id": "cyberbattlesim-chain-baseline-reproduction", + "study_kind": "study", + "study_version": "1.0.0", + "title": "CyberBattleSim chain source-native and RAES-mediated reproduction", + "validation_basis_disclosures": [], + "validity_notes": [ + { + "category": "reproducibility", + "mitigation": "Record actual lane-specific binding dispositions and make no replay claim.", + "note": "The source evaluator leaves four random streams unbound." + } + ] + }, + "terminal_dispositions": [ + "excluded", + "failed", + "invalid", + "valid" + ], + "tier_policy": [ + "authored-source", + "contract", + "execution-control", + "state-observation", + "outcome-evaluation", + "disclosure" + ] + }, + "declaration_sha256": "825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232", + "oracle": { + "declaration_sha256": "825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232", + "lane": "source-native", + "native_result_set_sha256": "00041aa18dc205e0923531a3d05f4e5216c3375a2f90275eac320bd7e650366e", + "ordered_results": [ + { + "metrics": { + "cumulative_attacker_reward": 5782.0, + "network_availability": [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.75 + ], + "steps_to_termination": 266, + "terminal_cause": "defender-sla" + }, + "run_id": "cbs-native-01" + }, + { + "metrics": { + "cumulative_attacker_reward": 5647.0, + "network_availability": [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.75 + ], + "steps_to_termination": 406, + "terminal_cause": "defender-sla" + }, + "run_id": "cbs-native-02" + }, + { + "metrics": { + "cumulative_attacker_reward": 6009.0, + "network_availability": [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.75 + ], + "steps_to_termination": 336, + "terminal_cause": "defender-sla" + }, + "run_id": "cbs-native-03" + }, + { + "metrics": { + "cumulative_attacker_reward": 5758.0, + "network_availability": [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.75 + ], + "steps_to_termination": 251, + "terminal_cause": "defender-sla" + }, + "run_id": "cbs-native-04" + }, + { + "metrics": { + "cumulative_attacker_reward": 5880.0, + "network_availability": [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.6666666666666666 + ], + "steps_to_termination": 226, + "terminal_cause": "defender-sla" + }, + "run_id": "cbs-native-05" + }, + { + "metrics": { + "cumulative_attacker_reward": 5772.0, + "network_availability": [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.75 + ], + "steps_to_termination": 291, + "terminal_cause": "defender-sla" + }, + "run_id": "cbs-native-06" + }, + { + "metrics": { + "cumulative_attacker_reward": 5639.0, + "network_availability": [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.75 + ], + "steps_to_termination": 146, + "terminal_cause": "defender-sla" + }, + "run_id": "cbs-native-07" + }, + { + "metrics": { + "cumulative_attacker_reward": 5779.0, + "network_availability": [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.75 + ], + "steps_to_termination": 366, + "terminal_cause": "defender-sla" + }, + "run_id": "cbs-native-08" + }, + { + "metrics": { + "cumulative_attacker_reward": 5886.0, + "network_availability": [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.75 + ], + "steps_to_termination": 331, + "terminal_cause": "defender-sla" + }, + "run_id": "cbs-native-09" + }, + { + "metrics": { + "cumulative_attacker_reward": 6020.0, + "network_availability": [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.75 + ], + "steps_to_termination": 361, + "terminal_cause": "defender-sla" + }, + "run_id": "cbs-native-10" + } + ] + }, + "schema_version": "cyberbattlesim-baseline-reproduction/v1" +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-01/record.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-01/record.json new file mode 100644 index 0000000..c754560 --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-01/record.json @@ -0,0 +1,306 @@ +{ + "attempt_id": "cbs-native-01-attempt-01", + "cleanup": { + "attempted": true, + "receipt_ref": "cleanup.cbs-native-01-attempt-01", + "verified": true + }, + "declaration_sha256": "825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232", + "diagnostics": [], + "disposition": "valid", + "evidence_refs": [], + "lane": "source-native", + "metric_status": { + "cumulative_attacker_reward": "available", + "network_availability": "available", + "steps_to_termination": "available", + "terminal_cause": "available" + }, + "metrics": { + "cumulative_attacker_reward": 5782.0, + "network_availability": [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.75 + ], + "steps_to_termination": 266, + "terminal_cause": "defender-sla" + }, + "protocol_sha256": null, + "replicate": 1, + "run_id": "cbs-native-01", + "schema_version": "cyberbattlesim-baseline-run/v1", + "seed_label": 20260729, + "stochastic_controls": { + "applied": [], + "unbound": [ + "gym-environment", + "gym-action-space", + "python-random", + "numpy-global" + ] + } +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-02/record.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-02/record.json new file mode 100644 index 0000000..b15f063 --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-02/record.json @@ -0,0 +1,446 @@ +{ + "attempt_id": "cbs-native-02-attempt-01", + "cleanup": { + "attempted": true, + "receipt_ref": "cleanup.cbs-native-02-attempt-01", + "verified": true + }, + "declaration_sha256": "825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232", + "diagnostics": [], + "disposition": "valid", + "evidence_refs": [], + "lane": "source-native", + "metric_status": { + "cumulative_attacker_reward": "available", + "network_availability": "available", + "steps_to_termination": "available", + "terminal_cause": "available" + }, + "metrics": { + "cumulative_attacker_reward": 5647.0, + "network_availability": [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.75 + ], + "steps_to_termination": 406, + "terminal_cause": "defender-sla" + }, + "protocol_sha256": null, + "replicate": 2, + "run_id": "cbs-native-02", + "schema_version": "cyberbattlesim-baseline-run/v1", + "seed_label": 20260729, + "stochastic_controls": { + "applied": [], + "unbound": [ + "gym-environment", + "gym-action-space", + "python-random", + "numpy-global" + ] + } +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-03/record.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-03/record.json new file mode 100644 index 0000000..e71c492 --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-03/record.json @@ -0,0 +1,376 @@ +{ + "attempt_id": "cbs-native-03-attempt-01", + "cleanup": { + "attempted": true, + "receipt_ref": "cleanup.cbs-native-03-attempt-01", + "verified": true + }, + "declaration_sha256": "825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232", + "diagnostics": [], + "disposition": "valid", + "evidence_refs": [], + "lane": "source-native", + "metric_status": { + "cumulative_attacker_reward": "available", + "network_availability": "available", + "steps_to_termination": "available", + "terminal_cause": "available" + }, + "metrics": { + "cumulative_attacker_reward": 6009.0, + "network_availability": [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.75 + ], + "steps_to_termination": 336, + "terminal_cause": "defender-sla" + }, + "protocol_sha256": null, + "replicate": 3, + "run_id": "cbs-native-03", + "schema_version": "cyberbattlesim-baseline-run/v1", + "seed_label": 20260729, + "stochastic_controls": { + "applied": [], + "unbound": [ + "gym-environment", + "gym-action-space", + "python-random", + "numpy-global" + ] + } +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-04/record.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-04/record.json new file mode 100644 index 0000000..f9eff1b --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-04/record.json @@ -0,0 +1,291 @@ +{ + "attempt_id": "cbs-native-04-attempt-01", + "cleanup": { + "attempted": true, + "receipt_ref": "cleanup.cbs-native-04-attempt-01", + "verified": true + }, + "declaration_sha256": "825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232", + "diagnostics": [], + "disposition": "valid", + "evidence_refs": [], + "lane": "source-native", + "metric_status": { + "cumulative_attacker_reward": "available", + "network_availability": "available", + "steps_to_termination": "available", + "terminal_cause": "available" + }, + "metrics": { + "cumulative_attacker_reward": 5758.0, + "network_availability": [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.75 + ], + "steps_to_termination": 251, + "terminal_cause": "defender-sla" + }, + "protocol_sha256": null, + "replicate": 4, + "run_id": "cbs-native-04", + "schema_version": "cyberbattlesim-baseline-run/v1", + "seed_label": 20260729, + "stochastic_controls": { + "applied": [], + "unbound": [ + "gym-environment", + "gym-action-space", + "python-random", + "numpy-global" + ] + } +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-05/record.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-05/record.json new file mode 100644 index 0000000..46bf914 --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-05/record.json @@ -0,0 +1,266 @@ +{ + "attempt_id": "cbs-native-05-attempt-01", + "cleanup": { + "attempted": true, + "receipt_ref": "cleanup.cbs-native-05-attempt-01", + "verified": true + }, + "declaration_sha256": "825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232", + "diagnostics": [], + "disposition": "valid", + "evidence_refs": [], + "lane": "source-native", + "metric_status": { + "cumulative_attacker_reward": "available", + "network_availability": "available", + "steps_to_termination": "available", + "terminal_cause": "available" + }, + "metrics": { + "cumulative_attacker_reward": 5880.0, + "network_availability": [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.6666666666666666 + ], + "steps_to_termination": 226, + "terminal_cause": "defender-sla" + }, + "protocol_sha256": null, + "replicate": 5, + "run_id": "cbs-native-05", + "schema_version": "cyberbattlesim-baseline-run/v1", + "seed_label": 20260729, + "stochastic_controls": { + "applied": [], + "unbound": [ + "gym-environment", + "gym-action-space", + "python-random", + "numpy-global" + ] + } +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-06/record.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-06/record.json new file mode 100644 index 0000000..208a62d --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-06/record.json @@ -0,0 +1,331 @@ +{ + "attempt_id": "cbs-native-06-attempt-01", + "cleanup": { + "attempted": true, + "receipt_ref": "cleanup.cbs-native-06-attempt-01", + "verified": true + }, + "declaration_sha256": "825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232", + "diagnostics": [], + "disposition": "valid", + "evidence_refs": [], + "lane": "source-native", + "metric_status": { + "cumulative_attacker_reward": "available", + "network_availability": "available", + "steps_to_termination": "available", + "terminal_cause": "available" + }, + "metrics": { + "cumulative_attacker_reward": 5772.0, + "network_availability": [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.75 + ], + "steps_to_termination": 291, + "terminal_cause": "defender-sla" + }, + "protocol_sha256": null, + "replicate": 6, + "run_id": "cbs-native-06", + "schema_version": "cyberbattlesim-baseline-run/v1", + "seed_label": 20260729, + "stochastic_controls": { + "applied": [], + "unbound": [ + "gym-environment", + "gym-action-space", + "python-random", + "numpy-global" + ] + } +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-07/record.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-07/record.json new file mode 100644 index 0000000..a1b7f4d --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-07/record.json @@ -0,0 +1,186 @@ +{ + "attempt_id": "cbs-native-07-attempt-01", + "cleanup": { + "attempted": true, + "receipt_ref": "cleanup.cbs-native-07-attempt-01", + "verified": true + }, + "declaration_sha256": "825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232", + "diagnostics": [], + "disposition": "valid", + "evidence_refs": [], + "lane": "source-native", + "metric_status": { + "cumulative_attacker_reward": "available", + "network_availability": "available", + "steps_to_termination": "available", + "terminal_cause": "available" + }, + "metrics": { + "cumulative_attacker_reward": 5639.0, + "network_availability": [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.75 + ], + "steps_to_termination": 146, + "terminal_cause": "defender-sla" + }, + "protocol_sha256": null, + "replicate": 7, + "run_id": "cbs-native-07", + "schema_version": "cyberbattlesim-baseline-run/v1", + "seed_label": 20260729, + "stochastic_controls": { + "applied": [], + "unbound": [ + "gym-environment", + "gym-action-space", + "python-random", + "numpy-global" + ] + } +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-08/record.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-08/record.json new file mode 100644 index 0000000..676da4d --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-08/record.json @@ -0,0 +1,406 @@ +{ + "attempt_id": "cbs-native-08-attempt-01", + "cleanup": { + "attempted": true, + "receipt_ref": "cleanup.cbs-native-08-attempt-01", + "verified": true + }, + "declaration_sha256": "825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232", + "diagnostics": [], + "disposition": "valid", + "evidence_refs": [], + "lane": "source-native", + "metric_status": { + "cumulative_attacker_reward": "available", + "network_availability": "available", + "steps_to_termination": "available", + "terminal_cause": "available" + }, + "metrics": { + "cumulative_attacker_reward": 5779.0, + "network_availability": [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.75 + ], + "steps_to_termination": 366, + "terminal_cause": "defender-sla" + }, + "protocol_sha256": null, + "replicate": 8, + "run_id": "cbs-native-08", + "schema_version": "cyberbattlesim-baseline-run/v1", + "seed_label": 20260729, + "stochastic_controls": { + "applied": [], + "unbound": [ + "gym-environment", + "gym-action-space", + "python-random", + "numpy-global" + ] + } +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-09/record.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-09/record.json new file mode 100644 index 0000000..a65c980 --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-09/record.json @@ -0,0 +1,371 @@ +{ + "attempt_id": "cbs-native-09-attempt-01", + "cleanup": { + "attempted": true, + "receipt_ref": "cleanup.cbs-native-09-attempt-01", + "verified": true + }, + "declaration_sha256": "825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232", + "diagnostics": [], + "disposition": "valid", + "evidence_refs": [], + "lane": "source-native", + "metric_status": { + "cumulative_attacker_reward": "available", + "network_availability": "available", + "steps_to_termination": "available", + "terminal_cause": "available" + }, + "metrics": { + "cumulative_attacker_reward": 5886.0, + "network_availability": [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.75 + ], + "steps_to_termination": 331, + "terminal_cause": "defender-sla" + }, + "protocol_sha256": null, + "replicate": 9, + "run_id": "cbs-native-09", + "schema_version": "cyberbattlesim-baseline-run/v1", + "seed_label": 20260729, + "stochastic_controls": { + "applied": [], + "unbound": [ + "gym-environment", + "gym-action-space", + "python-random", + "numpy-global" + ] + } +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-10/record.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-10/record.json new file mode 100644 index 0000000..6b46833 --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/runs/cbs-native-10/record.json @@ -0,0 +1,401 @@ +{ + "attempt_id": "cbs-native-10-attempt-01", + "cleanup": { + "attempted": true, + "receipt_ref": "cleanup.cbs-native-10-attempt-01", + "verified": true + }, + "declaration_sha256": "825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232", + "diagnostics": [], + "disposition": "valid", + "evidence_refs": [], + "lane": "source-native", + "metric_status": { + "cumulative_attacker_reward": "available", + "network_availability": "available", + "steps_to_termination": "available", + "terminal_cause": "available" + }, + "metrics": { + "cumulative_attacker_reward": 6020.0, + "network_availability": [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.8333333333333334, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.9166666666666666, + 0.75 + ], + "steps_to_termination": 361, + "terminal_cause": "defender-sla" + }, + "protocol_sha256": null, + "replicate": 10, + "run_id": "cbs-native-10", + "schema_version": "cyberbattlesim-baseline-run/v1", + "seed_label": 20260729, + "stochastic_controls": { + "applied": [], + "unbound": [ + "gym-environment", + "gym-action-space", + "python-random", + "numpy-global" + ] + } +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/source-ledger.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/source-ledger.json new file mode 100644 index 0000000..28cf724 --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/source-ledger.json @@ -0,0 +1,107 @@ +{ + "adapter": { + "distribution": "raes-adapters", + "runner_artifact_ids": [ + "reproduction-runner", + "mediated-researcher", + "mediated-driver", + "selected-source-helper" + ], + "version": "0.0.0" + }, + "artifact_refs": [ + { + "artifact_id": "qualification", + "path": "src/raes_adapters/cyberbattlesim/qualification.json", + "sha256": "0b55f88c0ff628980c976a50f38f71ff7ec0f94b2e50e2b87f6498d5dd01c147" + }, + { + "artifact_id": "public-protocol", + "path": "src/raes_adapters/cyberbattlesim/public-protocol.md", + "sha256": "0de0d8585ee9e3bb0901bd2d71b71a9504774b38bdab38f6f5509d0a9e34d26f" + }, + { + "artifact_id": "source-ledger", + "path": "src/raes_adapters/cyberbattlesim/mapping/source-ledger.jsonl", + "sha256": "8776a340873e6b56a55767e4257f05ba1bb71fa2b37003a2023b0fe3b0cce553" + }, + { + "artifact_id": "loss-disclosures", + "path": "src/raes_adapters/cyberbattlesim/mapping/loss-disclosures.md", + "sha256": "3c2530553a6ab035a6c505e80bf02298f1ab07dd3ffc72216f87f6381113181c" + }, + { + "artifact_id": "reproduction-runner", + "path": "src/raes_adapters/cyberbattlesim/reproduction.py", + "sha256": "44c5573635a2adc655e78eff8765c25c58b469a3f378975fce83f21c6c4ead98" + }, + { + "artifact_id": "mediated-researcher", + "path": "src/raes_adapters/cyberbattlesim/researcher.py", + "sha256": "35a320b319fd2fd880a49ce2a670576c23a754ff4a67d80618be848fb42fc0d1" + }, + { + "artifact_id": "mediated-driver", + "path": "src/raes_adapters/cyberbattlesim/backend/driver.py", + "sha256": "1f86e3522c6e7ff5b17f8ac4eed5d9567da3c674218b5f1bf3cd8c0e10028202" + }, + { + "artifact_id": "selected-source-helper", + "path": "src/raes_adapters/cyberbattlesim/backend/source.py", + "sha256": "977b91e77d0c1fe23f265ab59151a8c478b43fff20d44afd79b0392c20bf62de" + }, + { + "artifact_id": "task", + "path": "environments/cyberbattlesim-chain/experiment/cyberbattlesim-chain.task.exp.json", + "sha256": "6588ac115931b8de7052d52ccb94bbd258c5e6c78ffb9d5f5d1c0570f9236ce5" + }, + { + "artifact_id": "spec", + "path": "environments/cyberbattlesim-chain/experiment/cyberbattlesim-chain.spec.exp.json", + "sha256": "c31d2f4376ad7877d756e6a572a5e9e344b0899c4e8e996e1b5f57eaa78be391" + }, + { + "artifact_id": "pack-manifest", + "path": "environments/cyberbattlesim-chain/pack.content-manifest.json", + "sha256": "8131a2a294da39fceeca1595da1f987dbbc934a234c635fbb935e7d223cf103c" + }, + { + "artifact_id": "participant-manifest", + "path": "environments/cyberbattlesim-chain/participant/cyberbattlesim-red-credential-cache.manifest.json", + "sha256": "2ea827eb709a036b1721a91fabce787a320845bf26e3e6f0a0e5e768e7f9d93b" + }, + { + "artifact_id": "participant-selection", + "path": "environments/cyberbattlesim-chain/participant/cyberbattlesim-red-credential-cache.selection.json", + "sha256": "ce920ca6362b37e8cde6af12190ee9b84e9ea3c3fc89842d31366f0ec6031935" + }, + { + "artifact_id": "participant-configuration", + "path": "environments/cyberbattlesim-chain/participant/cyberbattlesim-red-credential-cache.configuration.json", + "sha256": "2b5e0fd0ef0be839af33763199e76192196a4928ca555a230af0f685c38eeced" + } + ], + "compatibility_patches": [], + "exclusions": [ + "historical benchmark output from a different commit", + "native observations, action coordinates, credentials, hidden state, and reward vectors", + "provider logs, credentials, environment dumps, and tracebacks" + ], + "loss_refs": [ + "loss-abstracted-topology", + "loss-benchmark-defects", + "loss-no-source-artifact", + "loss-observation-abstraction", + "loss-unbound-random-streams" + ], + "schema_version": "cyberbattlesim-baseline-source-ledger/v1", + "source": { + "commit": "854d6966607fb68645651f55b0f97221bd293e0d", + "notebook_path": "notebooks/notebook_withdefender.py", + "notebook_sha256": "847999b0a907c22a6e64b93c96d444d43e0a66dbfba2a2bd0a9ba888cfa41fcc", + "repository": "https://github.com/microsoft/CyberBattleSim", + "runtime_tree_sha256": "1b8bf39a7cb9c172b51b5223dfac13b9d01e166b34dc2bb29297cddb254a06fe", + "tree": "4271b137ab2de593be52d7afb0a51bee59045a45", + "version": "0.1.0" + } +} From bf1cbff7bfeace506324910651697ef7b00b5de6 Mon Sep 17 00:00:00 2001 From: Brad Edwards Date: Mon, 10 Aug 2026 06:26:18 +0200 Subject: [PATCH 03/14] fix(cyberbattlesim): preserve rejected baseline series --- docs/cyberbattlesim-baseline-reproduction.md | 11 + .../declaration/bench-notes.json | 23 + .../declaration/inventory.json | 22 + .../declaration/protocol.json | 495 +++ .../{ => declaration}/source-ledger.json | 0 .../mediated/bench-notes.json | 344 ++ .../mediated/collection.json | 6 + .../mediated/environment.json | 41 + .../mediated/inventory.json | 628 +++ .../{ => mediated}/protocol.json | 0 .../cbs-mediated-01/portable/inventory.json | 58 + .../portable/machine-inventory.json | 17 + .../cbs-mediated-01/portable/provenance.json | 409 ++ .../cbs-mediated-01-1/derived-measures.json | 46 + .../runs/cbs-mediated-01-1/diagnostics.json | 30 + .../cbs-mediated-01-1/evidence-records.json | 59 + .../participant-provenance.json | 55 + .../portable/runs/cbs-mediated-01-1/run.json | 391 ++ .../runs/cbs-mediated-01-1/summary.json | 8 + .../cbs-mediated-01/portable/summary.json | 15 + .../mediated/runs/cbs-mediated-01/record.json | 57 + .../cbs-mediated-02/portable/inventory.json | 58 + .../portable/machine-inventory.json | 17 + .../cbs-mediated-02/portable/provenance.json | 409 ++ .../cbs-mediated-02-1/derived-measures.json | 46 + .../runs/cbs-mediated-02-1/diagnostics.json | 30 + .../cbs-mediated-02-1/evidence-records.json | 59 + .../participant-provenance.json | 55 + .../portable/runs/cbs-mediated-02-1/run.json | 391 ++ .../runs/cbs-mediated-02-1/summary.json | 8 + .../cbs-mediated-02/portable/summary.json | 15 + .../mediated/runs/cbs-mediated-02/record.json | 57 + .../cbs-mediated-03/portable/inventory.json | 58 + .../portable/machine-inventory.json | 17 + .../cbs-mediated-03/portable/provenance.json | 409 ++ .../cbs-mediated-03-1/derived-measures.json | 46 + .../runs/cbs-mediated-03-1/diagnostics.json | 30 + .../cbs-mediated-03-1/evidence-records.json | 59 + .../participant-provenance.json | 55 + .../portable/runs/cbs-mediated-03-1/run.json | 391 ++ .../runs/cbs-mediated-03-1/summary.json | 8 + .../cbs-mediated-03/portable/summary.json | 15 + .../mediated/runs/cbs-mediated-03/record.json | 57 + .../cbs-mediated-04/portable/inventory.json | 58 + .../portable/machine-inventory.json | 17 + .../cbs-mediated-04/portable/provenance.json | 409 ++ .../cbs-mediated-04-1/derived-measures.json | 46 + .../runs/cbs-mediated-04-1/diagnostics.json | 30 + .../cbs-mediated-04-1/evidence-records.json | 59 + .../participant-provenance.json | 55 + .../portable/runs/cbs-mediated-04-1/run.json | 391 ++ .../runs/cbs-mediated-04-1/summary.json | 8 + .../cbs-mediated-04/portable/summary.json | 15 + .../mediated/runs/cbs-mediated-04/record.json | 57 + .../cbs-mediated-05/portable/inventory.json | 58 + .../portable/machine-inventory.json | 17 + .../cbs-mediated-05/portable/provenance.json | 409 ++ .../cbs-mediated-05-1/derived-measures.json | 46 + .../runs/cbs-mediated-05-1/diagnostics.json | 30 + .../cbs-mediated-05-1/evidence-records.json | 59 + .../participant-provenance.json | 55 + .../portable/runs/cbs-mediated-05-1/run.json | 391 ++ .../runs/cbs-mediated-05-1/summary.json | 8 + .../cbs-mediated-05/portable/summary.json | 15 + .../mediated/runs/cbs-mediated-05/record.json | 57 + .../cbs-mediated-06/portable/inventory.json | 58 + .../portable/machine-inventory.json | 17 + .../cbs-mediated-06/portable/provenance.json | 409 ++ .../cbs-mediated-06-1/derived-measures.json | 46 + .../runs/cbs-mediated-06-1/diagnostics.json | 30 + .../cbs-mediated-06-1/evidence-records.json | 59 + .../participant-provenance.json | 55 + .../portable/runs/cbs-mediated-06-1/run.json | 391 ++ .../runs/cbs-mediated-06-1/summary.json | 8 + .../cbs-mediated-06/portable/summary.json | 15 + .../mediated/runs/cbs-mediated-06/record.json | 57 + .../cbs-mediated-07/portable/inventory.json | 58 + .../portable/machine-inventory.json | 17 + .../cbs-mediated-07/portable/provenance.json | 409 ++ .../cbs-mediated-07-1/derived-measures.json | 46 + .../runs/cbs-mediated-07-1/diagnostics.json | 30 + .../cbs-mediated-07-1/evidence-records.json | 59 + .../participant-provenance.json | 55 + .../portable/runs/cbs-mediated-07-1/run.json | 391 ++ .../runs/cbs-mediated-07-1/summary.json | 8 + .../cbs-mediated-07/portable/summary.json | 15 + .../mediated/runs/cbs-mediated-07/record.json | 57 + .../cbs-mediated-08/portable/inventory.json | 58 + .../portable/machine-inventory.json | 17 + .../cbs-mediated-08/portable/provenance.json | 409 ++ .../cbs-mediated-08-1/derived-measures.json | 46 + .../runs/cbs-mediated-08-1/diagnostics.json | 30 + .../cbs-mediated-08-1/evidence-records.json | 59 + .../participant-provenance.json | 55 + .../portable/runs/cbs-mediated-08-1/run.json | 391 ++ .../runs/cbs-mediated-08-1/summary.json | 8 + .../cbs-mediated-08/portable/summary.json | 15 + .../mediated/runs/cbs-mediated-08/record.json | 57 + .../cbs-mediated-09/portable/inventory.json | 58 + .../portable/machine-inventory.json | 17 + .../cbs-mediated-09/portable/provenance.json | 409 ++ .../cbs-mediated-09-1/derived-measures.json | 46 + .../runs/cbs-mediated-09-1/diagnostics.json | 30 + .../cbs-mediated-09-1/evidence-records.json | 59 + .../participant-provenance.json | 55 + .../portable/runs/cbs-mediated-09-1/run.json | 391 ++ .../runs/cbs-mediated-09-1/summary.json | 8 + .../cbs-mediated-09/portable/summary.json | 15 + .../mediated/runs/cbs-mediated-09/record.json | 57 + .../cbs-mediated-10/portable/inventory.json | 58 + .../portable/machine-inventory.json | 17 + .../cbs-mediated-10/portable/provenance.json | 409 ++ .../cbs-mediated-10-1/derived-measures.json | 46 + .../runs/cbs-mediated-10-1/diagnostics.json | 30 + .../cbs-mediated-10-1/evidence-records.json | 59 + .../participant-provenance.json | 55 + .../portable/runs/cbs-mediated-10-1/run.json | 391 ++ .../runs/cbs-mediated-10-1/summary.json | 8 + .../cbs-mediated-10/portable/summary.json | 15 + .../mediated/runs/cbs-mediated-10/record.json | 57 + .../{ => native-oracle}/bench-notes.json | 0 .../{ => native-oracle}/collection.json | 0 .../{ => native-oracle}/environment.json | 0 .../{ => native-oracle}/inventory.json | 0 .../native-oracle/protocol.json | 3581 +++++++++++++++++ .../runs/cbs-native-01/record.json | 0 .../runs/cbs-native-02/record.json | 0 .../runs/cbs-native-03/record.json | 0 .../runs/cbs-native-04/record.json | 0 .../runs/cbs-native-05/record.json | 0 .../runs/cbs-native-06/record.json | 0 .../runs/cbs-native-07/record.json | 0 .../runs/cbs-native-08/record.json | 0 .../runs/cbs-native-09/record.json | 0 .../runs/cbs-native-10/record.json | 0 .../native-oracle/source-ledger.json | 107 + .../rejection.json | 34 + .../cyberbattlesim/reproduction.py | 77 +- tests/test_cyberbattlesim_reproduction.py | 64 + 139 files changed, 16875 insertions(+), 8 deletions(-) create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/declaration/bench-notes.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/declaration/inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/declaration/protocol.json rename packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/{ => declaration}/source-ledger.json (100%) create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/bench-notes.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/collection.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/environment.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/inventory.json rename packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/{ => mediated}/protocol.json (100%) create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/machine-inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/provenance.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/derived-measures.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/diagnostics.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/evidence-records.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/participant-provenance.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/run.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/summary.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/summary.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/record.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-02/portable/inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-02/portable/machine-inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-02/portable/provenance.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-02/portable/runs/cbs-mediated-02-1/derived-measures.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-02/portable/runs/cbs-mediated-02-1/diagnostics.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-02/portable/runs/cbs-mediated-02-1/evidence-records.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-02/portable/runs/cbs-mediated-02-1/participant-provenance.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-02/portable/runs/cbs-mediated-02-1/run.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-02/portable/runs/cbs-mediated-02-1/summary.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-02/portable/summary.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-02/record.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-03/portable/inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-03/portable/machine-inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-03/portable/provenance.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-03/portable/runs/cbs-mediated-03-1/derived-measures.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-03/portable/runs/cbs-mediated-03-1/diagnostics.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-03/portable/runs/cbs-mediated-03-1/evidence-records.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-03/portable/runs/cbs-mediated-03-1/participant-provenance.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-03/portable/runs/cbs-mediated-03-1/run.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-03/portable/runs/cbs-mediated-03-1/summary.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-03/portable/summary.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-03/record.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-04/portable/inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-04/portable/machine-inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-04/portable/provenance.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-04/portable/runs/cbs-mediated-04-1/derived-measures.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-04/portable/runs/cbs-mediated-04-1/diagnostics.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-04/portable/runs/cbs-mediated-04-1/evidence-records.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-04/portable/runs/cbs-mediated-04-1/participant-provenance.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-04/portable/runs/cbs-mediated-04-1/run.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-04/portable/runs/cbs-mediated-04-1/summary.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-04/portable/summary.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-04/record.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-05/portable/inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-05/portable/machine-inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-05/portable/provenance.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-05/portable/runs/cbs-mediated-05-1/derived-measures.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-05/portable/runs/cbs-mediated-05-1/diagnostics.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-05/portable/runs/cbs-mediated-05-1/evidence-records.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-05/portable/runs/cbs-mediated-05-1/participant-provenance.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-05/portable/runs/cbs-mediated-05-1/run.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-05/portable/runs/cbs-mediated-05-1/summary.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-05/portable/summary.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-05/record.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-06/portable/inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-06/portable/machine-inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-06/portable/provenance.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-06/portable/runs/cbs-mediated-06-1/derived-measures.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-06/portable/runs/cbs-mediated-06-1/diagnostics.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-06/portable/runs/cbs-mediated-06-1/evidence-records.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-06/portable/runs/cbs-mediated-06-1/participant-provenance.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-06/portable/runs/cbs-mediated-06-1/run.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-06/portable/runs/cbs-mediated-06-1/summary.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-06/portable/summary.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-06/record.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-07/portable/inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-07/portable/machine-inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-07/portable/provenance.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-07/portable/runs/cbs-mediated-07-1/derived-measures.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-07/portable/runs/cbs-mediated-07-1/diagnostics.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-07/portable/runs/cbs-mediated-07-1/evidence-records.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-07/portable/runs/cbs-mediated-07-1/participant-provenance.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-07/portable/runs/cbs-mediated-07-1/run.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-07/portable/runs/cbs-mediated-07-1/summary.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-07/portable/summary.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-07/record.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-08/portable/inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-08/portable/machine-inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-08/portable/provenance.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-08/portable/runs/cbs-mediated-08-1/derived-measures.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-08/portable/runs/cbs-mediated-08-1/diagnostics.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-08/portable/runs/cbs-mediated-08-1/evidence-records.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-08/portable/runs/cbs-mediated-08-1/participant-provenance.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-08/portable/runs/cbs-mediated-08-1/run.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-08/portable/runs/cbs-mediated-08-1/summary.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-08/portable/summary.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-08/record.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-09/portable/inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-09/portable/machine-inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-09/portable/provenance.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-09/portable/runs/cbs-mediated-09-1/derived-measures.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-09/portable/runs/cbs-mediated-09-1/diagnostics.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-09/portable/runs/cbs-mediated-09-1/evidence-records.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-09/portable/runs/cbs-mediated-09-1/participant-provenance.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-09/portable/runs/cbs-mediated-09-1/run.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-09/portable/runs/cbs-mediated-09-1/summary.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-09/portable/summary.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-09/record.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-10/portable/inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-10/portable/machine-inventory.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-10/portable/provenance.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-10/portable/runs/cbs-mediated-10-1/derived-measures.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-10/portable/runs/cbs-mediated-10-1/diagnostics.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-10/portable/runs/cbs-mediated-10-1/evidence-records.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-10/portable/runs/cbs-mediated-10-1/participant-provenance.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-10/portable/runs/cbs-mediated-10-1/run.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-10/portable/runs/cbs-mediated-10-1/summary.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-10/portable/summary.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-10/record.json rename packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/{ => native-oracle}/bench-notes.json (100%) rename packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/{ => native-oracle}/collection.json (100%) rename packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/{ => native-oracle}/environment.json (100%) rename packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/{ => native-oracle}/inventory.json (100%) create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/native-oracle/protocol.json rename packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/{ => native-oracle}/runs/cbs-native-01/record.json (100%) rename packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/{ => native-oracle}/runs/cbs-native-02/record.json (100%) rename packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/{ => native-oracle}/runs/cbs-native-03/record.json (100%) rename packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/{ => native-oracle}/runs/cbs-native-04/record.json (100%) rename packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/{ => native-oracle}/runs/cbs-native-05/record.json (100%) rename packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/{ => native-oracle}/runs/cbs-native-06/record.json (100%) rename packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/{ => native-oracle}/runs/cbs-native-07/record.json (100%) rename packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/{ => native-oracle}/runs/cbs-native-08/record.json (100%) rename packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/{ => native-oracle}/runs/cbs-native-09/record.json (100%) rename packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/{ => native-oracle}/runs/cbs-native-10/record.json (100%) create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/native-oracle/source-ledger.json create mode 100644 packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/rejection.json diff --git a/docs/cyberbattlesim-baseline-reproduction.md b/docs/cyberbattlesim-baseline-reproduction.md index b73cf70..8cd8a49 100644 --- a/docs/cyberbattlesim-baseline-reproduction.md +++ b/docs/cyberbattlesim-baseline-reproduction.md @@ -47,6 +47,17 @@ schedule. Native reward vectors exist only in private scratch; portable rows retain cumulative reward, steps, availability, and a source-backed terminal cause. +The first terminalized 20-attempt series under declaration +`825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232` +is rejected from final publication. Its byte-oriented leak gate treated the +names of fields explicitly listed in RAES `withheld_refs` as if native values +had leaked. The scanner bound into that declaration was not changed in place. +The replacement declaration discloses the rejection and allocates disjoint +`cbs-r2-*` run and attempt identities while leaving the source, conditions, +metrics, aggregation, tolerances, and tier policy unchanged. The structural +gate permits those names only as withheld-reference strings; the same names as +JSON keys, embedded payload strings, or non-JSON content still fail closed. + Every stage also writes `bench-notes.json`. Each closed note has an RFC 3339 UTC timestamp with millisecond precision, phase, severity, stable event code, concise observation, disposition, and relative evidence references. Collection diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/declaration/bench-notes.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/declaration/bench-notes.json new file mode 100644 index 0000000..1ab3ece --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/declaration/bench-notes.json @@ -0,0 +1,23 @@ +{ + "declaration_sha256": "825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232", + "notes": [ + { + "disposition": "passed", + "event_code": "protocol-declared", + "evidence_refs": [ + { + "path": "protocol.json" + }, + { + "path": "source-ledger.json" + } + ], + "note_id": "declaration-001", + "phase": "declaration", + "recorded_at": "2026-08-10T03:54:02.312Z", + "severity": "info", + "summary": "The declaration and 20 never-reused attempt identities were written before experiment effects." + } + ], + "schema_version": "cyberbattlesim-baseline-bench-notes/v1" +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/declaration/inventory.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/declaration/inventory.json new file mode 100644 index 0000000..9bbc9eb --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/declaration/inventory.json @@ -0,0 +1,22 @@ +{ + "artifacts": [ + { + "media_type": "application/json", + "path": "bench-notes.json", + "sha256": "2abc2ef6dbd22b16fe465068d557edd87864cb5f5c44ab23fd78b96499e81690", + "size_bytes": 662 + }, + { + "media_type": "application/json", + "path": "protocol.json", + "sha256": "ca618b9541527af706bc78d8b8262f9c83af0668801adf6574b2517d52e4ed1f", + "size_bytes": 17372 + }, + { + "media_type": "application/json", + "path": "source-ledger.json", + "sha256": "01c8dee3298778bdf537281b128b39c8030f134fe7492fabe4577d62ed370598", + "size_bytes": 4338 + } + ] +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/declaration/protocol.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/declaration/protocol.json new file mode 100644 index 0000000..eded497 --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/declaration/protocol.json @@ -0,0 +1,495 @@ +{ + "declaration": { + "aggregation": { + "bootstrap_resamples": 10000, + "missingness": "No imputation; every terminal attempt remains in denominators.", + "numeric_statistics": [ + "count", + "mean", + "median", + "sample-standard-deviation", + "minimum", + "maximum" + ], + "uncertainty": "95% deterministic percentile bootstrap interval of the mean" + }, + "artifacts": [ + { + "artifact_id": "qualification", + "path": "src/raes_adapters/cyberbattlesim/qualification.json", + "sha256": "0b55f88c0ff628980c976a50f38f71ff7ec0f94b2e50e2b87f6498d5dd01c147" + }, + { + "artifact_id": "public-protocol", + "path": "src/raes_adapters/cyberbattlesim/public-protocol.md", + "sha256": "0de0d8585ee9e3bb0901bd2d71b71a9504774b38bdab38f6f5509d0a9e34d26f" + }, + { + "artifact_id": "source-ledger", + "path": "src/raes_adapters/cyberbattlesim/mapping/source-ledger.jsonl", + "sha256": "8776a340873e6b56a55767e4257f05ba1bb71fa2b37003a2023b0fe3b0cce553" + }, + { + "artifact_id": "loss-disclosures", + "path": "src/raes_adapters/cyberbattlesim/mapping/loss-disclosures.md", + "sha256": "3c2530553a6ab035a6c505e80bf02298f1ab07dd3ffc72216f87f6381113181c" + }, + { + "artifact_id": "reproduction-runner", + "path": "src/raes_adapters/cyberbattlesim/reproduction.py", + "sha256": "44c5573635a2adc655e78eff8765c25c58b469a3f378975fce83f21c6c4ead98" + }, + { + "artifact_id": "mediated-researcher", + "path": "src/raes_adapters/cyberbattlesim/researcher.py", + "sha256": "35a320b319fd2fd880a49ce2a670576c23a754ff4a67d80618be848fb42fc0d1" + }, + { + "artifact_id": "mediated-driver", + "path": "src/raes_adapters/cyberbattlesim/backend/driver.py", + "sha256": "1f86e3522c6e7ff5b17f8ac4eed5d9567da3c674218b5f1bf3cd8c0e10028202" + }, + { + "artifact_id": "selected-source-helper", + "path": "src/raes_adapters/cyberbattlesim/backend/source.py", + "sha256": "977b91e77d0c1fe23f265ab59151a8c478b43fff20d44afd79b0392c20bf62de" + }, + { + "artifact_id": "task", + "path": "environments/cyberbattlesim-chain/experiment/cyberbattlesim-chain.task.exp.json", + "sha256": "6588ac115931b8de7052d52ccb94bbd258c5e6c78ffb9d5f5d1c0570f9236ce5" + }, + { + "artifact_id": "spec", + "path": "environments/cyberbattlesim-chain/experiment/cyberbattlesim-chain.spec.exp.json", + "sha256": "c31d2f4376ad7877d756e6a572a5e9e344b0899c4e8e996e1b5f57eaa78be391" + }, + { + "artifact_id": "pack-manifest", + "path": "environments/cyberbattlesim-chain/pack.content-manifest.json", + "sha256": "8131a2a294da39fceeca1595da1f987dbbc934a234c635fbb935e7d223cf103c" + }, + { + "artifact_id": "participant-manifest", + "path": "environments/cyberbattlesim-chain/participant/cyberbattlesim-red-credential-cache.manifest.json", + "sha256": "2ea827eb709a036b1721a91fabce787a320845bf26e3e6f0a0e5e768e7f9d93b" + }, + { + "artifact_id": "participant-selection", + "path": "environments/cyberbattlesim-chain/participant/cyberbattlesim-red-credential-cache.selection.json", + "sha256": "ce920ca6362b37e8cde6af12190ee9b84e9ea3c3fc89842d31366f0ec6031935" + }, + { + "artifact_id": "participant-configuration", + "path": "environments/cyberbattlesim-chain/participant/cyberbattlesim-red-credential-cache.configuration.json", + "sha256": "2b5e0fd0ef0be839af33763199e76192196a4928ca555a230af0f685c38eeced" + } + ], + "bench_notes": { + "artifact": "bench-notes.json", + "publication_policy": "Record controlled observations and dispositions as work occurs; exclude raw native output, exception text, host paths, credentials, and provider identifiers.", + "required_fields": [ + "note_id", + "recorded_at", + "phase", + "severity", + "event_code", + "summary", + "disposition", + "evidence_refs" + ], + "schema_version": "cyberbattlesim-baseline-bench-notes/v1", + "timestamp_profile": "RFC3339 UTC with millisecond precision" + }, + "comparison": { + "bounded": { + "cumulative_attacker_reward": 500.0, + "network_availability": 0.05, + "steps_to_termination": 60.0, + "terminal_cause": 0.1 + }, + "exact": "Complete ordered per-run vectors and control dispositions match.", + "failed": "A complete interval lies outside its bound.", + "unavailable": "A declared metric is absent from either lane; no tolerance is inferred." + }, + "condition": { + "attacker": "CredentialCacheExploiter", + "defender": "ScanAndReimageCompromisedMachines(0.6,2,5)", + "episode_count_per_lane": 10, + "epsilon": 0.9, + "epsilon_exponential_decay": 10000, + "epsilon_minimum": 0.1, + "gym_id": "CyberBattleChain-v0", + "maximum_steps": 600, + "size": 10 + }, + "explicit_non_claims": [ + "deterministic replay", + "exact state or observation equivalence", + "cross-simulator equality", + "agent ranking", + "benchmark comparability", + "outcome equivalence", + "general scientific reproducibility" + ], + "metrics": [ + "steps_to_termination", + "cumulative_attacker_reward", + "network_availability", + "terminal_cause" + ], + "retry_budget": 0, + "schedule": [ + { + "attempt_id": "cbs-native-01-attempt-01", + "lane": "source-native", + "replicate": 1, + "run_id": "cbs-native-01", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-native-02-attempt-01", + "lane": "source-native", + "replicate": 2, + "run_id": "cbs-native-02", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-native-03-attempt-01", + "lane": "source-native", + "replicate": 3, + "run_id": "cbs-native-03", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-native-04-attempt-01", + "lane": "source-native", + "replicate": 4, + "run_id": "cbs-native-04", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-native-05-attempt-01", + "lane": "source-native", + "replicate": 5, + "run_id": "cbs-native-05", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-native-06-attempt-01", + "lane": "source-native", + "replicate": 6, + "run_id": "cbs-native-06", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-native-07-attempt-01", + "lane": "source-native", + "replicate": 7, + "run_id": "cbs-native-07", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-native-08-attempt-01", + "lane": "source-native", + "replicate": 8, + "run_id": "cbs-native-08", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-native-09-attempt-01", + "lane": "source-native", + "replicate": 9, + "run_id": "cbs-native-09", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-native-10-attempt-01", + "lane": "source-native", + "replicate": 10, + "run_id": "cbs-native-10", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-mediated-01-attempt-01", + "lane": "raes-mediated", + "replicate": 1, + "run_id": "cbs-mediated-01", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-mediated-02-attempt-01", + "lane": "raes-mediated", + "replicate": 2, + "run_id": "cbs-mediated-02", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-mediated-03-attempt-01", + "lane": "raes-mediated", + "replicate": 3, + "run_id": "cbs-mediated-03", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-mediated-04-attempt-01", + "lane": "raes-mediated", + "replicate": 4, + "run_id": "cbs-mediated-04", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-mediated-05-attempt-01", + "lane": "raes-mediated", + "replicate": 5, + "run_id": "cbs-mediated-05", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-mediated-06-attempt-01", + "lane": "raes-mediated", + "replicate": 6, + "run_id": "cbs-mediated-06", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-mediated-07-attempt-01", + "lane": "raes-mediated", + "replicate": 7, + "run_id": "cbs-mediated-07", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-mediated-08-attempt-01", + "lane": "raes-mediated", + "replicate": 8, + "run_id": "cbs-mediated-08", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-mediated-09-attempt-01", + "lane": "raes-mediated", + "replicate": 9, + "run_id": "cbs-mediated-09", + "seed_label": 20260729 + }, + { + "attempt_id": "cbs-mediated-10-attempt-01", + "lane": "raes-mediated", + "replicate": 10, + "run_id": "cbs-mediated-10", + "seed_label": 20260729 + } + ], + "source_selection": { + "commit": "854d6966607fb68645651f55b0f97221bd293e0d", + "evaluator": "cyberbattle.agents.baseline.learner.epsilon_greedy_search", + "notebook_path": "notebooks/notebook_withdefender.py", + "notebook_sha256": "847999b0a907c22a6e64b93c96d444d43e0a66dbfba2a2bd0a9ba888cfa41fcc", + "repository": "https://github.com/microsoft/CyberBattleSim", + "runtime_tree_sha256": "1b8bf39a7cb9c172b51b5223dfac13b9d01e166b34dc2bb29297cddb254a06fe", + "tree": "4271b137ab2de593be52d7afb0a51bee59045a45", + "version": "0.1.0" + }, + "stochastic_controls": { + "raes-mediated": { + "applied": [ + "gym-environment", + "gym-action-space" + ], + "unbound": [ + "python-random", + "numpy-global" + ] + }, + "source-native": { + "applied": [], + "unbound": [ + "gym-environment", + "gym-action-space", + "python-random", + "numpy-global" + ] + } + }, + "study": { + "analysis_plan": { + "analysis_id": "cyberbattlesim-baseline-comparison-v1", + "description": "Lane summaries and predeclared bounded differences.", + "metrics": [ + "steps_to_termination", + "cumulative_attacker_reward", + "network_availability", + "terminal_cause" + ], + "missing_data_policy": { + "handling": "Retain all terminal attempts in denominators; do not impute or silently drop.", + "missingness_assumption": "Missingness is apparatus- or failure-induced, not random.", + "sensitivity_analysis": "Unavailable declared metrics weaken the applicable tier." + }, + "multiple_comparison_policy": { + "correction": "none", + "family": "four descriptive metric comparisons", + "rationale": "No hypothesis-test or general population claim is made." + }, + "primary_metric": "cumulative_attacker_reward", + "statistical_method": { + "assumptions": [ + "Attempts are the fixed scheduled episodes and are not replaced after failure." + ], + "comparison_family": "four predeclared task metrics", + "estimand": "RAES-mediated lane mean minus source-native lane mean", + "method": "descriptive lane summaries and difference in means", + "unit_of_analysis": "episode" + }, + "uncertainty_method": { + "interval_level": 0.95, + "method": "deterministic percentile bootstrap", + "procedure": "10,000 counter-addressed SHA-256 resamples bound to the declaration digest." + } + }, + "behavioral_claims": [ + { + "assurance_axis": "bounded-test", + "assurance_status": "tested", + "evidence_boundary": "Exactly ten preallocated terminal attempts per lane under the frozen issue-30 comparison and missingness rules.", + "evidence_refs": [], + "evidence_scope": "finite", + "explicit_non_claims": [ + "No trace, state, observation, deterministic-replay, or outcome-equivalence claim is made." + ], + "left_carrier_ref": "condition:source-native", + "limitations": [ + "The lanes have different stochastic bindings and evaluator paths." + ], + "observation_projection_ref": "experiment-study-v1", + "observation_projection_revision": "rev1", + "quantifier_scope": "finite-cases", + "relation_id": "empirical-adequacy", + "relation_parameter_profile_ref": null, + "relation_parameter_profile_revision": null, + "right_carrier_ref": "condition:raes-mediated", + "subject": "The fixed CyberBattleSim credential-cache baseline selection", + "taxonomy_id": "raes-behavioral-relations", + "taxonomy_revision": "rev12" + } + ], + "description": "Frozen two-lane reproduction of the selected public credential-cache baseline.", + "export_artifacts": [], + "factors": { + "execution-lane": { + "factor_kind": "apparatus", + "levels": [ + "source-native", + "raes-mediated" + ], + "name": "Execution lane" + } + }, + "inclusion_criteria": [ + "Only preallocated terminal attempts from the exact qualified selection are included." + ], + "membership": { + "primary-task": { + "grouping": null, + "inclusion_rationale": "The qualified public task owns all measured constructs.", + "role": "primary-task", + "target_ref": { + "ref_digest": null, + "ref_id": "cyberbattlesim-chain-task", + "ref_kind": "task", + "ref_path": null, + "ref_version": null + } + } + }, + "owner": "OpenRAE", + "purpose": "Retain bounded readiness and reproduction evidence for OpenRAE/research#14 and OpenRAE/research#20 without asserting deterministic replay or outcome equivalence.", + "report_artifacts": [], + "research_questions": [ + "Which authored, contract, control, observation, outcome, and disclosure facts survive the selected RAES-mediated execution?" + ], + "run_allocation": { + "allocation_method": "preallocated fixed condition matrix", + "allocation_unit": "episode", + "blocking_factors": [], + "compared_conditions": [ + "source-native", + "raes-mediated" + ], + "condition_assignments": { + "raes-mediated": { + "condition_id": "raes-mediated", + "description": null, + "difficulty_condition": "fixed", + "difficulty_policy_id": null, + "factor_levels": { + "execution-lane": "raes-mediated" + }, + "required_parameters": [ + { + "name": "execution-lane", + "redaction": "none", + "value": "raes-mediated", + "value_kind": "apparatus" + } + ], + "required_refs": [] + }, + "source-native": { + "condition_id": "source-native", + "description": null, + "difficulty_condition": "fixed", + "difficulty_policy_id": null, + "factor_levels": { + "execution-lane": "source-native" + }, + "required_parameters": [ + { + "name": "execution-lane", + "redaction": "none", + "value": "source-native", + "value_kind": "apparatus" + } + ], + "required_refs": [] + } + }, + "randomization_unit": null, + "replication_policy": "Ten fixed scheduled episodes per lane; retry budget zero.", + "stopping_rule": "Terminalize every scheduled attempt; do not replace failures.", + "target_runs_per_condition": 10 + }, + "schema_version": "experiment-study/v1", + "study_id": "cyberbattlesim-chain-baseline-reproduction", + "study_kind": "study", + "study_version": "1.0.0", + "title": "CyberBattleSim chain source-native and RAES-mediated reproduction", + "validation_basis_disclosures": [], + "validity_notes": [ + { + "category": "reproducibility", + "mitigation": "Record actual lane-specific binding dispositions and make no replay claim.", + "note": "The source evaluator leaves four random streams unbound." + } + ] + }, + "terminal_dispositions": [ + "excluded", + "failed", + "invalid", + "valid" + ], + "tier_policy": [ + "authored-source", + "contract", + "execution-control", + "state-observation", + "outcome-evaluation", + "disclosure" + ] + }, + "declaration_sha256": "825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232", + "oracle": null, + "schema_version": "cyberbattlesim-baseline-reproduction/v1" +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/source-ledger.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/declaration/source-ledger.json similarity index 100% rename from packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/source-ledger.json rename to packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/declaration/source-ledger.json diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/bench-notes.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/bench-notes.json new file mode 100644 index 0000000..4c76bac --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/bench-notes.json @@ -0,0 +1,344 @@ +{ + "declaration_sha256": "825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232", + "notes": [ + { + "disposition": "observed", + "event_code": "mediated-collection-started", + "evidence_refs": [ + { + "path": "protocol.json" + }, + { + "path": "environment.json" + } + ], + "note_id": "mediated-001", + "phase": "mediated", + "recorded_at": "2026-08-10T03:58:46.141Z", + "severity": "info", + "summary": "The ten preallocated RAES-mediated attempts were started with zero retries." + }, + { + "disposition": "observed", + "event_code": "mediated-attempt-started", + "evidence_refs": [ + { + "path": "protocol.json" + } + ], + "note_id": "mediated-002", + "phase": "mediated", + "recorded_at": "2026-08-10T03:58:46.141Z", + "severity": "info", + "summary": "Scheduled RAES-mediated attempt cbs-mediated-01 was started." + }, + { + "disposition": "passed", + "event_code": "mediated-attempt-terminalized", + "evidence_refs": [ + { + "path": "runs/cbs-mediated-01/record.json" + } + ], + "note_id": "mediated-003", + "phase": "mediated", + "recorded_at": "2026-08-10T03:58:50.964Z", + "severity": "info", + "summary": "Scheduled RAES-mediated attempt cbs-mediated-01 was terminalized as valid." + }, + { + "disposition": "observed", + "event_code": "mediated-attempt-started", + "evidence_refs": [ + { + "path": "protocol.json" + } + ], + "note_id": "mediated-004", + "phase": "mediated", + "recorded_at": "2026-08-10T03:58:50.965Z", + "severity": "info", + "summary": "Scheduled RAES-mediated attempt cbs-mediated-02 was started." + }, + { + "disposition": "passed", + "event_code": "mediated-attempt-terminalized", + "evidence_refs": [ + { + "path": "runs/cbs-mediated-02/record.json" + } + ], + "note_id": "mediated-005", + "phase": "mediated", + "recorded_at": "2026-08-10T03:58:55.538Z", + "severity": "info", + "summary": "Scheduled RAES-mediated attempt cbs-mediated-02 was terminalized as valid." + }, + { + "disposition": "observed", + "event_code": "mediated-attempt-started", + "evidence_refs": [ + { + "path": "protocol.json" + } + ], + "note_id": "mediated-006", + "phase": "mediated", + "recorded_at": "2026-08-10T03:58:55.538Z", + "severity": "info", + "summary": "Scheduled RAES-mediated attempt cbs-mediated-03 was started." + }, + { + "disposition": "passed", + "event_code": "mediated-attempt-terminalized", + "evidence_refs": [ + { + "path": "runs/cbs-mediated-03/record.json" + } + ], + "note_id": "mediated-007", + "phase": "mediated", + "recorded_at": "2026-08-10T03:58:59.661Z", + "severity": "info", + "summary": "Scheduled RAES-mediated attempt cbs-mediated-03 was terminalized as valid." + }, + { + "disposition": "observed", + "event_code": "mediated-attempt-started", + "evidence_refs": [ + { + "path": "protocol.json" + } + ], + "note_id": "mediated-008", + "phase": "mediated", + "recorded_at": "2026-08-10T03:58:59.661Z", + "severity": "info", + "summary": "Scheduled RAES-mediated attempt cbs-mediated-04 was started." + }, + { + "disposition": "passed", + "event_code": "mediated-attempt-terminalized", + "evidence_refs": [ + { + "path": "runs/cbs-mediated-04/record.json" + } + ], + "note_id": "mediated-009", + "phase": "mediated", + "recorded_at": "2026-08-10T03:59:04.334Z", + "severity": "info", + "summary": "Scheduled RAES-mediated attempt cbs-mediated-04 was terminalized as valid." + }, + { + "disposition": "observed", + "event_code": "mediated-attempt-started", + "evidence_refs": [ + { + "path": "protocol.json" + } + ], + "note_id": "mediated-010", + "phase": "mediated", + "recorded_at": "2026-08-10T03:59:04.335Z", + "severity": "info", + "summary": "Scheduled RAES-mediated attempt cbs-mediated-05 was started." + }, + { + "disposition": "passed", + "event_code": "mediated-attempt-terminalized", + "evidence_refs": [ + { + "path": "runs/cbs-mediated-05/record.json" + } + ], + "note_id": "mediated-011", + "phase": "mediated", + "recorded_at": "2026-08-10T03:59:08.958Z", + "severity": "info", + "summary": "Scheduled RAES-mediated attempt cbs-mediated-05 was terminalized as valid." + }, + { + "disposition": "observed", + "event_code": "mediated-attempt-started", + "evidence_refs": [ + { + "path": "protocol.json" + } + ], + "note_id": "mediated-012", + "phase": "mediated", + "recorded_at": "2026-08-10T03:59:08.959Z", + "severity": "info", + "summary": "Scheduled RAES-mediated attempt cbs-mediated-06 was started." + }, + { + "disposition": "passed", + "event_code": "mediated-attempt-terminalized", + "evidence_refs": [ + { + "path": "runs/cbs-mediated-06/record.json" + } + ], + "note_id": "mediated-013", + "phase": "mediated", + "recorded_at": "2026-08-10T03:59:13.532Z", + "severity": "info", + "summary": "Scheduled RAES-mediated attempt cbs-mediated-06 was terminalized as valid." + }, + { + "disposition": "observed", + "event_code": "mediated-attempt-started", + "evidence_refs": [ + { + "path": "protocol.json" + } + ], + "note_id": "mediated-014", + "phase": "mediated", + "recorded_at": "2026-08-10T03:59:13.532Z", + "severity": "info", + "summary": "Scheduled RAES-mediated attempt cbs-mediated-07 was started." + }, + { + "disposition": "passed", + "event_code": "mediated-attempt-terminalized", + "evidence_refs": [ + { + "path": "runs/cbs-mediated-07/record.json" + } + ], + "note_id": "mediated-015", + "phase": "mediated", + "recorded_at": "2026-08-10T03:59:18.456Z", + "severity": "info", + "summary": "Scheduled RAES-mediated attempt cbs-mediated-07 was terminalized as valid." + }, + { + "disposition": "observed", + "event_code": "mediated-attempt-started", + "evidence_refs": [ + { + "path": "protocol.json" + } + ], + "note_id": "mediated-016", + "phase": "mediated", + "recorded_at": "2026-08-10T03:59:18.457Z", + "severity": "info", + "summary": "Scheduled RAES-mediated attempt cbs-mediated-08 was started." + }, + { + "disposition": "passed", + "event_code": "mediated-attempt-terminalized", + "evidence_refs": [ + { + "path": "runs/cbs-mediated-08/record.json" + } + ], + "note_id": "mediated-017", + "phase": "mediated", + "recorded_at": "2026-08-10T03:59:22.579Z", + "severity": "info", + "summary": "Scheduled RAES-mediated attempt cbs-mediated-08 was terminalized as valid." + }, + { + "disposition": "observed", + "event_code": "mediated-attempt-started", + "evidence_refs": [ + { + "path": "protocol.json" + } + ], + "note_id": "mediated-018", + "phase": "mediated", + "recorded_at": "2026-08-10T03:59:22.580Z", + "severity": "info", + "summary": "Scheduled RAES-mediated attempt cbs-mediated-09 was started." + }, + { + "disposition": "passed", + "event_code": "mediated-attempt-terminalized", + "evidence_refs": [ + { + "path": "runs/cbs-mediated-09/record.json" + } + ], + "note_id": "mediated-019", + "phase": "mediated", + "recorded_at": "2026-08-10T03:59:27.003Z", + "severity": "info", + "summary": "Scheduled RAES-mediated attempt cbs-mediated-09 was terminalized as valid." + }, + { + "disposition": "observed", + "event_code": "mediated-attempt-started", + "evidence_refs": [ + { + "path": "protocol.json" + } + ], + "note_id": "mediated-020", + "phase": "mediated", + "recorded_at": "2026-08-10T03:59:27.003Z", + "severity": "info", + "summary": "Scheduled RAES-mediated attempt cbs-mediated-10 was started." + }, + { + "disposition": "passed", + "event_code": "mediated-attempt-terminalized", + "evidence_refs": [ + { + "path": "runs/cbs-mediated-10/record.json" + } + ], + "note_id": "mediated-021", + "phase": "mediated", + "recorded_at": "2026-08-10T03:59:31.176Z", + "severity": "info", + "summary": "Scheduled RAES-mediated attempt cbs-mediated-10 was terminalized as valid." + }, + { + "disposition": "passed", + "event_code": "mediated-collection-completed", + "evidence_refs": [ + { + "path": "runs/cbs-mediated-01/record.json" + }, + { + "path": "runs/cbs-mediated-02/record.json" + }, + { + "path": "runs/cbs-mediated-03/record.json" + }, + { + "path": "runs/cbs-mediated-04/record.json" + }, + { + "path": "runs/cbs-mediated-05/record.json" + }, + { + "path": "runs/cbs-mediated-06/record.json" + }, + { + "path": "runs/cbs-mediated-07/record.json" + }, + { + "path": "runs/cbs-mediated-08/record.json" + }, + { + "path": "runs/cbs-mediated-09/record.json" + }, + { + "path": "runs/cbs-mediated-10/record.json" + } + ], + "note_id": "mediated-022", + "phase": "mediated", + "recorded_at": "2026-08-10T03:59:31.177Z", + "severity": "info", + "summary": "The RAES-mediated lane terminalized all ten attempts; 10 were valid and 0 failed." + } + ], + "schema_version": "cyberbattlesim-baseline-bench-notes/v1" +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/collection.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/collection.json new file mode 100644 index 0000000..fccaf80 --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/collection.json @@ -0,0 +1,6 @@ +{ + "lane": "raes-mediated", + "protocol_sha256": "93d79b72c9e26af2be1365e094e04ac0fff0fa884a7afdb8650e7e52a90418c4", + "terminal_count": 10, + "valid_count": 10 +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/environment.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/environment.json new file mode 100644 index 0000000..f286755 --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/environment.json @@ -0,0 +1,41 @@ +{ + "lane": "raes-mediated", + "limitations": [ + "The upstream source has no selected public index or release artifact.", + "Python-global and NumPy-global random streams are unbound in the mediated lane.", + "All four observed random streams are unbound in the source-native lane.", + "The authored RAES topology is representative rather than state-identical.", + "The mediated evaluator does not retain availability series or a specific terminal cause." + ], + "machine": { + "architecture": "x86_64", + "logical_cpu_count": 4, + "operating_system": "Linux", + "operating_system_release": "6.17.0-1019-aws", + "physical_memory_bytes": 16375947264 + }, + "pack": { + "content_digest": "sha256:66493882579d5cba87248c5722782ff5ded5f0d7423f4e559f15bfb61712a905", + "identity": "cyberbattlesim-chain", + "version": "1.0.0" + }, + "python": { + "implementation": "CPython", + "version": "3.12.3" + }, + "schema_version": "cyberbattlesim-baseline-environment/v1", + "software": { + "cyberbattlesim": "0.1.0", + "gymnasium": "0.29.1", + "numpy": "1.26.4", + "raes": "3.3.0", + "raes-adapters": "0.0.0", + "raes-env-packs": "3.6.2" + }, + "source": { + "commit": "854d6966607fb68645651f55b0f97221bd293e0d", + "installed_artifact_sha256": "unavailable", + "tree": "4271b137ab2de593be52d7afb0a51bee59045a45", + "version": "0.1.0" + } +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/inventory.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/inventory.json new file mode 100644 index 0000000..5b3af24 --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/inventory.json @@ -0,0 +1,628 @@ +{ + "artifacts": [ + { + "media_type": "application/json", + "path": "bench-notes.json", + "sha256": "459541c4b6968940ef04ec5b0297da0d18259ee6896ac83dce63030c2bec3641", + "size_bytes": 10053 + }, + { + "media_type": "application/json", + "path": "collection.json", + "sha256": "a29a4b6b2f605dcc2b611355542ddefc987e8aeddfc224551eceb37ce6ee3b2e", + "size_bytes": 164 + }, + { + "media_type": "application/json", + "path": "environment.json", + "sha256": "44c306f0e7090dfe5e2229e1d3f08435ebc80aeb5b814f7d9a10f970ce2f520e", + "size_bytes": 1378 + }, + { + "media_type": "application/json", + "path": "protocol.json", + "sha256": "93d79b72c9e26af2be1365e094e04ac0fff0fa884a7afdb8650e7e52a90418c4", + "size_bytes": 93420 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-01/portable/machine-inventory.json", + "sha256": "ad489e5c927c7356c8716b5276cc47cc764233e7cefb802ce8b85913a5b90eae", + "size_bytes": 370 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-01/portable/provenance.json", + "sha256": "03718a9eecba2f934fd86a16abaa833dfdb7af16da03e3b789000a774a42c91d", + "size_bytes": 14050 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/derived-measures.json", + "sha256": "b9923ad9ae6b1ee6ca2cdfdee7aa4bead10820c74b04c2ab7d2340926734729b", + "size_bytes": 1642 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/diagnostics.json", + "sha256": "5c8608e37ae160bd6e20c2b492c0ad45c2ca19797dd843f020c9e4e2f43b1258", + "size_bytes": 957 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/evidence-records.json", + "sha256": "998fab14ee3502f674b46cc5439c13e271af53df29e8e53950081a895e891b8d", + "size_bytes": 2381 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/participant-provenance.json", + "sha256": "d7ec55c3983741a9f05979540b526b2dc4ce3133bf1842d0d2f91aceb8815d2c", + "size_bytes": 1956 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/run.json", + "sha256": "1825d1ee178afc31ef60e9d02704554e647d9470bf9a916eed8588df45f65b22", + "size_bytes": 11909 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/summary.json", + "sha256": "86895aa82134ad8fef357b331a40ff42acb7bca4e6792df8c8a692f5d8514e8a", + "size_bytes": 170 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-01/portable/summary.json", + "sha256": "e8cb3e4c56ae65bc4a4f8a6758f22628e324bc483371f55b45a0fb92fc4b00ea", + "size_bytes": 289 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-01/record.json", + "sha256": "8e26a43edc3cf39d0b2fb7a50bfba7212eb59f6ad7fffa3f04d263bee15384eb", + "size_bytes": 1726 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-02/portable/machine-inventory.json", + "sha256": "ad489e5c927c7356c8716b5276cc47cc764233e7cefb802ce8b85913a5b90eae", + "size_bytes": 370 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-02/portable/provenance.json", + "sha256": "17dec483032c790d671036be819ec23901e4fe4005b8e176bd2281c4f73be0b2", + "size_bytes": 14050 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-02/portable/runs/cbs-mediated-02-1/derived-measures.json", + "sha256": "20a28932577668883cc571cef9826ffb38a113060646450b40da09b8d040c5ec", + "size_bytes": 1642 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-02/portable/runs/cbs-mediated-02-1/diagnostics.json", + "sha256": "5c8608e37ae160bd6e20c2b492c0ad45c2ca19797dd843f020c9e4e2f43b1258", + "size_bytes": 957 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-02/portable/runs/cbs-mediated-02-1/evidence-records.json", + "sha256": "ae62234d13f73675cae6a29a874460a83cafd4af7b0e9dd1030a2ab6d4659107", + "size_bytes": 2381 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-02/portable/runs/cbs-mediated-02-1/participant-provenance.json", + "sha256": "d7ec55c3983741a9f05979540b526b2dc4ce3133bf1842d0d2f91aceb8815d2c", + "size_bytes": 1956 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-02/portable/runs/cbs-mediated-02-1/run.json", + "sha256": "56d68c6c05be4765e5ec02f84224ddb9c678e57dd20e28953b55e29aca941460", + "size_bytes": 11909 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-02/portable/runs/cbs-mediated-02-1/summary.json", + "sha256": "d5c27b06168da4abe8c336433d2352d17b66c3d150e1694df924525869313bb1", + "size_bytes": 170 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-02/portable/summary.json", + "sha256": "809da44fe887b86ba9861f51601cb9d800cfb46249016f67ad23d9dfa4eec2f7", + "size_bytes": 289 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-02/record.json", + "sha256": "3edf234eacf55ed6a7a453f4d3fcad576de9527fa5925b3f00544d4bed9ab75c", + "size_bytes": 1726 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-03/portable/machine-inventory.json", + "sha256": "ad489e5c927c7356c8716b5276cc47cc764233e7cefb802ce8b85913a5b90eae", + "size_bytes": 370 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-03/portable/provenance.json", + "sha256": "a108c3fd211dd413f4a3c6d3843e7da9afd53afd4a2c883e755a4e22e471de12", + "size_bytes": 14050 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-03/portable/runs/cbs-mediated-03-1/derived-measures.json", + "sha256": "c4c32630bbf611049df06286f7ec5812cc8821b3de395dc87758a149258885ec", + "size_bytes": 1642 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-03/portable/runs/cbs-mediated-03-1/diagnostics.json", + "sha256": "5c8608e37ae160bd6e20c2b492c0ad45c2ca19797dd843f020c9e4e2f43b1258", + "size_bytes": 957 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-03/portable/runs/cbs-mediated-03-1/evidence-records.json", + "sha256": "5594e0bcae99c74fb3ad55e42cb884baaf91b2445b7d0b802f846ba3be262864", + "size_bytes": 2381 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-03/portable/runs/cbs-mediated-03-1/participant-provenance.json", + "sha256": "d7ec55c3983741a9f05979540b526b2dc4ce3133bf1842d0d2f91aceb8815d2c", + "size_bytes": 1956 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-03/portable/runs/cbs-mediated-03-1/run.json", + "sha256": "8b3c1e8acb2954d5194704ada9c38e3e144e264bb63991b8c7c016ba079881b6", + "size_bytes": 11909 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-03/portable/runs/cbs-mediated-03-1/summary.json", + "sha256": "e2b37cf4e0279e5885f93d4f5d3b7f8333f0352331f8783c1701722fc17f1913", + "size_bytes": 170 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-03/portable/summary.json", + "sha256": "9ed101fd4e3da5bc5a8fb60a9c57380b38e5dff7cbf02314d5aa29373f0cc906", + "size_bytes": 289 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-03/record.json", + "sha256": "318a37cee896be2d141b2732196265dd6b240518bf5709e36f4c3bab4573a86e", + "size_bytes": 1726 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-04/portable/machine-inventory.json", + "sha256": "ad489e5c927c7356c8716b5276cc47cc764233e7cefb802ce8b85913a5b90eae", + "size_bytes": 370 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-04/portable/provenance.json", + "sha256": "594eb6a2d712aa6a770986e640eba9f80d39f3ff6155d90e029d5b36ab313991", + "size_bytes": 14050 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-04/portable/runs/cbs-mediated-04-1/derived-measures.json", + "sha256": "e8bbd32209c81de19ed022ff23970248bd887cdb7f378b557c536d0ad47f13b3", + "size_bytes": 1642 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-04/portable/runs/cbs-mediated-04-1/diagnostics.json", + "sha256": "5c8608e37ae160bd6e20c2b492c0ad45c2ca19797dd843f020c9e4e2f43b1258", + "size_bytes": 957 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-04/portable/runs/cbs-mediated-04-1/evidence-records.json", + "sha256": "bf8613e7ee71e1f414bf851796b695ba0c49be4ab415b77e9bd299c4fae28c83", + "size_bytes": 2381 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-04/portable/runs/cbs-mediated-04-1/participant-provenance.json", + "sha256": "d7ec55c3983741a9f05979540b526b2dc4ce3133bf1842d0d2f91aceb8815d2c", + "size_bytes": 1956 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-04/portable/runs/cbs-mediated-04-1/run.json", + "sha256": "f6d8f297f09d51d9da8428a08605c91f076b7e8114d38488ef1455481fea2328", + "size_bytes": 11909 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-04/portable/runs/cbs-mediated-04-1/summary.json", + "sha256": "811313046e1e395632aa77bdecfcaa0e16915712af32eb263052d0fb4668124c", + "size_bytes": 170 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-04/portable/summary.json", + "sha256": "7217fcaaee27fe61a23daf4b5db0c777ce778f945e722a8e10e488a91f73b786", + "size_bytes": 289 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-04/record.json", + "sha256": "0c19313d95e3fa5ab8a3d33d5bf954a3c7acf420b2e4d697f5b6e61a71e5494e", + "size_bytes": 1726 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-05/portable/machine-inventory.json", + "sha256": "ad489e5c927c7356c8716b5276cc47cc764233e7cefb802ce8b85913a5b90eae", + "size_bytes": 370 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-05/portable/provenance.json", + "sha256": "66ca289f8394f3ac6c7a4a25870a2635ce2153739483214a745c1f34b21a8723", + "size_bytes": 14050 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-05/portable/runs/cbs-mediated-05-1/derived-measures.json", + "sha256": "7f627482e4e287aa6c3ce06e9a10506355a72f1de0dddb6023db9cfe6039a803", + "size_bytes": 1642 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-05/portable/runs/cbs-mediated-05-1/diagnostics.json", + "sha256": "5c8608e37ae160bd6e20c2b492c0ad45c2ca19797dd843f020c9e4e2f43b1258", + "size_bytes": 957 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-05/portable/runs/cbs-mediated-05-1/evidence-records.json", + "sha256": "12c9154e3469508b19dfa1898fb7ffdab0f06582881702f2947dbb865f42efe6", + "size_bytes": 2381 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-05/portable/runs/cbs-mediated-05-1/participant-provenance.json", + "sha256": "d7ec55c3983741a9f05979540b526b2dc4ce3133bf1842d0d2f91aceb8815d2c", + "size_bytes": 1956 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-05/portable/runs/cbs-mediated-05-1/run.json", + "sha256": "9924235d97130e1ebfe62e8dbc692908ca9f248f0e3c79c15209b720c59ae7ea", + "size_bytes": 11909 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-05/portable/runs/cbs-mediated-05-1/summary.json", + "sha256": "b13458ea370ae803b1d91421dfdc3f69654d5f84ec093420a3dc52411af08aea", + "size_bytes": 170 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-05/portable/summary.json", + "sha256": "97388e187ae683897f8bc1dc3888ea7bfe54d85c773022e69a9795809165efa7", + "size_bytes": 289 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-05/record.json", + "sha256": "60d6364171e331c6495becf07ec336ac1aba2508c885b0c3164905c7ee735ee4", + "size_bytes": 1726 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-06/portable/machine-inventory.json", + "sha256": "ad489e5c927c7356c8716b5276cc47cc764233e7cefb802ce8b85913a5b90eae", + "size_bytes": 370 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-06/portable/provenance.json", + "sha256": "cd91b0b2a8122594e3b02e2f612278ef99cafb1690648085863627e499c761b8", + "size_bytes": 14050 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-06/portable/runs/cbs-mediated-06-1/derived-measures.json", + "sha256": "0c02d43749b2b802972789a24408191a207e19c463db913f0451271b92926282", + "size_bytes": 1642 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-06/portable/runs/cbs-mediated-06-1/diagnostics.json", + "sha256": "5c8608e37ae160bd6e20c2b492c0ad45c2ca19797dd843f020c9e4e2f43b1258", + "size_bytes": 957 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-06/portable/runs/cbs-mediated-06-1/evidence-records.json", + "sha256": "3c66dfd94a862fa6e5219c075d50492ec8385d9a130bae6bd2795bb05268b6eb", + "size_bytes": 2381 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-06/portable/runs/cbs-mediated-06-1/participant-provenance.json", + "sha256": "d7ec55c3983741a9f05979540b526b2dc4ce3133bf1842d0d2f91aceb8815d2c", + "size_bytes": 1956 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-06/portable/runs/cbs-mediated-06-1/run.json", + "sha256": "3116420331f894d5a4bb4538c77ec6198cf4b8c08d5d093255f914aff9e7c18f", + "size_bytes": 11909 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-06/portable/runs/cbs-mediated-06-1/summary.json", + "sha256": "f8a93ed0fa7b1cafa01b162472f6aa9e14764132a2b988bffd2d6e711005f7a1", + "size_bytes": 170 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-06/portable/summary.json", + "sha256": "54074c5e353bce586fbfc35479cdb0cd50c4462d668df8abbe02be7c6c1d094c", + "size_bytes": 289 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-06/record.json", + "sha256": "81620548fa781a077eb7fe1f7ba1c72505b3f11edb38912cc5868354077dd80b", + "size_bytes": 1726 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-07/portable/machine-inventory.json", + "sha256": "ad489e5c927c7356c8716b5276cc47cc764233e7cefb802ce8b85913a5b90eae", + "size_bytes": 370 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-07/portable/provenance.json", + "sha256": "f585296ae4108beee144c762a19de4524058370f8cbee80a8a785e9385730ce0", + "size_bytes": 14050 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-07/portable/runs/cbs-mediated-07-1/derived-measures.json", + "sha256": "cedb8789257c34a562cd71319a74a981b19e067508705b6e0076540d5b5730b9", + "size_bytes": 1642 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-07/portable/runs/cbs-mediated-07-1/diagnostics.json", + "sha256": "5c8608e37ae160bd6e20c2b492c0ad45c2ca19797dd843f020c9e4e2f43b1258", + "size_bytes": 957 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-07/portable/runs/cbs-mediated-07-1/evidence-records.json", + "sha256": "9b736a9c1c6a4e7765c3d1448bdbd121ea44d7518dd3d61b74595997c64833e1", + "size_bytes": 2381 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-07/portable/runs/cbs-mediated-07-1/participant-provenance.json", + "sha256": "d7ec55c3983741a9f05979540b526b2dc4ce3133bf1842d0d2f91aceb8815d2c", + "size_bytes": 1956 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-07/portable/runs/cbs-mediated-07-1/run.json", + "sha256": "65d41221e6e7f6701469689bccc770640e27ff2c3ecfad3b4352d135bdc0eaea", + "size_bytes": 11909 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-07/portable/runs/cbs-mediated-07-1/summary.json", + "sha256": "42150411b6e95cbc377e44b37c916fc926238e51bcf23dd9efc084a1d7b85112", + "size_bytes": 170 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-07/portable/summary.json", + "sha256": "0d89dae302276247616016fec5339ccccc163cf9f3c44afced338cf83d76ddab", + "size_bytes": 289 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-07/record.json", + "sha256": "13786db778e209465d673af04fd39a184ec8d90b69796dcdd520444d05c8961e", + "size_bytes": 1726 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-08/portable/machine-inventory.json", + "sha256": "ad489e5c927c7356c8716b5276cc47cc764233e7cefb802ce8b85913a5b90eae", + "size_bytes": 370 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-08/portable/provenance.json", + "sha256": "1f2319131e850a3f36592bd9cb3588aaed9db720655fc57183e8187ce2e66c74", + "size_bytes": 14050 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-08/portable/runs/cbs-mediated-08-1/derived-measures.json", + "sha256": "aea78ed2523331b4fec74c5197b711dc1e5a78c6a461836f1131417046fe4f21", + "size_bytes": 1642 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-08/portable/runs/cbs-mediated-08-1/diagnostics.json", + "sha256": "5c8608e37ae160bd6e20c2b492c0ad45c2ca19797dd843f020c9e4e2f43b1258", + "size_bytes": 957 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-08/portable/runs/cbs-mediated-08-1/evidence-records.json", + "sha256": "621e6b3d2e2e19cf1606d75565a1a8b1bffdaab9560e4421b267adbf739fd40a", + "size_bytes": 2381 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-08/portable/runs/cbs-mediated-08-1/participant-provenance.json", + "sha256": "d7ec55c3983741a9f05979540b526b2dc4ce3133bf1842d0d2f91aceb8815d2c", + "size_bytes": 1956 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-08/portable/runs/cbs-mediated-08-1/run.json", + "sha256": "c5a5b7608adceb242c1a6f78dbbb4812c5f6fd33b9549d179873548df0ce1518", + "size_bytes": 11909 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-08/portable/runs/cbs-mediated-08-1/summary.json", + "sha256": "25a4adc5170c29cf89fb43b802b99c67f7a91ee7781fd10661d35a9efe170243", + "size_bytes": 170 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-08/portable/summary.json", + "sha256": "3264b6d97612c3bece5ab5e35b966cbf4d15c288306d24352de8d6251e9affb3", + "size_bytes": 289 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-08/record.json", + "sha256": "55ca5f68bf191b574161bc0e6afc7511786fd3202218f937bb62dddd7ddfe192", + "size_bytes": 1726 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-09/portable/machine-inventory.json", + "sha256": "ad489e5c927c7356c8716b5276cc47cc764233e7cefb802ce8b85913a5b90eae", + "size_bytes": 370 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-09/portable/provenance.json", + "sha256": "1b9a306b4e18e9e7c9f0e9d130da67b97825d5698e62e1f40e44a5135d88e0e8", + "size_bytes": 14050 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-09/portable/runs/cbs-mediated-09-1/derived-measures.json", + "sha256": "a48eef6c35c553e4714fd16f19b9e58c60cfcd5e81ec482434d4f17ab08cb3ef", + "size_bytes": 1642 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-09/portable/runs/cbs-mediated-09-1/diagnostics.json", + "sha256": "5c8608e37ae160bd6e20c2b492c0ad45c2ca19797dd843f020c9e4e2f43b1258", + "size_bytes": 957 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-09/portable/runs/cbs-mediated-09-1/evidence-records.json", + "sha256": "a313189482561b821e21d8847693de02eafd247a1d46decc3f5a3d3dd43b986b", + "size_bytes": 2381 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-09/portable/runs/cbs-mediated-09-1/participant-provenance.json", + "sha256": "d7ec55c3983741a9f05979540b526b2dc4ce3133bf1842d0d2f91aceb8815d2c", + "size_bytes": 1956 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-09/portable/runs/cbs-mediated-09-1/run.json", + "sha256": "d3fe4c9523a69c7450534f9459cfc1e5806e2e03280ad21b66be65b80caa5d90", + "size_bytes": 11909 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-09/portable/runs/cbs-mediated-09-1/summary.json", + "sha256": "4baf599d7a77dce3336ffbf27c272e3a3b457850e61c990e15cdf2d4f6321364", + "size_bytes": 170 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-09/portable/summary.json", + "sha256": "03a5fd3e63340ee9697732df43efb4eb642b7b1f14f92ebd712b1ec2ea7e1466", + "size_bytes": 289 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-09/record.json", + "sha256": "5a733c167b231ded8c438082ad96980ce3000c4111156cc65844caa82b10632f", + "size_bytes": 1726 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-10/portable/machine-inventory.json", + "sha256": "ad489e5c927c7356c8716b5276cc47cc764233e7cefb802ce8b85913a5b90eae", + "size_bytes": 370 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-10/portable/provenance.json", + "sha256": "92b684f05bf78164edcdf99f30403b49f56eb831f00fc7fa5d3e6e716a9846c2", + "size_bytes": 14050 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-10/portable/runs/cbs-mediated-10-1/derived-measures.json", + "sha256": "27b28ef443746a650d985d5dba4fdb825ef358aa3d828b17a78065e235a7fc10", + "size_bytes": 1642 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-10/portable/runs/cbs-mediated-10-1/diagnostics.json", + "sha256": "5c8608e37ae160bd6e20c2b492c0ad45c2ca19797dd843f020c9e4e2f43b1258", + "size_bytes": 957 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-10/portable/runs/cbs-mediated-10-1/evidence-records.json", + "sha256": "b5f78d37505a5698a01b0a245aefb09fbeb584c6874a31d3a6d652791b01c90e", + "size_bytes": 2381 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-10/portable/runs/cbs-mediated-10-1/participant-provenance.json", + "sha256": "d7ec55c3983741a9f05979540b526b2dc4ce3133bf1842d0d2f91aceb8815d2c", + "size_bytes": 1956 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-10/portable/runs/cbs-mediated-10-1/run.json", + "sha256": "1aecba4321e5508359af171c4203ac6ba32e175df969d95970ad44ffa50443d5", + "size_bytes": 11909 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-10/portable/runs/cbs-mediated-10-1/summary.json", + "sha256": "684165d88b0cf7dfb2d42b003b3c8517ae09391449b305f70a718f95f25304ea", + "size_bytes": 170 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-10/portable/summary.json", + "sha256": "6db3a0ad784e8a0e743a3690050e18adfd8d90de3778c4d3019680b3405712d8", + "size_bytes": 289 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-10/record.json", + "sha256": "b5bd0562d75b245575f361163ea62a256e0b4af4feebaeefd904626665dc9d7c", + "size_bytes": 1727 + } + ] +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/protocol.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/protocol.json similarity index 100% rename from packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/protocol.json rename to packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/protocol.json diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/inventory.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/inventory.json new file mode 100644 index 0000000..5a41bbe --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/inventory.json @@ -0,0 +1,58 @@ +{ + "artifacts": [ + { + "media_type": "application/json", + "path": "machine-inventory.json", + "sha256": "ad489e5c927c7356c8716b5276cc47cc764233e7cefb802ce8b85913a5b90eae", + "size_bytes": 370 + }, + { + "media_type": "application/json", + "path": "provenance.json", + "sha256": "03718a9eecba2f934fd86a16abaa833dfdb7af16da03e3b789000a774a42c91d", + "size_bytes": 14050 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-01-1/derived-measures.json", + "sha256": "b9923ad9ae6b1ee6ca2cdfdee7aa4bead10820c74b04c2ab7d2340926734729b", + "size_bytes": 1642 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-01-1/diagnostics.json", + "sha256": "5c8608e37ae160bd6e20c2b492c0ad45c2ca19797dd843f020c9e4e2f43b1258", + "size_bytes": 957 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-01-1/evidence-records.json", + "sha256": "998fab14ee3502f674b46cc5439c13e271af53df29e8e53950081a895e891b8d", + "size_bytes": 2381 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-01-1/participant-provenance.json", + "sha256": "d7ec55c3983741a9f05979540b526b2dc4ce3133bf1842d0d2f91aceb8815d2c", + "size_bytes": 1956 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-01-1/run.json", + "sha256": "1825d1ee178afc31ef60e9d02704554e647d9470bf9a916eed8588df45f65b22", + "size_bytes": 11909 + }, + { + "media_type": "application/json", + "path": "runs/cbs-mediated-01-1/summary.json", + "sha256": "86895aa82134ad8fef357b331a40ff42acb7bca4e6792df8c8a692f5d8514e8a", + "size_bytes": 170 + }, + { + "media_type": "application/json", + "path": "summary.json", + "sha256": "e8cb3e4c56ae65bc4a4f8a6758f22628e324bc483371f55b45a0fb92fc4b00ea", + "size_bytes": 289 + } + ] +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/machine-inventory.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/machine-inventory.json new file mode 100644 index 0000000..81b3dee --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/machine-inventory.json @@ -0,0 +1,17 @@ +{ + "architecture": "x86_64", + "operating_system": "Linux", + "operating_system_release": "6.17.0-1019-aws", + "python": { + "implementation": "CPython", + "version": "3.12.3" + }, + "software": { + "cyberbattlesim": "0.1.0", + "gymnasium": "0.29.1", + "numpy": "1.26.4", + "raes": "3.3.0", + "raes-adapters": "0.0.0", + "raes-env-packs": "3.6.2" + } +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/provenance.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/provenance.json new file mode 100644 index 0000000..c8c36b2 --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/provenance.json @@ -0,0 +1,409 @@ +{ + "adapter": { + "distribution": "raes-adapters", + "version": "0.0.0" + }, + "backend_manifest": { + "capabilities": { + "cleanup": { + "name": "cyberbattlesim-cleanup", + "supported_action_kinds": [ + "destroy", + "reset", + "verify" + ], + "supported_contract_versions": [ + "trial-cleanup-plan-v1", + "trial-cleanup-receipt-v1" + ], + "supported_verification_methods": [ + "probe", + "receipt" + ], + "supports_residual_state_disclosure": true, + "supports_reusable_state": true + }, + "evaluator": { + "constraints": { + "objective_terminal_state": "running until a distinct mapped terminal cause is available", + "outcome_reproduction": "stochastic-bounded", + "proposition_projection": "binding-preserving unknown under lossy source evidence", + "reward_owner": "evaluator" + }, + "name": "cyberbattlesim-evaluator", + "preserves_binding_provenance": true, + "supported_evidence_channels": [ + "api_response" + ], + "supported_predicate_families": [ + "boolean", + "number", + "presence", + "string" + ], + "supported_quantifiers": [ + "all", + "any", + "at_least" + ], + "supported_sections": [ + "assertions", + "conditions", + "objectives", + "propositions" + ], + "supported_time_domains": [ + "wall_clock" + ], + "supported_truth_outcomes": [ + "false", + "true", + "unknown", + "unsupported" + ], + "supports_objectives": true, + "supports_scoring": true + }, + "observation": null, + "orchestrator": { + "constraints": { + "native_transition_owner": "participant-runtime", + "workflow_scope": "episode lifecycle and serialized participant steps" + }, + "name": "cyberbattlesim-orchestrator", + "supported_sections": [ + "events", + "workflows" + ], + "supported_workflow_features": [ + "call" + ], + "supported_workflow_state_predicates": [], + "supports_assertion_refs": false, + "supports_inject_bindings": false, + "supports_workflows": true + }, + "participant_runtime": { + "constraints": { + "autonomous_policy": "qualified CredentialCacheExploiter through RAES action admission", + "max_in_flight_native_transitions": "1", + "native_action_coordinates": "driver-private", + "native_target_attribution": "unavailable; request targets remain intent and are not echoed as realized effect targets", + "participant_action_scope": "connect, local-vulnerability, and remote-vulnerability attacker contracts", + "source_internal_defender": "scan-and-reimage executes inside the selected source step and is not a participant-admitted action" + }, + "execution_bindings": [ + { + "action_contract_address": "participant.action-contract.connect", + "binding_id": "cyberbattlesim-connect", + "constraint_refs": [ + "constraint:serialized-native-transition" + ], + "evidence_refs": [ + "source-ledger:credential-cache-exploiter" + ], + "max_action_attempts": 1, + "max_in_flight": 1, + "max_retries": 0, + "participant_implementation_ref": "participant/cyberbattlesim-red-credential-cache.manifest.json", + "schema_version": "participant-execution-binding/v1", + "target_addresses": [ + "provision.node.customer-data" + ], + "timeout_seconds": 30 + }, + { + "action_contract_address": "participant.action-contract.local-vulnerability", + "binding_id": "cyberbattlesim-local-vulnerability", + "constraint_refs": [ + "constraint:serialized-native-transition" + ], + "evidence_refs": [ + "source-ledger:credential-cache-exploiter" + ], + "max_action_attempts": 1, + "max_in_flight": 1, + "max_retries": 0, + "participant_implementation_ref": "participant/cyberbattlesim-red-credential-cache.manifest.json", + "schema_version": "participant-execution-binding/v1", + "target_addresses": [ + "provision.node.linux-relay" + ], + "timeout_seconds": 30 + }, + { + "action_contract_address": "participant.action-contract.remote-vulnerability", + "binding_id": "cyberbattlesim-remote-vulnerability", + "constraint_refs": [ + "constraint:serialized-native-transition" + ], + "evidence_refs": [ + "source-ledger:credential-cache-exploiter" + ], + "max_action_attempts": 1, + "max_in_flight": 1, + "max_retries": 0, + "participant_implementation_ref": "participant/cyberbattlesim-red-credential-cache.manifest.json", + "schema_version": "participant-execution-binding/v1", + "target_addresses": [ + "provision.node.windows-relay" + ], + "timeout_seconds": 30 + } + ], + "feature_support": [ + { + "constraint_refs": [], + "disclosure_refs": [ + "docs/decisions/cyberbattlesim-backend-guardrails.md" + ], + "evidence_refs": [], + "feature": "interference", + "limitation_refs": [ + "limitation:cyberbattlesim:source-internal-defender" + ], + "support_level": "disclosed_weak" + } + ], + "max_autonomous_action_attempts": 1, + "max_autonomous_burst_size": 1, + "max_autonomous_in_flight": 1, + "max_autonomous_occurrences": 10000, + "max_autonomous_participants": 1, + "max_autonomous_retries_per_occurrence": 1, + "max_concurrent_actions": 2, + "max_execution_services": 1, + "name": "cyberbattlesim-participant-runtime", + "resource_budgets": null, + "supported_autonomous_action_contracts": [ + "participant.action-contract.connect", + "participant.action-contract.local-vulnerability", + "participant.action-contract.remote-vulnerability" + ], + "supported_autonomous_activity_features": [], + "supported_autonomous_observation_boundaries": [ + "participant.observation-boundary.attacker-view" + ], + "supported_autonomous_policy_profiles": [ + "participant-autonomous-execution/v1" + ], + "supported_autonomous_random_stream_profiles": [], + "supported_autonomous_selection_strategies": [ + "ordered_cycle" + ], + "supported_autonomous_target_addresses": [ + "provision.node.customer-data", + "provision.node.linux-relay", + "provision.node.windows-relay" + ], + "supported_behavior_features": [ + "action_contracts", + "attribution_support", + "autonomous_execution", + "behavior_history", + "effects", + "failure_classes", + "observation_boundaries", + "outcome_interpretation", + "preconditions", + "state_transitions", + "temporal_contracts" + ], + "supported_execution_control_actions": [ + "drain", + "pause", + "reset", + "resume", + "start", + "teardown" + ], + "supported_interaction_features": [ + "interference" + ], + "supported_participant_roles": [ + "red" + ], + "supports_autonomous_execution": true, + "supports_bounded_concurrency": true, + "supports_execution_control": true + }, + "provisioner": { + "constraints": { + "account_realization": "auth method and group intent map to source-generated credentials; no source identity equivalence", + "topology_realization": "selected generated chain; authored topology is representative" + }, + "max_total_nodes": 10, + "name": "cyberbattlesim-provisioner", + "supported_account_features": [ + "auth_method", + "groups" + ], + "supported_content_types": [], + "supported_domain_profiles": [], + "supported_generated_artifact_kinds": [], + "supported_node_types": [ + "switch", + "vm" + ], + "supported_os_families": [ + "linux", + "windows" + ], + "supported_service_materialization_profiles": [], + "supports_accounts": true, + "supports_acls": false, + "supports_generated_artifacts": false, + "supports_persistent_volumes": false + } + }, + "compatibility": { + "processors": [ + "raes-reference-processor" + ] + }, + "concept_bindings": [ + { + "family": "assets", + "scope": "capabilities.provisioner.supported_node_types" + }, + { + "family": "assets", + "scope": "capabilities.provisioner.supported_os_families" + }, + { + "family": "tools-and-artifacts", + "scope": "capabilities.provisioner.supported_content_types" + }, + { + "family": "identities", + "scope": "capabilities.provisioner.supported_account_features" + }, + { + "family": "identities", + "scope": "capabilities.provisioner.supported_domain_profiles" + }, + { + "family": "tools-and-artifacts", + "scope": "capabilities.provisioner.supported_service_materialization_profiles" + }, + { + "family": "actions-and-events", + "scope": "capabilities.orchestrator.supported_sections" + }, + { + "family": "observables", + "scope": "capabilities.evaluator.supported_sections" + }, + { + "family": "identities", + "scope": "capabilities.participant_runtime.supported_participant_roles" + }, + { + "family": "actions-and-events", + "scope": "capabilities.participant_runtime.supported_behavior_features" + }, + { + "family": "relationships", + "scope": "capabilities.participant_runtime.supported_interaction_features" + } + ], + "constraints": { + "dependency_installation": "separately-installed-pinned-source", + "execution_controls": "partial", + "outcome_reproduction": "stochastic-bounded", + "protocol_configuration": "attested", + "run_evidence": "attestable", + "source_identity": "qualified-complete-runtime-artifact-roots-attested" + }, + "identity": { + "name": "cyberbattlesim", + "version": "0.0.0" + }, + "realization_support": [ + { + "artifact_mechanisms": [], + "constraints": { + "source_profile": "cyberbattlesim-chain-public-854d696", + "topology": "representative authored topology maps to generated size-10 chain" + }, + "disclosure_kinds": [ + "backend-manifest-v2", + "operation-status-v1", + "runtime-snapshot-v1" + ], + "domain": "runtime-realization", + "observation_capabilities": {}, + "support_mode": "constrained", + "supported_constraint_kinds": [ + "account-feature", + "node-type", + "os-family", + "workflow-feature", + "workflow-state-predicate" + ], + "supported_exact_requirement_kinds": [ + "declared-capability-match" + ] + } + ], + "schema_version": "backend-manifest/v2", + "supported_contract_versions": [ + "backend-manifest-v2", + "provisioning-plan-v1", + "orchestration-plan-v1", + "evaluation-plan-v1", + "operation-receipt-v1", + "operation-status-v1", + "runtime-snapshot-v1", + "workflow-result-envelope-v1", + "workflow-history-event-stream-v1", + "evaluation-result-envelope-v1", + "proposition-truth-result-v1", + "evaluation-history-event-stream-v1", + "participant-episode-state-envelope-v1", + "participant-episode-history-event-stream-v1", + "participant-behavior-history-event-stream-v1", + "participant-execution-binding-v1", + "participant-execution-control-v1", + "participant-execution-service-state-v1", + "participant-control-occurrence-v1", + "participant-crossing-occurrence-v1", + "participant-lifecycle-event-v1", + "participant-observation-envelope-v1", + "participant-shared-state-record-v1", + "participant-joint-action-record-v1", + "participant-time-management-context-v1", + "experiment-capture-spec-v1", + "experiment-evidence-record-v1", + "experiment-derived-measure-v1", + "trial-cleanup-plan-v1", + "trial-cleanup-receipt-v1" + ] + }, + "configuration": { + "experiment_id": "cyberbattlesim-chain-spec", + "experiment_version": "1.0.0", + "mode": "smoke", + "participant_configuration": "participant/cyberbattlesim-red-credential-cache.configuration.json", + "participant_implementation": "cyberbattlesim-red-credential-cache", + "participant_manifest": "participant/cyberbattlesim-red-credential-cache.manifest.json", + "participant_selection": "participant/cyberbattlesim-red-credential-cache.selection.json", + "run_id": "cbs-mediated-01", + "seeds": [ + 20260729 + ], + "trial_length": 600 + }, + "environment_pack": { + "digest": "sha256:66493882579d5cba87248c5722782ff5ded5f0d7423f4e559f15bfb61712a905", + "identity": "cyberbattlesim-chain" + }, + "scenario": { + "digest": "sha256:9d696ea7fa23a1e7cf4c1cbc145a7989370dc4e9afff2cd5a17d6d1af887b528", + "identity": "sdl/cyberbattlesim-chain.sdl.yaml" + }, + "source": { + "commit": "854d6966607fb68645651f55b0f97221bd293e0d", + "version": "0.1.0" + } +} diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/derived-measures.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/derived-measures.json new file mode 100644 index 0000000..41e940b --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/derived-measures.json @@ -0,0 +1,46 @@ +[ + { + "derived_measure_id": "measure.cyberbattlesim.cumulative-attacker-reward.d60d9f9c96354972ada424f62e23546de444a921962010632149728df7f4977d", + "generated_at": "2026-08-10T03:58:50.048204Z", + "limitations": [ + "Single-run cumulative source reward; no deterministic replay or outcome equivalence is claimed.", + "Python-global and NumPy-global random streams remain unbound by the selected reset protocol." + ], + "measure_kind": "score", + "measure_version": "1.0.0", + "method": { + "description": "Report the sanitized cumulative reward maintained by the serialized source driver.", + "method_id": "cyberbattlesim-cumulative-reward", + "method_version": "1.0.0", + "name": "Source cumulative attacker reward", + "parameters": [] + }, + "metric_ref": { + "ref_digest": null, + "ref_id": "cumulative_attacker_reward", + "ref_kind": "metric-definition", + "ref_path": null, + "ref_version": "1.0.0" + }, + "provenance_refs": [ + { + "ref_digest": null, + "ref_id": "cyberbattlesim-chain-task", + "ref_kind": "task", + "ref_path": null, + "ref_version": "1.0.0" + } + ], + "schema_version": "experiment-derived-measure/v1", + "source_evidence_refs": [ + { + "ref_id": "evidence-record.cyberbattlesim.evaluator-summary.d60d9f9c96354972ada424f62e23546de444a921962010632149728df7f4977d", + "ref_kind": "evidence-record", + "ref_version": "1.0.0" + } + ], + "uncertainty": "No statistical uncertainty is estimated from this single run.", + "value": 6036.0, + "value_status": "reported" + } +] diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/diagnostics.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/diagnostics.json new file mode 100644 index 0000000..a0d2e58 --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/diagnostics.json @@ -0,0 +1,30 @@ +[ + { + "address": "/participant/behavior/red", + "code": "cyberbattlesim.seed.applied", + "domain": "participant", + "message": "The adapter bound a selected random stream; binding is not a deterministic-replay claim.", + "severity": "info" + }, + { + "address": "/participant/behavior/red", + "code": "cyberbattlesim.seed.applied", + "domain": "participant", + "message": "The adapter bound a selected random stream; binding is not a deterministic-replay claim.", + "severity": "info" + }, + { + "address": "/participant/behavior/red", + "code": "cyberbattlesim.seed.unbound", + "domain": "participant", + "message": "A selected random stream remains unbound this reset.", + "severity": "warning" + }, + { + "address": "/participant/behavior/red", + "code": "cyberbattlesim.seed.unbound", + "domain": "participant", + "message": "A selected random stream remains unbound this reset.", + "severity": "warning" + } +] diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/evidence-records.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/evidence-records.json new file mode 100644 index 0000000..01268cd --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/evidence-records.json @@ -0,0 +1,59 @@ +[ + { + "apparatus_context_ref": null, + "capture_requirement_ref": "cyberbattlesim-evaluator-summary.d60d9f9c96354972ada424f62e23546de444a921962010632149728df7f4977d", + "capture_spec_ref": { + "ref_id": "cyberbattlesim-evaluator-capture.d60d9f9c96354972ada424f62e23546de444a921962010632149728df7f4977d", + "ref_kind": "capture-spec", + "ref_version": "1.0.0" + }, + "capture_window_ref": "cyberbattlesim-selected-episode.d60d9f9c96354972ada424f62e23546de444a921962010632149728df7f4977d", + "captured_at": "2026-08-10T03:58:50.048204Z", + "evidence_kind": "telemetry", + "evidence_record_id": "evidence-record.cyberbattlesim.evaluator-summary.d60d9f9c96354972ada424f62e23546de444a921962010632149728df7f4977d", + "provenance_refs": [ + { + "ref_digest": null, + "ref_id": "qualification.cyberbattlesim.selected-source", + "ref_kind": "other", + "ref_path": null, + "ref_version": "854d6966607fb68645651f55b0f97221bd293e0d" + } + ], + "raw_content": { + "artifact_ref": null, + "content_checksum": { + "algorithm": "sha256", + "value": "0d56feb988390d49b2505d47b492f327f96e1f67ffb7a1900822983712cf54f0" + }, + "content_uri": "urn:raes:evidence-record.cyberbattlesim.evaluator-summary.d60d9f9c96354972ada424f62e23546de444a921962010632149728df7f4977d:payload-summary", + "loss_disclosure": "Source-native observations, action availability, credentials, reward components, hidden state, and info are withheld.", + "payload_summary": "Sanitized evaluator summary: 381 source transitions and cumulative reward 6036; terminated=True truncated=False terminal_cause=source-terminated." + }, + "record_version": "1.0.0", + "redaction_state": "redacted", + "run_ref": { + "ref_digest": null, + "ref_id": "driver.reset.1", + "ref_kind": "run", + "ref_path": null, + "ref_version": "1.0.0" + }, + "schema_version": "experiment-evidence-record/v1", + "sensitivity": "redacted", + "source_refs": [ + { + "ref_digest": null, + "ref_id": "cyberbattlesim-chain-public", + "ref_kind": "protocol", + "ref_path": null, + "ref_version": "854d6966607fb68645651f55b0f97221bd293e0d" + } + ], + "task_ref": { + "ref_id": "cyberbattlesim-chain-task", + "ref_kind": "task", + "ref_version": "1.0.0" + } + } +] diff --git a/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/participant-provenance.json b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/participant-provenance.json new file mode 100644 index 0000000..b75ebe2 --- /dev/null +++ b/packages/cyberbattlesim_adapter/reproduction/825dde3b4cd66f228e0f93157a2add35e3c9a822a7adac1d8ffd322b32116232/mediated/runs/cbs-mediated-01/portable/runs/cbs-mediated-01-1/participant-provenance.json @@ -0,0 +1,55 @@ +{ + "backend_manifest_ref": "manifest.cyberbattlesim-chain", + "metadata": { + "selection_source": "admitted-experiment-artifact" + }, + "participant_implementations": [ + { + "configuration_digest": "sha256:2254dad60b577628a134a55484d36487ead453f9033313150eb684060b6e1b07", + "configuration_ref": "participant/cyberbattlesim-red-credential-cache.configuration.json", + "exposure_policy": { + "constraints": {}, + "disclosed_refs": [ + "participant.observation-boundary.attacker-view" + ], + "exposure_policy_kinds": [ + "hidden-truth", + "observation-stream" + ], + "policy_digest": null, + "policy_id": "cyberbattlesim-red-observation-boundary", + "policy_version": null, + "tool_affordance_refs": [], + "visibility_scope_refs": [ + "participant.behavior.red" + ], + "withheld_refs": [ + "action_mask", + "credential_cache_matrix", + "credential_cache_length", + "nodes_privilegelevel", + "discovered_nodes_properties", + "native-action-coordinate", + "reward-vector", + "