Skip to content

phalus-sh/phalus

Repository files navigation

phalus

Private Headless Automated License Uncoupling System — a self-hosted tool for AI-powered clean room software reimplementation. Feed it a dependency manifest and it runs a two-phase, isolation-enforced LLM pipeline: Agent A reads only public documentation and produces a formal specification, Agent B uses a symbiont reasoning loop to iteratively implement the package from scratch.

No user accounts. No payments. No SaaS. You run it on your own machine with your own API keys.

Documentation | Website | crates.io

PHALUS Web UI

Install

From crates.io

cargo install phalus

Download binary

Pre-built binaries for Linux (x86_64, aarch64), macOS (Apple Silicon), and Windows are available from GitHub Releases.

# Linux (x86_64)
curl -L https://github.com/phalus-sh/phalus/releases/latest/download/phalus-v0.6.1-x86_64-unknown-linux-gnu.tar.gz | tar xz
sudo mv phalus /usr/local/bin/

# macOS (Apple Silicon)
curl -L https://github.com/phalus-sh/phalus/releases/latest/download/phalus-v0.6.1-aarch64-apple-darwin.tar.gz | tar xz
sudo mv phalus /usr/local/bin/

Docker

docker run -p 3000:3000 \
  -e PHALUS_LLM__AGENT_A_API_KEY=sk-ant-... \
  -e PHALUS_LLM__AGENT_B_API_KEY=sk-ant-... \
  ghcr.io/phalus-sh/phalus:latest

Build from source

git clone https://github.com/phalus-sh/phalus.git
cd phalus && cargo build --release -j2

Quick Start

Set your API keys:

export PHALUS_LLM__AGENT_A_API_KEY=sk-ant-...
export PHALUS_LLM__AGENT_B_API_KEY=sk-ant-...

Preview what would be processed:

phalus plan package.json

Run a single package through the full pipeline:

phalus run-one npm/left-pad@1.1.3 --license mit

Run all packages in a manifest:

phalus run package.json --license apache-2.0 --output ./reimplemented

Dry run (Agent A only, produce specs without implementation):

phalus run package.json --dry-run

Cross-language reimplementation:

phalus run package.json --license mit --target-lang rust

Inspect results:

phalus inspect ./phalus-output --audit
phalus inspect ./phalus-output --similarity
phalus inspect ./phalus-output --csp

Re-validate existing output:

phalus validate ./phalus-output --similarity-threshold 0.5

Resume a previous run (skip completed packages):

phalus run package.json --resume

License Scanning

Scan a project's dependencies for license compliance:

phalus scan ./my-project

Output:

Scan: ./my-project (42 packages from 1 manifest, 0 SBOMs)

Package              Version    Ecosystem    License          Class
lodash               4.17.21    npm          MIT              permissive
express              4.18.2     npm          MIT              permissive
serde                1.0.197    crates       MIT OR Apache-2.0  permissive
numpy                2.2.6      pypi         BSD-3-Clause     permissive

Summary: 38 permissive, 3 copyleft-weak, 1 copyleft-strong

Supports npm, PyPI, crates.io, and Go registries. Handles CycloneDX and SPDX SBOM formats. Compound licenses (MIT OR Apache-2.0, Apache-2.0 AND ISC) are classified by their most relevant component.

Supported Ecosystems

Ecosystem Manifest Registry
npm package.json registry.npmjs.org
Python requirements.txt pypi.org
Rust Cargo.toml crates.io
Go go.mod proxy.golang.org

How It Works

Manifest → Registry Resolver → Doc Fetcher → Agent A (Analyzer)
    → Isolation Firewall → Agent B (Builder) → Validator → Output
  1. Agent A reads only public documentation (README, API docs, type definitions) and produces a Clean Room Specification Pack (CSP) — 10 documents describing what the package does, never how.
  2. The Isolation Firewall enforces separation: Agent B never sees the original documentation or source code. Only the CSP crosses the boundary, logged with SHA-256 checksums.
  3. Agent B uses a symbiont ORGA reasoning loop (Observe-Reason-Gate-Act) to iteratively implement the package. It writes files, checks API surface completeness, resolves missing imports, and repeats until the implementation is complete.
  4. The Validator checks syntax, runs tests, scores similarity against the original, and flags anything above threshold.

Every step is recorded in an append-only audit trail.

Configuration

~/.phalus/config.toml:

[llm]
agent_a_provider = "anthropic"    # anthropic | openai | openrouter | ollama | any OpenAI-compatible
agent_a_model = "claude-sonnet-4-6"
agent_a_api_key = ""
agent_a_base_url = ""             # optional: override API endpoint
agent_b_provider = "anthropic"
agent_b_model = "claude-sonnet-4-6"
agent_b_api_key = ""
agent_b_base_url = ""
agent_a_max_tokens = 16384       # max output tokens for Agent A
agent_b_max_tokens = 65536       # max output tokens for Agent B

[llm.retry]
max_retries = 3
initial_backoff_ms = 500
timeout_secs = 600

[isolation]
mode = "context"    # context | process | container
docker_image = "alpine:3"
memory_limit = "256m"
cpu_limit = "1.0"
timeout_secs = 60
network_mode = "none"
pids_limit = 64

[limits]
max_packages_per_job = 50
max_package_size_mb = 10
concurrency = 3

[validation]
similarity_threshold = 0.70
run_tests = true
syntax_check = true

[output]
default_license = "mit"
output_dir = "./phalus-output"
include_csp = true
include_audit = true

[web]
enabled = false
host = "127.0.0.1"
port = 3000

[doc_fetcher]
max_readme_size_kb = 500
max_code_example_lines = 10
github_token = ""

All config keys can be overridden via environment variables with PHALUS_ prefix and double-underscore nesting:

PHALUS_LLM__AGENT_A_API_KEY=sk-ant-...
PHALUS_LLM__AGENT_A_MODEL=claude-sonnet-4-6
PHALUS_ISOLATION__MODE=process
PHALUS_WEB__ENABLED=true

Using OpenAI, OpenRouter, or Ollama

Any provider with an OpenAI-compatible /v1/chat/completions endpoint works:

# OpenAI
export PHALUS_LLM__AGENT_A_PROVIDER=openai
export PHALUS_LLM__AGENT_A_MODEL=gpt-4o
export PHALUS_LLM__AGENT_A_API_KEY=sk-...

# OpenRouter
export PHALUS_LLM__AGENT_A_PROVIDER=openrouter
export PHALUS_LLM__AGENT_A_BASE_URL=https://openrouter.ai/api
export PHALUS_LLM__AGENT_A_MODEL=anthropic/claude-sonnet-4
export PHALUS_LLM__AGENT_A_API_KEY=sk-or-...

# Ollama (local, no API key needed)
export PHALUS_LLM__AGENT_A_PROVIDER=ollama
export PHALUS_LLM__AGENT_A_BASE_URL=http://localhost:11434
export PHALUS_LLM__AGENT_A_MODEL=llama3
export PHALUS_LLM__AGENT_A_API_KEY=unused

Set AGENT_B_* equivalents for Agent B (can be a different provider/model).

Output Licenses

License ID
MIT mit
Apache 2.0 apache-2.0
BSD 2-Clause bsd-2
BSD 3-Clause bsd-3
ISC isc
Unlicense unlicense
CC0 1.0 cc0

Web UI

Enable the optional local web UI:

PHALUS_WEB__ENABLED=true phalus run package.json

Or set web.enabled = true in config.toml. Serves on http://127.0.0.1:3000 by default.

Ethical Notice

This tool raises serious ethical and legal questions about open source sustainability. It exists for research, education, and transparent discourse — not to encourage license evasion. You are responsible for understanding the legal implications in your jurisdiction. The legality of AI-assisted clean room reimplementation is unsettled law.

Background

This project replicates the core pipeline demonstrated by Malus, presented at FOSDEM 2026 by Dylan Ayrey and Mike Nolan. PHALUS strips the concept down to the essential machinery: the pipeline, the isolation, and the audit trail.

License

0BSD

About

PHALUS: Private Headless Automated License Uncoupling System

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors