The scan
On September 21, Ghost Architect™ Local ran a Points of Interest scan of playwright-php/playwright on our own machines. The model ran locally, so no code left our network. The project is young, about a year old, but it is in real use: roughly 166,000 downloads on Packagist and around 60,000 a month. We posted what the scan found to the project as a GitHub issue, #173, and said up front that it was unsolicited and that the maintainers knew their code far better than a scanner does.
What we found, and what we recommended
Secrets in diagnostic output. The scan read src/Transport/Sanitizer.php, the code that masks credentials before errors are logged, and found that its patterns were narrow enough for some tokens to get through. It recommended broader patterns and tests for unusual token shapes. The maintainers opened #175, which redacts sensitive URL query values, including repeated and percent-encoded keys, and masks complete Basic and Bearer credentials.
Resources left behind after a browser closes. The scan flagged the browser cleanup path in the Node server, where pages were deleted with no handling if something went wrong, and warned that leftover references would build up in a long-running process. It recommended handling and logging cleanup failures. The maintainers found the real cause: closing a browser removed it from the registry before its pages were identified, so page registrations and context mappings stayed behind. #176 cleans up every context the browser owned. The scan’s explanation was not exact, but it pointed at the right place, and the people who know the code took it from there.
Popup failures that lost their cause. The scan found that when waiting for a popup failed, the caller learned only that it failed, not why. It recommended errors that say what kind of failure happened. #177 keeps the original error instead of reporting every failure as a timeout. While fixing it, the maintainers also stopped an early failure from terminating the Node bridge while PHP was still running its callback.
Pending work expired too early. The scan flagged the coordinator that tracks callbacks between PHP and Node, and how it cleans up after failures. #178 gives every operation its full timeout before its pending state is thrown away. Before, the coordinator could discard a callback after 60 seconds even when the operation was allowed to wait longer.
What the maintainer said
“We checked the findings against current main, and the report led us to four concrete fixes.”
“Each fix includes regression coverage.”
What they did not take, and what we changed
Not every finding held up, and the maintainer said so plainly. Several points were already handled on main. They did not reproduce three of the failures the report described, and they said its CRITICAL ratings were not supported by the cases they reproduced. They also refused one recommendation, to return the original value when the sanitizer hits an error, because that would expose the secret the sanitizer exists to hide. They were right. We have since built a rule into Ghost Architect™ Local that marks any fix which would make a security control fail open, and we are tightening how a finding earns a CRITICAL rating.
Why this matters
A scan is not a verdict. It is a map of where to look, handed to the people who know the code best. Here it led a busy maintainer to four real fixes, each with tests, in a library thousands of developers depend on, from an analysis that ran on our own hardware with no code sent anywhere. When a finding was wrong, the feedback made Ghost Architect™ Local better. That is how it is supposed to work.
Ghost Architect™ Local is out of beta and commercially released.
If you want an evaluation trial, the download page tells you how to get the tarball, verify it, and start the evaluation trial on your own hardware.
Request Ghost Architect™ LocalEJ Wisner, founder of Ghost Architect™. Local pricing is monthly, per team size, with no per-token bill; the numbers are on the pricing page.