Aestra documentation
Aestra is a deterministic execution sandbox and testcase engine built to accurately enforce hardware constraints — CPU time limit and peak RAM limit — on untrusted binaries with microsecond precision. It is designed for competitive programming online judges, automated grading systems, and local problem testing workflows.
Why Aestra exists
Traditional testcase runners use wall-clock timeouts and heuristic memory checks. This leads to inconsistent verdicts across machines with different CPU speeds or system loads. Aestra solves this by using POSIX kernel-level resource limits (setrlimit) that enforce constraints at the hardware scheduler level, making results deterministic regardless of host load.
The engine measures CPU time (user + kernel) via the wait4 system call with sub-millisecond resolution, and reads peak RSS from kernel accounting — not by polling /proc or sampling memory at intervals.
Core capabilities
Hardware enforcement
POSIX setrlimit for hard CPU and memory ceilings enforced by the Linux kernel scheduler, not userspace timers.
Microsecond telemetry
User + kernel CPU time and peak resident set size via wait4 with rusage accounting.
Cross-platform
Native Rust POSIX sandbox on Linux/WSL. Automatic SubprocessEngine fallback on Windows and macOS.
Process isolation
Forked child process with empty environment, capped file descriptors, and bounded pipe buffers. No network access.
Technology stack
| Layer | Technology | Role |
|---|---|---|
| Sandbox | Rust + libc crate | POSIX fork, execve, setrlimit, wait4 |
| FFI bridge | PyO3 0.20 | Zero-cost Rust ↔ Python interop with ABI3 stable API |
| Build | Maturin | Compile Rust extension and install into venv |
| Frontend | Python 3.10+ | CLI, test runner, output checker, config |
| CI | GitHub Actions | Ruff, Mypy, Cargo Clippy, Cargo Test, Maturin Build |
Release v0.1.2. Hardened POSIX sandbox with non-blocking pipe multiplexing, active wall-clock watchdog, and real-time cross-platform peak memory tracking.
Installation
Aestra is not a PyPI package. You build it from source using Maturin, which compiles the Rust core and installs the Python package into your virtual environment in one step.
Prerequisites
| Tool | Version | Why |
|---|---|---|
| Python | 3.10+ | Required for the Python frontend and CLI |
| Rust | 1.75+ | Required to compile the native POSIX sandbox extension |
| Maturin | Latest | Build tool that compiles Rust and installs the Python package |
If you don't have Rust installed, get it from rustup.rs:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Build from source
Clone the repository, create a virtual environment, and build the native extension:
git clone https://github.com/Elitsuv/aestra.git
cd aestra
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install maturin
maturin develop
The maturin develop command compiles the Rust aestra_core crate and installs it as a Python extension module into the active virtual environment. This takes about 30 seconds on first build and under 5 seconds on incremental rebuilds.
Optional automated installers
For zero-friction setup without manual environment configuration, we created automated installer scripts (scripts/install.sh and scripts/install.ps1). These scripts automate dependency checks, environment isolation, and compilation in a single command:
One-line remote installation:
curl -fsSL https://raw.githubusercontent.com/Elitsuv/aestra/main/scripts/install.sh | bash
Or run locally from a cloned repository:
chmod +x scripts/install.sh
./scripts/install.sh
What the script executes:
- Verifies
python3(3.10+) is in PATH; warns if missing - Inspects kernel capabilities (Linux/WSL native POSIX hardware limits vs. Darwin fallback)
- Bootstraps
pipif missing usingensurepip - Installs the local package or builds the latest release directly from GitHub
One-line remote installation (PowerShell 5.1+ or 7+):
iex (irm https://raw.githubusercontent.com/Elitsuv/aestra/main/scripts/install.ps1)
Or run locally from a cloned repository:
powershell -ExecutionPolicy Bypass -File .\scripts\install.ps1
What the script executes:
- Locates
pythonexecutable (3.10+) and checks version compatibility - Installs Aestra into
~/.aestraand exposes globalaestracommand via PATH - Enables Windows cross-platform
SubprocessEnginefallback sandbox (zero Rust required)
Safe & non-intrusive. Both optional install scripts operate entirely in user space. They never alter your system registry, never request sudo/administrator rights, and make zero changes outside the project directory.
Verify installation
Run this command to confirm the engine is working and see which backend is active:
python3 -c "from src.engine import get_engine; e = get_engine(); print(type(e).__name__)"
| Output | Meaning |
|---|---|
NativeEngine | Rust POSIX sandbox loaded — full hardware enforcement available |
SubprocessEngine | Fallback mode — timeouts work, kernel-level memory measurement unavailable |
Uninstall
Delete the cloned directory and remove the virtual environment. No system files are modified:
deactivate # exit the venv
rm -rf aestra/ # remove the project directory
Safety and system integrity
Aestra is designed to execute untrusted code safely. It runs entirely in user space, never requests root or administrator privileges, never modifies system files, never writes outside its own directory, and leaves no persistent background processes or services.
No system risk. Installing and running Aestra cannot corrupt your operating system, registry, PATH, or personal files. It behaves identically to any standard Python development tool — it lives inside a virtual environment and cleans up completely on uninstall.
How untrusted code is contained
When the native POSIX sandbox executes a binary, it applies multiple layers of kernel-enforced constraints before the target program starts running. These are not heuristic — they are enforced by the Linux kernel scheduler itself.
| Threat | Attack vector | Mitigation |
|---|---|---|
| CPU spin | while(true); infinite loop |
RLIMIT_CPU sends SIGXCPU when time limit is reached. A watchdog SIGKILL fires 1 second later as a hard backstop. |
| RAM flood | malloc(64GB) allocation |
RLIMIT_AS causes mmap and brk to fail once the ceiling is hit. Host memory is never touched. |
| Fork bomb | fork() in a loop |
RLIMIT_NPROC caps total child processes for the user. |
| Disk fill | 50 GB stdout dump | RLIMIT_FSIZE limits maximum file write size. Stdout is read through bounded pipe buffers (output_limit_bytes). |
| Network exfiltration | Socket open to external host | Empty environment passed to execve. No environment variables, no proxy configuration, no DNS resolution context. |
What Aestra does NOT do
- Never requests
sudo,root, or administrator privileges - Never writes outside the project directory
- Never installs system-wide services, daemons, or startup scripts
- Never modifies your shell profile, PATH, registry, or system configuration
- Never sends telemetry, analytics, or crash reports to any server
- Never opens network connections (the sandbox itself is fully offline)
Subprocess engine safety
On Windows and macOS where the native POSIX sandbox is not available, SubprocessEngine uses Python's subprocess.run() with strict timeout enforcement. While this does not provide kernel-level memory limits, the process is still killed after the timeout expires. No zombie processes are left behind — the watchdog ensures cleanup.
Target use cases
Aestra is engineered for environments where untrusted or user-submitted code must be executed with microsecond-level determinism, strict hardware boundaries, and zero risk to the host system.
Competitive programming judges
Online judge platforms (such as Codeforces, AtCoder, CSES, or internal team training judges) require predictable time and memory accounting across thousands of heterogeneous submissions. Traditional judges rely on wall-clock measurements that fluctuate with server CPU load, causing false Time Limit Exceeded verdicts during traffic spikes.
Aestra solves this by delegating time limits to Linux kernel scheduler accounting:
- Deterministic CPU time: Measures strictly
user_time + kernel_timevia thewait4system call with microsecond resolution. Background server operations never inflate submission runtimes. - Hardware memory ceiling: Uses
RLIMIT_ASto restrict address space. When a submission allocates beyond its quota (e.g.vector<int> a(1e9)), the allocation immediately fails without touching host swap or triggering the OS OOM killer. - Sub-millisecond startup: Uses native
forkandexecvewithout the multi-hundred-millisecond latency overhead of Docker container lifecycle management.
Automated academic grading
Computer science university courses and autograding portals (such as Gradescope or automated lab submission runners) frequently run untrusted student code that may contain infinite loops, memory leaks, or accidental system calls.
- Zero root privilege: Runs entirely in user space. Student submissions cannot modify system configuration, write outside the designated sandbox, or corrupt other processes.
- Fork bomb protection: Enforces
RLIMIT_NPROCto cap child process creation, preventing malicious or accidental recursivefork()calls from locking the grading server. - Standardized verdicts: Direct mapping to educational grading categories (
ACCEPTED,WRONG_ANSWER,TIME_LIMIT_EXCEEDED,MEMORY_LIMIT_EXCEEDED,RUNTIME_ERROR).
Local problem setting & stress testing
Contest problem setters and competitive programmers preparing for ICPC or Codeforces rounds need to stress-test candidate solutions against edge cases before publishing:
- Automated test discovery: Scans test suites matching
.inwith.outor.ansand executes full batches with aggregated verdicts. - Diff inspector: Pinpoints exact token differences between actual program output and expected answers using
TOKENorEXACTmode. - Generator stress loops: Can be scripted inside a Python loop to continuously generate random test cases, run a brute-force $O(N^2)$ solution against an optimized $O(N \log N)$ solution, and stop upon finding a counterexample.
AI & LLM code evaluation
Autonomous AI agents, coding assistants, and research benchmark suites (such as HumanEval, MBPP, or SWE-bench) generate and execute arbitrary code strings at high velocity. Running LLM-generated code directly on the host machine presents substantial risk of system pollution, rogue network sockets, or infinite execution loops.
- Environment isolation: Unsets all host environment variables, removing API keys, credentials, and network proxy access from the executed child process.
- Hard backstop watchdog: If a runaway AI-generated process ignores
SIGXCPU, a hard kernelSIGKILLterminates the process cleanly within 1 second. - Machine-readable telemetry: The Python SDK returns structured dataclasses (
ExecutionResult) ready for automated reward scoring and validation pipelines.
Running programs
Execute a compiled binary or script under hardware-enforced CPU and memory constraints, and receive structured telemetry about the execution.
CLI usage
The aestra run command executes a single binary with the specified constraints:
aestra run ./solution.out --time-limit 2000 --memory-limit 512
Or invoke directly via Python module: python -m src.cli run ./solution.out --time-limit 2000 --memory-limit 512
Telemetry output
After execution completes (or is terminated), Aestra prints a structured telemetry block:
[Telemetry]
Status: TIME_LIMIT_EXCEEDED
CPU Time: 2003ms
Peak Memory: 12.1MB
Exit Code: 137 (SIGKILL)
The CPU time shown is user + kernel time measured by the kernel via wait4 — not wall-clock time. This means background system load does not affect the measurement.
Available flags
| Flag | Default | Description |
|---|---|---|
--time-limit | 2000 | Maximum CPU time in milliseconds. Maps to RLIMIT_CPU on POSIX systems. |
--memory-limit | 512 | Maximum memory in megabytes. Maps to RLIMIT_AS on POSIX systems. |
--input | "" | String piped to the program's stdin via POSIX pipe. |
Python SDK
Use the engine directly from Python for programmatic execution and result inspection:
from pathlib import Path
from src.config import ExecutionLimits
from src.engine import get_engine
engine = get_engine()
limits = ExecutionLimits(time_limit_ms=2000, memory_limit_mb=512)
result = engine.execute(Path("./solution.out"), limits, input_data="42\n")
print(result.status.value) # OK | TIME_LIMIT_EXCEEDED | ...
print(f"{result.cpu_time_ms:.2f} ms")
print(f"{result.peak_memory_mb:.1f} MB")
print(result.stdout)
Execution statuses
Every execution returns an ExecutionStatus enum. These map directly to competitive programming judge verdicts:
| Status | Trigger | Exit code |
|---|---|---|
OK | Normal termination with exit code 0 | 0 |
TIME_LIMIT_EXCEEDED | CPU time exceeded limit or SIGXCPU/SIGKILL | 128 + signal |
MEMORY_LIMIT_EXCEEDED | SIGSEGV with peak memory ≥ limit | 128 + 11 |
RUNTIME_ERROR | Non-zero exit or uncaught signal | Varies |
OUTPUT_LIMIT_EXCEEDED | Stdout exceeds output_limit_bytes | Varies |
INTERNAL_ERROR | Sandbox infrastructure failure (pipe, fork, import) | 1 |
Batch testing
Run a program against a full directory of test cases, automatically discover input/output pairs, and receive aggregated verdicts with per-case timing.
Basic usage
aestra test ./solution.out --cases ./tests/ --mode token
Or invoke directly via Python module: python -m src.cli test ./solution.out --cases ./tests/ --mode token
Test case discovery
Aestra automatically discovers paired input/output files in the test directory. It supports multiple naming conventions commonly used in competitive programming:
| Input file | Expected output |
|---|---|
1.in | 1.out or 1.ans |
test_01.in | test_01.out or test_01.ans |
sample.in | sample.out |
Files are matched by base name — foo.in pairs with foo.out or foo.ans. Input files without a matching output file are skipped with a warning.
Verdicts
Each test case produces one of the following verdicts:
| Verdict | Meaning |
|---|---|
ACCEPTED | Program output matches the expected answer after applying the comparison mode |
WRONG_ANSWER | Program ran successfully but output does not match |
TIME_LIMIT_EXCEEDED | CPU time exceeded the configured limit |
MEMORY_LIMIT_EXCEEDED | Memory usage exceeded the configured ceiling |
RUNTIME_ERROR | Program crashed or returned non-zero exit code |
Comparison modes
The --mode flag controls how actual output is compared against expected output. See the Output comparison section for detailed behavior.
Output comparison modes
The OutputChecker class compares actual program output against expected answers using one of three comparison strategies. The mode you choose affects whether trailing whitespace, extra newlines, or formatting differences cause a WRONG_ANSWER verdict.
Available modes
| Mode | Behavior | Use case |
|---|---|---|
TOKEN |
Splits both strings by whitespace (.split()), then compares the resulting token sequences. Any amount of whitespace between tokens is treated identically. |
Standard competitive programming problems. Ignores trailing spaces, extra newlines, and inconsistent indentation. |
IGNORE_WHITESPACE |
Strips leading and trailing whitespace from both strings (.strip()), then performs exact string comparison on the result. |
Problems where internal formatting matters but trailing newlines should be tolerated. |
EXACT |
Byte-for-byte equality comparison. No normalization applied. | Strict output problems: formatted text, ASCII art, CSV output, or any case where whitespace is significant. |
Python usage
from src.checker import OutputChecker, CheckerMode
checker = OutputChecker(CheckerMode.TOKEN)
result = checker.check(actual="42 \n", expected="42")
print(result.is_correct) # True — whitespace difference ignored in TOKEN mode
# EXACT mode would reject this:
strict = OutputChecker(CheckerMode.EXACT)
result = strict.check(actual="42 \n", expected="42")
print(result.is_correct) # False — trailing space and newline cause mismatch
CheckResult object
The check() method returns a CheckResult dataclass:
| Field | Type | Description |
|---|---|---|
is_correct | bool | Whether the output matched under the chosen mode |
diff | str | None | A human-readable diff showing expected vs. actual (only set when incorrect) |
Interface and system layout
Aestra provides structured interfaces at every layer: a clear terminal output layout for interactive debugging, a composable Python SDK for automated pipelines, and hardware-enforced boundaries at the kernel level.
System architecture layout
The system is organized into decoupled layers communicating across language boundaries:
Terminal CLI output layout
When running through the command line, Aestra produces structured visual output designed for rapid terminal inspection.
Single execution layout
$ aestra run ./solution.out --time-limit 2000 --memory-limit 512
[Telemetry]
Status: OK
CPU Time: 14.8ms
Peak Memory: 8.4MB
Exit Code: 0
[Output]
42
Batch test runner layout
$ aestra test ./solution.out --cases ./tests/ --mode token
Running 4 test cases on solution.out...
Limits: 2000ms CPU, 512MB RAM | Mode: TOKEN
[ACCEPTED] test_01.in 12.4ms 8.2MB
[ACCEPTED] test_02.in 15.1ms 8.4MB
[TIME_LIMIT_EXCEEDED] test_03.in 2001.2ms 12.0MB
[WRONG_ANSWER] test_04.in 9.8ms 6.1MB
Expected:
42 100
Actual:
42 99
Verdict: 2/4 test cases accepted.
Verdict badge taxonomy
Verdicts represent standardized competitive programming judge outcomes:
| Verdict | Badge | Condition |
|---|---|---|
| Accepted | ACCEPTED | Process exited 0 and output matched expected answer under active comparison mode |
| Wrong Answer | WRONG_ANSWER | Process exited 0 but output differed from expected answer |
| Time Limit | TIME_LIMIT_EXCEEDED | CPU time exceeded limit or terminated by SIGXCPU / SIGKILL |
| Memory Limit | MEMORY_LIMIT_EXCEEDED | Process exceeded configured RAM ceiling or crashed with SIGSEGV under memory pressure |
| Runtime Error | RUNTIME_ERROR | Process crashed with non-zero exit code or uncaught signal (e.g. SIGABRT) |
Python SDK dataflow layout
The programmatic interface follows a unidirectional dataflow pipeline:
from pathlib import Path
from src.config import ExecutionLimits
from src.engine import get_engine
from src.checker import OutputChecker, CheckerMode
# 1. Configure resource limits
limits = ExecutionLimits(time_limit_ms=1000, memory_limit_mb=256)
# 2. Acquire appropriate engine (NativeEngine or SubprocessEngine)
engine = get_engine()
# 3. Execute binary and capture telemetry
result = engine.execute(Path("./solution"), limits, input_data="10 20\n")
# 4. Compare output against expected answer
checker = OutputChecker(mode=CheckerMode.TOKEN)
check_result = checker.check(actual=result.stdout, expected="30\n")
print(f"Verdict: {'ACCEPTED' if check_result.is_correct else 'WRONG_ANSWER'}")
print(f"CPU Time: {result.cpu_time_ms}ms | Peak RAM: {result.peak_memory_mb}MB")
Architecture
Aestra uses a two-tier execution model. The Rust core handles low-level POSIX sandboxing, while the Python frontend provides CLI orchestration, answer verification, and configuration management. The two layers communicate through a zero-cost PyO3 FFI bridge.
Tier 1 — Native POSIX sandbox
On Linux and WSL, aestra_core (compiled from src/sandbox_posix.rs) performs the following sequence:
- Creates three POSIX pipes for stdin, stdout, and stderr IPC
- Calls
fork()to create a child process - In the child: applies
setrlimitforRLIMIT_CPU,RLIMIT_AS,RLIMIT_NPROC, andRLIMIT_FSIZE - Redirects file descriptors with
dup2and callsexecvewith an empty environment - In the parent: writes input data to stdin pipe, then reads stdout and stderr through bounded buffers
- Calls
wait4to collect the exit status andrusagestruct containing CPU time and peak RSS - Interprets the exit signal (
SIGXCPU,SIGKILL,SIGSEGV) to determine the verdict
Tier 2 — Subprocess fallback
On Windows and macOS, or when the native extension is not compiled, SubprocessEngine in src/engine.py provides an equivalent interface using Python's subprocess.run(). It passes timeout= for time enforcement and measures wall-clock time via time.perf_counter().
Limitations of the fallback engine:
- Memory measurement is not available (reports 0 bytes)
- Wall-clock time is used instead of CPU time — affected by system load
- No kernel-level process limits — the target runs with normal user permissions
Automatic selection. The get_engine() factory function detects available backends at import time. It tries to import aestra_core and returns NativeEngine if successful, otherwise falls back to SubprocessEngine. No configuration or environment variables needed.
Project structure
aestra/
├── src/
│ ├── __init__.py # Package exports
│ ├── cli.py # CLI entrypoint (run, test commands)
│ ├── config.py # ExecutionLimits dataclass
│ ├── models.py # ExecutionResult, ExecutionStatus enum
│ ├── engine.py # BaseEngine, NativeEngine, SubprocessEngine, get_engine()
│ ├── runner.py # BatchRunner engine with testcase discovery
│ ├── checker.py # OutputChecker with TOKEN/EXACT/IGNORE_WHITESPACE
│ ├── lib.rs # PyO3 module definition — exposes execute_native()
│ └── sandbox_posix.rs # Rust POSIX sandbox: fork, setrlimit, execve, wait4
├── tests/
│ └── test.py # Unified test suite
├── scripts/
│ ├── install.sh # Zero-dependency Linux/macOS installer
│ └── install.ps1 # PowerShell Windows installer
├── Cargo.toml # Rust crate config (PyO3, libc)
├── pyproject.toml # Python project metadata
└── .github/
└── workflows/ci.yml # CI: Ruff, Mypy, Clippy, Cargo Test, Maturin Build
API reference
Complete reference for all public classes, methods, and data models in the Aestra Python SDK.
ExecutionLimits
Python src.config.ExecutionLimits
Frozen dataclass that defines resource constraints for a single execution run.
| Field | Type | Default | Description |
|---|---|---|---|
time_limit_ms | int | 2000 | Maximum CPU time in milliseconds |
memory_limit_mb | int | 512 | Maximum memory in megabytes |
Properties
| Property | Returns | Description |
|---|---|---|
.time_limit | int | Time limit in whole seconds (floor division, minimum 1) |
.memory_limit_bytes | int | Memory limit converted to bytes |
ExecutionResult
Python src.models.ExecutionResult
Frozen dataclass containing the outcome and telemetry from a single execution.
| Field | Type | Description |
|---|---|---|
status | ExecutionStatus | Verdict enum |
exit_code | int | Process exit code (128 + signal if killed) |
cpu_time_ms | float | User + kernel CPU time in milliseconds |
wall_time_ms | float | Wall-clock time in milliseconds |
peak_memory_bytes | int | Peak resident set size in bytes |
stdout | str | Captured standard output |
stderr | str | Captured standard error |
error_message | str | None | Internal error description (if applicable) |
Properties
| Property | Returns | Description |
|---|---|---|
.peak_memory_mb | float | Peak memory converted to megabytes |
.is_success | bool | True if status is SUCCESS, OK, or ACCEPTED and exit code is 0 |
get_engine()
Python src.engine.get_engine() → BaseEngine
Factory function that returns the best available execution engine. Attempts to import aestra_core and returns NativeEngine if available, otherwise returns SubprocessEngine.
from src.engine import get_engine
engine = get_engine()
# Returns NativeEngine on Linux/WSL, SubprocessEngine on Windows/macOS
OutputChecker
Python src.checker.OutputChecker
| Method | Arguments | Returns |
|---|---|---|
__init__ | mode: CheckerMode = TOKEN | — |
check | actual: str, expected: str | CheckResult |
execute_native()
Rust aestra_core.execute_native() → dict
Low-level Rust function exposed via PyO3. Called internally by NativeEngine.
| Parameter | Type | Description |
|---|---|---|
command | str | Path to the executable binary |
args | list[str] | Command-line arguments |
input_data | str | Data piped to stdin |
time_limit_ms | int | CPU time limit in milliseconds |
memory_limit_mb | int | Memory limit in megabytes |
Contributing
Contributions to Aestra are welcome. We maintain strict engineering standards to preserve deterministic execution and FFI boundary safety. This guide covers development setup, quality checks, pull request workflow, and project conventions.
Development setup
You need both Rust and Python to work on the full codebase:
Prerequisites
| Tool | Version | Install |
|---|---|---|
| Rust | 1.75.0+ | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh |
| Python | 3.10+ | python.org |
Environment setup
git clone https://github.com/Elitsuv/aestra.git
cd aestra
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install maturin ruff mypy pytest
maturin develop
Quality standards
All pull requests must pass the following checks locally before submission. The CI pipeline runs these automatically on every PR.
Python linting Python
ruff check . # Lint check
ruff format --check . # Format check
mypy src/ # Type check
Rust linting Rust
cargo fmt --all -- --check # Format check
cargo clippy --all-targets --all-features -- -D warnings # Lint check
cargo test --all # Unit tests
Pull request lifecycle
- Branch naming: Use scoped branch names like
feat/sandbox-limits,fix/zombie-pid, ordocs/api-reference - Atomic commits: Write clear, imperative commit messages following conventional commits — e.g.
feat(rust-core): enforce rlimit AS - Target main: All PRs target the
mainbranch. Ensure both Python and Rust CI checks pass before requesting review. - PR quality audit: The PR template includes a checklist for code quality, test coverage, and documentation updates.
Label taxonomy
Attach appropriate labels to your PR for categorization and changelog generation:
Size labels
| Label | Lines changed |
|---|---|
size: xsmall | < 10 lines |
size: small | < 50 lines |
size: mid | < 250 lines |
size: large | < 1000 lines |
Type labels
| Label | Use for |
|---|---|
type: feature | New functionality |
type: bug | Bug fixes |
type: perf | Performance improvements |
type: refactor | Code restructuring without behavior change |
type: chore | Build system, CI, dependency updates |
type: docs | Documentation only |
Domain labels
| Label | Scope |
|---|---|
domain: rust-core | Rust engine, PyO3 FFI, POSIX sandbox |
domain: python-core | CLI, config, checker, test runner |
CI pipeline
The CI pipeline runs on every push to main and every pull request. It has two jobs:
Python quality CI
Runs on ubuntu-latest with Python 3.11. Executes Ruff lint, Ruff format, and Mypy type checking against src/.
Rust core build CI
Runs on both ubuntu-latest and windows-latest in a matrix. Executes cargo fmt --check, cargo clippy -D warnings, cargo test, and maturin build --release to verify the extension compiles cleanly on both platforms.
Branch protection. The main branch has protection rules enabled: force pushes are blocked and branch deletion is restricted. All CI checks must pass before merge.
Changelog
Release notes and version history for Aestra.
Engine hardening release: POSIX sandbox deadlock elimination, wall-clock watchdog, and real-time cross-platform memory telemetry.
- POSIX Pipe Buffer Deadlock Resolution: Replaced sequential blocking pipe reads with non-blocking
libc::pollevent multiplexing (POLLIN | POLLHUP | POLLERR) to prevent 64KB kernel buffer deadlocks when children emit verbose stderr logs. - Active Wall-Clock Watchdog: Added parent-side deadline enforcement using
std::time::Instantandlibc::SIGKILLto prevent sleeping or deadlocked binaries from bypassingRLIMIT_CPUand hanging the runner. - Cross-Platform Peak Memory Tracking:
SubprocessEnginenow accurately reports peak working set size on Windows viaK32GetProcessMemoryInfoand peak child RSS on macOS/POSIX viaresource.getrusage(RUSAGE_CHILDREN). - Strict Memory Limit Enforcement (MLE): Automatic enforcement of
limits.memory_limit_bytesacross all platforms, reliably returningMEMORY_LIMIT_EXCEEDEDon breach. - Strict Type Compliance: Added full return type annotations and
Callable[[], None]type hints acrosstests/test.pyfor 100% strict Mypy compliance. - Automated Release CI Pipeline: Added
.github/workflows/release.ymlto build native wheel packages via Maturin and publish official GitHub Releases on tags.
Official release: global PATH integration, native Python solution testing, and CLI visual overhaul.
- Global Command Installation:
install.ps1andinstall.shinstallaestrainto user PATH (PythonScripts/and~/.local/bin) for global execution from any directory. - Native Python Solution Support:
SubprocessEngineautomatically executes.pyscripts without requiring shell wrappers or pre-compilation. - Modern Terminal Interface: CLI upgraded with clean boxed headers, command groupings, and formatted ASCII telemetry tables.
- Installer Directory Self-Healing: Automated pre-check cleans broken directory artifacts before cloning to prevent git destination conflicts.
- Complete CP User Guide: Hands-on guides for evaluating competitive programming solutions against
.in/.outtestcase suites.
Initial public beta release. Core sandbox and testing infrastructure.
- Rust POSIX sandbox with
fork,execve,setrlimit, andwait4telemetry (sandbox_posix.rs) - PyO3 FFI bridge exposing
execute_native()to Python vialib.rs - Cross-platform SubprocessEngine fallback for environments without a native Rust toolchain
- Batch test runner with automated
.in/.outtestcase discovery and verdict aggregation (runner.py) - Terminal CLI with
runandtestsubcommands, colored badges, and microsecond telemetry (cli.py) - Output checker with TOKEN, EXACT, and IGNORE_WHITESPACE comparison modes (
checker.py) - Domain models with immutable
ExecutionLimitsand richExecutionResultstatus telemetry - Zero-dependency installers for Linux/macOS Bash (
install.sh) and Windows PowerShell (install.ps1) - Enterprise CI/CD pipeline with Ruff formatting/linting, strict Mypy types, and Rust test matrices
- Documentation portal hosted on GitHub Pages with 12 guides, dark mode, dynamic TOC, and live commit feed
- Engineering standards including branch protection, standardized PR/issue templates, and PR commenter bot
Recent commits
Loading from GitHub…