From 31ab794473bb9fab72ec57c40ae3193169aec2bb Mon Sep 17 00:00:00 2001 From: Enrico Piovesan Date: Mon, 10 Aug 2026 01:05:59 -0600 Subject: [PATCH] Publish core.notify-stakeholders 1.1.0 --- .../1.1.0/contract.json | 384 ++++++++++++++++++ 1 file changed, 384 insertions(+) create mode 100644 capabilities/core/core.notify-stakeholders/1.1.0/contract.json diff --git a/capabilities/core/core.notify-stakeholders/1.1.0/contract.json b/capabilities/core/core.notify-stakeholders/1.1.0/contract.json new file mode 100644 index 0000000..43a3520 --- /dev/null +++ b/capabilities/core/core.notify-stakeholders/1.1.0/contract.json @@ -0,0 +1,384 @@ +{ + "kind": "capability_contract", + "schema_version": "1.0.0", + "id": "core.notify-stakeholders", + "namespace": "core", + "name": "notify-stakeholders", + "version": "1.1.0", + "lifecycle": "active", + "owner": { + "team": "loop", + "contact": "founders@loop.dev" + }, + "summary": "Prepares notification intents for stakeholders when an action item changes status. Pure \u2014 does not send.", + "description": "Pure WF4 capability. Builds recipient/channel/subject/body intents from item + stakeholder list + event_type. Delivery is caller-owned.\n\nImplemented and smoke-tested matrix (use_cases):\n- completed event with multiple stakeholders\n- nothing_to_notify when stakeholders is empty\n- status_changed event intents\n- blocked event intents\n\nKnown limitations (intentional in 1.1.0):\n- reason_code invalid_event_type and invalid_input removed; event_type is a schema enum and host-required fields make those guest denial paths unreachable without schema weakening\n- No actual notification delivery", + "use_cases": [ + { + "scenario": "As a completion path, I want requester and manager notified that an item is done, so that stakeholders learn without polling.", + "input_example": { + "item": { + "id": "ai-1", + "title": "Send the revised proposal", + "owner_id": "user-ada", + "owner_name": "Ada", + "status": "done" + }, + "stakeholders": [ + { + "user_id": "user-carol", + "role": "requester", + "channel": "in_app" + }, + { + "user_id": "user-mgr", + "role": "manager", + "channel": "email" + } + ], + "event_type": "completed", + "notify_config": { + "version": "1.0", + "include_manager_on_complete": true + } + }, + "output_example": { + "intents": [ + { + "recipient_id": "user-carol", + "channel": "in_app", + "subject": "Action completed: Send the revised proposal", + "body": "Ada marked \"Send the revised proposal\" as done." + }, + { + "recipient_id": "user-mgr", + "channel": "email", + "subject": "Action completed: Send the revised proposal", + "body": "Ada marked \"Send the revised proposal\" as done." + } + ], + "intent_count": 2, + "reason_code": "ok", + "evaluation_trace": [ + "event_type=completed", + "prepared 2 intents" + ] + }, + "happy": true, + "persona_ref": "meeting-organizer" + }, + { + "scenario": "As a system, I want zero intents when there are no stakeholders, so that empty recipient lists do not fabricate notifications.", + "input_example": { + "item": { + "id": "ai-3", + "title": "Draft agenda", + "owner_id": "user-bob", + "owner_name": "Bob", + "status": "done" + }, + "stakeholders": [], + "event_type": "completed", + "notify_config": { + "version": "1.0", + "include_manager_on_complete": true + } + }, + "output_example": { + "intents": [], + "intent_count": 0, + "reason_code": "nothing_to_notify", + "evaluation_trace": [ + "event_type=completed", + "prepared 0 intents" + ] + }, + "happy": false, + "persona_ref": "runtime-engineer" + }, + { + "scenario": "As a WF4 workflow author, I want status_changed notification intents for stakeholders, so that status flips can be announced consistently.", + "input_example": { + "item": { + "id": "ai-1", + "title": "Send the revised proposal", + "owner_id": "user-ada", + "owner_name": "Ada", + "status": "in_progress" + }, + "stakeholders": [ + { + "user_id": "user-carol", + "role": "requester", + "channel": "in_app" + } + ], + "event_type": "status_changed", + "notify_config": { + "version": "1.0", + "include_manager_on_complete": true + } + }, + "output_example": { + "intents": [ + { + "recipient_id": "user-carol", + "channel": "in_app", + "subject": "Action updated: Send the revised proposal", + "body": "Ada updated \"Send the revised proposal\"." + } + ], + "intent_count": 1, + "reason_code": "ok", + "evaluation_trace": [ + "event_type=status_changed", + "prepared 1 intents" + ] + }, + "happy": true, + "persona_ref": "collaboration-product-owner" + }, + { + "scenario": "As a WF4 workflow author, I want blocked notification intents for stakeholders, so that blockers surface to the right people.", + "input_example": { + "item": { + "id": "ai-1", + "title": "Send the revised proposal", + "owner_id": "user-ada", + "owner_name": "Ada", + "status": "blocked" + }, + "stakeholders": [ + { + "user_id": "user-carol", + "role": "requester", + "channel": "in_app" + } + ], + "event_type": "blocked", + "notify_config": { + "version": "1.0", + "include_manager_on_complete": true + } + }, + "output_example": { + "intents": [ + { + "recipient_id": "user-carol", + "channel": "in_app", + "subject": "Action blocked: Send the revised proposal", + "body": "Ada blocked \"Send the revised proposal\"." + } + ], + "intent_count": 1, + "reason_code": "ok", + "evaluation_trace": [ + "event_type=blocked", + "prepared 1 intents" + ] + }, + "happy": true, + "persona_ref": "meeting-organizer" + } + ], + "inputs": { + "schema": { + "type": "object", + "required": [ + "item", + "stakeholders", + "event_type", + "notify_config" + ], + "properties": { + "item": { + "type": "object", + "required": [ + "id", + "title", + "status" + ], + "properties": { + "id": { + "type": "string" + }, + "title": { + "type": "string" + }, + "owner_id": { + "type": "string" + }, + "owner_name": { + "type": "string" + }, + "status": { + "type": "string" + } + } + }, + "stakeholders": { + "type": "array", + "items": { + "type": "object", + "required": [ + "user_id" + ], + "properties": { + "user_id": { + "type": "string" + }, + "role": { + "type": "string" + }, + "channel": { + "type": "string" + } + } + } + }, + "event_type": { + "type": "string", + "enum": [ + "completed", + "status_changed", + "blocked" + ] + }, + "notify_config": { + "type": "object", + "required": [ + "version" + ], + "properties": { + "version": { + "type": "string" + }, + "include_manager_on_complete": { + "type": "boolean" + } + } + } + } + } + }, + "outputs": { + "schema": { + "type": "object", + "required": [ + "intents", + "reason_code" + ], + "properties": { + "intents": { + "type": "array", + "items": { + "type": "object", + "required": [ + "recipient_id", + "channel", + "subject", + "body" + ], + "properties": { + "recipient_id": { + "type": "string" + }, + "channel": { + "type": "string" + }, + "subject": { + "type": "string" + }, + "body": { + "type": "string" + } + } + } + }, + "intent_count": { + "type": "integer" + }, + "reason_code": { + "type": "string", + "enum": [ + "ok", + "nothing_to_notify" + ] + }, + "evaluation_trace": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "preconditions": [], + "postconditions": [ + { + "id": "deterministic", + "description": "Identical inputs produce identical outputs" + } + ], + "side_effects": [ + { + "kind": "memory_only", + "description": "Pure intent preparation; does not send notifications" + } + ], + "emits": [], + "consumes": [], + "permissions": [ + { + "id": "core.notify-stakeholders" + } + ], + "execution": { + "binary_format": "wasm", + "entrypoint": { + "kind": "wasi-command", + "command": "run" + }, + "preferred_targets": [ + "local", + "edge", + "browser" + ], + "constraints": { + "host_api_access": "none", + "network_access": "forbidden", + "filesystem_access": "none" + } + }, + "policies": [], + "dependencies": [], + "provenance": { + "source": "ai-assisted", + "author": "loop-founders + traverse-capability-author", + "created_at": "2026-08-08T06:00:00Z", + "spec_ref": "core.notify-stakeholders@1.1.0", + "adr_refs": [ + "persona-council-review-2026-08-08" + ], + "exception_refs": [] + }, + "evidence": [ + { + "evidence_id": "core-notify-stakeholders-1.1.0-contract-validation", + "type": "contract_validation", + "status": "passed" + } + ], + "service_type": "stateless", + "permitted_targets": [ + "local", + "edge", + "browser", + "cloud" + ], + "artifact_type": "native", + "artifact": { + "digest": "sha256:bdf0a366617d2b3084887d5dd883d0187193ab546c6cbf614b5b65d822c3093d", + "url": "https://github.com/traverse-framework/registry/releases/download/artifacts/core.notify-stakeholders-1.1.0/core-notify-stakeholders.wasm" + } +}