Orchestrata Ultimate › Plans › spec-audit › reverify-2026-10-18 › H-integrations
Cluster H — Integrations reverify (2026-10-18)
Source: plans/spec-audit/reverify-2026-10-18/H-integrations.md at 8a2cb42ad · last changed 2026-10-18 · first committed 2026-10-18 · 334 lines.
Prose pending.
Plan text
Cluster H — Integrations reverify (2026-10-18)
READ-ONLY reverification of SPEC-017 / 018 / 020 / 021 / 052 against current code
(branch components, 337 commits ahead of the session-195 audit). Every claim is
re-derived from code via the AST toolkit (Python) or grep/ls (JS/TS/JSON/sh) — the
checklists/requirements.md boxes and the 2026-07-14 gap-register are treated as stale.
Delta vs the session-195 H-integrations.md audit (the material changes):
- SPEC-018 server side grew and de-orphaned:
FirefliesHandlernow exposes 6 RPC methods (was 4) —fireflies.healthandfireflies.syncadded; the previously orphanedFirefliesKnowledgeSyncis now wired throughfireflies.sync. - SPEC-020 is no longer a clean DONE:
claude/install.shis gone, the deployment moved to a Claude Code plugin (plugins/orchestrata/),session_auto_start.pywas retired, and the core enforcement hooks are absent from the live pluginhooks.json. - SPEC-021 substantially built out: the "missing periphery" from session 195
(2 agents,
/query-kg,install.sh) now exists; the 3,234-line monolithorchestrata.tswas refactored intoorchestrata-ultimate.ts+ alib/of 14 TS modules + 3 tool modules. The 5 Python KG tools were replaced by TS tools + 2 bash wrappers (divergence). - SPEC-017 / SPEC-052 unchanged at the capability level (calendar event-creation UI
- offline retry still missing; no Python Todoist backend; dead
todoist-api-pythondep).
- offline retry still missing; no Python Todoist backend; dead
SPEC-017 Calendar Integration — PARTIAL
- Specifies: A VizInt Command Center browser gadget with a day-view timeline, Google OAuth2 + CalDAV providers, event creation, and automatic session start/close→event sync.
- Verified:
- ✅ Gadget exists and is registered:
CalendarGadgetmanifestorchestrata-calendarinvizint-ui/app.js:98-103(entry./gadgets/calendar/gadget.js); mount atgadget.js:72, unmount:89, refresh:173, now-marker 60s timer:86. - ✅ Both providers implement the contract:
CalDAVProvider.createEventproviders.js:135,listCalendars:72;GoogleCalendarProvider.createEventproviders.js:237,listCalendars:203(OAuth2 implicit + Bearer confirmed by session-195 audit, unchanged). - ✅ Day-view timeline geometry + now marker:
blockGeometrytimeline.js:23,nowMarkerPct:38,splitEventsForDay:70,formatRange:59. - ✅ RFC-5545 parse/serialize:
parseICSical.js:35,buildICSical.js:124. - ✅ Session→calendar sync (US-004):
SessionCalendarSyncsync.jssubscribessession.events(start()sync.js:34), creates "Orchestrata Session {id}" onopened, re-PUTs onclosed(handleEventsync.js:66-101). - ✅ Day navigation: prev/today/next buttons
gadget.js:231-233+ handlersgadget.js:378-386. - ❌ Event-creation UI (US-003 / FR-004) absent.
gadget.jshas nocreateEvent/newEvent/form call (grep → onlyformatRangehits "form"); providers exposecreateEventbut the gadget never invokes it and never emitscalendar.event.created. - ❌ Offline retry/backoff queue (FR-005 / SAC-US4-06) absent —
sync.jshas noretry/backoff/localStorage; the session→event mapping is an in-memoryMap(sync.js:16), not the localStorage correlation FR-005 requires. - ❌ Cache TTL (FR-001) + health/metrics/tracing (Observability §) absent (grep
cache|ttlingadgets/calendar/→ only a comment about clearing cached lists). - ⚠️ Close path re-uses
createEvent(re-PUT) rather than a dedicatedupdateEvent(sync.js:93-97); for Googleevents.insertthis would create a duplicate instead of updating end-time.ICalendarProvider.updateEventfrom the spec is not implemented. - ⚠️ No date-picker (US-005 / SAC-US5-02) and no multi-account toggle (US-002) evidenced.
- ✅ Gadget exists and is registered:
- Remaining work / plan:
- Scope: (1) event-creation form wired to
provider.createEvent+calendar.event.createdemit; (2) localStorage-backed retry queue with exponential backoff inSessionCalendarSync+ localStorage session↔event map; (3) in-memory cache w/ TTL; (4) optionalctx.health/ctx.metrics. (5) AddupdateEventto providers (or accept re-PUT divergence) so Google close does not duplicate. - Target files:
vizint-ui/gadgets/calendar/{gadget.js,sync.js,providers.js}; new form module;vizint-ui/tests/. - Approach: provider/timeline/ical foundation is real (real fetch, no mocks). Work is UI + resilience glue.
- Dependencies: SPEC-016 (ctx.bus/GadgetBridge,
session.events). - Effort: M. Risk: low.
- Scope: (1) event-creation form wired to
- Evidence log:
ls vizint-ui/gadgets/calendar→ gadget/ical/providers/sync/timeline.js; grep gadget.js → no createEvent/newEvent/calendar.event.created; grep sync.js → no retry/backoff/localStorage; grep timeline.js → splitEventsForDay/nowMarkerPct/blockGeometry; grep app.js → manifestorchestrata-calendar. (No Python; ASTsymbols --pattern Calendar→ 0.)
SPEC-018 Fireflies Integration — PARTIAL
- Specifies: A Fireflies.ai browser gadget (transcript list/search/summaries/
session-linking/config, US-001..005) plus a Python MCP bridge exposing
fireflies.*gateway RPC (US-006). - Verified:
- ✅ MCP bridge (US-006) wired and grown to 6 methods.
FirefliesHandlergateway/handlers/fireflies.py:17—handle_transcripts:46,handle_transcript:68,handle_search:89,handle_summary:112,handle_health:133(new),handle_sync:153(new). Registered ingateway/method_table.py:fireflies.transcripts:359,fireflies.transcript:366,fireflies.search:373,fireflies.summary:380,fireflies.health:387,fireflies.sync:394. Instantiatedgateway/rpc.py:108, graph-repo injectedrpc.py:192.refs FirefliesHandler→ 1 def, 6 imports, 2 prod uses. - ✅
FirefliesClientreal GraphQL client:integrations/fireflies_client.py:88(list_transcripts:146,get_transcript:204,search_transcripts:286,summarize_transcript:349,test_connection:415,close:450),httpx-based (fireflies_client.py:14). - ✅ Write-side KG sync now wired (prior audit's orphan resolved).
FirefliesKnowledgeSyncintegrations/fireflies_sync.py:43(sync_recent:65,inject_transcript:90) —refs→ importedgateway/handlers/fireflies.py:12, usedfireflies.py:181insidehandle_sync. Reachable viafireflies.sync. - ❌ Entire browser gadget (US-001..005) still ABSENT. No
vizint-ui/gadgets/fireflies/;vizint-ui/app.jsregisters only calendar + todoist. - ⚠️ Caching / rate-limiting still absent from the wired path (SAC-US006-05/06).
FirefliesHandlercalls the client directly (no TTL);FirefliesClienthas no 429/retry/backoff/Retry-After(grep429|retry|backoff|rate|cache|ttloversource integrations.fireflies_client→ 0 matches). - ⚠️
FirefliesMCPTools(the 10-min cache) remains ORPHANED.session/fireflies_tools.py:38(cache_ttl=600:46) —refs→ 0 production imports/uses (only tests). False-confidence pattern persists. - ⚠️ FR-005 divergence unchanged: spec says "register a
FirefliesMCPBridgeas a SPEC-015 plugin"; impl wiresFirefliesHandlerdirectly intogateway/rpc.py(rpc.py:108,method_table.py:359-394), not via the SPEC-015 plugin registry.
- ✅ MCP bridge (US-006) wired and grown to 6 methods.
- Remaining work / plan:
- Scope: (1) build the fireflies browser gadget (5 of 6 stories) mirroring calendar/
todoist structure; (2) decide cache placement — route
FirefliesHandlerthroughFirefliesMCPToolsor add TTL to the handler, and add 429/backoff toFirefliesClient(or formally retire the orphan); (3) session-linking + State Sync (US-004). - Target files: new
vizint-ui/gadgets/fireflies/*;gateway/handlers/fireflies.py;integrations/fireflies_client.py;session/fireflies_tools.py(wire or delete). - Approach: server plumbing is ~85% done (6 RPC methods + KG sync wired); the missing bulk is the entire UI plus one cache-consolidation decision.
- Dependencies: SPEC-016 (gadget host), SPEC-014 (RPC ✓ wired), SPEC-015 (plugin reg — still bypassed), knowledge_graph/Neo4j (sync ✓ wired).
- Effort: L (browser gadget dominates). Risk: med.
- Scope: (1) build the fireflies browser gadget (5 of 6 stories) mirroring calendar/
todoist structure; (2) decide cache placement — route
- Evidence log:
symbols --pattern Fireflies→ 9 symbols (handler/client/sync/tools);refs FirefliesHandler→ rpc.py:22/107/404;refs FirefliesKnowledgeSync→ fireflies.py:12/181;refs FirefliesMCPTools→ 0 prod;source gateway.method_tablegrep fireflies → 6 method rows;source integrations.fireflies_clientgrep 429/retry/backoff/cache → 0;ls vizint-ui/gadgets→ no fireflies.
SPEC-020 Claude Code Harness — DIVERGENCE (was DONE)
- Specifies: A hook harness wrapping Claude Code — 21 Python hooks over 5 lifecycle
events, error gate, stop-audit deception detection, safety guards, session module + CLI,
deployed via
claude/install.shto~/.claude/and registered in~/.claude/settings.json. - Verified:
- ✅ Harness hooks current and grown: 39
.pyhooks inclaude/hooks/(ls claude/hooks/*.py | wc -l→ 39; spec baseline 21). All named hooks present exceptsession_auto_start(retired, see below):block_except_pass.py,block_file_tools.py,enforcement_hook.py,error_gate_hook.py,intercept_bash.py,intercept_edit.py,intercept_write.py,log_operation.py,posttool_auditor.py,read_throttle.py,remember_hook.py,session_close_hook.py,session_context_hook.py,session_open_hook.py,stop_auditor.py,stop_auditor_subagent.py,sync_context_md.py,deception_detector.py. - ✅ Error gate package intact (exact spec set):
claude/hooks/error_gate/=checks_syntax.py,checks_lint.py,checks_test.py,checks_structure.py,utils.py,__init__.py. - ✅ Stop-audit package intact (exact spec set):
claude/hooks/stop_audit/=deception.py,transcript.py,subagent.py,__init__.py. - ✅ Session module + CLI:
claude/tools/session/(models.py,context.py,session.py,archive.py,carryover.py,handover.py,portfolio.py,exceptions.py,facts.py,prolog_interface.py) +claude/tools/session_cli.py+claude/tools/statusline_session.py+claude/scripts/strip_traces.py. - ❌
claude/install.shis ABSENT (spec FR-018 "deployed via ./claude/install.sh"). Deployment now lives inclaude/scripts/{register_hooks.py, patch_settings.py, gen_plugin.py}plus a Claude Code pluginplugins/orchestrata/(.claude-plugin/plugin.json,hooks/hooks.json508 lines,project-hooks/36 files incl._dispatch.sh), and.claude/hooks/— the ADR-0070 / RUL-035 "hooks at USER level via plugin dispatch" model, which deliberately supersedes repo-levelsettings.jsonregistration. - ⚠️
session_auto_start.pyretired (spec FR-003).claude/README.md:141andclaude/SESSION_SYSTEM.md:224document it as legacy/superseded; superseded byplugins/orchestrata/tools/session_start.py+session_resume_context.py. Yetclaude/settings.json:84still referencespython3 ~/.claude/hooks/session_auto_start.py— a stale registration line. - ⚠️ Core enforcement hooks absent from the live plugin dispatch.
plugins/orchestrata/ hooks/hooks.jsonregisters the safety hooks (intercept_bash.py:370,intercept_write.py:381,intercept_edit.py:392), session open/close/remember, and the new project-hooks shell guards — but grep ofhooks.jsonfinds noerror_gate_hook,stop_auditor,stop_auditor_subagent,read_throttle,block_except_pass,enforcement_hook,posttool_auditor,sync_context_md,block_file_tools, orlog_operation. Those exist only in the legacyclaude/settings.json(e.g.stop_auditor.pyat Stop:97-102,enforcement_hook.py,log_operation.py,posttool_auditor.py) — which ADR-0070 declares "dark" in$HOME-rooted sessions. The error gate (error_gate_hook.py) is registered in no in-repo JSON at all.
- ✅ Harness hooks current and grown: 39
- Remaining work / plan:
- Scope: (1) reconcile the spec's deployment narrative (install.sh,
~/.claude/settings.jsonregistration) with the plugin-dispatch reality; (2) decide the fate of the unwired core hooks — either registererror_gate_hook.py/stop_auditor.py/read_throttle.py/block_except_pass.py/posttool_auditor.py/sync_context_md.pyintoplugins/orchestrata/hooks/hooks.json, or formally declare them retired; (3) drop the stalesession_auto_start.pyline fromclaude/settings.json(or retire that file). - Target files:
plugins/orchestrata/hooks/hooks.json,claude/settings.json,specs/020-*/spec.md. - Approach: harness code is complete (39 hooks, both packages, session module). The gap is wiring/registration drift, not missing logic. Needs an owner decision on which enforcement hooks remain canonical in the plugin era.
- Dependencies: ADR-0070/RUL-035 (hook location ruling); session module (present).
- Effort: S–M. Risk: med (a "DONE" spec whose enforcement may be partially dark in the
current plugin registration — verify runtime
~/.claude/settings.jsonbefore closing).
- Scope: (1) reconcile the spec's deployment narrative (install.sh,
- Evidence log:
ls claude/hooks/*.py | wc -l→ 39;ls claude/hooks/error_gate→ 6;ls claude/hooks/stop_audit→ 4;ls claude/install.sh→ ABSENT;ls plugins/orchestrata→ .claude-plugin/hooks/project-hooks/tools/systemd; grepplugins/orchestrata/hooks/hooks.json→ intercept_* present, error_gate_hook/stop_auditor/read_throttle/block_except_pass absent; grepclaude/settings.json→ session_auto_start still referenced;claude/README.md:141claude/SESSION_SYSTEM.md:224→ retired note.
SPEC-021 OpenCode Integration — DIVERGENCE (was 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/. - Verified:
- ✅ Plugin present and refactored.
opencode/plugins/orchestrata-ultimate.ts(438 lines) +opencode/plugins/lib/(14 TS modules, 1,463 lines:deception.ts,kg-context.ts,kg-sync.ts,kg-cypher.ts,remember.ts,review-gate.ts,session-cli.ts,session-close.ts,conversation-producer.ts,redis-exec.ts,message-text.ts,project.ts,constants.ts,types.ts) + tests inopencode/plugins/lib/__tests__/. - ✅ All 7 lifecycle capabilities handled.
orchestrata-ultimate.ts:session.created:266,session.idle:269,message.updated:279,file.edited:301,tool.execute.before:336,tool.execute.after:393,experimental.session.compacting:423. (Header:14-48documents the real OpenCode key map — 5 events +chat.message+experimental.chat.system.transform.) - ✅ 24+ tools present.
opencode/plugins/tools/session-tools.ts(9: session-status/ begin/end/log-work/log-achievement/add-work/complete-work/update-state/log-choice);conversation-tools.ts(3: conv-status/conv-sync/conv-query);kg-tools.ts(14: kg-query/find-file/find-entity/trace-req/session-audit/stats/cxp-thread/file-context/ sync/queue-status/flush-queue/daemon-start/daemon-stop/daemon-status) — the 12 spec KG tools plus 2 additions. - ✅ Periphery now exists (was missing in session 195).
opencode/agents/ {auto-kg-context.md, kg-context-agent.md};opencode/commands/query-kg.md;opencode/install.sh(14 KB, idempotent, deploys agents/commands/config/tools/plugins). - ⚠️ The "5 Python KG tools" are a DIVERGENCE.
opencode/tools/contains only bash wrapperskg_queryandredis-cli;find opencode -name '*.py'→ none. The spec'skg_query.py/kg_query_inner.py/neo4j_query.py/simple_kg_query.pywere replaced by the TSkg-tools.ts+lib/kg-cypher.ts. - ⚠️
scripts/sync_monorepo_to_neo4j.pystill ABSENT, but no longer a runtime gap. The plugin acknowledges it ("doesn't exist in ultimate",orchestrata-ultimate.ts:171); KG sync is self-contained inlib/kg-sync.ts:166-180(writes an inline Python daemon body, runsuv run python '<script>'viaBun.spawn). No dependency on the missing script. - ⚠️ FR-008 policy enforcement partially externalized (divergence).
orchestrata-ultimate.ts:350-363documents thatenforceTestingPolicy/enforceImportPolicy/enforceDevelopmentPolicyare DROPPED as OBSOLETE/SUPERSEDED by.claude/hooks+code-review.py/test-review.pyT-rules; only bash-safety (destructive regexes:370-378) and write-policy (~/.claude/plans:382-388) remain intool.execute.before.
- ✅ Plugin present and refactored.
- Remaining work / plan:
- Scope: (1) update SPEC-021 to reflect the refactor — plugin renamed to
orchestrata-ultimate.ts(438 + 1,463 lib, no longer 3,234 monolith), 26 tools (not 24), Python KG tools → TS tools + bash wrappers,sync_monorepo_to_neo4j.py→ in-plugin daemon, FR-008 testing/import/pip policies externalized. No feature code required. - Target files:
specs/021-*/spec.md(doc-only). - Approach: mechanical spec reconciliation; the implementation is current and superset.
- Dependencies: shares
~/.claude/tools/session_cli.pywith SPEC-020; Neo4j/Redis infra (runtime, out-of-repo). - Effort: S. Risk: low.
- Scope: (1) update SPEC-021 to reflect the refactor — plugin renamed to
- Evidence log:
ls -R opencode/→ agents/commands/config/plugins/tools/install.sh;wc -l opencode/plugins/orchestrata-ultimate.ts→ 438;wc -l opencode/plugins/lib/*.ts→ 1,463; grep orchestrata-ultimate.ts → 7 hook literals; grepopencode/plugins/tools/*.ts→ 9 + 3 + 14 tool names;find opencode -name '*.py'→ none;ls scripts/ sync_monorepo_to_neo4j.py→ ABSENT; grep kg-sync.ts → Bun.spawn + uv run python inline.
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, rate limiting, priority/status mapping,
agent-assignment custom fields, bulk sync, audit logging (
TodoistSyncManager,UltimateTodoistIntegration,RateLimiter, webhook handler). - Verified:
- ❌ No Python implementation.
symbols --pattern Todoist→ 0 symbols. NoTodoistSyncManager/UltimateTodoistIntegration/verify_webhook/RateLimiter;integrations/contains onlycheetahclaws/,fireflies_client.py,fireflies_sync.py. - ❌ Dead declared dependency persists.
pyproject.toml:23todoist-api-python>=2.0.0(regular dep); imported nowhere (grepimport todoist|TodoistAPIover src/ → 0; onlystandards/orchestrata_specific_checklist.mdname-drops "todoist"). No todoist tests. - ⚠️ Minimal browser gadget still present & wired (divergence).
TodoistGadgetvizint-ui/gadgets/todoist/gadget.js(registeredapp.js:106-111, manifesttodoist), withgadget.test.js. Browser-direct REST v2 only: encrypted token (gadget.js:216-220), fetch tasks/projects, create/complete/reopen. Implements none of the spec sync engine (grep → no webhook/hmac/signature/conflict/sync_all/priority/ rate/backoff).
- ❌ No Python implementation.
- Remaining work / plan:
- Scope: If the spec is authoritative, build the Python sync engine
(
integrations/todoist/…): REST client, 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 a gadget and remove the deadtodoist-api-pythondep (MASTER-PLAN S8 item). - Target files: new
src/orchestrata_ultimate/integrations/todoist/*; gateway webhook route;pyproject.toml(drop unused dep);vizint-ui/gadgets/todoist/gadget.js(if gadget path chosen). - Approach: greenfield Python; surface the product decision (full engine vs. keep gadget) before building.
- Dependencies: SPEC-014 HTTP surface (webhook reception FR-003/FR-004 needs an HTTP endpoint the WS-only gateway lacks — gap-register SPEC-014 FR-021); Neo4j + Redis.
- Effort: L (full spec) / S (spec-rewrite-to-gadget). Risk: high (scope decision; webhook half blocked on gateway HTTP).
- Scope: If the spec is authoritative, build the Python sync engine
(
- Evidence log:
symbols --pattern Todoist→ 0;ls src/orchestrata_ultimate/ integrations/→ no todoist/; grepimport todoistsrc/ → 0;pyproject.toml:23declares the dep;app.js:106-111registers the gadget; grep gadget.js → no webhook/hmac/conflict/sync_all/priority.
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 (sync ✓ wired) |
| SPEC-020 Claude harness | DIVERGENCE (was DONE) | S–M | ADR-0070/RUL-035 plugin-dispatch; session module (present) |
| SPEC-021 OpenCode | DIVERGENCE (was PARTIAL) | S (doc) | shares session_cli w/ SPEC-020; Neo4j/Redis (runtime, out-of-repo) |
| SPEC-052 Todoist | GAP / DIVERGENCE | L (or S) | SPEC-014 HTTP surface (absent) for webhooks; Neo4j/Redis; dead todoist-api-python dep |
Real remaining work (honest)
- SPEC-052 Todoist — still the biggest gap: zero Python backend, dead declared dep, only a divergent minimal gadget. Scope decision required.
- SPEC-018 Fireflies — MCP bridge now 6 methods + KG sync wired; the entire browser
gadget (5 of 6 stories) is still missing;
FirefliesMCPToolscache remains orphaned and the wired path has no caching/rate-limiting. - SPEC-017 Calendar — unchanged: missing event-creation UI, offline retry/backoff,
cache TTL; plus a Google close-path duplicate risk (re-PUT via
createEvent). - SPEC-020 Claude harness — core hooks intact (39), but deployment moved to a plugin and
the error-gate/stop-auditor/read-throttle/bare-except hooks are absent from the live
plugin
hooks.json(a wiring drift that needs a decision, not new code). - SPEC-021 OpenCode — functionally complete; the spec doc is stale (monolith line count,
5 Python tools,
sync_monorepo_to_neo4j.py, FR-008 in-plugin policies). Doc reconciliation only.
Cross-cluster dependencies
- SPEC-018 ↔ SPEC-014:
fireflies.*RPC wired viagateway/method_table.py+rpc.py— confirmed live. - SPEC-018 ↔ SPEC-015: FR-005 plugin-registration still bypassed (direct
rpc.pywiring). - SPEC-052 ↔ SPEC-014: webhook reception blocked on gateway HTTP surface (gap-register SPEC-014 FR-021).
- SPEC-020 ↔ SPEC-021: share
~/.claude/tools/session_cli.py; SPEC-021 no longer needs the absentscripts/sync_monorepo_to_neo4j.py. - SPEC-017/018 ↔ SPEC-016: both gadgets depend on the Command Center host / ctx.bus / session.events.