Development
The codebase is Odin plus explicit Python child tools. Run checks from the repository root.
Build and test
odin check . -vet
odin test .
/opt/homebrew/bin/python3 -m unittest discover -s tools -p 'test_*.py' -v
shaders/build/main --if-needed
./tools/run_macos_app.sh --build-only
git diff --check
Run odin test . and the app build serially. Both may use the repository's
default output path; overlapping them can replace the test executable with the
application binary before the test runner starts.
Normal GUI startup is:
./tools/run_macos_app.sh
main.odin starts the editor directly. It has no alternate CLI dispatch or
headless worker mode.
The GUI is the only supported user entry point. Project authoring, Case and Job creation, PHITS execution and monitoring, Result opening, Study assessment, and ML operations must be reachable from RAMAL-EBX. Commands documented below are development, debugging, integrity-verification, or child-process boundaries; they are not alternate user workflows. When a real workflow fails, reproduce and repair it through the GUI before accepting a command-line workaround.
Native macOS accessibility and input
RAMAL's visible ImGui buttons are registered each frame by ui_button and its
semantic wrappers. On macOS, macos_accessibility.odin mirrors those live
items as retained NSAccessibilityElement children of the SDL content view;
it does not create an overlay or a second UI model. Accessibility frames are
updated in the content-view coordinate system, and stale elements are pruned
when the ImGui item disappears.
The main loop owns a Cocoa autorelease pool for each frame, alongside Odin's temporary allocator reset. SDL's internal pools do not cover the application's native accessibility calls. Without this scope, temporary Cocoa objects can accumulate while the editor is idle.
On 2026-09-09, the long-running Design process had a 7.7 GiB physical footprint
and approximately 73 million default-zone allocations (7.3 GiB allocated).
After adding the frame pool and reopening the same saved Design, native checks
showed about 37,000–50,000 allocations and a 366–375 MiB sampled footprint
over a roughly two-minute comparison, ending at 369 MiB. This is a short regression check, not an
overnight endurance result. Use vmmap -summary <pid> for footprint and heap
counts; RSS alone misses the compressed/swapped memory in this failure.
An Accessibility API press queues the registered ImGui item ID. The matching button wrapper consumes that ID on the next frame, so the existing production callback remains the only action path. Disabled ImGui controls are exposed as disabled and cannot be activated through AX. The SDL/ImGui event bridge also forwards the mouse-button event's own coordinates before backend processing so a native or injected click does not require a preceding mouse-motion event.
Runtime and local files
The active PHITS installation is external at /Users/faiz/phits; do not copy
or commit it. Install requirements.txt into the Python environment used to
launch the GUI. Research tasks invoke python3 directly, so missing or
incompatible dependencies fail in the visible task log. Case evidence calls
from Odin use the system Python for the strict runner and remote tools.
Preserve these local paths:
projects/— user Projects and scientific evidence;ramalebx.sublime-projectandramalebx.sublime-workspace— Sublime Text project files;resources/fonts/default.ttf— runtime font;shaders/compiled/— shader files loaded by the renderer; andshaders/build/bin/andshaders/build/lib/— local shader compiler files.
Ignored files are not automatically disposable. Do not use git clean -fdX as
a general cleanup command because it can remove Project workspaces and runtime
assets. Routine disposable files are .DS_Store, *.dSYM/, and empty
temporary directories.
Case runner checks
The strict runner in tools/run_case_attempt.py supports:
python3 tools/run_case_attempt.py --verify-succeeded-attempt <attempt-directory>
python3 tools/run_case_attempt.py --resolve-result-roles <attempt-directory>
Preparation requires the Attempt ID, source input, immutable Case document,
content-addressed Case scientific specification, Attempt root, PHITS launcher,
multiplier file, all four result roles, and explicit maxcas, maxbch, and
rseed controls. The runner validates the nested scientific schema, snapshots
both Case records, and inventories and hashes every decisive file.
Remote PHITS checks
tools/remote_phits.py is the GUI child-process transport boundary, not a
second user-facing runner. It loads the strict profiles document from
~/Library/Application Support/RAMAL-EBX/remote-profiles.json, stages a
prepared Attempt atomically, watches the detached worker, and transfers only a
terminal Attempt that passes run_case_attempt.py verification. Keep the
profile outside the repository. Optional non-default ssh_port and
ssh_host_key_alias values are validated and applied consistently to SSH/SCP.
Use a second profile for a temporary forward tunnel; do not overwrite the
direct profile or disable host-key checking.
Focused transport coverage is in tools/test_remote_phits.py. It covers
profile validation, -envnone ordering, containment, transfer replacement,
batch progress, cancellation/recovery state, and manifest compatibility. Do
not use the transport commands as an end-user shell workflow or launch a long
cluster run as a test; exercise the Simulate GUI and inspect only filtered
bat[...] progress there. Verbose SSH/MPI/PHITS output belongs in Diagnostics.
Research tools
/opt/homebrew/bin/python3 -m pip install -r requirements.txt
python3 tools/build_dataset.py --project <project.ramal-project> --spec <dataset-spec.json>
python3 tools/model_pipeline.py train --dataset <dataset.ramal-dataset> --model-id <id> --display-name <name>
python3 tools/model_pipeline.py evaluate-final --model <model.ramal-model>
python3 tools/model_pipeline.py predict --model <model.ramal-model> --spec <prediction-spec.json>
python3 tools/model_pipeline.py verify-prediction --prediction <prediction.ramal-prediction> --result <result.ramal-result>
The GUI starts these as visible asynchronous ML_Task processes. Study
execution stays in Odin orchestration and reuses the sole Case runner.
Generated codebase tutorial
tools/generate_codebase_tutorial.sh runs the pinned PocketFlow Codebase
Knowledge pipeline against the local source. Its only provider change is the
LLM boundary: each PocketFlow prompt is passed to codex exec, which reuses
the developer's saved ChatGPT sign-in. No API key is required.
View the current tutorial locally without making model calls:
./tools/view_knowledge_base.sh
The site opens at http://127.0.0.1:8001/. Set RAMAL_DOCS_PORT to use a
different local port.
After meaningful code changes, regenerate through PocketFlow and then serve the validated site:
./tools/view_knowledge_base.sh --update-software
The generated Markdown is written to
docs/gen_ai/software/codebase-tutorial/. PocketFlow's prompt cache is retained
in its ignored local checkout, so unchanged work can be reused on later updates.
Regenerate only the Paper 1 research dashboard after its source records change:
./tools/view_knowledge_base.sh --update-paper1
Source boundaries
- HLSL source is under
shaders/src/; compiled shader output is undershaders/compiled/. shader_dev.odinowns development freshness checks; renderer code loads compiled outputs.storage.odinandproject_storage.odinown write/path/hash primitives.Scene_Stateis an in-memory shared shape for an editable Design and a reconstructed immutable Result; it is not a new persisted scene format.- Hard changes are applied to the current source and current files. There is no compatibility reader or second execution path.