Skip to content

v4.1.0

Latest

Choose a tag to compare

@github-actions github-actions released this 20 Aug 19:34
· 26 commits to master since this release
6cebeb5

Added

  • CUE code formatting support
  • CUE tree-sitter grammar
  • CUE Language Server support
  • CUE symbol and import extraction (refs #1522, #1519)
  • cue vet auxiliary runner for CUE evaluation errors (refs #1522, #1519)
  • Rendered-manifest validation for Helm charts, opt-in (refs #1283)
  • ast-grep rule: ban bare object parameter annotations (Refs #1597)
  • Ported anti-slop's AI-authorship rules into the shipped ast-grep catalog (refs #1718)
  • One primitive for "at most one execution per key" replaces ten hand-rolled copies (closes #1753)
  • Merge-train warden (refs #1844)
  • Add autofixes for mechanical ast-grep rules (refs #1850)
  • Record host-ready delay (refs #1859)
  • Three CI smoke lanes for the lifecycle/scope defect classes of the 2026-08 arc (refs #1605)
  • State-machine property tests for the availability latch (refs #1609)
  • Reset-interleaving test explorer (refs #1840)

Changed

  • Anti-slop rules: one promotion to error, six deliberate holds (refs #1727, refs #1777)
  • Credit external contributors ahead of v4.1.0
  • Docs: agent-guide reflects the stale-secrets ACTION NEEDED tier (refs #1522)
  • Codified live-binary discipline in AGENTS.md, per maintainer directive
  • Ast-grep authoring skills now teach the stopBy boundary idiom, the four-tier severity policy, and suppression-fixture discipline
  • Added the 2026-08-17 through 2026-08-20 recurring defect shapes to the agent catalog
  • docs: language-coverage lists mypy in the Python row
  • AGENTS.md: six new PR-discipline rules from the v4.1.0 review arc
  • One helper for bounded telemetry, and a sweep that keeps failure paths on it (refs #1743)
  • One generation guard instead of four hand-rolled ones
  • Consolidated three duplicated test-fixture families onto shared support helpers (refs #1816)
  • Workspace-scope LSP queries identify their serving client (refs #1854)
  • Turn-end madge circular-dependency check is opt-in, default off (closes #766)
  • Narrow no-non-null-assertion false positives (refs #1777)
  • A cascade that a slow prelude pushed out of the turn-end window now shortens its neighbour walk to land on time, when shortening it actually helps (refs #1462)
  • Promote laundering, unknown-return, and Reflect rules to errors (refs #1856)
  • Consolidate the registered-or-fail sweep machinery
  • Turn-simulation harness and a session-state lifecycle registry (refs #1635)
  • Test fixtures now match the real host's session_start/tool_result event shape (refs #1681)
  • Pinned trivy's dependency-CVE disposition filter with a regression test (refs #1813)

Fixed

  • Reach never-swept monorepo caches on workspace refresh (closes #1707)
  • LSP navigation verifies capabilities at the client boundary (closes #1826)
  • Distinguish a slow LSP warm spawn from no clients (closes #1875)
  • Avoid doomed waits for historically slow LSP spawns (refs #1884)
  • Re-arm direct-LSP and installer availability caches (closes #1897)
  • Bound the cascade tier-3 reconcile backlog and drop the dead neighbour-touch cache (closes #1899)
  • Avoid false read-guard blocks after formatter writes (closes #1903)
  • Credit search hits with the lines the search actually showed (closes #1904)
  • A size-capped write no longer says both "attached" and "too large to attach" (closes #1590)
  • Preserve biome's info/hint severity in dispatch
  • cuelsp's silent clean-open no longer reads as inconclusive (refs #1522, #1519)
  • Preserve ast-grep rule severity tiers through dispatch
  • Persist degradation-ledger decisions in latency.log
  • A write that already handed back its post-fix content no longer also tells you to re-read it (closes #1464)
  • Knip's per-turn delta no longer reads a shifted finding as newly unused (#1483)
  • A stalled PowerShell check no longer disables PSScriptAnalyzer for the rest of the session (closes #1490)
  • A silent auxiliary no longer reads as confirmed clean (closes #1493)
  • A stalled version check no longer disables eslint, credo or clippy for the rest of the session (closes #1494)
  • A stalled PATH lookup no longer disables a formatter until you edit a config file (closes #1495)
  • A stalled package-manager check no longer downgrades pi-lens's own managed installs to npm (closes #1496)
  • A repeatedly timing-out go install no longer re-compiles govulncheck every few minutes forever (closes #1497)
  • Tool-availability records now show what actually failed, and a failed auto-install is no longer a silent verdict (closes #1500)
  • Transient security-scanner probe records now carry their retry schedule (closes #1501)
  • Venv-resolved tool paths are no longer wrapped in literal quotes (closes #1508)
  • Auxiliary diagnostic waits and their outcome rows are now decided per file (closes #1531)
  • A silent auxiliary no longer reads as confirmed clean on batch scans either (closes #1533)
  • A failed grammar download no longer disables a language for the rest of the session (closes #1536)
  • A lazy install that dies on a network blip is retried instead of skipped for the session (closes #1537)
  • A stalled PATH probe no longer hands your project to its second-choice formatter for the session (closes #1539)
  • An execution-policy-blocked PSScriptAnalyzer run no longer reports the file as clean (closes #1540)
  • Fish had no LSP runner in the registry, and 21 extensions had no language id, because two seams were hand-copies of the language registry (closes #1545)
  • biome-client-dedupe test now isolates the in-flight probe dedupe from package-manager spawn count (refs #1546)
  • A captive portal can no longer poison a grammar file permanently (closes #1548)
  • A workspace sweep no longer speaks for a scanner that missed its deadline (refs #1549)
  • One slow scanner no longer discards every good answer in a cascade sweep (refs #1549)
  • Cascade "could not compute impact" records now name the file that actually caused it (closes #1550)
  • The availability-policy coverage gate no longer waves through a verdict that dodges the word "boolean" (refs #1552)
  • A resolved blocker no longer re-appears as "Unresolved from this turn" after pi-lens has confirmed the file clean (refs #1561)
  • A truncated grammar download no longer poisons the file permanently (#1564)
  • Tests no longer reset a duplicate copy of the module state they are guarding (closes #1565)
  • The availability-policy coverage gate no longer inherits routing from a memo that merely mentions a policy handle's name (refs #1566)
  • The ast-grep native-addon load no longer starves a concurrent caller or latches across sessions (refs #1567)
  • A stalled ast-grep binary no longer pins the whole session to npx (closes #1568)
  • A tool tier degraded by a transient stall no longer survives 24h across process restarts (#1569)
  • A failed lazy-module load or classic-tsserver repair no longer stays broken for the rest of the process (closes #1570)
  • Formatter config-file cache now sees files created mid-session, for several formatters that previously missed it (refs #1572)
  • psscriptanalyzer-format can now be selected for .ps1/.psm1/.psd1 files, and honors its settings file (closes #1572)
  • npm-global tool discovery now flags a stalled package-manager probe as transient (refs #1585)
  • A scanner that answered while its resync sat queued is no longer reported as a blackout (refs #1586)
  • TreeSitterClient.init() no longer replays a dead import() on every file parse (refs #1592)
  • The retained-winner arm no longer re-serves an ast-grep command this same sweep just proved gone
  • Basename-classified files (Makefile, Dockerfile.<suffix>) reached didOpen as plaintext, invisible to the #1545 extension-seam guards (refs #1594)
  • Seven more config-gated formatters were unselectable under any project configuration (refs #1595)
  • An exit-0 PSScriptAnalyzer run with empty or malformed stdout no longer reports the file as clean (refs #1598, refs #1540)
  • BiomeClient's in-flight leak guard could not fail (refs #1601)
  • PSScriptAnalyzer's execution-policy regex tightening now has regression tests (refs #1604)
  • Security scanners log a compensating available row when auto-install recovers a failed probe (refs #1606)
  • agent_end no longer misreads a disabled feature as a missing cache (closes #1607)
  • language: TypeScript ast-grep rules now run on .tsx files
  • Several installer writes and two persisted-state read paths did not survive a hard kill cleanly (refs #1609)
  • ~16 CLI runners now log recovery when auto-install fixes a failed tool probe (closes #1612)
  • Marking a secrets/security finding false-positive or won't-fix now sticks, on every reporting lane (refs #1617)
  • Idle-reset timer no longer destroys the LSP service mid-sweep (closes #1618)
  • LSP teardown no longer hangs on a wedged server, leaking the process (refs #1620, #1459)
  • LSP teardown: live-wedged proof, precise failure attribution, and safe idempotent shutdown (refs #1620)
  • Rename propagation no longer hangs on a wedged LSP server (refs #1621, #1620)
  • Cached secret findings no longer replay pre-edit line numbers (refs #1622)
  • Fix "age unknown old" grammar in lens_diagnostics cache-age notes (refs #1623)
  • lens_diagnostics now names every lane that did not run, instead of rendering silence as clean (refs #1623)
  • A blocking secrets finding can no longer be silenced by a loosely-matched mark (refs #1617)
  • Trivy secret findings now honor dispositions (closes #1628)
  • instance-reaper-prune-concurrency no longer times out flakily under CI contention (closes #1629)
  • knip no longer reports an export as unused after a new test imports it (refs #1630)
  • Cached cross-file blockers no longer replay for the whole session after the cause is fixed in a dependency (closes #1631)
  • Dependency-drift blocker freshness gate: review-round hardening (refs #1631)
  • Every agent-facing finding surface now either routes through the shared freshness/disposition gate stack or explicitly states its cache age — no more silent third state (refs #1634)
  • markdownlint and 14 other CLI runners now log recovery when the install-fallback helpers fix a failed probe (closes #1636)
  • createVenvFinder now checks the managed tools dir before falling back to PATH (closes #1638)
  • TypeScript diagnostic-sequence records now report a real settle duration, a real version, and a distinct source for every settle shape (closes #1639)
  • TypeScript diagnostics on files outside every tsconfig no longer block
  • Diagnostics no longer cite lines past the file's current EOF (refs #1641)
  • Past-EOF diagnostic gate review round (refs #1641)
  • Verify round: line-count memo keyed on size too (refs #1641)
  • Turn-end inline blockers now gate on past-EOF lines too (closes #1641)
  • A gitignored worktree edit could dirty the parent checkout (refs #1642)
  • The #1605 lifecycle-smoke lane's phase 5 now genuinely exercises an absent gh, and safeSpawnAsync decides a never-started spawn from the close event's own shape (refs #1651)
  • Package-manager availability latches re-arm at session_start (closes #1653)
  • Deferred format/autofix drain no longer runs mid-run on auto-retry or overflow-compaction (refs #1654)
  • Hardened pi-lens against five pi host-contract facts it mishandled (refs #1655)
  • safeSpawnAsync's post-exit pipe-idle wait no longer pays out its full 100ms grace window on every call (refs #1656)
  • safeSpawnAsync's post-exit pipe-idle wait no longer lets a late, unrelated error steal an already-decided healthy verdict (refs #1656)
  • safeSpawnAsync no longer hangs forever on a daemonized descendant that inherits its stdout/stderr pipe (refs #1656)
  • A compensating available row that corrected nothing no longer silences the real one
  • Pull diagnostics no longer miss whole categories on multi-source servers
  • LSP servers now learn about files a bash command deleted, even though pi-lens never sends workspace/didChangeWatchedFiles type 3 anywhere (refs #1668)
  • LSP client answers workspace/diagnostic/refresh and honors Incremental text sync (refs #1669)
  • Monorepo Cargo and Maven projects no longer spawn one heavy LSP server per crate or module (refs #1671)
  • Path-attribution follow-ups: bounded orphan degradation, documented id-fallback assumption, pinned reclaim test (refs #1678, #1642, #1648)
  • Bound the playground rule verifier's child-process wait (closes #1679)
  • The secrets and govulncheck gates' disposition filters are now proven, not just present (closes #1694)
  • Give findingPathFreshness the same mtime-skew tolerance its sibling freshness gates carry (closes #1708)
  • Give reconcileProjectDiagnosticsSnapshot the shared mtime-skew tolerance, not a bare +1ms (closes #1711)
  • Pull-diagnostic timeouts are observable again (refs #1713)
  • Full-scan sweeps no longer out-run an auxiliary scanner (refs #1714)
  • navRequest timeouts are observable again (refs #1716)
  • The ast-grep self-scan now actually runs (closes #1718)
  • A cascade's neighbor re-check no longer notifies auxiliary scanners
  • Knip now runs the project's own knip (refs #1721)
  • loop_block now names a synchronous block still in progress
  • loop_block now records every block over the floor, not only the session's biggest (refs #1723)
  • A forced LSP shutdown could leave the dead pid registered in instances.json for the rest of the session (refs #1724)
  • Sweep the remaining author-machine paths baked into scripts/ and package.json (closes #1728)
  • Managed tools now refresh instead of drifting stale (refs #1730)
  • taplo, biome, stylua, and vulture now prefer the project's own binary and config over pi-lens's managed copy (refs #1731)
  • Runner exit codes now gate clean vs. errored (refs #1736)
  • Managed tools from GitHub releases, pip, gem, archives and Maven now refresh too (refs #1747)
  • ruff S security rules now run by default; the IaC misconfig lane now actually scans (refs #1757)
  • Tree-sitter grammar wasms now refresh when the pinned version moves (refs #1760)
  • LSP resync timeout no longer blames a server still spawning (closes #1766)
  • runtime-session.test.ts no longer flakes under CI contention (closes #1767)
  • Genuine pull timeouts now count in the degradation ledger (#1771)
  • index-loop-block-wiring case (a) no longer times out flakily under load (closes #1772)
  • Diagnostic pulls no longer dispatch once the caller's budget is exhausted (#1773)
  • A pull timeout's abandoned request now traces server rejections, not just late answers (#1774)
  • Two more index-*-wiring test files budget their cold import (closes #1778)
  • session_start self-heals cachedExports after a starved sequence read (closes #1785)
  • workspace/symbol no longer goes to LSP servers that never advertised it (refs #1789)
  • blocker_freshness_sweep's population excludes cache-served diagnostic rows (closes #1790)
  • Clean workspace-diagnostics cache entries no longer replay across a dependency edit on a cold session
  • lens_diagnostics no longer double-counts error findings (closes #1799)
  • callHierarchy/incomingCalls and outgoingCalls no longer go to servers that never advertised callHierarchyProvider (closes #1803)
  • Biome findings can now reach actionable warnings
  • workspaceSymbol's no-filePath branch now picks a client that actually supports it (refs #1812)
  • A warm session's dependency index no longer vacuously clears files it never scanned
  • Actionable-warning and code-quality-warning ids now canonicalize the file path like disposition anchors already did
  • Session-state conformance coverage catches a new latch landing inside an already-registered file (refs #1817)
  • ast-grep-napi LSP supersede gate B tests now pin the gate, not the fallback (closes #1830)
  • require-safety-comment-for-as-unknown-as's SAFETY: valve no longer exempts every later cast in the same block (closes #1834)
  • Workspace-wide capability checks now describe every live client, not just the first (closes #1846)
  • require-safety-comment-for-as-unknown-as's SAFETY: valve now accepts a comment above an exported, class-field, or enum-member cast (closes #1847)
  • Resource sampling distinguishes failed process-table queries from empty samples (closes #1863)
  • Ignore zero-byte freshness reads (refs #1865)
  • Reuse knip results for unchanged project content
  • Identify TypeScript diagnostic sequence records
  • Accept SAFETY comments on object-literal members (refs #1870)
  • javac fallback skips classpath-less compiles inside Maven/Gradle projects (closes #1877)
  • Tally verified relative-path attribution guesses instead of logging one record per read (refs #1884)
  • Keep context-free compiler findings non-blocking (closes #1885)
  • Unverified path guesses remain visible (refs #1886)
  • The widget count now includes project self-scan findings
  • Formatter PATH availability re-arms at session start (closes #1895)
  • Coverage-marker dedupe key sorts with an explicit code-unit comparator.
  • Stale workspace-diagnostics cache entries now expire
  • A clean re-answer now clears a cached diagnostics entry
  • Surface silent LSP scanners to the agent (refs #1867)
  • Heal the LSP view after an untracked disk edit
  • no-non-null-assertion narrows two more idiom shapes
  • no-unknown-returns drops its callback/type-alias arm
  • Orphan backstop: off the session-start critical path, with verified kills (closes #1857)
  • Preserve pyright's information severity and fix its diagnostic positions in dispatch (closes #1802)
  • Eight ast-grep rules stop flagging correct code
  • Seven linters no longer report a clean file after a failed run
  • Project snapshot misses now name the rejecting gate (refs #1858)
  • Tree-sitter cache now spans a full-project scan
  • Two error-tier ast-grep rules now run in the CI self-scan

Security

  • A cascade sweep no longer blacks out the security scanner, and a blackout no longer reads as clean (closes #1459)
  • A stalled gh auth token probe no longer disables zizmor's online audits for the session (closes #1535)
  • Directory-scanning security lanes no longer scan pi-ecosystem scratch trees, and gitleaks recognizes placeholder secrets (closes #1562)

🙏 Thanks

Thanks to the external contributors in this release: