nexus/.planning/phases/27-hermes-adapter/27-VERIFICATION.md
Nexus Dev 285bf585be chore: complete v1.5 Smart Onboarding + Personal AI Assistant milestone
6 phases, 13 plans, 21 requirements.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:55:49 +00:00

106 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
phase: 27-hermes-adapter
verified: 2026-04-02T16:30:35Z
status: gaps_found
score: 3/4 must-haves verified
re_verification: false
gaps:
- truth: "AGENT_ADAPTER_TYPES has no duplicate entries"
status: failed
reason: "packages/shared/src/constants.ts still contains two gemini_local entries (lines 29 and 35). The SUMMARY claimed this was 'already clean on this branch' but the file has not been deduplicated. Commit 79b61059 ([nexus] feat(20-01)) added gemini_local after hermes_local, creating the duplicate, and no subsequent commit removed it."
artifacts:
- path: "packages/shared/src/constants.ts"
issue: "gemini_local appears twice: line 29 (first occurrence, correct) and line 35 (second occurrence after hermes_local, duplicate to remove)"
missing:
- "Remove the second 'gemini_local' entry (line 35) from AGENT_ADAPTER_TYPES in packages/shared/src/constants.ts"
---
# Phase 27: Hermes Adapter Verification Report
**Phase Goal:** Users can create a Hermes agent in Nexus, configure it, and have it execute heartbeats that spawn `hermes chat -q`, return a result, and persist the session across runs
**Verified:** 2026-04-02T16:30:35Z
**Status:** gaps_found — 1 gap blocking full compliance
**Re-verification:** No — initial verification
## Goal Achievement
### Observable Truths
| # | Truth | Status | Evidence |
|----|----------------------------------------------------------------------------------------|-------------|----------------------------------------------------------------------------------------------|
| 1 | hermes_local is treated as a sessioned local adapter for orphan-process liveness checks | VERIFIED | `heartbeat.ts` line 75: `"hermes_local"` in `SESSIONED_LOCAL_ADAPTERS` set; consumed at line 1759 via `isTrackedLocalChildProcessAdapter` in orphan-reaping logic |
| 2 | Toolsets field does not corrupt extraArgs when creating a new Hermes agent | VERIFIED | `config-fields.tsx` lines 70119: Toolsets `<Field>` is inside `{!isCreate && (<> ... </>)}` guard; no `extraArgs` reference anywhere in the file |
| 3 | Hermes session codec round-trip is tested (serialize, deserialize, getDisplayId, legacy key) | VERIFIED | `adapter-session-codecs.test.ts` lines 16, 109132: hermesSessionCodec imported from `hermes-paperclip-adapter/server`; 2 hermes test cases pass; all 11 adapter-session-codecs tests pass |
| 4 | AGENT_ADAPTER_TYPES has no duplicate entries | FAILED | `constants.ts` line 29 and line 35 both contain `"gemini_local"` — duplicate not removed |
**Score:** 3/4 truths verified
### Required Artifacts
| Artifact | Expected | Status | Details |
|-------------------------------------------------------|-------------------------------------------------|------------|-----------------------------------------------------------------------------------------------------------|
| `server/src/services/heartbeat.ts` | hermes_local in SESSIONED_LOCAL_ADAPTERS set | VERIFIED | Line 75: `"hermes_local"` present in set; function `isTrackedLocalChildProcessAdapter` wraps set at line 655657, called at line 1759 |
| `packages/shared/src/constants.ts` | Deduplicated AGENT_ADAPTER_TYPES array | FAILED | File exists and contains hermes_local (line 34), but gemini_local is duplicated (lines 29 and 35); deduplication task was not completed |
| `ui/src/adapters/hermes-local/config-fields.tsx` | Toolsets field hidden in create mode | VERIFIED | File created (123 lines); Toolsets inside `{!isCreate && ...}` at line 70; no extraArgs references; no stubs |
| `server/src/__tests__/adapter-session-codecs.test.ts` | Hermes session codec test block | VERIFIED | Lines 16 (import), 109132 (2 test cases); all 11 tests pass in vitest run |
### Key Link Verification
| From | To | Via | Status | Details |
|---------------------------------------------------|------------------------------------------|----------------------------------------------|----------|------------------------------------------------------------------------------------------------------|
| `server/src/services/heartbeat.ts` | `server/src/adapters/registry.ts` | SESSIONED_LOCAL_ADAPTERS set membership check | WIRED | `isTrackedLocalChildProcessAdapter` defined line 655, called line 1759 in orphan-reaping loop |
| `server/src/__tests__/adapter-session-codecs.test.ts` | `hermes-paperclip-adapter/server` | import sessionCodec | WIRED | Line 16: `import { sessionCodec as hermesSessionCodec } from "hermes-paperclip-adapter/server"`; tests pass |
### Data-Flow Trace (Level 4)
Not applicable — this phase modifies backend constants, a heartbeat set, test coverage, and a UI config form. No new data-rendering components were introduced that require data-flow tracing.
### Behavioral Spot-Checks
| Behavior | Command | Result | Status |
|---------------------------------------------------|-------------------------------------------------------------------------------------------------------|-----------------------------|---------|
| All session codec tests pass (incl. hermes) | `pnpm --filter server exec vitest run src/__tests__/adapter-session-codecs.test.ts` | 11/11 tests pass | PASS |
| Hermes dual-source tests pass (regression check) | `pnpm --filter server exec vitest run src/__tests__/hermes-dual-source.test.ts` | 7/7 tests pass | PASS |
| UI TypeScript compiles cleanly | `pnpm --filter ui exec tsc --noEmit` | Exit 0, no errors | PASS |
| Server TypeScript (excluding pre-existing errors) | `pnpm --filter server exec tsc --noEmit` | Only plugin-sdk errors (pre-existing, unrelated to this phase) | PASS (scoped) |
| Toolsets field has no extraArgs reference | `grep -n "extraArgs" ui/src/adapters/hermes-local/config-fields.tsx` | No output (no matches) | PASS |
| constants.ts gemini_local count | `grep -c "gemini_local" packages/shared/src/constants.ts` | 2 (should be 1) | FAIL |
### Requirements Coverage
| Requirement | Source Plan | Description | Status | Evidence |
|-------------|-------------|-----------------------------------------------------------------------------------------------------------|----------------|--------------------------------------------------------------------------------------------------------|
| HERM-01 | 27-01-PLAN | Hermes adapter installed, enabled, appears in "Add Agent" dropdown | SATISFIED | Pre-existing: `ui/src/components/NewAgentDialog.tsx` lists hermes_local; `ui/src/components/AgentConfigForm.tsx` includes hermes_local in ENABLED_ADAPTER_TYPES |
| HERM-02 | 27-01-PLAN | User can create a Hermes agent with config options (model selection, tool permissions) | SATISFIED | `config-fields.tsx` has Model field in both modes; Toolsets properly guarded to edit-only, preventing extraArgs corruption |
| HERM-03 | 27-01-PLAN | Heartbeat execution spawns `hermes chat -q`, processes task, returns result | SATISFIED | `hermes_local` in SESSIONED_LOCAL_ADAPTERS enables correct orphan-process liveness checks; adapter wiring pre-exists from prior phase; 7 hermes-dual-source tests pass |
| HERM-04 | 27-01-PLAN | Session persistence works across heartbeats via `--resume` flag | SATISFIED | Hermes session codec tests pass: serialize/deserialize round-trip and legacy session_id key both verified |
**Note:** HERM-01 through HERM-04 are marked complete in REQUIREMENTS.md. The one failing truth (duplicate constant) is a cleanup item that supports HERM-01 type compliance but does not directly block any of the 4 HERM requirements from functioning at runtime. However, the PLAN explicitly listed it as a must-have truth, so it is recorded as a gap.
### Anti-Patterns Found
| File | Line | Pattern | Severity | Impact |
|------------------------------------|-------|----------------------------------------------|-----------|-------------------------------------------------------------------------------------------------|
| `packages/shared/src/constants.ts` | 35 | `"gemini_local"` — duplicate array entry | Warning | TypeScript `as const` array has duplicate. No runtime breakage (TypeScript union types deduplicate), but it is incorrect and the plan explicitly required removal. |
The server TS errors (`plugin-sdk` module not found) are pre-existing and unrelated to this phase — they exist on the branch prior to any phase-27 commits and are not introduced by this phase.
### Human Verification Required
None — all critical behaviors are verifiable programmatically for this phase.
### Gaps Summary
One gap blocks full must-have compliance:
**Duplicate `gemini_local` in `AGENT_ADAPTER_TYPES` (constants.ts)** — The plan task required removing the second `"gemini_local"` entry from `AGENT_ADAPTER_TYPES` in `packages/shared/src/constants.ts`. The SUMMARY noted "already clean on this branch," but the actual file has the duplicate at lines 29 and 35. Commit `79b61059` (from an earlier phase) added `gemini_local` after `hermes_local`, and no subsequent commit in phase 27 removed it. The fix is a single-line deletion.
The three other must-haves are fully implemented and tested:
- `hermes_local` is correctly in `SESSIONED_LOCAL_ADAPTERS` and the orphan-reaping logic uses it
- `config-fields.tsx` correctly guards the Toolsets field behind `{!isCreate && ...}` with no extraArgs corruption
- Hermes session codec has 2 passing tests (standard sessionId + legacy session_id key)
---
_Verified: 2026-04-02T16:30:35Z_
_Verifier: Claude (gsd-verifier)_