feat: Add unified feature extraction - #41
Conversation
- Rename modules to better match their scientific function - Add additional details in docstrings
📝 WalkthroughWalkthroughCentralized SensoryModule framework added and exported; PPOBrain extended to support legacy and unified sensory modes plus LR warmup/decay scheduling; Modular/QModular brains updated to use SENSORY_MODULES; predator gradient direction fix applied; multiple new PPO experiment configs, docs, ablation specs, and tests added. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Config as Config (YAML)
participant Env as Environment
participant PPO as PPOBrain
participant Modules as SENSORY_MODULES
participant Optim as Optimizer
Note over Config,PPO: Experiment loads config (sensory_modules, LR schedule)
Config->>Modules: specify sensory_modules list
Env->>Modules: provide sensory params (gradients, signals)
Modules->>PPO: extract_classical_features(params, modules)
PPO->>PPO: preprocess -> input tensor (2 features/module) or legacy(2)
PPO->>Env: step(action)
Env->>Env: compute separated gradients (food, predator) with fixed predator dir
Env->>PPO: observation (including gradients)
PPO->>Optim: during episode end -> _update_learning_rate(current_episode)
Optim-->>PPO: optimizer.lr updated
Note over PPO,Optim: iterative training with warmup -> decay schedules
Estimated code review effort🎯 4 (Complex) | ⏱️ ~70 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
packages/quantum-nematode/quantumnematode/brain/arch/ppo.py (1)
269-269: Remove unusednoqadirective.Static analysis indicates that
PLR0913andPLR0915are non-enabled rules, making this directive unnecessary.🔎 Proposed fix
- def __init__( # noqa: PLR0913, PLR0915 + def __init__(packages/quantum-nematode/quantumnematode/brain/modules.py (1)
321-331: Consider documenting thatto_classicalomits the binary field.The
to_classical()method returns only[strength, angle], omitting thebinaryfield fromCoreFeatures. For modules like mechanosensation that encode meaningful data in all three fields, this could result in information loss. If this is intentional (e.g., classical networks use a different encoding), consider adding a brief note in the docstring.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (21)
artifacts/experiments/20260102_052412/20260102_052412.jsonartifacts/experiments/20260102_052412/ppo_stationary_predators_sensory_small_tuned.ymlartifacts/experiments/20260102_093709/20260102_093709.jsonartifacts/experiments/20260102_093709/ppo_pursuit_predators_sensory_small.ymlconfigs/examples/ppo_pursuit_predators_sensory_small.ymlconfigs/examples/ppo_stationary_predators_sensory_small.ymldocs/experiments/README.mddocs/experiments/logbooks/006-unified-sensory-modules.mdopenspec/changes/add-ablation-toolkit/proposal.mdopenspec/changes/add-ablation-toolkit/specs/ablation-analysis/spec.mdopenspec/changes/add-ablation-toolkit/tasks.mdopenspec/changes/add-multi-sensory-environment/tasks.mdpackages/quantum-nematode/quantumnematode/brain/__init__.pypackages/quantum-nematode/quantumnematode/brain/arch/modular.pypackages/quantum-nematode/quantumnematode/brain/arch/ppo.pypackages/quantum-nematode/quantumnematode/brain/arch/qmodular.pypackages/quantum-nematode/quantumnematode/brain/modules.pypackages/quantum-nematode/quantumnematode/env/env.pypackages/quantum-nematode/tests/quantumnematode_tests/brain/arch/test_ppo.pypackages/quantum-nematode/tests/quantumnematode_tests/brain/test_modules.pypackages/quantum-nematode/tests/quantumnematode_tests/brain/test_ppo_features.py
🧰 Additional context used
📓 Path-based instructions (3)
openspec/changes/*/tasks.md
📄 CodeRabbit inference engine (openspec/AGENTS.md)
Create tasks.md with numbered implementation sections and checkbox-style task lists (- [ ] format) to track completion before confirming work is finished
Files:
openspec/changes/add-ablation-toolkit/tasks.mdopenspec/changes/add-multi-sensory-environment/tasks.md
openspec/changes/*/proposal.md
📄 CodeRabbit inference engine (openspec/AGENTS.md)
Write proposal.md with three sections: Why (1-2 sentences on problem/opportunity), What Changes (bulleted list with BREAKING markers for breaking changes), and Impact (affected specs and code)
Files:
openspec/changes/add-ablation-toolkit/proposal.md
openspec/changes/*/specs/**/*.md
📄 CodeRabbit inference engine (openspec/AGENTS.md)
openspec/changes/*/specs/**/*.md: Use ## ADDED|MODIFIED|REMOVED|RENAMED Requirements headers in delta specs, with each requirement containing at least one scenario using #### Scenario: format (4 hashtags, not bullets or bold)
Use SHALL/MUST for normative requirements in spec deltas; avoid should/may unless intentionally marking non-normative requirements
When using MODIFIED Requirements, paste the complete existing requirement (header + all scenarios) from openspec/specs//spec.md and edit to reflect new behavior, ensuring the header text matches exactly (whitespace-insensitive)
Format scenarios with bullet points for WHEN/THEN conditions using WHEN and THEN bold markers, not prose or alternative structures
Files:
openspec/changes/add-ablation-toolkit/specs/ablation-analysis/spec.md
🧠 Learnings (7)
📓 Common learnings
Learnt from: chrisjz
Repo: SyntheticBrains/nematode PR: 15
File: packages/quantum-nematode/quantumnematode/brain/arch/qmodular.py:744-750
Timestamp: 2025-12-13T10:34:16.900Z
Learning: In QModularBrain (packages/quantum-nematode/quantumnematode/brain/arch/qmodular.py), the prepare_episode() and post_process_episode() hooks are intentionally kept as no-ops until the feature to save only successful episodes is implemented for all brain architectures (currently only modular brain has it).
📚 Learning: 2025-12-30T13:55:00.474Z
Learnt from: chrisjz
Repo: SyntheticBrains/nematode PR: 36
File: openspec/changes/add-multi-sensory-environment/tasks.md:229-229
Timestamp: 2025-12-30T13:55:00.474Z
Learning: In Markdown review, if the repository uses mdformat to format Markdown, do not flag backslash escapes that mdformat may automatically insert (e.g., \< for <). Treat such escapes as intentional formatter-enforced formatting, not unnecessary markup. This applies to all Markdown files in the repo (e.g., openspec/changes/add-multi-sensory-environment/tasks.md and similar). If unsure, verify formatter configuration (mdformat rules) before marking as unnecessary.
Applied to files:
openspec/changes/add-ablation-toolkit/tasks.mdopenspec/changes/add-ablation-toolkit/proposal.mddocs/experiments/logbooks/006-unified-sensory-modules.mddocs/experiments/README.mdopenspec/changes/add-multi-sensory-environment/tasks.mdopenspec/changes/add-ablation-toolkit/specs/ablation-analysis/spec.md
📚 Learning: 2026-01-01T07:04:38.772Z
Learnt from: chrisjz
Repo: SyntheticBrains/nematode PR: 40
File: configs/examples/modular_predators_small_validate.yml:55-55
Timestamp: 2026-01-01T07:04:38.772Z
Learning: Maintain backward-compatible defaults in YAML configs (e.g., RewardConfig.penalty_boundary_collision defaults to 0.0). When overriding in examples, show explicit values (e.g., 0.02) and ensure the spec documents this two-tier setup so maintainers understand the relationship between default and overridden values.
Applied to files:
configs/examples/ppo_pursuit_predators_sensory_small.ymlconfigs/examples/ppo_stationary_predators_sensory_small.yml
📚 Learning: 2025-12-30T14:07:46.289Z
Learnt from: CR
Repo: SyntheticBrains/nematode PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-12-30T14:07:46.289Z
Learning: Applies to openspec/changes/*/proposal.md : Write proposal.md with three sections: Why (1-2 sentences on problem/opportunity), What Changes (bulleted list with **BREAKING** markers for breaking changes), and Impact (affected specs and code)
Applied to files:
openspec/changes/add-ablation-toolkit/proposal.md
📚 Learning: 2025-12-13T10:34:16.900Z
Learnt from: chrisjz
Repo: SyntheticBrains/nematode PR: 15
File: packages/quantum-nematode/quantumnematode/brain/arch/qmodular.py:744-750
Timestamp: 2025-12-13T10:34:16.900Z
Learning: In QModularBrain (packages/quantum-nematode/quantumnematode/brain/arch/qmodular.py), the prepare_episode() and post_process_episode() hooks are intentionally kept as no-ops until the feature to save only successful episodes is implemented for all brain architectures (currently only modular brain has it).
Applied to files:
packages/quantum-nematode/quantumnematode/brain/arch/modular.pypackages/quantum-nematode/tests/quantumnematode_tests/brain/test_ppo_features.pypackages/quantum-nematode/quantumnematode/brain/modules.pyopenspec/changes/add-multi-sensory-environment/tasks.mdpackages/quantum-nematode/tests/quantumnematode_tests/brain/test_modules.pypackages/quantum-nematode/quantumnematode/brain/arch/qmodular.pypackages/quantum-nematode/quantumnematode/brain/arch/ppo.py
📚 Learning: 2025-12-30T14:07:46.289Z
Learnt from: CR
Repo: SyntheticBrains/nematode PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-12-30T14:07:46.289Z
Learning: Applies to openspec/changes/*/specs/**/*.md : When using MODIFIED Requirements, paste the complete existing requirement (header + all scenarios) from openspec/specs/<capability>/spec.md and edit to reflect new behavior, ensuring the header text matches exactly (whitespace-insensitive)
Applied to files:
openspec/changes/add-ablation-toolkit/specs/ablation-analysis/spec.md
📚 Learning: 2025-12-30T14:07:46.289Z
Learnt from: CR
Repo: SyntheticBrains/nematode PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-12-30T14:07:46.289Z
Learning: Use ADDED for new standalone capabilities or sub-capabilities orthogonal to existing requirements; use MODIFIED when changing behavior, scope, or acceptance criteria of an existing requirement; use RENAMED when only the requirement name changes; combine RENAMED and MODIFIED when renaming with behavior changes
Applied to files:
openspec/changes/add-ablation-toolkit/specs/ablation-analysis/spec.md
🧬 Code graph analysis (6)
packages/quantum-nematode/tests/quantumnematode_tests/brain/arch/test_ppo.py (2)
packages/quantum-nematode/quantumnematode/brain/arch/ppo.py (4)
PPOBrainConfig(71-129)PPOBrain(261-797)_get_current_lr(467-494)_update_learning_rate(496-503)packages/quantum-nematode/quantumnematode/brain/arch/dtypes.py (1)
DeviceType(20-34)
packages/quantum-nematode/quantumnematode/brain/arch/modular.py (1)
packages/quantum-nematode/quantumnematode/brain/modules.py (1)
to_quantum_dict(308-319)
packages/quantum-nematode/quantumnematode/brain/modules.py (3)
packages/quantum-nematode/quantumnematode/brain/actions.py (1)
Action(8-16)packages/quantum-nematode/quantumnematode/env/env.py (1)
Direction(50-57)packages/quantum-nematode/quantumnematode/brain/arch/_brain.py (1)
BrainParams(126-213)
packages/quantum-nematode/tests/quantumnematode_tests/brain/test_modules.py (3)
packages/quantum-nematode/quantumnematode/brain/modules.py (6)
CoreFeatures(53-64)ModuleName(72-94)count_total_qubits(518-531)to_quantum(262-306)to_classical(321-331)to_quantum_dict(308-319)packages/quantum-nematode/quantumnematode/env/env.py (1)
Direction(50-57)packages/quantum-nematode/quantumnematode/brain/arch/_brain.py (1)
BrainParams(126-213)
packages/quantum-nematode/quantumnematode/brain/__init__.py (1)
packages/quantum-nematode/quantumnematode/brain/modules.py (3)
ModuleName(72-94)extract_classical_features(442-486)get_classical_feature_dimension(489-504)
packages/quantum-nematode/quantumnematode/brain/arch/qmodular.py (1)
packages/quantum-nematode/quantumnematode/brain/modules.py (1)
to_quantum_dict(308-319)
🪛 Ruff (0.14.10)
packages/quantum-nematode/quantumnematode/brain/arch/ppo.py
269-269: Unused noqa directive (non-enabled: PLR0913, PLR0915)
Remove unused noqa directive
(RUF100)
🔇 Additional comments (46)
openspec/changes/add-ablation-toolkit/specs/ablation-analysis/spec.md (1)
1-235: LGTM! Spec follows all formatting guidelines.The spec delta correctly uses:
## ADDED Requirementsheader### Requirement:headers for each requirement#### Scenario:format (4 hashtags) for all scenarios- GIVEN/WHEN/THEN/AND bullet points
- SHALL/MUST for normative requirements
The new ablation requirements (PPOBrain Sensory Module Ablation, Gradient Mode Ablation, Feature Normalization Ablation) are well-structured and provide clear acceptance criteria.
packages/quantum-nematode/quantumnematode/env/env.py (1)
1320-1355: Predator direction inversion is correctly implemented.The changes introduce explicit raw magnitude computation and normalize predator direction semantics:
- Raw magnitudes (lines 1321, 1324): Computed before normalization, allowing separate processing.
- Predator direction inversion (line 1330): Negating both components converts the repulsive gradient direction (away from predator) to a threat-indicator direction (toward predator), giving consistent semantics where:
food_direction: points toward food (approach this direction)predator_direction: points toward predator (avoid this direction)- Magnitude normalization (lines 1338-1339):
tanhscaling ensures bounded [0,1] range, matching combined gradient scaling and providing proper inputs for sensory modules.The implementation correctly separates magnitude computation from direction semantics, enabling unified feature extraction.
openspec/changes/add-ablation-toolkit/tasks.md (3)
97-166: LGTM! New ablation sections follow task format guidelines.Sections 4-6 (PPOBrain Sensory Configuration, Gradient Mode, and Feature Normalization Ablation) correctly use:
- Numbered implementation sections
- [ ]checkbox-style task lists- Clear subsection structure
- Validation sections for each major component
The expansion provides systematic coverage of PPOBrain-specific ablation capabilities.
168-295: Section renumbering is correct and consistent.Sections 7-10 (formerly 4-7) maintain:
- Proper numbering sequence
- Original task structure and content
- Checkbox format throughout
- Code examples unchanged (section 7.1)
The renumbering accommodates the new sections 4-6 without disrupting existing task definitions.
300-343: Dependency diagram and success criteria correctly updated.Dependency diagram (lines 300-328):
- Clearly shows PPOBrain Ablation branch splitting into sections 4, 5, 6
- Correctly indicates parallel execution capability after framework completion
- Notes dependency on PPOBrain infrastructure (section 3)
Success criteria (lines 336-340):
- Comprehensive coverage of new ablation modes (sensory, gradient, normalization)
- Maintains seed-controlled reproducibility requirement
Both sections accurately reflect the expanded ablation scope.
configs/examples/ppo_stationary_predators_sensory_small.yml (1)
1-95: Configuration is well-structured and consistent.Strengths:
- Header comments (lines 1-14) clearly document differences from legacy config
sensory_modules(lines 38-41) correctly aligned withuse_separated_gradients: true(line 70)- Stationary predator configuration (lines 80-89) is consistent:
speed: 0.0andmovement_pattern: stationaryboth enforce stationary behaviorkill_radius: 0withdamage_radius: 2enables health-based gameplay- Explicit reward/penalty values (lines 45-58) follow backward-compatibility guidance
Minor observation:
Lines 83-84 have redundant stationary specification (speed: 0.0andmovement_pattern: stationary). While clear, consider if one is sufficient or if both provide useful validation.Based on learnings, explicit config values in examples are appropriate.
packages/quantum-nematode/quantumnematode/brain/arch/qmodular.py (3)
41-46: LGTM: Import updated for centralized sensory module registry.The addition of
SENSORY_MODULESand removal ofRotationAxisandextract_features_for_modulecorrectly reflects the transition to the unified sensory module architecture.
296-298: LGTM: Safe string-key access for quantum gate parameters.The change from
RotationAxisenum to direct string keys"rx","ry","rz"with.get()defaults aligns with theto_quantum_dict()interface documented inmodules.py(lines 307-318) and provides safe fallback to0.0if keys are missing.
368-370: No issue found — all ModuleName enum values are registered in SENSORY_MODULES.The direct dictionary access
SENSORY_MODULES[module]is safe. All 12 ModuleName enum members (PROPRIOCEPTION, CHEMOTAXIS, FOOD_CHEMOTAXIS, NOCICEPTION, MECHANOSENSATION, THERMOTAXIS, AEROTAXIS, VISION, ACTION, APPETITIVE, AVERSIVE, OXYGEN) have entries in the SENSORY_MODULES registry—either as direct registrations or as aliases. Sinceself.modulesis typed asdict[ModuleName, list[int]], its keys can only be ModuleName enum values, guaranteeing all keys exist in the registry.Likely an incorrect or invalid review comment.
packages/quantum-nematode/quantumnematode/brain/__init__.py (1)
6-21: LGTM: Public API expanded for unified sensory module architecture.The new exports (
SENSORY_MODULES,ModuleName,extract_classical_features,get_classical_feature_dimension) provide a clean public interface for the centralized sensory module registry and classical feature extraction, as documented in the relevant code snippets frommodules.py.docs/experiments/logbooks/006-unified-sensory-modules.md (4)
1-58: Excellent experiment documentation structure.The document provides clear motivation, hypothesis, and problem definition. The explanation of why 4-feature credit assignment is harder than 2-feature (lines 40-48, 289-312) effectively frames the experimental challenge.
59-122: LGTM: Implementation changes well-documented with code examples.The architecture evolution table and key implementation changes provide clear technical detail. The code snippets for gradient normalization (line 73), predator direction fix (line 79), and LR scheduling (lines 91-94) enable reproducibility.
123-313: Strong experimental methodology and analysis.The systematic ablation studies (lines 154-203) demonstrate rigorous experimentation. The clear metric definitions (lines 127-131), session ID traceability, and "what worked/didn't work" tables (lines 266-287) make this excellent scientific documentation.
The pursuit predator findings (lines 252-260) appropriately identify that scenario-specific reward tuning is required, with remaining performance gap attributed to temporal credit assignment.
314-384: Comprehensive conclusions with actionable insights.The 7 key findings (lines 315-330) succinctly capture experiment outcomes. The future work section (lines 340-351) appropriately defers LSTM complexity while acknowledging the temporal credit assignment gap. Data references (lines 353-383) provide full traceability for reproducibility.
artifacts/experiments/20260102_052412/ppo_stationary_predators_sensory_small_tuned.yml (3)
21-46: LGTM: Brain configuration matches documented experiment parameters.The PPO configuration correctly implements the LR warmup/decay schedule (lines 39-42) and unified sensory modules (lines 43-45) as documented in the experiment logbook. The doubled network capacity (128 hidden dims, 512 buffer) aligns with the findings that larger networks help with 4-feature credit assignment.
49-63: LGTM: Reward shaping aligns with experimental findings.The reward configuration (distance_scale: 0.3, predator_proximity: 0.3, health_damage: 1.5) implements the tuning identified as critical in the experiment analysis. These values balance food/predator signal strength to improve credit assignment with separated gradients.
69-99: LGTM: Environment configuration properly enables separated gradients.The
use_separated_gradients: true(line 74) is correctly set to enable the unified sensory module architecture. The stationary predator setup (speed: 0.0, line 87) matches the experiment scenario, and the health/damage parameters are consistent with the documented tuning.packages/quantum-nematode/tests/quantumnematode_tests/brain/test_ppo_features.py (4)
11-63: LGTM: Comprehensive legacy mode backward compatibility tests.The tests verify that PPOBrain maintains backward compatibility with the legacy 2-feature preprocessing mode, including default input_dim (line 19), explicit overrides (line 27), correct output shapes (lines 43-44), and value correctness for aligned gradients (lines 60-62).
65-163: Excellent coverage of unified sensory mode semantics.The tests thoroughly verify input_dim auto-computation (lines 68-98), module-specific feature extraction (lines 118-137), and critically test semantic range preservation (lines 138-162). The assertion that
strength = 0.0means "no signal" (line 152) correctly validates the classical feature semantics documented in the modules implementation.
165-204: LGTM: Integration tests verify end-to-end functionality.The tests confirm that
run_brainproduces valid actions in both unified mode (lines 168-187) and legacy mode (lines 189-203), verifying action structure and probability ranges without overspecifying expected behavior.
206-275: LGTM: Thorough coverage of scientific module names and multi-sensory configurations.The tests verify all major scientific module names (FOOD_CHEMOTAXIS, NOCICEPTION, MECHANOSENSATION) and their specific feature semantics. The MECHANOSENSATION test (lines 240-260) correctly validates contact-based binary features, and the multi-sensory test (lines 262-275) confirms the architecture scales to 4 modules (8 features).
openspec/changes/add-ablation-toolkit/proposal.md (1)
1-106: LGTM! Proposal structure aligns with guidelines.The proposal correctly follows the required three-section format (Why, What Changes, Impact) and the expanded ablation study scope (sensory configuration, gradient modes, normalization) is well-organized and comprehensive.
As per coding guidelines, proposal.md should contain three sections with appropriate structure, which this document maintains.
packages/quantum-nematode/quantumnematode/brain/arch/modular.py (5)
92-92: LGTM! Centralized sensory module registry.The import of
SENSORY_MODULESenables unified feature extraction across quantum brain architectures.
414-419: LGTM! Consistent refactoring to string-based feature keys.The switch from
RotationAxisenum to string keys ("rx","ry","rz") and centralizedSENSORY_MODULES[module].to_quantum_dict(params)simplifies feature encoding and aligns with the unified sensory module architecture.
537-538: LGTM! Consistent use of centralized feature extraction.The refactoring to
SENSORY_MODULES[module].to_quantum_dict(params)is applied consistently inrun_brain, maintaining alignment with the unified sensory module pattern.
1180-1182: LGTM! Trajectory gradient computation updated.The
trajectory_parameter_shift_gradientsmethod correctly uses the new centralized feature extraction pathway.
1316-1319: LGTM! Parameter-shift gradients updated.The
parameter_shift_gradientsmethod correctly uses the new centralized feature extraction pathway, completing the consistent refactoring across all gradient computation paths.artifacts/experiments/20260102_093709/ppo_pursuit_predators_sensory_small.yml (1)
1-94: LGTM! Well-documented pursuit predator configuration.The configuration properly enables unified sensory modules (
food_chemotaxis,nociception) and LR scheduling with clear documentation of pursuit-specific parameter tuning.configs/examples/ppo_pursuit_predators_sensory_small.yml (1)
1-94: LGTM! Example configuration for pursuit predators.The configuration demonstrates unified sensory module usage and LR scheduling in a pursuit predator scenario. Parameter values are well-documented and align with the experimental artifact version.
Based on learnings, the explicit penalty values (e.g.,
penalty_boundary_collision: 0.02) properly override defaults and are documented for maintainability.openspec/changes/add-multi-sensory-environment/tasks.md (1)
158-234: LGTM! Documentation accurately reflects the unified sensory module implementation.The task list correctly documents the completed SensoryModule architecture, module renaming, brain integration, and PPO training improvements. The checkbox format follows the coding guidelines for tasks.md files.
packages/quantum-nematode/quantumnematode/brain/arch/ppo.py (5)
42-46: LGTM!The imports correctly bring in the new unified sensory module utilities needed for feature extraction.
333-355: LGTM!The LR scheduling configuration is well-structured with sensible defaults (10% of base LR for warmup start and decay end) and clear logging of the schedule phases.
446-465: LGTM!The preprocess method cleanly handles both unified sensory mode and legacy 2-feature mode, maintaining backward compatibility while enabling the new modular architecture.
467-503: LGTM!The LR scheduling implementation correctly handles warmup and decay phases with linear interpolation. The method properly respects the schedule configuration and updates the optimizer appropriately.
760-761: LGTM!The LR update is correctly placed after the episode count increment, ensuring the learning rate is adjusted before the next episode begins.
packages/quantum-nematode/quantumnematode/brain/modules.py (6)
52-64: LGTM!The
CoreFeaturesdataclass provides a clean, architecture-agnostic representation with well-documented semantic ranges for each field.
102-135: LGTM!The relative angle computation correctly normalizes the difference between target and agent directions to [-1, 1], with proper handling of None inputs.
177-182: LGTM!The mechanosensation module appropriately repurposes the CoreFeatures fields for binary contact signals, with clear documentation in the registry describing the unconventional but intentional semantic mapping.
421-428: Note: ACTION module extracts data but returns zeros.The ACTION module has a real
_action_coreextractor but usestransform_type="placeholder", meaningto_quantum()will return zeros regardless of input. This is likely intentional for deferred implementation, but worth verifying this matches the expected behavior.
472-486: LGTM!The function correctly sorts modules for consistent feature ordering and defensively handles missing modules. The approach ensures deterministic output regardless of input order.
489-504: LGTM!Simple and correct utility for computing the expected feature dimension.
packages/quantum-nematode/tests/quantumnematode_tests/brain/test_modules.py (5)
15-30: LGTM!Good coverage of
CoreFeaturesdefault and custom value initialization.
33-80: LGTM!The tests correctly verify the transform logic for both standard and binary types, with appropriate assertions for shape, dtype, and computed values.
83-129: LGTM!Thorough testing of proprioception module across all direction values, correctly verifying the RZ-only encoding.
274-300: LGTM!Good coverage of module name values, legacy aliases, and registry completeness verification.
393-480: LGTM!Excellent test coverage for food_chemotaxis and nociception modules, including quantum transforms, classical semantic ranges, and legacy alias verification.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
packages/quantum-nematode/quantumnematode/brain/arch/ppo.py (1)
72-91: Docstring correctly updated to reference brain/modules.py.The docstring now correctly references
brain/modules.pyfor modular feature extraction (line 80), resolving the previous comment about the outdated reference to brain/features.py.
🧹 Nitpick comments (1)
packages/quantum-nematode/quantumnematode/brain/arch/ppo.py (1)
269-269: Remove unused noqa directive.The static analysis tool reports that
PLR0913andPLR0915are not enabled in the project configuration, making thenoqadirective unnecessary. Consider removing it for cleaner code.🔎 Proposed fix
- def __init__( # noqa: PLR0913, PLR0915 + def __init__(
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
openspec/changes/add-multi-sensory-environment/design.mdopenspec/changes/add-multi-sensory-environment/proposal.mdopenspec/changes/add-thermotaxis-system/tasks.mdpackages/quantum-nematode/quantumnematode/brain/arch/ppo.pypackages/quantum-nematode/quantumnematode/brain/modules.py
✅ Files skipped from review due to trivial changes (1)
- openspec/changes/add-thermotaxis-system/tasks.md
🧰 Additional context used
📓 Path-based instructions (1)
openspec/changes/*/proposal.md
📄 CodeRabbit inference engine (openspec/AGENTS.md)
Write proposal.md with three sections: Why (1-2 sentences on problem/opportunity), What Changes (bulleted list with BREAKING markers for breaking changes), and Impact (affected specs and code)
Files:
openspec/changes/add-multi-sensory-environment/proposal.md
🧠 Learnings (4)
📓 Common learnings
Learnt from: chrisjz
Repo: SyntheticBrains/nematode PR: 15
File: packages/quantum-nematode/quantumnematode/brain/arch/qmodular.py:744-750
Timestamp: 2025-12-13T10:34:16.900Z
Learning: In QModularBrain (packages/quantum-nematode/quantumnematode/brain/arch/qmodular.py), the prepare_episode() and post_process_episode() hooks are intentionally kept as no-ops until the feature to save only successful episodes is implemented for all brain architectures (currently only modular brain has it).
📚 Learning: 2025-12-13T10:34:16.900Z
Learnt from: chrisjz
Repo: SyntheticBrains/nematode PR: 15
File: packages/quantum-nematode/quantumnematode/brain/arch/qmodular.py:744-750
Timestamp: 2025-12-13T10:34:16.900Z
Learning: In QModularBrain (packages/quantum-nematode/quantumnematode/brain/arch/qmodular.py), the prepare_episode() and post_process_episode() hooks are intentionally kept as no-ops until the feature to save only successful episodes is implemented for all brain architectures (currently only modular brain has it).
Applied to files:
openspec/changes/add-multi-sensory-environment/proposal.mdopenspec/changes/add-multi-sensory-environment/design.mdpackages/quantum-nematode/quantumnematode/brain/modules.pypackages/quantum-nematode/quantumnematode/brain/arch/ppo.py
📚 Learning: 2025-12-30T13:55:00.474Z
Learnt from: chrisjz
Repo: SyntheticBrains/nematode PR: 36
File: openspec/changes/add-multi-sensory-environment/tasks.md:229-229
Timestamp: 2025-12-30T13:55:00.474Z
Learning: In Markdown review, if the repository uses mdformat to format Markdown, do not flag backslash escapes that mdformat may automatically insert (e.g., \< for <). Treat such escapes as intentional formatter-enforced formatting, not unnecessary markup. This applies to all Markdown files in the repo (e.g., openspec/changes/add-multi-sensory-environment/tasks.md and similar). If unsure, verify formatter configuration (mdformat rules) before marking as unnecessary.
Applied to files:
openspec/changes/add-multi-sensory-environment/proposal.mdopenspec/changes/add-multi-sensory-environment/design.md
📚 Learning: 2025-12-27T08:02:58.340Z
Learnt from: chrisjz
Repo: SyntheticBrains/nematode PR: 22
File: openspec/changes/add-phase0-foundation-baselines/design.md:64-69
Timestamp: 2025-12-27T08:02:58.340Z
Learning: Design.md files under openspec/changes/ should document architectural or design decisions and rationale, not normative requirements. Do not use SHALL/MUST language in design.md (reserve such language for spec.md files). The strict SHALL/MUST wording should appear only in openspec/changes/*/specs/*/specs.md (spec deltas). Use objective, rationale-focused language in design.md and place any formal requirements in the appropriate spec files.
Applied to files:
openspec/changes/add-multi-sensory-environment/design.md
🧬 Code graph analysis (2)
packages/quantum-nematode/quantumnematode/brain/modules.py (3)
packages/quantum-nematode/quantumnematode/brain/actions.py (1)
Action(8-16)packages/quantum-nematode/quantumnematode/env/env.py (1)
Direction(50-57)packages/quantum-nematode/quantumnematode/brain/arch/_brain.py (1)
BrainParams(126-213)
packages/quantum-nematode/quantumnematode/brain/arch/ppo.py (1)
packages/quantum-nematode/quantumnematode/brain/modules.py (3)
ModuleName(72-94)extract_classical_features(448-492)get_classical_feature_dimension(495-510)
🪛 Ruff (0.14.10)
packages/quantum-nematode/quantumnematode/brain/arch/ppo.py
269-269: Unused noqa directive (non-enabled: PLR0913, PLR0915)
Remove unused noqa directive
(RUF100)
🔇 Additional comments (11)
openspec/changes/add-multi-sensory-environment/design.md (1)
65-65: LGTM! Documentation accurately reflects the module consolidation.The update from
brain/features.pytobrain/modules.pycorrectly reflects the unified feature extraction layer implementation.openspec/changes/add-multi-sensory-environment/proposal.md (1)
66-66: LGTM! Proposal accurately reflects the module path update.The reference update to
brain/modules.pycorrectly documents the location of the unified feature extraction layer.packages/quantum-nematode/quantumnematode/brain/modules.py (5)
1-28: Excellent documentation of the unified sensory module architecture.The module docstring clearly explains the architecture-agnostic feature extraction, the transformation paths for quantum and classical brains, and the C. elegans neuroscience conventions.
160-174: Documentation consistency issue resolved.The nociception semantics are now consistent: both the docstring (line 165) and the registry description (lines 369-370) correctly state that
predator_gradient_directionpoints TOWARD predators, andangle=0means the predator is directly ahead. This resolves the previous documentation inconsistency.
177-182: Unconventional but documented field semantics for mechanosensation.The mechanosensation module repurposes
strengthandanglefields for binary signals (boundary and predator contact), deviating from their typical directional semantics in other modules. While unconventional, this is explicitly documented, and the comment at lines 324-328 explains why the binary field is omitted in classical feature extraction to maintain consistency.
448-492: LGTM! Robust classical feature extraction with deterministic ordering.The function correctly sorts modules for consistent feature ordering and gracefully handles missing modules with zero values. The semantic-preserving ranges ([0,1] for strength, [-1,1] for angle) are well-documented.
344-440: Well-structured sensory module registry with backward compatibility.The registry provides a comprehensive mapping of sensory modules with C. elegans neuron references. The legacy aliases (lines 438-440) ensure backward compatibility for renamed modules (APPETITIVE → FOOD_CHEMOTAXIS, AVERSIVE → NOCICEPTION).
packages/quantum-nematode/quantumnematode/brain/arch/ppo.py (4)
114-129: Well-designed configuration extensions for unified sensory mode and LR scheduling.The new config fields are clearly documented with sensible defaults. The LR scheduling parameters support warmup and decay phases, and the
sensory_modulesfield enables the unified feature extraction mode.
289-314: Solid input dimension computation with clear mode selection.The logic correctly auto-computes
input_dimfromsensory_moduleswhen unified mode is enabled, warns on conflicts, and falls back to legacy 2-feature mode when appropriate. The logging clearly indicates which mode is active.
467-503: LR scheduling implementation is correct and well-integrated.The learning rate scheduling correctly implements warmup (linear increase) and optional decay (linear decrease) phases. The
_update_learning_ratemethod is properly called in_complete_episode_tracking(lines 760-761) to adjust the optimizer's learning rate per episode.
431-465: Clean preprocessing implementation supporting both legacy and unified modes.The method cleanly separates unified sensory mode (lines 446-448) using
extract_classical_featuresfrom the legacy 2-feature mode (lines 450-465), with clear documentation of the semantic ranges for each mode.
…xtraction feat: Add unified feature extraction
Changes:
Addresses #37
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.