v0.5.19 2026-09-29
Added
python deploy.py --skip-systemruns the deployment without Phase 1: no package manager is invoked and nosudoruns, so a machine whose packages are already installed, or an operator or agent without sudo, can still deploy. The phase prints the manual package, Go tool and Python package list instead, and the run continues into the remaining phases. With the flag, a distribution whose package manager cannot be detected warns and continues, rather than exiting before any other phase ran.
Fixed
python deploy.py --skip-system --with-msfno longer reports Metasploit as installed. Skipping Phase 1 skips the only step that installs it, so the closing banner now says it was skipped, matching the warning printed at the top of the run. The undetected-package-manager exit is unchanged for a run that does not pass the flag, where a missing package manager is still fatal.
Changed
- The manual install list โ packages, Go tools, Python packages โ is written once, in
print_manual_install_list(), and printed by both the undetected-package-manager path and--skip-system, so the two messages cannot drift apart. The unflagged run prints exactly what it printed before, in the same order.
v0.5.18 2026-09-28
Fixed
- The CI check on the published suite's size now runs. It could not measure the figure it asserted: the project declared no build system and no package set, so
pip installfailed in the backend's discovery before a single test was collected, and the strip step the count depends on lived inside the release pipeline's own script, which the job never invoked. The job installs.[core,dev,report], builds a release tree the way this repository's pipeline builds one when the site fixtures are present, measures in place when they are not, and names each failure rather than stopping on an unbound variable.
Changed
- The release pipeline's strip loop is a script of its own, used by the pipeline and by the count job, so what a release tree contains has one implementation instead of two that can drift apart. Its guards fail closed: it refuses to strip a source checkout in place, refuses an absolute pattern or one carrying a
.., refuses any match resolving outside the tree โ validating every match before removing any, so a refusal leaves the tree untouched โ and refuses a pattern that would withhold the whole tree at exit 0, judged against the entries that pattern can actually match. A slash-spelled entry names a directory and no longer removes a regular file of that name or a symlink pointing at one; a pattern whose every component is a wildcard is refused rather than silently stripping a level; and a pattern that operates inside directories is no longer judged against the top-level entry count, which refused a deep glob that touched no top-level entry at all.
v0.5.17 2026-09-27
Fixed
- The theme toggle now honours the choice made on any page, on every page. Two of the site's pages โ
dependencies.htmlandwireless.htmlโ kept their own copy of the theme script written against a storage key of their own, so a theme chosen anywhere else was ignored on those two and they moved together with each other. All ten pages now load one shared implementation from a single script: the theme is stored under one key, a value left by the old key is migrated once on the first page visited after this release, and a first visit to either of those two pages now follows the operating system preference rather than the markup's default.
v0.5.16 2026-09-26
Changed
- The release boundary check now accounts for every byte of every file it reads. Instead of trusting each reader to declare the ranges it handles, the check records what each reader actually consumed and fails the release when a byte inside a container was read by no reader โ so a reader that skips a range, or a call site that stops passing a declaration another call site passes, is a failed check rather than a hole in one. A declaration is satisfied only by a decoded range and never by a claim; where a reader stops at a read cap, its claim is trimmed to the bytes it actually read and the trim is reported; and an archive the check refuses to open beside one it accepts reports the refusal rather than dropping it. Verified against a tree built the way this repository builds one: the file count, the scan-through reads, the six conditions and the cleared-line count are unchanged, the coverage audit is clean, and the run exits 0.
v0.5.15 2026-09-26
Added
- A CI check on the size of the published test suite:
tests/public-suite.jsonpublishes the figure this tree is expected to collect โ **557 tests**, measured on a release tree built the way this repository's pipeline builds one โ together with what that run reported (38 failed, 515 passed, 4 errors, broken down by file) and why the subset behaves that way..github/workflows/public-suite.ymlruns on pull requests, installs.[dev,report], and fails when the collected count differs from the published figure. It deliberately does not run on pushes tomain, whichpr-gate.ymlguards.
Changed
tests/integration/test_pipeline_smoke.pyand thegit fetchtest intests/test_uat_wired.pynow declare thenetworkmarker they always depended on. The smoke module's own docstring said it required network and nmap while declaring onlysmoke; a run with-m "not network"is clean now, and no test lost coverage.
Removed
- The skill directories that used to ship alongside the tools: two
SKILL.mdfiles and the test that validated their shape. This tree carries the tools and their documentation; how to wire them into an agent isreferences/agent-integration.md, which is where a reader of this tree finds it.
v0.5.14 2026-09-25
Added
- Synthetic sample reports on the website. The sample gallery's six images are generated from an invented assessment rather than captured from a real one:
tools/sample-findings.jsonholds the fixture (six example findings on the documentation range192.0.2.0/24, reserved example hostnames, real public CVE identifiers),tools/make-sample-report-images.pyrenders it throughreport-gen.pyand draws a label under every image, andapproved-assets.jsonpins the six hashes. - A release boundary check:
scripts/boundary-check.py, run against the exported tree before anything is published, failing closed on six conditions โ a stripped path referenced by a shipped file, a stripped path present in the tree, a private path written into the copy, a shipped instruction naming something that is not there, a learnings marker, and an asset manifest that does not account for every file in the assets directory. It reads archives and the members inside them, PDF content streams, PNG text chunks and the UTF-16 encodings of all of it; a file it cannot read in full fails the run rather than passing unexamined. - Agent integration documentation in
references/agent-integration.md: how to wire PortShim into an agent's own skills and instruction files, with the commands, replacing the installer that used to do it.
Changed
- The seven pipeline scripts moved to
scripts/at the repository root, so the tree that holds them is no longer a mix of published code and internal notes. scripts/report-gen.pytakes the assessment date as an input โ--assessment-date, orPORTSHIM_REPORT_DATEโ with the month spelled from a fixed table so the output does not depend on the host locale, and a malformed date is an error rather than a silent fallback to today. The target network is read from the findings.- The
reportextra requires WeasyPrint andpillow>=10. - Shipped documentation re-pointed at paths that exist in the published tree; a page describing a directory as it sits in the development repository now describes the published layout.
- Site copy: a footer credit pointing at an unrelated third party replaced with the product name, and a retired internal placeholder name removed from the pages and the README.
- The landing README's learnings section removed; the guidance it summarised is on the site's own pages and in each tool's
--help, which is where a reader of the published tree finds it.
Fixed
scripts/render-docs.pyderived its operator-guide directory from a path that does not exist in a published tree and could not be pointed anywhere else. It now takes--all-guides DIRand exits with a message when it cannot resolve one.- The publishing pipeline no longer exports a tree it has not checked. The landing page is read from the committed revision rather than the working copy, so a file no commit has seen cannot ride into a release, and the run refuses to start while any of its own inputs is uncommitted.
v0.5.13 2026-09-21
Added
- External tool dependency reference (
references/tool-dependencies.md) โ every tool PortShim shells out to, which pipeline phase uses it, whether it is required or optional, and what stops working when it is absent. The inventory is derived fromdeploy.pyso it cannot drift from the installer. - Dependencies page on the website (
pages/dependencies.html), linked from the feature grid and from the requirements section.
Fixed
portshim wireless selectandportshim wireless assessnow honour--output-dirfor scan discovery, not only for writing results โ previously the flag was accepted but discovery always searchedoutputs/wireless/.portshim wireless selectnow exposes--output-dir,--auto,--max,--forceand--list. Its forwarding block already read all five, so four were unreachable and--maxwas silently ignored.- An explicit
--max 0is honoured instead of being dropped and falling back to 5.
Changed
- Wireless tests are hermetic: the graceful-failure tests use an isolated output directory, and the association test patches the interface probe rather than requiring a host
wlan0. - README System Requirements corrected โ the tool list links the new reference, and the Python row no longer implies
requests,fpdf2andparamikoare used (no code imports them). - Executive summary no longer describes subfinder as a Phase 1 recon tool โ it is installed but not wired into the pipeline.
- Knowledge sources re-synced (NeuroSploit 4.2.0, nuclei, httpx, nmap-vulners, Anthropic Cybersecurity Skills) and the
nmap/nmapsource dropped โ it pointed at a path that does not exist upstream, so it could never sync. - Website requirements card trimmed to the essentials; Python floor stated as 3.10+ to match
pyproject.toml.
v0.5.12 2026-07-17
Added
portshim discoversubcommand โ automatic VLAN/subnet discovery from the current machinevlan-subnet-discoveryHermes skill โ reusable manual workflow for the same task
Changed
- Landing page Quick Start and README updated with
portshim discoverexamples
v0.5.11 2026-07-14
Fixed
- Release pipeline: stripped conflicting GitHub Action from public repo (was force-pushing stale HTML over script push, causing version/changelog to never update)
- Release pipeline: changelog regex backreference fixed (
\1not\\1) - Release pipeline: reminder to commit source version bumps added
Added
- NIC comparison diagnostic script (
scripts/diag/compare-nics.py)
Changed
- Hardware guidance: Dell USB-C (Realtek RTL8153) recommended for wired scanning
- D-Link DUB-1312 (ASIX AX88179) added as tested backup adapter
- Warning added: avoid ASIX adapters on generic cdc_ncm driver
- Warning added: do not scan wired networks over WiFi (ARP broken)
- Warning added: dock Ethernet shares DisplayLink bus โ dedicated adapter preferred
- Landing page: requirements + FAQ updated with NIC selection guidance
- Operator guide: quick start and pre-engagement checklist updated
v0.5.10 2026-07-14
Fixed
- Release pipeline: version bump source HTML now committed (prevented stale footer/title)
- Release pipeline: changelog regex backreference fixed (
\1not\\1) - Release pipeline: reminder to commit source version bumps added
Added
- NIC comparison diagnostic script (
scripts/diag/compare-nics.py)
Changed
- Hardware guidance: Dell USB-C (Realtek RTL8153) recommended for wired scanning
- D-Link DUB-1312 (ASIX AX88179) added as tested backup adapter
- Warning added: avoid ASIX adapters on generic cdc_ncm driver
- Warning added: do not scan wired networks over WiFi (ARP broken)
- Warning added: dock Ethernet shares DisplayLink bus โ dedicated adapter preferred
- Landing page: requirements + FAQ updated with NIC selection guidance
- Operator guide: quick start and pre-engagement checklist updated
v0.5.9 2026-07-14
Added
- NIC comparison diagnostic script (
scripts/diag/compare-nics.py)
Changed
- Hardware guidance: Dell USB-C (Realtek RTL8153) recommended for wired scanning
- D-Link DUB-1312 (ASIX AX88179) added as tested backup adapter
- Warning added: avoid ASIX adapters on generic cdc_ncm driver
- Warning added: do not scan wired networks over WiFi (ARP broken)
- Warning added: dock Ethernet shares DisplayLink bus โ dedicated adapter preferred
- Landing page: requirements + FAQ updated with NIC selection guidance
- Operator guide: quick start and pre-engagement checklist updated
v0.5.8 2026-07-13
Fixed
- Root cause: git init + force push creates orphan commits GitHub
v0.5.7 2026-07-13
Fixed
- Add hard verification of version bump before pushing public repo
- Add debug output to trace bump/push pipeline
v0.5.6 2026-07-13
Fixed
- Robust version bump: per-file loop with verification replaces
v0.5.5 2026-07-13
Fixed
- Release script now bumps the site source versions too,
v0.5.4 2026-07-13
Fixed
- report-gen.py: outputs to timestamped subdirectory (wired-{ts}/)
v0.5.3 2026-07-13
Added
- Changelog page uses full site template (nav, CSS, theme, footer)
- Release guard: rejects release if CHANGELOG.md missing version entry
Fixed
- Footer link opens in new tab (target="_blank")
v0.5.2 2026-07-13
Added
- Auto-generated changelog page on website (pages/changelog.html)
- GitHub Releases auto-created with changelog notes on release
- CHANGELOG.md backfilled from v0.4.0
v0.5.1 2026-07-13
Fixed
- Move hashid from system packages to pip (hashid is a Python package, not a system package)
v0.5.0 2026-07-13
Added
- masscan, macchanger, john, hashid, exploitdb to deploy.py base install
- Also added missing hcxdumptool, hcxtools, hashcat to deploy.py
- PACKAGE_MAP completeness test to prevent future tool drift
v0.4.5 2026-07-13
Fixed
- MAC spoofing: interface left DOWN on failure (added finally block to bring it back up)
- test_report.py: tempfile leak on subprocess failure (fixed cleanup)
- searchsploit: added per-CVE caching to avoid redundant lookups
- Removed dead --force flag from network_scan.py
- Removed unreachable except block in run_john
- Simplified crack_auto dead fallback expression
v0.4.4 2026-07-13
Added
- Test report generation:
test_report.pysaves results tooutputs/reports/{wired,wireless}-{timestamp}/ - Structured JSON + human-readable summary per test run
- Auto-detects wired vs wireless from test file paths
v0.4.3 2026-07-13
Added
- searchsploit CVE-to-exploit lookup in
generate-findings.py - Findings now include
exploit_available,exploit_paths,exploit_count - john + hashid as alternative cracking backends in
wireless_crack.py crack_auto()tries aircrack โ hashcat โ john in priority order- MAC spoofing support:
get_current_mac(),spoof_mac(),restore_mac(),random_mac()inwireless_hardware.py - masscan fast host discovery via
network_scan.pywith nmap fallback
Fixed
- Double nmap call when masscan fails (Claude review)
- Removed unused
output_formatparameter fromrun_masscan
v0.4.2 2026-07-13
Added
- PMKID passive capture via
wireless_pmkid.py(hcxdumptool โ hcxpcapngtool โ hashcat) - Auto-fallback to PMKID capture when airodump-ng returns zero handshakes
Fixed
- Band suffixes: removed invalid
{ch}bfor 2.4 GHz channels (hcxdumptool convention: a=2.4, b=5, c=6) - Process timeout: use
timeout --kill-after=5instead of raw process group kill - Timestamp correlation between capture and hashcat output files
- Secure output path: write to OUTPUT_DIR instead of /tmp
- Root privilege check before PMKID capture
- Zero-size hcxpcapngtool output detection (no PMKID hashes)
- MT7921AU USB adapter classification via
DEVTYPE=usb_*fallback - Landing page version regex: replace ALL vX.Y.Z patterns, not just previous tag
v0.4.1 2026-07-11
Fixed
- PDF report: prevent table rows from splitting across pages
v0.4.0 2026-07-11
Changed
- Consolidate CVEs per host:port into single findings