Files
swarm-zap/WIP.md

15 KiB

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

  • Live openclaw-action workflow exists and is active.
  • Live workflow re-synced from the current workspace asset after implementation completed.
  • 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
  • Approval-gated notification execution works live:
    • send_notification_draft
    • approve → real notify

Google access

  • gog installed and authenticated for:
    • Gmail
    • Calendar
    • Drive
    • Contacts
    • Docs
    • Sheets
  • Local-only Gog automation env stored outside git at:
    • /home/openclaw/.openclaw/credentials/gog.env
  • Host bridge implemented:
    • skills/n8n-webhook/scripts/resolve-approval-with-gog.py
  • n8n history patch action implemented:
    • approval_history_attach_execution
  • Dry-run end-to-end bridge tests succeeded for:
    • Gmail draft creation
    • Calendar event creation
  • Headless non-interactive Gog execution works via the stored local env.
  • Direct real Gmail draft create test succeeded.
  • Direct real Gmail draft delete test succeeded.
  • 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
  • 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

  • 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
  • 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

  • Add delete_email_draft
  • Add list_email_drafts
  • Add send_gmail_draft / send-approved-email path
  • Add update_calendar_event
  • Add delete_calendar_event
  • 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

  • Add a compact operator command/reference section for common approval flows
  • Add one or two canned test payloads for real bridge verification flows
  • Decide/document approval defaults clearly per action family
  • 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_draftsgog gmail drafts list
    • email_draft_deletegog gmail drafts delete
    • email_draft_sendgog 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_emailresult.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_eventsgog calendar events
    • calendar_event_updategog calendar update
    • calendar_event_deletegog calendar delete
  • docs + sample payloads + workflow validator updates for the expanded calendar contract
  • explicit approval policy preserved:
    • list_upcoming_eventsapproval.mutation_level = low
    • update_calendar_event / delete_calendar_eventapproval.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_eventsgog calendar events primary --account will@example.com --json --no-input --max 10 --days 7 --query zap --dry-run
    • calendar_event_updategog 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_deletegog 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_logok: true
    • get_logsok: true
    • list_email_draftsstatus: queued_for_approval
    • list_upcoming_eventsstatus: queued_for_approval
    • approval_queue_listok: true, with pending_compact + history_compact present
    • fetch_and_normalize_url against local n8n /healthzok: 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