4 — Additions: Bridges to the Outside

Colibri is a closed system with a three-axis physics, a four-tier social hierarchy, and a locked execution pipeline. But it lives in a world full of other systems: Git, Obsidian, Claude API, developer editors, human messaging tools. The system must integrate with these external realities without allowing them to corrupt internal invariants. This is what ν Integrations does.


The Integration Pattern

Nothing enters or exits the world without passing through the α chain and leaving a ζ record. External systems are not trusted — they are mediated.

Pattern: The α-ζ Invariant

Every external call follows a schema:

invoke(context, #contract) → Record
  1. context: the current state (which task, which round, which identity)
  2. #contract: a schema that validates what an external system can and cannot do
  3. Record: a ζ thought record added to the decision trail, timestamped and hashed

Stages:

  1. Audit-enter (α.3): The call enters the middleware chain. The contract is loaded.
  2. Schema-validate (α.2): The external request is mapped to the contract schema. Invalid requests are rejected.
  3. Dispatch: The external system is called with the validated request.
  4. Audit-exit (α.4): The response is logged and added to the ζ decision trail.
  5. Record-finalize (ζ): The record is hash-chained to the previous decision in the trail.

If any stage fails, the entire operation is aborted. The external system never sees a half-baked mutation.

Example: GitHub commit via the GitHub Desktop bridge (Phase 0)

  1. Task P0.3.2 completes in a worktree
  2. Executor calls git commit -m "feat(tasks): ..."
  3. Audit-enter: the executor’s session is checked (is it running in a valid worktree?)
  4. Schema-validate: the commit message is parsed. Forbidden patterns are rejected. Max message length is enforced.
  5. Dispatch: git commit is run via the GitHub Desktop MCP
  6. Audit-exit: the commit SHA is logged, the branch name is verified as feature/<task-slug>
  7. Record-finalize: a ζ record is added: {"event": "vcs_commit", "branch": "feature/p0.3.2", "sha": "abc123...", "timestamp": "2026-04-13T10:22:45Z"}

If the commit fails (e.g., non-fast-forward), the stage 5 error is propagated back, and no ζ record is created.


Phase 0 Integrations (Implemented or Near-Ready)

Git (GitHub Desktop, never manual CLI)

Why not manual CLI? The Phase 0 Git interface is GitHub Desktop only. Direct CLI access (git push) is forbidden from T3 executor sessions. This prevents accidental force-pushes to main.

Contract: Per CLAUDE.md §3 (worktree rule):

  • git fetch origin allowed (read-only)
  • git worktree add .worktrees/claude/<task-slug> -b feature/<task-slug> origin/main allowed (creates worktree)
  • git commit on feature/<task-slug> allowed (local changes)
  • git push forbidden (human authorizes via GitHub Desktop / PR merge)
  • Force-push (git push -f) forbidden on all branches
  • Deletion of feature/<task-slug> before merge forbidden

Bridge: GitHub Desktop MCP (not yet connected in Phase 0, manual until P0.9)

Records: Every commit, branch creation, and push attempt is logged to mcp_vcs_events.


Obsidian (Pull-based sync via robocopy)

Why pull-based? Obsidian is a human workspace. It is read-only for code. Changes made in the vault (Obsidian Vault/Colibri/docs/) are never synced back to the repo. This prevents accidental overwrite of canonical specs.

Contract:

  • docs/ → Obsidian vault: full mirror, updated via robocopy or the colibri-docs-sync skill
  • Obsidian _vault/ → repo: never. Human planning lives here, is never committed.
  • Merge strategy: docs/ always wins. If a file exists in both places, the repo copy is canonical.

Direction: One-way, docs → vault. If the human edits a file in the vault that also exists under docs/, those edits are local-only (not pushed).

Sync timing: Manual skill execution (Phase 0), or scheduled (Phase 1+)

Excluded from sync: .git, _vault, .worktrees, node_modules, temp/

Records: Every sync operation logs a ν_obsidian_sync record with file count, conflict resolution strategy, timestamp.


Claude API (Anthropic SDK, Phase 0.5+)

Why separate from Colibri server? Phase 0 is Claude-only, but the language model is external to the server. When a task dispatcher (T2 PM or T3 executor) needs to call Claude, it goes through the router (δ).

Contract:

  • Request schema: {task_id, context, max_tokens, temperature, model}
  • Response schema: {tokens_in, tokens_out, model_used, stop_reason, completion}
  • No system prompt injection: system is fixed per phase
  • Latency budget: 60 seconds per call (P0), 120 seconds (later phases with reasoning)

Bridge: Claude API wrapper (src/domains/router/call.ts, P0.5.2)

Records: Every API call logs mcp_model_calls with routing decision, model, tokens, latency, completion reason.

Forbidden:

  • Streaming responses (Phase 0 is one-shot only)
  • Vision (deferred to Phase 1)
  • Batch processing (deferred to Phase 1)

Integration Architecture (ν domains)

The integrations layer lives in src/domains/integrations/ (Phase 0.9 target). It is organized by external system:

src/domains/integrations/
  ├── github/
  │   ├── contracts.ts        # what GitHub APIs can be called
  │   ├── client.ts          # GitHub Desktop MCP wrapper
  │   └── events.ts          # vcs_* record schemas
  │
  ├── obsidian/
  │   ├── contracts.ts        # what paths can be synced
  │   ├── sync.ts            # robocopy wrapper + strategy
  │   └── events.ts          # obsidian_sync record schema
  │
  ├── anthropic/
  │   ├── contracts.ts        # API request/response schemas
  │   ├── client.ts          # SDK wrapper
  │   └── events.ts          # model_calls record schema
  │
  └── index.ts                # adapter dispatcher

Every adapter follows the same pattern:

  1. contracts.ts: Zod schemas for request/response
  2. client.ts: MCP tool wrapper or HTTP client
  3. events.ts: ζ record schema
  4. index.ts: registration in the dispatcher

Failure Handling

External systems fail. Networks go down. APIs return 5xx. The integration pattern isolates failures.

Failure modes:

Failure Stage Behavior
Invalid request Schema-validate Rejected before dispatch. ζ record: {status: "rejected", reason: "schema_error"}
Network timeout Dispatch Task is retried 3 times, then marked deferred (Phase 1+) or escalated (Phase 0)
API error (4xx) Audit-exit Logged as-is. No ζ record (auth failures) or ζ record with error (business logic failure)
API error (5xx) Audit-exit Retried with exponential backoff. Max 5 retries. Then escalated to T2 PM
Partial success Audit-exit Depends on operation. Commits are atomic (all-or-nothing). Syncs are idempotent.

Key principle: If ζ record is written, the operation is committed. If ζ record is not written, the operation must be retried or escalated.


Phase 0.9: ν Additions in Action

P0.9 lands in round R80 (the final Phase 0 round). By then:

  • GitHub Desktop integration is connected (PR creation + merge workflow)
  • Obsidian sync is automated via a scheduled skill
  • Claude API calls are logged and routed through the decision trail
  • All integration records are validated and added to ζ

At Phase 0 seal, the system has:

  • 256 task-level ζ records (one per task, plus routing + API calls)
  • ≈50 vcs records (commits, branch creates, PRs)
  • ≈8 obsidian_sync records (end of each round)
  • Hundreds of model_calls records (every executor session)

All are Merkle-sealed into the session root hash.


Future Integrations (Phase 1+)

Phase Bridge What it adds
P1 Editor tools (VS Code, JetBrains) Live diagnostics, task-aware linting
P1 Slack / Discord Status updates, notifications
P1+ Plugin system User-defined adapters, worker thread isolation
P7 CRDT/OT sync Real-time vault collaboration via Yjs + WebSocket
P7 AI intelligence suite Semantic cache, query optimizer, pattern recognizer (24 sub-modules)

Every new integration:

  1. Defines a contract schema
  2. Implements an adapter in src/domains/integrations/<system>/
  3. Registers itself in the dispatcher
  4. Logs its output as ζ records

No integration can read or modify the main database. All mutations go through the α middleware chain.


The Core Guarantee

Nothing enters or exits the world without passing through the α chain and leaving a ζ record.

This is not a performance optimization. It is a security invariant. Every external connection is mediated, validated, logged, and sealed into the proof tree. At Phase 0 seal, the system has a complete, auditable log of every external interaction it ever had. The proof tree roots this log cryptographically. Trust is not a feature — it is a consequence of architecture.


Integration Failure Contract

Every integration adapter must answer the same four questions the same way: what does a transient failure look like, what does a permanent failure look like, how many times do I retry, and where does the proof go? This section specifies the universal contract; per-integration sections above already describe their own schemas and bridges.

Per-integration failure semantics

GitHub Desktop MCP — if not connected, ν_github_* tools return:

{
  "ok": false,
  "error": {
    "code": "INTEGRATION_UNAVAILABLE",
    "message": "github-desktop MCP not connected"
  }
}

The task layer retries up to 3 times with exponential backoff (200ms, 1s, 5s) before escalating to T2 PM. Permanent auth errors (e.g., GitHub token revoked) skip the retry loop and escalate immediately.

Obsidian sync bridge — if temp/sync-full.bat fails (robocopy exit code > 3), the failure is logged to mcp_integrations_log with the robocopy exit code and the first 512 bytes of stderr. Vault drift is acceptable and non-blocking: the Obsidian vault is a human workspace, not a runtime dependency. PM (T2) runs the sync manually on the next round seal if the automated retry didn’t recover.

Claude API (Anthropic SDK) — 5xx errors retry with exponential backoff (1s, 4s, 15s, 60s). 4xx errors (except 429 rate-limit) do not retry. 429 retries use the retry-after header if present; otherwise it falls back to a 30-second floor.

Generic retry semantics

  • Transient (network drop, timeout, 5xx, 429 rate-limit, lock contention) — retry with exponential backoff, 3 attempts by default.
  • Permanent (auth failure, schema mismatch, 4xx other than 429) — fail fast, log the error, escalate to T0 via session seal notes.
  • Unknown — treat as transient once; if the second attempt reproduces the same error code, reclassify as permanent.

Logging shape

Every adapter writes to mcp_integrations_log (Phase 1 target table; Phase 0 stashes this in mcp_vcs_events / mcp_model_calls per domain) using the same record shape:

{
  "timestamp": "2026-04-16T14:30:02Z",
  "integration_id": "github-desktop",
  "operation": "commit",
  "result": "SUCCESS" ,
  "attempt_number": 1,
  "error_code": null,
  "latency_ms": 412
}

result is one of SUCCESS | RETRY | FAIL. RETRY rows are emitted per attempt so that a failing operation produces N-1 RETRY rows followed by a terminal FAIL row. SUCCESS after RETRYs is permitted and expected.

Cross-refs


See Also


Back to top

Colibri — documentation-first MCP runtime. Apache 2.0 + Commons Clause.

This site uses Just the Docs, a documentation theme for Jekyll.