You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
docs(cyberbattlesim): author the RAES scenario and pinned source mapping ledger #26
gc workflow phase recorded: preflight (issue #26). Posted by the MCP server to enforce ordering between workflow steps (issue #794 MVP-2). Do not edit or delete — used by downstream tools to gate phase prerequisites.
gc workflow phase recorded: plan (issue #26). Posted by the MCP server to enforce ordering between workflow steps (issue #794 MVP-2). Do not edit or delete — used by downstream tools to gate phase prerequisites.
Requirement-free run (no #### Requirements section). Acceptance is the issue's criteria. Branch 26-cyberbattlesim-scenario-ledger off dev (which carries #25's merged, qualified profile). Binding design authority: the architecture-preflight note docs/decisions/cyberbattlesim-scenario-ledger-guardrails.md (authored this run) + docs/decisions/cyberbattlesim-qualification-guardrails.md + ADR-002 + AGENTS.md.
Key design decision (from preflight guardrails)
RAES 2.0.0 rejects SDL scoring/reward sections, so the deliverable is one artifact set, not one document:
Authored RAES SDL scenario — portable topology/objective truth only.
Companion published experiment contracts — reward, evaluator policy, study metrics, episode/turn/termination control, and stochastic controls, authored against raes_contracts published models (ExperimentSpecModel/ExperimentTaskModel family) with ContractModel(extra="forbid") and parse_experiment_spec().
Loss disclosures — bound to the ADR-069 equivalence tier each loss weakens.
Deterministic validation + tests — module-local, running inside the existing tests/verify nox graph (no new policy gate, CI job, DTO, schema, or vocabulary).
The not-admissible qualification is unchanged; authoring validity is not installability, replay, conformance, or equivalence. No adapter, extra, manifest, runtime smoke, evidence run, or environment pack is added.
Files (all under src/raes_adapters/cyberbattlesim/, present in wheel/sdist)
scenario/cyberbattle-chain.sdl.yaml — fixed CyberBattleChain-v0 chain: nodes (entry/relays/customer-data + switch), services, vulnerabilities (CWE-classed), relationships, entities (red/blue), accounts (synthetic credential intent only), agents (attacker=CredentialCacheExploiter, defender=ScanAndReimage), action_contracts (local/remote vuln, connect, scan-and-reimage), observation_boundaries, propositions/assertions/objectives (attacker ownership; defender availability/SLA), evidence_requirements, and a chain_sizevariable representing the generated-topology family (parameterized instantiation → distinct canonical snapshots; not a generator block). Prototype already validates: parse_sdl_file → instantiate_scenario → canonical_instantiated_sdl_digest → admit_instantiated_scenario all green.
experiment/cyberbattle-chain.experiment.yaml (+ any companion) — reward (winning 5000 / losing 0), evaluator (epsilon_greedy_search + epsilon params), metrics (steps-to-termination, cumulative reward, availability series, terminal cause), episode control (episode_count 10, iteration cutoff 600), termination precedence, and 4 descriptive stochastic controls (no executable random-stream binding — the losses are retained).
mapping/source-ledger.jsonl — one row per source fact.
mapping/loss-disclosures.md — narrative losses bound to equivalence tiers.
mapping/README.md — row schema + governance (mirrors the CybORG mapping README pattern, not its CAGE field names).
scenario_ledger.py — public loaders + deterministic validators (extends the load_qualification/importlib.resources/SHA-256 join pattern).
Experiment contracts validate via parse_experiment_spec() / closed published models.
Ledger: row shape + unknown-field + duplicate-key rejection; unique source_id; every source pin (repo/commit/path/digest) joins offline to qualification.json and the recorded protocol.sha256 (source-drift = integrity join, no network/no upstream execution); all required categories present (topology/state, identities, participants, actions, observations, controls, rewards/objectives, termination, evaluator facts, stochastic policy, provenance/licensing); exactly one disposition per row; excluded needs a rationale; every loss row references a disclosure and every disclosure is referenced by a row and names its ADR-069 tier.
Targets: each raes_target resolves to a real validated artifact path or a contract id + property path in raes_contracts.contracts.schema_bundle() — derived from parsed artifacts, no second target catalog.
No native leakage: reject any native action id, Gym tuple, raw object/state, credential value, reward vector, hidden truth, sim log, argv/env dump, token, or traceback in portable content.
TDD (full red/green — SDL/experiment YAML + ledger + validator are runtime-parsed, so no doc-only carve-out)
Write failing validator/loader tests first, then author each artifact to pass. Run narrow tests while iterating; make verify once on the final tree (Step 6). make policy uses --skip-requirement (requirement-free).
Design lenses
Security: static checked-in artifacts, no auth/HTTP/secret surface; SDL carries synthetic credential intent only; strict bounded parsers (RAES SDL parser, closed experiment models, strict JSONL); no env override of source identity; in-process, no network/shell/native execution.
Maintainability: reuse raes SDL/contract APIs, schema_bundle(), the qualification loader + SHA-256 join, existing nox graph and wheel/sdist proof; no new gate/workflow/DTO.
Extensibility: validator's seam is an explicit module-local artifact-root/selection identity; a second CyberBattleSim case is another immutable selection using the same validator — no central registry.
Whole-repo: artifacts under the package tree (wheel/sdist + clean-install prove presence); no change to raes_adapters.base/cyborg, RAES corpus, or env-pack schemas; Release Please owns CHANGELOG.md/version (no hand edits); single distribution + one uv.lock.
Non-goals
Not-admissible unchanged; no adapter/extra/manifest/runtime smoke/conformance/evidence run/env-pack/persistence/equivalence claim; no SDLLineageLedgerModel for this mapping; no repo-local SDL/schema/vocabulary. The module-local validator is test/helper code, not an ADR-backed structural gate, so no Ground Control requirement is minted (REP-series requirements live upstream).
gc_codex_review — cycle 1 of 1 (pre-push) on issue #26 (branch 26-cyberbattlesim-scenario-ledger) Diff mode: inline — the complete diff was supplied in one prompt
Core review
Verdict:don't-ship
The artifact split is shaped correctly: CyberBattleSim evidence remains module-local, portable semantics use published RAES SDL and experiment contracts, qualification remains the provenance authority, and no backend vocabulary leaks into raes_adapters.base. The design seam is the package-local evidence bundle plus its deterministic validator, which could naturally accommodate another immutable scenario selection. However, the core SDL does not represent the selected size-10 topology it claims to map, and the validator has fail-open omissions at two evidence joins. Those defects undermine the evidence set’s semantic and integrity claims, so this is not production-ready.
Blocking findings (2):
[one-off] The size-10 source topology is represented by only four static hosts — src/raes_adapters/cyberbattlesim/scenario/cyberbattle-chain.sdl.yaml:12 chain_size defaults to 10 but is used only in descriptive interpolation; the scenario contains four host nodes and three fixed adjacency relationships, with no variation point or instantiation mechanism that expands the chain. Accounts and action targets are likewise hard-coded to those few hosts. Consequently, the canonical digest pins a four-host abstraction while the task, ledger, and scenario all claim to represent the selected CyberBattleChain-v0, size=10 case. Encode the complete selected topology, or implement the size-driven SDL variation and validate representative assignments, before treating this as source-mapped portable evidence.
[class] Omitting optional parse results bypasses fail-closed evidence checks — src/raes_adapters/cyberbattlesim/scenario_ledger.py:239
Two required integrity joins are enforced only when an optional value was successfully extracted. load_loss_disclosures overwrites a pending heading when the next heading arrives, so a disclosure without an equivalence-tier line disappears and cannot be reported as malformed or unreferenced. At line 355, qualification membership for source_path is checked only when source_digest is present, so deleting the optional digest allows an arbitrary unqualified path to pass. Preserve and validate every disclosure heading, and always join source_path to qualification.source_files independently of whether a digest was supplied; add source-level negative tests for both omission cases.
Security review
Verdict:ship
This change is shaped correctly as a package-local, static evidence set: authored SDL and experiment artifacts flow through published RAES parsers and closed models, while the backend-local ledger receives strict parsing, integrity joins, target resolution, and leakage checks. The design seam is checked-in resource loading followed by deterministic in-process validation; it introduces no request, authentication, persistence, subprocess, network, dynamic execution, or secret-bearing surface, and it leaves the next scenario variation open through explicit artifact selection. I found no concrete, exploitable security issue introduced by the diff.
gc_codex_review pre-push cycle 1 of 1 complete for issue #26 on branch '26-cyberbattlesim-scenario-ledger'. Posted by the MCP server to enforce the pre-push hard-cap-1 contract (issues #796, #804, #906). Do not edit or delete — used by the next gc_codex_review (uncommitted) invocation to count cycles.
Review decision record — codex cycle 1 (issue #26)
Reviewer: codex Cycle: 1
Architectural read:
Core reviewer: The artifact split is shaped correctly: CyberBattleSim evidence remains module-local, portable semantics use published RAES SDL and experiment contracts, qualification remains the provenance authority, and no backend vocabulary leaks into raes_adapters.base. The design seam is the package-local evidence bundle plus its deterministic validator, which could naturally accommodate another immutable scenario selection. However, the core SDL does not represent the selected size-10 topology it claims to map, and the validator has fail-open omissions at two evidence joins. Those defects undermine the evidence set’s semantic and integrity claims, so this is not production-ready.
Security reviewer: This change is shaped correctly as a package-local, static evidence set: authored SDL and experiment artifacts flow through published RAES parsers and closed models, while the backend-local ledger receives strict parsing, integrity joins, target resolution, and leakage checks. The design seam is checked-in resource loading followed by deterministic in-process validation; it introduces no request, authentication, persistence, subprocess, network, dynamic execution, or secret-bearing surface, and it leaves the next scenario variation open through explicit artifact selection. I found no concrete, exploitable security issue introduced by the diff.
Blocking findings: 2
Finding 1 — one-off
ID:F1
Title: [core] The size-10 source topology is represented by only four static hosts
Rationale:chain_size defaults to 10 but is used only in descriptive interpolation; the scenario contains four host nodes and three fixed adjacency relationships, with no variation point or instantiation mechanism that expands the chain. Accounts a…
Rationale: Two required integrity joins are enforced only when an optional value was successfully extracted. load_loss_disclosures overwrites a pending heading when the next heading arrives, so a disclosure without an equivalence-tier line disappea…
gc_codex_review — cycle 2 of 1 (pre-push) on issue #26 (branch 26-cyberbattlesim-scenario-ledger) Diff mode: inline — the complete diff was supplied in one prompt
Core review
Verdict:ship-with-fixes
Architecture-fit: the split between portable SDL, published RAES experiment contracts, and a backend-local mapping ledger is correct; it keeps semantic authority in RAES and avoids leaking CyberBattleSim concepts into shared plumbing. The design seam should be one immutable evidence selection whose resources and references are validated together, but the implementation hardwires independent singleton resources without integrity joins, foreclosing the documented second-scenario variation. Code-quality: the negative tests cover many ledger corruptions well, but the native-state boundary is implemented as a short literal blacklist rather than the declared contract. The overall shape is sound, with two material validation gaps to close.
Blocking findings (2):
[class] Evidence resources are not modeled or validated as one selection — src/raes_adapters/cyberbattlesim/scenario_ledger.py:51
The new guardrail makes an explicit artifact root or selection identity the extension seam, but the implementation represents the current selection as global path constants plus one global digest, and validate_all() always loads those singletons. A second scenario therefore requires editing the validator's current-selection code. More importantly, the independently parsed artifacts are never joined: the spec task_ref is not matched to the loaded task, the task/spec scenario references are not collectively matched to the loaded scenario's identity, path, and canonical digest, and the task's public-protocol checksum and size are not verified through the incumbent read_public_protocol integrity pattern. Stale references or protocol drift can consequently remain schema-valid and produce an empty validate_all() result. Introduce a small module-local immutable selection descriptor, pass it through the loaders and validator, and validate these relational joins; this belongs here rather than in raes_adapters.base or a new semantic schema.
[one-off] Literal marker scanning does not enforce the native-state boundary — src/raes_adapters/cyberbattlesim/scenario_ledger.py:103
The leakage gate recognizes only a short list of exact, case-sensitive identifiers and one traceback prefix. It does not enforce several classes the change explicitly promises CI will reject, including numeric native action IDs, Gym tuples, reward vectors, raw or hidden state, credential values, arbitrary simulator logs, argument/environment dumps, tokens, or simple spelling and case variants. The matching test exercises one listed fixture literal, so portable content containing another prohibited native representation can still pass validate_all(). Ground this check in the portable contract structure and explicit provenance rules, or narrow the claimed guarantee to what can actually be enforced and add behavioral tests for every retained leakage class.
Security review
Verdict:ship
This change is shaped correctly as a static, package-local evidence set: authored scenario and experiment artifacts pass through safe or closed-model parsers, the source ledger is strictly decoded and joined to immutable qualification data, and target resolution is limited to package resources and published schema metadata. It introduces no request, authentication, persistence, subprocess, network-fetch, dynamic-import, or secret-handling boundary, and it preserves the seam for additional immutable CyberBattleSim selections without widening the shared semantic surface. I found no concrete, exploitable security issue introduced by the diff.
gc_codex_review pre-push cycle 2 (USER-AUTHORIZED OVERRIDE past cap 1) complete for issue #26 on branch '26-cyberbattlesim-scenario-ledger'. Posted by the MCP server to enforce the pre-push hard-cap-1 contract (issues #796, #804, #906). Do not edit or delete — used by the next gc_codex_review (uncommitted) invocation to count cycles.
Override reason: User authorized an over-cap re-review of the cycle-1 fixes: the topology-fidelity reframe (representative chain + disclosed loss-abstracted-topology) and the two validator integrity fixes (required source_digest + unconditional qualification join; tier-less disclosure headings preserved).
Review decision record — codex cycle 2 (issue #26)
Reviewer: codex Cycle: 2
Architectural read:
Core reviewer: Architecture-fit: the split between portable SDL, published RAES experiment contracts, and a backend-local mapping ledger is correct; it keeps semantic authority in RAES and avoids leaking CyberBattleSim concepts into shared plumbing. The design seam should be one immutable evidence selection whose resources and references are validated together, but the implementation hardwires independent singleton resources without integrity joins, foreclosing the documented second-scenario variation. Code-quality: the negative tests cover many ledger corruptions well, but the native-state boundary is implemented as a short literal blacklist rather than the declared contract. The overall shape is sound, with two material validation gaps to close.
Security reviewer: This change is shaped correctly as a static, package-local evidence set: authored scenario and experiment artifacts pass through safe or closed-model parsers, the source ledger is strictly decoded and joined to immutable qualification data, and target resolution is limited to package resources and published schema metadata. It introduces no request, authentication, persistence, subprocess, network-fetch, dynamic-import, or secret-handling boundary, and it preserves the seam for additional immutable CyberBattleSim selections without widening the shared semantic surface. I found no concrete, exploitable security issue introduced by the diff.
Blocking findings: 2
Finding 1 — class (11 instances)
ID:F1
Title: [core] Evidence resources are not modeled or validated as one selection
Rationale: The new guardrail makes an explicit artifact root or selection identity the extension seam, but the implementation represents the current selection as global path constants plus one global digest, and validate_all() always loads those sing…
Rationale: The leakage gate recognizes only a short list of exact, case-sensitive identifiers and one traceback prefix. It does not enforce several classes the change explicitly promises CI will reject, including numeric native action IDs, Gym tuples…
gc_test_quality_review cycle 1 of 1 complete for issue #26 on branch '26-cyberbattlesim-scenario-ledger'. Posted by the MCP server to enforce the gc_test_quality_review hard-cap-1 contract (issue #884 follow-up, default lowered in #906). Do not edit or delete — used by the next gc_test_quality_review invocation to count cycles.
Review decision record — test-quality cycle 1 (issue #26)
Reviewer: test-quality Cycle: 1
Architectural read:
This is a fail-closed validator for a provenance/audit-integrity ledger (source-to-portable-artifact mapping with digest pinning, disposition rules, and loss-disclosure bookkeeping), and the test suite is shaped to match: every enforcement branch in validate_source_ledger, resolve_target, validate_selection_joins, parse_ledger_rows, parse_loss_disclosures, and native_leakage_problems is exercised by mutating a real checked-in row/selection/document and asserting the specific LedgerProblem the corruption should produce, rather than asserting on mocks or on mere presence of a rule. No mocking of subprocess/filesystem/datetime internals; the SimpleNamespace stand-ins in test_protocol_artifact_join_detects_checksum_and_size_drift are plain duck-typed data objects for a pure helper, not framework mocking. Reading packaged YAML/JSON resources isn't integration-masquerading-as-unit here — loading and validating those exact bundled artifacts is the module's entire contract. Positive tests (test_full_evidence_set_is_valid, test_scenario_pipeline_compiles_with_pinned_release) and the full battery of negative/fail-closed tests together mean a no-op or weakened validator would fail nearly every test in the file. I would ship this.
The repository now ships a portable, machine-validated RAES evidence set for the selected public CyberBattleSim case: an SDL scenario that parses, compiles, and admits against raes 2.0.0, companion published experiment contracts, and a pinned source-to-RAES mapping ledger with disclosed losses. CI fails closed if that evidence drifts from the qualified source, loses required category coverage, breaks a cross-artifact reference, or leaks native simulator state. The case remains not-admissible and still ships no installable cyberbattlesim extra.
Author the CyberBattleSim RAES SDL scenario + published experiment contracts + pinned source-mapping ledger with deterministic, fail-closed validation.
codex: 2 cycles (one over-cap): fixed the size-10 topology overclaim (now a representative model with a disclosed loss) and two fail-open evidence joins; added cross-artifact joins. All findings resolved.
test-quality: Clean, 0 findings. The suite pairs positive checks with fail-closed negatives for every enforced condition.
Traceability reconciliation
Pending — requirement status transition and IMPLEMENTS/TESTS reconciliation run in Phase E once the PR merges.
Status
CI: ✅ green
SonarCloud: ✅ passed
PR ready for user review and merge. Ground Control reconciliation (requirement status + traceability) runs on merge (Phase E).
gc workflow phase recorded: traceability_reconciled (issue #26). Posted by the MCP server to enforce ordering between workflow steps (issue #794 MVP-2). Do not edit or delete — used by downstream tools to gate phase prerequisites.
no in-scope requirements; touched-files audit clean.
The repository now ships a portable, machine-validated RAES evidence set for the selected public CyberBattleSim case: an SDL scenario that parses, compiles, and admits against raes 2.0.0, companion published experiment contracts, and a pinned source-to-RAES mapping ledger with disclosed losses. CI fails closed if that evidence drifts from the qualified source, loses required category coverage, breaks a cross-artifact reference, or leaks native simulator state. The case remains not-admissible and still ships no installable cyberbattlesim extra.
Author the CyberBattleSim RAES SDL scenario + published experiment contracts + pinned source-mapping ledger with deterministic, fail-closed validation.
codex: 2 cycles (one over-cap): fixed the size-10 topology overclaim (now a representative model with a disclosed loss) and two fail-open evidence joins; added cross-artifact joins. All findings resolved.
test-quality: Clean, 0 findings. The suite pairs positive checks with fail-closed negatives for every enforced condition.
Traceability reconciliation
IMPLEMENTS / TESTS / DOCUMENTS added: 0
Links updated: 0
Stale links removed: 0
Requirement-free run: no in-scope requirements to transition or link. The diff adds all-new files and touches three docs/config files, none carrying traceability links to existing requirements, so reconciliation added, updated, and deleted nothing.
Activity
Brad-Edwards commentedon Jul 29, 2026
🛠️ Picked up by /implement - driver claude-code, branch
26-cyberbattlesim-scenario-ledger, 2026-07-29T21:31:28.064Z.Brad-Edwards commentedon Jul 29, 2026
gc workflow phase recorded:
preflight(issue #26). Posted by the MCP server to enforce ordering between workflow steps (issue #794 MVP-2). Do not edit or delete — used by downstream tools to gate phase prerequisites.Brad-Edwards commentedon Jul 29, 2026
gc workflow phase recorded:
plan(issue #26). Posted by the MCP server to enforce ordering between workflow steps (issue #794 MVP-2). Do not edit or delete — used by downstream tools to gate phase prerequisites.Plan — CyberBattleSim RAES scenario + pinned source mapping ledger (#26)
Requirement-free run (no
#### Requirementssection). Acceptance is the issue's criteria. Branch26-cyberbattlesim-scenario-ledgeroffdev(which carries #25's merged, qualified profile). Binding design authority: the architecture-preflight notedocs/decisions/cyberbattlesim-scenario-ledger-guardrails.md(authored this run) +docs/decisions/cyberbattlesim-qualification-guardrails.md+ ADR-002 + AGENTS.md.Key design decision (from preflight guardrails)
RAES 2.0.0 rejects SDL scoring/reward sections, so the deliverable is one artifact set, not one document:
raes_contractspublished models (ExperimentSpecModel/ExperimentTaskModelfamily) withContractModel(extra="forbid")andparse_experiment_spec().tests/verifynox graph (no new policy gate, CI job, DTO, schema, or vocabulary).The
not-admissiblequalification is unchanged; authoring validity is not installability, replay, conformance, or equivalence. No adapter, extra, manifest, runtime smoke, evidence run, or environment pack is added.Files (all under
src/raes_adapters/cyberbattlesim/, present in wheel/sdist)scenario/cyberbattle-chain.sdl.yaml— fixed CyberBattleChain-v0 chain: nodes (entry/relays/customer-data + switch), services,vulnerabilities(CWE-classed),relationships,entities(red/blue),accounts(synthetic credential intent only),agents(attacker=CredentialCacheExploiter, defender=ScanAndReimage),action_contracts(local/remote vuln, connect, scan-and-reimage),observation_boundaries,propositions/assertions/objectives(attacker ownership; defender availability/SLA),evidence_requirements, and achain_sizevariable representing the generated-topology family (parameterized instantiation → distinct canonical snapshots; not a generator block). Prototype already validates:parse_sdl_file→instantiate_scenario→canonical_instantiated_sdl_digest→admit_instantiated_scenarioall green.experiment/cyberbattle-chain.experiment.yaml(+ any companion) — reward (winning 5000 / losing 0), evaluator (epsilon_greedy_search+ epsilon params), metrics (steps-to-termination, cumulative reward, availability series, terminal cause), episode control (episode_count 10, iteration cutoff 600), termination precedence, and 4 descriptive stochastic controls (no executable random-stream binding — the losses are retained).mapping/source-ledger.jsonl— one row per source fact.mapping/loss-disclosures.md— narrative losses bound to equivalence tiers.mapping/README.md— row schema + governance (mirrors the CybORG mapping README pattern, not its CAGE field names).scenario_ledger.py— public loaders + deterministic validators (extends theload_qualification/importlib.resources/SHA-256 join pattern).tests/test_cyberbattlesim_scenario_ledger.py— TDD tests.docs/index.md/mkdocs.yml(preflight already wired the new guardrails note into the nav).Ledger row schema
source_id,source_repo,source_commit,source_path,source_selector,source_digest?,category,disposition∈mapped|excluded|loss-disclosed,raes_target?,mapping_rule,loss_ref?,verification. Closed flat package data — not a Pydantic model, DTO, or schema.Deterministic validation (fails closed; acceptance criterion 6)
parse_sdl_file(semantic on) → instantiate representative fixed/generated assignments → canonical digest (pinned; drift fails) →raes_processor.compiler.compile_scenario_runtime_model();admit_instantiated_scenario.parse_experiment_spec()/ closed published models.source_id; every source pin (repo/commit/path/digest) joins offline toqualification.jsonand the recordedprotocol.sha256(source-drift = integrity join, no network/no upstream execution); all required categories present (topology/state, identities, participants, actions, observations, controls, rewards/objectives, termination, evaluator facts, stochastic policy, provenance/licensing); exactly one disposition per row;excludedneeds a rationale; every loss row references a disclosure and every disclosure is referenced by a row and names its ADR-069 tier.raes_targetresolves to a real validated artifact path or a contract id + property path inraes_contracts.contracts.schema_bundle()— derived from parsed artifacts, no second target catalog.TDD (full red/green — SDL/experiment YAML + ledger + validator are runtime-parsed, so no doc-only carve-out)
Write failing validator/loader tests first, then author each artifact to pass. Run narrow tests while iterating;
make verifyonce on the final tree (Step 6).make policyuses--skip-requirement(requirement-free).Design lenses
raesSDL/contract APIs,schema_bundle(), the qualification loader + SHA-256 join, existing nox graph and wheel/sdist proof; no new gate/workflow/DTO.raes_adapters.base/cyborg, RAES corpus, or env-pack schemas; Release Please ownsCHANGELOG.md/version (no hand edits); single distribution + oneuv.lock.Non-goals
Not-admissible unchanged; no adapter/extra/manifest/runtime smoke/conformance/evidence run/env-pack/persistence/equivalence claim; no
SDLLineageLedgerModelfor this mapping; no repo-local SDL/schema/vocabulary. The module-local validator is test/helper code, not an ADR-backed structural gate, so no Ground Control requirement is minted (REP-series requirements live upstream).Brad-Edwards commentedon Jul 29, 2026
gc_codex_review — cycle 1 of 1 (pre-push) on issue #26 (branch
26-cyberbattlesim-scenario-ledger)Diff mode: inline — the complete diff was supplied in one prompt
Core review
Verdict:
don't-shipThe artifact split is shaped correctly: CyberBattleSim evidence remains module-local, portable semantics use published RAES SDL and experiment contracts, qualification remains the provenance authority, and no backend vocabulary leaks into
raes_adapters.base. The design seam is the package-local evidence bundle plus its deterministic validator, which could naturally accommodate another immutable scenario selection. However, the core SDL does not represent the selected size-10 topology it claims to map, and the validator has fail-open omissions at two evidence joins. Those defects undermine the evidence set’s semantic and integrity claims, so this is not production-ready.Blocking findings (2):
src/raes_adapters/cyberbattlesim/scenario/cyberbattle-chain.sdl.yaml:12chain_sizedefaults to 10 but is used only in descriptive interpolation; the scenario contains four host nodes and three fixed adjacency relationships, with no variation point or instantiation mechanism that expands the chain. Accounts and action targets are likewise hard-coded to those few hosts. Consequently, the canonical digest pins a four-host abstraction while the task, ledger, and scenario all claim to represent the selectedCyberBattleChain-v0, size=10case. Encode the complete selected topology, or implement the size-driven SDL variation and validate representative assignments, before treating this as source-mapped portable evidence.src/raes_adapters/cyberbattlesim/scenario_ledger.py:239Two required integrity joins are enforced only when an optional value was successfully extracted.
load_loss_disclosuresoverwrites a pending heading when the next heading arrives, so a disclosure without an equivalence-tier line disappears and cannot be reported as malformed or unreferenced. At line 355, qualification membership forsource_pathis checked only whensource_digestis present, so deleting the optional digest allows an arbitrary unqualified path to pass. Preserve and validate every disclosure heading, and always joinsource_pathtoqualification.source_filesindependently of whether a digest was supplied; add source-level negative tests for both omission cases.Security review
Verdict:
shipThis change is shaped correctly as a package-local, static evidence set: authored SDL and experiment artifacts flow through published RAES parsers and closed models, while the backend-local ledger receives strict parsing, integrity joins, target resolution, and leakage checks. The design seam is checked-in resource loading followed by deterministic in-process validation; it introduces no request, authentication, persistence, subprocess, network, dynamic execution, or secret-bearing surface, and it leaves the next scenario variation open through explicit artifact selection. I found no concrete, exploitable security issue introduced by the diff.
No blocking findings.
Brad-Edwards commentedon Jul 29, 2026
gc_codex_review pre-push cycle 1 of 1 complete for issue #26 on branch '26-cyberbattlesim-scenario-ledger'. Posted by the MCP server to enforce the pre-push hard-cap-1 contract (issues #796, #804, #906). Do not edit or delete — used by the next
gc_codex_review(uncommitted) invocation to count cycles.Brad-Edwards commentedon Jul 29, 2026
Review decision record — codex cycle 1 (issue #26)
Reviewer: codex
Cycle: 1
Architectural read:
Blocking findings: 2
Finding 1 —
one-offF1src/raes_adapters/cyberbattlesim/scenario/cyberbattle-chain.sdl.yaml:12chain_sizedefaults to 10 but is used only in descriptive interpolation; the scenario contains four host nodes and three fixed adjacency relationships, with no variation point or instantiation mechanism that expands the chain. Accounts a…Finding 2 —
class(2 instances)F2src/raes_adapters/cyberbattlesim/scenario_ledger.py:239load_loss_disclosuresoverwrites a pending heading when the next heading arrives, so a disclosure without an equivalence-tier line disappea…src/raes_adapters/cyberbattlesim/scenario_ledger.py:239src/raes_adapters/cyberbattlesim/scenario_ledger.py:355Brad-Edwards commentedon Jul 29, 2026
gc_codex_review — cycle 2 of 1 (pre-push) on issue #26 (branch
26-cyberbattlesim-scenario-ledger)Diff mode: inline — the complete diff was supplied in one prompt
Core review
Verdict:
ship-with-fixesArchitecture-fit: the split between portable SDL, published RAES experiment contracts, and a backend-local mapping ledger is correct; it keeps semantic authority in RAES and avoids leaking CyberBattleSim concepts into shared plumbing. The design seam should be one immutable evidence selection whose resources and references are validated together, but the implementation hardwires independent singleton resources without integrity joins, foreclosing the documented second-scenario variation. Code-quality: the negative tests cover many ledger corruptions well, but the native-state boundary is implemented as a short literal blacklist rather than the declared contract. The overall shape is sound, with two material validation gaps to close.
Blocking findings (2):
src/raes_adapters/cyberbattlesim/scenario_ledger.py:51The new guardrail makes an explicit artifact root or selection identity the extension seam, but the implementation represents the current selection as global path constants plus one global digest, and validate_all() always loads those singletons. A second scenario therefore requires editing the validator's current-selection code. More importantly, the independently parsed artifacts are never joined: the spec task_ref is not matched to the loaded task, the task/spec scenario references are not collectively matched to the loaded scenario's identity, path, and canonical digest, and the task's public-protocol checksum and size are not verified through the incumbent read_public_protocol integrity pattern. Stale references or protocol drift can consequently remain schema-valid and produce an empty validate_all() result. Introduce a small module-local immutable selection descriptor, pass it through the loaders and validator, and validate these relational joins; this belongs here rather than in raes_adapters.base or a new semantic schema.
src/raes_adapters/cyberbattlesim/scenario_ledger.py:103The leakage gate recognizes only a short list of exact, case-sensitive identifiers and one traceback prefix. It does not enforce several classes the change explicitly promises CI will reject, including numeric native action IDs, Gym tuples, reward vectors, raw or hidden state, credential values, arbitrary simulator logs, argument/environment dumps, tokens, or simple spelling and case variants. The matching test exercises one listed fixture literal, so portable content containing another prohibited native representation can still pass validate_all(). Ground this check in the portable contract structure and explicit provenance rules, or narrow the claimed guarantee to what can actually be enforced and add behavioral tests for every retained leakage class.
Security review
Verdict:
shipThis change is shaped correctly as a static, package-local evidence set: authored scenario and experiment artifacts pass through safe or closed-model parsers, the source ledger is strictly decoded and joined to immutable qualification data, and target resolution is limited to package resources and published schema metadata. It introduces no request, authentication, persistence, subprocess, network-fetch, dynamic-import, or secret-handling boundary, and it preserves the seam for additional immutable CyberBattleSim selections without widening the shared semantic surface. I found no concrete, exploitable security issue introduced by the diff.
No blocking findings.
Brad-Edwards commentedon Jul 29, 2026
gc_codex_review pre-push cycle 2 (USER-AUTHORIZED OVERRIDE past cap 1) complete for issue #26 on branch '26-cyberbattlesim-scenario-ledger'. Posted by the MCP server to enforce the pre-push hard-cap-1 contract (issues #796, #804, #906). Do not edit or delete — used by the next
gc_codex_review(uncommitted) invocation to count cycles.Override reason: User authorized an over-cap re-review of the cycle-1 fixes: the topology-fidelity reframe (representative chain + disclosed loss-abstracted-topology) and the two validator integrity fixes (required source_digest + unconditional qualification join; tier-less disclosure headings preserved).
Brad-Edwards commentedon Jul 29, 2026
Review decision record — codex cycle 2 (issue #26)
Reviewer: codex
Cycle: 2
Architectural read:
Blocking findings: 2
Finding 1 —
class(11 instances)F1src/raes_adapters/cyberbattlesim/scenario_ledger.py:51src/raes_adapters/cyberbattlesim/scenario_ledger.py:51src/raes_adapters/cyberbattlesim/scenario_ledger.py:53src/raes_adapters/cyberbattlesim/scenario_ledger.py:54src/raes_adapters/cyberbattlesim/scenario_ledger.py:55src/raes_adapters/cyberbattlesim/scenario_ledger.py:56src/raes_adapters/cyberbattlesim/scenario_ledger.py:57src/raes_adapters/cyberbattlesim/scenario_ledger.py:531src/raes_adapters/cyberbattlesim/experiment/cyberbattle-chain.spec.exp.yaml:11src/raes_adapters/cyberbattlesim/experiment/cyberbattle-chain.spec.exp.yaml:14src/raes_adapters/cyberbattlesim/experiment/cyberbattle-chain.task.exp.yaml:12src/raes_adapters/cyberbattlesim/experiment/cyberbattle-chain.task.exp.yaml:114Finding 2 —
one-offF2src/raes_adapters/cyberbattlesim/scenario_ledger.py:103Brad-Edwards commentedon Jul 29, 2026
gc_test_quality_review cycle 1 of 1 — issue #26
Reviewer: test-quality (claude-sonnet-5 via gc_test_quality_review)
Branch:
26-cyberbattlesim-scenario-ledgerCycle: 1 / 1
Findings: 0 (clean run)
Brad-Edwards commentedon Jul 29, 2026
gc_test_quality_review cycle 1 of 1 complete for issue #26 on branch '26-cyberbattlesim-scenario-ledger'. Posted by the MCP server to enforce the gc_test_quality_review hard-cap-1 contract (issue #884 follow-up, default lowered in #906). Do not edit or delete — used by the next
gc_test_quality_reviewinvocation to count cycles.Brad-Edwards commentedon Jul 29, 2026
Review decision record — test-quality cycle 1 (issue #26)
Reviewer: test-quality
Cycle: 1
Architectural read:
Blocking findings: 0 (clean run)
Brad-Edwards commentedon Jul 29, 2026
Pre-PR base synchronization
refs/remotes/origin/devat93f3782ea111874b534b7f6ea7328109ce767c7balready_current2cfd45d88eff58eccca4f825ec7fa3b67dfcbb1d341a3df03284b0126272ed4dac2e6b0ff58feeffBrad-Edwards commentedon Jul 29, 2026
Pre-PR base synchronization
refs/remotes/origin/devat93f3782ea111874b534b7f6ea7328109ce767c7balready_currenta0fdc2293c77e84e4912222b5a7dc3b88e83c00d34ccc4e7e5f77d29300cbdee3856ad1bd8e955fbBrad-Edwards commentedon Jul 29, 2026
Pre-PR base synchronization
refs/remotes/origin/devat93f3782ea111874b534b7f6ea7328109ce767c7balready_current26d63fca953e6074b52f43dc3c3b47ba27c250af7854bf47842c4191934fdcab10a1e3f1bf6a3f7fBrad-Edwards commentedon Jul 29, 2026
Ready for review — issue #26
PR: #55
Plan: #26 (comment)
Outcome
The repository now ships a portable, machine-validated RAES evidence set for the selected public CyberBattleSim case: an SDL scenario that parses, compiles, and admits against raes 2.0.0, companion published experiment contracts, and a pinned source-to-RAES mapping ledger with disclosed losses. CI fails closed if that evidence drifts from the qualified source, loses required category coverage, breaks a cross-artifact reference, or leaks native simulator state. The case remains not-admissible and still ships no installable cyberbattlesim extra.
Author the CyberBattleSim RAES SDL scenario + published experiment contracts + pinned source-mapping ledger with deterministic, fail-closed validation.
Files changed
Added:
docs/decisions/cyberbattlesim-scenario-ledger-guardrails.mdsrc/raes_adapters/cyberbattlesim/scenario/cyberbattle-chain.sdl.yamlsrc/raes_adapters/cyberbattlesim/experiment/cyberbattle-chain.task.exp.yamlsrc/raes_adapters/cyberbattlesim/experiment/cyberbattle-chain.spec.exp.yamlsrc/raes_adapters/cyberbattlesim/mapping/source-ledger.jsonlsrc/raes_adapters/cyberbattlesim/mapping/loss-disclosures.mdsrc/raes_adapters/cyberbattlesim/mapping/README.mdsrc/raes_adapters/cyberbattlesim/scenario_ledger.pytests/test_cyberbattlesim_scenario_ledger.pyModified:
README.mddocs/index.mdmkdocs.ymlReviews
Traceability reconciliation
Status
Brad-Edwards commentedon Jul 29, 2026
gc workflow phase recorded:
traceability_reconciled(issue #26). Posted by the MCP server to enforce ordering between workflow steps (issue #794 MVP-2). Do not edit or delete — used by downstream tools to gate phase prerequisites.no in-scope requirements; touched-files audit clean.
Brad-Edwards commentedon Jul 29, 2026
Final report — issue #26 complete
PR: #55
Plan: #26 (comment)
Outcome
The repository now ships a portable, machine-validated RAES evidence set for the selected public CyberBattleSim case: an SDL scenario that parses, compiles, and admits against raes 2.0.0, companion published experiment contracts, and a pinned source-to-RAES mapping ledger with disclosed losses. CI fails closed if that evidence drifts from the qualified source, loses required category coverage, breaks a cross-artifact reference, or leaks native simulator state. The case remains not-admissible and still ships no installable cyberbattlesim extra.
Author the CyberBattleSim RAES SDL scenario + published experiment contracts + pinned source-mapping ledger with deterministic, fail-closed validation.
Files changed
Added:
docs/decisions/cyberbattlesim-scenario-ledger-guardrails.mdsrc/raes_adapters/cyberbattlesim/scenario/cyberbattle-chain.sdl.yamlsrc/raes_adapters/cyberbattlesim/experiment/cyberbattle-chain.task.exp.yamlsrc/raes_adapters/cyberbattlesim/experiment/cyberbattle-chain.spec.exp.yamlsrc/raes_adapters/cyberbattlesim/mapping/source-ledger.jsonlsrc/raes_adapters/cyberbattlesim/mapping/loss-disclosures.mdsrc/raes_adapters/cyberbattlesim/mapping/README.mdsrc/raes_adapters/cyberbattlesim/scenario_ledger.pytests/test_cyberbattlesim_scenario_ledger.pyModified:
README.mddocs/index.mdmkdocs.ymlReviews
Traceability reconciliation
Requirement-free run: no in-scope requirements to transition or link. The diff adds all-new files and touches three docs/config files, none carrying traceability links to existing requirements, so reconciliation added, updated, and deleted nothing.
Status