fix: wake dedupe + inline slot context + complete contracts.tools #6

Merged
hzhang merged 1 commits from fix/wake-dedupe-and-contracts into main 2026-05-20 14:48:07 +00:00
Contributor

Three issues making HF→agent wakeup unusable in practice, surfaced by DinD sim e2e test (recruiter agent + slot for 招募 manager task).

1. Plugin re-woke the same slot every 30s

The inline runCheck only destructured agentId from scheduleCache.getAgentsWithDueSlots() and dropped the slots array, then called wakeAgent without recording the wake. The simplified inline scheduler also never PATCHes slot status from not_started→ongoing server-side, so the next 30s check sees the slot still due and wakes again.

Fix: keep slots in runCheck, add in-memory wakedSlotKeys set keyed by (agentId, slotId|virtual_id|scheduled_at). Dedupe on this set; clear inside the sync interval. Server-side slot transition still TODO (needs CalendarScheduler class path or backend PATCH); the dedupe at least stops the wake spam.

2. Wakeup message had no slot context

Wakeup body just said follow hf-wakeup workflow — no slot id, no event_data, no task_code. Agent then had to call harborforge_calendar_status, which is broken in the simplified scheduler.

Fix: pass dueSlots into wakeAgent and inline the highest-priority slot's {slot_id, scheduled_at, priority, slot_type, event_data} as a JSON block. Agent reads event_data.task_code directly and routes via workflow_lookup. Matches the contract in hf-hangman-lab SKILL.md (lyn/ClawSkills#10).

3. contracts.tools listed 5 of the 9 registered tools

Manifest had 5 of 9. With OpenClaw plugin host enforcement (same gotcha as zhi/Meridian#2), undeclared tools are silently dropped from agent tool list.

Fix: add harborforge_calendar_abort, _pause, _resume, harborforge_restart_status.

🤖 Generated with Claude Code

Three issues making HF→agent wakeup unusable in practice, surfaced by DinD sim e2e test (recruiter agent + slot for `招募 manager` task). ## 1. Plugin re-woke the same slot every 30s The inline `runCheck` only destructured `agentId` from `scheduleCache.getAgentsWithDueSlots()` and dropped the slots array, then called `wakeAgent` without recording the wake. The simplified inline scheduler also never PATCHes slot status from `not_started→ongoing` server-side, so the next 30s check sees the slot still due and wakes again. **Fix**: keep slots in `runCheck`, add in-memory `wakedSlotKeys` set keyed by `(agentId, slotId|virtual_id|scheduled_at)`. Dedupe on this set; clear inside the sync interval. Server-side slot transition still TODO (needs `CalendarScheduler` class path or backend PATCH); the dedupe at least stops the wake spam. ## 2. Wakeup message had no slot context Wakeup body just said `follow hf-wakeup workflow` — no slot id, no event_data, no task_code. Agent then had to call `harborforge_calendar_status`, which is broken in the simplified scheduler. **Fix**: pass `dueSlots` into `wakeAgent` and inline the highest-priority slot's `{slot_id, scheduled_at, priority, slot_type, event_data}` as a JSON block. Agent reads `event_data.task_code` directly and routes via `workflow_lookup`. Matches the contract in `hf-hangman-lab` SKILL.md (lyn/ClawSkills#10). ## 3. contracts.tools listed 5 of the 9 registered tools Manifest had 5 of 9. With OpenClaw plugin host enforcement (same gotcha as zhi/Meridian#2), undeclared tools are silently dropped from agent tool list. **Fix**: add `harborforge_calendar_abort`, `_pause`, `_resume`, `harborforge_restart_status`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
hzhang added 1 commit 2026-05-20 11:03:02 +00:00
Three issues making HF→agent wakeup unusable in practice, surfaced by
DinD sim end-to-end test (recruiter agent + slot for 招募 manager task):

1. **Plugin re-woke the same slot every 30s.** The inline runCheck only
   destructured agentId from scheduleCache.getAgentsWithDueSlots() and
   dropped the slots array, then called wakeAgent without recording the
   wake. The simplified inline scheduler also never PATCHes slot status
   server-side from not_started→ongoing, so the next 30s check sees the
   slot still due and wakes again. After 4 wakes the agent's wakeup
   session was full of WAKEUP_OK noise.

   Fix: keep slots in runCheck, add an in-memory wakedSlotKeys set
   keyed by (agentId, slotId|virtual_id|scheduled_at). Dedupe on this
   set; clear it inside the sync interval (fresh wake budget per sync).
   Server-side slot transition still TODO (requires re-introducing the
   CalendarScheduler class path or PATCH /calendar/slots/.../agent-update
   here); the dedupe at least stops the wake spam.

2. **Wakeup message had no slot context.** The wakeup body just said
   'follow hf-wakeup workflow' with no slot id/event_data/task_code.
   The agent then had to call harborforge_calendar_status to learn
   anything — which itself is broken in the simplified scheduler (it
   queries a CalendarScheduler instance that never gets created).

   Fix: pass dueSlots into wakeAgent and inline the highest-priority
   slot's {slot_id, scheduled_at, priority, slot_type, event_data} as
   a JSON block in the wakeup message. The agent reads event_data.
   task_code directly and routes via workflow_lookup without any
   round-trip. Per PLG-CAL-001 docs in hf-hangman-lab SKILL.md, this
   is the documented contract; we are bringing the message in line.

3. **contracts.tools listed 5 of the 9 registered tools.** Manifest had
   harborforge_status/telemetry/monitor_telemetry/calendar_status/
   calendar_complete. Code also registers calendar_abort, calendar_pause,
   calendar_resume, harborforge_restart_status. With the new OpenClaw
   plugin host enforcement (same gotcha that bit Meridian — see
   zhi/Meridian#2), undeclared tools are silently dropped from the
   agent's tool list, so abort/pause/resume cannot be called by the
   agent. plugin doctor was emitting:
   'plugin tool is undeclared (harbor-forge): harborforge_calendar_abort'
   for each missing tool.

   Fix: add the 4 missing tool names to contracts.tools.

Also use api.config as the primary config source in wakeAgent (current
public API), falling back to runtime.config.loadConfig() for older
hosts — same pattern as the Meridian fix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hzhang merged commit f627845543 into main 2026-05-20 14:48:07 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: zhi/HarborForge.OpenclawPlugin#6