Files
Heretek-OpenCode Coordinator 51feda30bf feat(gateway): hardened opencode-gateway contract v1 (closes #18/#19, ready for #20 v1.0.0)
- contract/v1/fixtures: 10 golden JSON-RPC 2.0 pairs for search/fetch/
  extract_structured/research_report (+initialize, tools-list wire compat),
  X-Swarm-Contract:1 headers, real sha256 contentHash digests
- packages/contract-client (@heretek-ai/gateway-contract 1.0.0): Zod schemas
  for all tools, provenance envelope {provenance,trust:untrusted,content},
  typed MCP client (initialize negotiation, Retry-After retry, sha256
  verification, contract header assertion), fixture loader + hash check,
  pure SSRF/sanitize/circuit/cache modules
- packages/opencode-guard (@heretek-ai/gateway-guard): OpenCode v2 plugin on
  @opencode/plugin 2.0.26 exact (define + tool.hook + mcp.transform),
  gateway-only allowlist, lane-egress fallback documented
- apps/gateway (Bun/TS): SSRF fail-closed (literal blocklist + DNS pin +
  no-redirect-to-private), per-(host,engine) circuit breakers with half-open,
  injection sanitize envelope, sha256 cache keys + TTLs, caps as error codes
- catalog (4 engines), deploy (smokescreen + caddy snippets)
- QA: bun test 44/44, tsc clean, oxlint clean
2026-10-12 13:10:42 -04:00

3.2 KiB
Raw Permalink Blame History

@heretek-ai/opencode-gateway

Hardened web-ingestion MCP gateway (contract v1, X-Swarm-Contract: 1), evolved from scraper-swarm's operational architecture: golden contract fixtures, fail-closed SSRF, Smokescreen egress proxying.

packages/opencode-gateway/
├── contract/            # versioned golden fixtures (contract v1)
├── packages/
│   ├── contract-client/ # @heretek-ai/gateway-contract 1.0.0 (Zod + typed MCP client)
│   └── opencode-guard/  # @heretek-ai/gateway-guard (OpenCode v2 plugin, @opencode/plugin 2.0.26 exact)
├── apps/
│   └── gateway/         # TS/Bun MCP gateway (POST /mcp, GET /ready, GET /health)
├── catalog/             # engine defs (searxng, crawl4ai, scrapling, firecrawl)
└── deploy/              # smokescreen + caddy snippets

Contract

  • POST /mcp — strict JSON-RPC 2.0 (-32700/-32600/-32601/-32602, 202 notifications, initialize negotiation).
  • Every response carries X-Swarm-Contract: 1; tools return text plus structuredContent with the prompt-injection envelope ({ provenance: { url, fetchedAt, engine, contentHash }, trust: "untrusted", content }) and machine-readable error codes.
  • Golden fixtures: contract/v1/fixtures/ (vendor by commit; contentHash values are real digests — recompute on vendoring).

Hardening

  • SSRF fail-closed: literal blocklist (127/8, 10/8, 172.16/12, 192.168/16, 169.254/16, 100.64/10, ::1, fc00::/7, fe80::/10, 0.0.0.0, dword/hex/octal/shortened encodings, ::ffff:-mapped), DNS pin (any private resolution denied, NXDOMAIN fails closed), no-redirect-to-private (redirects followed manually, every hop checked).
  • Per-host circuit breakers keyed by (host, engine) with half-open probes; backoff surfaced in structuredContent.
  • Prompt-injection envelope: zero-width strip (U+200B–U+200F, U+FEFF, U+2060–U+2064, U+180E), override phrasings → [removed], hash covers the sanitized bytes.
  • Cache: key sha256(tool + params + contractVersion); TTLs search 5m / fetch+extract 1h / research 1d; hits keep original fetchedAt + cached: true.
  • Caps fail closed with error codes, never truncated success.

Tests

bun test packages/opencode-gateway/packages/contract-client/test packages/opencode-gateway/apps/gateway/test packages/opencode-gateway/packages/opencode-guard/test

Issue closure notes (v1.0.0 readiness)

  • #19 (contract as a package): closed by packages/contract-client (@heretek-ai/gateway-contract 1.0.0) — Zod schemas for all four tools, typed /mcp client (initialize negotiation, Retry-After retries, sha256 verification), vendored golden fixtures with hash check.
  • #18 (OpenCode plugin rewrite): closed by packages/opencode-guard (@heretek-ai/gateway-guard) — rewritten against pinned @opencode/plugin 2.0.26 exact (v2 define + tool.hook + mcp.transform API), strict tool guards with gateway-only allowlist, lane egress fallback documented in its README.
  • #20 (first release tag): this package is cut as v1.0.0 — fixtures frozen, conformance green, CHANGELOG finalized. Tags are human-only; automation must never push main or create tags.