phalus 0.4.0

Private Headless Automated License Uncoupling System — AI-powered clean room software reimplementation
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
# CLI Reference

PHALUS is CLI-first. Every capability is accessible from the command line; the web UI is a convenience wrapper over the same pipeline.

```
phalus [COMMAND] [OPTIONS]
```

Run `phalus --help` for a summary or `phalus [COMMAND] --help` for per-command help.

---

## Commands

| Command | Description |
|---------|-------------|
| [`plan`]#plan | Parse a manifest and show what would be processed |
| [`run`]#run | Run the full clean room pipeline from a manifest |
| [`run-one`]#run-one | Run the pipeline on a single package without a manifest |
| [`build`]#build | Run Agent B only from an existing CSP |
| [`inspect`]#inspect | Inspect a completed job's output directory |
| [`validate`]#validate | Re-run validation on an existing output directory |
| [`config`]#config | Print the active configuration (API keys redacted) |
| [`serve`]#serve | Start the local web UI |

---

## plan

Parse a manifest file and display the packages that would be processed. No network calls to registries or LLMs are made. Use this to preview filtering before a long run.

```
phalus plan <MANIFEST> [OPTIONS]
```

### Arguments

| Argument | Description |
|----------|-------------|
| `MANIFEST` | Path to the manifest file (e.g. `package.json`, `requirements.txt`, `Cargo.toml`, `go.mod`) |

### Options

| Option | Description |
|--------|-------------|
| `--only <pkg1,pkg2,...>` | Process only these packages (comma-separated names) |
| `--exclude <pkg1,pkg2,...>` | Skip these packages (comma-separated names) |

### Example

```bash
phalus plan package.json

phalus plan package.json --only lodash,chalk

phalus plan requirements.txt --exclude boto3,botocore
```

**Output:**

```
Manifest: package.json (5 packages, 3 after filtering)

PACKAGE                        VERSION          ECOSYSTEM
-------------------------------------------------------
lodash                         ^4.17.21         npm
express                        ^4.18.2          npm
chalk                          ^5.3.0           npm
```

---

## run

Run the full clean room pipeline for all packages in a manifest. Packages are processed concurrently up to the configured limit.

```
phalus run <MANIFEST> [OPTIONS]
```

### Arguments

| Argument | Description |
|----------|-------------|
| `MANIFEST` | Path to the manifest file |

### Options

| Option | Default | Description |
|--------|---------|-------------|
| `--license <id>` | `mit` | SPDX license identifier for the generated code. Options: `mit`, `apache-2.0`, `bsd-2`, `bsd-3`, `isc`, `unlicense`, `cc0` |
| `--license-file <path>` || Path to a file containing full license text (overrides `--license`) |
| `--output <dir>` | `./phalus-output` | Directory to write generated packages |
| `--only <pkg1,pkg2,...>` || Process only these packages |
| `--exclude <pkg1,pkg2,...>` || Skip these packages |
| `--target-lang <lang>` | Same as source | Reimplement in a different language: `rust`, `go`, `python`, `typescript` |
| `--isolation <mode>` | `context` | Isolation strategy: `context`, `process`, `container` |
| `--similarity-threshold <f>` | `0.70` | Similarity score above which a package is flagged as FAIL |
| `--concurrency <n>` | `3` | Number of packages to process in parallel |
| `--dry-run` | false | Run Agent A only — produce CSP specs, skip Agent B and validation. Use with [`build`]#build for a split workflow. |
| `--verbose` | false | Enable verbose logging |

### Exit codes

| Code | Meaning |
|------|---------|
| `0` | All packages processed successfully |
| `1` | One or more packages failed |

### Examples

```bash
# Basic run, MIT license
phalus run package.json

# Apache-2.0 output into a specific directory
phalus run package.json --license apache-2.0 --output ./liberated/

# Process only two packages
phalus run package.json --only lodash,express

# Reimplement JavaScript packages in Rust
phalus run package.json --target-lang rust --license apache-2.0

# Dry run: trigger Agent A only, produce CSP specs without code generation
phalus run package.json --dry-run

# Dry run a single package, then build from the CSP later
phalus run-one npm/lodash@4.17.21 --dry-run
phalus build ./phalus-output/lodash/.cleanroom/csp/

# Stricter similarity threshold
phalus run package.json --similarity-threshold 0.50

# Stronger isolation mode
phalus run package.json --isolation process
```

---

## run-one

Run the clean room pipeline on a single package without needing a manifest file. Useful for quick experiments and testing a specific package.

```
phalus run-one <PACKAGE> [OPTIONS]
```

### Arguments

| Argument | Description |
|----------|-------------|
| `PACKAGE` | Package specification in the format `ecosystem/name@version`. For example: `npm/lodash@4.17.21`, `pypi/requests@2.31.0`, `crates/serde@1.0.193`, `go/github.com/gin-gonic/gin@v1.9.1` |

Supported ecosystems: `npm`, `pypi`, `crates`, `go`.

### Options

| Option | Default | Description |
|--------|---------|-------------|
| `--license <id>` | `mit` | SPDX license identifier |
| `--license-file <path>` || Path to a file containing full license text (overrides `--license`) |
| `--output <dir>` | `./phalus-output` | Output directory |
| `--target-lang <lang>` | Same as source | Target language: `rust`, `go`, `python`, `typescript` |
| `--isolation <mode>` | `context` | Isolation mode: `context`, `process`, `container` |
| `--similarity-threshold <f>` | `0.70` | Similarity threshold |
| `--verbose` | false | Enable verbose logging |

### Examples

```bash
phalus run-one npm/left-pad@1.1.3

phalus run-one npm/lodash@4.17.21 --license apache-2.0

phalus run-one pypi/requests@2.31.0 --output ./py-output/

phalus run-one npm/chalk@5.3.0 --target-lang rust --license mit

phalus run-one crates/serde@1.0.193 --isolation process
```

---

## build

Run Agent B (Builder) from an existing Clean Room Specification Pack without re-running Agent A. This is the second half of the split pipeline workflow:

1. Generate a CSP with `--dry-run` (Agent A only)
2. Optionally review or modify the CSP files on disk
3. Run `build` to implement from the CSP (Agent B only)

```
phalus build <CSP> [OPTIONS]
```

### Arguments

| Argument | Description |
|----------|-------------|
| `CSP` | Path to a CSP `manifest.json` file, **or** a directory containing one (e.g. `./phalus-output/lodash/.cleanroom/csp/`) |

### Options

| Option | Default | Description |
|--------|---------|-------------|
| `--license <id>` | `mit` | SPDX license identifier for the generated code |
| `--license-file <path>` || Path to a file containing full license text (overrides `--license`) |
| `--output <dir>` | `./phalus-output` | Output directory |
| `--target-lang <lang>` | Same as source | Target language: `rust`, `go`, `python`, `typescript` |
| `--isolation <mode>` | `context` | Isolation mode: `context`, `process`, `container` |
| `--similarity-threshold <f>` | `0.70` | Similarity threshold |
| `--verbose` | false | Enable verbose logging |

### Examples

```bash
# Build from a CSP directory (looks for manifest.json inside)
phalus build ./phalus-output/lodash/.cleanroom/csp/

# Build from a specific manifest.json
phalus build ./my-specs/lodash-csp/manifest.json --license apache-2.0

# Build in a different language
phalus build ./phalus-output/chalk/.cleanroom/csp/ --target-lang rust

# Full split workflow: generate CSP, review it, then build
phalus run-one npm/express@4.18.2 --dry-run
# ... inspect and optionally edit the CSP files ...
phalus build ./phalus-output/express/.cleanroom/csp/ --license mit
```

### Split pipeline workflow

The `build` command enables a split pipeline where Agent A and Agent B run as separate steps. This is useful for:

- **Reviewing the CSP** before committing to implementation
- **Injecting custom constraints** into the specification (e.g. security requirements in `03-behavior-spec.md` or `04-edge-cases.md`)
- **Reusing a CSP** to generate implementations in multiple languages
- **Iterating on the implementation** without re-running analysis

See the [Cookbook](cookbook.md) for detailed examples of these workflows.

---

## inspect

Display the contents of a completed job's output directory. With no flags, all sections are shown. Use individual flags to show only what you need.

```
phalus inspect <OUTPUT_DIR> [OPTIONS]
```

### Arguments

| Argument | Description |
|----------|-------------|
| `OUTPUT_DIR` | Path to the output directory written by `run` or `run-one` |

### Options

| Option | Description |
|--------|-------------|
| `--audit` | Show the audit log (timestamp, sequence number, event type per entry) |
| `--similarity` | Show similarity scores and verdict for each package |
| `--csp` | Show the CSP document list for each package |

If none of `--audit`, `--similarity`, or `--csp` are given, all three sections are shown.

### Example

```bash
# Show everything
phalus inspect ./phalus-output

# Show only similarity scores
phalus inspect ./phalus-output --similarity

# Show only the CSP inventory
phalus inspect ./phalus-output --csp

# Show only the audit log
phalus inspect ./phalus-output --audit
```

**Sample similarity output:**

```
=== Similarity Reports ===
  lodash@4.17.21:
    token_similarity: 0.1200
    name_overlap:     0.8900
    string_overlap:   0.1500
    overall_score:    0.2800
    verdict:          PASS
```

---

## validate

Re-run the validation stage on an existing output directory without regenerating any code. Useful for checking outputs against a different similarity threshold, or after manually reviewing generated files.

```
phalus validate <OUTPUT_DIR> [OPTIONS]
```

### Arguments

| Argument | Description |
|----------|-------------|
| `OUTPUT_DIR` | Path to the output directory to validate |

### Options

| Option | Default | Description |
|--------|---------|-------------|
| `--similarity-threshold <f>` | `0.70` | Similarity threshold for pass/fail |

### Exit codes

| Code | Meaning |
|------|---------|
| `0` | All packages passed validation |
| `1` | One or more packages failed |

### Example

```bash
phalus validate ./phalus-output

phalus validate ./phalus-output --similarity-threshold 0.50
```

**Sample output:**

```
PASS lodash (similarity: 0.2800, license: ok)
PASS chalk (similarity: 0.1900, license: ok)
FAIL express (similarity: 0.7200, license: ok)
```

---

## config

Print the active configuration, merging `~/.phalus/config.toml` with any `PHALUS_*` environment variable overrides. API keys are always redacted (shown as `***`).

```
phalus config
```

No options or arguments.

### Example

```bash
phalus config
```

**Sample output:**

```toml
[llm]
agent_a_provider = "anthropic"
agent_a_model = "claude-sonnet-4-6"
agent_a_api_key = "***"
agent_a_base_url = ""
agent_b_provider = "anthropic"
agent_b_model = "claude-sonnet-4-6"
agent_b_api_key = "***"
agent_b_base_url = ""

[isolation]
mode = "context"

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

---

## serve

Start the local web UI. The server binds to `127.0.0.1:3000` by default and is accessible only from the local machine.

```
phalus serve [OPTIONS]
```

### Options

| Option | Default | Description |
|--------|---------|-------------|
| `--host <host>` | `127.0.0.1` | Address to bind to |
| `--port <port>` | `3000` | Port to listen on |

### Example

```bash
# Default: localhost only
phalus serve

# Custom port
phalus serve --port 8080

# Bind to all interfaces (use with caution — no authentication)
phalus serve --host 0.0.0.0 --port 3000
```

After starting, open `http://127.0.0.1:3000` in a browser.

See [Web UI](web-ui.md) for a description of the interface and [API Reference](api-reference.md) for the backing REST endpoints.