# Validation record

## 0.6.0 release validation

- Coordinator reran typecheck, full tests and installed-package checks after all workers finished: **134 passed, 2 Windows-native skipped, 0 failed**. Package allowlist: 44 files. `git diff --check` passed.
- Coverage includes actual Pi loader upgrade regressions, visible host-start success/failure, split-above/new-tab placement, pending mutation fences, and buffered log scrolling with PTY keyboard checks.
- An earlier overlapping build removed `dist` while another test run was executing. That run was discarded; the final validation above ran sequentially after worker settlement.
- No live Windows or new-Herdr visual result is inferred from these automated checks.


## Above-caller placement correction (local Linux)

- Installed `herdr-app --version` / `--skill` / `commands` and `herdr-core --version` / `schema` confirm app **0.1.13**, core **0.1.18**. No live user pane was mutated. App `pane.split` accepts only right/down; `pane.swap` has only a direction and depends on focus. App `layout.set` edits window chrome, not tab pane trees. No fictitious `up` API is used.
- Supported replacement: core schema documents `doc.set` as an atomic version-checked opaque document write that emits a doc event. App [mirror_sync.rs](https://github.com/herdrdev/herdr-app/blob/v0.1.13/src/mirror_sync.rs) uses that exact public API; [window.rs](https://github.com/herdrdev/herdr-app/blob/v0.1.13/src/window.rs) `documents_updated` consumes changed versions into the model; [layout.rs](https://github.com/herdrdev/herdr-app/blob/v0.1.13/src/layout.rs) `split` inserts after the caller in a column (reusing a same-axis parent). The adapter changes only those adjacent exact-ID leaves using one CAS and verifies above ordering in core and the app inventory before success.
- Legacy [v0.9.5 CLI reference](https://github.com/herdrdev/herdr/blob/v0.9.5/docs/next/website/src/content/docs/cli-reference.mdx) likewise lists right/down only, but explicitly supports `pane swap --source-pane ID --target-pane ID`. Version-tagged `src/cli/pane.rs`, `src/api/schema/panes.rs` and `src/app/api/panes.rs` confirm exact IDs, focus preservation and returned layout rectangles. The adapter checks that response's exact IDs and above geometry before shell submission.
- Creation, reorder and verification are separately fenced. No focus-based swaps, automatic mutation retry, live pane mutation, runtime/service-management edits or native Windows visual verification. A failure can leave the intermediate lower pane fenced; it is not success. Existing submitted records remain reused in place, including old below-caller records; tabs are unchanged.
- `npm run build`, `npm run typecheck` and `git diff --check` passed. Focused adapter suite: **91 tests, 90 passed, 1 native Windows skipped, 0 failures**. Full `npm test` on the shared working tree: **134 tests, 132 passed, 2 Windows-native skipped, 0 failures**. Includes top layout assertions, preservation of unrelated column nodes, CAS conflict/lost/invalid acknowledgement, stale app/core ordering, invalid pair, legacy wrong target/no-op/below/lost swap and read-only fenced reopen/reconnect. A disposable socket/pipe server exercises the production CAS transport; delayed observations do not repeat its write. These are source-derived fixtures, not a live visual smoke.

## Herdr app/core architecture increment (local Linux)

- `npm run typecheck` passed. `npm test`: **84 tests, 82 passed, 2 Windows-native skipped, 0 failures**. `npm run check:package`: **2/2 passed**, exact **29-file / 17-module** allowlist, actual installed tarball outside checkout and pack dry run. `git diff --check` passed. No version bump; package remains 0.4.1 until separately released.
- 35 new tests cover explicit backend selection, partial/mixed identities, Linux and mocked Windows direct argv (including drive/UNC/Unicode/metacharacters), unique caller mapping, sub-agent/remote/duplicate rejection, core labels/layout/permanent ID, app home/socket changes, read-only reuse, terminal incarnation/argv/lifetime replacement, pending-before-mutation persistence, lost acknowledgements, concurrent exclusion, core identity changes during launch and bounded/sanitized disposable socket transport. Existing legacy Linux and v0.4.1 Windows tests remain unchanged. Package tests assert the new compiled adapter ships and constructs installed-path argv without loading Pi peers.
- Read both installed `--skill` manuals fully, app/core help/command list and core schema. Versions were `herdr-app 0.1.13` and `herdr-core 0.1.18`; `hc` is available, legacy `herdr` is not required. Read-only core caller/status observations succeeded. **App `ls` and `status` reported no window at the default app home**; the requested installed `~/.config/herdr-app/AGENTS.md` did not exist. No successful live app hierarchy/launch response is claimed. Read the guide embedded in the installed binary instead, then checked version-tagged upstream source rather than inventing schemas.
- Contract sources: app [window.rs](https://github.com/herdrdev/herdr-app/blob/v0.1.13/src/window.rs) (`world`, `split`, `new_tab`, `agent_argv`), [model.rs](https://github.com/herdrdev/herdr-app/blob/v0.1.13/src/model.rs) (split focuses new pane/clears tab zoom), [hc.rs](https://github.com/herdrdev/herdr-app/blob/v0.1.13/src/hc.rs) (direct `terminal.run`, keep enabled, no caller/parent), [mirror.rs](https://github.com/herdrdev/herdr-app/blob/v0.1.13/src/mirror.rs) / `mirror_sync.rs` / `layout.rs` (persisted document schema), and core 0.1.18 schema plus [Windows transport](https://github.com/herdrdev/herdr-core/blob/v0.1.18/crates/herdr-core/src/platform/windows.rs) (local named pipe). Core CLI `connect`/ordinary observations can autostart core; the implementation deliberately uses bounded direct read-only socket/pipe RPC instead.
- **Behavior change:** new app/core opens a caller-targeted down split that receives tab focus and clears tab zoom. It does not preserve focus, restore focus, target an unrelated focused pane, or wrap argv in a shell. Cwd follows the caller/space; absolute CLI/config paths make project cwd unnecessary. Legacy non-focusing split/Windows encoded PowerShell remain preserved.
- No live app mutation, real terminal/service launch, app/core restart, worker, external message, Pi host API change, runtime/process-management change, helper, commit, push or release. All execution tests use disposable fixtures. Direct core observations return no terminal text or raw argv to the user.
- **Remaining verification:** native Windows named-pipe/Herdr direct argv and inherited cwd, native legacy PowerShell, TUI appearance/focus/zoom, recovery-shell behavior, app/Pi/caller closure and Windows console lifetime. Mocked Windows tests on Linux cannot prove these. A new-backend live smoke requires owner permission to change a display and an already-open app; explicitly start/authenticate the ServiceHost host separately. In the current app-less environment, panel operations fail safely rather than opening a window.

## Windows Herdr panel increment (local Linux, v0.4.1)

- `npm run typecheck` passed. `npm test`: **49 tests, 47 passed, 2 Windows-native skipped, 0 failures**. `npm run check:package`: **2/2 passed**, unchanged exact 28-file/16-module allowlist, installed-tarball checks and pack dry run. `git diff --check` passed.
- Deterministic tests decode the fixed PowerShell grammar and verify exact argv including spaces, Unicode, apostrophes, smart quotes and shell metacharacters; drive/UNC package URL conversion is tested. Mock Windows Herdr transport exercises complete open → persisted submission → reconnect/reopen without input, terminal replacement refusal and lost split/rename/run acknowledgement fences. The installed tarball is imported outside the checkout to verify its own bundled CLI and exact Node path in the Windows command.
- Consulted sibling Intercom launcher/monitor code read-only and installed `herdr pane split --help` / `pane run --help` for command contracts. No real Herdr mutation, real service, worker, external message, version bump, commit, push or publication. No Pi host API change or service/runtime lifecycle redesign.
- The new native Windows test uses Windows PowerShell to run only a disposable Node argv recorder (not Herdr or a service). It and the existing Windows service execution test are gated and skipped on this Linux host. **Native Windows PowerShell execution, live Herdr pane opening/reconnect/non-focus, TUI behavior and console-close behavior remain unverified here.** Deterministic/mocked Linux checks are not a Windows live smoke or proof of foreground readiness. Windows service limitations are unchanged.

## Pi integration increment (local Linux)

- `npm run typecheck` passed against pinned Pi 1.0.4 declarations.
- `npm test` passed: **43 tests, 42 passed, 1 Windows-native skipped, 0 failures**.
- `npm run check:package` passed: **2/2 package tests**, exact **28-file / 16-module** allowlist and pack dry run. Actual tarball installed outside checkout with scripts and peer auto-installation disabled (`--legacy-peer-deps --omit=dev`). Tests assert Pi/typebox are absent there and exercise standalone lifecycle and PTY panel/watch/follow.
- Five new integration tests cover inert mock Pi registration (16 focused tools), secret-safe malformed-config errors, sanitized panel errors, config validation/revision/concurrent writer exclusion, active/stale runtime guards, duplicate prevention after external apiPort edit, failed-bind guard cleanup, conflicting-port/no-fallback behavior, detached host reconnect, service status/start/restart/stop/shutdown, bounded/cancelled readiness wait, default log-text withholding and explicit sensitive-text opt-in, byte limits, terminal escaping and no credential-file parsing. Five mocked Herdr tests cover non-focusing creation, returned IDs, reuse without input, terminal mismatch, pending launch fencing (lost split/run acknowledgements), cross-process lock exclusion, Linux-only refusal, and disposable shell argument roundtrip. Packed-module path resolution and connect-only PTY display are also tested.
- `git diff --check` passed. Only Herdr help/skill and read-only current/list inspection were used; no live pane mutations, real project/service manipulation, models, nested workers, external messages, version bump, commit or publication. All process tests use disposable fixtures.
- A direct compiled-extension import against the local development Pi dependency succeeded (no session/model run). Extension tests mock the host module and registration API rather than starting Pi. The development host is pinned to 1.0.4; its permissive codemode transitive range resolved to an incompatible 1.4.0 export surface, so a scoped 1.0.4 override keeps that development import compatible. Scoped undici 8.12.2 removes reported high-severity dev advisories. These overrides do not replace the real host supplied by Pi or add standalone runtime dependencies.
- `npm install --ignore-scripts` reports **2 moderate development-tree advisories** (minimatch and the affected Pi dependency); no runtime dependencies are shipped. They remain an upstream development dependency limitation, not a claim of a clean full dependency audit.

Review `docs/pi-integration.md` for explicit limits: Herdr open/reconnect verify display identity, not foreground process readiness; log excerpts explicitly opt into potentially sensitive output and are not guaranteed secret-free; no real Pi session/visual approval or native Windows validation is claimed. Crash guards require independent manual reconciliation. Configuration mutation protection assumes cooperating processes and trusted local directories; older binaries/external editors do not honor the protocol.

## Interactive panel increment (local Linux, 2026-10-13)

- `npm run typecheck` passed.
- `npm test` passed: 33 tests, 32 passed, one Windows-native test skipped, zero failures.
- `npm run check:package` passed the installed-tarball test and exact allowlist dry run (22 files / twelve JS modules). Tarball installation uses `--ignore-scripts` outside the checkout, including the new default panel and retained prompt/ledger. Ctrl+L leaves fixture logs unchanged; quitting preserves its PID.
- Renderer tests verify exact cell widths/heights at 100×28, 80×24, 50×16, 32×8 and tiny sizes, including info, selection viewport, empty/loading/unavailable/pending/disconnected states, ANSI/OSC/C1/bidi neutralization and CJK/combining/emoji fitting. Controller tests cover serial requests, pending guard, captured action target, selection persistence, ambiguous outcomes without automatic action retry, and clear-during-read cursor advancement.
- A separate Python-standard-library PTY fixture uses an authenticated local mock API, **no child services**: actual function-key decoding, selection/list toggle, pending-action guard, Ctrl+L, resize, Ctrl+Q/q, SIGTERM and disconnect. It checks termios before/after plus cursor/alternate-screen restore sequences. Linux test prerequisites are `python3` and util-linux `script`; neither is a runtime/package dependency.
- `artifacts/panel-preview.txt` is an actual renderer-generated plain-text review artifact; it is not shipped. Frames were read/reviewed at the listed sizes. The layout now matches the requested legacy structure: compact service rows, full-width rules, selected logs and shortcuts/version only; no title, column headings or persistent connection banner. Tests cover F2 in the footer, transient notice expiry and disconnected cached-output warnings. No emulator screenshot, live Herdr test, native Windows TUI evidence or owner visual approval is claimed.
- No live services, Pi host dependency, external messaging, nested workers, version bump, commit, push or publication. Runtime API/lifecycle implementation and `FEEDBACK.md` are unchanged.

Limitations: ANSI/Unicode rendering conventions vary by terminal; byte-cursor boundaries may split UTF-8, stream interleaving is not timestamp ordering, long log rows are clipped, and cache eviction reattaches to a bounded tail. F5 is omitted. Handled signals restore the terminal; SIGKILL/power loss cannot run cleanup. Disconnection retries reads only. Existing runtime ownership/lease restrictions are unchanged.

## Previous feedback increment (local Linux, 2026-10-13)

The following records the earlier pre-panel run, not the current package manifest.

Environment: Node v22.23.3, npm 10.9.9. These checks cover the source increment; they do not establish npm publication. The owner separately verified installation and a disposable Linux smoke test of the **registry 0.1.0** package. Trusted Publisher configuration is owner-reported; no remote CI/OIDC/provenance run was inspected or claimed here.

Final local suite results: Tests use disposable projects and cooperative/self-expiring fixture processes; no real services, live Herdr manipulation, Pi SDK, nested workers, external messaging, account changes, commits, pushes or publication.

- `npm run typecheck` — passed strict TypeScript checking.
- `npm test` — passed: 24 tests, 23 passed, 1 Windows-native integration skipped, 0 failures.
- `npm run check:package` — passed build, 2/2 package tests, and exact allowlisted pack dry run. The manifest contains 20 files, including all eleven built JS modules. Source, tests, feedback, legacy references, secrets and runtime state are excluded.
- Package tests create an actual tarball in a temporary directory and install it with `--ignore-scripts`, invoking its installed executable bin outside the checkout: help/up/status/start/logs/watch/follow/log-inventory/reconnect/stop/shutdown. The installed live watch, follow, default prompt and `panel --live` also run under a disposable PTY using Linux util-linux `script` (required for this Linux test). Quitting leaves the same fixture PID running. Consecutive polls neither repeat unchanged status nor reread an unchanged log chunk. This is terminal protocol/output evidence, not a human visual review or evidence for every terminal emulator.

- `git diff --check` — passed.

### New coverage

Readiness: strict config bounds/closed endpoint grammar; expected response; mismatched status retries; refusal to follow redirects; oversized headers; hung endpoint/startup timeout; success without collecting a body; explicit cancellation; stop/restart launch-generation separation; natural exit cancellation with known exit code. Timeout leaves process/ownership intact. Status exposes a generic observation only, not response text or credentials.

Logs and views: API and Manager follow cursors, empty follow after catch-up, bounded chunk advancement, invalid cursors and byte limits, reset after restart or cursor beyond file size, escaped ANSI/C1/bidi output, narrow terminal wrapping without losing fields, one-shot non-TTY commands, installed PTY quit preserving services. Inventory covers bounds, active/historical retained files, symlink/directory/hard-link/unrelated-name exclusions, and byte-for-byte nonmutation. It does not prove inactivity or authorize deletion.

### Existing regression coverage retained

Disposable parent → child → grandchild fixtures validate cooperative Linux process-group drain, stop/restart with and without natural parent exit, portless ownership, shutdown fencing, old stdout/stderr preservation, and TERM-resistant descendants retaining leases on bounded timeout. Lost-anchor stop fails closed; runtime loss leaves survivors logging and a new Manager unable to signal or relaunch from a lease. An escaped setsid descendant explicitly demonstrates survival beyond group stop.

Authentication/project handshake, origin rejection, conflicting runtime port, listener identity, adoption identity mismatch, observe-only adoption, bounded log reads, status credential withholding, raw log caveat, reconnection, stale leases, failed-launch cleanup, config-relative paths, duplicate validation, Windows pure planner and native argv regression tests remain in the suite.

## Historical evidence and limits

The 2026-10-12 release-preparation suite had 19 tests (18 passed, 1 Windows-native skipped), and an eight-module/17-file package. That earlier run also checked workflow YAML/shell syntax and local publication-guard cases; those checks are not remote Actions execution and were not re-run for this runtime increment. No workflow changes are part of this increment.

Linux group signaling uses the live anchor's own `kill(0)`, not saved numeric PID/PGID authority. Drain uses non-atomic procfs scans, excluding zombies; escaping or hostile processes are not contained. No crash/reboot cleanup, zombie-reaping, malicious filesystem-race, power-loss durability or production-supervision guarantee is made. Trusted project directories and same PID/network namespace/readable procfs remain prerequisites.

Readiness is a bounded startup observation, not continuous health, process identity attestation, or a trigger for lifecycle actions. Fast restarts can skip historical log output and byte boundaries can split UTF-8. Inventory is bounded filesystem-order reporting, not an exhaustive disk usage audit; destructive retention is deferred because even stopped processes may have escaped descriptor holders.

Windows native batch/PATH/log/lease execution, ACLs, console closure and Job Objects remain deferred; Linux tests cannot certify them. See [Windows ownership design](windows-lifecycle.md). Remote Linux Node 22.19/24 CI, publication provenance and human terminal visual review are not established by this local record.
