Repository navigation
feat(activity): attribute AI tool creates and edits to the tool actor (Macro AI) - #6050
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Team Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Team Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (23)
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review. 📝 SummarySummary by CodeRabbit
WalkthroughDocument update and delete metadata now includes optional Merge Risk: 🔵 Low · up to AI-created and edited documents will show Macro AI acting for the requesting user while preserving that user's permissions. The PR is mergeable with owner awareness that incorrect upstream identity binding could misattribute or authorize writes, and that attribution may be lost during partial event-publication or recovery failures. 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 8234e42. Configure here.
CreateDocument sets Delegated(MACRO_AI_BOT_ID, user). Rename, property writes, and MoveToProject mint a user-scoped AI bot receipt. Document Updated/Deleted gain actor and on_behalf_of so those receipts ingest as Edited, not Ignore. Co-authored-by: teo <synoet@users.noreply.github.com>
Same Kafka fields as property publish. A named struct replaces the positional triple. Co-authored-by: teo <synoet@users.noreply.github.com>
DocumentUpdatedMetadata and DocumentDeletedMetadata now carry optional actor and on_behalf_of. Refresh the OpenAPI spec and SDK types. Co-authored-by: teo
MoveToProject minted a Macro AI receipt for every entity kind, but chat patch, project updates, and email project-changed events still require an authenticated user. Only documents publish bot attribution. Co-authored-by: teo <synoet@users.noreply.github.com>
SetEntityProperty mints a Macro AI receipt, but parent/subtask checks treated every bot as denied and assignee notify read only authenticated_user. Use the acting user for both. Co-authored-by: teo <synoet@users.noreply.github.com>
…ceipt path - BotAccessScope::user replaces the per-crate ai_tool_user_scope helpers and inline literals. - MoveToProject mints entity and project receipts through a single MovePrincipal::receipt instead of two duplicated if/else blocks. - published_document_actors uses Default; mutation_attribution uses Attribution::new. Co-authored-by: teo <synoet@users.noreply.github.com>
16427d0 to
4cb7304
Compare
…Macro AI Every mutating AI tool hardcoded MACRO_AI_BOT_ID into whatever carrier its domain uses: create metadata, bot receipts, the collab JWT actor claim, the channel Sender. The identity now lives once on each toolset context as `actor: BotId` (default Macro AI) and ToolServiceContext::with_actor sets it for a whole agent session. Tools read service_context.actor; documents expose attribution(user) for the create metadata carrier, and MovePrincipal carries the bot it mints receipts for. Tests pin both the Macro AI default and with_actor flowing into the edit token, the create attribution, and the channel message sender.

Middle of the activity-attribution stack. Parent #6051 has merged; this PR is now based on
main.Stack
feat(activity): attribute EditDocument collab edits to the AI bot #6051 — EditDocument collab actor(merged)Supersedes #5841.
Why
AI tools that create or edit entities minted a user receipt or omitted attribution. Ingest then recorded a silent user write, or dropped the event. The feed should show the AI acting for the requesting user.
How identity flows
Tools never name a bot. Each toolset context (
DocumentToolContext,PropertiesToolContext,ProjectToolContext,ChannelToolContext) carriesactor: BotId, defaulting toMACRO_AI_BOT_ID, withwith_actor(BotId).ai_tools::ToolServiceContext::with_actorsets all four at once, so a host running a specific agent sets the identity once per session and every mutating tool follows. (ai_toolset::RequestContextis frozen, so the actor lives on the service contexts rather than the request.)Each domain then receives the actor through its own carrier:
generate_bot_entity_access_receipt(actor, BotAccessScope::user(user), ..)):RenameDocument,SetEntityProperty,BulkSetEntityPropertyOptions,MoveToProjectfor documents. The domain mapsEntityAccessAuth::Bottoactor/on_behalf_ofon the event.DocumentToolContext::attribution(user)→Attribution::delegated(actor, user)):CreateDocument, because the create path discards its receipt.actorclaim:EditDocument(carrier from feat(activity): attribute EditDocument collab edits to the AI bot #6051).Sender::new_from_bot(actor):SendChannelMessage.BotAccessScope::user(user_id)is the constructor for callers that know only the acting user (AI tool requests carry no org context).Coverage
Attributed to the actor on behalf of the user:
CreateDocument,EditDocument,RenameDocument,SetEntityProperty,BulkSetEntityPropertyOptions,MoveToProject(documents),SendChannelMessage.Still attributed to the user directly, because the domain does not yet accept a bot principal (
projectsdropsEntityAccessAuth::Bot, channels'user_sender(&receipt)?rejects it, email uses the acting user):MoveToProjectfor chat/email/project (MovePrincipal::User),CreateProject,CreateChannel,RenameChannel,ManageChannelParticipants,SendEmail,UpdateThreadLabels,SetSenderPolicy,CreateTag/EditTag/DeleteTag. Each of those becomes a one-line switch to the context actor once its domain accepts bot receipts; that is follow-up work per domain.No
ActivitySourceat all (out of scope for activity): calendar, reminders, import, notifications, bots tools. The import job'sToolEntityCreatorkeepsMACRO_AI_BOT_IDbecause it runs detached from the requesting agent's session.Also in this PR
DocumentUpdatedMetadataandDocumentDeletedMetadataadd optionalactorandon_behalf_of.published_document_actorsfills them from a user-scoped bot receipt. Ingest usesmutation_attributionso those events becomeEdited/Deletedinstead ofIgnore.SetEntityPropertyparent/subtask access and assignee notify useacting_user_id()so a user-scoped bot receipt can link tasks and notify.EditDocumentkeeps a user receipt for the access check; attribution rides the JWTactor.Tests
documents: edit token carries the context actor (with_actor) and defaults to Macro AI;attribution(user)is delegated from the context actor.channels:SendChannelMessageposts as the default Macro AI sender and as awith_actorbot, withtriggered_byset to the user.properties,projects: schema tests unchanged; receipts now readservice_context.actor.Blast Radius
User-receipt document edits keep the old
actor_user_idJSON. Team-scoped bot deletes stay unattributed. Downstream Kafka test fixtures that construct Updated/Deleted set the new optional fields. Property and project crates depend onbot_id.documentsandchannelsaddbot_id/test-utilsas a dev-dependency forBotId::TEST_A.