System model
Current state + immutable historyTwo writers. One execution truth.
Humans write through Flutter. Agents write through MCP and the API. Both update the same WorkItem graph and append attributable events.
Selected boundaryFirestore
- Credential
- Rules or Admin SDK
- Responsibility
- WorkItem current state and append-only ExecutionEvents
- Trust boundary
- Integration secrets and key hashes are denied to all clients.
Atomic execution
A transition writes state and evidence together
A completion is not finished unless both the current item and its event commit successfully.
Before
status: in_progresszoneId: focuscompletedAt: nullcompleteone transaction
After
+status: donezoneId: donecompletedBy: actorId Appended event
type: completedactorId: agent:buildidempotencyKey: ...Firestore shape
Top-level executable work
Stack, Queue, Zones, and Done are derived views. Durable work state is stored once.
users/{uid}/goals/{goalId}Outcome and timeframeusers/{uid}/workItems/{workItemId}Current executable truthusers/{uid}/actors/{actorId}Human and agent identityusers/{uid}/executionEvents/{eventId}Append-only historyusers/{uid}/executionZones/{zoneId}Lanes and WIP limitsusers/{uid}/integrations/{integrationId}Connection metadataSecrets never cross into Flutter or MCP
API-key hashes, encrypted Slack tokens, and OAuth state live in server-only collections denied to Firestore clients.
Every accepted action remains attributable