vantage-peers-mcp 2.19.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +112 -511
- package/README.md +213 -849
- package/dist/api.d.ts +4 -42
- package/dist/server-http.d.ts +1 -1
- package/dist/server-http.js +55 -56
- package/dist/src/auth.d.ts +238 -13
- package/dist/src/auth.js +457 -155
- package/dist/src/authenticatedConvexClient.d.ts +15 -11
- package/dist/src/authenticatedConvexClient.js +15 -11
- package/dist/src/normalizeOrchestratorId.d.ts +22 -2
- package/dist/src/normalizeOrchestratorId.js +22 -2
- package/dist/src/refusal.d.ts +4 -0
- package/dist/src/refusal.js +11 -0
- package/dist/src/registerTool.js +70 -3
- package/dist/src/tools/kbIngest.js +4 -0
- package/dist/src/tools.d.ts +13 -29
- package/dist/src/tools.js +268 -378
- package/dist/src/ui-resources/primitives/briefing-note.js +5 -0
- package/package.json +1 -2
- package/tool-exposure.json +13 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,636 +1,237 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [
|
|
3
|
+
## [3.0.0] — 2026-10-01
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Customer-facing summary of every `mcp-server/` change since 2.19.0 (commit `f718dd3`). Earlier releases are listed below.
|
|
6
|
+
|
|
7
|
+
### Breaking
|
|
6
8
|
|
|
7
|
-
-
|
|
9
|
+
- The `components` registry (six tools: `list_components`, `register_component`, `get_component`, `update_component`, `delete_component`, `search_components`) is removed, together with its entry in the `vantage-peers-mcp/api` type exports. These tools were not advertised to clients in 2.19.0.
|
|
10
|
+
- Two legacy credential types are no longer accepted: tokens from the retired dynamic-registration token store, and legacy internal tenant bearers. A request presenting either is refused with HTTP 401. OAuth access tokens issued by `/token` and Clerk session tokens are unaffected.
|
|
8
11
|
|
|
9
12
|
### Added
|
|
10
13
|
|
|
11
|
-
-
|
|
12
|
-
-
|
|
14
|
+
- `correct_task_segment`: narrow a recorded work span to its real boundaries, once, with a mandatory reason. The original span is kept for audit.
|
|
15
|
+
- Now available to clients: `whoami` (returns the identity attached to your own credential: agent name, scope profile, namespaces) and `generate_upload_url` (an upload URL for your own organisation's storage, used before `store_document_chunked`).
|
|
16
|
+
- Now available to clients: `fail_task` (a third terminal state, distinct from done and cancelled), `pause_task` and `resume_task` (stop and restart a task's work clock without ending it).
|
|
17
|
+
- Now available to clients: the fix-pattern tools `create_fix_pattern`, `get_fix_pattern`, `list_fix_patterns`, `search_fix_patterns`, `add_fix_attempt`, `validate_fix` and `link_issue_to_pattern`.
|
|
18
|
+
- `check_messages` reports how many in-progress tasks are stuck past the configured threshold on an open work segment, alongside the stuck list.
|
|
19
|
+
- `/health` publishes the agent-identity mode, where that mode comes from, and how many calls were served on a typed agent name without a credential.
|
|
13
20
|
|
|
14
|
-
### Security
|
|
21
|
+
### Security and fixes
|
|
15
22
|
|
|
16
|
-
-
|
|
23
|
+
- Agents act under the credential they present (`x-vantage-agent-credential`), not under a name typed into a tool argument. Names are compared after case and Unicode normalisation; accented and unaccented names stay distinct.
|
|
24
|
+
- A message's sender is checked against the verified caller: a caller from another organisation can no longer sign as one of your agents.
|
|
25
|
+
- `list_peers` surfaces a backend refusal as an explicit error instead of an empty list.
|
|
26
|
+
- A signed-in user with no organisation yet receives a typed refusal instead of the "invalid token" answer. An agent credential that does not resolve is refused as `AGENT_CREDENTIAL_INVALID` (HTTP 401), distinct from a lookup failure.
|
|
27
|
+
- Every refresh now returns a new refresh token, so a seat that keeps refreshing no longer expires at 30 days.
|
|
28
|
+
- Seat names are canonical and unique across organisations.
|
|
29
|
+
- The server no longer passes a privileged secret to the backend as a function argument; the backend authorises it by identity.
|
|
17
30
|
|
|
31
|
+
## Changes between 2.18.0 and 3.0.0 (some shipped in 2.19.0)
|
|
18
32
|
|
|
33
|
+
### Added
|
|
19
34
|
|
|
20
|
-
-
|
|
35
|
+
- `fail_task`: a third terminal task state, `failed`, distinct from `done` and `cancelled`, with a mandatory failure note. `update_task` cannot set `failed` or `blocked`; use `fail_task` and `block_task`.
|
|
36
|
+
- `block_task` accepts an optional `blockedCause` (`peer_task`, `human`, `authorisation` or `other`, default `other`) naming what the task is waiting on, and always returns it.
|
|
21
37
|
|
|
22
38
|
### Fixed
|
|
23
39
|
|
|
24
|
-
-
|
|
40
|
+
- `list_peers` and `list_mandates` no longer turn a backend refusal into an empty list. A refusal is returned as an error result that starts with `REFUSED (RBAC_DENIED)` and names the tool; a genuinely empty result is still `[]`.
|
|
41
|
+
- `check_messages` shows how many in-progress tasks are stuck past the configured threshold, and renders the stuck lists correctly against both older and newer backends.
|
|
42
|
+
|
|
43
|
+
### Security
|
|
44
|
+
|
|
45
|
+
- An identity named on a mission (pilot or agent), a mandate (requester or fulfiller) or a task (assignee) can read that record, while still being unable to read records it is not named on.
|
|
46
|
+
- Clerk session tokens are checked for the expected audience (`CLERK_JWT_AUDIENCE`, default `convex`), so a token minted for another audience is refused.
|
|
25
47
|
|
|
26
48
|
## [2.18.0] — 2026-08-11
|
|
27
49
|
|
|
28
50
|
### Changed
|
|
29
|
-
|
|
51
|
+
|
|
52
|
+
- The server advertises only its core tool set, listed in `tool-exposure.json`. The other tools stay in the code but are disabled: a client can neither list nor call them. The server refuses to start if that file names a tool that does not exist.
|
|
30
53
|
|
|
31
54
|
## [2.17.0] — 2026-08-11
|
|
32
55
|
|
|
33
56
|
### Removed
|
|
34
|
-
- 14 duplicate alias tools removed (mission `vp-mcp-alias-cleanup-v1`, S2, merged in #1169), keeping the fleet-used survivor of each pair — decided by call-site usage, never the code's `DEPRECATED ALIAS` label. Registered tool count 123→109. Context-token saving 1347 (11.1%) of the tool-list surface. Full list + arbitration in the root `CHANGELOG.md` and `elpi-corp/.../S1-arbitrated-pairs-day159.md`.
|
|
35
57
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
### Security
|
|
58
|
+
- 14 duplicate alias tools were removed; the canonical tool of each pair remains.
|
|
39
59
|
|
|
40
|
-
|
|
60
|
+
## Changes between 2.12.0 and 2.17.0
|
|
41
61
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
### Security
|
|
45
|
-
|
|
46
|
-
- **Scope `list_bus`/`get_bu`, `list_mandates`/`get_mandate` to their owner; move `list_errors`/`get_error` to master-only.** These six handlers fed `scopeFilterList`/`scopeFilterGet` rows whose shape carried neither `createdBy` nor `namespace`, so the guard refused **every** non-master caller including the owner (the refus-total form measured in the S0 campaign). Per-table remedy, decided by measurement: `businessUnits` is owned by `orchestratorId` → named remap to `createdBy` before the filter (the `list_broadcast_status` precedent); `mandates` has two owners `requestedBy`/`fulfilledBy` → dual remap unioned by `_id` (a single remap would hide one party's own mandates); `errorLogs` has no client owner (fleet-ops monitoring) → its `defineTool` scope becomes `{ kind: "master" }`, a structural removal from the client surface (non-master now gets an explicit Forbidden instead of a silent empty list). Per tool: RED (owner refused) → GREEN with owner/deny/master poles moving independently; 28 new tests + updated `scope-aware-filter-wave-c3`; full CI-scoped suite green, tsc + scope-typecheck exit 0. Class sweep found 8 further same-class instances (`get_profile`, `list_peers`, `list_issues`, `get_issue`, `issue_stats`, `list_repo_mappings`, `get_repo_mapping`, `get_message`) — tracked as a follow-up, out of this PR's named scope. Closes VP `k177617dqg6z5c099p1rdp5rqn8b2rp0`.
|
|
62
|
+
### Added
|
|
47
63
|
|
|
48
|
-
|
|
64
|
+
- Knowledge-base ingest: `store_document_chunked` (chunk and index a file previously uploaded to storage; returns `{ docId, chunkCount, storageId }`) and `soft_delete_document`. Both require an organisation-scoped Clerk session.
|
|
65
|
+
- Clerk session tokens carrying an organisation claim are verified against Clerk's published keys and scoped to that organisation's `team/<orgId>` namespace for reads and writes. A token for an organisation that is not registered is refused.
|
|
49
66
|
|
|
50
67
|
### Security
|
|
51
68
|
|
|
52
|
-
-
|
|
69
|
+
- `list_messages`, `search_messages_by_keyword`, `search_tasks_by_keyword`, `get_profile`, `list_peers`, `get_message`, `list_mandates` and `get_mandate` return only rows the caller owns or is a party to. Previously some of them refused every scoped caller, including the owner.
|
|
70
|
+
- Operations tools with no customer owner (error logs, issue tracking, repository mappings) are restricted to the service operator; other callers receive an explicit refusal instead of an empty list.
|
|
71
|
+
- Cross-organisation reads and writes in another team's namespace are refused.
|
|
53
72
|
|
|
54
73
|
## 2.14.2 — 2026-06-30
|
|
55
74
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
## [Unreleased]
|
|
59
|
-
|
|
60
|
-
### Added
|
|
61
|
-
|
|
62
|
-
- **B5 KB ingest MCP tools** — `store_document_chunked` and `soft_delete_document` registered via `mcp-server/src/tools/kbIngest.ts`. `store_document_chunked` accepts `storageId` + `mimeType` + `filename` (+ optional `docId`) and proxies to `kb:storeDocumentChunked`; returns `{ docId, chunkCount, storageId }`. `soft_delete_document` accepts `docId` and proxies to `kb:softDeleteDocument`; returns `{ docId, markedCount }`. Both tools require Clerk JWT with `org_id` — no anonymous access. Exported: `STORE_DOCUMENT_CHUNKED_TOOL_DESCRIPTION`, `storeDocumentChunkedArgsSchema`, `SOFT_DELETE_DOCUMENT_TOOL_DESCRIPTION`, `softDeleteDocumentArgsSchema`. Mission `k5779qbxhwrfjmj02t31yvehns8911jp`, task `k17bdmhr2hffhz2t96p65j70nh891wcp`.
|
|
63
|
-
|
|
64
|
-
## [Unreleased] — B4 RAG namespace team/<orgId> tenant enforcement
|
|
65
|
-
|
|
66
|
-
### Added
|
|
67
|
-
|
|
68
|
-
- **`team-member` scope profile** in `bearerAuthMiddleware` (layer 2.5): Clerk JWTs carrying an `org_id` claim are now verified against the Clerk JWKS (`CLERK_DOMAIN/.well-known/jwks.json`, cached 10 min) and resolve to `scopeProfile="team-member"` with `namespaceReadPrefixes=["team/<orgId>"]` and `namespaceWritePrefixes=["team/<orgId>"]`. Cross-tenant reads/writes are rejected by the existing `checkNamespaceRead` / `checkNamespaceWrite` predicates before any Convex call.
|
|
69
|
-
- **`convex/memoriesScoped.ts`**: new `listMemoriesScoped` (query) and `storeMemoryScoped` (mutation) Convex functions that enforce `team/<orgId>` namespace isolation at the Convex layer using `ctx.auth.getUserIdentity()`. Clerk callers with `org_A` cannot read or write `team/org_B/*`.
|
|
70
|
-
- **`jose`** (transitive, already present via `@modelcontextprotocol/sdk`) used for JWKS fetch and JWT verification. No new npm dep.
|
|
71
|
-
- **`CLERK_DOMAIN` env var**: override the Clerk instance domain (default `https://sharp-sponge-67.clerk.accounts.dev`).
|
|
72
|
-
|
|
73
|
-
### Security
|
|
74
|
-
|
|
75
|
-
- Architectural choice: **Option A** (direct Clerk JWT verification in bearer middleware) over Option B (DCR→Clerk join via Convex query). Rationale: Clerk JWTs are self-contained — no extra Convex round-trip needed. Option B would be required only if DCR clients were the sole entry point.
|
|
76
|
-
- Cross-tenant deny preserved for DCR `client-generic` (empty prefixes, unchanged) and unregistered orgs (fail-closed: `AUTH_NAMESPACE_DENIED`).
|
|
77
|
-
|
|
78
|
-
### Tests
|
|
75
|
+
### Fixed
|
|
79
76
|
|
|
80
|
-
- `
|
|
81
|
-
- `convex/__tests__/auth-namespace-deny.test.ts` — 9 convex-test tests verifying `AUTH_NAMESPACE_DENIED` for cross-tenant access at the Convex layer.
|
|
77
|
+
- OAuth dynamic client registration (`/register`) rejects a missing, empty or malformed `redirect_uris` with `invalid_redirect_uri` (RFC 7591).
|
|
82
78
|
|
|
83
79
|
## [2.12.0] — 2026-06-14
|
|
84
80
|
|
|
85
81
|
### Changed
|
|
86
|
-
- `check_messages` now calls `messages:checkNewMessagesEnvelope` (Convex PR #759 mergeCommit `c03023fc85463fe16fc53948d3002420bc1c4547`) for bounded tool-response size. New optional `limit` arg (1-50, default 20). When the call is truncated, the text payload appends `— truncated. Resume with check_messages since=<nextSince>` so the orchestrator can page the backlog cleanly without busting Claude Code's tool-response cap.
|
|
87
|
-
- `since` arg description amended with a "pair with `nextSince` from a previous truncated reply" hint.
|
|
88
|
-
|
|
89
|
-
### Notes
|
|
90
|
-
- Closes Pi BLOCKER VP task `k1702xaahb` (Day 102 — sigma-vps cron crash on a 36-message / 53 KB backlog).
|
|
91
|
-
- Legacy `messages:checkNewMessages` Convex query left intact for vp-mcp <2.12.0 callers (no break).
|
|
92
|
-
|
|
93
|
-
## [2.11.0] — 2026-06-14 — Day 102 CRUD baseline PR-C-bis option B: 3-entity Convex searchIndex (mission k575kc1ryps0n8br95jw3q7d0x88m2v9)
|
|
94
|
-
|
|
95
|
-
Mission `mcp-crud-baseline-standard` PR-C-bis under T2. Pi-sequenced follow-up after PR-C (rename-only safe subset) — implements **option B SCOPED** per Pi arbitrage msg `jn7abynmghy5qdr9ga0b914wmh88n99w` ("GO option B SCOPED — démarre PR-C avec 3 entités prioritaires"): tasks + messages + briefingNotes get native Convex BM25 search via `.searchIndex()` schema additions + per-entity Convex queries + MCP tool wrappers.
|
|
96
|
-
|
|
97
|
-
Backend choice (B over A): Convex native `.searchIndex()` is BM25-only, no embeddings, no RAG per-entity pipeline. Sub-linear scan stays in the same backend without spinning up an embedding pipeline per table. Hybrid/semantic per entity remains a future RFC.
|
|
98
|
-
|
|
99
|
-
### Added — Convex schema searchIndex (3 tables)
|
|
100
|
-
|
|
101
|
-
- `tasks` → `searchIndex("search_title", { searchField: "title", filterFields: ["assignedTo", "status", "project", "missionId", "orgId"] })`
|
|
102
|
-
- `messages` → `searchIndex("search_content", { searchField: "content", filterFields: ["from", "channel", "sessionDay", "tenantId"] })`
|
|
103
|
-
- `briefingNotes` → `searchIndex("search_content", { searchField: "content", filterFields: ["topic", "createdBy", "orgId"] })`
|
|
104
|
-
|
|
105
|
-
### Added — Convex query functions
|
|
106
|
-
|
|
107
|
-
- `tasks:searchTasksByKeyword` — BM25 over title with assignedTo/status/project/missionId filters + scope gate via `withOrgScope` + `filterByOrgScope` + `requireScope("view-own-tasks")`. Lite/full projection.
|
|
108
|
-
- `messages:searchMessagesByKeyword` — BM25 over content with from/channel/sessionDay/tenantId filters.
|
|
109
|
-
- `briefingNotes:searchBriefingNotesByKeyword` — BM25 over content with topic/createdBy filters.
|
|
110
|
-
|
|
111
|
-
All three: 20-item default limit, 200 cap, lite projection on demand.
|
|
112
|
-
|
|
113
|
-
### Added — MCP tool wrappers (3 canonical)
|
|
114
|
-
|
|
115
|
-
- **`search_tasks_by_keyword`** — wires to `tasks:searchTasksByKeyword`. `readOnlyHint=true`.
|
|
116
|
-
- **`search_messages_by_keyword`** — wires to `messages:searchMessagesByKeyword`. `readOnlyHint=true`.
|
|
117
|
-
- **`search_briefing_notes_by_keyword`** — wires to `briefingNotes:searchBriefingNotesByKeyword`. `readOnlyHint=true`.
|
|
118
|
-
|
|
119
|
-
### Why option B (and why scoped to 3)
|
|
120
|
-
|
|
121
|
-
`grep searchIndex convex/schema.ts` previously returned zero hits; only `memories` had search infrastructure (via `@convex-dev/rag`). The original "13-entity cluster" full scope was deferred via PR-C (rename-only) after arbitrage timeout. Pi's arbitrage landed shortly after: **option B SCOPED to 3 priority entities** is the right blend of doctrine progress + bounded scope:
|
|
122
|
-
- `tasks` — largest fleet audience (Eta T13 close-issue scan, dispatch-task-find, etc.).
|
|
123
|
-
- `messages` — post-incident audit + messages-history skill demand.
|
|
124
|
-
- `briefingNotes` — daily snapshot recall narrative.
|
|
125
|
-
|
|
126
|
-
The remaining 10 entities (mission/mandate/fix_pattern/component/repo_mapping/bu/profile/deployment/diary/error/issue/recurring_task/summary) go to a per-entity RFC (mission walk-through scheduled Wed 17 June 15h with Laurent) — each entity decides B (searchIndex), A (RAG if semantic justified, e.g. episodes/diary), or N/A semantic documented (deployment/repo_mapping).
|
|
127
|
-
|
|
128
|
-
### Version sync
|
|
129
|
-
|
|
130
|
-
- `mcp-server/server.ts:115` SERVER_VERSION 2.10.0 → 2.11.0
|
|
131
|
-
- `mcp-server/package.json` → 2.11.0
|
|
132
|
-
- README + 4 cloud docs bumped to 2.11.0 markers (`enforce-release-sync` v1.0.1 gate).
|
|
133
|
-
|
|
134
|
-
### Test fixture catch-up
|
|
135
|
-
|
|
136
|
-
- `READ_ONLY_TOOLS` set in `mcp-server/src/__tests__/chatgpt-tool-annotations.test.ts` extended with the 3 new canonical tool names.
|
|
137
|
-
|
|
138
|
-
### Refs
|
|
139
|
-
|
|
140
|
-
- Mission `k575kc1ryps0n8br95jw3q7d0x88m2v9`.
|
|
141
|
-
- Pi sequencing dispatch: msg `jn76360ckrrkwpqbfwa6tst7k588mpsh` ("(1) T2 PR-C-bis option B SCOPED 3 entities").
|
|
142
|
-
- Pi arbitrage that selected option B: msg `jn7abynmghy5qdr9ga0b914wmh88n99w`.
|
|
143
|
-
- Audit T1: `analysis/mcp-crud-baseline-vp-audit-2026-06-14.md` rows 1 (task), 3 (message), 4 (briefing_note).
|
|
144
|
-
- Doctrine memory: `j57dhrmkzjerjtssnr0z9ba57n88n7q7` (5 ops per entity).
|
|
145
|
-
- Predecessors: PR-A 2.8.0 (memories canonical), PR-B 2.9.0 (episode 5-op), PR-C 2.10.0 (rename-only safe subset).
|
|
146
|
-
|
|
147
|
-
## [2.10.0] — 2026-06-14 — Day 102 CRUD baseline PR-C: rename-only safe subset (mission k575kc1ryps0n8br95jw3q7d0x88m2v9)
|
|
148
|
-
|
|
149
|
-
Mission `mcp-crud-baseline-standard` PR-C under T2. Third of 4 sub-PRs aligning the MCP surface with the Day 101 doctrine `j57dhrmkzjerjtssnr0z9ba57n88n7q7`. Sigma autonomous default after arbitrage timeout on the original "13-entity search_by_keyword cluster" scope — that fuller scope requires a backend search-infrastructure decision (RAG-index per entity vs Convex `.searchIndex()` per table) that is NOT a thin-wrapper PR. PR-C ships the rename-only safe subset now to keep doctrine velocity; the full cluster is deferred to a backend-RFC mission.
|
|
150
|
-
|
|
151
|
-
### Added (2 canonical search tools)
|
|
152
|
-
|
|
153
|
-
- **`search_components_by_keyword`** — BM25 / substring search over components by name or team. Wire-identical to `search_components` (same Convex query `components:search` 1:1, same scope filter, same defaults). `readOnlyHint=true`.
|
|
154
|
-
- **`search_fix_patterns_by_semantic`** — semantic embedding-similarity search over fix patterns. Wire-identical to `search_fix_patterns` (same Convex action `search:searchFixPatterns` 1:1, same scope filter, same defaults). `readOnlyHint=true`. Note: the canonical suffix is `_by_semantic` (NOT `_by_keyword`) because the underlying ranker is embedding-cosine, not BM25 — naming follows behavior, not entity convention.
|
|
155
|
-
|
|
156
|
-
### Deprecated (alias-only, removal target 2.11.0)
|
|
157
|
-
|
|
158
|
-
- **`search_components`** — alias of `search_components_by_keyword`. Description leads with `DEPRECATED ALIAS …`.
|
|
159
|
-
- **`search_fix_patterns`** — alias of `search_fix_patterns_by_semantic`. Description leads with `DEPRECATED ALIAS …`.
|
|
160
|
-
|
|
161
|
-
### Re-targeted deprecations (FOLLOW-UP from Eta PR #750 review)
|
|
162
|
-
|
|
163
|
-
- **`text_search`** — 2.8.0 originally targeted removal at 2.9.0; episode-only PR-B did not include the removal. Source comments + this entry re-target removal to **2.11.0**.
|
|
164
|
-
- **`recall`** — same re-target rationale, removal now **2.11.0**.
|
|
165
|
-
|
|
166
|
-
Both `text_search` and `recall` remain wire-identical to their canonical successors (`search_memories_by_keyword` / `search_memories_by_semantic`). Closes FOLLOW-UP task `k1754apqtcjpre2vd5ghbkcmzn88mhwf`.
|
|
167
|
-
|
|
168
|
-
### Scope NOT in this PR (deferred)
|
|
169
|
-
|
|
170
|
-
The original PR-C "13-entity search_by_keyword cluster" required adding BM25 / search infrastructure to 10+ entities that currently have NO backend search index (`grep searchIndex convex/schema.ts` → zero hits; only `memories` is indexed, via `@convex-dev/rag`). Two backend paths exist:
|
|
171
|
-
|
|
172
|
-
- **Path A** — extend RAG indexing to each entity (heavy: per-table embedding pipeline, RAG namespace per entity, vector cost; gets hybrid search for free).
|
|
173
|
-
- **Path B** — Convex native `.searchIndex()` per table (lightweight: schema migration + one query per entity, BM25-only, no embeddings).
|
|
174
|
-
|
|
175
|
-
Either path is a multi-day backend RFC, NOT a thin-wrapper PR. Sigma sent the arbitrage to Pi (msg `jn75zy4g7bhj95bhyz2zvv6n8d88na6s`) and defaulted to PR-C path C (rename-only) after 2 cron ticks of no reply. A follow-up mission to scope the backend search infrastructure is the next mission proposal.
|
|
176
|
-
|
|
177
|
-
### Version sync
|
|
178
|
-
|
|
179
|
-
- `mcp-server/server.ts:115` SERVER_VERSION 2.9.0 → 2.10.0
|
|
180
|
-
- `mcp-server/package.json` → 2.10.0
|
|
181
|
-
- README + 4 cloud docs bumped to 2.10.0 markers (`enforce-release-sync` v1.0.1 gate).
|
|
182
|
-
|
|
183
|
-
### Test fixture catch-up
|
|
184
|
-
|
|
185
|
-
- `READ_ONLY_TOOLS` set in `mcp-server/src/__tests__/chatgpt-tool-annotations.test.ts` extended with the 2 new canonical names.
|
|
186
|
-
|
|
187
|
-
### Refs
|
|
188
|
-
|
|
189
|
-
- Mission `k575kc1ryps0n8br95jw3q7d0x88m2v9` (MCP CRUD Baseline Standard).
|
|
190
|
-
- Pi authorization msg `jn74q7twhr3s1s8dvqxbzvky9588msdd` ("next: T2-PR-C 13-entity search_by_keyword cluster post #750 merge").
|
|
191
|
-
- Sigma arbitrage msg to Pi: `jn75zy4g7bhj95bhyz2zvv6n8d88na6s` (3 paths A/B/C).
|
|
192
|
-
- FOLLOW-UP task: `k1754apqtcjpre2vd5ghbkcmzn88mhwf` (text_search/recall deprecation slipped).
|
|
193
|
-
- Audit T1: `analysis/mcp-crud-baseline-vp-audit-2026-06-14.md` § 4.
|
|
194
|
-
|
|
195
|
-
## [2.9.0] — 2026-06-14 — Day 102 CRUD baseline PR-B: episode entity 5-op surface (mission k575kc1ryps0n8br95jw3q7d0x88m2v9)
|
|
196
|
-
|
|
197
|
-
Mission `mcp-crud-baseline-standard` PR-B under T2. Second of 4 sub-PRs aligning the MCP surface with the Day 101 doctrine `j57dhrmkzjerjtssnr0z9ba57n88n7q7` ("5 ops per entity"). PR-B adds the missing read/list/search facades for the `episode` entity, completing the 5-op surface (the write side `store_episode` already existed since the 8-Sins doctrine).
|
|
198
|
-
|
|
199
|
-
Architectural note: episodes are NOT a separate Convex table — per hotfix `7f958d0`, episodes are stored as memories with `type='episode'` (context/goal/action/outcome/insight + severity). The 4 new tools are thin wrappers that force `type='episode'` on the existing `memories:*` / `search:*` actions, so callers get an ergonomic episode-scoped surface without introducing a new backend table or duplicating index logic.
|
|
200
|
-
|
|
201
|
-
### Added (4 canonical episode tools)
|
|
202
|
-
|
|
203
|
-
- **`get_episode`** — fetch a single episode by memory ID. Calls `memories:getMemory` then asserts the returned row has `type='episode'`; otherwise returns a non-leaky "Episode not found" so wrong-type IDs do not leak existence of non-episode memories. Scope-aware via `scopeFilterGet`. Annotations: `readOnlyHint=true`, `openWorldHint=false`, `destructiveHint=false`.
|
|
204
|
-
- **`list_episodes`** — list episodes ordered newest first. Calls `memories:listMemories` with `type='episode'` forced. Accepts `namespace?`, `createdBy?`, `limit?`, `fields?`, `cursor?` — same paging semantics as `list_memories`. Scope-aware via `scopeFilterList`. Envelope-capped via `capListResponseBytes("list_episodes")`.
|
|
205
|
-
- **`search_episodes_by_keyword`** — BM25 search restricted to episodes. Calls `search:textSearch` with `type='episode'` forced. Same `guardRead` namespace gate, same 20-default / 200-cap limits.
|
|
206
|
-
- **`search_episodes_by_semantic`** — semantic vector cosine search restricted to episodes. Calls `search:recall` with `type='episode'` forced. Same gate, same limits.
|
|
207
|
-
|
|
208
|
-
All four are pure MCP-layer additions: no Convex schema change, no new index, no new action. tsc clean.
|
|
209
|
-
|
|
210
|
-
### Why
|
|
211
|
-
|
|
212
|
-
Episode = the 8-Sins / orchestrator-introspection memory type (severity + context/goal/action/outcome/insight). Until 2.9.0, recalling past episodes required `recall query='...' type='episode'` — discoverable only to callers who already knew the memory-side filter trick. Surfacing dedicated wrappers makes the episode lifecycle (write via `store_episode`, read via `get_episode`, browse via `list_episodes`, recall via the two search ops) consistent with the doctrine and self-documenting in any MCP client's tool list.
|
|
213
82
|
|
|
214
|
-
`
|
|
83
|
+
- `check_messages` returns a bounded page of messages. New optional `limit` (1–50, default 20). When more messages are waiting, the reply ends with the `since` value to pass on the next call.
|
|
215
84
|
|
|
216
|
-
|
|
85
|
+
## [2.11.0] — 2026-06-14
|
|
217
86
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
### Refs
|
|
221
|
-
|
|
222
|
-
- Mission `k575kc1ryps0n8br95jw3q7d0x88m2v9` (MCP CRUD Baseline Standard, pilot Sigma + agents Sigma + Eta).
|
|
223
|
-
- Pi authorization msg `jn74v2pkfz08agex4nfm2yfvfd88nzdw` — "chain T2 PR-B episode entity en autonomie scope mission".
|
|
224
|
-
- Audit T1 deliverable: `analysis/mcp-crud-baseline-vp-audit-2026-06-14.md` row 7 (episode entity recommendation: add façade wrappers).
|
|
225
|
-
- Architecture: hotfix `7f958d0` — episodes are memories with metadata, not a separate table.
|
|
226
|
-
|
|
227
|
-
## [2.8.0] — 2026-06-14 — Day 101 CRUD baseline PR-A: search_memories_by_keyword + search_memories_by_semantic (mission k575kc1ryps0n8br95jw3q7d0x88m2v9, task k1735qk9kx6agjjyt3e38rdvvh88mk0p)
|
|
228
|
-
|
|
229
|
-
Mission `mcp-crud-baseline-standard` PR-A under T2 `[CRUD-T2] Implémentation gaps VP MCP`. First of 4 sub-PRs aligning the MCP surface with the Day 101 doctrine `j57dhrmkzjerjtssnr0z9ba57n88n7q7` ("5 ops per entity: get / list / search_by_keyword / search_by_semantic / create-or-upsert"). PR-A handles the convention drift on the `memories` entity — the only entity that already had both keyword + semantic search wired, but under non-canonical names.
|
|
230
|
-
|
|
231
|
-
### Added (canonical names)
|
|
232
|
-
|
|
233
|
-
- **`search_memories_by_keyword`** — BM25 full-text search over memories, identical wire to `text_search`. Calls `search:textSearch` Convex action 1:1, same params (`query`, `namespace?`, `type?`, `limit?`, `fields?`), same `guardRead` namespace gate, same 20-item default limit + 200 cap, same `mcpConvexError` error surface (2.7.1 sweep). Annotations: `readOnlyHint=true`, `openWorldHint=false`, `destructiveHint=false`, title `"Search memories by keyword (BM25)"`.
|
|
234
|
-
- **`search_memories_by_semantic`** — semantic vector cosine search over memories, identical wire to `recall`. Calls `search:recall` Convex action 1:1, same params, same gate, same defaults. Annotations: `readOnlyHint=true`, `openWorldHint=false`, `destructiveHint=false`, title `"Search memories by semantic (vector cosine)"`.
|
|
235
|
-
|
|
236
|
-
### Deprecated (alias-only, one minor window)
|
|
237
|
-
|
|
238
|
-
- **`text_search`** — alias of `search_memories_by_keyword`. Description now leads with `DEPRECATED ALIAS`, source comment marks it for removal in `2.9.0`. Wire unchanged — existing callers continue to work for one minor.
|
|
239
|
-
- **`recall`** — alias of `search_memories_by_semantic`. Description now leads with `DEPRECATED ALIAS`, source comment marks it for removal in `2.9.0`. Wire unchanged.
|
|
240
|
-
|
|
241
|
-
### Why
|
|
242
|
-
|
|
243
|
-
Per mission `k575kc1r` brief + Pi arbitrage `jn77rpx2msfy2v174sdqyjzp6n88m9bw` Q4 (RENAME CLEAN, optional one-minor dual-emit buffer if Sigma judges useful): the legacy `text_search` / `recall` pair predates the Day 101 CRUD baseline naming convention. Other entities will gain `search_<entity>s_by_keyword` / `search_<entity>s_by_semantic` in PR-C (cluster of 13) and PR-D (vectorIndex add for briefing_notes + diary). Aligning the `memories` entity FIRST means PR-C/D ship into a fleet that already understands the new naming, and skill / plugin / docs propagation (T-SKILLS, T-PLUGIN, T-DOC) has a single canonical truth to follow.
|
|
244
|
-
|
|
245
|
-
`hybrid_search` is intentionally NOT renamed — it remains a cross-cutting RRF-fusion tool, not entity-scoped, per the audit `analysis/mcp-crud-baseline-vp-audit-2026-06-14.md` § 4.
|
|
246
|
-
|
|
247
|
-
### Refs
|
|
248
|
-
|
|
249
|
-
- Mission `k575kc1ryps0n8br95jw3q7d0x88m2v9` (MCP CRUD Baseline Standard, pilot Sigma + agents Sigma + Eta).
|
|
250
|
-
- Task T2 `k1735qk9kx6agjjyt3e38rdvvh88mk0p`.
|
|
251
|
-
- Audit T1 deliverable: `analysis/mcp-crud-baseline-vp-audit-2026-06-14.md` (140 lines, 53 table rows).
|
|
252
|
-
- Doctrine memory: `j57dhrmkzjerjtssnr0z9ba57n88n7q7` (5 ops per entity).
|
|
253
|
-
- Pi Q4 arbitrage: msg `jn77rpx2msfy2v174sdqyjzp6n88m9bw`.
|
|
254
|
-
|
|
255
|
-
## [2.7.1] — 2026-06-14 — Day 101 FIX-B mcpError() → mcpConvexError() sweep (task k1744wk2gfgqt2gdqh41d4r91h88n410)
|
|
256
|
-
|
|
257
|
-
Patch-level fix to make every tool wrapper surface structured ConvexError
|
|
258
|
-
diagnostics instead of opaque `"Server Error [Request ID: ...]"` strings.
|
|
259
|
-
|
|
260
|
-
**Problem (Day 101):** when a Convex mutation/query threw a `ConvexError`
|
|
261
|
-
(e.g. `TASK_START_BLOCKED`, `COMPLETION_NOTE_REQUIRED`) or an
|
|
262
|
-
`ArgumentValidationError`, the tool wrapper called
|
|
263
|
-
`mcpError(error.message ?? String(error))` which returned a plain
|
|
264
|
-
`Error: <message>` text payload. The MCP client (Claude Code) then often
|
|
265
|
-
re-displayed this as a generic `Server Error [Request ID:...]`, masking the
|
|
266
|
-
actual root cause and triggering misdiagnosis sprees (Pi msg
|
|
267
|
-
`jn7c5tfj0347vaenyqgrezehk188mr11` mistakenly attributed the symptoms to
|
|
268
|
-
a backend regression that did not exist — see Sigma report msg
|
|
269
|
-
`jn773p8qnfp6ycb1f7gajhs8vn88m11a`).
|
|
270
|
-
|
|
271
|
-
**Fix:** sweep all 99 occurrences of
|
|
272
|
-
`return mcpError(error.message ?? String(error))` →
|
|
273
|
-
`return mcpConvexError(error)`. The `mcpConvexError` helper (already
|
|
274
|
-
present at `src/tools.ts:535`, shipped 2.4.x) parses ConvexError messages
|
|
275
|
-
into a structured JSON `{ code, message, path, hint }` payload that
|
|
276
|
-
surfaces the actual error code (`ArgumentValidationError`,
|
|
277
|
-
`ConvexError`, `AuthorizationError`, `SchemaValidationError`, etc.)
|
|
278
|
-
along with a path and a concise hint for ID-table mismatches.
|
|
279
|
-
|
|
280
|
-
Total counts post-sweep: `grep mcpConvexError(` → 102 ; `grep
|
|
281
|
-
mcpError(error.message` → 0.
|
|
282
|
-
|
|
283
|
-
Type check: `npx tsc --noEmit` exits 0.
|
|
284
|
-
|
|
285
|
-
Mission/refs: `k575kc1ryps0n8br95jw3q7d0x88m2v9` MCP CRUD Baseline Standard,
|
|
286
|
-
task FIX-B `k1744wk2gfgqt2gdqh41d4r91h88n410`. Co-shipped with hook
|
|
287
|
-
`enforce-friction-field.py` v1.1.0 STDERR clarification (Day 101 task
|
|
288
|
-
FIX-A `k17ads7kh7qk7yxgfe0dh73ggx88ny9f`).
|
|
289
|
-
|
|
290
|
-
## [2.7.0] — 2026-06-13 — Day 100 get_by_id surface Phase 2b (task k172735brsw6bc3j2dkkkfxqrx88kkjq)
|
|
291
|
-
|
|
292
|
-
Phase 2b wires 2 MCP wrappers calling the Phase 2a Convex queries deployed
|
|
293
|
-
in commit 2ebdaba (PR #735 + hotfix 7f958d0):
|
|
294
|
-
|
|
295
|
-
- **get_message** — `messages:getById` plumbing. Fetch full message row by
|
|
296
|
-
Convex doc ID (channel, sender, sessionDay, tenant scope) for read-receipt
|
|
297
|
-
audit, delete confirmation, or fix-pattern referencing.
|
|
298
|
-
- **get_recurring_task** — `recurringTasks:getById` plumbing. Fetch
|
|
299
|
-
recurring task definition (cron schedule, prompt, assignee, last-fire
|
|
300
|
-
metadata) before pause/update/delete.
|
|
301
|
-
|
|
302
|
-
Both follow the existing `get_memory` / `get_briefing_note` pattern:
|
|
303
|
-
`scopeFilterGet(oauthCtx, row)` for scope-aware cross-tenant collapse,
|
|
304
|
-
read-only annotations.
|
|
305
|
-
|
|
306
|
-
**get_episode** was DROPPED from Phase 2b scope: episodes are stored as
|
|
307
|
-
memories with episode metadata (no separate `episodes` table in
|
|
308
|
-
`convex/schema.ts`). Use existing `get_memory` to fetch episode rows by
|
|
309
|
-
their memory document ID. Hotfix 7f958d0 removed the invalid
|
|
310
|
-
`episodes:getById` query that broke `convex deploy` typecheck.
|
|
311
|
-
|
|
312
|
-
Phase 2a CHANGELOG entry deferred — Convex changes shipped in main repo
|
|
313
|
-
CHANGELOG, not mcp-server.
|
|
314
|
-
|
|
315
|
-
Total MCP `get_*` tools after Phase 2b: 16 (was 14 after Phase 1, 10 before
|
|
316
|
-
Day 100 task).
|
|
317
|
-
|
|
318
|
-
## [2.6.0] — 2026-06-13 — Day 100 get_by_id surface Phase 1 (task k172735brsw6bc3j2dkkkfxqrx88kkjq)
|
|
319
|
-
|
|
320
|
-
Pi reported get_<entity>_by_id MCP surface gaps observed during Day 100 fleet ops.
|
|
321
|
-
Phase 1 adds 4 plumbing-only read tools mapping to pre-existing Convex queries:
|
|
322
|
-
|
|
323
|
-
- **get_task** — `tasks:getById` plumbing. Fetch full task record (description, dependsOn,
|
|
324
|
-
missionId, completionNote, claimedByInstance, startedAt) by Convex doc ID.
|
|
325
|
-
- **get_fix_pattern** — `fixPatterns:get` plumbing. Fetch fix pattern with full linked
|
|
326
|
-
fix attempts history.
|
|
327
|
-
- **get_mandate** — `mandates:get` plumbing. Fetch spending mandate with limits, current
|
|
328
|
-
spend, approver chain for validateSpending/settleMandate pre-checks.
|
|
329
|
-
- **get_repo_mapping** — `githubRepoMapping:getByRepo` plumbing. Fetch GitHub repo→VP project
|
|
330
|
-
mapping by repo slug.
|
|
331
|
-
|
|
332
|
-
All 4 tools apply `scopeFilterGet(oauthCtx, row)` for scope-aware cross-tenant collapse,
|
|
333
|
-
mirroring the existing `get_memory` / `get_briefing_note` pattern (Day 92 S3.1 wave).
|
|
334
|
-
|
|
335
|
-
Annotations test (chatgpt-tool-annotations.test.ts) READ_ONLY_TOOLS set extended with
|
|
336
|
-
the 4 new tools. Pre-existing 84/97 count mismatch in same test is unrelated (separate
|
|
337
|
-
F-list track).
|
|
338
|
-
|
|
339
|
-
Phase 2 (follow-on PR) will add get_message / get_episode / get_recurring_task
|
|
340
|
-
(Convex query additions required).
|
|
341
|
-
Phase 3 (separate mission) will audit deployment entity (table+queries+tool) and the
|
|
342
|
-
cross-backend cloud proxy redeploy cadence.
|
|
343
|
-
|
|
344
|
-
## [2.5.0] — 2026-06-06 — Day 92 VP MCP quality overhaul (mission k57a36y8)
|
|
345
|
-
|
|
346
|
-
Day 92 mission `k57a36y8w5t085bqr23dsmvb2d882506` ships a fleet-wide VP MCP quality bump
|
|
347
|
-
across audit, docs, hooks, security, and consistency dimensions. 15 PRs merged to main.
|
|
348
|
-
|
|
349
|
-
### Phase A — Audit + new tools
|
|
350
|
-
- **A1** Day 92 VP MCP tools audit matrix (85 tools, 14 P0 zero-auth gaps) — `docs/test-reports/day92-vp-mcp-audit-matrix.md`.
|
|
351
|
-
- **A2** Consistency analysis report — `docs/test-reports/day92-vp-mcp-consistency-analysis.md`.
|
|
352
|
-
- **A3** New `whoami` LECTURE tool — first per-tool `outputSchema` export precedent.
|
|
353
|
-
- **A4** Consolidated gap matrix — `docs/test-reports/day92-vp-mcp-gap-matrix-consolidated.md`.
|
|
354
|
-
|
|
355
|
-
### Phase B — Documentation
|
|
356
|
-
- **B1** `docs/cloud/security-multi-tenant.md` §4 scope-aware filter framework rewrite.
|
|
357
|
-
- **B2** `docs/cloud/tools-quality-standard.md` (NEW) — 12-section bilingual quality standard.
|
|
358
|
-
- **B3** `docs/cloud/onboarding-customer.md` (NEW) — customer onboarding guide (bilingual FR+EN).
|
|
359
|
-
|
|
360
|
-
### Phase C — Consistency
|
|
361
|
-
- **C0** 14 P0 zero-auth write tools secured with `guardMasterOnly` (C0.1 → C0.6, 6 PRs).
|
|
362
|
-
- **C1** 87 Zod `outputSchema` exports per per-family envelope standard (B2 §3).
|
|
363
|
-
- **C2** Orchestrator-id NFC normalization + case-insensitive matching; idempotent prod migration `convex/migrations/c2-normalize-orchestrator-ids.ts` (7 tables).
|
|
364
|
-
- **C3** 97 tool descriptions standardized + 10 canonical aliases gated through `guardMasterOnly` (security regression fixed in iter 2) + alias-c0-gate-coverage test (15/15 PASS).
|
|
365
|
-
- **C4** Legacy `claude-peers` references removed repo-wide + `grep-gate` CI workflow.
|
|
366
|
-
|
|
367
|
-
### Phase F — Hooks + plugin
|
|
368
|
-
- **F1** New consolidated `validate_task_payload` MCP tool + TypeScript validator library (replaces 5 single-axis hooks).
|
|
369
|
-
- **F2** Plugin propagation runbook + `plugin-vs-workspace-hooks.md` doctrine.
|
|
370
|
-
|
|
371
|
-
### Scope-aware filtering
|
|
372
|
-
- `list_tasks` `fromAllowList[]` + case-insensitive matching (PR #654, #661).
|
|
373
|
-
- 3 admin endpoints reinstated for Nadia cohort (prior session).
|
|
87
|
+
### Added
|
|
374
88
|
|
|
375
|
-
|
|
376
|
-
- Persistent test tenant trio (alpha/beta/gamma) seeded on prod with bearers, scope_profiles, and seed data for cross-orchestrator E2E.
|
|
89
|
+
- Keyword (BM25) search over tasks, messages and briefing notes: `search_tasks_by_keyword`, `search_messages_by_keyword`, `search_briefing_notes_by_keyword`. Default 20 results, maximum 200, compact projection available.
|
|
377
90
|
|
|
378
|
-
|
|
379
|
-
- `PI_AUTHORIZED_TASK_ID=k1751nfs27t9f9mpvg3ppd6xad884r59` (Day 82 doctrine).
|
|
380
|
-
- Mission: `k57a36y8w5t085bqr23dsmvb2d882506`.
|
|
381
|
-
- Branch: `release/v2.5.0` opened against `main` at HEAD `18a5530`.
|
|
91
|
+
## [2.10.0] — 2026-06-14
|
|
382
92
|
|
|
383
|
-
|
|
93
|
+
### Added
|
|
384
94
|
|
|
385
|
-
|
|
95
|
+
- `search_components_by_keyword` and `search_fix_patterns_by_semantic` as the canonical names of `search_components` and `search_fix_patterns`.
|
|
386
96
|
|
|
387
|
-
|
|
97
|
+
### Deprecated
|
|
388
98
|
|
|
389
|
-
|
|
390
|
-
- `mcp-server/package.json`: author restructured to "VantageOS AI Orchestrator Team" with contributors block (Pi, Laurent Perello, ElPi Corp). Dependency `@vantageos/mosaic@^0.1.2` added for Phase 1 Mosaic groundwork (PR #605, server-side createMosaicResource API ready for Phase 2 primitive swap).
|
|
391
|
-
- `mcp-server/CHANGELOG.md`: version headers simplified to `X.Y.Z — YYYY-MM-DD` (Day N anchors dropped per Laurent verdict 2026-06-02 — dates are self-explanatory, day numbers added noise). Narrative client-name mentions (Nadia/<client-org>/Cédric Delport) genericized to "early-access RH cohort" / "self-host incident" per RULE #7 pre-public scrub.
|
|
392
|
-
- Root README rework (PR #611 + PR #610 + PR #616 chain): TL;DR + Mermaid architecture diagram + 5 hero features + 22-features collapsed details + 84-tools 8-groups + Backend: Convex 3-paths + attribution Credits section. README /team 404 hotfix landed in PR #616.
|
|
99
|
+
- `search_components` and `search_fix_patterns`, kept as aliases of the canonical names. The removal of `text_search` and `recall` was moved to 2.11.0.
|
|
393
100
|
|
|
394
|
-
|
|
395
|
-
- PR #611 (`9464f9a`) — T5ter README rework + CHANGELOG day-numbers + attribution
|
|
396
|
-
- PR #615 (`c189a1d`) — Phase 1 RULE #7 pre-public scrub
|
|
397
|
-
- PR #616 (`99eeae5`) — README /team 404 hotfix
|
|
101
|
+
## [2.9.0] — 2026-06-14
|
|
398
102
|
|
|
399
|
-
|
|
400
|
-
Friction capitalize: `post-public-flip-must-trigger-npm-republish-for-consistency-not-just-repo-visibility-flip` + `day-79-hook-should-validate-tree-not-commit-sha`.
|
|
103
|
+
### Added
|
|
401
104
|
|
|
402
|
-
|
|
105
|
+
- Episode tools: `get_episode`, `list_episodes`, `search_episodes_by_keyword`, `search_episodes_by_semantic`. Episodes are memories of type `episode`; these tools are shortcuts that apply that type for you. An ID that is not an episode returns "Episode not found".
|
|
403
106
|
|
|
404
|
-
|
|
405
|
-
**Pi sign-off** : PI_AUTHORIZED_TASK_ID=`k1793m1qgn0zaay6r87dhvsh7187kwya` (PROD-DEPLOY-AUTHORIZED).
|
|
406
|
-
**Eta sign-off** : ETA_APPROVED_TASK_ID=`k171ep964sxabbrgmb21fk9axd87ka1n` at commit `338a7b9e6130ce69dc5fe7f3e2e9ecc4648b4f6a` (SHA-pinned).
|
|
407
|
-
**Merge** : PR #545 squash `f509c8d92f0b142bc063a0e9dd070e1993cc729b`.
|
|
107
|
+
## [2.8.0] — 2026-06-14
|
|
408
108
|
|
|
409
|
-
|
|
410
|
-
to the Gen UI iframe bridge. All marker emission is gated behind `VP_EMIT_UI_MARKERS=1`
|
|
411
|
-
so production behaviour is unchanged until the bridge is deployed.
|
|
109
|
+
### Added
|
|
412
110
|
|
|
413
|
-
|
|
111
|
+
- `search_memories_by_keyword` (BM25) and `search_memories_by_semantic` (vector) as the canonical memory search tools.
|
|
414
112
|
|
|
415
|
-
|
|
416
|
-
- Fields : `sessionId` (string), `tenantId` (optional string), `origin` (string),
|
|
417
|
-
`userId` (optional string), `createdAt` (number), `lastSeenAt` (number),
|
|
418
|
-
`expiresAt` (number), `revoked` (boolean).
|
|
419
|
-
- Indexes : `by_session_id` on `["sessionId"]`, `by_origin_expires` on `["origin", "expiresAt"]`.
|
|
113
|
+
### Deprecated
|
|
420
114
|
|
|
421
|
-
|
|
422
|
-
- `createSession` mutation — inserts a new session row.
|
|
423
|
-
- `getSession` query — returns session or null (null for expired / revoked).
|
|
424
|
-
- `touchSession` mutation — bumps `lastSeenAt` to now; returns bool.
|
|
425
|
-
- `revokeSession` mutation — sets `revoked=true`; returns bool.
|
|
115
|
+
- `text_search` and `recall`, kept as aliases of the two tools above with identical behaviour.
|
|
426
116
|
|
|
427
|
-
|
|
117
|
+
## [2.7.1] — 2026-06-14
|
|
428
118
|
|
|
429
|
-
|
|
119
|
+
### Fixed
|
|
430
120
|
|
|
431
|
-
|
|
432
|
-
- Validates via `VpToolResultSchema`, throws `TypeError` on schema failure.
|
|
433
|
-
- Returns `__VP_TOOL_RESULT__<json>__END__`.
|
|
121
|
+
- Tool errors return a structured payload (`code`, `message`, `path`, `hint`) instead of an opaque "Server Error" string, so the real cause (for example a validation error) is visible to the client.
|
|
434
122
|
|
|
435
|
-
|
|
436
|
-
- Extracts marker substring (handles bare, embedded, surrounding text).
|
|
437
|
-
- Returns validated `VpToolResult` or null on any failure (no-throw contract).
|
|
123
|
+
## [2.7.0] — 2026-06-13
|
|
438
124
|
|
|
439
|
-
###
|
|
125
|
+
### Added
|
|
440
126
|
|
|
441
|
-
|
|
442
|
-
when `VP_EMIT_UI_MARKERS=1` (default OFF) :
|
|
127
|
+
- `get_message` and `get_recurring_task`: fetch a single message or recurring task by ID, scoped to the caller.
|
|
443
128
|
|
|
444
|
-
|
|
445
|
-
|-----------------------|--------------------|
|
|
446
|
-
| `list_tasks` | `tasks-table` |
|
|
447
|
-
| `list_messages` | `messages-feed` |
|
|
448
|
-
| `get_diary` | `diary-entry` |
|
|
449
|
-
| `list_missions` | `mission-timeline` |
|
|
450
|
-
| `list_briefing_notes` | `briefing-note` |
|
|
451
|
-
| `list_memories` | `memory-quote` |
|
|
129
|
+
## [2.6.0] — 2026-06-13
|
|
452
130
|
|
|
453
|
-
|
|
131
|
+
### Added
|
|
454
132
|
|
|
455
|
-
|
|
133
|
+
- `get_task`, `get_fix_pattern`, `get_mandate` and `get_repo_mapping`: fetch a single record by ID, scoped to the caller.
|
|
456
134
|
|
|
457
|
-
|
|
458
|
-
for the beta verifier cohort. Covers: package install, primitive reads, Shadow DOM scoping,
|
|
459
|
-
stream marker emit + parse, bilingual spot check, WCAG AA (contrast + role attrs),
|
|
460
|
-
default-OFF guard.
|
|
135
|
+
## [2.5.0] — 2026-06-06
|
|
461
136
|
|
|
462
|
-
###
|
|
137
|
+
### Added
|
|
463
138
|
|
|
464
|
-
|
|
465
|
-
- `
|
|
466
|
-
|
|
467
|
-
non-marker text ×2, embedded text, malformed JSON ×2, schema rejects unknown kind ×2.
|
|
468
|
-
- `convex/iframeEmbedSessions.test.ts` — 7 cases:
|
|
469
|
-
create+get, optional fields, getSession unknown, expired session null,
|
|
470
|
-
touchSession updates lastSeenAt, touchSession unknown false,
|
|
471
|
-
revokeSession marks revoked (getSession null), revokeSession unknown false.
|
|
139
|
+
- `whoami`: returns the identity attached to the current credential, so a client can discover its agent name instead of asking the user.
|
|
140
|
+
- `validate_task_payload`: checks a task or message payload against every validation rule at once and returns all failures together.
|
|
141
|
+
- Output schemas on tools, and standardised tool descriptions.
|
|
472
142
|
|
|
473
|
-
|
|
143
|
+
### Changed
|
|
474
144
|
|
|
475
|
-
|
|
145
|
+
- Agent names are Unicode-normalised and matched case-insensitively.
|
|
146
|
+
- `list_tasks` honours the caller's allowed agent names.
|
|
476
147
|
|
|
477
|
-
|
|
148
|
+
### Security
|
|
478
149
|
|
|
479
|
-
|
|
480
|
-
**Template VR consumed** : `gui-iframe-embed-v1` v1.0.0 (jx7bzk0x1086tgwgj2zrssk2pn87k1ga).
|
|
150
|
+
- Write tools that previously required no authorisation are restricted to the service operator.
|
|
481
151
|
|
|
482
|
-
|
|
483
|
-
- NEW `mcp-server/src/ui-resources/index.ts` : URI parser `ui://vp/v1/<primitive>?<query>` + primitive registry + handler factory.
|
|
484
|
-
- NEW `mcp-server/src/ui-resources/primitives/tasks-table.ts` : M1 MVP primitive returning HTML inline (Shadow DOM scoped CSS) — WCAG AA + bilingual FR+EN.
|
|
485
|
-
- `mcp-server/server-http.ts` : wired `ListResourcesRequestSchema` + `ReadResourceRequestSchema` MCP handlers on the existing McpServer instance.
|
|
152
|
+
## [2.4.13] — 2026-06-02
|
|
486
153
|
|
|
487
|
-
|
|
154
|
+
### Changed
|
|
488
155
|
|
|
489
|
-
|
|
156
|
+
- Documentation and package metadata only; no runtime change.
|
|
490
157
|
|
|
491
|
-
|
|
492
|
-
- `messages-feed` (`messages:listMessages` backend — channel filter applied client-side)
|
|
493
|
-
- `diary-entry` (`diary:get` single-entry + `diary:list` multi-entry backend)
|
|
494
|
-
- `mission-timeline` (`missions:list` backend with fields=lite)
|
|
495
|
-
- `briefing-note` (`briefingNotes:get` by noteId OR `briefingNotes:list` by topic backend)
|
|
496
|
-
- `memory-quote` (`memories:listMemories` backend — supports both plain-array and paginated result shapes)
|
|
158
|
+
## [2.4.0] — 2026-05-29
|
|
497
159
|
|
|
498
|
-
|
|
160
|
+
### Added
|
|
499
161
|
|
|
500
|
-
|
|
162
|
+
- Optional UI result markers: with `VP_EMIT_UI_MARKERS=1` (off by default), `list_tasks`, `list_messages`, `get_diary`, `list_missions`, `list_briefing_notes` and `list_memories` append a machine-readable `__VP_TOOL_RESULT__…__END__` block after their normal output, for clients that render rich views. Output is unchanged when the variable is unset.
|
|
163
|
+
- Embedded-session registry backing those views.
|
|
501
164
|
|
|
502
|
-
|
|
165
|
+
## UI resources (released with 2.4.0)
|
|
503
166
|
|
|
504
|
-
|
|
167
|
+
### Added
|
|
505
168
|
|
|
506
|
-
|
|
169
|
+
- `ui://vp/v1/<primitive>` MCP resources rendering tasks, messages, diary entries, missions, briefing notes and memories as accessible, bilingual (EN/FR) HTML fragments, with typed payload schemas.
|
|
507
170
|
|
|
508
171
|
## v2.3.5 — 2026-05-28
|
|
509
172
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
Fixes:
|
|
513
|
-
- `mcp-server/src/tools.ts` : 4 list tools now expose `createdBy` (`list_tasks` + `list_tasks_by_mission` only — `list_missions` + `list_briefing_notes` do not accept it backend-side) and `updatedSince` (all 4).
|
|
514
|
-
- Removed `.default(50)` (3 tools) and `.default(20)` (1 tool) on `limit` so absent value reaches the backend, enabling the v2.3.3 auto-clamp safeguard.
|
|
515
|
-
|
|
516
|
-
Tests : 8 new boundary-forwarding cases (`src/__tests__/list-queries-v2.3.5-wire-createdby-updatedsince.test.ts`) — verify MCP layer actually forwards new params to `convex.query` instead of dropping them. 0 regression on existing suites.
|
|
517
|
-
|
|
518
|
-
Detection : Vantage-Bridge architecture review Sigma scope 2026-05-28 — direct `grep`/`sed` inspection of `tools.ts` confirmed the gap. Backend already correct since v2.3.3 (`convex/tasks.ts:354-357`).
|
|
519
|
-
|
|
520
|
-
Fix-pattern (2026-05-28 capitalize) : when adding a new param across backend + MCP wrapper, the test suite MUST cover not only schema validation but also the tool-handler→convex.query forwarding boundary. Schema-only tests passed cleanly in v2.3.3 while the actual feature was broken in prod.
|
|
173
|
+
### Fixed
|
|
521
174
|
|
|
522
|
-
|
|
175
|
+
- `list_tasks` and `list_tasks_by_mission` forward `createdBy`, and all four list tools forward `updatedSince`; previously these filters were silently dropped. An omitted `limit` now reaches the backend so its automatic page-size cap applies.
|
|
523
176
|
|
|
524
177
|
## v2.3.4 — 2026-05-28
|
|
525
178
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
Changes:
|
|
529
|
-
- `convex/oauth.ts`: `registerPublicClient` now explicitly rejects `scopeProfile="master"` with a `ScopeViolation` error. Previously only the HTTP server enforced this; the Convex-layer was bypassable via direct internal call.
|
|
530
|
-
- `mcp-server/src/auth.ts`: bearer layer 3 (DCR token path) no longer maps `mcp:full` scope string to `scopeProfile="master"`. DCR tokens now always resolve to `client-generic` (deny-by-default). The `mcp:full` label in the legacy `oauthTokens` table was a scope label, not an authorization grant.
|
|
531
|
-
- `convex/oauthDcr.ts`: added security documentation clarifying the legacy table is no longer an escalation path; the auth middleware fix is the primary gate.
|
|
532
|
-
|
|
533
|
-
Tests: 5 new Convex security tests (`convex/oauth-dcr-security.test.ts`) + 5 new MCP scope enforcement tests (`mcp-server/src/__tests__/dcr-scope-enforcement.test.ts`), 0 regression on existing suites.
|
|
179
|
+
### Security
|
|
534
180
|
|
|
535
|
-
|
|
181
|
+
- Dynamic client registration can no longer obtain operator scope; self-registered clients receive a tenant scope only.
|
|
536
182
|
|
|
537
183
|
## v2.3.3 — 2026-05-28
|
|
538
184
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
Backend (Convex) :
|
|
542
|
-
- `tasks.list` + `tasks.listByMission` : + `createdBy` (filter by task creator) + `updatedSince` (Unix ms window) + auto-clamp limit=30 when `fields="full"` and no explicit limit
|
|
543
|
-
- `missions.list` : + `updatedSince` + auto-clamp (30)
|
|
544
|
-
- `briefingNotes.list` : + `updatedSince` + auto-clamp (15 when fields=full)
|
|
545
|
-
|
|
546
|
-
MCP wrapper :
|
|
547
|
-
- 4 list tools forward the new params
|
|
548
|
-
- New export `updatedSinceSchema` (positive integer ms)
|
|
549
|
-
- `limit` `.default()` removed on the 4 list tools so absent limit flows to backend → enables auto-clamp
|
|
550
|
-
|
|
551
|
-
Tests : 15 new MCP schema cases (`src/__tests__/list-queries-v2.3.3-createdby-updatedsince.test.ts`) + 6 new Convex round-trip cases.
|
|
552
|
-
|
|
553
|
-
Pi pull cycle unblocked : `list_tasks createdBy="pi" status="review" fields="lite"` returns only Pi-dispatched tasks recently moved to review, payload 5-10× smaller.
|
|
554
|
-
|
|
555
|
-
Cap fleet : 0 overflow tolérance future (auto-clamp).
|
|
185
|
+
### Added
|
|
556
186
|
|
|
557
|
-
|
|
187
|
+
- `createdBy` and `updatedSince` filters on list queries, and an automatic page-size cap when full records are requested without a limit.
|
|
558
188
|
|
|
559
189
|
## v2.3.2 — 2026-05-28
|
|
560
190
|
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
Backend support for these params shipped in v2.3.1 but the MCP wrapper Zod schemas never exposed them, so MCP clients couldn't pass them. Fixed for 4 list tools:
|
|
564
|
-
|
|
565
|
-
- `list_tasks`: + `fields`, status now accepts aliases (`"open"`, `"active"`, `"all"`) and arrays
|
|
566
|
-
- `list_tasks_by_mission`: same
|
|
567
|
-
- `list_missions`: + `fields`, status accepts aliases and arrays
|
|
568
|
-
- `list_briefing_notes`: + `fields`
|
|
569
|
-
|
|
570
|
-
Aliases NOT permitted inside arrays (matches backend rejection contract).
|
|
571
|
-
|
|
572
|
-
Tests: 14 new cases (`src/__tests__/list-queries-schema-v2.3.2.test.ts`), 0 regression on 295+ existing.
|
|
573
|
-
|
|
574
|
-
Fix-pattern (fleet-wide): When backend query supports a new param, ALWAYS update the MCP wrapper tool schema in the SAME PR.
|
|
191
|
+
### Fixed
|
|
575
192
|
|
|
576
|
-
|
|
193
|
+
- `list_tasks`, `list_tasks_by_mission`, `list_missions` and `list_briefing_notes` accept `fields="lite"`; the task and mission tools accept status arrays and aliases (`open`, `active`, `all`). Aliases are not allowed inside an array.
|
|
577
194
|
|
|
578
195
|
## 2.3.1 — 2026-05-26
|
|
579
196
|
|
|
580
|
-
### Fixed
|
|
581
|
-
|
|
582
|
-
- `status=
|
|
583
|
-
- `setPendingAliasReleases` on the Convex backend converted from `mutation` to `internalMutation`. It was a public DoS surface against the auto-IRP pipeline; it is a lifecycle operation only and must not be reachable via MCP.
|
|
197
|
+
### Fixed
|
|
198
|
+
|
|
199
|
+
- `status="all"` returns every row; `status=["all"]` is rejected like the other aliases inside an array.
|
|
584
200
|
|
|
585
201
|
## 2.3.0 — 2026-05-26
|
|
586
202
|
|
|
587
203
|
### Added
|
|
588
|
-
- `list_tasks`, `list_missions`, `list_tasks_by_mission`, `list_briefing_notes` now accept `fields=lite` for compact payloads.
|
|
589
|
-
- Status filters on `list_tasks`, `list_tasks_by_mission`, and `list_missions` now accept arrays and aliases:
|
|
590
|
-
- `status=["todo","in_progress"]` — multi-value array
|
|
591
|
-
- `status="open"` — expands to non-terminal statuses (tasks: todo+in_progress+review+blocked; missions: brainstorm+plan+execute+validate)
|
|
592
|
-
- `status="active"` — in_progress only on tasks; plan+execute on missions
|
|
593
|
-
- `status="all"` — no filter applied
|
|
594
|
-
|
|
595
|
-
### Backward compat
|
|
596
|
-
- Single-string status still accepted unchanged.
|
|
597
|
-
- Omitting `fields` defaults to `"full"` — existing callers unaffected.
|
|
598
204
|
|
|
599
|
-
|
|
205
|
+
- `fields=lite` on `list_tasks`, `list_missions`, `list_tasks_by_mission` and `list_briefing_notes` for compact payloads.
|
|
206
|
+
- Status filters accept arrays and the aliases `open` (non-terminal), `active` and `all`. A single status string and an omitted `fields` behave as before.
|
|
600
207
|
|
|
601
208
|
## 2.2.0 — 2026-05-07
|
|
602
209
|
|
|
603
|
-
-
|
|
604
|
-
-
|
|
605
|
-
- New "Fix patterns cycle" section documenting the KB learning loop
|
|
606
|
-
- 41 new Zod input-validation unit tests for fix-pattern tools
|
|
210
|
+
- New fix-pattern tools: `create_fix_pattern`, `add_fix_attempt`, `validate_fix`, `link_issue_to_pattern`.
|
|
211
|
+
- Per-tool documentation with argument tables and examples.
|
|
607
212
|
|
|
608
213
|
## 2.1.1 — 2026-05-04
|
|
609
214
|
|
|
610
|
-
-
|
|
215
|
+
- Stricter memory ID validation on `create_briefing_note` and `update_briefing_note`.
|
|
611
216
|
|
|
612
217
|
## 2.1.0 — 2026-04-25
|
|
613
218
|
|
|
614
|
-
- `update_briefing_note`
|
|
219
|
+
- `update_briefing_note` with role-based access control.
|
|
615
220
|
|
|
616
221
|
## 2.0.2 — 2026-04-14
|
|
617
222
|
|
|
618
|
-
-
|
|
619
|
-
- Added Orchestrator Roles reference table including alpha, lambda, victor
|
|
620
|
-
- Added note that any custom lowercase role name is accepted
|
|
621
|
-
- Added `bugs` URL and additional keywords to `package.json`
|
|
223
|
+
- README badges, `bugs` URL and keywords in `package.json`. Any lowercase agent name is accepted.
|
|
622
224
|
|
|
623
225
|
## 2.0.1 — 2026-04-14
|
|
624
226
|
|
|
625
|
-
- Docstring fix
|
|
227
|
+
- Docstring fix.
|
|
626
228
|
|
|
627
229
|
## 2.0.0
|
|
628
230
|
|
|
629
|
-
-
|
|
630
|
-
- Deploy
|
|
631
|
-
-
|
|
632
|
-
- Programmatic API section in README
|
|
231
|
+
- Typed function references for calling a deployment directly (`vantage-peers-mcp/api`).
|
|
232
|
+
- Deploy-key authentication guide.
|
|
233
|
+
- `update_mission_template`.
|
|
633
234
|
|
|
634
235
|
## 1.x
|
|
635
236
|
|
|
636
|
-
- Initial public release
|
|
237
|
+
- Initial public release.
|