.omo/evidence/omo-senpi-adapter/20260729-lsp-sweep-version/README.md
This QA covers the Senpi startup process sweep after wiring the effective LSP
daemon runtime version into sweepStaleLspDaemonVersions, including supported
paired CLI/version overrides, isolating runtime resolution to that cleanup family,
and stabilizing the diagnostics freshness integration
coverage that failed on the loaded macOS runner.
Command:
bun test \
/home/minpeter/.local/share/oh-my-openagent-senpi-pr/packages/omo-senpi/src/components/task/process-sweep.test.ts
Observed before the implementation:
error: stale-version sweep was not called
5 pass
1 fail
This proves the session-start path did not honor the injected packaged-version resolver and family sweep dependencies before the wiring seam was implemented.
Command:
bun test packages/omo-senpi/src/components/task/process-sweep.test.ts
Observed before moving daemon resolution into the stale-version family:
error: unrelated cleanup families did not complete
6 pass
1 fail
The injected daemon resolver threw before the three family-level best-effort boundaries started, reproducing the review finding.
The packaged daemon is version 0.1.0, while the regression fixture starts a
paired override contract at version 9.8.7 with a real temporary CLI path.
Before the fix, startup passed no environment to the resolver and selected
0.1.0 as current:
Expected: "9.8.7"
Received: "0.1.0"
7 pass
1 fail
That incorrect current version makes the live 9.8.7 owner a stale candidate.
After startup began resolving the same effective runtime contract as the daemon,
the test ran the real stale-version sweeper and proved only PID 100 from
v0.1.0 was terminated while active override PID 987 remained alive. Ten
repeated runs passed:
10 pass
0 fail
30 expect() calls
The resolver parity cases also reject an unpaired override, relative CLI, directory CLI, and invalid version exactly as the daemon client does:
4 pass
0 fail
8 expect() calls
The current-head security review reproduced two unsafe behaviors in the original PID-only sweep authorization:
TERM:4242:attested-daemon
ALIVE:4242:unrelated-replacement
KILL:4242:unrelated-replacement
It also proved that an unrelated node ... cli.js daemon command satisfied the
legacy argv matcher. The stale-version family now preserves the complete owner
record, re-reads it, authenticates omo/ping (params._omo.{protocolVersion, token}) with the version daemon.auth token, and compares PID, nonce, start
time, endpoint path, and socket identity. The same owner-bound proof runs during
planning, immediately before SIGTERM, and again before SIGKILL; uncertainty
spares the PID.
Deterministic regressions prove generic argv is insufficient and an identity
change after TERM never receives KILL. One case drives the real
packages/lsp-daemon/src/request-routing.ts router so the wire envelope cannot
drift, and one pins the daemon.auth token path:
19 process-sweep family tests pass
5 owner-attestation tests pass
0 fail
Command:
bun test \
/home/minpeter/.local/share/oh-my-openagent-senpi-pr/packages/omo-senpi/src/components/task/process-sweep.test.ts
Observed after the implementation:
8 pass
0 fail
12 expect() calls
The added assertion dispatched the real session_start handler, resolved the
distinct "9.8.7" sentinel through the version-resolution seam, and observed
that value at the stale-version sweep dependency. The override assertion also
uses 9.8.7, deliberately different from packaged 0.1.0, so the test fails
if startup ignores the effective runtime environment.
The isolation assertion also injects an unreadable daemon metadata error and proves that CodeGraph and orphaned-proxy cleanup still complete while only the stale-version family logs a skip.
The failed macOS CI run expected the first pull result stale-pull but received
[] before any cache invalidation occurred. The child-process integration case
used a 60ms freshness budget, which is also the pull request timeout; under the
loaded runner the first response missed that budget.
The two pull-fallback cases now use the existing 500ms integration-test budget. Both cases were repeated 20 times:
40 pass
0 fail
120 expect() calls
The complete lsp-core package also passed:
92 pass
0 fail
277 expect() calls
The refreshed macOS run proved the diagnostics fallback fix, then exposed two independent timing assumptions elsewhere in the root suite:
survivor.pid.The reconcile failure reproduced locally 20 times in 1,000 runs. The corrected assertion verifies the actual invariant: exactly one child is terminated and disposed, and the surviving child remains the manager owner regardless of start order.
1000 pass
0 fail
5000 expect() calls
The CodeGraph fixture now starts a readiness listener before spawning the
command. After the descendant writes its PID and signals that listener, the
test resolves an injected timeout trigger that runs the same process-tree
termination path as the production timer. The standard AbortSignal listener
is removed when the command settles. This removes wall-clock startup from
the asserted behavior.
100 pass
0 fail
200 expect() calls
Affected package gates:
senpi-task: 1035 pass, 0 fail
codegraph-bootstrap: 21 pass, 0 fail
workspace typecheck: exit code 0
After materializing the repository's ignored build prerequisites with
bun run build, the full root suite passed:
12518 pass
3 skip
0 fail
42864 expect() calls
After fetching origin/dev, the branch was already current:
behind 0, ahead 5
Command:
bun run --cwd /home/minpeter/.local/share/oh-my-openagent-senpi-pr/packages/omo-senpi typecheck
Observed result: exit code 0 with no diagnostics.
Command:
bun run --cwd /home/minpeter/.local/share/oh-my-openagent-senpi-pr test:senpi
Observed result:
492 pass
0 fail
1379 expect() calls
The gate rebuilt the packaged daemon and regenerated Senpi extension artifacts, ran the adapter typecheck, and ran all 78 Senpi test files.
The built PR plugin was installed into the isolated agent directory:
/home/minpeter/.cache/omo-pr-lsp-sweep-qa-20260729
OMO_LSP_DAEMON_VERSION and OMO_LSP_DAEMON_CLI were explicitly unset before
launching the real senpi --no-session TUI.
Observed result:
{"badge":true,"staleVersionWarning":false,"unknownVersion":false,"undefinedSuffix":false}
The rerun again rendered:
(🏴☠️ OmO Native)
The real senpi --mode rpc --no-session process was launched with the same
isolated agent directory and without either LSP daemon override variable. A
get_commands request confirmed the built plugin loaded its task surface.
Observed result:
{"tasks":true,"staleVersionWarning":false,"unknownVersion":false,"undefinedSuffix":false}
The successful get_commands response reported both tasks and task-kill
from the PR worktree's generated omo.js. The TUI and RPC were rerun with
OMO_LSP_DAEMON_CLI pointing at the built worktree CLI and
OMO_LSP_DAEMON_VERSION=9.8.7; the badge, command surface, and clean startup
remained intact with a version distinct from packaged 0.1.0.
lsp-core package gate
cover the macOS CI failure without changing production timing behavior.Raw TUI escape sequences, environment dumps, session files, credentials, and other secret-bearing runtime logs were not recorded. Only the sanitized boolean observations above are retained.