Engineering documents from the cMCP pilot build (October 2026). Statuses here are engineering states, not product claims: see cMCP for what is available. All documents

← cMCP home

Build plan: from the built system to the space and memory model

Plan v1.0 · approved (M-106) and built: stages 1l–1s live 2026-10-11 (M-109), 1t (M-111) v1.2 · next: the move to IT-Labs hardware (section 15); 1u set aside 2026-10-11
This plan looks at the whole picture once more. It covers what is built (stages 1a–1k), what the research asks for (Q-35 auto-mapping and automatic saving, Q-36 space and memory model v1.1), and the gap between them. It then says what we reuse, what we build new, and in what order. It replaces the old "stage 1l = live sync" line on the roadmap. Nothing is built until the user approves.

Summary

The plan in ten points
  1. Keep and extend; don't rebuild. The built system already does the hard parts: sign-in, tenant walls in the database, permissions, grants, approvals, promotion, connectors, audit, sync and search. The new model is a layer on top of it, not a replacement.
  2. What is missing comes down to four things: spaces (space IDs, aliases, links to places), the memory address on every item, automatic capture (helper, hooks and checkpoints), and a two-way loop (envelope, conversations and a change cursor). After those come collective memory, space knowledge and index cards.
  3. The two memories fit the existing scopes. Organizational memory = today's Org / Project / Team / Client memory. A person's "lane" = today's User memory (or a bot's own memory) plus a space ID. The work pool = User memory with no space yet. Collective memory = a view that counts lane items by space links. So the scopes, rules and tests we have stay valid.
  4. One new registry: spaces. It has company and client tenants, spaces, aliases and versioned links. Today's place mappings (git_repo:, jira_project:) are moved into it, so place resolution keeps working.
  5. One small client: the cmcp helper. It fingerprints the folder, receives the space manifest, tags each stretch of a session, and uploads checkpoints in the background. The first tool is Claude Code; others follow through the same helper.
  6. The server routes; the tool's model writes notes. The notes come from the tool's own model, already short and marked "about the person" or "about the work". cMCP routes them by rules (stretch tag first, then an explicit mention). The slow local model is never needed in the request path.
  7. Private first, review first. Automatic items land only in the person's own memory or work pool. Shared places get them through the approval and promotion paths that already exist. Real accounts start in "review first".
  8. Space knowledge reuses connectors and the memories table. Jira and the IMAP mailbox already store sources and approve facts. They gain layers (raw → cleaned → typed records), and typed records (decision, action, status) are memories with a kind and fields. No second store is needed.
  9. Seven stages, 1l–1r, each a thin, testable slice following the usual flow: threat model → build → tests → reviews → S-xx approval → commit. The first visible proof comes at the end of stage 1n: this server's own Claude saves into owner-solo on its own, and every item answers the seven questions.
  10. The real account pilot joins last, after the allowed-AI-apps list (1q) and company approval, because tools like Claude Code send the memory they read to their vendor's cloud model.

1. The complete picture

1.1 What is built (stages 1a–1k, live since go-live)

AreaWhat exists today (verified in the code, HEAD e719914, migrations 0001–0054)
IdentityKeycloak (one-time code for people), web-admin login, bot keys cmcp_bot_…, AI apps as OAuth clients. principals types: human, delegated_agent, bot, service. client_apps = person + app (agent instance), with elevation.
Places and scopesOne org per account. Projects, teams, clients and memberships (several leads). Scopes: org, project, client, team, user, personal, agent. Client wall. Org read floor.
RulesForced RLS on every tenant table (41 tables; platform.audit is the approved exception). One permission service. Grants, powers, elevation, covers, feature switches, times and limits, access requests, the ADMIN role, audit in the same transaction.
Memorymemories with scope, owner, kind, audience, confidence, valid from / to, version, status (current / superseded / deleted / staged), created_via_app_id and created_via_model; memory_versions; memory_links (derived_from, promoted_from, contradicts, relates_to, supersedes); sources with raw text.
FlowsMemory requests, promotion User / Agent → Team (≥ 3 people, neutral rewrite, lead approves), lateral synthesis (off by default), approvals inbox and bulk decisions.
SyncScope versions, change_events (bigserial), per-app manifest {"scope:id": version}, delta packs with removed ids, must-apply notices, resource subscription on cmcp://context/{app_id}, memory_refresh.
Place resolutioncontext.resolve_place: explicit place → app default → mapping rule (git_repo:, jira_project:, chat_channel: in place_mappings, member only) → home team → org. URL spelling is cleaned; there is no fingerprint and no alias table.
ConnectorsJira Cloud, PostgreSQL views, IMAP. Each item version is a sources row (external_ref unique per connector). The extract job stages facts, and leads approve them. Raw mail / row text is emptied 30 days after the decision. OpenBao holds the secrets.
Worker and engineJobs: extract, index, unindex, promote, synthesize, import, housekeeping (and reembed, which has no handler). Local qwen3 4B for real accounts; Groq first for synthetic ones. Hindsight in chunks mode: one bank per account with strict scope tags, and separate banks for each Personal space and each client.
InterfacesREST /v1 (reads X-CMCP-Place / Model / Purpose / Token-Budget / Format / App) and /mcp with 11 tools. /mcp reads no X-CMCP headers and no _meta. Web console with W-01…W-10 screens, the platform screens and the manual.
Tests399 backend tests at the end of 1k (282 test functions: e2e 118, isolation 90, unit 67, sync 7; some take parameters), about 13 browser tests, and retrieval and Jira extraction eval scripts.

1.2 What the research asks for

Q-35: auto-mapping and automatic saving
A helper shared by all tools. Folder fingerprints and aliases. Private spaces. Ask-once links. Personal device keys. An allowed-AI-apps list per account. Identity from the sign-in only. An envelope (place, conversation, run, tool, model, idempotency key) on REST, /mcp headers and _meta. A cursor change feed. Saving at checkpoints through hooks and a bot library, curated first, private first, review first for real accounts. Whole conversations only under M-105.
Q-36: space and memory model v1.1
Four kinds of actor. Space IDs from platform ids, never with the person in them. Owner side from hard facts. Links: same / declared / confirmed / suggested. A space manifest sent at session start. Session routing and a private work pool. A memory address on every item. Store once, count by links. Collective vs organizational memory. Space knowledge in four layers. Indexes per category, a link graph and index cards.

1.3 The gap, in one table

Needed by the modelTodayGap
Space ID, address, aliases, owner sideSpelling-cleaned mapping keys onlyNew registry (tenants, spaces, aliases)
Links space → place with kind, confidence, historyplace_mappings (one kind, no history)Versioned links; migrate the mappings
Memory address (space, app, run, conversation, confidence)Scope, owner, app id, modelAdd columns plus a frozen address stamp
Envelope on every callREST headers only; /mcp reads tool argumentsOne envelope reader for REST and /mcp
Conversations, runs, idempotencyNone (only connector external_ref)New tables
"What changed since" cursorScope-version manifest and push notice/v1/changes?cursor= on change_events
Automatic captureExplicit saves; session summary (staged ones are stuck: no confirm path)Helper, hooks, checkpoint, "To review" list (bug fix)
Work pool, routing, ask-onceNoneRouting service and pool view
Collective memory (aggregate, ≥ 3)Promotion counts confirmations inside a teamCounts-toward view by space links; promotion reads it
Space knowledge layers and typed recordsRaw source → staged factsCleaned layer, typed kinds, digests
Index cards and catalog indexesContext pack (all scopes, within a budget)Person and place cards; catalog search
Digital workersBots with a sponsor and keysNew principal kind with master / backup rules
Allowed AI apps, device keysApp registration; bot keysAllow-list per account; personal device keys

2. Reuse or rebuild: the verdict

Extend the built system. A fresh system would have to rebuild 54 migrations of tenant walls, the permission service and about 400 tests before it reached today's level, and none of the new ideas needs that. Every new concept either maps onto an existing scope or table, or is an added table with the same row-level security. Three parts are reworked, not added to: place mappings (moved into the space registry), the stuck staged-summary path (replaced by "To review"), and the per-app manifest (extended with spaces, cards and a cursor). Nothing is thrown away.
Why it fits
  • The model's "store once, count by links" matches how memory is already owned (owner + scope) and linked (memory_links).
  • "Organizational memory needs approval" is exactly the promotion and approval flow built in 1d.
  • "Derived data keeps its source's rules" already holds for connector facts (source link, strictest audience).
  • change_events is already a per-account sequence, so the cursor feed is a read over it.
Where we must be careful
  • Space knowledge from a private channel needs per-source audiences. That is a new access rule, so it is deferred: the first sources are only spaces whose audience equals a place's members (stage 1p).
  • Local paths are personal data. Path aliases are stored only for the person who owns them.
  • Adding a principal kind (digital worker) touches every permission check, so it waits for its own stage (1r) and threat model.

3. Reuse map: every part, and what happens to it

REUSE as is · EXTEND small additions · NEW new part · RETIRE moved into a new part

Existing partRole in the new modelChange
Keycloak, bot keys, OAuth clientsREUSEWho: org, actor, app (principle P1)Device keys added in 1q
principalsEXTENDPerson, task bot (bot), agent (delegated_agent)Kind worker plus a worker profile in 1r
client_appsEXTEND"App" = tool + actor (+ device later)Tool label, device, allowed-list state
Places, memberships, client wallREUSEPlaces of the model, unchangedNone
Org / Project / Team / Client memoryREUSEOrganizational memoryEvidence links from promotions
User memory, a bot's own memory, Agent scopeEXTENDLanes (with space_id) and the work pool (no space yet)Address columns, routing state
Personal memoryREUSEStays per-app, never promoted, never routedNone
place_mappings + resolve_placeRETIREBecome space aliases + declared links; resolution goes envelope → space → link → placeRead-compatible for one stage, then dropped
memory_linksREUSEEvidence, "replaces", one item linked to several spacesNone
sourcesEXTENDSession copy, and layers 1–2 of space knowledgespace_id, conversation_id, cleaned text, hash, thread key
Promotion, synthesis, requests, approvals inboxREUSECollective → organizational, and lead approval of space knowledgePromotion reads the counts-toward view
change_events, scope versions, app manifestEXTENDCursor feed and the space manifest/v1/changes, manifest v2
Context packEXTENDIndex cards plus details on demandCards first, pack kept as a fallback
memory_save_session_summary (staged)EXTENDOne kind of checkpoint"To review" list and a confirm path (bug fix)
Connectors (Jira, IMAP, DB views), OpenBaoEXTENDCompany spaces and space knowledgeSpaces registered from connectors; layers and kinds
Worker jobs, Hindsight banksEXTENDSame jobs plus routing suggestions, ageing, digestsTag space:{id} on documents
Feature switches, times and limitsEXTENDCapture mode, allowed apps, the source defaults of Q-36 decision 17New keys, and the risk notices of M-105
Audit, versioning, isolation test harnessREUSEP10 "everything stamped"New tables get the same harness
Envelope reader, conversations, idempotency, routing service, space registry, helper and hooks, cards, counts-toward viewNEWThe missing partsSections 6–8

4. How the model fits the existing scopes

This is the key design choice, because it decides whether everything built so far stays valid.

Model term (Q-36)Stored asWho reads it (existing rules)
Lane "Alice · sp_ship_api"memories with scope user = Alice, space_id = sp_ship_api, routing state placedAlice and her apps (User memory rules)
Work poolSame, with space_id empty and routing state poolAlice only
Task bot laneThe bot's own memory with space_idThe bot and its sponsor (sponsor view)
Digital worker lane (1r)The worker's own memory with space_id, marked AIThe worker and its master
Collective memory of ShippingNothing stored: a view counts_toward(item → place) through the item's space and that space's linksMembers see aggregates only (≥ 3 distinct people, humans only); names only on items people shared
Organizational memory of ShippingProject memory (unchanged), with promoted_from links to the evidenceProject members (unchanged)
Space knowledge from #shipping (company space, members = Shipping)memories with scope project = Shipping, space_id = sp_ship_chan, kind decision / action / status …, status staged until the lead approves (as connector facts today)Project members; restricted items as today
Session copysources kind session_copy, private to the person, emptied after 30 days (like connector text)The person
Why this works. A space ID never changes who can read an item (principle P6). The scope and owner still decide that, exactly as today. The space ID only decides what an item counts toward and what it is offered to. So all the RLS policies, isolation tests and permission checks keep their meaning. The new risk is narrow: the aggregate view must never leak an individual item. It gets its own isolation tests (group size, client wall, Personal memory excluded).

5. Target architecture

Clients cmcp helper + Claude Code hooksfingerprint · stretch tags · uploader Bot library / other toolsstart → checkpoint → changes Web console+ My spaces · Work pool · To review Chat apps (claude.ai …)connector · allowed-apps list REST + /mcpEnvelope readerplace · conversationrun · tool · modelidempotency · cursorIdentity from thesign-in onlyheader vs _metadisagree → refused Services Space registry + links Conversations + routing Manifest v2 + index cards Change feed (cursor) Counts-toward + aggregates Permission service Scopes · places · client wall Promotion · approvals · requests Connectors (space knowledge) Audit · versions · switches PostgreSQL 18 (forced RLS on every table)existing tables + tenants · spaces · aliases · links · conversations · stretches · idempotency · routing · cards Workerextract · index · promote + route-suggest · age · digest Hindsight index+ tag space:{id} · same banks Legend reuse as is extend new
Green parts stay as they are, amber parts get small additions, and purple parts are new. The new services call the existing permission service for every read; they never decide access themselves.

6. Data model changes (migrations 0055 onward)

Every new table follows the new-tenant-table skill: account_id, ENABLE + FORCE RLS, policies bound to cmcp_app / cmcp_worker, audit, and isolation tests in the two-account harness.

Table / changeMain columnsStage
NEW tenantsplatform (github, bitbucket, atlassian, microsoft, google, slack), tenant key, owner side (company / client), client_id, how it was verified1m
NEW spacesspace ID (sp_ + short id), kind, address space:<kind>:<tenant>/<stable id> (unique per account), owner side and its basis, owner principal (person-owned only), client_id, status, created_by1m
NEW space_aliasesspace_id, alias kind (url, root_commits, jira_key, name, marker, path), normalised value; path aliases carry the owner principal and are visible only to that person1m
NEW space_linksspace_id → place (type, id), kind (same / declared / confirmed / suggested), confidence, evidence (jsonb), author, accepted_by, valid_from / valid_to, version1m
NEW space_rulesCompany mapping rules ("Bitbucket workspace pilot, project SHIP → project Shipping"); the existing place_mappings rows are migrated into aliases + declared links1m
NEW conversationsclient_app_id, principal, outside id (session_id, conversation_id, run id), tool and model labels, started / last seen, last cursor, last space; unique per (app, outside id)1l
NEW stretchesconversation_id, sequence number, space_id (or none), from / to, match evidence, confidence1n
NEW idempotency_keysprincipal, key, request hash, stored response, created_at (kept 24 h)1l
EXTEND memoriesspace_id, conversation_id, stretch_id, origin (explicit, checkpoint, memory_file, model_note, connector, promotion), routing_state (placed, pool, suggested), address jsonb (frozen stamp with a confidence per part, never rewritten), fields jsonb for typed kinds; new kinds: preference, decision, action_item, status_signal, procedure1l (columns), 1n, 1p
EXTEND sourcesspace_id, conversation_id, kind session_copy, cleaned text, content hash, thread key1n, 1p
NEW routing_decisionsmemory_id, candidates, chosen space, evidence (tag / mention / similarity), confidence, decided by (rule / person)1n
NEW view counts_towarditem → place through space links (current version at the item's time); aggregate functions only, minimum group 3, humans only1o
NEW index_cardssubject (person / place / space), version, lines with references, audience, built_at, pinned lines1n (v0), 1o
EXTEND settings / switchescapture_mode (off / review_first / auto_with_undo), allowed_ai_apps, source defaults per space kind, risk-notice records (M-105)1n, 1q
EXTEND principals + NEW worker_profileskind worker; master, backup, purpose, end date, spend / call limits, review date1r
NEW device_keyspersonal device keys (device flow), shown once, revocable, per device1q
Migration safety. Each migration is applied by the user from the copy file, as before (the session's classifier blocks this). The place_mappings move is copy-then-switch: 1m writes both, and 1n reads only spaces. The old table is dropped one stage later, after a count check.

7. API and MCP changes

InterfaceChangeStage
EnvelopeOne reader shared by REST and /mcp: headers X-CMCP-Place, X-CMCP-Space, X-CMCP-Conversation, X-CMCP-Run, X-CMCP-Cursor, Idempotency-Key, plus _meta["com.example.cmcp/envelope"]. If a header and _meta disagree, the call is refused. A declared org or user that differs from the sign-in is refused (Q-35 decision 16).1l
POST /v1/conversations, …/{id}/checkpoint, …/{id}/endStart returns the place, cards, manifest version and cursor. Checkpoint takes notes (each marked about=person / work, with an optional stretch tag) and the session copy, and returns where each note landed, the changes and a new cursor. Idempotent.1l (start / end), 1n (checkpoint routing)
GET /v1/changes?cursor=Built on change_events, filtered for the caller when it is read. Returns changed, removed and the new cursor. A cursor that is too old, or a permission change since the cursor (authz_epochs), returns 410: fetch the full context again.1l
GET /v1/review, POST /v1/memories/{id}/confirm | discardThe "To review" list for staged and auto-saved items. This fixes the stuck session summaries.1l
GET /v1/manifestManifest v2: the person's spaces with their recognisers and place paths, a version, and the person and place cards. Client spaces only when the person is assigned to that client.1n
POST /v1/spaces/resolveFingerprint (remotes, root commits, marker, Jira key) → space ID and confidence. An unknown space returns "ask once" choices.1n
/v1/spaces, /v1/spaces/{id}/links, /v1/space-rules, /v1/me/spaces, /v1/me/poolRegister, alias and link spaces (ADMIN / lead); the person's own spaces, confirmations and work pool1m, 1n
MCP toolsmemory_get_context returns cards and the manifest version. New space_link (answer to an ask-once question) and memory_checkpoint (for tools without hooks). memory_save accepts a space and the about flag. Built with the mcp-tool-pair skill; mcp-tools.json → 1.5.0, openapi → 1.8.0.1l–1n
Webhooks (signed)For bots: a "something changed" wake-up only; bots always pull from their cursor1q

8. The cmcp helper and hooks

Helper (Python, installed with uv tool, Q-35 decision 8)
  • cmcp login: reuses today's sign-in (the headersHelper pattern); device keys come in 1q.
  • cmcp status | link | pool: shows where you are and lets you answer ask-once questions.
  • cmcp hook <event>: one entry point for every tool's hooks.
  • Local cache in ~/.cmcp/: manifest, cursor, upload queue. Path aliases never leave the machine unless the person links them.
  • Fingerprint: remotes, root commits (git rev-list --max-parents=0), the .cmcp-space marker, Jira keys in branch names.
  • Secret scan before any upload. Text that came from cMCP is marked, so it is never saved back (echo filter).
Claude Code plugin (first tool)
SessionStart → manifest + cards + cursor into the session UserPromptSubmit → cursor check (< 20 ms if nothing changed); folder change → new stretch tag Stop / PreCompact → optional: ask the model for 0–5 notes (about=person|work), at most every ~20 min SessionEnd → hand off to the background uploader: notes + changed auto-memory files + session copy → checkpoint
Hooks are in bash and PowerShell. Cloud sessions get only hooks committed in the repo. Codex, Gemini CLI, Cursor and Copilot follow in 1q through the same cmcp hook.
Routing without the slow model. The tool's own model writes the notes and marks each one about the person or about the work. cMCP then routes by rules, strongest evidence first: (1) the stretch tag; (2) an explicit mention that matches a recogniser in the manifest (repo name, Jira key, path); (3) otherwise the note goes to the work pool. Similarity runs later in the worker and only adds a suggestion (1o). This keeps checkpoints fast on CPU and keeps decisions explainable in routing_decisions.

9. Stages

Each stage keeps the usual flow: threat model (threat-modeler, once) → build → tests → reviews by the custom agents → docs and manual → S-xx in todo.md → commit and push only after "S-xx: approved". Sizes are relative to stages 1h–1k (M ≈ one of those). Every stage is tested in synthetic accounts (test, other, owner-solo) only.

1l · Two-way base: envelope, conversations, change feed, To review size M

Builds on: change_events, REST headers, session summaries · Q-35 decisions 15–18
Exit test: a script bot runs start → saves (retried with the same key, no duplicates) → end. The next run gets only the changes since its cursor, including removals. A revoked grant gives 410, not stale data. Staged summaries can be confirmed.

1m · Space registry: company side size M–L

Builds on: place_mappings, connectors, places · Q-36 rollout step 1, decisions 3, 4, 8, 9, 21
Exit test: every company repo and Jira project has one space ID and a place. Two spellings of the same remote (SSH and HTTPS, with and without .git) and a mirror resolve to one space. A faked remote routes, but reads nothing without membership.

1n · People's side, first slice: manifest, helper, Claude Code capture, work pool size L

Builds on: 1l + 1m, User memory, approvals · Q-36 steps 2–3, Q-35 decisions 4, 5, 6, 10–13, 19 · M-105 for session copies
Exit test (the first visible proof): on this server, a Claude Code session in owner-solo works across two repos and a scratch folder. Items land in the right lanes and the work pool without anyone saving, and every item answers the seven questions. A second machine (or a second clone) gets the same space IDs. The ~24 outdated items from 2026-10-03 are replaced or marked by the imported memory files.

1o · Collective → organizational memory size M

Builds on: promotion pipeline (1d), cards · Q-36 step 4, decisions 5, 6, 15, 22–24
Exit test: three test people noting the same rule in their own lanes produce one promotion proposal. The lead approves it. Every linked app sees the new place card line on its next prompt. Two people produce no aggregate. Nothing crosses a client wall.

1p · Space knowledge v1: Jira, shared mailbox, first channel size L

Builds on: connectors, extract job, approvals · Q-36 step 5, decisions 17, 18, 20
Exit test: in a synthetic workspace, a quiet thread yields a decision and an action with source quotes. The lead approves the decision into the decision log. The action shows on the owner's person card. Deleting the source removes the derived records. Extraction stays on the local model for real accounts.

1q · Every surface: allowed apps, device keys, other tools, bot library size L

Q-35 stage 1n, decisions 3, 7, 9, 17, 20–22
Exit test: one session each in Claude Code, Codex and a scripted bot write to the same space with correct addresses. An app that is not allowed is refused for a real-style test account.

1r · Digital workers size M

Q-36 decisions 13–16
Exit test: a test worker reads #shipping, writes a status item marked AI, and can never approve, grant, read Personal memory or create another worker.
Later (not planned in detail yet): drives, OneDrive / SharePoint and Notion spaces; private channels with per-source audiences; topic and glossary index; bigger-model synthesis (procedures, cross-source entities) once a GPU or an approved cloud model exists; whole conversations under M-105; Phase 2 items (off-server backups, Bitbucket move, SSO / SCIM, deployment options Q-34).
The real account pilot. No stage switches it on. It joins only after 1q (allowed-apps list, review first) and after the company approves which AI apps may read company memory. Until then, the rule stays: tools that send text to a cloud model use synthetic accounts.

10. Quality, speed and measures

Speed targets (p95, on this host)
  • Per-prompt cursor check with nothing new: < 20 ms
  • Session start (manifest + cards): < 150 ms
  • Checkpoint accepted (routing by rules): < 300 ms; embedding and indexing in the background
  • Space resolve: < 50 ms
  • Existing targets unchanged: search < 100 ms, pack < 150 ms
Measures that show it works
  • Share of new items with a full address (target: 100 % for hook-captured items)
  • Items placed vs left in the work pool; pool items placed later
  • Automatic saves per active person per day (today: zero)
  • "To review" backlog and its age; share of items discarded (noise)
  • Promotions from collective memory, and how often organizational items are used
  • Stale items found and replaced

Reviews before any stage is called done: security, tenant isolation, db-schema, authz, audit-log, mcp-protocol, UI, licence and host-guard. retrieval-evaluator runs on 1n, 1o and 1p (routing and cards change what search returns).

11. Risks of this plan

RiskControl
Automatic capture brings noise (one public audit found 97.8 % junk in raw extraction)Curated inputs only (memory files and model notes), quality gate, review first, ageing, a measured discard rate
Aggregates or cards reveal one person's private itemMinimum group 3, humans only, Personal memory and the pool excluded, dedicated isolation tests, cards built per audience
Wrong link (a fork or mirror) routes items to the wrong placeAutomatic only at ≥ 0.95 (host id or root set); 0.8 asks first; links are versioned and items keep their address; routing never shares
Session copies and path aliases are personal dataOwner-only, 30 days, emptied like connector text; path aliases stay on the machine unless linked
Hooks differ per tool or don't run headless (not yet verified)Short spike at the start of 1n and 1q; the MCP tool memory_checkpoint is the fallback
Local 4B model too weak for long mail threadsRules first; per-message extraction with thread context; extractor version stored for re-extraction later
Scope grows again (as it did with Q-35)Each stage has one exit test; anything else goes to "Later"; stay centred on the space-mapping problem
Shared production host loadBackground jobs capped as today; host-change-check before any new container or connector

12. Decisions

Most questions were already answered with suggestions on the two research pages. This plan proposes taking those suggestions as they are, and asks only for what is new.

#QuestionSuggestion
N1Adopt this plan: extend, not rebuild, with stages 1l–1r in this order?Yes (proposal S-43)
N2Accept the suggested answers on the Q-35 page (decisions 1–13, 15–22) and the Q-36 paper (decisions 3–24) as written?Yes, in one approval, so stages don't wait on them one by one
N3First chat platform for space knowledge (1p): Microsoft Teams or Slack?The one the company actually uses for project talk. If both, Teams (Graph delta queries are well documented)
N4Lanes and organizational memory stored in the existing scopes (section 4), not in new tables?Yes
N5Typed space knowledge stored as memories with new kinds and a fields column, not as separate record tables?Yes: search, versioning, audit and RLS come free; add tables only if the kinds outgrow it
N6Company repo spaces from GitHub (IT-Labs-AJ) now, Bitbucket aliases added when the workspace exists?Yes: space IDs survive the move by design
N7When may pilot use any of this?After 1q and company approval of the allowed apps; never before
N8Drop place_mappings after the copy-then-switch in 1m / 1n?Yes, one stage after the switch, after a count check

13. Next steps

  1. The user reviews this plan and answers N1–N8 (or writes "S-43: approved" to take every suggestion).
  2. Threat model for 1l (envelope, cursor feed, idempotency, review list) with threat-modeler.
  3. Build 1l in repo/, with its PLAN.md under docs/stage-1l/. The user applies the migrations from the copy file.
  4. Short spikes due before 1m / 1n: whether GitHub repo ids stay stable after a rename; whether hooks run in Claude Code headless and cloud sessions; which MCP clients pass _meta.
  5. Update the whitepaper only minimally, once 1n proves the model works.

14. Stage 1u (set aside): first real use in pilot

Set aside 2026-10-11 · nothing built 2026-10-11

Set aside. The pilot on the company's server ends: the account's imported company data was cleared (connector, imported texts, notes and search index) and the account is now a test account. cMCP moves to IT-Labs' own hardware first (section 15). Stage 1u will be planned again for the new setup; its readiness report, onboarding, operations and measures still apply.
Why this stage, now. Stages 1h–1t are built and tested, but only in the synthetic accounts. The real account (pilot) has a Jira connector and little else. One day of real use already found what tests didn't: a browser that never reached the console, a sign-in code the helper hid, bot notes discarded by mistake with no way back, and a sign-in limit shared by the whole company. The pitch promised value for one real team before Phase 2. The cheapest way to learn whether spaces and automatic saving help is a few weeks of real use, measured, before packaging cMCP for other companies.

1u · First real use in pilot size M

Builds on: everything up to 1t · real-data rules: local model only, no cloud LLM, review first · the user plus 1–3 colleagues

A. A real account that is ready

B. Real people can start on their own

C. Operations that matter once data is real (the open go-live items)

D. Measures (a weekly report page, counts only, never memory text)

E. Carried over from 1t

Exit test (go / no-go for Phase 2): two or more people use Claude Code with the plugin in pilot on at least ten working days; the readiness report is green; a restore and a reboot succeeded; at least 60% of automatic notes are kept rather than discarded or aged (otherwise tune what is saved); at least one promotion suggestion accepted per active place each week, or a clear reason why not; no secret stored and no read across accounts or clients in the audit; answer quality on the real questions at least the synthetic baseline (23 of 24 in the top five).

What 1u does not do

No new memory features, no cloud model for real data, no packaging for other companies (that is Phase 2, Q-34). Anything the pilot shows is missing becomes a short follow-up or a Phase 2 item.

Decisions for 1u

#QuestionSuggestion
U1Next stage: first real use (1u), or start Phase 2 packaging (Q-34 option B) now?1u first: Phase 2 should follow real evidence
U2Who joins the pilot?The user and one to three colleagues who use Claude Code daily (the user names them)
U3Off-server encrypted backups: pull into 1u, or keep in Phase 2?Pull in: once the data is real, a server failure must not lose it
U4Connectors in pilot during the pilot?Jira only, as today; Microsoft 365, Google Drive and GitHub stay Phase 2 (decided 2026-10-02)
U5Allowed AI apps in pilot at the start?Claude Code (device keys) and the web console only
U6How long, and how is it reviewed?Three weeks, with the weekly report reviewed each week

To start: answer U1–U6, or write "S-45: approved" to take every suggestion. Then the threat model for 1u, the build, and the pilot.

15. Next: the move to IT-Labs hardware

Planned · on hold until the owner resumes it 2026-10-11

The web console (people, ADMINs and the web-admin) moves to IT-Labs' web server at cmcp.it-labs.in. The API, MCP endpoint, sign-in, database, search and the local AI model move to a new GPU server. Until that server is rented, the console uses the pilot server's API and sign-in addresses.

Done (2026-10-11)Result
Company data cleared from the pilot accountConnector with its stored secret, 568 imported texts, 5,344 notes with their history, the Jira space and 1,504 search entries removed; backup taken first; a reusable maintenance script that counts first and audits what it removes
IT-Labs web server checked and hardenedEvery installed package verified against its distribution's checksums; no sign of compromise; integrity scanners re-baselined (0 warnings); host firewall with an allow-list (23 of 23 outside checks passed, monitoring and proxy ports closed); the unused desktop turned off; the saved boot firewall, which would have blocked everything, replaced
Documents movedAll cMCP documents now at it-labs.in/cmcp/docs, hidden from search engines; GPU estimate added to the LLM results page

A · Restart the web server into its newer kernel on hold

B · The console at cmcp.it-labs.in on hold

Exit test: people sign in at cmcp.it-labs.in and use every screen against the pilot API; the other sites on that server answer exactly as before.

C · The stack on a GPU server (Hetzner GEX45) when rented

RTX PRO 4000 Blackwell SFF, 24 GB GDDR7 · Core i5-13500, 14 cores · 64 GB RAM · 2 × 512 GB NVMe · Helsinki · €214 a month + €209 setup, no minimum term
Exit test: the full test suites pass against the GPU server; extraction runs on the GPU; a restore from the off-server backup works.

Decisions for the move

#QuestionSuggestion
V1When may the web server restart?A quiet hour outside the hosted applications' busy times
V2Where does the web-admin live?Its own address (for example admin.cmcp.it-labs.in), reachable only from the owner's addresses or the VPN
V3The DNS record and the hosting-panel site for cmcp.it-labs.inYes, at the start of B
V4When to rent the GPU serverWhen B is stable; no minimum term
V5Rotate the web server's passwords and keys from its earlier incidentBefore other people use the console
V6The web server's operating system has reached end of lifePlan an upgrade or a new server; keep the console isolated until then