Carry the owning task's notification subscriptions independently of dependency edges, within the creation transaction. Prefer its durable session over worker and request-local sessions while preserving explicit overrides. Cover worker CLI create and built-in decomposition, and retain conversation route anchors. Auto-subscribe no longer upgrades an inherited passive subscription. Slim adaptation of Christopher-Schulze's session-precedence fix in #85687, expanded to durable subscription provenance and sibling creation paths. Related: #85575, #85687 Validation: strict RED/GREEN (7 failing cases before; 7 passing after), then 58 Kanban test files: 383 passed, 2 skipped. Real dispatcher-spawn subprocess probe covers direct, linked, unlinked, explicit-session, worker CLI, built-in children and a plain CLI negative control, with recording transport only. Co-authored-by: Christopher <210261288+Christopher-Schulze@users.noreply.github.com>
62 lines
3.2 KiB
Python
62 lines
3.2 KiB
Python
"""Worker provenance is not a dependency edge or a transient runtime session."""
|
|
import json
|
|
|
|
import pytest
|
|
|
|
|
|
@pytest.mark.parametrize("linked,explicit", [(False, None), (True, None), (False, "override")])
|
|
def test_worker_create_keeps_durable_origin(tmp_path, monkeypatch, linked, explicit):
|
|
from hermes_cli import kanban_db as kb, kanban_db_connect as kbc, kanban_db_notify as kn
|
|
from tools import kanban_tools as kt, async_delegation
|
|
from gateway.session_context import set_session_vars, clear_session_vars
|
|
|
|
monkeypatch.setenv("HERMES_HOME", str(tmp_path))
|
|
monkeypatch.delenv("HERMES_KANBAN_TASK", raising=False)
|
|
kb.init_db()
|
|
with kbc.connect_closing() as conn:
|
|
owner = kb.create_task(conn, title="owner", session_id="durable")
|
|
kn.add_notify_sub(conn, task_id=owner, platform="discord", chat_id="chat",
|
|
user_id="user", notifier_profile="default", delivery_mode="notify",
|
|
delivery_metadata={"scope_id": "guild", "parent_chat_id": "forum"})
|
|
expected = kn.list_notify_subs(conn, owner)[0]
|
|
monkeypatch.setenv("HERMES_KANBAN_TASK", owner)
|
|
monkeypatch.setenv("HERMES_SESSION_ID", "ephemeral")
|
|
monkeypatch.setattr(async_delegation, "_current_origin_session_id", lambda: "api-origin")
|
|
# Even a matching current channel must not upgrade an inherited passive policy.
|
|
tokens = set_session_vars(platform="discord", chat_id="chat", profile="default")
|
|
try:
|
|
result = json.loads(kt._handle_create(dict(title="child", assignee="default",
|
|
parents=[owner] if linked else [], session_id=explicit)))
|
|
finally:
|
|
clear_session_vars(tokens)
|
|
assert result["ok"], result
|
|
with kbc.connect_closing() as conn:
|
|
child = kb.get_task(conn, result["task_id"])
|
|
assert child.session_id == (explicit or "durable")
|
|
subs = kn.list_notify_subs(conn, child.id)
|
|
assert len(subs) == 1
|
|
for key in ("platform", "chat_id", "user_id", "delivery_mode", "delivery_metadata", "notifier_profile"):
|
|
assert subs[0][key] == expected[key]
|
|
assert bool(conn.execute("SELECT 1 FROM task_links WHERE child_id = ?", (child.id,)).fetchone()) == linked
|
|
|
|
|
|
def test_tool_subscription_captures_conversation_anchors(tmp_path, monkeypatch):
|
|
from hermes_cli import kanban_db as kb, kanban_db_connect as kbc, kanban_db_notify as kn
|
|
from tools import kanban_tools as kt
|
|
from gateway.session_context import set_session_vars, clear_session_vars
|
|
|
|
monkeypatch.setenv("HERMES_HOME", str(tmp_path))
|
|
monkeypatch.delenv("HERMES_KANBAN_TASK", raising=False)
|
|
kb.init_db()
|
|
tokens = set_session_vars(platform="discord", chat_id="thread", chat_type="thread",
|
|
scope_id="guild", parent_chat_id="forum", profile="default")
|
|
try:
|
|
result = json.loads(kt._handle_create(dict(title="direct", assignee="default")))
|
|
finally:
|
|
clear_session_vars(tokens)
|
|
assert result["ok"], result
|
|
with kbc.connect_closing() as conn:
|
|
metadata = kn.list_notify_subs(conn, result["task_id"])[0]["delivery_metadata"]
|
|
assert metadata["scope_id"] == "guild"
|
|
assert metadata["parent_chat_id"] == "forum"
|