diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 1f0c2a5d..f29ccd8a 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -88,6 +88,6 @@ All 16 v1 requirements are mapped to exactly one phase. No orphans. | Phase | Milestone | Plans Complete | Status | Completed | |-------|-----------|----------------|--------|-----------| -| 27. Hermes Adapter | v1.4 | 1/1 | Complete | 2026-04-02 | +| 27. Hermes Adapter | v1.4 | 1/1 | Complete | 2026-04-02 | | 28. Ollama Integration & Agent Surface | v1.4 | 0/? | Not started | - | | 29. Default Provider & End-to-End | v1.4 | 0/? | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index 0ab6d54b..08afbb42 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -4,7 +4,7 @@ milestone: v1.4 milestone_name: milestone status: verifying stopped_at: Completed 27-hermes-adapter-27-01-PLAN.md -last_updated: "2026-04-02T16:26:30.127Z" +last_updated: "2026-04-02T16:31:58.709Z" last_activity: 2026-04-02 progress: total_phases: 3 @@ -25,8 +25,8 @@ See: .planning/PROJECT.md (updated 2026-04-02) ## Current Position -Phase: 27 (hermes-adapter) — EXECUTING -Plan: 1 of 1 +Phase: 28 +Plan: Not started Status: Phase complete — ready for verification Last activity: 2026-04-02 diff --git a/.planning/phases/27-hermes-adapter/27-VERIFICATION.md b/.planning/phases/27-hermes-adapter/27-VERIFICATION.md new file mode 100644 index 00000000..982ebbd6 --- /dev/null +++ b/.planning/phases/27-hermes-adapter/27-VERIFICATION.md @@ -0,0 +1,106 @@ +--- +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 70–119: Toolsets `` 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, 109–132: 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 655–657, 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), 109–132 (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)_