Repository navigation
Conversation
There is no way for another system to react to platform activity, for example a chat message when a gate needs a human, without polling the API. With notification_events_enabled (default false) the deployment creates an EventBridge bus (notification_event_bus_name, default <project>-<environment>-events). The projects, discussions and v2-orchestrator Lambdas get NOTIFICATION_EVENT_BUS, NOTIFICATION_EVENT_SOURCE (default collaborative-ai-dlc) and events:PutEvents on that bus only. They publish: - space.created when a space is created - gate.pending when an intent waits at a gate, from a durable step so a replay does not publish twice - discussion.message and discussion.resolved for intent discussions Publishing (lambda/shared/notification-events.js) is best-effort: it never throws, gives up after two seconds, and without a bus does nothing and never loads the EventBridge client. The bus name and ARN are root outputs, and docs/using-the-platform/notification-events.md documents the event schema. Disabled, nothing is created and no Lambda changes. Co-authored-by: ashley.fairclough <ashley.fairclough@cdl.co.uk> Co-authored-by: Matt Houghton <matthew.houghton@cdl.co.uk>
thenom
requested review from
JWThewes,
eipasteur,
jeromevdl,
leandrodamascena and
svozza
as code owners
October 26, 2026 15:32
gate.pending only fired for agent gates and its prompt was always null: agent questions carry a questions JSON array, not a prompt. - prompt falls back to the first entry of the gate's questions. - gate.pending adds need (answer, or approval for checkpoints and engine gates), intentTitle and startedBy. - Engine gates (validation, walking skeleton, batch, autonomy ladder, lane failure) publish gate.pending from inside their existing gate-open step, so the durable step sequence is unchanged. stage is the stage id where there is one, else a readable gate label. - Every event's detail has schemaVersion (1) and an eventId for deduplication. The docs now say delivery is at least once. All additive: no field is renamed or removed, and nothing changes without a bus configured. Co-authored-by: Adrian Robinson <adrian.robinson@cdl.co.uk>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue #, if available: None
Description of changes:
Problem
Nothing outside the platform can react to what happens in it without polling the API. Common asks are a chat message when a gate is waiting for a human, a notice when a discussion is resolved, or an audit record when a space is created.
Solution
An opt-in outbound event feed on Amazon EventBridge. The platform publishes, and integrations subscribe with their own rules, in this deployment or another.
Terraform (root variables, all optional):
notification_events_enabled(defaultfalse) creates anaws_cloudwatch_event_businmodules/api/lambda.notification_event_bus_name(default empty, which means<project_name>-<environment>-events).notification_event_source(defaultcollaborative-ai-dlc). It's validated, and must not start withaws..NOTIFICATION_EVENT_BUS,NOTIFICATION_EVENT_SOURCE, and a separateevents:PutEventspolicy on that bus alone.notification_event_bus_nameandnotification_event_bus_arn.Events:
space.createdgate.pendingdiscussion.messagediscussion.resolvedEvery detail has
schemaVersion(1) and aneventIdfor deduplication.gate.pendingalso carriesneed(answerfor an agent question,approvalfor checkpoints and engine gates),kind,stage,intentTitle,startedByandprompt(an agent question's first question), so a consumer can render a useful message without calling back into the API.docs/using-the-platform/notification-events.md, added to the nav, documents every detail field, delivery semantics (normally once, at least once) and an example rule.Publishing (
lambda/shared/notification-events.js) is best-effort:gate-openstep. Either way, without a bus the step sequence of existing executions is unchanged.@aws-sdk/client-eventbridgeis added to the root devDependencies at the version the other clients use (^3.1106.0). That's wherelambda/sharedresolves its clients. The projects and v2-orchestrator bundles include it, and discussions uses the runtime's SDK like its other clients.Testing
lambda/shared/test/notification-events.test.jscovers no bus (no client load), the entry shape and default source, a custom source, rejected entries, send failures, client load failures, the real client loaded lazily, and thegate.pendingdetail:need, the prompt from aquestionsarray, clipping, and reading the gate and META only when not given them.lambda/v2-orchestrator/test/engine-gate-notification.test.jscovers engine gates: one publish per gate with the expected detail, nothing when the run was replaced, and an identical step sequence with and without a bus.npm run lint,npm run format:check, and the discussions, projects, v2-orchestrator and shared vitest projects pass, includingbundle-smoke.test.js. The projects and discussions bundles also import cleanly with a bus configured.terraform fmt -check,terraform validate -no-testsand everyterraform testsuite from the Terraform workflow pass on Terraform 1.15.0, as does the SSO plan-privacy test. There's no new Terraform test: a plan ofmodules/api/lambdabuilds every Lambda package.Impact
Disabled (the default), nothing is created and no Lambda's configuration changes. Event details include user names, email addresses and message text; the docs page says so.
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.