Developing aslice

Use python dev.py from the repository root to build, run tests, and launch the simulator. It orchestrates CMake, CTest, LLVM tools, Docker, and the two web projects. The optional Makefile delegates to the same commands; it owns no separate recipes. On Linux, substitute python3 if necessary.

First run

Use Python 3.11 or newer. Native C++ development needs CMake, Ninja, a C++20 compiler, and LLVM 22's formatter and analyzer. Windows uses the existing CLion MinGW preset and dependency bootstrap. Linux dependencies and compiler selection are described in that guide. Docker Desktop must use Linux containers. Node is needed to build the console, not to run packaged assets; the web projects declare their supported Node versions in package.json.

python dev.py doctor
python dev.py build
python dev.py test core
python dev.py check

doctor reports executable locations and missing prerequisites. It does not boot a VM or claim platform qualification. build configures a missing build tree. Use configure after changing configuration, or --build-dir PATH before the command to select another tree. Defaults are build/windows-clion on Windows and build/native elsewhere. Tool overrides use ASLICE_CMAKE, ASLICE_CTEST, ASLICE_CLANG_FORMAT, and ASLICE_CLANG_TIDY.

Which code is real?

The simulator exercises shared implementation through different platform adapters. The normal executable cannot switch to the modeled backend through an environment variable. Fixture installation remains a prototype, even when run on a native OS.

Component Code What runs
Normal CLI src/cli/main.cpp, shared subsystem libraries Native aslice; production-directed implementation with explicitly limited fixture commands.
Modeled executable src/cli/simulator_main.cpp, src/platform/*simulator* aslice-simulator; the shared C++ operations call a modeled filesystem and process/channel boundary.
Model and test orchestration tools/simulator/model.py, server.py, harness.py Python model, seeded faults, trace recording, and replay; never shipped as package-manager implementation.
Compatibility runtime tools/simulator/darwin.py, vm.py, controller.py, guest_agent.py Persistent Linux VM running Darwin binaries through Darling, hosted on Windows or Linux.
Simulator application tools/simulator/application.py, tools/simulator/web/ Launcher, controller connection, terminal, application display, machine controls, and diagnostics.
Developer entrypoint dev.py, tools/dev/ Build/test/quality/package recipes; delegates to the component owners above.
Test peers and probes tests/*driver.cpp, tests/simulator/, tests/simulator/corpus/ Test-only executables and input programs. These are not installer code.

The application display has an optional 2015 iMac-style bezel and silver chin, without a stand. The frame toggle persists independently of the explicit light and dark appearance toggle. Neither presentation changes guest pixels.

CTest labels make the existing source boundaries selectable without renaming Python modules used by recorded workflows. Further source moves should split modeled and runtime tests into separate packages, then move the modeled Python backend under tools/simulator/modeled/ and VM/controller code under tools/simulator/runtime/, retaining compatibility imports. Do these as separate changes with replay checks; changing directories alone does not change evidence.

Tests and quality checks

Command Scope
python dev.py test core Shared C++ and native-adapter tests.
python dev.py test modeled Shared C++ through modeled boundaries, faults, lifecycle, and replay.
python dev.py test runtime VM preparation, controller, and guest-agent tests; unavailable external prerequisites may cause skips.
python dev.py test requirements Requirement inventory and evidence rules.
python dev.py test developer CLI recipes, packaging, preview, and application lifecycle.
python dev.py test all All configured CTests, including archive checks and the developer harness.
python dev.py test web Simulator TypeScript, lint, formatting, and unit tests.
python dev.py test library Documentation library checks.
python dev.py test browser Compiled console browser smoke: appearances, frame, keyboard, narrow layout, content preservation, Console filters, and offline resources.
python dev.py format Rewrite owned C++ formatting.
python dev.py format-check Check formatting without rewriting.
python dev.py tidy Analyze the configured C++ compilation database.
python dev.py check --with-web Configure, build, format-check, tidy, CTest, and both web checks.

Run python dev.py web simulator setup and python dev.py web library setup before their first checks. python dev.py web simulator build builds live and demo assets and checks ES5/CSS compatibility. Development Vite requires a modern browser; compiled assets retain the Safari 9 floor. Automated fallback checks and compatibility-runtime tests do not establish native OS X acceptance.

For browser checks, install tools/dev/browser-requirements.txt with pip and run python -m playwright install chromium. The tests use sample guest data and write screenshots to build/reports/console-browser/.

Commands stop on failure and retain output under build/reports/<run>/. Authentication URLs and machine-command output are not retained by the developer runner. Ctrl+C terminates an active build/test process tree. A successfully launched simulator controller has a separate lifetime.

python dev.py --dry-run check
python dev.py docker check
python dev.py docker check --sanitizers
python dev.py docker application

Docker builds use the tracked Dockerfile, including formatting, analysis, and CTest. Initial builds download dependencies. To reuse a provisioned image, pass --reuse-image --image IMAGE: current source is mounted read-only, networking is disabled, and build writes remain inside the disposable container. Choose an image with the required compiler and cached CMake dependencies. Use python dev.py compare-coverage --image IMAGE to compare the complete decoded native and container requirement reports; matching reports grant no acceptance credit.

docker application uses a disposable Python Linux image, installs the pinned runtime dependencies, and runs the developer and extracted-package tests against current source and compiled assets. This command needs network access for image and Python dependency acquisition; the application browser check separately verifies that UI resources stay offline.

Run the simulator application

python dev.py simulator setup
python dev.py simulator open

Setup installs pinned controller dependencies and builds the console. Launch checks assets, starts or reconnects to the loopback controller, waits for its authenticated readiness response, and opens the application in your browser. Use --no-browser to print the connection URL. Treat that URL as a credential. Readiness failure points to .controller/startup.log; the failed launch attempt reaps only the child it created, never a process identified solely by a saved PID.

The browser is the application window on both Windows and Linux. No native Mac shell is required. Terminal and guest application display take priority over configuration and diagnostics. Closing a window disconnects that client while the controller, machine supervisors, and guest sessions remain available.

The Console pane reads the guest's ASL store with syslog, unified logging with log show, or /var/log/system.log. These are the guest logging sources, separate from host controller diagnostics and terminal stdout. A missing facility is shown as unavailable; Darling does not thereby acquire macOS logging compatibility. New provisioning includes the reader. Existing guests need the updated guest_agent.py and guest_logs.py deployed together under /opt/aslice, followed by a guest agent service restart during a maintenance window.

Console provides the source sidebar, Type/Time/Process/Message table, selected message details, refresh, pause, and Clear view. Queries accept process: (p:), message: (m:), type: (t:), subsystem: (s:), category: (c:), and pid:; quote phrases. Alternatives for one property are ORed, while different properties are ANDed. Reads cover five minutes, retain at most 500 rows, and have time/output bounds. Clear view never erases the guest store. This implements the main Console workflow, not every Console.app capability such as activity tracing or saved searches.

Verify ingestion on the host that owns the machine with:

python dev.py simulator logs-probe --machine-dir STATE/machines/NAME --output build/reports/guest-logs.json

The probe uploads a uniquely named reader into guest Imports, writes a tagged message through logger and syslog, and checks whether a logging store returns it. It uses a temporary administrative session and closes only that session. It does not replace or restart the agent. The report includes source availability, the reader hash, daemon configuration, and whether pre-existing active sessions remain active. Success requires observing the marker; a write command returning zero is insufficient. Run with the same host account that owns the VM credentials.

The current Darling runtime disables com.apple.syslogd in its launch plist, with an upstream comment identifying a crash under darlingserver. It also lacks /usr/bin/log and /var/log/system.log in the observed environment. The Console reader detects the disabled, unloaded ASL daemon and reports it as unavailable. Enabling that daemon and qualifying ingestion require an isolated runtime fix; do not enable its crashing KeepAlive job in a machine with active sessions.

python dev.py simulator machine -- status
python dev.py simulator machine -- start example
python dev.py simulator machine -- stop example
python dev.py simulator shutdown
python dev.py simulator shutdown --stop-machines

Machine names are durable handles. Shell/exec/debug operations return session identifiers; machine session NAME SESSION reconnects. The existing CLI remains available through python -m tools.simulator. See the runtime guide for provisioning, QEMU/SSH prerequisites, supervisor ownership, debugger support, and known compatibility gaps.

shutdown stops the controller and preserves machines. --stop-machines first requests graceful shutdown of each active machine and stops on failure. It does not force-kill machines or stop separate provisioning builders. Stop a builder explicitly with machine provision-stop NAME. Reopening reconnects to existing supervisors. The sample UI needs neither a VM nor controller dependencies:

python dev.py simulator demo
python dev.py simulator model --suite fixture

The demo serves compiled sample data on loopback port 8766; --port overrides it and conflicts are errors. Ctrl+C stops that preview server. The model command requires a C++ build and creates a fresh workspace under build/runs/modeled/. The full modeled suite intentionally reports missing acceptance requirements.

Package and distribute the application

python dev.py simulator package

This produces build/packages/aslice-simulator.zip, containing the Python controller and launcher, compiled UI and bundled third-party notices, Windows and Linux launch scripts, and a checksum inventory. Existing output is refused; select another --output PATH for another package. Dependencies, machines, credentials, and local logs are excluded. After extracting:

python simulator.py setup
python simulator.py
python simulator.py status
python simulator.py shutdown

Setup creates a private .venv and installs pinned Python dependencies. Later launches select that environment automatically. Windows users can launch Simulator.cmd; Linux users can run sh simulator.sh. Python 3.11+ remains a host prerequisite; this is not a frozen binary distribution. Node and the source checkout are unnecessary. QEMU, SSH, and provisioned images are required for VM execution, separately from launching the application.

State and the existing build directory

New application state defaults to %LOCALAPPDATA%/aslice/simulator on Windows and $XDG_STATE_HOME/aslice/simulator (or ~/.local/state/aslice/simulator) on Linux. Set ASLICE_SIMULATOR_HOME or pass --root PATH to open another store. The retained Python CLI still uses its historical default, build/darwin-machines. To reconnect to those machines through the new launcher:

python dev.py simulator open --root build/darwin-machines

Do not treat the current build/ as disposable. It contains experiments, diagnostic evidence, and possibly persistent images alongside generated output. Moving qcow2 images without preserving backing-file references can break them.

python dev.py audit-build

The audit records source candidates, hashes of small source files, protected VM state, evidence categories, and excluded dependency directories. It neither executes nor deletes discovered files. Its classifications are review aids; unclassified files may contain credentials or irreplaceable evidence.

Existing material Durable destination or treatment
Reusable quality/container recipes in build/verification/ Rewritten in tools/dev/; the CLI owns future recipes.
Requirement-report comparison experiment Rewritten as compare-coverage, with explicit image selection and full-report comparison.
Runtime patches and minimal input programs Maintain in tools/simulator/runtime-patches/ and tests/simulator/corpus/; preserve any unmatched experimental variants until reviewed.
Hard-coded VM repair, download, and evidence scripts in build/darwin-live/ Retain originals. Extract a reusable operation only with explicit inputs, bounded effects, and a regression test; do not copy the whole directory into production source.
Capture experiments Retain alongside their evidence until compared with the documentation archive tools and preservation records.
Logs, screenshots, receipts, machine disks, and credentials Keep outside source control; preserve separately before any manual cleanup.
Compiler caches, installed dependencies, generated headers and console bundles Regenerate from tracked recipes after confirming they contain no unique work.

There is deliberately no recursive clean command. New reports and model runs have separate output directories, and new persistent machines live outside the build tree. This makes future cleanup reviewable without risking legacy state.

Source document