Future Extensions (Appendix D)
Design gaps and planned capabilities discovered during development. Each item describes the gap, the current workaround (if any), and the intended solution.
When an item is implemented, move it to the relevant spec file and mark it resolved here.
Items are referenced from local/WORK_QUEUE.md by FE-XX ID.
FE-01: Async Actor Delivery (status: 'accepted' + tracking_id)
Section titled “FE-01: Async Actor Delivery (status: 'accepted' + tracking_id)”Gap: DeliveryResult.status only supports 'delivered' | 'rejected' | 'error'. Actors like deep-research (30+ min), ChatGPT Pro (3-70 min), and supervisor agent (unbounded) accept work but don’t complete immediately. There’s no way to express “work queued, will complete later.”
Current workaround: Treat webhook acceptance (HTTP 200) as 'delivered', even though the actor hasn’t finished. No correlation back to the original event when work completes.
Intended solution:
- Add
status: 'accepted'toDeliveryResult - Add
tracking_id: stringtoDeliveryResultfor correlating completion events - Actor completion feeds back as
actor.stoppedwithtracking_idin provenance - Engine can correlate delivery -> completion via tracking_id
Affects: packages/sdk/src/connector.ts, packages/core/src/runtime.ts (core runtime logic; engine.ts is now a backward-compatible wrapper), Event Schema
FE-02: orgloop hook CLI Command + Engine HTTP Listener Resolved (MVP)
Section titled “FE-02: orgloop hook CLI Command + Engine HTTP Listener Resolved (MVP)”orgloop hook CLI Command + Engine HTTP ListenerImplemented:
orgloop hook claude-code-stopCLI command reads stdin, POSTs tohttp://127.0.0.1:<port>/webhook/<sourceId>- Engine starts
WebhookServer(lightweight HTTP listener, localhost-only, default port 4800) when any webhook-based source is configured packages/core/src/http.ts—WebhookServerclass routesPOST /webhook/:sourceIdto registered handlerspackages/cli/src/commands/hook.ts— stdin-to-HTTP bridgeorgloop initinstallsorgloop hook claude-code-stoppointing to the engine’s listener
FE-03: Actor Delivery Adapters (CLI, File, Browser, Message)
Section titled “FE-03: Actor Delivery Adapters (CLI, File, Browser, Message)”Gap: Current actor delivery assumes HTTP webhook. Five distinct delivery patterns exist in the ecosystem:
| Pattern | Examples |
|---|---|
| HTTP webhook | OpenClaw, generic webhooks (working) |
| CLI invocation | deep-research, narrator, reviewer, scanner |
| File I/O | deep-research output, narrator audio |
| Browser automation | ChatGPT Pro |
| Message passing | supervisor/reviewers |
Current workaround: Only HTTP webhook delivery is implemented. Other actors must be wrapped in HTTP endpoints or triggered manually.
Intended solution:
- Create
DeliveryAdapterabstraction layered on top ofActorConnector - Implement adapters:
WebhookDeliveryAdapter(exists),CLIDeliveryAdapter,FileDeliveryAdapter,BrowserDeliveryAdapter,MessagePassingAdapter - Allow
RouteDeliveryConfigto hint at delivery requirements (actor_type,expected_duration,response_mode)
Affects: packages/sdk/src/connector.ts, new adapter packages
FE-04: CWD-Based Routing for Claude Code Events
Section titled “FE-04: CWD-Based Routing for Claude Code Events”Gap: The bespoke notify-openclaw.sh routes Claude Code sessions to different agents based on working directory (~/code/mono* -> work team via Slack, ~/personal/* -> personal via Mattermost). The OrgLoop production config routes all actor.stopped events to a single agent.
Current workaround: Single route to openclaw-engineering-agent. CWD info is in the event payload so the agent can see it, but routing is not differentiated.
Intended solution:
- Multiple routes with transform-filter using regex on
payload.working_directory - Multiple actor configs (work-agent, personal-agent) with different channels/targets
- Transform-filter already supports
/regex/patterns — config-only change
Affects: Route config, actor config (no code changes needed)
FE-05: Linear User-Level Filtering
Section titled “FE-05: Linear User-Level Filtering”Gap: The bespoke Linear script filters issues by a specific user ID. The OrgLoop Linear connector filters by team, returning all team activity. This is noisier.
Current workaround: Accept all team activity. Could add a transform-filter on provenance.author with regex.
Intended solution (options):
- Config-only: Add transform-filter with
match: { provenance.author: "/alice|a-smith/i" }to Linear routes - Connector-level: Add optional
assigneefilter toLinearSourceConfigto filter at the GraphQL query level (reduces API calls)
Affects: connectors/linear/src/source.ts (if connector-level), route/transform config (if config-only)
FE-06: CLI Env Var Onboarding UX Resolved (MVP)
Section titled “FE-06: CLI Env Var Onboarding UX Resolved (MVP)”Implemented:
ConnectorSetup.env_varssupportsEnvVarDefinitionwith per-variabledescriptionandhelp_urlorgloop envshows set/unset status withdescriptionandhelp_urlper variableorgloop initshows indicators with connector-provided guidance for missing varsorgloop startruns a pre-flight env var check before config loadingorgloop doctorreports credential status with descriptions and help URLsenv-metadata.tsprovides hardcoded metadata as a fallback for known env vars- Remaining:
.envfile loading inorgloop start(dotenv or similar)
FE-07: OpenClaw as a Source Connector
Section titled “FE-07: OpenClaw as a Source Connector”Gap: OpenClaw is currently target-only. It receives events but doesn’t emit them. If an OpenClaw agent completes work, there’s no way for that completion to feed back into OrgLoop as an actor.stopped event.
Current workaround: None. The feedback loop is broken for OpenClaw-delivered work.
Intended solution:
- Build
connector-openclawsource that polls or subscribes to OpenClaw session completions - Or: OpenClaw POSTs completion events to OrgLoop’s webhook endpoint (requires FE-02)
Affects: connectors/openclaw/, possibly new source connector
FE-08: Event Aggregation & Windowing
Section titled “FE-08: Event Aggregation & Windowing”Gap: Routes trigger actors on individual events. No way to batch N events before triggering, collapse similar events into one (beyond dedup’s exact-match), or trigger on event absence (“no PR reviews in 2 hours”).
Intended solution:
- Window transform: accumulate events matching a pattern, emit a single aggregated event after N events or T time
- Absence trigger: emit a synthetic event when a source produces no events within a configurable window
- Collapse: merge N similar events into one summary event
Affects: New transform package(s), possibly scheduler integration for time-based windows
FE-09: Multi-Org Composition
Section titled “FE-09: Multi-Org Composition”Gap: Running multiple orgs or composing one org from pieces of another.
Intended solution: Explore later. Possible directions: multiple config roots per instance, cross-org event routing, credential isolation between orgs.
Affects: Core architecture, config schema, project model
FE-10: Observability Beyond Logs
Section titled “FE-10: Observability Beyond Logs”Gap: MVP has file + console loggers. No metrics, alerting, or dashboards.
Intended solution:
- Structured metrics: event rate, delivery success/failure/latency, transform drop rate, source poll duration
- OpenTelemetry logger (traces + metrics export)
- Alert conditions: delivery failure rate > threshold, source stalled, transform error spike
Affects: packages/core/src/runtime.ts (core runtime logic; engine.ts is now a backward-compatible wrapper), new logger packages
FE-11: Event Replay & Time-Travel Debugging
Section titled “FE-11: Event Replay & Time-Travel Debugging”Gap: Can’t replay a past event through the pipeline.
Intended solution:
orgloop replay <event-id>— re-inject a logged event--from/--tofor time range replay--dry-runmode shows what would happen without delivering
Affects: packages/cli/, packages/core/src/runtime.ts (engine.ts is now a backward-compatible wrapper)
FE-12: Secret Management Integrations
Section titled “FE-12: Secret Management Integrations”Gap: Secrets are env vars only. No vault integration, rotation, or audit trail.
Intended solution:
- Pluggable secret resolver interface:
resolve(ref: string) -> string - Built-in: env var,
.envfile. Community: Vault, AWS SM, 1Password CLI - Config syntax:
token: "vault:secret/data/github#token"or similar URI scheme
Affects: packages/core/src/schema.ts, new secret resolver interface in SDK
FE-13: Cron Source Connector Resolved (MVP)
Section titled “FE-13: Cron Source Connector Resolved (MVP)”Implemented as @orgloop/connector-cron. Supports standard 5-field cron expressions and interval-based schedules (every 5m, every 1h). Emits resource.changed with provenance.platform: 'cron' and provenance.platform_event: 'schedule.<name>'. Poll-based: on each poll, checks whether any scheduled cron time has passed since the last checkpoint. See connectors/cron/src/source.ts.
FE-14: Communications Platform Connectors (Human-in-the-Loop)
Section titled “FE-14: Communications Platform Connectors (Human-in-the-Loop)”Gap: No way to route events to humans via comms platforms.
Intended solution: Slack (API), Discord, email, Mattermost as both source and target connectors. Enables human approval gates via message.received feedback.
FE-15: Installable Organization Packages Resolved then Removed (v0.1.9)
Section titled “FE-15: Installable Organization Packages Resolved then Removed (v0.1.9)”The module system was removed in v0.1.9 in favor of a package-native project model. Projects use package.json + orgloop.yaml with standard npm dependency management. See the Project Model spec for the current design.
FE-16: Property-Based Testing
Section titled “FE-16: Property-Based Testing”Gap: All tests are example-based. No property tests exercising invariants.
Intended solution: Add fast-check for core invariants: router matching laws, transform pipeline composition, event schema round-trips, config env var substitution.
FE-17: Environment Orchestrator (Sister Project)
Section titled “FE-17: Environment Orchestrator (Sister Project)”Gap: OrgLoop declares what an organization needs but doesn’t install services, broker credentials, or configure hooks across systems. The “blank machine -> running org” story requires tooling outside OrgLoop’s scope.
Intended solution: orgctl — a sister project that reads project config and handles Tier 4 (local service installation) and Tier 5 (cross-system configuration). See the orgctl RFP for the full project specification and spec 14 (Scope Boundaries) for the shared contract model.
Depends on: Stable project config schema, orgloop doctor --json, --non-interactive CLI flags.
FE-18: Route Visualization Resolved (MVP)
Section titled “FE-18: Route Visualization Resolved (MVP)”Implemented as orgloop routes command. ASCII rendering shows sources -> routes (with filter criteria and transform chains) -> actors. Highlights unrouted sources and unreachable actors as warnings. Supports --json for machine-readable graph data (nodes, edges, warnings). See packages/cli/src/commands/routes.ts.
FE-19: Source Scoping vs. Event Filtering
Section titled “FE-19: Source Scoping vs. Event Filtering”Gap: Connectors like GitHub and Linear fetch all events for a team/repo, then rely on transforms to filter. The bespoke scripts they replace filtered at the API level (only PRs by specific authors, only issues assigned to a user). This causes unnecessary API calls and noisy logs.
Design decision: Keep filtering at the route/transform level, NOT in connectors.
Rationale:
- Observability — if a connector silently drops events,
orgloop logscan’t show what’s happening. Users can’t answer “is data flowing?” vs. “is there a filter I forgot about?” - Composability — one team filters by assignee, another by project. Connector config becomes a bag of N filter options. Transforms are the composable mechanism.
- Debugging — event flow is always traceable: source emitted -> bus received -> route matched -> transform filtered -> actor received. No hidden drops.
- Separation of concerns — sources observe, transforms decide, routes deliver.
Connector scope (future, optional):
- API-level scoping (e.g.,
scope: { assignee: "me" }) is a valid performance optimization — fewer API calls, less network traffic. - Should be framed as
config.scopeNOT as event filtering. Clearly documented as “reduces API usage, not event semantics.” - Events within scope still flow through the full pipeline (bus -> transforms -> delivery).
- Events outside scope are never fetched — this is a data fetch boundary, not a filter.
What’s needed now (short-term):
- Connectors should emit richer
provenancefields (assignee, author list, PR authors) so route-level filters can match on them using existing regex/match transform capabilities. - Linear: add
provenance.assigneeto issue events - GitHub: add
provenance.pr_authorto PR events
Affects: connectors/*/src/, packages/sdk/src/connector.ts (provenance type), transform-filter docs
FE-20: Actor-to-OrgLoop Event Emission (Mid-Session)
Section titled “FE-20: Actor-to-OrgLoop Event Emission (Mid-Session)”Gap: Actors can only emit events via actor.stopped — after their session ends. An actor mid-session has no way to say “route this event now” without completing. This limits actor-to-actor coordination to sequential handoffs (actor A finishes, actor B starts). Richer patterns — like an actor requesting help from another actor while continuing its own work — are not possible.
Current workaround: None. Actors must complete before their output becomes routable. Multi-step workflows require supervisor-mediated re-dispatch.
Intended solution:
- Provide a standardized interface (MCP tool, HTTP endpoint, or SDK method) that actors can call mid-session to emit events into OrgLoop’s bus
- New event type or use of
message.receivedwith actor provenance - Engine routes the emitted event through normal pipeline (bus -> routes -> transforms -> delivery)
- Actor continues running — emission is fire-and-forget from the actor’s perspective
Design considerations:
- Must not create tight coupling between actor runtime and OrgLoop engine
- Should work regardless of actor type (Claude Code, Codex, custom agents)
- MCP tool approach: OrgLoop provides an MCP server with an
emit_eventtool that agents can call - HTTP approach: actors POST to
http://localhost:<port>/emit(similar to webhook source, but for outbound from actors) - Rate limiting and loop detection needed to prevent infinite emission chains (loop detection now implemented in FE-25)
Affects: packages/core/src/runtime.ts (core runtime logic; engine.ts is now a backward-compatible wrapper), packages/core/src/http.ts, packages/sdk/src/connector.ts, possibly new MCP server package
FE-21: Transform Failure Policy (Fail-Open vs Fail-Closed) Resolved
Section titled “FE-21: Transform Failure Policy (Fail-Open vs Fail-Closed) Resolved”Implemented per-transform on_error policy with three modes:
pass(fail-open, default) — event passes through unmodified on error (backwards-compatible)drop(fail-closed) — event is silently dropped on errorhalt— pipeline halts with error, engine emits error event
Configurable at both the transform definition level (global default) and the route transform reference level (per-route override). Route-level takes precedence. Dedicated log phases: transform.error_drop and transform.error_halt. See Built-in Transforms spec, section 10.4 for full documentation.
FE-22: Plugin Trust & Permissions Superseded (v0.1.9)
Section titled “FE-22: Plugin Trust & Permissions Superseded (v0.1.9)”Trust and permissions for third-party connectors and transforms are handled through standard npm security practices (package provenance, audit, lockfiles). SOP review remains a human responsibility — routes and SOPs are plain files in the project directory, fully inspectable before use.
FE-23: Delivery Journal (Idempotent Re-delivery)
Section titled “FE-23: Delivery Journal (Idempotent Re-delivery)”Gap: If OrgLoop adds WAL replay (re-processing unacked events after crash recovery), the delivery pipeline needs idempotency. Currently, an event replayed from the WAL could be delivered to an actor twice. The dedup transform doesn’t help here — it’s a source-level dedup (prevents the same external event from being polled twice), not a delivery-level dedup.
Architectural decision (WQ-95): Source dedup and delivery dedup are deliberately separate concerns:
-
Source dedup (transforms/dedup) — prevents the same external event from entering the pipeline twice. Time-window based, in-memory, reset on restart. This is correct: the checkpoint already prevents most re-polls, and the dedup window is a safety net. Re-delivering a few events after restart is acceptable (actors should be idempotent per OrgLoop’s design philosophy).
-
Delivery journal (future, in Runtime) — tracks
(event_id, route, actor)tuples to ensure at-most-once delivery per route. This belongs inpackages/core/src/runtime.ts, not in the dedup transform. It should be a persistent store (file-based, alongside the WAL) that the Runtime consults before callingactor.deliver().
Why not persist the dedup transform? Adding persistence to the dedup transform would conflate two concerns. The dedup transform answers “have I seen this event key before?” while the delivery journal answers “have I delivered this specific event to this specific actor?” These have different key spaces, different lifetimes, and different consistency requirements.
Intended solution:
- Add
DeliveryJournalinterface to core withhasDelivered(eventId, route, actor)andrecordDelivery(eventId, route, actor)methods - File-based implementation alongside the WAL
- Runtime checks journal before
deliverToActor()— skip if already delivered - Journal compacted periodically (entries older than event retention window)
- Opt-in via config:
delivery: { journal: true }on routes that need exactly-once semantics
Affects: packages/core/src/runtime.ts, packages/core/src/store.ts (new DeliveryJournal), packages/sdk/src/types.ts (route config)
FE-24: Daemon Supervisor & Health Monitoring
Section titled “FE-24: Daemon Supervisor & Health Monitoring”Gap: OrgLoop daemon has no automatic restart capability. If the process crashes due to an uncaught exception, OOM, or signal, manual intervention is required.
Implemented (WQ-93):
Supervisorclass inpackages/core/src/supervisor.ts— wraps child process fork with exponential backoff restart- Crash handlers (
uncaughtException,unhandledRejection) in Runtime — attempt graceful shutdown before exit - Health heartbeat file (
~/.orgloop/heartbeat) — written every 30s with timestamp, PID, uptime --supervisedflag onorgloop start --daemonto enable supervisor wrapper- Crash loop detection: max 10 restarts within 5-minute window
Future improvements:
- Integration with systemd/launchd for OS-level supervision
- Health check HTTP endpoint (
GET /control/health) with liveness/readiness semantics - Watchdog pattern: supervisor reads heartbeat file and force-restarts wedged processes
- Graceful degradation: shed load when sources are unhealthy rather than crashing
Affects: packages/core/src/supervisor.ts, packages/core/src/runtime.ts, packages/cli/src/commands/start.ts
FE-25: SOP Execution Audit Trail & Output Validation Resolved (v0.6.2)
Section titled “FE-25: SOP Execution Audit Trail & Output Validation Resolved (v0.6.2)”Implemented in packages/core/src/:
audit.ts—AuditTrailclass records every SOP execution with full provenance: input event (source, type, content hash), matched route, SOP file, actor session, outputs with content hashes, chain depth, and validation flagsoutput-validator.ts—OutputValidatorpre-delivery validation checks for instruction injection patterns (prompt injection defense), input echo/amplification, scope violations (unauthorized URLs, shell commands). Supports hold-for-review on critical flagsloop-detector.ts—LoopDetectortracks event chains by trace_id, alerts on configurable chain depth (default: 3 hops), auto-stops via circuit breaker at configurable depth (default: 5 hops). Detects repeated source+type patterns within chains
Defense against the Viral Agent Loop (arXiv:2602.19555). See Security guide for usage.
This appendix is committed to the repo. Actionable work items referencing these IDs are tracked in local/WORK_QUEUE.md (gitignored, private sprint queue).