// what's next · v0.6.4 · multi-ecosystem
§ 00 Roadmap npm → Go → beyond

From a Node.js scanner to install-time interception across ecosystems.

phi started as an npm-only behavioral scanner. It's becoming a supply-chain firewall that doesn't care which registry produced the bytes. This page is the overview; per-version release notes live in CHANGELOG.md.

Status legend

shipped released, on GitHub Releases, runnable today
in progress actively being worked on
next up committed direction, queued behind the in-progress item
horizon direction we're going, not committed to dates
out of scope explicit boundary — phi will not become this

Shipped

v0.6.4 — optional dependencies + install UX 2026-05-30

optionalDependencies are now resolved by default with platform-aware filtering. Modern dev tooling that ships native binaries this way — vite, rollup, esbuild, swc, lightningcss, sharp — finally installs cleanly. The resolver reads each package's os and cpu fields and silently drops platform mismatches the same way npm does; a packument failure on an optional entry is also silent. --omit=optional becomes meaningful and reinstates the previous strict behavior.

The install flow now runs in two phases: safe packages extract immediately after the scan, then the review prompt fires with the full per-detection breakdown inline — severity badge, detector, the why: description, the matched evidence:, and the file: path. No more scrolling up to remember what you're approving. Review-approved packages and any safes that were deferred because their closure touched a pending review then extract in a second pass.

Detector tightening, round 3: pdfjs-dist cleared to SAFE; next@16.2.6's @vercel/og TrueType font embed (String.fromCharCode(0, 1, 0, 0, …)) and node-html-parser's character-class boundary table both stopped firing. The eval bundler-recovery whitelist was rewritten exact-match plus __dirname-anchored to close a real security bypass — the previous "contains require(" rule accepted eval("require('child_process').exec('rm -rf /')"). Four attack shapes are now pinned in regression tests.

phi watch backend gains a /api/stats endpoint for the live headline package count, accepts $DATABASE_URL as the Postgres DSN (Railway / Fly Postgres plugin auto-wires), and the Dockerfile drops the VOLUME directive that Railway's Metal builder rejects.

v0.6.3 — detector accuracy, strict-closure, phi watch goes live 2026-05-29

The detector pipeline was tuned to clear false positives on popular bundled CLIs and packages with embedded binary data. prisma (score 100 → 35) and pdfjs-dist (90 → 20) no longer land in the BLOCKED tier: their hex-escape charset tables, embedded OpenType / TrueType fonts, bundler eval("__dirname") recovery shims, and .npmrc reads by legitimate native-binary installers all stopped tripping detectors without weakening coverage of real attacks. Six new regression tests pin the contract.

phi install gains --strict-closure / PHI_STRICT_CLOSURE: a CI gate that bails before writing phi.lock when any package would be pruned due to incomplete dep closure. Without the flag, partial-prune installs now exit non-zero so CI pipelines notice the incompleteness without re-reading the per-package warnings.

phi watch v0.1.0 ships as a public feed: a 24/7 poller scanning a curated watchlist, with anonymous package submission. The phi view <pkg> hint is now the suggested next step whenever an install is blocked — the per-detection evidence is one command away.

v0.6.2 — closure-consistency pruning during install 2026-05-23

phi install now iteratively prunes packages whose transitive dependency closure is incomplete — typically when a parent in the resolved tree has a dep that itself failed scan, was excluded by --omit, or has no available tarball. The previous behavior would install the parent with dangling refs, leaving node_modules in a state where requires could fail at runtime.

A fixed-point algorithm walks until no further pruning is needed, records each skip reason (blocked transitive, missing tarball, removed from tree), and surfaces the list of affected direct deps in the install report so the user knows exactly what to address.

v0.6.1 — npm installer resilience and verification 2026-05-23

npm installs are now best-effort: phi installs resolved SAFE packages first, reports unresolved packages after extraction, skips BLOCKED packages unless --force is used, and queues REVIEW packages for an explicit approval step.

Accepted REVIEW packages are remembered in phi.lock, so repeated installs do not ask again for the same accepted package version. CLI flags such as --yes and --no-advisories are parsed as installer flags instead of package names.

New phi check / phi verify validates package.json, phi.lock, installed package directories, cached tarball integrity, and installed files when a cached tarball is available. Registry fetches also gained retries, a longer default timeout plus PHI_REGISTRY_TIMEOUT, PHI_REGISTRY_ATTEMPTS, and PHI_REGISTRY_RETRY_DELAY for slow networks.

v0.6.0 — multi-ecosystem: Go modules support 2026-05-16

phi becomes a polyglot supply chain firewall. Auto-detects Go modules (go.mod, go.work) and routes to the new hybrid replace pipeline: shells out to go mod download into a phi-controlled staging dir, scans every fetched zip with the analyzer + OSV, then atomically materializes approved bytes into $GOMODCACHE. BLOCKED modules never reach Go's cache without an explicit override.

Full command surface: phi install, install <mod>@<v>, update, remove, audit, audit fix, outdated, upgrade-interactive, view, why, ls, build / test / run / vet / fmt, doc, replace / unreplace, init --go. Plus Go-toolchain aliases (phi mod tidy = phi install, phi get = phi install, phi mod verify = phi audit, etc.) and the universal phi go <anything> escape hatch.

Go workspaces (go.work) — multi-module monorepos walk every use directive with a per-member phi.lock and an aggregate verdict summary. Binary install (phi install <tool>@latest outside a project) gates global Go tools through the same scan pipeline before go install writes to $GOBIN. Vendor via phi mod vendor. Cross-compile sugar (phi build --cross linux/arm64). Replace /unreplace wrappers with cross-org-fork detection.

Six new Go-specific detectors: go-init-network, go-init-fs-write, go-cgo-shellexec, go-build-tag-gated, go-go-generate-curl, go-unsafe-import. Plus the project-level go-replace-with-fork. Schema-v3 phi.lock with a tagged source.type union covers npm and Go in one file. Verdict cache (h1-keyed, content-addressed) cuts warm-cache install time ~50%. .phi-allow persistent project allowlist. Retraction + deprecation warnings surfaced on install. sum.golang.org transparency status in audit footer.

v0.5.1 — phi view scans by default; live spinners 2026-05-16

phi view <pkg> now runs the detector pipeline + OSV check on the resolved tarball and prints a security: block (score, verdict, detections, advisories with fix versions) alongside the standard metadata. Same engine phi install and phi audit use — so you get the same verdict you would get if you installed the package, before you add it. --no-scan opts out for scripting; field-targeted queries (phi view react license) auto-skip. Spinners now cover phi view, phi outdated, and phi upgrade-interactive so long-running phases never look stuck. phi help rewritten and grouped by lifecycle.

v0.5.0 — workspace tooling and developer ergonomics 2026-05-15

The biggest single drop of CLI ergonomics so far. Tier 1 features: phi ls (npm-style ASCII trees), workspace: protocol (workspace:*, workspace:^1.0.0, path-relative form), phi link / phi unlink (Windows junctions, no admin), and phi do --filter (pnpm-style selectors). Tier 2: phi view packument inspector, phi config with secret redaction, phi pkg dot-path editing, and phi upgrade-interactive. Plus --omit=dev,optional,peer, env var equivalents (PHI_OMIT, PHI_CI, …), and phi cache clean --runs / --all-caches for stage cache eviction.

v0.4.2 — typed registry errors & resilient audits 2026-05-15

Registry failures now surface with the right shape: a non-existent package gets a clear not found · check the spelling or whether it's private instead of a raw 404 Not Found string. phi audit no longer dies on the first registry failure — transient or missing packages are recorded in phi-report.json's new skipped array and the rest of the tree is scanned. Registry fetches retry up to 3× with exponential backoff (500ms / 1s / 2s) + ±25% jitter on network errors, 429 rate-limits, and 5xx; Retry-After honored. The spinner now shows resolving... (retrying X · N total) so flaky networks are visible instead of looking like a hang.

v0.4.1 — phi ci for production installs 2026-05-11

phi ci is the canonical one-line install for non-interactive environments (Docker builds, GitHub Actions) — sugar for phi install --frozen-lockfile --yes. The frozen lockfile is the audit record: anything in phi.lock was already reviewed and approved by the developer during their local install, so prod can auto-approve review verdicts without a prompt. Blocked verdicts still abort unless --force. Plus two composable primitives: -y/--yes (auto-approve reviews on any install/update) and --omit=dev (skip devDependencies, npm parity).

v0.3.0 — phi x, scan-and-run like npx 2026-05-10

phi x <pkg> now mirrors npx: if the bin isn't already in node_modules/.bin, phi resolves the providing package, runs the full scanner + advisory pipeline over the transitive tree, then runs the bin from a per-version cache without polluting your node_modules. A scan-passed marker means repeat invocations skip straight to running. Pinned versions, scoped packages, bin-name-≠-package-name (phi x -p typescript tsc), and the -- separator all work the npx way. Lifecycle scripts stay off — phi-stricter than npx by design. Plus an animated resolver spinner with the first frame drawn immediately — no more silence between banner and progress.

v0.2.5 — robustness + better Windows experience 2026-05-09

Mid-install interruption can no longer corrupt your package.json. Bad packages can no longer crash a scan run. Friendlier first-run experience on Windows.

v0.2.3 — auto-fix + uniform progress UI 2026-05-08

phi audit fix [--apply | --force] — proposes safe fixes for typosquats, vulnerable versions, and deprecated packages. Preview by default; you opt in to applying. Scan progress now renders consistently across every shell we ship to.

v0.2.2 — supply-chain detectors 2026-05-08

Two new behavioral detectors targeting recent threat patterns (credential exfiltration flow + Linux system tampering), plus deprecation guidance for packages with safer successors.

v0.2.1 — self-update 2026-05-08

phi self-update brings phi current with one command. Verifies the new binary against published checksums before swapping.

v0.2.0 — scaffolding + force 2026-05-08

phi create bootstraps React, Next, Express, Fastify, or Nest projects — with the scaffolder itself audited first. --force escape hatch for packages you know you trust despite a flagged verdict.

v0.1.0 – 0.1.2 — foundation 2026-05-07

The install-time interception pipeline: 19 detectors (npm + Go), OSV vulnerability layer, lifecycle scripts off by default, lockfile + audit report, cross-platform binaries.

In progress

Code signing for Windows release artifacts

Cleans up the install experience on first run. Same binary, signed.

Next up

npm command parity and policy ergonomics

Continue tightening npm compatibility where it helps daily workflows: script shorthands such as phi check <file> when a project defines a check script, stricter/faster install modes, and clearer policy output for skipped, REVIEW, and BLOCKED packages.

On the horizon

Directional, not committed to dates. Order is rough priority.

Python (PyPI) ecosystem support

Rust (crates.io) ecosystem support

IDE integration

Live scan as you edit your manifest.

CI integrations

First-class GitHub Action, GitLab CI templates, drop-in for the major platforms.

Sandboxed dynamic analysis

Opt-in per package; results feed the same risk score.

Custom detector plugins

Strict trust model — signed plugins only.

Out of scope

phi will not become these things. Listing them here so the boundary is explicit.

Runtime sandbox

phi is install-time only. Once code is in node_modules/ and your app runs it, that's the application's concern — use container limits, gVisor, or an EDR for that.

Forced migration

phi.lock is a complete, integrity-verified lockfile — phi can be your only package manager, in CI, in Docker, in production. But if you'd rather keep package-lock.json / yarn.lock / pnpm-lock.yaml alongside for tooling that expects them, phi leaves them alone. Drop-in, not rip-out.

Telemetry / centralized policy

No daemon. No phone-home. Ever. Decisions happen on your machine, with your data, full stop.

Paid SaaS tier on the install path

phi stays free and open-source. Commercial offerings would be separate products built on top — never behind a paywall on the install path itself.

Influence the roadmap