todo2code

Ticket 020: Role-bound trusted intake with CQRS, ES, Protobuf, MCP and A2A

Goal and scope

Implement a deterministic trusted-intake boundary which binds every captured human message to a verified stable participant, a persistent governance role (manager, user or dev) and one ticket. The assignment is stored in a repository-level participant registry, so it remains stable across tickets. Filename prefixes are projections of verified identity and role; they are never accepted as identity evidence by themselves.

The boundary will expose one domain contract through a Python shell CLI, the existing TypeScript CLI, MCP tools and an A2A skill. All transports call the same command/query handlers and return the same stable diagnostic codes. The required decision path is deterministic and does not call an LLM.

The implementation uses CQRS and event sourcing:

The canonical transport envelope is Protobuf. Strict JSON Schemas validate the JSON representation and command payloads. TypeScript and dependency-free Python codecs support the limited wire types used by the envelope and are checked against shared golden vectors.

This interfaces ticket owns only src/communication/**, src/interfaces/**, src/cli.ts and matching interface tests. It will not change package, top-level schema, Docker, SDK or documentation paths. If such a shared path is proved necessary, work stops and a separate integration ticket is planned and approved instead of widening this scope.

Role and authority model

kind and governanceRole are separate fields. Humans have a stable participant-id and one primary governance role; agents retain an agent:* identity and cannot acquire a human role. Roles grant explicit capabilities, not implicit inheritance:

Role changes are versioned commands authorized by the configured manager or a trusted intake policy. Historical role files are migration evidence only and cannot silently change the registry.

Planned contracts

Commands include RegisterParticipant, BindExternalIdentity, AssignRole, CaptureMessage, RebuildProjection and VerifyEventStream. Queries include ResolveParticipant, GetRole, GetTicketConversation, GetCommandStatus and ValidateProjection.

Events include ParticipantRegistered, ExternalIdentityBound, GovernanceRoleAssigned, MessageCaptured and ProjectionRebuilt. Rejected commands produce a sanitized audit result, not a successful domain event.

The response envelope contains at least: schema version, message ID, correlation/causation IDs, authenticated principal, aggregate ID, expected and actual stream versions, idempotency key, timestamp, payload hash, diagnostic code, remediation and retryability.

Acceptance criteria

Participants

Approval record

The user explicitly instructed the agent to implement (“wdrażaj”) in chat on 2026-08-01 after the agent restated that ticket-020 and AC-01..AC-19 required explicit approval. This authorizes the interactive EDIT phase only; it is not trusted merge evidence.

Risks and stop conditions

Implementation and validation result

Final closure evidence