Orchestrata Ultimate › Plans › spec-audit › H-integrations
Cluster H — External integrations & agent harnesses (SPEC-017, 018, 020, 021, 052)
Source: plans/spec-audit/H-integrations.md at 8a2cb42ad · last changed 2026-07-27 · first committed 2026-07-04 · 298 lines.
Prose pending.
Plan text
Cluster H — External integrations & agent harnesses (SPEC-017, 018, 020, 021, 052)
Investigation agent report. READ-ONLY audit against actual code; boxes in
specs/*/checklists/requirements.md ignored per _METHOD.md. None of these 5
specs appear in docs/spec-gap-register.md (which covers 20 core specs), so
there is no prior audit to reconcile — this is a fresh judgement.
Cross-cutting note on where the code lives. Three of these specs are not
Python-src/ features:
- SPEC-017 (calendar) and SPEC-052 (todoist) are browser gadgets under
vizint-ui/gadgets/; SPEC-018 (fireflies) is a hybrid (Python MCP bridge insrc/+ a missing browser gadget). - SPEC-020 is a Claude Code hook harness version-controlled in
claude/(deployed to~/.claude/), and SPEC-021 is an OpenCode TypeScript plugin inopencode/. Neither belongs insrc/orchestrata_ultimate/.
Copy-paste artifact warning. The ## Visual Architecture Mermaid class
diagrams in SPEC-017/018/021/052 all show the same four unrelated classes
(CheetahClawsTUI, OpenRouterProvider, TodoistIntegration, VizIntWebUI).
These are boilerplate carried over from the source monorepo and do not
describe the ultimate implementation — ignore them when reading the specs.
SPEC-017 Calendar Integration — PARTIAL
- Specifies: A VizInt Command Center browser gadget with a day-view timeline, Google Calendar (OAuth2) + CalDAV providers, event creation, and automatic session start/close → calendar-event sync.
- Verified:
- ✅ Gadget exists and is wired/registered:
CalendarGadget(vizint-ui/gadgets/calendar/gadget.js:57), registered as manifestorchestrata-calendarinvizint-ui/app.js:98-104and loaded by_registerGadgets()(app.js:218). - ✅ Both providers implement the
ICalendarProvidercontract:CalDAVProvider(providers.js:21, PROPFIND/REPORT/PUT + Basic auth) andGoogleCalendarProvider(providers.js:156) with OAuth2 implicit flow (response_type=token,accounts.google.com/o/oauth2/v2/auth,providers.js:170-174) and Bearer auth (providers.js:178). - ✅ Day-view timeline geometry + "now" marker:
timeline.js(splitEventsForDay,blockGeometry,nowMarkerPct,formatRange). Timeline CSS (.calendar__timeline1440px,.calendar__now-marker) present. - ✅ RFC-5545 iCalendar parsing:
ical.js(+ unit testvizint-ui/tests/unit/calendar-ical.test.js,calendar-timeline.test.js). - ✅ Session→calendar sync (US-004):
SessionCalendarSync(sync.js:11) subscribessession.events(sync.js:37), createsOrchestrata Session {id}onopened(sync.js:68-75) and recordsclosed(sync.js:86-99). Encrypted credential storage vialib/crypto.js. - ✅ Day navigation: prev/next/refresh handlers (
gadget.js:209-211,345-354). - ⚠️ Event creation UI (US-003 / FR-004) missing. Providers expose
createEvent, butgadget.jshas no "New Event" form and never calls it (0createEvent/newEventrefs ingadget.js); nocalendar.event.createdbus emit. OnlySessionCalendarSynccreates events. - ❌ Offline retry/backoff queue (FR-005 / SAC-US4-06) absent —
sync.jshas noretry/backoff/localStoragequeue; a failed session sync is not persisted/retried. - ❌ Cache TTL (FR-001), health/metrics/tracing (Observability §) absent.
- ❌ Multi-account (US-002) / calendar toggle / date-picker not evidenced.
- ✅ Gadget exists and is wired/registered:
- Remaining work / plan:
- Scope: (1) add an event-creation form to the gadget wired to
provider.createEvent+ emitcalendar.event.createdonctx.bus; (2) add localStorage-backed retry queue with exponential backoff toSessionCalendarSync; (3) add in-memory event cache w/ TTL; (4) optionalctx.health/ctx.metricsreporting. - Target files:
vizint-ui/gadgets/calendar/gadget.js,sync.js; new small form module; tests undervizint-ui/tests/. - Approach: The provider/timeline/ical foundation is solid and real (no mocks, real fetch). Work is UI + resilience glue, not new provider protocol.
- Dependencies: SPEC-016 Command Center (
ctx.bus, GadgetBridge,session.eventsemitted by the session-manager gadget). No Python coupling. - Effort: M. Risk: low (isolated browser gadget; established patterns).
- Scope: (1) add an event-creation form to the gadget wired to
- Evidence log:
symbols --pattern Calendar→ 0 (no Python);find vizint-ui/gadgets/calendar→ gadget/ical/providers/sync/timeline.js; grep ofapp.js→ manifestorchestrata-calendarregistered; grep providers.js → OAuth2 implicit + CalDAV; grep gadget.js → no createEvent/New-Event UI; grep sync.js → no retry/backoff/localStorage.
SPEC-018 Fireflies Integration — PARTIAL
- Specifies: A Fireflies.ai browser gadget (transcript list, search,
summaries, session-linking, config — US-001..US-005) plus a Python
server-side MCP bridge exposing
fireflies.*gateway RPC (US-006). - Verified:
- ✅ MCP bridge (US-006) is real and WIRED.
FirefliesHandler(src/orchestrata_ultimate/gateway/handlers/fireflies.py:16) is imported and instantiated ingateway/rpc.py:93, and its 4 methods are registered in the RPC method map:fireflies.transcripts/transcript/search/summary(gateway/rpc.py:353-356).refs FirefliesHandler→ 1 def, 2 imports, 2 uses. - ✅
FirefliesClient(integrations/fireflies_client.py:79) is a real GraphQL client overhttpx(declaredhttpx>=0.28.0), withlist_transcripts/get_transcript/search_transcripts/summarize_transcript; driven by a real-HTTP integration test (tests/integrations/test_fireflies_client.pyagainsttests.real_http_server.graphql_server).refs→ 3 imports, 5 uses. - ❌ Entire browser gadget (US-001..US-005) is ABSENT. There is no
vizint-ui/gadgets/fireflies/directory (confirmed: gadget list has calendar & todoist but no fireflies). Transcript list, search UI, summary tabs, session-linking, and the config/API-key panel do not exist. - ⚠️ Caching & rate-limiting missing from the WIRED path (SAC-US006-05/06).
The gateway
FirefliesHandlerdoes no caching and the client does no 429/backoff handling (grep: nocache/rate/retry/429infireflies_client.py). Caching does exist inFirefliesMCPTools(session/fireflies_tools.py:46,cache_ttl=600, REQ-018-074) — but that class is ORPHANED:refs FirefliesMCPTools→ 1 def, 0 imports, 0 uses (production). It is tested (tests/session/test_fireflies_tools.py) but never wired into the gateway → classic false-confidence pattern. - ⚠️ Write-side KG sync orphaned.
FirefliesKnowledgeSync(integrations/fireflies_sync.py:42, upserts transcripts as Neo4j:Documentnodes) →refs0 imports/0 uses. Its docstring names afireflies.syncRPC that is not registered ingateway/rpc.py. Tested (tests/knowledge_graph/test_fireflies_sync.py) but unwired. - ⚠️ Divergence from FR-005: spec says "register a
FirefliesMCPBridgeas a SPEC-015 plugin"; the impl instead wiresFirefliesHandlerdirectly intogateway/rpc.py. Functionally equivalent for the 4 read methods, but not the plugin architecture the spec describes.
- ✅ MCP bridge (US-006) is real and WIRED.
- Remaining work / plan:
- Scope: (1) build the fireflies browser gadget (bulk of the spec, 5 of 6
stories) mirroring the calendar/todoist gadget structure, in
browser_directmcp_bridgemodes; (2) decide the caching story — either route the gateway handler through the already-builtFirefliesMCPToolscache or add TTL caching toFirefliesHandler, and add 429/backoff toFirefliesClient; (3) register afireflies.syncRPC to makeFirefliesKnowledgeSyncreachable (or delete it); (4) session-linking + State Sync (US-004).
- Target files: new
vizint-ui/gadgets/fireflies/*;gateway/rpc.py(register sync + wire cache);gateway/handlers/fireflies.py;integrations/fireflies_client.py. - Approach: server plumbing is 70% done; the missing 30% is the entire UI plus two decisions (cache placement, orphan sync fate).
- Dependencies: SPEC-014 Gateway (RPC — already integrated), SPEC-015 Plugin SDK (spec-mandated plugin registration — currently bypassed), SPEC-016 Command Center (gadget host), knowledge_graph/Neo4j (sync).
- Effort: L (browser gadget is substantial). Risk: med (UI surface large; orphan-consolidation is a design call, not a mechanical fix).
- Scope: (1) build the fireflies browser gadget (bulk of the spec, 5 of 6
stories) mirroring the calendar/todoist gadget structure, in
- Evidence log:
symbols --pattern Fireflies(7 symbols across 4 files);refsfor Handler/Client/MCPTools/KnowledgeSync; grepgateway/rpc.py→ method map;find vizint-ui/gadgets→ no fireflies; grep client → no cache/rate.
SPEC-020 Claude Code Harness — DONE
- Specifies: A hook-based harness wrapping Claude Code — ~21 Python hooks over
5 lifecycle events, error gate, stop-audit deception detection, safety guards,
session module + CLI, deployment via
install.sh. Status in spec: Implemented. - Verified:
- ✅ 23 hook scripts in
claude/hooks/(spec baseline 21; harness has grown withinfra_check.py,session_handoff_reminder.py,session_resume_context.py,deception_detector.py). All named hooks present:session_auto_start→session_context_hook,session_close_hook,session_open_hook,read_throttle,block_except_pass,intercept_bash,intercept_write,intercept_edit,enforcement_hook,sync_context_md,remember_hook,log_operation,posttool_auditor,block_file_tools,stop_auditor,stop_auditor_subagent. - ✅ Error gate package
claude/hooks/error_gate/=checks_syntax.py,checks_lint.py,checks_test.py,checks_structure.py,utils.py(exact spec set). - ✅ Stop-audit package
claude/hooks/stop_audit/=deception.py,transcript.py,subagent.py(exact spec set). - ✅ Session module at
claude/tools/session/(models.py,context.py,session.py,archive.py,carryover.py,handover.py,portfolio.py,spec_parserequiv, templates) +claude/tools/session_cli.py. - ✅
claude/install.sh(executable) +claude/scripts/strip_traces.pypresent;claude/settings.jsonregisters all 5 event types (PreToolUse/PostToolUse/SessionStart/Stop/UserPromptSubmit).
- ✅ 23 hook scripts in
- Remaining work / plan: none material. Spec doc could be updated to reflect the 4 extra hooks (spec undercounts at 21). No code action.
- Evidence log:
ls claude/hooks/*.py | wc -l→ 23;ls claude/hooks/error_gate+stop_audit;grep settings.json→ 5 event keys;find claude -iname strip_traces→ present.
SPEC-021 OpenCode Integration — PARTIAL
- Specifies: A 3,234-line TypeScript plugin (
orchestrata.ts) hooking 7 OpenCode lifecycle events + 24 tools, plus 2 agents, 1 slash command, 5 Python KG tools, and aninstall.sh, deployed to~/.opencode/. Status: Complete. - Verified:
- ✅ Plugin present and matches spec size exactly:
opencode/plugins/orchestrata.ts= 3,234 lines. All 7 lifecycle hooks present:session.created(:285),session.idle(:566),tool.execute.before(:671),tool.execute.after(:796),message.updated(:854),file.edited(:1211),experimental.session.compacting(:1726). Tool export block at:1752; ~24 custom tools defined inline (session/kg/conv names present). - ⚠️ Plugin delegates to
python3 ~/.claude/tools/session_cli.py(:30 — shared with SPEC-020, present) andpython3 scripts/sync_monorepo_to_neo4j.py(:380,:2037) — that script is ABSENT from this repo (ls scripts/…→ ABSENT). KG sync tools (US-009) will fail at runtime. - ❌ Supporting artifacts from the spec's deployment layout are MISSING from
the repo: no
agents/auto-kg-context.md, noagents/kg-context-agent.md(US-010), nocommands/query-kg.md, notools/kg_query*,neo4j_query.py,simple_kg_query.py(the 5 Python KG tools), and no OpenCodeinstall.sh. Onlyorchestrata.ts+OPENCODE_SETUP.mdexist underopencode/.
- ✅ Plugin present and matches spec size exactly:
- Remaining work / plan:
- Scope: port/create the 2 agent
.mddefs, the/query-kgcommand, the 5 Python KG-query tools, andscripts/sync_monorepo_to_neo4j.py; add an OpenCodeinstall.sh. The plugin brain is done; the periphery + one referenced script are absent. - Target files: new
opencode/agents/*.md,opencode/commands/query-kg.md,opencode/tools/*.py,scripts/sync_monorepo_to_neo4j.py,opencode/install.sh. - Approach: mechanical port from the source monorepo
open-code/tree; verify Neo4j endpoint/project-scoping against the ultimate KG. - Dependencies: shares
session_cli.pywith SPEC-020; needs the KG-sync script (shared concern with knowledge_graph tooling); Neo4j/Redis infra. - Effort: M. Risk: med (referenced sync script absent; unverifiable without a live OpenCode + Neo4j run).
- Scope: port/create the 2 agent
- Evidence log:
wc -l orchestrata.ts→ 3234; grep 7 hook literals (all found);grep -ctool names → present;ls scripts/sync_monorepo_to_neo4j.py→ ABSENT;findfor agents/commands/tools/install.sh → none.
SPEC-052 Todoist Integration — GAP (Python backend) / DIVERGENCE (gadget)
- Specifies: A Python async bidirectional sync engine — Todoist REST v2 +
webhooks, HMAC-SHA256 verification, conflict resolution (last-write-wins/manual),
rate limiting, project/priority/status mapping, agent-assignment custom fields,
bulk sync, audit logging (
TodoistSyncManager,UltimateTodoistIntegration,RateLimiter, webhook handler). - Verified:
- ❌ No Python implementation exists.
symbols --pattern Todoist→ 0 symbols. NoTodoistSyncManager/UltimateTodoistIntegration/verify_webhookanywhere insrc/ortests/(grep → 0). Notodoisttests at all. - ❌ Declared-but-unused dependency:
todoist-api-python>=2.0.0is a regular dependency inpyproject.toml:21, yet it is imported nowhere (grep import todoist|TodoistAPIacrosssrc//vizint-ui/claude/opencode→ 0). Dead dependency — would fail a strictcheck-deps/unused-dep gate. - ⚠️ Divergent minimal browser gadget exists & is wired:
TodoistGadget(vizint-ui/gadgets/todoist/gadget.js:158), registered as manifesttodoistinapp.js:106-111, withgadget.test.js. It does browser-direct Todoist REST v2: load/save encrypted token, fetch tasks/projects, create/complete/reopen tasks. It implements none of the spec's sync engine: no webhooks, no HMAC, no conflict resolution, no bidirectionalsync_all, no priority/status mapping, no rate limiter.
- ❌ No Python implementation exists.
- Remaining work / plan:
- Scope: If the spec is authoritative, build the Python sync engine
(
integrations/todoist/…): REST client (use the declared dep or httpx), webhook receiver + HMAC verify, conflict detection/resolution, rate limiter, Neo4j task mapping, audit log. If the browser gadget is the intended reality, rewrite the spec to match (mark it a browser gadget, drop the Python backend) and either use or remove thetodoist-api-pythondep. - Target files: new
src/orchestrata_ultimate/integrations/todoist/*; gateway webhook route;pyproject.toml(resolve the unused dep). - Approach: this is greenfield Python — the spec's Python examples are illustrative, not ported. Surface the product decision (full sync engine vs. keep the lightweight gadget) before building.
- Dependencies: SPEC-014 Gateway — webhook reception (FR-003/FR-004) needs an
HTTP endpoint, but per
docs/spec-gap-register.md(SPEC-014 FR-021) the gateway is websockets-only with no HTTP/health//metricssurface; the webhook path is therefore blocked on gateway HTTP work. Also Neo4j (task storage) + Redis (rate-limit/sync state). - Effort: L (full spec) / S (spec-rewrite-to-gadget path). Risk: high — scope/authority decision required; webhook half blocked on gateway HTTP gap.
- Scope: If the spec is authoritative, build the Python sync engine
(
- Evidence log:
symbols --pattern Todoist→ 0; grep todoist acrosssrc/→ onlystandards/orchestrata_specific_checklist.md; grepimport todoist→ 0;pyproject.toml:21declares the dep;app.js:106-111registers the gadget; gadget grep → no webhook/hmac/conflict/sync_all.
Cluster summary table
| Spec | Class | Effort | Hard deps |
|---|---|---|---|
| SPEC-017 Calendar | PARTIAL | M | SPEC-016 (ctx.bus/GadgetBridge, session.events) |
| SPEC-018 Fireflies | PARTIAL | L | SPEC-016 (gadget host), SPEC-014 (RPC ✓ wired), SPEC-015 (plugin reg — bypassed), knowledge_graph/Neo4j |
| SPEC-020 Claude harness | DONE | — | session_cli / session module (present) |
| SPEC-021 OpenCode | PARTIAL | M | shares session_cli w/ SPEC-020; needs scripts/sync_monorepo_to_neo4j.py (absent); Neo4j/Redis |
| SPEC-052 Todoist | GAP | L | SPEC-014 HTTP surface (per gap-register FR-021, absent) for webhooks; Neo4j/Redis; unused todoist-api-python dep |
Real remaining work (honest)
- SPEC-052 Todoist — biggest gap: zero Python backend; unused declared dep; only a divergent minimal browser gadget. Needs a scope decision.
- SPEC-018 Fireflies — MCP bridge wired, but the whole browser gadget is
missing and two tested-but-orphaned pieces (
FirefliesMCPToolscache,FirefliesKnowledgeSync) sit outside the live path (false-confidence). - SPEC-017 Calendar — solid foundation; missing event-creation UI, offline retry/backoff, cache TTL, observability.
- SPEC-021 OpenCode — plugin complete; agents/command/python-tools/install.sh and one referenced sync script absent from the repo.
- SPEC-020 Claude harness — done (spec merely undercounts the hooks).
Cross-cluster dependencies noticed
- SPEC-018 ↔ SPEC-014 (Gateway): fireflies
*.*RPC methods are wired intogateway/rpc.py— integration confirmed working. - SPEC-018 ↔ SPEC-015 (Plugin SDK): spec FR-005 mandates registering the bridge as a plugin; impl bypasses SPEC-015 and wires directly. If Cluster owning SPEC-015 formalises a plugin registry, fireflies should migrate onto it.
- SPEC-052 ↔ SPEC-014 (Gateway HTTP gap): Todoist webhook reception needs an HTTP endpoint the gateway does not have (gap-register SPEC-014 FR-021, websockets-only) — Todoist FR-003/FR-004 are blocked on that gateway work.
- SPEC-020 ↔ SPEC-021: both harnesses share
~/.claude/tools/session_cli.pyand the session module; SPEC-021 additionally depends onscripts/sync_monorepo_to_neo4j.py(a knowledge_graph tooling artifact) which is currently absent. - SPEC-017/018 ↔ SPEC-016 (Command Center): both gadgets rely on the gadget
host,
ctx.bus, GadgetBridge, andsession.eventsemitted by the session-manager gadget.