loopctl-mcp-server 2.62.0 → 2.63.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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/index.js +19 -4
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -323,7 +323,7 @@ it is enforced server-side and a no-op for a non-superadmin key — see below.)
323
323
  | `knowledge_article_stats` | Per-article usage stats: total accesses, unique agents, by-type breakdown, recent events. Required: `article_id`. |
324
324
  | `knowledge_agent_usage` | Per-agent knowledge usage: total reads, unique articles, top read articles. Required: exactly one of `api_key_id` (credential) or `agent_id` (logical identity). Optional: `limit`, `since_days`. See Wiki Attribution section. |
325
325
  | `knowledge_unused_articles` | Published articles with zero accesses in the window. Optional: `days_unused` (default 30), `limit` (default 50, max 200). |
326
- | `knowledge_curation_log` | Concise human-readable log of KB CURATION adjustments — novelty-gate decisions (`gate_duplicate`/`gate_draft`) and conflict resolutions (`supersede`/`merge`/`dismiss`) — for analyzing the agents'-KB rollout, distinct from the verbose audit log. Each entry: `{at, kind, summary, refs, actor, confidence}`. **RECORDED ONLY when `settings.kb_curation_log` is on** (PATCH `/api/v1/admin/tenants/:id` with `settings:{kb_curation_log:true}`); off by default = no rows. Most recent first. Requires orchestrator role. Optional: `kind`, `since` (ISO8601), `limit` (default 50, max 500), `offset`. |
326
+ | `knowledge_curation_log` | Concise human-readable log of KB CURATION adjustments — novelty-gate decisions (`gate_duplicate`/`gate_draft`/`gate_skip`) and conflict resolutions (`supersede`/`merge`/`dismiss`) — for analyzing the agents'-KB rollout, distinct from the verbose audit log. Each entry: `{at, kind, summary, refs, actor, confidence}`. **RECORDED ONLY when `settings.kb_curation_log` is on** (PATCH `/api/v1/admin/tenants/:id` with `settings:{kb_curation_log:true}`); off by default = no rows. Most recent first. Requires orchestrator role. Optional: `kind`, `since` (ISO8601), `limit` (default 50, max 500), `offset`. |
327
327
  | `knowledge_retrieval_metrics` | Daily retrieval-PRECISION time series: for each day, the share of search results the agent then opened (search → get/context within a window). A proxy for whether retrieval is improving as the corpus is de-duplicated, better navigated (MOCs), and conflict-resolved. Most recent day first. Requires orchestrator role. Optional: `limit` (default 30, max 365), `offset`. |
328
328
 
329
329
  ### Egress / Privacy Tools (US-41.4)
package/index.js CHANGED
@@ -1504,6 +1504,7 @@ async function knowledgeCreate({
1504
1504
  project_id,
1505
1505
  draft,
1506
1506
  force,
1507
+ skip_low_novelty,
1507
1508
  source_type,
1508
1509
  source_id,
1509
1510
  idempotency_key,
@@ -1525,8 +1526,10 @@ async function knowledgeCreate({
1525
1526
  if (draft) payload.draft = true;
1526
1527
 
1527
1528
  // The server-side novelty gate dedups the proposal against the corpus (verdict in
1528
- // the response `gate`). force:true bypasses it.
1529
+ // the response `gate`). force:true bypasses it; skip_low_novelty:true drops a
1530
+ // high-overlap proposal instead of banking it as a draft. Mutually exclusive (422).
1529
1531
  if (force) payload.force = true;
1532
+ if (skip_low_novelty) payload.skip_low_novelty = true;
1530
1533
 
1531
1534
  const result = await apiCall(
1532
1535
  "POST",
@@ -4601,7 +4604,9 @@ const TOOLS = [
4601
4604
  "so NOTHING was created (HTTP 200, `deduplicated: true`); read/update the article at `data.id` " +
4602
4605
  "instead (its `gate.similarity` ~1.0). `gated_to_draft` means high overlap, so the article was " +
4603
4606
  "created as a DRAFT (not published) with the near-neighbors in metadata.proposal_novelty for you " +
4604
- "to merge or publish. `created` means it was novel and went through normally. Pass force: true to " +
4607
+ "to merge or publish unless you passed skip_low_novelty: true, in which case the verdict is " +
4608
+ "`skipped_low_novelty` and NOTHING was created (HTTP 200, `skipped: true`, `data: null`). " +
4609
+ "`created` means it was novel and went through normally. Pass force: true to " +
4605
4610
  "bypass the gate when you intentionally want an article near an existing one. " +
4606
4611
  "Concurrency-safe: if a create races/retries against an " +
4607
4612
  "existing article with the same title AND an identical body (ignoring surrounding whitespace), the " +
@@ -4645,6 +4650,15 @@ const TOOLS = [
4645
4650
  "semantic dedup and creates on the requested path even if a near-duplicate exists. " +
4646
4651
  "Use only when you've already checked and intend an article close to an existing one.",
4647
4652
  },
4653
+ skip_low_novelty: {
4654
+ type: "boolean",
4655
+ description:
4656
+ "Optional: on high overlap, create NOTHING instead of staging a draft (default " +
4657
+ "false → gated_to_draft). For an UNATTENDED writer with no reviewer behind it, " +
4658
+ "whose gated drafts would pile up unresolved; you get verdict skipped_low_novelty " +
4659
+ "with data:null. Mutually exclusive with force (422). An idempotency_key match or " +
4660
+ "an exact title collision is still answered as a dedup/409, never dropped.",
4661
+ },
4648
4662
  idempotency_key: {
4649
4663
  type: "string",
4650
4664
  description:
@@ -5905,7 +5919,7 @@ const TOOLS = [
5905
5919
  name: "knowledge_curation_log",
5906
5920
  description:
5907
5921
  "The concise, human-readable log of KB CURATION adjustments — novelty-gate decisions " +
5908
- "(gate_duplicate/gate_draft) and conflict resolutions (supersede/merge/dismiss) — for " +
5922
+ "(gate_duplicate/gate_draft/gate_skip) and conflict resolutions (supersede/merge/dismiss) — for " +
5909
5923
  "analyzing the agents'-KB rollout, distinct from the verbose audit log. Each entry is a " +
5910
5924
  "one-liner: {at, kind, summary, refs, actor, confidence}. RECORDED ONLY while the tenant " +
5911
5925
  "has the toggle on: settings.kb_curation_log (flip via the admin tenant API, " +
@@ -5917,7 +5931,8 @@ const TOOLS = [
5917
5931
  kind: {
5918
5932
  type: "string",
5919
5933
  description:
5920
- "Optional: filter by kind (gate_duplicate | gate_draft | supersede | merge | dismiss).",
5934
+ "Optional: filter by kind (gate_duplicate | gate_draft | gate_skip | supersede | merge | dismiss). " +
5935
+ "gate_skip = a high-overlap proposal DISCARDED under skip_low_novelty (dropped, not stored).",
5921
5936
  },
5922
5937
  since: {
5923
5938
  type: "string",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loopctl-mcp-server",
3
- "version": "2.62.0",
3
+ "version": "2.63.0",
4
4
  "description": "MCP server for loopctl \u2014 structural trust for AI development loops",
5
5
  "type": "module",
6
6
  "main": "index.js",