Files
openclaw-to-caret-migration/DEPENDENCIES.md

14 KiB
Raw Permalink Blame History

Openclaw dependency matrix

Every openclaw-provided capability that the current gitea-webhooks pipeline uses, and what Caret's replacement does with it. Source citations: R01 = RESEARCH-01, R02 = RESEARCH-02, R03 = RESEARCH-03, PLAN = PLAN.md.

Categories:

  • REMOVE — Caret's replacement doesn't need this at all
  • REPLACE — Caret builds a standalone equivalent
  • KEEP — Caret continues depending on openclaw for this (and why that's safe)
  • BLOCKING — Caret cannot move forward without resolving this first (Rooh action required)

By capability

1. HTTP webhook ingress (port 18789, /hooks/agent)

Category: REPLACE What Caret does: Stand up a bun HTTP listener at a Caret-owned port (e.g. 18790 or unix socket), with its own path. Mirrors openclaw's /hooks/agent shape so existing scripts can be reused. [R01 §Ingress path, R02 §HTTP endpoints] Risk if kept: Hard-couples Caret's lifecycle to the openclaw gateway container. Defeats the entire migration. Effort: 1 day. Stateless request/response, well-understood. [R02 difficulty matrix: Easy]

2. HMAC verification (currently NOT done by openclaw)

Category: REPLACE (net-new — openclaw never had it) What Caret does: Real HMAC-SHA256 of the raw body using X-Gitea-Signature header, timing-safe compare, raw body preserved before JSON parse. [R01 §HMAC recipe, R03 confirms all 4 known webhooks have Secret: NOT SET] Risk if kept: No HMAC at all today; protection is bearer + nginx ACL only. Caret should do better. Effort: 0.5 day. ~30 lines. Depends on BLOCKING #1 (webhook secret provisioning).

3. Bearer token authentication (OPENCLAW_HOOKS_TOKEN)

Category: REPLACE What Caret does: Own bearer token (CARET_HOOKS_TOKEN) stored in Caret's credentials dir, validated on each request as a second factor alongside HMAC. [R01 §Ingress path layer 3] Risk if kept: Sharing the openclaw token cross-couples secret rotation. Effort: Trivial.

4. nginx TLS termination and path rewriting

Category: KEEP (with new location block) What Caret does: Adds a new nginx location /hooks/caret block that proxies to the Caret listener, same TLS cert. Reuses existing Let's Encrypt setup. [R01 §Ingress path] Risk if kept: None — nginx is host-level infra, not openclaw-specific. Effort: 1 hour, but requires host root access. See BLOCKING #2.

5. Event dedup cache (X-Gitea-Delivery 24h)

Category: REPLACE What Caret does: Own JSON-on-disk dedup cache at /host/root/.caret/state/dedup-cache.json, identical 24h TTL semantics. [R01 §Ingress path layer 4, R01 gotcha 4] Risk if kept: Sharing openclaw's cache file is fragile and couples crash recovery. Effort: 0.5 day.

6. Rate limiting (5 concurrent per agent)

Category: REPLACE What Caret does: Per-route concurrency limiter in the listener. Caret's routing is simpler (one "agent") so this is mostly a global semaphore. [R01 gotcha 7] Risk if kept: N/A. Effort: Trivial.

7. Session lock manager (hooks/locks/)

Category: REPLACE What Caret does: Own lock dir at /host/root/.caret/state/locks/, same 2h TTL, same file naming {owner}-{repo}-{issue}, same IS_DONE 5min grace. [R01 §Session lock] Risk if kept: Two writers to one lock dir = race. Effort: 0.5 day.

8. Queue daemon (queue-inbox/ + queue-daemon.js)

Category: REPLACE What Caret does: In-process queue inside the listener (or a sidecar bun script reading from /host/root/.caret/state/queue/). Re-verifies spawn signatures off the hot path. [R01 gotcha 12, R03 §queue-daemon.js] Risk if kept: Couples Caret's spawn pipeline to openclaw container restart. Effort: 1 day.

9. sessions_spawn agent orchestration primitive

Category: REPLACE (with Claude Code Channels plugin) What Caret does: Build a Channels plugin at /host/root/.caret/channels/gitea-judgment/ that receives an HTTP POST and starts a Claude Code session with the payload as initial prompt. [R02 §Caret's conclusion, PLAN §Phase 3 J3.1] Risk if kept: Openclaw's sessions_spawn is the deepest coupling — see R02 difficulty matrix "Hard" rating. Keeping it means Caret can never fully cut over. Effort: 2-3 days for the minimum viable plugin. Full parity (wakeMode, thinking, model selection) is more like 1 week.

10. Tool allowlist enforcement per agent

Category: KEEP (judgment path runs inside Claude Code, which has its own tool config) What Caret does: Caret's deterministic path runs scripts directly with no tools concept. The judgment path is a Claude Code session whose tool allowlist is configured in Claude Code's settings.json (not openclaw's). [R02 §Tool policy resolution] Risk if kept: None — Caret never touches openclaw's tool policy resolver. Effort: 0 (already separated).

11. Plugin SDK (src/plugin-sdk/)

Category: REMOVE What Caret does: Doesn't load openclaw plugins. Caret's listener is a plain bun script with no plugin loader. Channels plugin uses Claude Code's plugin mechanism, not openclaw's. [R02 §Don't reinvent #2] Risk if kept: N/A. Effort: 0.

12. Delivery system (Telegram, Mattermost, Discord)

Category: REPLACE (use tg-stream + Mattermost direct calls) What Caret does: Calls tg-stream HTTP API for Telegram alerts and Mattermost webhook URL directly for incident posts. No multi-channel abstraction layer. [R02 §Don't reinvent #4 warns it's tightly coupled — we don't replicate, we use simpler primitives] Risk if kept: Hard coupling to openclaw outbound system. Effort: 0.5 day (just curl calls).

13. Session storage (JSONL transcripts at ~/.openclaw/sessions/)

Category: KEEP (judgment path only — Claude Code's own session store) What Caret does: Deterministic path has no sessions. Judgment path uses Claude Code's native session JSONL under Claude Code's config dir, NOT openclaw's. [R02 §Don't reinvent #1] Risk if kept: None — Caret never reads/writes openclaw's session files. Effort: 0.

14. Heartbeat scheduler (heartbeat-runner.ts)

Category: REPLACE (use Claude Code schedule skill / cron) What Caret does: Use systemd timer in the Caret container OR Claude Code's schedule mechanism for the 6h policy sweep and 15min webhook audit. No 28-item checklist — Caret's heartbeat is much smaller. [R02 §Heartbeat loop, R03 §Heartbeat checklists] Risk if kept: Couples to openclaw gateway uptime, which R03 shows is currently degraded. Effort: 0.5 day for the timer setup.

15. Cron service (CronService in gateway)

Category: REPLACE (same as #14 — single mechanism) What Caret does: Same as heartbeat — systemd timers or Claude Code schedule. [R02 §Cron service, R03 §Active cron jobs shows 8 of 12 currently failing] Risk if kept: R03 shows openclaw cron is currently degraded; depending on it inherits the breakage. Effort: Combined with #14.

16. Gitea API integration (token + curl wrappers)

Category: KEEP What Caret does: Continue using the same GITEA_TOKEN and stateless curl calls. Wrapper scripts ported into /host/root/.caret/tools/. [R01 §Tools fan-out, PLAN B2.3] Risk if kept: None — Gitea API is a third-party service, openclaw is not in the path. Effort: Path-strip and copy, 1 hour. Depends on BLOCKING #3 (admin scope).

17. Workspace directory (/root/.openclaw/workspace/)

Category: KEEP (155 projects stay owned by openclaw/Xen) What Caret does: Caret's migration scope is the Gitea-facing slice ONLY. The 155-project workspace, the PROJ-XXX-* hierarchy, and Xen's project ownership stay as-is. Caret has its own /host/root/.caret/workspace/ for migration artifacts only. [R03 §What the migration actually has to replace, PLAN §Goal] Risk if kept: None for the in-scope migration. Effort: 0.

18. Project registry (projects/registry.json)

Category: KEEP What Caret does: Read-only access if needed (e.g., to look up which manager owns a project for a given issue). No writes. [R03 §Shared state] Risk if kept: Stale reads possible but acceptable. Effort: 0.

19. Memory system (memory/)

Category: REMOVE (from migration scope) What Caret does: Caret's own memory is in /root/.claude/projects/-app/memory/. Doesn't touch openclaw's memory dir. [R03 §Shared state] Risk if kept: N/A. Effort: 0.

20. Credentials store (credentials/)

Category: KEEP (read-only for shared tokens like GITEA_TOKEN) What Caret does: Read GITEA_TOKEN from openclaw credentials OR copy to Caret credentials store. Caret-owned secrets (HMAC webhook secret, CARET_HOOKS_TOKEN) live in /host/root/.caret/credentials/. [R03 §Shared state credentials] Risk if kept: Cross-coupling on token rotation. Acceptable short-term. Effort: Trivial. See BLOCKING #4 (secret rotation story).

21. post-repo-audit.sh

Category: REPLACE (port the script verbatim) What Caret does: Copy to /host/root/.caret/tools/post-repo-audit.sh, strip openclaw path prefixes, ship as-is. Pure script, zero tokens. [R01 §Tools fan-out, PLAN B2.3] Risk if kept: Couples to openclaw tools dir lifecycle. Effort: 1 hour.

22. audit-repo-policies.sh

Category: REPLACE (port verbatim) What Caret does: Copy to Caret tools dir, point at sol/repo-policies template repo, run with --fix from Caret's heartbeat. [R01 §Tools fan-out] Risk if kept: Same as #21. Effort: 1 hour.

23. spawn-manager.sh

Category: REPLACE (port verbatim, but only after #9 is solved) What Caret does: Copy script. Generates Manager spawn JSON from issue body, creates project workspace. Caret's listener calls it via execSync with same 30s timeout pattern. [R01 §Tools fan-out, R01 gotcha 9] Risk if kept: Tightly coupled to openclaw workspace path conventions — depends on whether Caret keeps openclaw's PROJ-XXX scheme (R01 advises yes). Effort: 0.5 day.

24. create-implement-issue.sh

Category: REPLACE (port verbatim) What Caret does: Copy script. Creates signed [IMPLEMENT] issue with HMAC spawn signature using /host/root/.caret/credentials/spawn-secret. [R01 §Tools fan-out] Risk if kept: Spawn secret coupling. Effort: 1 hour. Depends on BLOCKING #5 (spawn secret ownership).

25. secret-scan.sh

Category: REPLACE (port verbatim) What Caret does: Copy script, used by both CI (make check) inside repos and Caret's push handler. [R01 §Tools fan-out] Risk if kept: N/A. Effort: 1 hour.

26. check-implement-orphans.sh

Category: REPLACE (port verbatim) What Caret does: Copy script, run from Caret's 15min heartbeat to detect stale pending spawns and orphaned managers. [R01 §Tools fan-out] Risk if kept: N/A. Effort: 1 hour.

27. auditLog → logs/audit.jsonl

Category: REPLACE What Caret does: Caret's listener writes to /host/root/.caret/log/audit.jsonl, same JSONL line schema. Rotation by line count. [R01 §Logging, PLAN B2.5] Risk if kept: Two writers to one file = corruption. Effort: 0.5 day.

28. Incident flagging (logs/incidents.jsonl)

Category: REPLACE What Caret does: Caret writes to /host/root/.caret/log/incidents.jsonl. Critical incidents also fan out to Telegram via tg-stream. [R01 §Logging, T2.23] Risk if kept: Same as #27. Effort: 0.5 day (combined with #27).

Summary by category

Category Count
REMOVE 2 (#11, #19)
REPLACE 19 (#1, #2, #3, #5, #6, #7, #8, #9, #12, #14, #15, #21, #22, #23, #24, #25, #26, #27, #28)
KEEP 6 (#4, #10, #13, #16, #17, #18, #20) — note #20 partially
BLOCKING 5 (see below)

BLOCKING items — Rooh action required

These five items must be resolved by Rooh before Caret can write the production code. They are not engineering decisions; they are policy / access decisions only Rooh can make.

BLOCKING #1 — Webhook secret provisioning and storage location

Question: Where is the new HMAC webhook secret stored? /host/root/.caret/credentials/webhook-secret? A vault entry? Reused from an existing openclaw secret? Why it blocks: Cannot ship HMAC verification (T1.06T1.11) without the secret being authoritative somewhere. Cannot register webhooks on sol/* repos without knowing what secret to set on the Gitea side. Reference: R01 §HMAC recipe, R03 confirms all current webhooks have Secret: NOT SET.

BLOCKING #2 — nginx config write access for /hooks/caret location

Question: Does Caret have permission to edit /host/etc/nginx/... and reload nginx, or does Rooh do that one-time setup? Why it blocks: Without an nginx route, Gitea cannot reach the Caret listener via HTTPS. Direct port exposure is the only alternative and that needs firewall changes. Reference: R01 §Ingress path nginx termination, dependency #4.

BLOCKING #3 — Gitea token admin scope OR manual system-webhook registration

Question: Will Rooh elevate the sol token to include read:admin + write:admin, or will Rooh manually register the system-level webhook one time? Why it blocks: Without admin scope Caret cannot list system-level webhooks (R03 confirmed) and cannot create them. The sol/* per-repo webhooks can be registered with the existing token, but for new repo bootstrap to register Caret's webhook automatically (T1.02), the admin scope or manual setup is required. Reference: R03 §Registered Gitea webhooks, PLAN §Dependencies token scope.

BLOCKING #4 — Secret rotation story across openclaw + Caret

Question: When GITEA_TOKEN or the webhook secret rotates, what's the rollout? Does Caret read from openclaw's credentials dir live, or get its own copy that needs separate rotation? Who is responsible for rotation drills? Why it blocks: PLAN §Risks #1 explicitly calls this out as a first-class deliverable. Without a documented rotation procedure, T3.13 cannot pass and the migration leaves a security debt. Reference: PLAN §Risks #1, dependency #20.

BLOCKING #5 — Spawn signature secret ownership (/root/.openclaw/hooks/spawn-secret)

Question: Does Caret get its own spawn secret (and create-implement-issue.sh is updated to use it), or does Caret read openclaw's existing secret? If the latter, what happens when openclaw rotates it? Why it blocks: T1.15T1.17 (spawn signature verification) require Caret and create-implement-issue.sh to share a secret. Cross-system sharing is the cleaner short-term answer but locks Caret to openclaw's lifecycle until cut-over completes. Reference: R01 §Ingress path "spawn signatures", dependency #24.