@productbrain/mcp 0.0.1-beta.8023 → 0.0.1-beta.8024

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.
@@ -39,7 +39,7 @@ import {
39
39
  trackQualityVerdict,
40
40
  trackSessionCaptureRate,
41
41
  trackZeroCaptureAuditFired
42
- } from "./chunk-N6HO6ETW.js";
42
+ } from "./chunk-NOQEMZRR.js";
43
43
 
44
44
  // src/server.ts
45
45
  import { McpServer as McpServer2 } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -564,7 +564,10 @@ var TOOL_NAME_MIGRATIONS = /* @__PURE__ */ new Map([
564
564
  ["record_activation", "closed \u2014 the setup-assets activation telemetry this tool wrote has been retired. There is no supported way to record an activation receipt through MCP."],
565
565
  ["get-usage-summary", 'workspace action="usage"'],
566
566
  ["audit", 'quality action="audit"'],
567
- ["governance-proposals", 'workspace action="proposals-list|proposals-respond|proposals-count" (list/respond/count \u2192 proposals-<same>)'],
567
+ // WP-776 S2a (DEC-1771): the `workspace` tool's proposals-list/proposals-respond/proposals-count
568
+ // actions this row targeted are themselves deleted along with the relation-consent proposal
569
+ // system — retargeted to a NOTICE row, same shape as skills/record_activation above.
570
+ ["governance-proposals", "closed \u2014 the relation-consent proposal system has been retired. There is no supported way to list/respond/count consent proposals through MCP."],
568
571
  // WP-757 TASK-224 F2 (DEC-1722): the `chain` and `chain-review` MCP tools these two rows
569
572
  // targeted are themselves deleted along with gitchain — retargeted from executable
570
573
  // replacements to NOTICE rows (no equivalent command exists), same shape as
@@ -3101,38 +3104,24 @@ No DB writes \u2014 call without \`preview:true\` to accept for real.` }],
3101
3104
  }
3102
3105
  const docId = result2?._id ?? entry._id;
3103
3106
  const wsCtx = await getWorkspaceContext();
3104
- const isProposal = result2?.status === "proposal_created";
3105
- if (!isProposal) {
3106
- await recordSessionActivity({ entryModified: docId });
3107
- const coll = entry.collectionSlug ?? entry.collection?.slug;
3108
- trackChainEntryCommitted(wsCtx.workspaceId, {
3109
- entry_id: entry.entryId ?? entryId,
3110
- collection: coll,
3111
- commit_method: "manual",
3112
- surface: "mcp_commit_tool"
3113
- });
3114
- }
3115
- let lines;
3116
- if (isProposal) {
3117
- lines = [
3118
- `# Proposal created: ${result2.entryId ?? entryId}`,
3119
- `**${result2.name ?? entry.name}** \u2014 accepting requires consent. A proposal was created instead of accepting directly.`,
3120
- `**Workspace:** ${wsCtx.workspaceSlug} (${wsCtx.workspaceId})`,
3121
- "",
3122
- result2.existing ? "An open proposal for this entry already exists." : "Affected owners will be notified. The entry will be accepted when the consent window expires with no objections, or when all owners approve."
3123
- ];
3124
- } else {
3125
- lines = [
3126
- `# Accepted: ${entryId}`,
3127
- `**${entry.name}** promoted to SSOT on the Chain.`,
3128
- `**Workspace:** ${wsCtx.workspaceSlug} (${wsCtx.workspaceId})`
3129
- ];
3130
- const autoVerified = result2?.autoVerified;
3131
- if (autoVerified?.strength) {
3132
- const who = autoVerified.verifiedBy ? ` (${autoVerified.verifiedBy})` : "";
3133
- lines.push("");
3134
- lines.push(`_Auto-verified as part of promote \u2014 ${autoVerified.strength}${who}._`);
3135
- }
3107
+ await recordSessionActivity({ entryModified: docId });
3108
+ const coll = entry.collectionSlug ?? entry.collection?.slug;
3109
+ trackChainEntryCommitted(wsCtx.workspaceId, {
3110
+ entry_id: entry.entryId ?? entryId,
3111
+ collection: coll,
3112
+ commit_method: "manual",
3113
+ surface: "mcp_commit_tool"
3114
+ });
3115
+ const lines = [
3116
+ `# Accepted: ${entryId}`,
3117
+ `**${entry.name}** promoted to SSOT on the Chain.`,
3118
+ `**Workspace:** ${wsCtx.workspaceSlug} (${wsCtx.workspaceId})`
3119
+ ];
3120
+ const autoVerified = result2?.autoVerified;
3121
+ if (autoVerified?.strength) {
3122
+ const who = autoVerified.verifiedBy ? ` (${autoVerified.verifiedBy})` : "";
3123
+ lines.push("");
3124
+ lines.push(`_Auto-verified as part of promote \u2014 ${autoVerified.strength}${who}._`);
3136
3125
  }
3137
3126
  if (advisoryWarnings.length > 0) {
3138
3127
  lines.push("");
@@ -3212,19 +3201,17 @@ No DB writes \u2014 call without \`preview:true\` to accept for real.` }],
3212
3201
  }
3213
3202
  } catch {
3214
3203
  }
3215
- const next = isProposal ? [
3216
- { tool: "entries", description: "View entry", parameters: { action: "get", entryId } }
3217
- ] : [
3204
+ const next = [
3218
3205
  { tool: "relations", description: "Discover connections", parameters: { action: "suggest", entryId } },
3219
3206
  { tool: "entries", description: "View accepted entry", parameters: { action: "get", entryId } }
3220
3207
  ];
3221
- const summary = isProposal ? `Proposal created for ${entryId} (${entry.name}). Awaiting consent.` : `Accepted ${entryId} (${entry.name}) onto the Chain.`;
3208
+ const summary = `Accepted ${entryId} (${entry.name}) onto the Chain.`;
3222
3209
  const commitSuccessEnvelope = success(
3223
3210
  summary,
3224
3211
  {
3225
3212
  entryId,
3226
3213
  name: entry.name,
3227
- outcome: isProposal ? "proposal_created" : "committed",
3214
+ outcome: "committed",
3228
3215
  qualityVerdict: coachingResult?.verdict ?? void 0,
3229
3216
  source: coachingResult?.source ?? void 0,
3230
3217
  contradictions: advisoryWarnings.length,
@@ -4704,62 +4691,49 @@ async function handleCreate(from, to, type, score, preview) {
4704
4691
  sessionId: agentSessionId ?? void 0,
4705
4692
  ...preview ? { preview: true } : {}
4706
4693
  });
4707
- if (result2?.chainDebtPrevented) {
4708
- const alts = result2.suggestedAlternatives ?? [];
4709
- const altList = alts.map((a) => ` \u2022 \`${a.type}\`: ${a.reason}`).join("\n");
4710
- if (result2.preview) {
4711
- return {
4712
- content: [{
4713
- type: "text",
4714
- text: `# Preview: Chain Debt Would Be Prevented
4715
-
4716
- **"${result2.originalType ?? type}"** is a common misuse for this entry pair \u2014 a real (non-preview) call would create an agent sign-off proposal instead of writing this relation.
4694
+ if (result2 && "outcome" in result2 && result2.outcome === "refused") {
4695
+ const refusal = result2.refusal;
4696
+ const recovery = refusal.requiredAction ?? "Route this change to the accountable role or Team Lead.";
4697
+ return failureResult(
4698
+ `Relation refused: **${from}** \u2014[${type}]\u2192 **${to}**.
4717
4699
 
4718
- **Suggested alternatives:**
4719
- ${altList}
4700
+ ${refusal.reason ?? "This relation was refused."}
4720
4701
 
4721
- No DB writes \u2014 call without \`preview:true\` to create the proposal for real.`
4722
- }],
4723
- structuredContent: success(
4724
- `Preview: "${result2.originalType ?? type}" would divert into an agent sign-off proposal instead of writing this relation.`,
4725
- {
4726
- status: "preview",
4727
- from,
4728
- to,
4729
- type,
4730
- chainDebtPrevented: true,
4731
- originalType: result2.originalType ?? type,
4732
- suggestedAlternatives: result2.suggestedAlternatives
4733
- },
4734
- []
4735
- )
4736
- };
4737
- }
4702
+ ${recovery}`,
4703
+ refusal.category === "auth" ? "AUTHORITY_REFUSED" : "VALIDATION_FAILED",
4704
+ refusal.reason ?? `Relating ${from} to ${to} was refused.`,
4705
+ recovery,
4706
+ void 0,
4707
+ { from, to, type, refusal }
4708
+ );
4709
+ }
4710
+ if (result2?.chainDebtPrevented && result2.preview) {
4711
+ const alts = result2.suggestedAlternatives ?? [];
4712
+ const altList = alts.map((a) => ` \u2022 \`${a.type}\`: ${a.reason}`).join("\n");
4738
4713
  return {
4739
4714
  content: [{
4740
4715
  type: "text",
4741
- text: `# Chain Debt Prevented
4716
+ text: `# Preview: Chain Debt Would Be Prevented
4742
4717
 
4743
- **"${result2.originalType ?? type}"** was intercepted as a common misuse for this entry pair and converted to an agent sign-off proposal.
4744
-
4745
- **Proposal ID:** \`${result2.proposalId}\`
4718
+ **"${result2.originalType ?? type}"** is a common misuse for this entry pair \u2014 a real (non-preview) call would be refused.
4746
4719
 
4747
4720
  **Suggested alternatives:**
4748
4721
  ${altList}
4749
4722
 
4750
- Review at /review in Cortex UI.`
4723
+ No DB writes \u2014 call without \`preview:true\` to see the real refusal.`
4751
4724
  }],
4752
4725
  structuredContent: success(
4753
- `Chain debt prevented: "${result2.originalType ?? type}" was intercepted and converted to an agent sign-off proposal.`,
4726
+ `Preview: "${result2.originalType ?? type}" would be refused as a common misuse.`,
4754
4727
  {
4728
+ status: "preview",
4729
+ from,
4730
+ to,
4731
+ type,
4755
4732
  chainDebtPrevented: true,
4756
- proposalId: result2.proposalId,
4757
4733
  originalType: result2.originalType ?? type,
4758
4734
  suggestedAlternatives: result2.suggestedAlternatives
4759
4735
  },
4760
- [
4761
- { tool: "relations", description: "Use correct type (e.g. informed_by)", parameters: { action: "create", from, to, type: alts[0]?.type ?? "informed_by" } }
4762
- ]
4736
+ []
4763
4737
  )
4764
4738
  };
4765
4739
  }
@@ -4776,39 +4750,16 @@ ${result2.blockingReason ?? "This relation would be rejected."}` }],
4776
4750
  )
4777
4751
  };
4778
4752
  }
4779
- if (result2.wouldRequireProposal) {
4780
- const advisoryText2 = (result2.advisories ?? []).map((a) => `
4781
-
4782
- \u26A0 **${a.ruleId}** (org stage: ${a.stage}): ${a.ruleText}`).join("");
4783
- return {
4784
- content: [{ type: "text", text: `# Preview: would relate ${from} \u2192 ${to} (${type}) \u2014 requires consent
4785
-
4786
- No DB writes. The real (non-preview) call would create an async-consent proposal instead of directly writing this relation.${advisoryText2}` }],
4787
- structuredContent: success(
4788
- `Preview: ${from} \u2192 ${to} (${type}) would require an async-consent proposal \u2014 no DB writes`,
4789
- {
4790
- status: "preview",
4791
- from,
4792
- to,
4793
- type,
4794
- wouldRequireProposal: true,
4795
- ...result2.advisories && result2.advisories.length > 0 && { advisories: result2.advisories }
4796
- },
4797
- [{ tool: "relations", description: "Create proposal for real", parameters: { action: "create", from, to, type } }]
4798
- )
4799
- };
4800
- }
4801
4753
  const suggested2 = result2.suggestedType;
4802
- const suggestedWithPosture2 = suggested2 ? { ...suggested2, governancePosture: suggested2.type === "governs" ? "requires_consent" : "direct" } : void 0;
4803
4754
  const advisoryText = (result2.advisories ?? []).map((a) => `
4804
4755
 
4805
4756
  \u26A0 **${a.ruleId}** (org stage: ${a.stage}): ${a.ruleText}`).join("");
4806
4757
  return {
4807
4758
  content: [{ type: "text", text: `# Preview: would relate ${from} \u2192 ${to} (${type})
4808
4759
 
4809
- No DB writes \u2014 call without \`preview:true\` to create for real.${suggestedWithPosture2 ? `
4760
+ No DB writes \u2014 call without \`preview:true\` to create for real.${suggested2 ? `
4810
4761
 
4811
- **Type suggestion:** \`${suggestedWithPosture2.type}\` may be more precise (${suggestedWithPosture2.confidence}% confidence). Governance: ${suggestedWithPosture2.governancePosture}.` : ""}${advisoryText}` }],
4762
+ **Type suggestion:** \`${suggested2.type}\` may be more precise (${suggested2.confidence}% confidence).` : ""}${advisoryText}` }],
4812
4763
  structuredContent: success(
4813
4764
  `Preview: would relate ${from} \u2192 ${to} (${type}) \u2014 no DB writes`,
4814
4765
  {
@@ -4816,7 +4767,7 @@ No DB writes \u2014 call without \`preview:true\` to create for real.${suggested
4816
4767
  from,
4817
4768
  to,
4818
4769
  type,
4819
- ...suggestedWithPosture2 && { suggestedType: suggestedWithPosture2 },
4770
+ ...suggested2 && { suggestedType: suggested2 },
4820
4771
  ...result2.advisories && result2.advisories.length > 0 && { advisories: result2.advisories }
4821
4772
  },
4822
4773
  [{ tool: "relations", description: "Create for real", parameters: { action: "create", from, to, type } }]
@@ -4824,28 +4775,6 @@ No DB writes \u2014 call without \`preview:true\` to create for real.${suggested
4824
4775
  };
4825
4776
  }
4826
4777
  const wsCtx = await getWorkspaceContext();
4827
- if (result2?.status === "proposal_created") {
4828
- const existingNote = result2.existing ? " (existing proposal reused)" : "";
4829
- return {
4830
- content: [{
4831
- type: "text",
4832
- text: `# Proposal Created \u2014 Governs Relation
4833
-
4834
- **${result2.fromEntryId ?? from}** \u2014[${type}]\u2192 **${result2.toEntryId ?? to}**
4835
-
4836
- ${result2.message ?? "Governs relation requires async consent. A proposal was created for review."}
4837
-
4838
- **Proposal ID:** \`${result2.proposalId}\`${existingNote}
4839
- **Workspace:** ${wsCtx.workspaceSlug} (${wsCtx.workspaceId})
4840
-
4841
- The relation was **not applied** \u2014 it will be created when the proposal is approved.`
4842
- }],
4843
- structuredContent: success(
4844
- `Proposal created for ${from} \u2192 ${to} (${type}). Awaiting consent.`,
4845
- { status: "proposal_created", from, to, type, proposalId: result2.proposalId }
4846
- )
4847
- };
4848
- }
4849
4778
  const lines = [
4850
4779
  `# Relation Created`,
4851
4780
  "",
@@ -4853,12 +4782,11 @@ The relation was **not applied** \u2014 it will be created when the proposal is
4853
4782
  `**Workspace:** ${wsCtx.workspaceSlug} (${wsCtx.workspaceId})`
4854
4783
  ];
4855
4784
  const suggested = result2?.suggestedType;
4856
- const suggestedWithPosture = suggested ? { ...suggested, governancePosture: suggested.type === "governs" ? "requires_consent" : "direct" } : void 0;
4857
- if (suggestedWithPosture) {
4785
+ if (suggested) {
4858
4786
  lines.push("");
4859
- lines.push(`**Type suggestion:** \`${suggestedWithPosture.type}\` may be more precise (${suggestedWithPosture.confidence}% confidence). Governance: ${suggestedWithPosture.governancePosture}.`);
4860
- lines.push(`_${suggestedWithPosture.reasoning}_`);
4861
- lines.push(`To use instead: \`relations action=create from="${from}" to="${to}" type="${suggestedWithPosture.type}"\``);
4787
+ lines.push(`**Type suggestion:** \`${suggested.type}\` may be more precise (${suggested.confidence}% confidence).`);
4788
+ lines.push(`_${suggested.reasoning}_`);
4789
+ lines.push(`To use instead: \`relations action=create from="${from}" to="${to}" type="${suggested.type}"\``);
4862
4790
  }
4863
4791
  for (const a of result2?.advisories ?? []) {
4864
4792
  lines.push("");
@@ -4873,7 +4801,7 @@ The relation was **not applied** \u2014 it will be created when the proposal is
4873
4801
  from,
4874
4802
  to,
4875
4803
  type,
4876
- ...suggestedWithPosture && { suggestedType: suggestedWithPosture },
4804
+ ...suggested && { suggestedType: suggested },
4877
4805
  ...result2?.advisories && result2.advisories.length > 0 && { advisories: result2.advisories }
4878
4806
  },
4879
4807
  [{ tool: "relations", description: "See connections", parameters: { action: "find", entryId: from } }]
@@ -4884,53 +4812,28 @@ async function handleBatchCreate(relations) {
4884
4812
  requireWriteAccess();
4885
4813
  const agentSessionId = getAgentSessionId();
4886
4814
  const results = [];
4887
- const governsRels = relations.filter((r) => r.type === "governs");
4888
- const batchRels = relations.filter((r) => r.type !== "governs");
4889
- if (batchRels.length > 0) {
4890
- try {
4891
- const batchResult = await kernelMutation("chain.createEntryRelations", {
4892
- // WP-474 E4-REWIRE: explicit relate tool creates CHOSEN edges — mark provenance
4893
- // "user" (no confidence; human-chosen) so the census can distinguish them.
4894
- relations: batchRels.map((r) => ({ fromEntryId: r.from, toEntryId: r.to, type: r.type, proposedBy: "user" })),
4895
- sessionId: agentSessionId ?? void 0
4896
- });
4897
- for (let i = 0; i < batchRels.length; i++) {
4898
- const rel = batchRels[i];
4899
- const res = batchResult.results[i];
4900
- results.push({ ...rel, ok: res?.ok ?? false, error: res?.error });
4901
- }
4902
- } catch (e) {
4903
- for (const rel of batchRels) {
4904
- results.push({ ...rel, ok: false, error: e instanceof Error ? e.message : "Batch failed" });
4905
- }
4815
+ try {
4816
+ const batchResult = await kernelMutation("chain.createEntryRelations", {
4817
+ // WP-474 E4-REWIRE: explicit relate tool creates CHOSEN edges — mark provenance
4818
+ // "user" (no confidence; human-chosen) so the census can distinguish them.
4819
+ relations: relations.map((r) => ({ fromEntryId: r.from, toEntryId: r.to, type: r.type, proposedBy: "user" })),
4820
+ sessionId: agentSessionId ?? void 0
4821
+ });
4822
+ for (let i = 0; i < relations.length; i++) {
4823
+ const rel = relations[i];
4824
+ const res = batchResult.results[i];
4825
+ results.push({ ...rel, ok: res?.ok ?? false, error: res?.error });
4906
4826
  }
4907
- }
4908
- for (const rel of governsRels) {
4909
- try {
4910
- const result2 = await kernelMutation("chain.createEntryRelation", {
4911
- fromEntryId: rel.from,
4912
- toEntryId: rel.to,
4913
- type: rel.type,
4914
- // WP-474 E4-REWIRE: explicit batch-relate governs = human/agent-CHOSEN → "user".
4915
- proposedBy: "user",
4916
- sessionId: agentSessionId ?? void 0
4917
- });
4918
- results.push({
4919
- ...rel,
4920
- ok: true,
4921
- proposalCreated: result2?.status === "proposal_created",
4922
- proposalId: result2?.proposalId
4923
- });
4924
- } catch (e) {
4925
- results.push({ ...rel, ok: false, error: e instanceof Error ? e.message : "Unknown error" });
4827
+ } catch (e) {
4828
+ for (const rel of relations) {
4829
+ results.push({ ...rel, ok: false, error: e instanceof Error ? e.message : "Batch failed" });
4926
4830
  }
4927
4831
  }
4928
- const created = results.filter((r) => r.ok && !r.proposalCreated);
4929
- const proposals = results.filter((r) => r.ok && r.proposalCreated);
4832
+ const created = results.filter((r) => r.ok);
4930
4833
  const failed = results.filter((r) => !r.ok);
4931
4834
  const lines = [`# Batch Link Results
4932
4835
  `];
4933
- lines.push(`**${created.length}** created, **${proposals.length}** proposals, **${failed.length}** failed out of ${relations.length} total.
4836
+ lines.push(`**${created.length}** created, **${failed.length}** failed out of ${relations.length} total.
4934
4837
  `);
4935
4838
  if (created.length > 0) {
4936
4839
  lines.push("## Created");
@@ -4938,13 +4841,6 @@ async function handleBatchCreate(relations) {
4938
4841
  lines.push(`- **${r.from}** \u2014[${r.type}]\u2192 **${r.to}**`);
4939
4842
  }
4940
4843
  }
4941
- if (proposals.length > 0) {
4942
- lines.push("");
4943
- lines.push("## Proposals (governs \u2014 not yet applied)");
4944
- for (const r of proposals) {
4945
- lines.push(`- **${r.from}** \u2014[${r.type}]\u2192 **${r.to}** \u2014 proposal \`${r.proposalId}\``);
4946
- }
4947
- }
4948
4844
  if (failed.length > 0) {
4949
4845
  lines.push("");
4950
4846
  lines.push("## Failed");
@@ -4956,8 +4852,8 @@ async function handleBatchCreate(relations) {
4956
4852
  return {
4957
4853
  content: [{ type: "text", text: lines.join("\n") }],
4958
4854
  structuredContent: success(
4959
- `Batch: ${created.length} created, ${proposals.length} proposals, ${failed.length} failed of ${relations.length}.`,
4960
- { created: created.length, proposals: proposals.length, failed: failed.length, total: relations.length, results },
4855
+ `Batch: ${created.length} created, ${failed.length} failed of ${relations.length}.`,
4856
+ { created: created.length, failed: failed.length, total: relations.length, results },
4961
4857
  next.length ? next : void 0
4962
4858
  )
4963
4859
  };
@@ -11637,7 +11533,7 @@ async function runWrapupCommitAll(data, cachedSuggestions) {
11637
11533
  requireWriteAccess();
11638
11534
  const sessionId = getAgentSessionId();
11639
11535
  if (!sessionId) {
11640
- return { text: "No active session.", committed: 0, proposalsCreated: 0, linksCreated: 0, linksFailed: 0, failed: 0, overflowUnscanned: 0 };
11536
+ return { text: "No active session.", committed: 0, linksCreated: 0, linksFailed: 0, failed: 0, overflowUnscanned: 0 };
11641
11537
  }
11642
11538
  const wsCtx = await getWorkspaceContext();
11643
11539
  const results = [];
@@ -11645,7 +11541,6 @@ async function runWrapupCommitAll(data, cachedSuggestions) {
11645
11541
  let linksFailed = 0;
11646
11542
  let linksAdvised = 0;
11647
11543
  const linkFailureDetails = [];
11648
- let proposalsCreated = 0;
11649
11544
  const allDrafts = [...data.drafts, ...data.overflowDrafts ?? []];
11650
11545
  const overflowUnscanned = data.overflowUnscanned ?? 0;
11651
11546
  for (const draft of allDrafts) {
@@ -11664,19 +11559,13 @@ async function runWrapupCommitAll(data, cachedSuggestions) {
11664
11559
  });
11665
11560
  continue;
11666
11561
  }
11667
- const proposed = !!(result2 && "status" in result2 && result2.status === "proposal_created");
11668
- if (!proposed) {
11669
- await recordSessionActivity({ entryModified: draft.docId });
11670
- trackChainEntryCommitted(wsCtx.workspaceId, {
11671
- entry_id: draft.entryId,
11672
- commit_method: "manual",
11673
- surface: "mcp_wrapup"
11674
- });
11675
- }
11676
- if (proposed) {
11677
- proposalsCreated++;
11678
- }
11679
- results.push({ entryId: draft.entryId, ok: true, proposed });
11562
+ await recordSessionActivity({ entryModified: draft.docId });
11563
+ trackChainEntryCommitted(wsCtx.workspaceId, {
11564
+ entry_id: draft.entryId,
11565
+ commit_method: "manual",
11566
+ surface: "mcp_wrapup"
11567
+ });
11568
+ results.push({ entryId: draft.entryId, ok: true });
11680
11569
  } catch (err) {
11681
11570
  const msg = err instanceof Error ? err.message : String(err);
11682
11571
  results.push({ entryId: draft.entryId, ok: false, error: msg });
@@ -11689,11 +11578,10 @@ async function runWrapupCommitAll(data, cachedSuggestions) {
11689
11578
  );
11690
11579
  const linkableSourceIds = /* @__PURE__ */ new Set([
11691
11580
  ...data.committed.map((entry) => entry.entryId),
11692
- ...results.filter((r) => r.ok && !r.proposed).map((r) => r.entryId)
11581
+ ...results.filter((r) => r.ok).map((r) => r.entryId)
11693
11582
  ]);
11694
11583
  const toApply = suggestionsToApply.filter((s) => linkableSourceIds.has(s.fromEntryId)).slice(0, 15);
11695
- const governsRels = toApply.filter((s) => s.type === "governs");
11696
- const batchRels = toApply.filter((s) => s.type !== "governs");
11584
+ const batchRels = toApply;
11697
11585
  if (batchRels.length > 0) {
11698
11586
  try {
11699
11587
  const batchResult = await kernelMutation("chain.createEntryRelations", {
@@ -11728,30 +11616,7 @@ async function runWrapupCommitAll(data, cachedSuggestions) {
11728
11616
  linkFailureDetails.push(`Batch creation failed (${batchRels.length} relations): ${msg}`);
11729
11617
  }
11730
11618
  }
11731
- for (const s of governsRels) {
11732
- try {
11733
- const result2 = await kernelMutation("chain.createEntryRelation", {
11734
- fromEntryId: s.fromEntryId,
11735
- toEntryId: s.toEntryId,
11736
- type: s.type,
11737
- // WP-474 E4-REWIRE: wrapup-applied governs suggestion is auto-inferred → "auto-link".
11738
- proposedBy: "auto-link",
11739
- ...s.confidence !== void 0 ? { confidence: s.confidence } : {},
11740
- sessionId
11741
- });
11742
- if (result2?.status === "proposal_created") {
11743
- } else if (result2?.advised) {
11744
- linksAdvised++;
11745
- } else {
11746
- linksCreated++;
11747
- }
11748
- } catch (err) {
11749
- linksFailed++;
11750
- const msg = err instanceof Error ? err.message : String(err);
11751
- linkFailureDetails.push(`${s.fromEntryId} \u2192 ${s.toEntryId} [${s.type}]: ${msg}`);
11752
- }
11753
- }
11754
- const committed = results.filter((r) => r.ok && !r.proposed).length;
11619
+ const committed = results.filter((r) => r.ok).length;
11755
11620
  const failed = results.filter((r) => !r.ok);
11756
11621
  const cleanDrain = failed.length === 0 && overflowUnscanned === 0;
11757
11622
  if (cleanDrain) {
@@ -11765,7 +11630,7 @@ async function runWrapupCommitAll(data, cachedSuggestions) {
11765
11630
  const lines = [
11766
11631
  "## Wrapup Complete",
11767
11632
  "",
11768
- `**${committed}** drafts accepted, **${proposalsCreated}** proposals created, **${linksCreated}** links created.`
11633
+ `**${committed}** drafts accepted, **${linksCreated}** links created.`
11769
11634
  ];
11770
11635
  if (linksFailed > 0) {
11771
11636
  lines.push(`**${linksFailed}** link${linksFailed === 1 ? "" : "s"} failed to create.`);
@@ -11792,7 +11657,6 @@ async function runWrapupCommitAll(data, cachedSuggestions) {
11792
11657
  return {
11793
11658
  text: lines.join("\n"),
11794
11659
  committed,
11795
- proposalsCreated,
11796
11660
  linksCreated,
11797
11661
  linksFailed,
11798
11662
  failed: failed.length,
@@ -11849,10 +11713,9 @@ function createWrapupHandler() {
11849
11713
  ] : result2.failed > 0 ? [{ tool: "session", description: "Re-review remaining drafts before closing", parameters: { action: "wrapup-review" } }] : [{ tool: "session", description: "Close the session now that drafts are committed", parameters: { action: "close" } }];
11850
11714
  return successResult(
11851
11715
  result2.text,
11852
- `Wrapup processed: ${result2.committed} accepted, ${result2.proposalsCreated} proposals, ${result2.linksCreated} links${linkWarnSuffix}.`,
11716
+ `Wrapup processed: ${result2.committed} accepted, ${result2.linksCreated} links${linkWarnSuffix}.`,
11853
11717
  {
11854
11718
  committed: result2.committed,
11855
- proposalsCreated: result2.proposalsCreated,
11856
11719
  linksCreated: result2.linksCreated,
11857
11720
  linksFailed: result2.linksFailed,
11858
11721
  failed: result2.failed
@@ -12100,21 +11963,12 @@ No constellation entries were accepted.`
12100
11963
  };
12101
11964
  const lines = [];
12102
11965
  const hasIssues = (result2.failedIds?.length ?? 0) > 0 || (result2.conflictIds?.length ?? 0) > 0;
12103
- if (result2.proposalCreated) {
12104
- lines.push(
12105
- hasIssues ? `# Proposal created with issues` : `# Proposal created`,
12106
- "",
12107
- `Workspace uses consent-based governance. \`${betId}\` was submitted as a proposal \u2014 it will be accepted when approved.`,
12108
- `No linked entries were accepted because the work package itself is still awaiting approval.`
12109
- );
12110
- } else {
12111
- lines.push(
12112
- hasIssues ? `# Accepted with issues` : `# Accepted`,
12113
- "",
12114
- `**${result2.committedIds?.length ?? 0} entries** accepted onto the Chain, **${result2.totalRelations} connections** preserved.`,
12115
- hasIssues ? `\`${betId}\` was partially accepted. Review conflicts/failed entries below before considering the constellation complete.` : `\`${betId}\` and its full constellation are now source of truth.`
12116
- );
12117
- }
11966
+ lines.push(
11967
+ hasIssues ? `# Accepted with issues` : `# Accepted`,
11968
+ "",
11969
+ `**${result2.committedIds?.length ?? 0} entries** accepted onto the Chain, **${result2.totalRelations} connections** preserved.`,
11970
+ hasIssues ? `\`${betId}\` was partially accepted. Review conflicts/failed entries below before considering the constellation complete.` : `\`${betId}\` and its full constellation are now source of truth.`
11971
+ );
12118
11972
  if (preflight.source === "semantic" && preflight.conflicts.length > 0) {
12119
11973
  lines.push(
12120
11974
  "",
@@ -12136,9 +11990,6 @@ No constellation entries were accepted.`
12136
11990
  if ((result2.alreadyCommittedIds?.length ?? 0) > 0) {
12137
11991
  lines.push("", `**Already accepted:** ${result2.alreadyCommittedIds.join(", ")}`);
12138
11992
  }
12139
- if ((result2.proposedIds?.length ?? 0) > 0) {
12140
- lines.push("", `**Proposed (not yet accepted):** ${result2.proposedIds.join(", ")}`);
12141
- }
12142
11993
  if ((result2.conflictIds?.length ?? 0) > 0) {
12143
11994
  lines.push("", `**${result2.conflictIds.length} conflicts:**`);
12144
11995
  for (const c of result2.conflictIds) {
@@ -12966,105 +12817,6 @@ async function handleUsageSummary(periodDays) {
12966
12817
  };
12967
12818
  }
12968
12819
 
12969
- // src/tools/governance.ts
12970
- async function handleProposalsList(status2) {
12971
- const proposals = await kernelQuery("governance.listProposals", {
12972
- ...status2 ? { status: status2 } : {}
12973
- });
12974
- if (proposals.length === 0) {
12975
- const statusLabel = status2 ?? "open";
12976
- return successResult(
12977
- `No ${statusLabel} consent proposals in this workspace.`,
12978
- `No ${statusLabel} consent proposals found.`,
12979
- { proposals: [], count: 0 }
12980
- );
12981
- }
12982
- const lines = ["# Consent Proposals", ""];
12983
- for (const p of proposals) {
12984
- const urgency = p.isExpired ? "EXPIRED" : p.hoursRemaining < 1 ? `< 1h remaining` : `${p.hoursRemaining}h remaining`;
12985
- lines.push(`## ${p.targetEntryName} \u2192 ${p.toEntryName ?? "unknown"}`);
12986
- lines.push(`- **ID:** \`${p._id}\``);
12987
- lines.push(`- **Status:** ${p.status} (${urgency})`);
12988
- lines.push(`- **Operation:** ${p.proposedOperation}`);
12989
- lines.push(`- **Reasoning:** ${p.reasoning}`);
12990
- lines.push(`- **Proposed by:** ${p.proposedBy}`);
12991
- if (p.objectionReason) {
12992
- lines.push(`- **Objection:** ${p.objectionReason}`);
12993
- }
12994
- lines.push("");
12995
- }
12996
- return successResult(
12997
- lines.join("\n"),
12998
- `Found ${proposals.length} consent proposal(s).`,
12999
- { proposals, count: proposals.length },
13000
- [
13001
- {
13002
- tool: "workspace",
13003
- description: "Respond to a proposal",
13004
- parameters: { action: "proposals-respond" }
13005
- }
13006
- ]
13007
- );
13008
- }
13009
- async function handleProposalsCount() {
13010
- const result2 = await kernelQuery("governance.countOpenProposals");
13011
- return successResult(
13012
- result2.count === 0 ? "No open consent proposals." : `${result2.count} open consent proposal(s) awaiting review.`,
13013
- `${result2.count} open consent proposal(s).`,
13014
- result2,
13015
- result2.count > 0 ? [{
13016
- tool: "workspace",
13017
- description: "List open proposals",
13018
- parameters: { action: "proposals-list" }
13019
- }] : void 0
13020
- );
13021
- }
13022
- async function handleProposalsRespond(proposalId, verdict, reason) {
13023
- requireWriteAccess();
13024
- if (verdict === "reject" && !reason) {
13025
- return validationResult(
13026
- "A reason is required when rejecting a proposal. Explain what harm this change would cause."
13027
- );
13028
- }
13029
- try {
13030
- const result2 = await kernelMutation(
13031
- "governance.respondToProposal",
13032
- {
13033
- proposalId,
13034
- verdict,
13035
- ...reason ? { reason } : {}
13036
- }
13037
- );
13038
- return successResult(
13039
- result2.message,
13040
- result2.message,
13041
- result2,
13042
- [
13043
- {
13044
- tool: "workspace",
13045
- description: "List remaining proposals",
13046
- parameters: { action: "proposals-list" }
13047
- }
13048
- ]
13049
- );
13050
- } catch (err) {
13051
- const msg = err?.message ?? String(err);
13052
- return failureResult(
13053
- msg,
13054
- "PROPOSAL_ERROR",
13055
- msg,
13056
- "Use workspace action=proposals-list to check proposal status.",
13057
- [
13058
- {
13059
- tool: "workspace",
13060
- description: "List proposals",
13061
- parameters: { action: "proposals-list" }
13062
- }
13063
- ]
13064
- );
13065
- }
13066
- }
13067
-
13068
12820
  // src/tools/workspace.ts
13069
12821
  var WORKSPACE_ACTIONS = [
13070
12822
  "check",
@@ -13072,21 +12824,14 @@ var WORKSPACE_ACTIONS = [
13072
12824
  "status",
13073
12825
  "audit",
13074
12826
  "self-test",
13075
- "usage",
13076
- "proposals-list",
13077
- "proposals-respond",
13078
- "proposals-count"
12827
+ "usage"
13079
12828
  ];
13080
12829
  var workspaceSchema = z28.object({
13081
12830
  action: z28.enum(WORKSPACE_ACTIONS).describe(
13082
- "'check': connectivity and workspace stats (absorbs health action=check). 'whoami': session identity (absorbs health action=whoami). 'status': workspace readiness (absorbs health action=status). 'audit': session audit log (absorbs health action=audit). 'self-test': validate all tool schemas (absorbs health action=self-test). 'usage': LLM usage and cost summary (absorbs get-usage-summary). 'proposals-list': list open consent proposals (absorbs governance-proposals action=list). 'proposals-respond': approve/reject a consent proposal (absorbs governance-proposals action=respond). 'proposals-count': count open consent proposals (absorbs governance-proposals action=count)."
12831
+ "'check': connectivity and workspace stats (absorbs health action=check). 'whoami': session identity (absorbs health action=whoami). 'status': workspace readiness (absorbs health action=status). 'audit': session audit log (absorbs health action=audit). 'self-test': validate all tool schemas (absorbs health action=self-test). 'usage': LLM usage and cost summary (absorbs get-usage-summary)."
13083
12832
  ),
13084
12833
  limit: z28.number().min(1).max(50).optional().describe("For 'audit': how many recent calls to show (max 50, default 20)."),
13085
- periodDays: z28.number().min(1).max(90).optional().describe("For 'usage': number of days to look back (default 30, max 90)."),
13086
- status: z28.enum(["open", "approved", "objected", "expired"]).optional().describe("For 'proposals-list': filter by status (default: open)."),
13087
- proposalId: z28.string().max(200).optional().describe("For 'proposals-respond': proposal ID."),
13088
- verdict: z28.enum(["approve", "reject"]).optional().describe("For 'proposals-respond': approve or reject."),
13089
- reason: z28.string().max(2e3).optional().describe("For 'proposals-respond': reason for the verdict (required when rejecting).")
12834
+ periodDays: z28.number().min(1).max(90).optional().describe("For 'usage': number of days to look back (default 30, max 90).")
13090
12835
  });
13091
12836
  var workspaceCheckVariant = z28.object({ action: z28.literal("check") });
13092
12837
  var workspaceWhoamiVariant = z28.object({ action: z28.literal("whoami") });
@@ -13094,27 +12839,13 @@ var workspaceStatusVariant = z28.object({ action: z28.literal("status") });
13094
12839
  var workspaceAuditVariant = z28.object({ action: z28.literal("audit"), limit: z28.number().min(1).max(50).optional().default(20) });
13095
12840
  var workspaceSelfTestVariant = z28.object({ action: z28.literal("self-test") });
13096
12841
  var workspaceUsageVariant = z28.object({ action: z28.literal("usage"), periodDays: z28.number().min(1).max(90).optional() });
13097
- var workspaceProposalsListVariant = z28.object({
13098
- action: z28.literal("proposals-list"),
13099
- status: z28.enum(["open", "approved", "objected", "expired"]).optional()
13100
- });
13101
- var workspaceProposalsRespondVariant = z28.object({
13102
- action: z28.literal("proposals-respond"),
13103
- proposalId: z28.string().max(200),
13104
- verdict: z28.enum(["approve", "reject"]),
13105
- reason: z28.string().max(2e3).optional()
13106
- });
13107
- var workspaceProposalsCountVariant = z28.object({ action: z28.literal("proposals-count") });
13108
12842
  var workspaceActionUnion = z28.discriminatedUnion("action", [
13109
12843
  workspaceCheckVariant,
13110
12844
  workspaceWhoamiVariant,
13111
12845
  workspaceStatusVariant,
13112
12846
  workspaceAuditVariant,
13113
12847
  workspaceSelfTestVariant,
13114
- workspaceUsageVariant,
13115
- workspaceProposalsListVariant,
13116
- workspaceProposalsRespondVariant,
13117
- workspaceProposalsCountVariant
12848
+ workspaceUsageVariant
13118
12849
  ]);
13119
12850
  var WORKSPACE_ACTION_SPECS = {
13120
12851
  check: { params: [], description: "Verify connectivity; no params." },
@@ -13122,10 +12853,7 @@ var WORKSPACE_ACTION_SPECS = {
13122
12853
  status: { params: [], description: "Workspace readiness; no params." },
13123
12854
  audit: { params: ["limit"], description: "limit is optional (default 20, max 50)." },
13124
12855
  "self-test": { params: [], description: "Validate all tool schemas; no params." },
13125
- usage: { params: ["periodDays"], description: "periodDays is optional (default 30, max 90)." },
13126
- "proposals-list": { params: ["status"], description: "status is optional (default 'open')." },
13127
- "proposals-respond": { params: ["proposalId", "verdict", "reason"], description: "proposalId and verdict are required; reason is required when rejecting." },
13128
- "proposals-count": { params: [], description: "Count open proposals; no params." }
12856
+ usage: { params: ["periodDays"], description: "periodDays is optional (default 30, max 90)." }
13129
12857
  };
13130
12858
  function registerWorkspaceTools(server) {
13131
12859
  const workspaceHandlers = {
@@ -13134,19 +12862,15 @@ function registerWorkspaceTools(server) {
13134
12862
  status: () => handleWorkspaceStatus(),
13135
12863
  audit: (data) => handleAudit2(data.limit ?? 20),
13136
12864
  "self-test": () => Promise.resolve(handleSelfTest(server)),
13137
- usage: (data) => handleUsageSummary(data.periodDays),
13138
- "proposals-list": (data) => handleProposalsList(data.status),
13139
- "proposals-respond": (data) => handleProposalsRespond(data.proposalId, data.verdict, data.reason),
13140
- "proposals-count": () => handleProposalsCount()
12865
+ usage: (data) => handleUsageSummary(data.periodDays)
13141
12866
  };
13142
12867
  server.registerTool(
13143
12868
  "workspace",
13144
12869
  {
13145
12870
  title: "Workspace",
13146
- description: "Diagnostics, session identity, usage, and governance proposals for the current workspace. Nine actions:\n\n- **check**: Verify connectivity \u2014 workspace, collections, entries, latency.\n- **whoami**: Session identity \u2014 workspace ID, slug, name.\n- **status**: Workspace readiness \u2014 checks (pass/fail), gaps, stats (entries, relations, orphans).\n- **audit**: Session audit log \u2014 last N backend calls with summary.\n- **self-test**: Validate all registered tool schemas.\n- **usage**: LLM usage and cost summary \u2014 spend, tokens, model/feature breakdown (absorbs `get-usage-summary`).\n- **proposals-list**: List open consent proposals awaiting review (absorbs `governance-proposals` action=list).\n- **proposals-respond**: Approve or reject a consent proposal (absorbs `governance-proposals` action=respond).\n- **proposals-count**: Count open consent proposals for badge/notification display (absorbs `governance-proposals` action=count).",
12871
+ description: "Diagnostics, session identity, and usage for the current workspace. Six actions:\n\n- **check**: Verify connectivity \u2014 workspace, collections, entries, latency.\n- **whoami**: Session identity \u2014 workspace ID, slug, name.\n- **status**: Workspace readiness \u2014 checks (pass/fail), gaps, stats (entries, relations, orphans).\n- **audit**: Session audit log \u2014 last N backend calls with summary.\n- **self-test**: Validate all registered tool schemas.\n- **usage**: LLM usage and cost summary \u2014 spend, tokens, model/feature breakdown (absorbs `get-usage-summary`).",
13147
12872
  inputSchema: workspaceSchema,
13148
- // Mixed read/write noun (§3 R3): proposals-respond writes; every other action reads.
13149
- annotations: { readOnlyHint: false, idempotentHint: true, openWorldHint: false }
12873
+ annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
13150
12874
  },
13151
12875
  thinWrapper(async (args) => {
13152
12876
  const parsed = parseOrFail(workspaceSchema, args);
@@ -13492,8 +13216,7 @@ function registerShapeTools(server) {
13492
13216
  title: "Shape",
13493
13217
  description: "Review and disposition shape-advisory (single-concern split) suggestions for this workspace. Four actions:\n\n- **list**: List shape advisories, latest per subject (filter by disposition/outcome).\n- **show**: Show one shape advisory in full by id.\n- **agree**: Agree with a compound advisory's split verdict.\n- **dismiss**: Dismiss a compound advisory's split verdict.",
13494
13218
  inputSchema: shapeSchema,
13495
- // Mixed read/write noun (§3 R3, same as workspace's proposals-respond): agree/dismiss write;
13496
- // list/show read.
13219
+ // Mixed read/write noun (§3 R3): agree/dismiss write; list/show read.
13497
13220
  annotations: { readOnlyHint: false, idempotentHint: false, openWorldHint: false }
13498
13221
  },
13499
13222
  thinWrapper(async (args) => {
@@ -14034,7 +13757,7 @@ var AGENT_CHEATSHEET = `# Product Brain \u2014 Agent Cheatsheet
14034
13757
  | \`quality\` | Score an entry, verify the Chain, audit a work package, spine check | \`action\`: check, re-evaluate, verify-chain, audit, spine-check |
14035
13758
  | \`session\` | Start / close, wrapup, resume, constellation accept | \`action\`: start, close, status, wrapup-review, wrapup-commit, resume, commit-constellation |
14036
13759
  | \`workflows\` | Run workflows, checkpoint | \`action\`: list, start, checkpoint, get-run |
14037
- | \`workspace\` | Check / whoami / status / self-test, usage, governance proposals | \`action\`: check, whoami, status, audit, self-test, usage, proposals-* |
13760
+ | \`workspace\` | Check / whoami / status / self-test, usage | \`action\`: check, whoami, status, audit, self-test, usage |
14038
13761
  | \`feedback\` | Submit product feedback (any key, no session required); \`list\` reads back your own workspace's feedback (no gate); vendor triage: queue / note / group / status | \`action\`: submit, list, queue, note, group, status |
14039
13762
  | \`shape\` | Review / disposition write-shape (single-concern split) advisories | \`action\`: list, show, agree, dismiss |
14040
13763
  | \`question\` | Routed questions \u2014 create, reassign, answer, force-close, list | \`action\`: create, assign, answer, force-close, list |
@@ -14859,4 +14582,4 @@ export {
14859
14582
  createProductBrainServer,
14860
14583
  initFeatureFlags
14861
14584
  };
14862
- //# sourceMappingURL=chunk-3VQ5VSBH.js.map
14585
+ //# sourceMappingURL=chunk-AS7ZMCGQ.js.map