Pastor is an early-stage Rust engine for understanding and safely changing PHP and Laravel code.
It is being designed to build a structural and semantic view of an application, explain why a change is justified, and turn that evidence into precise source edits. The goal is not to guess from text patterns. Pastor should know which symbol it is changing, why the symbol is a candidate, and whether the edit remains safe to apply.
Pastor is currently an early foundation. The crate provides a request-mode command-line interface, the pastor.analysis.v1 contract, unified diff previews, and guarded application of the first supported edit. It is not ready for production use.
PHP applications are difficult to change safely at scale. Symbols can be reached through ordinary calls, framework registration, routes, container bindings, model conventions, serialization, or runtime configuration. A text match can find code, but it cannot reliably explain whether that code is live or whether changing it preserves the application.
Pastor aims to make these changes reviewable:
- model PHP symbols and their relationships structurally;
- combine source evidence with explicit Laravel runtime facts;
- report findings with the evidence used to reach them;
- identify edits by symbol and source range, not by fragile text replacement;
- reject stale, ambiguous, overlapping, or syntactically invalid changes;
- produce deterministic plans and diffs suitable for local review and CI.
Pastor is intended for maintainers of PHP and Laravel applications who need to inspect or automate changes across a real codebase without treating framework behavior as invisible magic. It should also provide a reusable engine for developer tools that need machine-readable analysis and controlled mutations.
- Evidence before mutation. Every proposed edit must have an explainable reason.
- Symbols over strings. Changes target structural identities and verified source ranges.
- Framework behavior is input. Runtime facts complement static analysis where source alone is insufficient.
- Preserve the source. Edit the smallest necessary spans so surrounding formatting and comments remain intact.
- Fail closed. Ambiguity, stale input, invalid syntax, or conflicting edits must stop the write.
- Plan before apply. Analysis, proposed changes, diffs, and writes remain separate, inspectable stages.
- Deterministic by default. The same project state and inputs should produce the same result.
The first milestone is one complete, conservative workflow for unreachable PHP symbols in a Laravel application:
- index project symbols and supported references;
- incorporate explicit framework entrypoints and runtime facts;
- emit evidence-backed reachability findings;
- create a mutation plan tied to symbol identity and a source hash;
- apply edits in memory, reparse the result, and show the diff;
- stage and revalidate every file, replace each file atomically, and attempt rollback if a later replacement fails.
That vertical slice must be covered by deterministic fixtures and runnable tests before the scope expands.
Run a checked-in request fixture to emit a pastor.analysis.v1 report:
$ cargo run -- --request test/fixtures/contracts/deadcode/controller-basic.json
$ cargo run -- --request test/fixtures/contracts/deadcode/controller-basic.json --check
$ cargo run -- --request test/fixtures/contracts/deadcode/controller-basic.json --applyPlain request mode emits the analysis report. --check recomputes the analysis against the current project, validates supported edits, and prints a unified diff without writing. --apply performs the same checks, stages every changed file beside its destination, revalidates source hashes, emits the diff, and atomically replaces each destination.
Only findings carrying a verified AST edit are writable; all other findings remain report-only. Each file replacement is atomic, but a multi-file apply is not crash-atomic. If a later replacement fails, Pastor attempts to restore files already replaced.
Pastor aims to become a reusable PHP code-intelligence and transformation engine: framework-aware analysis, evidence-backed rules, safe multi-file changes, stable machine-readable contracts, and a small embeddable core. Dead-code removal is the first proving ground, not the intended limit.
Future capabilities should be earned by real transformations and fixtures. Extensibility, native bindings, and additional framework knowledge belong on the roadmap only when the core analysis-to-mutation path is dependable.
- a general-purpose formatter or full-file pretty-printer;
- a large catalog of transformations before the first workflow is safe;
- automatic writes without an inspectable plan and diff;
- a stable dynamic plugin ABI in the initial release;
- complete modeling of every dynamic PHP or Laravel behavior;
- an editor, language server, or hosted service.
Pastor will prefer a narrow supported case with explicit evidence over a broad transformation that cannot explain or validate its decisions.