# ICD Drift Audit — SDK vs Backend **Date:** 2026-03-23 **Method:** Compared `src/js/sw/sdk/api-domains.js` against `docs/ICD/*.md` and `server/main.go`. **Principle:** ICD is the zone of truth. SDK must conform to it. --- ## A. SDK Bugs — Wrong method or path (fix in SDK) | SDK Method | SDK Calls | Backend Route | Issue | |---|---|---|---| | `workflows.update(id, data)` | `PUT /workflows/:id` | `PATCH /workflows/:id` | `crud()` generates PUT; backend is PATCH → 404/405 | | `workspaces.update(id, data)` | `PUT /workspaces/:id` | `PATCH /workspaces/:id` | Same — `crud()` generates PUT; backend is PATCH | | `tasks.start(id, data)` | `POST /tasks/:id/start` | `POST /tasks/:id/run` | Path mismatch → 404 | | `tasks.stop(id)` | `POST /tasks/:id/stop` | `POST /tasks/:id/kill` | Path mismatch → 404 | | `dataPortability.deleteAccount(data)` | `POST /profile/delete` | `DELETE /me` | Both method and path wrong | ## B. SDK Bug — Duplicate key overwrites (fix in SDK) `notifications` is defined **three times** as a top-level key in the `createDomains` return object: 1. **Line 186** — Domain #11 (has `prefs`, `setPref`, `delPref`, uses `POST` for markRead) 2. **Line 431** — Inside `admin` namespace (correct, no conflict) 3. **Line 501** — "Misc" section (uses `PATCH` for markRead, no preference methods) JavaScript last-write-wins: #3 overwrites #1. The notification preference methods (`prefs`, `setPref`, `delPref`) are silently lost. The `markRead` method changes from POST to PATCH (PATCH matches the ICD, so #3 has the correct HTTP method but is missing methods). **Fix:** Delete the duplicate at line 501. Merge its `del` method and `PATCH` fix into the domain #11 block at line 186. ## C. ICD Gaps — Endpoints exist in main.go, not documented in ICD These endpoints are real (registered in main.go, used by the SDK) but have no ICD documentation. | Endpoint | Belongs in ICD File | Notes | |---|---|---| | `POST /channels/:id/mark-read` | channels.md | SDK: `channels.markRead()` | | `POST /channels/:id/generate-title` | channels.md | SDK: `channels.generateTitle()` | | `POST /channels/:id/summarize` | channels.md | SDK: `channels.summarize()` | | `GET /channels/:id/messages/:msgId/siblings` | channels.md | SDK: `channels.siblings()` | | `GET /knowledge-bases-discoverable` | knowledge.md | SDK: `knowledge.discoverable()` | | `GET /folders`, `POST`, `PUT /:id`, `DELETE /:id` | (new section) | Full CRUD, needs own ICD section or add to channels.md | | `GET /users/search?q=...` | (new section) | SDK: `users.search()` | | `POST /presence/heartbeat`, `GET /presence` | (new section) | SDK: `presence.heartbeat()` | | `GET /usage` | (new section) | SDK: `usage.mine()` | | `GET /groups/mine` | (new section) | SDK: `groups.mine()` | | `GET /export/me` | utility.md | SDK: `dataPortability.exportMe()` | | `DELETE /me` | utility.md | GDPR account deletion | | `GET /git-credentials`, `POST`, `DELETE /:id` | (new section) | SDK: `git.credentials.*` | | `POST /git-credentials/generate` | (new section) | Not in SDK — SSH key generation | | `GET /git-credentials/:id/public-key` | (new section) | Not in SDK | | `GET /tools` | (new section) | SDK: `tools.list()` | ## D. ICD-Documented Endpoints Missing from SDK In the ICD but the SDK doesn't expose them. Add only as surfaces need them. | Endpoint | ICD File | Notes | |---|---|---| | Workflow stages CRUD (`GET/POST/PUT/DELETE /workflows/:id/stages/*`) | workflows.md | Workflow editor needs these | | `PATCH /workflows/:id/stages/reorder` | workflows.md | | | `POST /workflows/:id/publish` | workflows.md | Team-scoped version exists in SDK | | `POST /workflows/:id/start` | workflows.md | Instance creation | | `GET /channels/:id/workflow/status` | workflows.md | | | `POST /channels/:id/workflow/advance` | workflows.md | | | Workspace archive (`download`, `upload`) | workspaces.md | | | `POST /workspaces/:id/reconcile` | workspaces.md | | | `GET /workspaces/:id/stats` | workspaces.md | | | `GET /workspaces/:id/index-status` | workspaces.md | | | `POST /workspaces/:id/git/clone`, `git/pull` | workspaces.md | | | `GET /extensions/:id/manifest` | extensions.md | | | `GET /extensions/tools` | extensions.md | | | `POST /personas/:id/avatar`, `DELETE` | personas.md | User-scoped (admin-scoped exists) | | `POST /knowledge-bases/:id/rebuild` | knowledge.md | | ## E. Response Shape Mismatches | Endpoint | Response Shape | Convention | Notes | |---|---|---|---| | `GET /api-configs` | `{"configs": [...]}` | Should be `{"data": [...]}` | SDK `_unwrap` won't strip | | `GET /admin/configs` | `{"configs": [...]}` | Should be `{"data": [...]}` | Same | | `GET /admin/models` | `{"models": [...]}` | Should be `{"data": [...]}` | Same | | `GET /admin/users` | `{"users": [...]}` | Should be `{"data": [...]}` | Same | These use named keys instead of the `{"data": [...]}` envelope convention. The SDK's `_unwrap` doesn't strip these, so consumers get the envelope object. --- ## Recommended Priority 1. Fix §A (SDK 404s) — these are broken in production 2. Fix §B (duplicate notifications key) 3. Document §C (ICD gaps) — endpoints work, just undocumented 4. Add §D methods to SDK — only as surfaces need them 5. Migrate §E response shapes to `{"data": [...]}` — breaking change, defer