Files
swarm-zap/WIP.md

323 lines
15 KiB
Markdown

# WIP.md
## Current focus
Google Workspace + n8n integration
## Goal
Use OpenClaw as the brain, n8n as the orchestration layer, and Google Workspace as a real execution surface for Gmail/Calendar workflows.
## Current status
Status: `completed`
Owner: `zap`
Started: `2026-03-12`
Completed: `2026-03-12`
### Architecture decision
- Keep `openclaw-action` as the narrow authenticated ingress into n8n.
- Keep approval/state/logging in n8n.
- Use workflow static data for tiny internal state and recent operational breadcrumbs.
- Do not adopt n8n data tables as the default state store yet; revisit only when shared row-based data, UI browsing/editing, or richer querying becomes a real need.
- Use host-side `gog` execution for Google Workspace actions for now.
- Attach execution results back into n8n history so approval items become auditable records.
- Prefer this over broad n8n Google credential sprawl unless a later need clearly justifies it.
### Where n8n is a good fit here
- approval-gated actions and human-in-the-loop workflows
- cross-system glue / action-bus routing
- inbound event filtering, normalization, and dedupe
- notification fanout and formatting
- retries / backoff / rate-limit wrappers around brittle integrations
- fetch-and-normalize pipelines for URLs or provider payloads
- compact audit trail / operator history
### Where n8n is not the default
- primary long-term database
- heavy archival logging
- large or fast-growing datasets
- business logic that is clearer and safer in normal code
## What is already done
### n8n action bus
- [x] Live `openclaw-action` workflow exists and is active.
- [x] Live workflow re-synced from the current workspace asset after implementation completed.
- [x] Core actions verified live:
- `append_log`
- `get_logs`
- `notify`
- `approval_queue_add`
- `approval_queue_list`
- `approval_queue_resolve`
- `fetch_and_normalize_url`
- `inbound_event_filter`
- [x] Approval-gated notification execution works live:
- `send_notification_draft`
- approve → real `notify`
### Google access
- [x] `gog` installed and authenticated for:
- Gmail
- Calendar
- Drive
- Contacts
- Docs
- Sheets
- [x] Local-only Gog automation env stored outside git at:
- `/home/openclaw/.openclaw/credentials/gog.env`
- [x] Host bridge implemented:
- `skills/n8n-webhook/scripts/resolve-approval-with-gog.py`
- [x] n8n history patch action implemented:
- `approval_history_attach_execution`
- [x] Dry-run end-to-end bridge tests succeeded for:
- Gmail draft creation
- Calendar event creation
- [x] Headless non-interactive Gog execution works via the stored local env.
- [x] Direct real Gmail draft create test succeeded.
- [x] Direct real Gmail draft delete test succeeded.
- [x] Real n8n-routed Gmail draft test succeeded end-to-end (queue → approve via bridge → verify → delete).
- approval id: `approval-mmnvjcak-qcuhbzqd`
- draft id: `r348335896293726096`
- subject: `[zap n8n e2e] Gmail draft test 20260312T194153Z`
- [x] Real n8n-routed Calendar event test succeeded end-to-end (queue → approve via bridge → verify → delete).
- approval id: `approval-mmnvjyo5-uezhcw84`
- event id: `il3ojkfnsnq3uhlepvrmaklpq4`
- title: `[zap n8n e2e] Calendar test 20260312T194222Z`
## What is left
### Highest priority: prove the bridge with real Google writes
- [x] Real end-to-end Gmail draft via n8n path:
1. queue `send_email_draft`
2. approve via `resolve-approval-with-gog.py`
3. verify draft exists in Gmail
4. delete the test draft
- [x] Real end-to-end Calendar event via n8n path:
1. queue `create_calendar_event`
2. approve via bridge
3. verify event exists in Calendar
4. delete the test event
### Then expand useful Google actions
- [x] Add `delete_email_draft`
- [x] Add `list_email_drafts`
- [x] Add `send_gmail_draft` / send-approved-email path
- [x] Add `update_calendar_event`
- [x] Add `delete_calendar_event`
- [x] Add `list_upcoming_events`
- [ ] Decide whether Drive/Docs/Sheets need action-bus verbs next or can stay direct-tool only for now
### Then polish the operator experience
- [x] Add a compact operator command/reference section for common approval flows
- [x] Add one or two canned test payloads for real bridge verification flows
- [x] Decide/document approval defaults clearly per action family
- [x] Add low-noise reporting so history clearly shows:
- queued
- approved/rejected
- executed
- execution result id / draft id / event id
## Nice-to-have / future
- [ ] Evaluate whether native n8n Google nodes are worth adding later
- [ ] Add retry/backoff wrappers for fragile or rate-limited actions
- [ ] Expand notification fanout / routing rules if more channels become useful
- [ ] Add more inbound event normalization/filtering when new providers are wired in
- [ ] Revisit n8n data tables only if shared row-based operator data becomes useful
- [ ] If useful, sync this work into the LAN Gitea repo for safer backup/review and easier long-lived tracking
## Current recommendation
Execution should proceed in staged fresh sessions using `WIP.md` as the canonical state file.
Execution note:
- For the remaining implementation passes on this WIP, prefer Codex `gpt-5.4` to reduce iteration time and avoid model-availability churn.
Planned passes:
1. Gmail pass: ✅ complete
- added `delete_email_draft`
- added `list_email_drafts`
- added `send_gmail_draft` / send-approved-email path
- updated workflow contract/docs/test payloads/bridge + WIP evidence
2. Calendar pass: ✅ complete
- added `update_calendar_event`
- added `delete_calendar_event`
- added `list_upcoming_events`
- updated workflow contract/docs/test payloads/bridge + WIP evidence
3. Operator/polish pass: ✅ complete
- documented approval defaults by action family (`notification`, `gmail`, `calendar`, `manual`)
- added low-noise queue/history reporting (`pending_compact`, `history_compact`, `summary_line`, `result_refs`)
- added compact operator command/reference docs
- added two canned recurring verification payloads
- refreshed `WIP.md` with evidence before ending the pass
## Fresh-session proof refresh (2026-03-12 19:44Z)
- Re-ran both target proofs through the real approval-routed path in a clean implementation session.
- Gmail draft flow:
- approval id: `approval-mmnvn4t2-w2rjlwz2`
- draft id: `r-3319106208870238577`
- subject: `[zap n8n e2e] Gmail draft test 20260312T194450Z`
- verified via `gog gmail drafts get`
- cleaned via `gog gmail drafts delete --force`
- Calendar flow:
- approval id: `approval-mmnvn6i8-e9eq8gdf`
- event id: `m7prri8vk2opuo6loq3qgtvsv4`
- title: `[zap n8n e2e] Calendar test 20260312T194450Z`
- verified via `gog calendar get primary <eventId>`
- cleaned via `gog calendar delete primary <eventId> --force`
## Gmail pass 1 completion (2026-03-12)
Implemented in this pass:
- workflow contract + router logic for:
- `list_email_drafts`
- `delete_email_draft`
- `send_gmail_draft` (alias: `send_approved_email`)
- explicit per-action approval metadata in queued responses (`approval.policy`, `approval.required`, `approval.mutation_level`)
- host bridge executor coverage for new approval kinds:
- `email_list_drafts``gog gmail drafts list`
- `email_draft_delete``gog gmail drafts delete`
- `email_draft_send``gog gmail drafts send`
- docs + sample payloads + workflow validator updates for the new contract
Targeted verification evidence:
- `python3 skills/n8n-webhook/scripts/validate-workflow.py skills/n8n-webhook/assets/openclaw-action.workflow.json`
- result: `OK: workflow asset structure looks consistent`
- Router simulation against the shipped workflow JS (`verify-list-001`, `verify-delete-001`, `verify-send-001`, `verify-send-alias-001`):
- all returned `status: queued_for_approval`
- alias normalization confirmed (`send_approved_email``result.action = send_gmail_draft`)
- approval metadata returned with expected mutation levels (`low` for list, `high` for delete/send)
- generated pending ids in the simulation run:
- `approval-mmny879w-5sncgd98`
- `approval-mmny879w-a353xg8q`
- `approval-mmny879w-yvqzokpz`
- `approval-mmny879w-md99hqxs`
- Bridge dry-run command execution (via real `gog` CLI) for new Gmail kinds:
- list: exit `0`, returned draft list JSON
- delete: exit `0`, returned dry-run op `delete gmail draft r-example-draft-id`
- send: exit `0`, returned dry-run op `gmail.drafts.send`
- `python3 -m py_compile skills/n8n-webhook/scripts/resolve-approval-with-gog.py` passed.
## Calendar pass 2 completion (2026-03-12)
Implemented in this pass:
- workflow contract + router logic for:
- `list_upcoming_events`
- `update_calendar_event`
- `delete_calendar_event`
- host bridge executor coverage for new approval kinds:
- `calendar_list_events``gog calendar events`
- `calendar_event_update``gog calendar update`
- `calendar_event_delete``gog calendar delete`
- docs + sample payloads + workflow validator updates for the expanded calendar contract
- explicit approval policy preserved:
- `list_upcoming_events``approval.mutation_level = low`
- `update_calendar_event` / `delete_calendar_event``approval.mutation_level = high`
Targeted verification evidence:
- `python3 skills/n8n-webhook/scripts/validate-workflow.py skills/n8n-webhook/assets/openclaw-action.workflow.json`
- result: `OK: workflow asset structure looks consistent`
- Workflow asset inspection confirmed new router actions are present:
- `list_upcoming_events`
- `update_calendar_event`
- `delete_calendar_event`
- Host bridge command-builder verification from shipped sample payloads:
- `calendar_list_events``gog calendar events primary --account will@example.com --json --no-input --max 10 --days 7 --query zap --dry-run`
- `calendar_event_update``gog calendar update primary example-calendar-event-id --account will@example.com --json --no-input --send-updates none --summary Updated call with vendor --from 2026-03-13T18:15:00Z --to 2026-03-13T18:45:00Z --description Updated by OpenClaw action bus. --location Updated room --dry-run`
- `calendar_event_delete``gog calendar delete primary example-calendar-event-id --account will@example.com --json --no-input --force --send-updates none --dry-run`
- `python3 -m py_compile skills/n8n-webhook/scripts/resolve-approval-with-gog.py` passed.
## Operator/polish pass 3 completion (2026-03-12)
Implemented in this pass:
- added explicit approval-family defaults in the shipped workflow + docs:
- `notification` → required `high`
- `gmail` read-only (`list_email_drafts`) → required `low`
- `gmail` mutating (`send_email_draft`, `delete_email_draft`, `send_gmail_draft`) → required `high`
- `calendar` read-only (`list_upcoming_events`) → required `low`
- `calendar` mutating (`create_calendar_event`, `update_calendar_event`, `delete_calendar_event`) → required `high`
- added compact operator-facing queue/history fields in the workflow:
- `payload_preview`
- `operator.summary_line`
- `operator.execution_state`
- `operator.result_refs`
- `approval_queue_list.result.pending_compact`
- `approval_queue_list.result.history_compact`
- `approval_queue_resolve.result.item_compact`
- `approval_history_attach_execution.result.item_compact`
- taught the host bridge to attach `execution.summary` + `execution.result_refs`
- added recurring verification payloads:
- `skills/n8n-webhook/assets/test-verify-email-draft-cycle.json`
- `skills/n8n-webhook/assets/test-verify-calendar-event-cycle.json`
- added operator runbook / recurring verification docs in:
- `skills/n8n-webhook/references/openclaw-action.md`
- `skills/n8n-webhook/references/payloads.md`
- `skills/n8n-webhook/SKILL.md`
Targeted verification evidence:
- `python3 skills/n8n-webhook/scripts/validate-workflow.py skills/n8n-webhook/assets/openclaw-action.workflow.json`
- result: `OK: workflow asset structure looks consistent`
- validator now also checks the two new recurring verification payload files
- `python3 -m py_compile skills/n8n-webhook/scripts/resolve-approval-with-gog.py`
- result: passed
- bridge helper proof via direct import/execution:
- `execution_result_refs('gmail.drafts.create', {'draft': {'id': 'r-proof-draft-123'}})``{'draft_id': 'r-proof-draft-123'}`
- `execution_summary(...)``gmail.drafts.create draft created (draft_id=r-proof-draft-123)`
- `execution_result_refs('calendar.create', {'event': {'id': 'evt-proof-456'}, 'calendar': 'primary'})``{'event_id': 'evt-proof-456', 'calendar': 'primary'}`
- `execution_summary(...)``calendar.create event created (event_id=evt-proof-456, calendar=primary)`
- workflow asset inspection confirmed low-noise operator fields are present:
- `pending_compact`
- `history_compact`
- `summary_line`
- `result_refs`
- `default_mode`
- `approval.family`
- recurring verification payload identity proofs:
- `test-verify-email-draft-cycle.json` → request id `verify-email-draft-cycle-001`
- `test-verify-calendar-event-cycle.json` → request id `verify-calendar-event-cycle-001`
## Live deploy + smoke verification (2026-03-12 21:36Z)
- Live workflow id: `Jwi54VWMdlLqYnRo`
- Synced the active n8n workflow in place from the current `skills/n8n-webhook/assets/openclaw-action.workflow.json` asset while preserving:
- webhook credential binding
- webhook registration id
- active state
- First live sync revealed the old minimal router was still running; re-synced from the current full code-node asset and re-activated successfully.
- Safe smoke calls succeeded against the production webhook:
- `append_log``ok: true`
- `get_logs``ok: true`
- `list_email_drafts``status: queued_for_approval`
- `list_upcoming_events``status: queued_for_approval`
- `approval_queue_list``ok: true`, with `pending_compact` + `history_compact` present
- `fetch_and_normalize_url` against local n8n `/healthz``ok: true`, HTTP `200`
- unknown action → expected HTTP `400` / `unknown_action`
- Smoke-created approval items were rejected and cleaned up:
- `approval-mmnzm1ev-yjk46sd1`
- `approval-mmnzm1gi-l7yszi92`
- `approval-mmnzmw80-kb8szya2`
- `approval-mmnzmw9w-c25hlml4`
- Remaining pending queue items after cleanup were pre-existing and left untouched:
- `approval-mmnvgv1o-h06r397e`
- `approval-mmnulm6r-mfaj7ea8`
## Next-session handoff
This WIP is complete. For the next fresh implementation session, review `HANDOFF.md` plus the proposed next-phase file `WIP.drive-docs-sheets.md`.
Immediate target:
- decide whether Drive / Docs / Sheets actually need action-bus verbs or can remain direct-tool workflows for now
- if Google action coverage expands again, preserve the same approval-family defaults and compact history contract
- refresh WIP/memory/tasks before ending
## Relevant files
- `skills/n8n-webhook/assets/openclaw-action.workflow.json`
- `skills/n8n-webhook/scripts/call-action.sh`
- `skills/n8n-webhook/scripts/resolve-approval-with-gog.py`
- `skills/n8n-webhook/references/openclaw-action.md`
- `memory/2026-03-12.md`
- `/home/openclaw/.openclaw/credentials/gog.env` (local-only, not for git)
## Current branch / checkpoints
- branch: `feat/n8n-action-bus-v2`
- key commits:
- `ffe7a6b` — add operator approval runbook
- `249e671` — add compact approval history views
- `9dcc477` — expand action bus starter workflow
- `dc990a1` — deploy and verify expanded action bus
- `1eabaeb` — add approval-gated notification executor
- `afa48a3` — bridge approvals to gog executors
- `044e36f` — auto-load local gog automation env