mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-20 01:41:26 +02:00
docs(ai): document Actor attribution + AI Workbench pilot
- COMPANION_BRAIN_ARCHITECTURE §20: Actor model, policy layer, pendingProposals lifecycle, ghost-UI pilot, roadmap, open follow-ups, manual test snippet - DATA_LAYER_AUDIT §9: new Actor columns on records (`__lastActor`, `__fieldActors`), `pendingProposals` table, write-path diagrams for user / AI / approval, open mana-sync Go + Postgres work - apps/mana/CLAUDE.md: short AI Workbench section with pointers + Dexie hook now lists actor stamping Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
851a281e5a
commit
0f3fd4eebd
3 changed files with 174 additions and 2 deletions
|
|
@ -70,7 +70,8 @@ table.add(encryptedRecord) ← Dexie write
|
|||
Dexie hooks (database.ts):
|
||||
- stamp userId
|
||||
- stamp __fieldTimestamps per field
|
||||
- record into _pendingChanges (tagged with appId)
|
||||
- stamp __lastActor + __fieldActors (user / ai / system — see AI Workbench)
|
||||
- record into _pendingChanges (tagged with appId + actor)
|
||||
- record into _activity
|
||||
│
|
||||
▼
|
||||
|
|
@ -166,11 +167,22 @@ pnpm test:e2e # Playwright
|
|||
|
||||
Svelte 5 runes are mandatory — no legacy `let count = 0; $: doubled = count * 2`. Always `$state`, `$derived`, `$effect`. See [`.claude/guidelines/sveltekit-web.md`](../../.claude/guidelines/sveltekit-web.md).
|
||||
|
||||
## AI Workbench (in progress)
|
||||
|
||||
The companion is being rebuilt into a **second actor** that works alongside the human in every module. Foundation shipped 2026-04-14:
|
||||
|
||||
- **Actor attribution** — every event, record, and sync row carries `{ kind: 'user' | 'ai' | 'system' }`. Code: `src/lib/data/events/actor.ts`.
|
||||
- **AI policy** — per-tool `auto | propose | deny`. AI-attributed tool calls default to `propose`, which stages an intent in `pendingProposals` instead of writing. Code: `src/lib/data/ai/policy.ts`.
|
||||
- **Proposal inbox** — drop `<AiProposalInbox module="todo" />` into any module page to render pending proposals inline as ghost cards with approve/reject. Wired in `/todo` as pilot.
|
||||
|
||||
Full architecture + roadmap (Missions, Runner, Workbench lens, server-side runner): [`docs/architecture/COMPANION_BRAIN_ARCHITECTURE.md` §20](../../docs/architecture/COMPANION_BRAIN_ARCHITECTURE.md).
|
||||
|
||||
## Reference Documents
|
||||
|
||||
| Path | Purpose |
|
||||
|------|---------|
|
||||
| [`apps/web/src/lib/data/DATA_LAYER_AUDIT.md`](apps/web/src/lib/data/DATA_LAYER_AUDIT.md) | Data-layer + sync deep dive, encryption rollout, threat model, backlog |
|
||||
| [`apps/web/src/lib/data/DATA_LAYER_AUDIT.md`](apps/web/src/lib/data/DATA_LAYER_AUDIT.md) | Data-layer + sync deep dive, encryption rollout, threat model, Actor attribution, backlog |
|
||||
| [`docs/architecture/COMPANION_BRAIN_ARCHITECTURE.md`](../../docs/architecture/COMPANION_BRAIN_ARCHITECTURE.md) | Companion brain + AI Workbench (Actor, Policy, Proposals, Missions roadmap) |
|
||||
| `apps/docs/src/content/docs/architecture/security.mdx` | User-facing security walkthrough |
|
||||
| `apps/docs/src/content/docs/architecture/authentication.mdx` | Auth flow + JWT structure |
|
||||
| [Root `CLAUDE.md`](../../CLAUDE.md) | Monorepo overview, services, dev commands, env vars |
|
||||
|
|
|
|||
|
|
@ -590,3 +590,52 @@ Zero-Knowledge-User: bis zum MK-Transfer-Pfad (M5) können sie sich selbst resto
|
|||
- **Signatur**: Ed25519 über `manifest.json` gegen Tampering — heute nur sha256 über events.jsonl
|
||||
- **Resumable Download**: Multi-GB-Accounts werden irgendwann fraglich im Browser
|
||||
- **`_appliedEventIds` Dedup-Tabelle**: Performance-Optimierung für Re-Import (heute macht LWW den Dedup, aber wir verarbeiten trotzdem jedes Event)
|
||||
|
||||
## 9. Actor-Attribution & AI-Workbench (ab 2026-04-14)
|
||||
|
||||
Jeder Write — User, AI, Subsystem — trägt ab jetzt einen expliziten `Actor`. Die Data-Schicht ist Source of Truth: ambient Context (`runAs`) ist nur Ergonomie-Schicht an definierten Boundaries, Primitive frieren den Actor synchron ein.
|
||||
|
||||
### Schreib-Pfade
|
||||
|
||||
```
|
||||
User-UI → tool.execute() → DB-Write
|
||||
hook stamps actor from getCurrentActor() → { kind: 'user' }
|
||||
__lastActor, __fieldActors, Event.meta.actor, _pendingChanges.actor ← alle tragen actor
|
||||
|
||||
AI-Orchestrator → executeTool(name, params, aiActor)
|
||||
→ policy.resolvePolicy() === 'propose'
|
||||
→ createProposal(...) [staged in pendingProposals, NICHT geschrieben]
|
||||
|
||||
User approved Proposal → approveProposal(id)
|
||||
→ runAsAsync(aiActor, () => executeToolRaw(...))
|
||||
→ wie User-Pfad, aber alle Stempel = { kind: 'ai', missionId, ... }
|
||||
```
|
||||
|
||||
### Neu im Record-Schema
|
||||
|
||||
| Feld | Typ | Zweck |
|
||||
| --------------- | ---------------------- | -------------------------------------------------------------------- |
|
||||
| `__lastActor` | `Actor` | Wer hat den Record zuletzt als Ganzes geschrieben (Workbench-Badges) |
|
||||
| `__fieldActors` | `Record<field, Actor>` | Parallel zu `__fieldTimestamps`, fuer feldweise Diffs |
|
||||
|
||||
Beide werden vom Dexie-Hook gestempelt. `isInternalKey` strippt sie aus dem Sync-Payload — sie sind rein lokales Bookkeeping.
|
||||
|
||||
### Neue Tabellen
|
||||
|
||||
| Tabelle | Sync? | Inhalt |
|
||||
| ------------------ | ------------ | ----------------------------------- |
|
||||
| `pendingProposals` | Nein (lokal) | Staged AI-Intents awaiting approval |
|
||||
|
||||
Proposals syncen **nicht** — der approved Write läuft normal durch den Modulpfad und syncet mit AI-Actor attribuiert. Indexe: `id, status, createdAt, missionId, [status+createdAt]`.
|
||||
|
||||
### Policy
|
||||
|
||||
`apps/mana/apps/web/src/lib/data/ai/policy.ts` — per-Tool `auto | propose | deny`. User/System Actors umgehen die Policy. Default konservativ: alles Mutierende → `propose`.
|
||||
|
||||
### Offene Server-Seite
|
||||
|
||||
`_pendingChanges.actor` landet im mana-sync Payload. Der Go-Server muss das Feld annehmen und in Postgres persistieren — separater Migration-Step. Bis dahin verwirft mana-sync das Feld stillschweigend (unknown fields werden ignoriert), cross-device Attribution fehlt.
|
||||
|
||||
### Deep-Dive
|
||||
|
||||
Architektur-Doku mit Roadmap + manuellen Tests: [`docs/architecture/COMPANION_BRAIN_ARCHITECTURE.md` §20](../../../../../../docs/architecture/COMPANION_BRAIN_ARCHITECTURE.md).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue