Summary
Adds an optional host.queueBus capability covering publish + inbound-consume + ack/nack/dead-letter, plus stream subscribe/publish. Required by core.openwop.messaging. Sibling to existing host.messaging (which is outbound-egress-only) — host.queueBus covers full message-queue semantics including delivery acknowledgement.
Motivation
n8n RabbitMQ/Kafka/SQS/NATS/MQTT/Pub-Sub nodes all expose the same pattern: a trigger fires on inbound, an action publishes outbound, plus ack/nack on the trigger side. openwop currently has no inbound-queue surface at all. host.messaging only handles outbound chat egress.
Proposal
§A Capability schema
{
"queueBus": {
"type": "object",
"properties": {
"supported": { "type": "boolean" },
"backends": { "type": "array", "items": { "type": "string", "enum": ["rabbitmq","kafka","sqs","sns","pubsub","mqtt","nats","redis-streams","in-memory"] } },
"deadLetterSupported": { "type": "boolean" },
"stream": {
"type": "object",
"properties": {
"supported": { "type": "boolean" },
"fromBeginning": { "type": "boolean" }
}
}
},
"additionalProperties": false
}
}
§B Host-contract MUSTs
- Cross-tenant message isolation. A consumer for tenant A MUST NOT receive messages published by tenant B, even on the same logical topic.
- Ack semantics:
ackremoves the message from the queue;nackreturns it for redelivery;deadLetterroutes it to the configured dead-letter queue. - Trigger-mode delivery: when a workflow registers
core.messaging.consumeas a trigger, the host MUST deliver one workflow run per message.
§C SECURITY invariant
- id: queue-cross-tenant-isolation
tier: protocol
summary: "host.queueBus MUST partition messages by tenant. Cross-tenant consumption MUST NOT occur."
conformance_test: "queue-cross-tenant-isolation.test.ts"
§D Conformance
queue-publish-consume-roundtrip.test.ts.queue-cross-tenant-isolation.test.ts.queue-ack-nack-dlq.test.ts.stream-subscribe-from-beginning.test.ts(gated onstream.fromBeginning).
Compatibility
Additive. New capability. host.messaging (existing, outbound-egress-only) remains unchanged.
Implementation notes (non-normative)
- Schema diff in §A lands in
schemas/capabilities.schema.jsonon Active promotion, not at Draft. - SECURITY invariant
queue-cross-tenant-isolationlands inSECURITY/invariants.yamlalongside the matching scenario. - Reference impl candidate: in-memory pub/sub bus per tenant in
examples/hosts/in-memory/.
Acceptance criteria
- [x] Capability block.
- [x] Prose section. (Landed at commit c5831fe.)
- [x] Invariant + 3 mandatory scenarios + 1 gated.
- [x] In-memory reference impl.
- [x] CHANGELOG entry.
References
- n8n RabbitMQ/Kafka/SQS/NATS/MQTT triggers (prior art).
- Existing
host.messaging(sibling, outbound-only). core.openwop.messagingpack.