// trust-zero install runtime · v0.6.0
§ 04 FAQ parity · false positives · ops

The questions everyone actually asks.

Honest answers about what phi does, what it doesn't, and how it co-exists with the rest of your toolchain.

Why doesn't phi run lifecycle scripts by default?

preinstall / install / postinstall in package.json is the single most-abused attack vector in npm. A compromised package can do anything as soon as you install it: download more code, exfiltrate environment variables, drop a backdoor. npm install runs these unconditionally.

phi treats lifecycle scripts as opt-in. Most packages don't need them; the ones that do (esbuild, sharp, native-binding installs) you allow per-package with --allow-scripts esbuild,sharp. This single decision closes the most common supply-chain vector.

How does phi differ from npm audit?

npm audit checks resolved dependencies against npm's vulnerability database after installation. phi does that plus:

Can I use phi alongside npm / yarn / pnpm?

Yes — phi reads package.json like the others and writes a separate phi.lock. You can keep your existing package-lock.json / yarn.lock / pnpm-lock.yaml for tools that expect them. phi never modifies them.

phi installs into node_modules/ the same way the others do, so any tool that resolves modules from node_modules/ (your bundler, your test runner, Node itself) just works.

What happens when phi blocks or flags a package I trust?

REVIEW-flagged packages prompt you. Read the report card to see which detector fired and decide.

BLOCKED packages refuse to install entirely. If you genuinely trust the package, you can lower the verdict by inspecting and opening an issue — phi's defaults are conservative and detector tuning is a public process.

If you want to install in spite of the flags, there's no global override flag — that would defeat the purpose. Either fix the detector pattern (PR welcome) or use npm install for that specific package while you investigate.

What if osv.dev is down or I'm offline?

Network failures are non-fatal. phi prints a warning that advisory data is unavailable and proceeds with just the static detectors. To skip the network call entirely (e.g. air-gapped CI), pass --no-advisories.

Does phi work on Windows?

Yes. The scanner, lockfile, cache, and resolver all work identically on Windows. node_modules/.bin/ shims are written as .cmd files; workspace siblings link as junctions (no admin privilege needed).

What about ARM64 (Apple Silicon, Linux ARM, AWS Graviton)?

Pre-built binaries are published for darwin-arm64 and linux-arm64. The install script auto-detects.

How do I install a private package from a self-hosted registry?

Add a .npmrc to your project (or $HOME) declaring the registry and an auth token. phi reads it the same way npm does:

@my-org:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:_authToken=${GITHUB_PAT}

The ${GITHUB_PAT} placeholder is substituted from your environment, so you can commit the .npmrc safely.

Why does Windows Defender flag phi as a virus?

It's a false positive. Defender's behavioral heuristics flag nearly every unsigned Go-compiled CLI binary on first encounter — same issue affects gh, cosign, goreleaser, and most security tooling built in Go. The pattern Defender flags (statically-linked binary, reads env vars, spawns subprocesses, fetches from network) is also the pattern a wave of Go-based Windows malware shares, so the heuristic catches both.

The phi install script verifies the binary's sha256 against the release's checksums.txt before handing it to Windows. If the install got past that check, the bytes are exactly what we published — Defender is wrong about what they do, not lying about a swap.

Unblock (run PowerShell as Administrator):

# Recommended: exempt the install location
Add-MpPreference -ExclusionPath "$env:LOCALAPPDATA\phi"

# Then re-run the installer
iwr -useb https://phi.philtechs.org/install.ps1 | iex

# Verify
phi version

Or, if you don't want a permanent exclusion, unblock the single binary after install:

Unblock-File "$env:LOCALAPPDATA\phi\phi.exe"
What we're doing about it: every phi release is submitted to Microsoft Defender Security Intelligence for false-positive review. Microsoft typically reverses incorrect detections within 24–72 hours; subsequent versions built with the same toolchain often inherit the trust. Long-term, code signing is on the roadmap (see GitHub issues for status).

How do I update phi?

Run phi self-update. It downloads the latest GitHub release archive for your platform, verifies the sha256 against checksums.txt, and replaces the running binary in place. --check reports whether an update is available without installing it; --version v0.X.Y pins to a specific tag; --yes skips the confirmation prompt.

Don't confuse with phi update. That command re-resolves your project's package.json dependencies. phi self-update replaces phi itself.

If self-update can't run (no internet, write-protected install dir, or you'd rather not trust it), re-running the install one-liner always pulls the latest release: curl -sSL https://phi.philtechs.org/install.sh | sh on Linux/macOS, iwr -useb https://phi.philtechs.org/install.ps1 | iex on Windows.

Does phi have something like npm audit fix?

Yes — phi audit fix. Three differences from npm's version:

After applying, run phi install to materialize the new versions.

How do I deploy with phi in Docker or GitHub Actions?

Use phi ci (v0.4.1+) as your install step. It's sugar for phi install --frozen-lockfile --yes — designed for non-interactive environments where there's no stdin for phi's REVIEW prompt. The frozen lockfile is the audit record: any package in phi.lock was already reviewed and approved by a developer locally, so prod can auto-approve REVIEW verdicts without hanging. BLOCKED verdicts still abort unless --force is explicit.

# Dockerfile
COPY package.json phi.lock ./
RUN phi ci --omit=dev

# GitHub Actions
- run: phi ci --omit=dev

--omit=dev skips devDependencies (test runners, linters, type defs, build tooling) — npm parity. Both --omit=dev and --omit dev are accepted. Pass -y/--yes standalone on phi install or phi update when you want auto-approve without the rest of phi ci's defaults.

If phi.lock is missing or doesn't cover package.json, phi ci errors loudly — there's no silent fallback to a fresh resolve, which is the whole point in CI.

Does phi have an npx equivalent?

Yes — phi x (in v0.3.0+). It's the same alias phi exec has always been, but extended to fetch + scan + run when the bin isn't already in node_modules/.bin:

phi x cowsay "hello phi"           # fetch, scan, run
phi x prettier --write src/        # args go to the bin verbatim
phi x cowsay@1.5.0                 # pin a specific version
phi x -p typescript tsc --version  # bin name (tsc) ≠ package name (typescript)

Three meaningful differences from npx:

For strict local-only behavior (the pre-v0.3.0 contract), pass --no-install. --rescan invalidates the cache; -y auto-approves review verdicts for CI / scaffolding; -f overrides blocked verdicts.

How does phi create work?

phi create <framework> <name> scaffolds a new project. Five frameworks ship in v0.2.0: react, next, express, fastify, nest. For four of them (everything except express), phi installs the canonical scaffolder package (create-vite, create-next-app, fastify-cli, @nestjs/cli) into a temp directory through phi's normal scan + extract pipeline (lifecycle scripts off — same as phi install), then invokes the scaffolder binary in your current directory. The temp directory is wiped after a single use.

For express, no canonical npm scaffolder exists, so phi ships a minimal Express template embedded in the binary itself via Go's embed.FS — no network fetch is needed.

Pass-through args after -- reach the scaffolder verbatim, and user flags override phi's baked-in defaults on flag-name collisions:

phi create react my-app
phi create next my-site -- --typescript --app
phi create express my-server

What's not supported?

Why isn't there a detector for X?

Likely either it's planned (open an issue), or it produces too many false positives at the regex/AST level (phi is conservative about what fires). The thirteen detectors are tuned against a real-world corpus (including discord.js, undici, grammy, ajv, fastify, axios, …) to keep noise low; expanding the set requires the same tuning work.

Is phi production-ready?

v0.6.x is feature-complete for typical Node.js and Go projects: 19 total detectors (13 for the npm ecosystem, 6 Go-specific), OSV layer for both ecosystems, project scaffolding (phi create for Node frameworks, phi init --go for new Go modules), npx-equivalent phi x for npm and binary-install (phi install <tool>@latest) for Go, and built-in updates (phi self-update). The real-world npm corpus and Go module corpus both install cleanly with no false-positive blocks. Expect breaking changes in 0.x as the detection model evolves — pin to a specific version in CI.

Which ecosystems does phi support?

As of v0.6.0, phi covers two:

phi auto-detects the ecosystem from your cwd. When both manifests are present in one directory, pass --ecosystem=npm or --ecosystem=go (or set PHI_ECOSYSTEM) to disambiguate.

Other ecosystems (PyPI, crates, Maven) are out of scope for v0.6.x — they'd each need a per-language detector suite, and we'd rather ship two languages well than four poorly.

What if phi blocks a package I trust?

Pass --force (or -f) to phi install / phi update. The scan still runs and phi-report.json is still written — phi's audit trail is preserved — but the install proceeds despite BLOCKED verdicts. A loud warning lists every forced package. Use this when you've reviewed the report and accepted the risk (e.g. discord.js ships an internal _eval() method that fires phi's Arbitrary Code Execution detector — a legitimate detection on a legitimately trusted library).

Where do I report bugs / feature requests?

Email bugs@phi.philtechs.org, or open an issue at github.com/philtechs-org/phi/issues. Especially valuable: false-positive reports against real-world packages, and missed-malware reports against known-bad packages. Include the package name, version, and what phi said vs what you expected.