Pointer
Point it at Python. Get an evidence-backed path to native.
Pointer is a static portability-analysis CLI and Codex-backed Python→Rust porting workflow. v0.1 analyzes any Python repository and produces evidence-backed portability reports. v0.2 adds one-command porting: pointer port ./my-project --target rust --agent codex.
Current release: v0.2.1. This maintenance release improves Rust toolchain discovery and makes failed/repairing port runs more reliable and diagnosable.
What's new in v0.2.0 — The Final Fantasy
pointer port ./python-repo --target rust --agent codex
One command initiates: analysis → oracle capture → plan → Codex generation → Rust build/test → behavioral comparison → bounded repair → evidence report. The command either returns a verified native result or fails honestly with exact blockers and resumable state.
Key additions:
- Durable run state machine — every run is persisted under
.pointer/runs/<run-id>/with atomic state writes. Interrupted runs resume without repeating completed work. - Replaceable agent backend —
AgentBackendprotocol withCodexBackend(real CLI) andFakeBackend(deterministic, no network). CI uses the fake backend — no model spending required. - Executable oracle —
pointer.tomldefines deterministic test cases. Python outputs are captured before generation, then compared against Rust outputs after build. - Differential verification — every oracle case (exit code, stdout, stderr) is compared after the Rust port builds. No false
verifiedverdicts. - Bounded repair — on build/test/behavior failure, structured diagnostics are fed back to Codex via resume. Default budget: 3 attempts. Never loops forever.
- Evidence reports — every run produces
report.mdandevidence.jsonwith full stage timeline, command outputs, binary hash, verdict, and disclosures.
Verdict vocabulary
| Verdict | Meaning |
|---|---|
verified |
Rust builds, passes fmt/clippy/test, and every oracle case matches |
generated_unverified |
Rust generated and may build, but verification incomplete |
blocked |
Missing capability, consent, or prerequisites |
failed |
Pipeline failed after exhausting repair budget |
cancelled |
Cancelled by user |
Install
pip install https://github.com/pilkquant/pointer/releases/download/v0.2.1/pointer_cli-0.2.1-py3-none-any.whl
PyPI installation with pip install pointer-cli will become available after the repository's trusted publisher is registered on PyPI.
Pointer has zero runtime dependencies — it uses only the Python standard library. Requires Python 3.11+.
For the port command you also need:
- Rust toolchain (cargo, rustc, clippy, rustfmt) —
rustup install stable - OpenAI Codex CLI — install and authenticate separately. Set
POINTER_CODEX_BINif not in PATH.
Quick start
Static analysis (v0.1)
# Analyze any Python repository
pointer analyze ./my-project
# Reports land in ./pointer-report/
ls pointer-report/
# report.md report.json
Porting (v0.2)
# Port with real Codex (requires authenticated Codex CLI)
pointer port ./my-project --target rust --agent codex --yes --allow-source-execution
# Check status of all runs
pointer status
# Resume an interrupted run
pointer continue <run-id>
# Re-verify a completed run
pointer verify <run-id>
Using the fake backend (for testing)
# Use deterministic fake backend — no Codex, no network
pointer port ./my-project --target rust --agent fake --yes
Oracle configuration
Create a pointer.toml in your project root to define executable oracle cases:
[port]
target = "rust"
[[oracle.cases]]
name = "basic"
command = ["python", "-m", "myapp", "1 + 2"]
expected_exit = 0
[[oracle.cases]]
name = "stdin"
command = ["python", "-m", "myapp"]
stdin = "3 * 4\n"
expected_exit = 0
[[oracle.cases]]
name = "error_path"
command = ["python", "-m", "myapp", "invalid"]
expected_exit = 1
[oracle.normalization]
strip_trailing_whitespace = true
normalize_newlines = true
Without pointer.toml, the port proceeds but cannot reach verified — it ends generated_unverified.
Security model
Pointer is designed to handle untrusted repositories safely:
Static analysis (pointer analyze):
- No code execution. No network access. No telemetry.
- Symlink-safe traversal. Files outside the repository root are never followed.
- All analysis uses stdlib
ast.parse()on file contents.
Porting (pointer port):
- Source execution is a separate security boundary.
pointer portcontacts the agent by default, but does NOT execute your Python source unless you pass--allow-source-execution. - Codex runs in sandbox. The agent operates only inside an isolated output workspace with
--sandbox workspace-write. Never uses--dangerously-bypass-approvals-and-sandbox. - Secret redaction. Likely secrets (API keys, tokens, passwords) are redacted from all logs and reports.
- Sanitized environment. Subprocess execution uses a documented env allowlist — no secret env vars leaked.
- No symlinks followed outside allowed roots.
- Size limits on all outputs and logs.
- Path validation before any destructive operation.
- Source repository is never modified.
See the security tests for verifiable proof.
CLI reference
pointer --help
pointer --version
pointer analyze PATH [options]
pointer port PATH [options]
pointer status [RUN_ID]
pointer continue RUN_ID
pointer verify RUN_ID
pointer doctor
pointer port
pointer port ./my-project --target rust --agent codex [options]
Options:
--target {rust} Target language (default: rust)
--agent {codex,fake} Agent backend (default: codex)
--yes Auto-confirm (does NOT grant source execution)
--allow-source-execution Allow running Python source as oracle
--max-repairs N Max repair attempts (default: 3)
--state-root DIR Override state directory
pointer status
pointer status # List all runs
pointer status <run-id> # Show details for a specific run
pointer status --json # JSON output
pointer analyze
pointer analyze ./my-project [options]
Options:
--target {compare,rust,cpp} Target language for analysis (default: compare)
--output, -o DIR Output directory (default: pointer-report)
--exclude GLOB Additional exclude pattern (repeatable)
Architecture
Porting pipeline stages
preflight → analyze → oracle_capture → plan → generate →
native_build → differential_verify → repair → final_verify → complete
Each stage is:
- Durable — persisted to
state.jsonatomically - Resumable — completed stages are skipped on resume
- Evidence-backed — command outputs, durations, and artifacts recorded
Agent backend protocol
The AgentBackend protocol decouples Pointer from any specific AI agent:
class AgentBackend(Protocol):
def probe(self) -> BackendCapabilities: ...
def generate(self, prompt, workspace, *, timeout) -> AgentResult: ...
def repair(self, prompt, workspace, *, session_id, timeout) -> AgentResult: ...
- CodexBackend — invokes
codex exec --json --sandbox=workspace-writeinside the isolated workspace - FakeBackend — writes real compilable Rust for testing without network
Example fixture
See examples/tinycalc/ — a minimal arithmetic calculator with:
- A CLI accepting arguments and stdin
- Deterministic stdout and exit behavior
- Unit tests
- 8 oracle cases including error paths
What the report tells you
Every analysis report answers nine questions across Markdown and JSON:
- Repository profile — project name, version, Python requirement, file/line counts
- Packaging & layout — build backends, lockfiles, source roots, entry points
- Native extension status — pure Python or already partly native?
- Imports & dependencies — full import inventory with portability dispositions
- Dynamic language blockers — eval, exec, metaclasses, monkeypatching
- Test & oracle evidence — test framework detection, oracle-readiness assessment
- Migration seams — recommended module boundaries for incremental porting
- Target recommendation — transparent Rust-vs-C++ scoring
- Evidence taxonomy — every finding labeled observed, inferred, or unknown
Limitations
- Dynamic Python behavior (reflection, monkeypatching) cannot be fully captured
- Nondeterministic outputs cannot be verified
- Network-dependent behavior may differ between Python and Rust
- Database, GUI, and distributed system ports are out of scope
- Native C/Fortran dependencies require manual handling
- Pointer does not port to C++ (v0.2 — Rust only)
Contributing
See CONTRIBUTING.md. Pointer is developed test-first with 221+ tests covering static analysis, porting, security, determinism, and integration.
Maintenance
Pointer is maintained by Madoka under PilkQuant. See MAINTAINERS.md for ownership and release responsibilities.
License
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pointer_cli-0.2.1.tar.gz.
File metadata
- Download URL: pointer_cli-0.2.1.tar.gz
- Upload date:
- Size: 101.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c6c363fb2dfd3c71b09b0e0a40f8376b37f5801de03a0e7eb2f2908d228c8882
|
|
| MD5 |
dcdebeb94dc872aa8cf6e7c4a84afed3
|
|
| BLAKE2b-256 |
338076134eb4bdce886fa6c00110358cb43916f6750541564b46ab78714d86ef
|
Provenance
The following attestation bundles were made for pointer_cli-0.2.1.tar.gz:
Publisher:
publish.yml on pilkquant/pointer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pointer_cli-0.2.1.tar.gz -
Subject digest:
c6c363fb2dfd3c71b09b0e0a40f8376b37f5801de03a0e7eb2f2908d228c8882 - Sigstore transparency entry: 2324800058
- Sigstore integration time:
-
Permalink:
pilkquant/pointer@d10e9df030d6d02bf3809320a44b9d7ccaa80e3b -
Branch / Tag:
refs/heads/main - Owner: https://github.com/pilkquant
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d10e9df030d6d02bf3809320a44b9d7ccaa80e3b -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file pointer_cli-0.2.1-py3-none-any.whl.
File metadata
- Download URL: pointer_cli-0.2.1-py3-none-any.whl
- Upload date:
- Size: 83.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fe1d5f214357f4d314ac71bc2ad94ebc3942d3c9a1179e06cda976805adcc2b4
|
|
| MD5 |
760db74f127caf26108c475fbf4e18cd
|
|
| BLAKE2b-256 |
72c448de09f4dd428728e8c2ffc92553e4f0722d29a12a3c60412ac4a4664fa9
|
Provenance
The following attestation bundles were made for pointer_cli-0.2.1-py3-none-any.whl:
Publisher:
publish.yml on pilkquant/pointer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pointer_cli-0.2.1-py3-none-any.whl -
Subject digest:
fe1d5f214357f4d314ac71bc2ad94ebc3942d3c9a1179e06cda976805adcc2b4 - Sigstore transparency entry: 2324800291
- Sigstore integration time:
-
Permalink:
pilkquant/pointer@d10e9df030d6d02bf3809320a44b9d7ccaa80e3b -
Branch / Tag:
refs/heads/main - Owner: https://github.com/pilkquant
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d10e9df030d6d02bf3809320a44b9d7ccaa80e3b -
Trigger Event:
workflow_dispatch
-
Statement type: