Skip to content

ConversationRouter.route() violates command-query separation (mutates lastActivity) #46

Description

@Anarchid

Found during review of #41. Design/hygiene follow-up.

Problem

ConversationRouter.route() is documented as a query ("Decide where an incoming message goes") but mutates TTL state.

src/mcpl/conversation-router.ts:157:

/** ... Pure read except for refreshing lastActivity ... */
route(facts) {
  ...
  existing.lastActivity = now;   // command hiding in a query

Impact

Command-query separation violation: you cannot preview a routing decision without resetting the idle clock. The test 'expired() respects lastActivity refresh from route()' is load-bearing on the side effect. A future diagnostic caller of route() would silently keep dying engagements alive.

Suggested fix

Split the side effect out — route() decides; an explicit touch(channelId) (or a refresh on the framework's delivery path) advances lastActivity.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions