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
feat(cyborg): implement logical step control and action translation #16
gc workflow phase recorded: preflight (issue #16). 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 #16). 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.
Implementation plan
Add red-first tests in tests/test_cyborg_execution.py for the issue contract: exact action/argument admission with zero native effects on rejection; one aggregate driver call and one typed terminal result per valid action; pinned Blue→Green→Red participant ordering; B-line, Meander, Sleep, and green occurrences; logical trial cutoffs at 30/50/100; native-terminal handling; reset/quarantine behavior; controlled-seed disclosures; and hostile native values proving no tuple, action id, reward, hidden truth, log, repr, or exception text crosses the boundary.
Extend the module-private CyborgDriver/provisioner ownership seam so construction, policy-bound reconstruction, reset, step, quarantine, stop, and cleanup share one re-entrant mutation lock and one active native handle. Keep lazy fixed imports for the pinned CybORG source, closed exact action-address dispatch, normalized argument conversion, caller random-state restoration, and bounded failures.
Add CyborgOrchestrator to admit one published RAES episode-control contract carried by the compiled workflow operation, reconcile workflow status/history through published RAES shapes, bind one initialized logical clock and the selected red variant, and prevent participant execution until an admitted run exists. It will not expose a public step method or advertise an Evaluator.
Add CyborgParticipantRuntime on BaseParticipantRuntime. Reuse RAES episode/action/history commit behavior, require the validated normalized selection, trigger at most one aggregate turn for the admitted external blue action, project internal red/green occurrences as distinct joined participant events, commit mapped shared-state/joint-action/time records, and advance the RAES clock exactly once only after complete projection validation. Invalid post-step output quarantines the native session; pre-effect failures preserve both snapshot and driver-call count.
Extend manifest.py, target.py, and __init__.py with only the orchestrator/participant/time capabilities and published contract IDs actually exercised. Preserve the single distribution, closed target config, provisioning realization envelope, and absent evaluator. Update README/API documentation only where the new public target capability needs discovery; retain the preflight guardrail note and MkDocs navigation.
Verify each acceptance criterion against exact source/test lines, run focused execution/provisioner/manifest tests with ACES_REQUIREMENT_UID=REP-004, then run the managed completion gate and canonical uv tool run --from 'nox[uv]==2026.4.10' nox -f noxfile.py -s verify graph. No changelog, new schema/profile/vocabulary, second lockfile, native dependency, or backend-specific SDL change is planned.
Whole-repository design checks
Security: action request type, live episode/run, exact contract address, normalized argument shape, target closure, trial bound, time state, driver result shape, portable models, and final snapshot transition are validated at their existing layers. No auth/network surface or secret input is added; native values and exceptions are default-deny.
Maintainability: reuse CyborgProvisioner, SourceInstalledCyborgDriver, BaseParticipantRuntime, ReferenceTimeRuntime, base clock/projection/redaction helpers, manifest/target factories, and the existing nox/test patterns.
Extensibility: fixed private translator functions are selected by exact admitted action addresses. A reviewed action/source profile or red variant adds one evidence-backed binding without changing portable contracts, receipts, diagnostics, or session ownership.
Scope/claims: RAES owns the semantic contracts. Full declared precondition/effect validation and direct receipt/action foreign-key projection remain explicitly unavailable until RAES exposes the necessary public context; no local DTO or fabricated receipt fills those gaps.
gc_codex_review — cycle 1 of 1 (pre-push) on issue #16 (branch 16-logical-step-control) Diff mode: inline — the complete diff was supplied in one prompt
Core review
Verdict:don't-ship
The intended shape is sound: published RAES orchestration, participant, and time contracts remain the portable boundary, while native action translation and aggregate-turn mechanics stay inside the CybORG module. The production seam is not yet preserved, however. Native lifecycle mutations, portable state construction, and logical-time updates are split across independently locked components, so they are neither serialized nor committed atomically; target-bearing actions also bypass the required realized-target closure. Those are boundary-contract failures rather than local polish, and they affect the obvious next variations—concurrent control-plane calls, additional target-bearing actions, and multi-trial reset.
Blocking findings (3):
[class] Native and portable transitions are not one serialized transaction — src/raes_adapters/cyborg/participant_runtime.py:155
The effectful native turn completes under the provisioner's lock, but that lock is released before logical-time advancement, construction of the shared-state/joint-action records, workflow completion, and final runtime validation. A failure in any post-step operation—for example, a missing red/green episode causing _portable_turn to raise, model construction failing, or the manager rejecting a hand-built record—can restore the baseline portable snapshot while leaving the mutated native handle available. The separate execution-control lock also permits start or reset to interleave with this gap. Use one module-private re-entrant session coordinator for start, turn, and reset, validate the complete candidate portable state before publishing it, and quarantine the native session on every failure after an effectful call.
[class] Target-bearing actions reach CybORG without realized-target validation — src/raes_adapters/cyborg/driver.py:285 validate_action_selection establishes only that hostname is a string; Analyse, Remove, and Restore then forward that value directly to native constructors. A normalized but unrealizable hostname therefore triggers an aggregate native turn—including red and green effects—instead of being rejected before the driver call. Resolve each portable target through the active scenario realization and admit only an exact mapped native hostname before constructing any target-bearing action.
[one-off] Coordinated reset leaves the logical trial clock exhausted — src/raes_adapters/cyborg/participant_runtime.py:126
After resetting all participant episodes and the native aggregate, this path only clears the source-terminal latch. It never applies the declared new_segment_zero time reset. After a trial reaches max_steps, a successful reset therefore leaves the clock at the limit and the next action is immediately rejected as trial-complete. Include the RAES time transition in the same coordinated reset transaction and test reset followed by a successful first turn after an exhausted trial.
Security review
Verdict:ship
This change is shaped correctly around the existing RAES runtime seam: validated portable orchestration and participant inputs cross into a module-private CybORG session through fixed action and policy dispatch, while native results are projected through bounded allowlists and failures are returned without native exception text or object representations. It adds no network, authentication, persistence, filesystem-input, shell, or caller-controlled import surface, and the obvious extensions remain additional reviewed bindings rather than dynamic execution paths. I found no concrete, exploitable security issue introduced by this diff.
gc_codex_review pre-push cycle 1 of 1 complete for issue #16 on branch '16-logical-step-control'. 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 #16)
Reviewer: codex Cycle: 1
Architectural read:
Core reviewer: The intended shape is sound: published RAES orchestration, participant, and time contracts remain the portable boundary, while native action translation and aggregate-turn mechanics stay inside the CybORG module. The production seam is not yet preserved, however. Native lifecycle mutations, portable state construction, and logical-time updates are split across independently locked components, so they are neither serialized nor committed atomically; target-bearing actions also bypass the required realized-target closure. Those are boundary-contract failures rather than local polish, and they affect the obvious next variations—concurrent control-plane calls, additional target-bearing actions, and multi-trial reset.
Security reviewer: This change is shaped correctly around the existing RAES runtime seam: validated portable orchestration and participant inputs cross into a module-private CybORG session through fixed action and policy dispatch, while native results are projected through bounded allowlists and failures are returned without native exception text or object representations. It adds no network, authentication, persistence, filesystem-input, shell, or caller-controlled import surface, and the obvious extensions remain additional reviewed bindings rather than dynamic execution paths. I found no concrete, exploitable security issue introduced by this diff.
Blocking findings: 3
Finding 1 — class (3 instances)
ID:F1
Title: [core] Native and portable transitions are not one serialized transaction
Rationale: The effectful native turn completes under the provisioner's lock, but that lock is released before logical-time advancement, construction of the shared-state/joint-action records, workflow completion, and final runtime validation. A failur…
Title: [core] Target-bearing actions reach CybORG without realized-target validation
Location:src/raes_adapters/cyborg/driver.py:285
Decision: fix
Rationale:validate_action_selection establishes only that hostname is a string; Analyse, Remove, and Restore then forward that value directly to native constructors. A normalized but unrealizable hostname therefore triggers an aggregate native t…
Instances:
src/raes_adapters/cyborg/driver.py:285
src/raes_adapters/cyborg/driver.py:289
src/raes_adapters/cyborg/driver.py:293
Finding 3 — one-off
ID:F3
Title: [core] Coordinated reset leaves the logical trial clock exhausted
Rationale: After resetting all participant episodes and the native aggregate, this path only clears the source-terminal latch. It never applies the declared new_segment_zero time reset. After a trial reaches max_steps, a successful reset therefor…
Problem: SourceInstalledCyborgDriver.step(), _native_blue_action(), _project_turn(), the module-level _project_native_action() mapping table, and construct_execution()'s red-agent import/binding branch are new production code in this diff, but no test in the repository ever calls them. tests/test_cyborg_execution.py uses FakeExecutionDriver, whose step()/construct_execution() hand-build the same _NativeTurnResult tuples the real driver is supposed to derive from CybORG's native Results/Observation objects, instead of exercising the real translation. tests/test_cyborg_provisioner.py's only real-driver test (test_driver_uses_generated_document_deletes_it_and_preserves_global_rng) drives construct(), never construct_execution() or step(). Why it matters: A regression in the real translation — e.g. inverting the observation.data.get("success") == TrinaryEnum.TRUE check, breaking the type(action) is native_type ordering in _project_native_action so a red exploit/impact action is misclassified as sleep, or passing wrong constructor kwargs in _native_blue_action — would not fail a single test, even though this is precisely the boundary the adapter exists to translate correctly for a security-research/RL environment. Fix: Add driver-level tests that construct a fake native handle (mirroring the existing FakeNative pattern) exposing step()/get_last_action(), and fake CybORG.Shared/.Actions/.Enums modules via monkeypatching driver_module.import_module (as already done in test_source_tree_is_verified_before_any_cyborg_import), so _native_blue_action, _project_turn, and _project_native_action run against real code for each supported action type plus the error branches (non-Results type, non-null error, unmapped native action type). Add a construct_execution test that exercises the unsupported-variant and agent-import-failure RuntimeError branches. Add an orchestrator-level test where FakeExecutionDriver.construct_execution raises, to cover the 'cyborg-backend.orchestration.session-construction-failed' path in CyborgOrchestrator._start_transaction, which is currently unreachable because every fake driver's construct_execution unconditionally succeeds.
gc_test_quality_review cycle 1 of 1 complete for issue #16 on branch '16-logical-step-control'. 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 #16)
Reviewer: test-quality Cycle: 1
Architectural read:
The orchestration/participant-runtime layer added in this diff (orchestrator.py, participant_runtime.py, and the new provisioner.py execution-transaction methods) is tested to an unusually high standard: the state-machine transitions, quarantine-and-recovery flow, portable/native leak boundary (the HostileNative/HostileNativeHandle trick that fails the test if a native handle is ever str()'d or repr()'d), and the cross-thread locking guarantee (via real Threads synchronized with Events, not sleeps) are all exercised with assertions on actual return values and snapshot state, not just mock-call checks. That is the correct design seam for isolating this logic from CybORG, which the project clearly cannot assume is installed in CI (confirmed by the separate qualification/ledger tooling in tools/verify_cyborg_qualification.py and tests/test_cyborg_qualification_driver.py, which validate an offline reproduction evidence shape rather than running live). The gap is that the same seam that makes the orchestration layer testable also hides the ~150 new lines of native-translation logic this diff adds to driver.py (step, _native_blue_action, _project_turn, _project_native_action, and construct_execution's red-agent binding): FakeExecutionDriver in test_cyborg_execution.py independently re-derives the exact _NativeTurnResult/_NativeParticipantOccurrence values the real driver is supposed to compute from actual CybORG Results/Observation objects, rather than driving the real code. The repo already has the right pattern for closing this gap (test_driver_uses_generated_document_deletes_it_and_preserves_global_rng builds a FakeNative object and monkeypatches _native_binding to unit-test construct() without a real CybORG install); it just wasn't extended to step()/_project_turn() or to construct_execution()'s agent-resolution failure paths.
Blocking findings: 1
Finding 1 — class (6 instances)
ID:F1
Title: (no title)
Decision: fix
Rationale: Addressed by next cycle
Instances:
src/raes_adapters/cyborg/driver.py: SourceInstalledCyborgDriver.step (never invoked by any test)
src/raes_adapters/cyborg/driver.py: SourceInstalledCyborgDriver._native_blue_action (never invoked by any test)
src/raes_adapters/cyborg/driver.py: SourceInstalledCyborgDriver._project_turn (never invoked by any test)
src/raes_adapters/cyborg/driver.py: module-level _project_native_action mapping table (never invoked by any test)
src/raes_adapters/cyborg/driver.py: SourceInstalledCyborgDriver.construct_execution red-agent import/binding branch, including both RuntimeError paths (never invoked by any test)
src/raes_adapters/cyborg/orchestrator.py: CyborgOrchestrator._start_transaction's 'cyborg-backend.orchestration.session-construction-failed' branch (configure_execution() returning False is never triggered in tests/test_cyborg_execution.py because FakeExecutionDriver/BlockingExecutionDriver.construct_execution always succeeds)
CAGE-2 workflows now execute one serialized aggregate native turn per admitted blue action, stop at the declared logical-step or source terminal boundary, project only bounded portable red/green/blue records, and reset all participants with the workflow and logical clock as one coordinated session.
Implemented CAGE-2 logical step control through published RAES provisioner, orchestrator, participant, and time contracts; canonical verification, all 188 tests, CI, CodeQL, and SonarCloud pass.
Files changed
Added:
docs/decisions/cyborg-step-control-guardrails.md
src/raes_adapters/cyborg/orchestrator.py
src/raes_adapters/cyborg/participant_runtime.py
tests/test_cyborg_execution.py
Modified:
README.md
mkdocs.yml
pyproject.toml
src/raes_adapters/cyborg/__init__.py
src/raes_adapters/cyborg/driver.py
src/raes_adapters/cyborg/manifest.py
src/raes_adapters/cyborg/provisioner.py
src/raes_adapters/cyborg/target.py
tests/test_cyborg_provisioner.py
Reviews
codex: One pre-push production-readiness cycle completed; shared transaction ownership, realized-target closure, and logical-clock reset findings were fixed and verified.
test-quality: One pre-push test-quality cycle completed; concrete source-driver construction, action-binding, projection, RNG, and failure-path coverage was added and verified.
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 #16). 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.
CAGE-2 workflows can now execute one serialized aggregate native turn per admitted blue action, stop at the declared logical-step or source terminal boundary, project only bounded portable red/green/blue records, and reset all participants with the workflow and logical clock as one coordinated session.
Implemented CAGE-2 logical step control through published RAES provisioner, orchestrator, participant, and time contracts; canonical verification, all 188 tests, CI, CodeQL, and SonarCloud passed before merge.
Files changed
Added:
docs/decisions/cyborg-step-control-guardrails.md
src/raes_adapters/cyborg/orchestrator.py
src/raes_adapters/cyborg/participant_runtime.py
tests/test_cyborg_execution.py
Modified:
README.md
mkdocs.yml
pyproject.toml
src/raes_adapters/cyborg/__init__.py
src/raes_adapters/cyborg/driver.py
src/raes_adapters/cyborg/manifest.py
src/raes_adapters/cyborg/provisioner.py
src/raes_adapters/cyborg/target.py
tests/test_cyborg_provisioner.py
Reviews
codex: One pre-push production-readiness cycle completed; shared transaction ownership, realized-target closure, and logical-clock reset findings were fixed and verified.
test-quality: One pre-push test-quality cycle completed; concrete source-driver construction, action-binding, projection, RNG, and failure-path coverage was added and verified.
Traceability reconciliation
IMPLEMENTS / TESTS / DOCUMENTS added: 0
Links updated: 0
Stale links removed: 0
Issue #16 has no canonical in-scope Requirements section. Post-merge reverse lookups found no existing requirement links on the issue or any touched artifact, so reconciliation required no link changes.
Activity
Brad-Edwards commentedon Jul 31, 2026
🛠️ Picked up by /implement - driver codex, branch
16-logical-step-control, 2026-07-31T14:49:48.256Z.Brad-Edwards commentedon Jul 31, 2026
gc workflow phase recorded:
preflight(issue #16). 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 31, 2026
gc workflow phase recorded:
plan(issue #16). 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.Implementation plan
tests/test_cyborg_execution.pyfor the issue contract: exact action/argument admission with zero native effects on rejection; one aggregate driver call and one typed terminal result per valid action; pinned Blue→Green→Red participant ordering; B-line, Meander, Sleep, and green occurrences; logical trial cutoffs at 30/50/100; native-terminal handling; reset/quarantine behavior; controlled-seed disclosures; and hostile native values proving no tuple, action id, reward, hidden truth, log, repr, or exception text crosses the boundary.CyborgDriver/provisioner ownership seam so construction, policy-bound reconstruction, reset, step, quarantine, stop, and cleanup share one re-entrant mutation lock and one active native handle. Keep lazy fixed imports for the pinned CybORG source, closed exact action-address dispatch, normalized argument conversion, caller random-state restoration, and bounded failures.CyborgOrchestratorto admit one published RAES episode-control contract carried by the compiled workflow operation, reconcile workflow status/history through published RAES shapes, bind one initialized logical clock and the selected red variant, and prevent participant execution until an admitted run exists. It will not expose a public step method or advertise an Evaluator.CyborgParticipantRuntimeonBaseParticipantRuntime. Reuse RAES episode/action/history commit behavior, require the validated normalized selection, trigger at most one aggregate turn for the admitted external blue action, project internal red/green occurrences as distinct joined participant events, commit mapped shared-state/joint-action/time records, and advance the RAES clock exactly once only after complete projection validation. Invalid post-step output quarantines the native session; pre-effect failures preserve both snapshot and driver-call count.manifest.py,target.py, and__init__.pywith only the orchestrator/participant/time capabilities and published contract IDs actually exercised. Preserve the single distribution, closed target config, provisioning realization envelope, and absent evaluator. Update README/API documentation only where the new public target capability needs discovery; retain the preflight guardrail note and MkDocs navigation.ACES_REQUIREMENT_UID=REP-004, then run the managed completion gate and canonicaluv tool run --from 'nox[uv]==2026.4.10' nox -f noxfile.py -s verifygraph. No changelog, new schema/profile/vocabulary, second lockfile, native dependency, or backend-specific SDL change is planned.Whole-repository design checks
CyborgProvisioner,SourceInstalledCyborgDriver,BaseParticipantRuntime,ReferenceTimeRuntime, base clock/projection/redaction helpers, manifest/target factories, and the existing nox/test patterns.Brad-Edwards commentedon Jul 31, 2026
gc_codex_review — cycle 1 of 1 (pre-push) on issue #16 (branch
16-logical-step-control)Diff mode: inline — the complete diff was supplied in one prompt
Core review
Verdict:
don't-shipThe intended shape is sound: published RAES orchestration, participant, and time contracts remain the portable boundary, while native action translation and aggregate-turn mechanics stay inside the CybORG module. The production seam is not yet preserved, however. Native lifecycle mutations, portable state construction, and logical-time updates are split across independently locked components, so they are neither serialized nor committed atomically; target-bearing actions also bypass the required realized-target closure. Those are boundary-contract failures rather than local polish, and they affect the obvious next variations—concurrent control-plane calls, additional target-bearing actions, and multi-trial reset.
Blocking findings (3):
src/raes_adapters/cyborg/participant_runtime.py:155The effectful native turn completes under the provisioner's lock, but that lock is released before logical-time advancement, construction of the shared-state/joint-action records, workflow completion, and final runtime validation. A failure in any post-step operation—for example, a missing red/green episode causing
_portable_turnto raise, model construction failing, or the manager rejecting a hand-built record—can restore the baseline portable snapshot while leaving the mutated native handle available. The separate execution-control lock also permits start or reset to interleave with this gap. Use one module-private re-entrant session coordinator for start, turn, and reset, validate the complete candidate portable state before publishing it, and quarantine the native session on every failure after an effectful call.src/raes_adapters/cyborg/driver.py:285validate_action_selectionestablishes only thathostnameis a string; Analyse, Remove, and Restore then forward that value directly to native constructors. A normalized but unrealizable hostname therefore triggers an aggregate native turn—including red and green effects—instead of being rejected before the driver call. Resolve each portable target through the active scenario realization and admit only an exact mapped native hostname before constructing any target-bearing action.src/raes_adapters/cyborg/participant_runtime.py:126After resetting all participant episodes and the native aggregate, this path only clears the source-terminal latch. It never applies the declared
new_segment_zerotime reset. After a trial reachesmax_steps, a successful reset therefore leaves the clock at the limit and the next action is immediately rejected astrial-complete. Include the RAES time transition in the same coordinated reset transaction and test reset followed by a successful first turn after an exhausted trial.Security review
Verdict:
shipThis change is shaped correctly around the existing RAES runtime seam: validated portable orchestration and participant inputs cross into a module-private CybORG session through fixed action and policy dispatch, while native results are projected through bounded allowlists and failures are returned without native exception text or object representations. It adds no network, authentication, persistence, filesystem-input, shell, or caller-controlled import surface, and the obvious extensions remain additional reviewed bindings rather than dynamic execution paths. I found no concrete, exploitable security issue introduced by this diff.
No blocking findings.
Brad-Edwards commentedon Jul 31, 2026
gc_codex_review pre-push cycle 1 of 1 complete for issue #16 on branch '16-logical-step-control'. 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 31, 2026
Review decision record — codex cycle 1 (issue #16)
Reviewer: codex
Cycle: 1
Architectural read:
Blocking findings: 3
Finding 1 —
class(3 instances)F1src/raes_adapters/cyborg/participant_runtime.py:155src/raes_adapters/cyborg/orchestrator.py:94src/raes_adapters/cyborg/participant_runtime.py:112src/raes_adapters/cyborg/participant_runtime.py:155Finding 2 —
class(3 instances)F2src/raes_adapters/cyborg/driver.py:285validate_action_selectionestablishes only thathostnameis a string; Analyse, Remove, and Restore then forward that value directly to native constructors. A normalized but unrealizable hostname therefore triggers an aggregate native t…src/raes_adapters/cyborg/driver.py:285src/raes_adapters/cyborg/driver.py:289src/raes_adapters/cyborg/driver.py:293Finding 3 —
one-offF3src/raes_adapters/cyborg/participant_runtime.py:126new_segment_zerotime reset. After a trial reachesmax_steps, a successful reset therefor…Brad-Edwards commentedon Jul 31, 2026
gc_test_quality_review cycle 1 of 1 — issue #16
Reviewer: test-quality (claude-sonnet-5 via gc_test_quality_review)
Branch:
16-logical-step-controlCycle: 1 / 1
Findings: 1
Finding 1 — [critical]
src/raes_adapters/cyborg/driver.py:250Problem: SourceInstalledCyborgDriver.step(), _native_blue_action(), _project_turn(), the module-level _project_native_action() mapping table, and construct_execution()'s red-agent import/binding branch are new production code in this diff, but no test in the repository ever calls them. tests/test_cyborg_execution.py uses FakeExecutionDriver, whose step()/construct_execution() hand-build the same _NativeTurnResult tuples the real driver is supposed to derive from CybORG's native Results/Observation objects, instead of exercising the real translation. tests/test_cyborg_provisioner.py's only real-driver test (test_driver_uses_generated_document_deletes_it_and_preserves_global_rng) drives construct(), never construct_execution() or step().
Why it matters: A regression in the real translation — e.g. inverting the observation.data.get("success") == TrinaryEnum.TRUE check, breaking the type(action) is native_type ordering in _project_native_action so a red exploit/impact action is misclassified as sleep, or passing wrong constructor kwargs in _native_blue_action — would not fail a single test, even though this is precisely the boundary the adapter exists to translate correctly for a security-research/RL environment.
Fix: Add driver-level tests that construct a fake native handle (mirroring the existing FakeNative pattern) exposing step()/get_last_action(), and fake CybORG.Shared/.Actions/.Enums modules via monkeypatching driver_module.import_module (as already done in test_source_tree_is_verified_before_any_cyborg_import), so _native_blue_action, _project_turn, and _project_native_action run against real code for each supported action type plus the error branches (non-Results type, non-null error, unmapped native action type). Add a construct_execution test that exercises the unsupported-variant and agent-import-failure RuntimeError branches. Add an orchestrator-level test where FakeExecutionDriver.construct_execution raises, to cover the 'cyborg-backend.orchestration.session-construction-failed' path in CyborgOrchestrator._start_transaction, which is currently unreachable because every fake driver's construct_execution unconditionally succeeds.
Brad-Edwards commentedon Jul 31, 2026
gc_test_quality_review cycle 1 of 1 complete for issue #16 on branch '16-logical-step-control'. 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 31, 2026
Review decision record — test-quality cycle 1 (issue #16)
Reviewer: test-quality
Cycle: 1
Architectural read:
Blocking findings: 1
Finding 1 —
class(6 instances)F1src/raes_adapters/cyborg/driver.py: SourceInstalledCyborgDriver.step (never invoked by any test)src/raes_adapters/cyborg/driver.py: SourceInstalledCyborgDriver._native_blue_action (never invoked by any test)src/raes_adapters/cyborg/driver.py: SourceInstalledCyborgDriver._project_turn (never invoked by any test)src/raes_adapters/cyborg/driver.py: module-level _project_native_action mapping table (never invoked by any test)src/raes_adapters/cyborg/driver.py: SourceInstalledCyborgDriver.construct_execution red-agent import/binding branch, including both RuntimeError paths (never invoked by any test)src/raes_adapters/cyborg/orchestrator.py: CyborgOrchestrator._start_transaction's 'cyborg-backend.orchestration.session-construction-failed' branch (configure_execution() returning False is never triggered in tests/test_cyborg_execution.py because FakeExecutionDriver/BlockingExecutionDriver.construct_execution always succeeds)Brad-Edwards commentedon Jul 31, 2026
Pre-PR base synchronization
refs/remotes/origin/devatc641cab7f0bb0664d54a9e7118686ac6887f49camerged_clean0ba620942aef3f8fb98edf8271afcc5286d7b1088caa2edb25516552b65d927015ba76b9efa60468Brad-Edwards commentedon Jul 31, 2026
Pre-PR base synchronization
refs/remotes/origin/devatc641cab7f0bb0664d54a9e7118686ac6887f49caalready_currentcbc0a2f77243d310238bd9f33ee40ac66df581d6b943f6ddfb15a898ea45188c731c0803b431cddbBrad-Edwards commentedon Jul 31, 2026
Ready for review — issue #16
PR: #61
Plan: #16 (comment)
Outcome
CAGE-2 workflows now execute one serialized aggregate native turn per admitted blue action, stop at the declared logical-step or source terminal boundary, project only bounded portable red/green/blue records, and reset all participants with the workflow and logical clock as one coordinated session.
Implemented CAGE-2 logical step control through published RAES provisioner, orchestrator, participant, and time contracts; canonical verification, all 188 tests, CI, CodeQL, and SonarCloud pass.
Files changed
Added:
docs/decisions/cyborg-step-control-guardrails.mdsrc/raes_adapters/cyborg/orchestrator.pysrc/raes_adapters/cyborg/participant_runtime.pytests/test_cyborg_execution.pyModified:
README.mdmkdocs.ymlpyproject.tomlsrc/raes_adapters/cyborg/__init__.pysrc/raes_adapters/cyborg/driver.pysrc/raes_adapters/cyborg/manifest.pysrc/raes_adapters/cyborg/provisioner.pysrc/raes_adapters/cyborg/target.pytests/test_cyborg_provisioner.pyReviews
Traceability reconciliation
Status
Brad-Edwards commentedon Jul 31, 2026
gc workflow phase recorded:
traceability_reconciled(issue #16). 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 31, 2026
Final report — issue #16 complete
PR: #61
Plan: #16 (comment)
Outcome
CAGE-2 workflows can now execute one serialized aggregate native turn per admitted blue action, stop at the declared logical-step or source terminal boundary, project only bounded portable red/green/blue records, and reset all participants with the workflow and logical clock as one coordinated session.
Implemented CAGE-2 logical step control through published RAES provisioner, orchestrator, participant, and time contracts; canonical verification, all 188 tests, CI, CodeQL, and SonarCloud passed before merge.
Files changed
Added:
docs/decisions/cyborg-step-control-guardrails.mdsrc/raes_adapters/cyborg/orchestrator.pysrc/raes_adapters/cyborg/participant_runtime.pytests/test_cyborg_execution.pyModified:
README.mdmkdocs.ymlpyproject.tomlsrc/raes_adapters/cyborg/__init__.pysrc/raes_adapters/cyborg/driver.pysrc/raes_adapters/cyborg/manifest.pysrc/raes_adapters/cyborg/provisioner.pysrc/raes_adapters/cyborg/target.pytests/test_cyborg_provisioner.pyReviews
Traceability reconciliation
Issue #16 has no canonical in-scope Requirements section. Post-merge reverse lookups found no existing requirement links on the issue or any touched artifact, so reconciliation required no link changes.
Status