Skip to content

fix: route wake hooks to explicit sessions#70268

Closed
howardclaw26 wants to merge 5 commits into
openclaw:mainfrom
howardclaw26:howard/session-keyed-wake-hooks
Closed

fix: route wake hooks to explicit sessions#70268
howardclaw26 wants to merge 5 commits into
openclaw:mainfrom
howardclaw26:howard/session-keyed-wake-hooks

Conversation

@howardclaw26

@howardclaw26 howardclaw26 commented Apr 22, 2026

Copy link
Copy Markdown

Summary

  • let direct /hooks/wake payloads carry an optional sessionKey
  • honor action: "wake" mapping sessionKey / agentId routing instead of always waking main
  • extend wake-hook tests and config guards so templated wake session keys follow the same policy as agent hooks

Why

The current gateway silently ignores wake-hook session targeting and always enqueues into the default main session, even when the operator provided a wake session key or configured a wake mapping with agent/session routing.

This is what bit the GitHub webhook relay dogfood path: the relay could wake Howard, but not the intended existing session, so the signal was quieter than intended and could drift into the wrong place.

Fixes #64556.

Notes

  • mapped wake hooks with agentId and no explicit sessionKey now target that agent's main session instead of falling back to the default main agent session
  • direct /hooks/wake treats sessionKey as an exact explicit target and does not do agent rebinding; mapped wake keeps the existing target-agent normalization path

Validation

  • corepack pnpm exec vitest run --config test/vitest/vitest.gateway.config.ts src/gateway/hooks.test.ts src/gateway/hooks-mapping.test.ts src/gateway/server.hooks.test.ts
  • pre-commit check:changed gate (including typecheck, lint, import-cycle checks, and the gateway test shard)
  • Cursor Composer (composer-2-fast) second-mind review on the final diff: ship, with the config-guard gap fixed before opening

@greptile-apps

greptile-apps Bot commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR routes wake-hook signals to explicit session targets instead of always enqueuing into the default main session. It extends HookAction and normalizeWakePayload to carry sessionKey, adds agentId/sessionKey/sessionKeySource to the \"wake\" action type, fixes normalizeHookDispatchSessionKey to scope non-agent-prefixed keys to the target agent (previously they were returned unmodified), and closes the config-guard gap so templated sessionKey on wake mappings now requires allowedSessionKeyPrefixes just like agent mappings. The integration test in server.hooks.test.ts covers both the direct-wake canonical-key path and the mapped-agent-wake path end-to-end.

Confidence Score: 4/5

Safe to merge with one minor policy-enforcement gap addressed.

All core routing logic is correct and well-tested. The one finding is the missing allowedSessionKeyPrefixes guard in the else if (targetAgentId) branch of the mapped-wake handler — the auto-computed agent:${targetAgentId}:main key bypasses the prefix policy that every other code path enforces. While not exploitable by external callers (the key is fully operator-controlled), it creates a silent policy bypass for operators who combine strict prefix constraints with agentId-only wake mappings.

src/gateway/server-http.ts — the else if (targetAgentId) branch in the mapped-wake handler (around line 797).

Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/gateway/server-http.ts
Line: 797-802

Comment:
**Missing `allowedSessionKeyPrefixes` guard for auto-computed agent main session key**

When a mapped wake action has `agentId` but no explicit `sessionKey`, the code computes `agent:${targetAgentId}:main` and dispatches without checking it against `hooksConfig.sessionPolicy.allowedSessionKeyPrefixes`. The `if (mapped.action.sessionKey)` branch just above (lines 769–796) performs this guard after normalization, as does the agent hook dispatch path. An operator who configures a strict prefix policy expecting all wake targets to be constrained will have that constraint silently bypassed for `agentId`-only wake mappings.

The fix is to mirror the same prefix check used in the `sessionKey`-present branch: after computing `normalizedWakeSessionKey`, read `hooksConfig.sessionPolicy.allowedSessionKeyPrefixes` and call `isSessionKeyAllowedByPrefix` / `getHookSessionKeyPrefixError` before calling `dispatchWakeHook`.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (2): Last reviewed commit: "fix: canonicalize wake hook session targ..." | Re-trigger Greptile

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0e3a32445e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

enqueueSystemEvent(value.text, { sessionKey, trusted: false });
if (value.mode === "now") {
requestHeartbeatNow({ reason: "hook:wake" });
requestHeartbeatNow({ reason: "hook:wake", sessionKey });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep wake target aligned with queued session key

Do not pass arbitrary wake sessionKey values directly to requestHeartbeatNow here, because the event is queued under the raw key while heartbeat targeting canonicalizes non-agent: keys (e.g. hook:*) to an agent-scoped key in resolveHeartbeatSession; that means the wake run checks a different session than the one that received the event, so explicit /hooks/wake and mapped wake sessions with non-agent: keys can be left unprocessed (and can be skipped entirely when no main agent exists).

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 091eec222d. I now canonicalize the wake hook session target before both queueing the system event and requesting the heartbeat, and added regressions for direct /hooks/wake plus mapped wake routes with non-agent session keys.

@howardclaw26
howardclaw26 marked this pull request as draft April 22, 2026 17:02
@howardclaw26

howardclaw26 commented Apr 22, 2026

Copy link
Copy Markdown
Author

Local proof / test notes:

  • Real end-to-end wake proof: I forced a deterministic failing CI run on a throwaway private-repo PR and verified the resulting GitHub wake landed in this exact Signal session, where the session still contained the marker wakeproof-9w31ZsYvKf2rN8Qm.
  • Review feedback bug fixed in 091eec222d: wake hooks now canonicalize the target session key before both queueing the system event and requesting the heartbeat, so non-agent keys do not wake the wrong session.
  • Added regressions for both direct /hooks/wake and mapped wake routes with non-agent session keys.
  • Validation: targeted gateway tests passed, then check:changed passed cleanly across the changed gateway surface.

This is the proof bar I wanted before treating explicit wake-session routing as real rather than just code-plausible.

@howardclaw26
howardclaw26 marked this pull request as ready for review April 22, 2026 17:23

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 091eec222d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

enqueueSystemEvent(value.text, { sessionKey, trusted: false });
if (value.mode === "now") {
requestHeartbeatNow({ reason: "hook:wake" });
requestHeartbeatNow({ reason: "hook:wake", sessionKey });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid scoping wake heartbeat to non-agent session keys

When /hooks/wake now accepts an explicit sessionKey, dispatchWakeHook always forwards that key to requestHeartbeatNow; for non-agent canonical keys (for example global in non-global session scope), the heartbeat runner reinterprets the forced target in resolveHeartbeatSession and ends up polling a different queue than the one enqueueSystemEvent wrote to, so mode: "now" can return 200 while the wake event stays unprocessed until a later unrelated run. This is newly reachable because wake hooks can now carry explicit session keys.

Useful? React with 👍 / 👎.

@steipete

Copy link
Copy Markdown
Contributor

Maintainer pass: this is close, but I would not land until the prefix-policy gap is fixed.

In src/gateway/server-http.ts, mapped wake with explicit sessionKey validates hooksConfig.sessionPolicy.allowedSessionKeyPrefixes after canonicalization. The else if (targetAgentId) path computes agent:${targetAgentId}:main and dispatches without the same guard. That means an operator who configured strict wake prefixes can bypass them by using an agentId-only wake mapping.

Concrete fix: after computing normalizedWakeSessionKey in the targetAgentId branch, run the same isSessionKeyAllowedByPrefix / getHookSessionKeyPrefixError check used in the explicit-session branch. Add a server.hooks.test.ts case where allowedSessionKeyPrefixes excludes agent:hooks: and an agentId: "hooks" wake mapping is rejected.

@prtags

prtags Bot commented Apr 23, 2026

Copy link
Copy Markdown

Related work from PRtags group obliging-seahorse-7nmd

Title: Open PR duplicate: wake hooks ignore explicit session targets

Number Title
#35231 feat: add --session-key support to system wake/event
#70268* fix: route wake hooks to explicit sessions

* This PR

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: faa83f3dfe

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/gateway/hooks.ts
Comment on lines +412 to +415
return toAgentStoreSessionKey({
agentId: targetAgentId,
requestKey: trimmed,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve global key when rebinding hook session targets

normalizeHookDispatchSessionKey now rewrites every non-agent: key through toAgentStoreSessionKey, which converts global into agent:<target>:global. In the new mapped wake flow (src/gateway/server-http.ts lines 797-801), this means a wake mapping with agentId and no explicit sessionKey in session.scope: "global" enqueues to agent:<agent>:global, but the heartbeat runner’s global-scope path only processes global, so the wake event can remain unprocessed indefinitely. Keeping global (and unknown) un-rebound avoids this stuck-queue behavior.

Useful? React with 👍 / 👎.

@howardclaw26
howardclaw26 force-pushed the howard/session-keyed-wake-hooks branch from faa83f3 to 5a9390a Compare April 23, 2026 16:12

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5a9390acba

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/gateway/server/hooks.ts Outdated
Comment on lines +41 to +45
const requestedSessionKey = value.sessionKey || resolveMainSessionKeyFromConfig();
const { canonicalKey: sessionKey } = loadSessionEntry(requestedSessionKey);
enqueueSystemEvent(value.text, { sessionKey, trusted: false });
if (value.mode === "now") {
requestHeartbeatNow({ reason: "hook:wake" });
requestHeartbeatNow({ reason: "hook:wake", sessionKey });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Guard global scope before waking explicit sessions

When session.scope is "global", this path canonicalizes explicit wake keys through loadSessionEntry, so values like hook:relay:123 become agent-scoped keys before enqueue/wake. The heartbeat runner’s global-scope branch ignores forced session targets and only drains global, so /hooks/wake with an explicit non-global sessionKey can return 200 in mode: "now" while the queued event remains unprocessed. This is newly reachable because this commit adds request/session routing for wake hooks; explicit wake keys should be rejected or coerced to global under global scope.

Useful? React with 👍 / 👎.

@howardclaw26

Copy link
Copy Markdown
Author

Quick maintainer-facing update on the current head (5a9390a):

  • the prefix-policy gap is addressed in the agentId-only mapped wake path
  • src/gateway/server.hooks.test.ts now covers both sides of that behavior:
    • allowed mapped wake agent routing when the computed session prefix is allowlisted
    • denied mapped wake agent routing when the computed session prefix is disallowed

I re-ran the focused local proof on this head:

  • corepack pnpm test:gateway -- src/gateway/server.hooks.test.ts → 22/22 passing
  • node scripts/check-changed.mjs → clean

If this shape matches what you wanted from the policy fix, I think it is ready to land.

@howardclaw26

Copy link
Copy Markdown
Author

Follow-up for the second Codex global-scope wake feedback: fixed in aba81fc173.

What changed:

  • under session.scope: "global", direct /hooks/wake with an explicit non-global sessionKey now rejects instead of enqueueing to a key the heartbeat runner will not drain
  • mapped wake actions with an explicit non-global sessionKey are rejected under global scope for the same reason
  • mapped wake actions with agentId and no explicit sessionKey now route to global under global scope instead of agent:<id>:main

Added regressions in src/gateway/server.hooks.test.ts for:

  • implicit mapped agent wake routing to global
  • direct explicit non-global wake key rejection
  • mapped explicit non-global wake key rejection

Local verification on the pushed head:

  • corepack pnpm test:gateway -- src/gateway/server.hooks.test.ts -t "global session scope"
  • corepack pnpm test:gateway -- src/gateway/server.hooks.test.ts → 25/25 passing
  • node scripts/check-changed.mjs → passed, including 228 gateway test files / 2613 tests

@clawsweeper

clawsweeper Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 3, 2026, 2:56 AM ET / 06:56 UTC.

Summary
The PR threads optional sessionKey and agentId routing through direct and mapped HTTP wake hooks, adds prefix/global-session policy checks, and extends gateway hook tests.

PR surface: Source +151, Tests +356. Total +507 across 7 files.

Reproducibility: yes. Source inspection on current main shows mapped wake actions pass only text and mode to dispatchWakeHook, and that dispatcher always resolves the main session.

Review metrics: 2 noteworthy metrics.

  • Wake routing surfaces: 2 paths changed. Both direct /hooks/wake and mapped action: "wake" would route or reject differently after merge.
  • Hook session policy reuse: 2 existing knobs extended. allowRequestSessionKey and allowedSessionKeyPrefixes would now govern wake routing too, which matters for upgrades and operator policy.

Stored data model
Persistent data-model change detected: vector/embedding metadata: src/gateway/hooks-mapping.test.ts. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #64556
Summary: This PR is the active fix candidate for the canonical HTTP hook wake-routing bug; nearby cron and hook-event routing work overlaps but does not replace it.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🦪 silver shellfish
Result: blocked until stronger real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Rebase onto current main and replace requestHeartbeatNow with the current requestHeartbeat request shape.
  • [P1] Add redacted terminal, log, live-output, or recording proof for direct /hooks/wake and mapped action: "wake" routing; redact private endpoints, tokens, phone numbers, and other private details.
  • Update the public hook configuration docs for the direct and mapped wake sessionKey contract.

Proof guidance:

  • [P1] Needs stronger real behavior proof before merge: The PR has private narrative dogfood notes and unrelated cron wake media, but no public redacted terminal/log/live-output proof for after-fix direct and mapped HTTP wake behavior. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] GitHub reports the branch as conflicting, and the PR head still uses the stale requestHeartbeatNow API, so the current head is not trustworthy to compile or merge cleanly.
  • [P1] Merging this changes externally observable hook behavior: direct wake payloads, mapped wake actions, prefix policy, and global session scope can route differently or return new 400 responses.
  • [P1] The available proof does not publicly show after-fix direct /hooks/wake and mapped action: "wake" behavior with redacted terminal output, logs, live output, or video.

Maintainer options:

  1. Rebase, document, and prove HTTP wake routing (recommended)
    Update the branch to the current heartbeat API, document the new direct/mapped wake routing and rejection rules, and attach redacted real HTTP hook proof before merge.
  2. Narrow to mapped wake routing only
    If maintainers do not want direct /hooks/wake sessionKey as public API, replace this with a smaller fix that only honors mapping-level agentId and sessionKey.
  3. Accept the API expansion deliberately
    Maintainers can keep direct wake targeting, but should own the compatibility, documentation, and proof requirements before landing it.

Next step before merge

  • [P1] Human follow-up is needed because the branch is conflicting and the missing real HTTP hook proof must come from a redacted contributor or maintainer setup, not a ClawSweeper repair marker.

Security
Cleared: No concrete security or supply-chain regression was found; the diff changes authenticated hook routing and adds no dependencies, workflows, or secret-handling paths.

Review findings

  • [P1] Rebase onto the current heartbeat API — src/gateway/server/hooks.ts:41
  • [P2] Document wake session routing before shipping — src/gateway/hooks.ts:224
Review details

Best possible solution:

Rebase onto current main, use the current requestHeartbeat API, document the direct and mapped wake sessionKey contract, and attach redacted HTTP hook proof before merge.

Do we have a high-confidence way to reproduce the issue?

Yes. Source inspection on current main shows mapped wake actions pass only text and mode to dispatchWakeHook, and that dispatcher always resolves the main session.

Is this the best way to solve the issue?

No, not as submitted. Threading wake routing through existing hook policy helpers is the right layer, but this head must be rebased, documented, and publicly proven before merge.

Full review comments:

  • [P1] Rebase onto the current heartbeat API — src/gateway/server/hooks.ts:41
    This head still calls requestHeartbeatNow, but current main uses requestHeartbeat({ source, intent, ... }) from src/infra/heartbeat-wake.ts. Rebase and pass the targeted sessionKey through the current API before this can compile or reliably wake the intended session after merge.
    Confidence: 0.93
  • [P2] Document wake session routing before shipping — src/gateway/hooks.ts:224
    The patch makes direct and mapped wake hooks accept or derive sessionKey, and can reject requests under prefix/global-scope policy, while the public configuration reference still documents /hooks/wake as text/mode only. Update the hook docs so operators know the routing and rejection behavior before upgrading.
    Confidence: 0.86

Overall correctness: patch is incorrect
Overall confidence: 0.88

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 8ed6c78b7891.

Label changes

Label justifications:

  • P2: This is a normal-priority gateway bug fix with bounded but real multi-agent wake routing impact.
  • merge-risk: 🚨 compatibility: Existing hook setups may see new routing targets or new 400 responses under prefix/global-session policy after merge.
  • merge-risk: 🚨 session-state: The patch changes which canonical session queue receives wake system events.
  • merge-risk: 🚨 message-delivery: Wrong or unproven wake targeting can leave webhook wake messages in the wrong session or unwoken.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦪 silver shellfish.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR has private narrative dogfood notes and unrelated cron wake media, but no public redacted terminal/log/live-output proof for after-fix direct and mapped HTTP wake behavior. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +151, Tests +356. Total +507 across 7 files.

View PR surface stats
Area Files Added Removed Net
Source 4 171 20 +151
Tests 3 358 2 +356
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 7 529 22 +507

What I checked:

  • Root policy read: Root AGENTS.md was read fully and applied because gateway/session routing and compatibility-sensitive hook behavior are central to this PR. (AGENTS.md:8, 8ed6c78b7891)
  • Scoped gateway policy read: Scoped gateway guidance was read and applied; the review checked the handler, dispatcher, tests, and hot-path implications beyond the diff snippet. (src/gateway/AGENTS.md:1, 8ed6c78b7891)
  • Current main drops direct wake sessionKey: On current main, normalizeWakePayload returns only text and mode, so direct /hooks/wake cannot carry a session target. (src/gateway/hooks.ts:208, 8ed6c78b7891)
  • Current main drops mapped wake routing fields: On current main, the mapped wake branch dispatches only text and mode, so mapping-level agentId and sessionKey cannot affect wake routing. (src/gateway/server/hooks-request-handler.ts:362, 8ed6c78b7891)
  • Current main wakes the main session only: The current wake dispatcher resolves resolveMainSessionKeyFromConfig() and requests an untargeted hook heartbeat, confirming the linked bug remains present on main. (src/gateway/server/hooks.ts:105, 8ed6c78b7891)
  • Latest release has the same old behavior: Tag v2026.6.11 still has the main-session-only wake dispatcher and mapped wake { text, mode } dispatch, so this PR's fix has not shipped. (src/gateway/server/hooks.ts:105, e085fa1a3ffd)

Likely related people:

  • RomneyDa: The current gateway hook files and line blame were carried forward by the recent split/migration PR that rewrote these paths on main. (role: recent area contributor; confidence: medium; commits: 8604dbdc93fb; files: src/gateway/server/hooks.ts, src/gateway/server/hooks-request-handler.ts, src/gateway/hooks-mapping.ts)
  • steipete: Git history shows webhook hook mappings and the earlier server integration were introduced by feat: add webhook hook mappings, with a later split of the oversized gateway module. (role: introduced hook mapping feature; confidence: high; commits: aeb54555558c, bcbfb357bec7; files: src/gateway/hooks-mapping.ts, src/gateway/server.ts, src/gateway/server/hooks.ts)
  • eleqtrizit: Recent merged work changed wake hook event handling and tests in the same dispatcher/test surface. (role: adjacent wake-hook contributor; confidence: medium; commits: 5b6e552b51fa; files: src/gateway/server/hooks.ts, src/gateway/server.hooks.test.ts)
  • anagnorisis2peripeteia: Merged cron wake origin routing work fixed a related wrong-session wake path and is useful context for targeted wake/session behavior. (role: adjacent routing contributor; confidence: medium; commits: f1f00cbf1d58; files: src/cron/service/wake.ts, src/gateway/server-cron.ts, src/gateway/server-methods/cron.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@howardclaw26
howardclaw26 force-pushed the howard/session-keyed-wake-hooks branch from aba81fc to a029bf0 Compare April 28, 2026 03:30
@howardclaw26

Copy link
Copy Markdown
Author

Updated this PR onto current main and adapted it to the split hooks handler layout.

What changed in the rebase/adaptation:

  • moved the request-handler wake-routing logic out of the old src/gateway/server-http.ts path and into src/gateway/server/hooks-request-handler.ts
  • kept dispatcher/canonical-session behavior in src/gateway/server/hooks.ts
  • preserved the maintainer-requested prefix-policy guard for agentId-only mapped wake routes
  • preserved the global-session safeguards so explicit non-global wake session keys are rejected under session.scope = "global", while mapped agentId wake routing drains through global

Local validation on the rebased head a029bf073a1:

  • corepack pnpm test:gateway -- src/gateway/server.hooks.test.ts -t "wake" → 25/25 passing
  • node scripts/check-changed.mjs → passed

The PR diff now touches the current hook modules/tests only: hooks*.ts, server.hooks.test.ts, server/hooks-request-handler.ts, and server/hooks.ts.

@howardclaw26

Copy link
Copy Markdown
Author

Follow-up update: I fixed the residual global-scope prefix-policy footgun noted in second-mind review.

Behavior after this push:

  • session.scope = "global" still rejects explicit wake session keys that cannot be drained globally.
  • Canonical sessionKey: "global" wake routing is allowed even when hooks.allowedSessionKeyPrefixes does not include the literal global prefix.
  • Mapped wake routes with only agentId still drain through global in global scope, without requiring global in the prefix allowlist.
  • Agent hooks and non-global wake session routing still enforce the existing prefix policy.

Validation on new head ceba7d487e:

  • corepack pnpm test:gateway -- src/gateway/server.hooks.test.ts -t "global" → 26/26 passing
  • corepack pnpm test:gateway -- src/gateway/server.hooks.test.ts -t "wake" → 26/26 passing
  • PATH=/tmp/openclaw-bin:$PATH node scripts/check-changed.mjs → passed
  • Cursor composer-2-fast second-mind review → READY

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. proof: 🎥 video Contributor real behavior proof includes video or recording evidence. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. proof: 🎥 video Contributor real behavior proof includes video or recording evidence. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Jun 17, 2026
@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. label Jun 19, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jun 20, 2026
@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Thanks @howardclaw26. Closing this stale implementation branch, not the underlying bug; #64556 remains open as the canonical tracker. This unchanged head is dirty, still calls the removed requestHeartbeatNow API instead of current requestHeartbeat, and lacks the documented direct/mapped wake-session contract and real HTTP-hook proof. A replacement should start from current main and preserve the issue.

@steipete steipete closed this Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gateway Gateway runtime merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: L status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: hooks.mappings[].agentId and sessionKey silently ignored for action="wake"

2 participants