# Tooling and hardening: in-place upgrades, request validation and core test coverage

- **`penguin update` upgrades an existing install in place.** `penguin update [--check] [--release <tag>] [-y|--yes]` resolves the newest version from the GitHub Releases API (the same source `install.sh` resolves `releases/latest/download` against) and upgrades using the mechanism the install actually came from, detected from the real path of the running CLI rather than guessed: a tarball install re-runs the official installer preserving its install dir and whether it bundles a Node runtime; a global npm/pnpm/yarn/bun install runs that manager's global install, and prints the command instead of guessing when the manager cannot be identified; a source checkout is refused with a pointer to `git pull` and a rebuild. Without `-y` it prints the mechanism, target version and install dir and asks for confirmation, and a non-TTY stdin requires `--yes` rather than blocking. The data root is never touched — only `bin`, `lib`, `web` and `node` are replaced. The target flag is `--release`, not `--version`, because the CLI's own `-v, --version` takes precedence over a subcommand option of the same name.
- The server now validates `positiveIntParam` and `optionalDateParam` inputs instead of trusting query strings — malformed paging/date parameters return a clean 400 rather than leaking into SQL or arithmetic.
- Core gained dedicated unit tests for `CappedTextBuffer` and `ToolCallIdAllocator`, two small pure modules that previously had no direct coverage.
