@productbrain/mcp 0.0.1-beta.1463 → 0.0.1-beta.1470
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/dist/{chunk-Q5IQ5I37.js → chunk-AMJILQKI.js} +12 -3
- package/dist/chunk-AMJILQKI.js.map +1 -0
- package/dist/{chunk-T566VC4F.js → chunk-GL6INEHP.js} +184 -90
- package/dist/chunk-GL6INEHP.js.map +1 -0
- package/dist/cli/index.js +1 -1
- package/dist/http.js +2 -2
- package/dist/index.js +2 -2
- package/dist/{setup-RZMT6ZGH.js → setup-6DPGRAQS.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-Q5IQ5I37.js.map +0 -1
- package/dist/chunk-T566VC4F.js.map +0 -1
- /package/dist/{setup-RZMT6ZGH.js.map → setup-6DPGRAQS.js.map} +0 -0
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
trackSessionCaptureRate,
|
|
38
38
|
trackWriteBackHintServed,
|
|
39
39
|
trackZeroCaptureAuditFired
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-AMJILQKI.js";
|
|
41
41
|
|
|
42
42
|
// src/server.ts
|
|
43
43
|
import { McpServer as McpServer2 } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -616,11 +616,6 @@ async function isGoverned(slug) {
|
|
|
616
616
|
const col = await getCollectionBySlug(slug);
|
|
617
617
|
return !!col?.governed;
|
|
618
618
|
}
|
|
619
|
-
async function isWorkPlanningCollection(slug) {
|
|
620
|
-
const col = await getCollectionBySlug(slug);
|
|
621
|
-
const layer = col?.thinkingLayer;
|
|
622
|
-
return layer === "delivery-container" || layer === "delivery-grouping" || layer === "delivery-work";
|
|
623
|
-
}
|
|
624
619
|
|
|
625
620
|
// src/tools/smart-capture.ts
|
|
626
621
|
var COMMON_CHECKS = {
|
|
@@ -1852,15 +1847,21 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
1852
1847
|
author: agentId ? `agent:${agentId}` : void 0,
|
|
1853
1848
|
sessionId: agentId ?? void 0
|
|
1854
1849
|
});
|
|
1855
|
-
|
|
1856
|
-
if (
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1850
|
+
const refusalReason = coherencyRefusalReason(commitResult);
|
|
1851
|
+
if (refusalReason) {
|
|
1852
|
+
commitError = `coherency gate refused this accept \u2014 ${refusalReason}`;
|
|
1853
|
+
finalStatus = "draft_on_failure";
|
|
1854
|
+
} else {
|
|
1855
|
+
finalStatus = commitResult?.status === "proposal_created" ? "proposed" : "committed";
|
|
1856
|
+
if (finalStatus === "committed") {
|
|
1857
|
+
await recordSessionActivity({ entryModified: internalId });
|
|
1858
|
+
trackChainEntryCommitted(wsCtx.workspaceId, {
|
|
1859
|
+
entry_id: finalEntryId,
|
|
1860
|
+
collection: resolvedCollection,
|
|
1861
|
+
commit_method: "auto",
|
|
1862
|
+
surface: "mcp_capture"
|
|
1863
|
+
});
|
|
1864
|
+
}
|
|
1864
1865
|
}
|
|
1865
1866
|
}
|
|
1866
1867
|
} catch (e) {
|
|
@@ -2423,15 +2424,21 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2423
2424
|
author: agentId ? `agent:${agentId}` : void 0,
|
|
2424
2425
|
sessionId: agentId ?? void 0
|
|
2425
2426
|
});
|
|
2426
|
-
|
|
2427
|
-
if (
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2427
|
+
const refusalReason = coherencyRefusalReason(commitResult);
|
|
2428
|
+
if (refusalReason) {
|
|
2429
|
+
commitError = `coherency gate refused this accept \u2014 ${refusalReason}`;
|
|
2430
|
+
finalStatus = "draft_on_failure";
|
|
2431
|
+
} else {
|
|
2432
|
+
finalStatus = commitResult?.status === "proposal_created" ? "proposed" : "committed";
|
|
2433
|
+
if (finalStatus === "committed") {
|
|
2434
|
+
await recordSessionActivity({ entryModified: internalId });
|
|
2435
|
+
trackChainEntryCommitted(wsCtx.workspaceId, {
|
|
2436
|
+
entry_id: finalEntryId,
|
|
2437
|
+
collection: resolvedSlug ?? void 0,
|
|
2438
|
+
commit_method: "auto",
|
|
2439
|
+
surface: "mcp_capture"
|
|
2440
|
+
});
|
|
2441
|
+
}
|
|
2435
2442
|
}
|
|
2436
2443
|
}
|
|
2437
2444
|
} catch (error) {
|
|
@@ -2677,6 +2684,10 @@ _Use \`move-entry\` to correct any misclassified entries._`);
|
|
|
2677
2684
|
);
|
|
2678
2685
|
trackWriteTool(batchCaptureTool);
|
|
2679
2686
|
}
|
|
2687
|
+
function coherencyRefusalReason(commitResult) {
|
|
2688
|
+
if (commitResult?.status !== "coherency_refused") return null;
|
|
2689
|
+
return commitResult.refusal?.reason ?? "refused by the coherency gate";
|
|
2690
|
+
}
|
|
2680
2691
|
async function recordCommitFailure({
|
|
2681
2692
|
entryId,
|
|
2682
2693
|
error,
|
|
@@ -2989,15 +3000,45 @@ var updateEntrySchema = z3.object({
|
|
|
2989
3000
|
autoPublish: z3.boolean().optional().default(false).describe("Only true when user explicitly asks to publish. Default false = draft. Never auto-publish without user confirmation."),
|
|
2990
3001
|
changeNote: z3.string().optional().describe("Strongly recommended: short human-readable rationale for WHY this change was made (e.g. 'Aligned description with F1-themed copy'). Surfaces in activity feed and pb get. If omitted, falls back to session purpose or auto-generated field summary."),
|
|
2991
3002
|
sourceRef: z3.string().optional().describe("URI or path of the source document backing this entry. Write-once: can only be set if currently empty."),
|
|
2992
|
-
sourceExcerpt: z3.string().optional().describe("Verbatim excerpt from the source that backs this entry's claims. Write-once: can only be set if currently empty.")
|
|
3003
|
+
sourceExcerpt: z3.string().optional().describe("Verbatim excerpt from the source that backs this entry's claims. Write-once: can only be set if currently empty."),
|
|
3004
|
+
// WP-465 slice ⑤ — relay-only (TEN-2233): validation/min-length/recording live in Convex.
|
|
3005
|
+
steeringOverrideReason: z3.string().optional().describe("Typed override (\u226512 chars) that clears a steering coherency block on a misaligned governance write \u2014 always recorded with author attribution."),
|
|
3006
|
+
coherencyAcknowledgement: z3.object({
|
|
3007
|
+
response: z3.enum(["linked", "accepted-fix", "diverged"]).describe("Explicit response to an acknowledge-required coherency challenge."),
|
|
3008
|
+
entryId: z3.string().optional().describe("Authorizing entry being linked/accepted (required for 'linked' and 'accepted-fix')."),
|
|
3009
|
+
reason: z3.string().optional().describe("Divergence rationale (required for 'diverged', \u226512 chars).")
|
|
3010
|
+
}).optional().describe("Explicit response to a coherency challenge (standard/strict workspace modes). One acknowledgement per challenge per entry per session.")
|
|
2993
3011
|
});
|
|
3012
|
+
function coherencyRefusedResult(toolName, entryId, refusal) {
|
|
3013
|
+
return failureResult(
|
|
3014
|
+
[
|
|
3015
|
+
`# Write refused by the coherency gate`,
|
|
3016
|
+
"",
|
|
3017
|
+
refusal.reason ?? `The coherency gate refused this write on ${entryId}.`,
|
|
3018
|
+
"",
|
|
3019
|
+
`Respond and retry: link the entry to the strategic spine, pass \`coherencyAcknowledgement\`, or supply a typed \`steeringOverrideReason\`.`
|
|
3020
|
+
].join("\n"),
|
|
3021
|
+
"COHERENCY_REFUSED",
|
|
3022
|
+
`Coherency gate refused ${toolName} on ${entryId}.`,
|
|
3023
|
+
"Use one of the refusal's routes (link / coherencyAcknowledgement / steeringOverrideReason), then retry.",
|
|
3024
|
+
void 0,
|
|
3025
|
+
{ entryId, refusal }
|
|
3026
|
+
);
|
|
3027
|
+
}
|
|
2994
3028
|
var getHistorySchema = z3.object({
|
|
2995
3029
|
entryId: z3.string().describe("Entry ID, e.g. 'T-SUPPLIER', '<PREFIX>-<n>'")
|
|
2996
3030
|
});
|
|
2997
3031
|
var commitEntrySchema = z3.object({
|
|
2998
3032
|
entryId: z3.string().describe("Entry ID to accept, e.g. 'TEN-abc123', '<PREFIX>-<n>'"),
|
|
2999
3033
|
// WP-316 S3: Preview gate — dry-run mode. Returns would-succeed result, no DB writes.
|
|
3000
|
-
preview: z3.boolean().optional().describe("If true, validates the accept without writing. Returns what would happen. Default false.")
|
|
3034
|
+
preview: z3.boolean().optional().describe("If true, validates the accept without writing. Returns what would happen. Default false."),
|
|
3035
|
+
// WP-465 slice ⑤ — relay-only (TEN-2233): validation/recording live in Convex.
|
|
3036
|
+
steeringOverrideReason: z3.string().optional().describe("Typed override (\u226512 chars) that clears a steering coherency block at the publish chokepoint \u2014 always recorded with author attribution."),
|
|
3037
|
+
coherencyAcknowledgement: z3.object({
|
|
3038
|
+
response: z3.enum(["linked", "accepted-fix", "diverged"]).describe("Explicit response to an acknowledge-required coherency challenge."),
|
|
3039
|
+
entryId: z3.string().optional().describe("Authorizing entry being linked/accepted (required for 'linked' and 'accepted-fix')."),
|
|
3040
|
+
reason: z3.string().optional().describe("Divergence rationale (required for 'diverged', \u226512 chars).")
|
|
3041
|
+
}).optional().describe("Explicit response to a coherency challenge (standard/strict workspace modes).")
|
|
3001
3042
|
});
|
|
3002
3043
|
function registerKnowledgeTools(server) {
|
|
3003
3044
|
const updateTool = server.registerTool(
|
|
@@ -3008,7 +3049,7 @@ function registerKnowledgeTools(server) {
|
|
|
3008
3049
|
inputSchema: updateEntrySchema,
|
|
3009
3050
|
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false }
|
|
3010
3051
|
},
|
|
3011
|
-
thinWrapper(async ({ entryId, name, status: rawStatus, workflowStatus: rawWorkflowStatus, data, order, canonicalKey, autoPublish, changeNote, sourceRef, sourceExcerpt }) => {
|
|
3052
|
+
thinWrapper(async ({ entryId, name, status: rawStatus, workflowStatus: rawWorkflowStatus, data, order, canonicalKey, autoPublish, changeNote, sourceRef, sourceExcerpt, steeringOverrideReason, coherencyAcknowledgement }) => {
|
|
3012
3053
|
requireWriteAccess();
|
|
3013
3054
|
const fieldsProvided = [];
|
|
3014
3055
|
if (name !== void 0) fieldsProvided.push("name");
|
|
@@ -3039,8 +3080,14 @@ function registerKnowledgeTools(server) {
|
|
|
3039
3080
|
changeNote,
|
|
3040
3081
|
changedBy: getAgentSessionId() ? `agent:${getAgentSessionId()}` : void 0,
|
|
3041
3082
|
...sourceRef ? { sourceRef } : {},
|
|
3042
|
-
...sourceExcerpt ? { sourceExcerpt } : {}
|
|
3083
|
+
...sourceExcerpt ? { sourceExcerpt } : {},
|
|
3084
|
+
...steeringOverrideReason ? { steeringOverrideReason } : {},
|
|
3085
|
+
...coherencyAcknowledgement ? { coherencyAcknowledgement } : {}
|
|
3043
3086
|
});
|
|
3087
|
+
const maybeRefused = updateResult;
|
|
3088
|
+
if (maybeRefused.outcome === "refused" && maybeRefused.refusal) {
|
|
3089
|
+
return coherencyRefusedResult("update-entry", entryId, maybeRefused.refusal);
|
|
3090
|
+
}
|
|
3044
3091
|
const id = updateResult.id;
|
|
3045
3092
|
await recordSessionActivity({ entryModified: id });
|
|
3046
3093
|
const wsCtx = await getWorkspaceContext();
|
|
@@ -3149,7 +3196,7 @@ ${formatted}` }],
|
|
|
3149
3196
|
inputSchema: commitEntrySchema,
|
|
3150
3197
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false }
|
|
3151
3198
|
},
|
|
3152
|
-
thinWrapper(async ({ entryId, preview }) => {
|
|
3199
|
+
thinWrapper(async ({ entryId, preview, steeringOverrideReason, coherencyAcknowledgement }) => {
|
|
3153
3200
|
requireWriteAccess();
|
|
3154
3201
|
const entry = await kernelQuery("chain.getEntry", { entryId });
|
|
3155
3202
|
if (!entry) {
|
|
@@ -3213,7 +3260,9 @@ ${formatted}` }],
|
|
|
3213
3260
|
entryId,
|
|
3214
3261
|
author: getAgentSessionId() ? `agent:${getAgentSessionId()}` : void 0,
|
|
3215
3262
|
sessionId: getAgentSessionId() ?? void 0,
|
|
3216
|
-
...preview ? { preview: true } : {}
|
|
3263
|
+
...preview ? { preview: true } : {},
|
|
3264
|
+
...steeringOverrideReason ? { steeringOverrideReason } : {},
|
|
3265
|
+
...coherencyAcknowledgement ? { coherencyAcknowledgement } : {}
|
|
3217
3266
|
});
|
|
3218
3267
|
} catch (commitErr) {
|
|
3219
3268
|
const errCode = commitErr?.code;
|
|
@@ -3232,6 +3281,9 @@ ${formatted}` }],
|
|
|
3232
3281
|
}
|
|
3233
3282
|
throw commitErr;
|
|
3234
3283
|
}
|
|
3284
|
+
if (result?.status === "coherency_refused" && result?.refusal) {
|
|
3285
|
+
return coherencyRefusedResult("commit-entry", entryId, result.refusal);
|
|
3286
|
+
}
|
|
3235
3287
|
if (result?.preview) {
|
|
3236
3288
|
const previewEnvelope = success(
|
|
3237
3289
|
`Preview: would accept ${entryId} \u2014 no DB writes`,
|
|
@@ -3336,6 +3388,11 @@ No DB writes \u2014 call without \`preview:true\` to accept for real.` }],
|
|
|
3336
3388
|
warning_types: uniqueTypes
|
|
3337
3389
|
});
|
|
3338
3390
|
}
|
|
3391
|
+
const steeringAdvisory = typeof result?.steeringAdvisory === "string" && result.steeringAdvisory.trim() ? result.steeringAdvisory : void 0;
|
|
3392
|
+
if (steeringAdvisory) {
|
|
3393
|
+
lines.push("");
|
|
3394
|
+
lines.push(`\u26A0 Coherency advisory (entry accepted): ${steeringAdvisory}`);
|
|
3395
|
+
}
|
|
3339
3396
|
const epistemic = deriveEpistemicStatus(toEpistemicInput(entry));
|
|
3340
3397
|
if (epistemic && (epistemic.level === "hypothesis" || epistemic.level === "untested")) {
|
|
3341
3398
|
lines.push("");
|
|
@@ -3371,7 +3428,8 @@ No DB writes \u2014 call without \`preview:true\` to accept for real.` }],
|
|
|
3371
3428
|
qualityVerdict: coachingResult?.verdict ?? void 0,
|
|
3372
3429
|
source: coachingResult?.source ?? void 0,
|
|
3373
3430
|
contradictions: advisoryWarnings.length,
|
|
3374
|
-
...epistemic ? { epistemicStatus: epistemic } : {}
|
|
3431
|
+
...epistemic ? { epistemicStatus: epistemic } : {},
|
|
3432
|
+
...steeringAdvisory ? { steeringAdvisory } : {}
|
|
3375
3433
|
},
|
|
3376
3434
|
next
|
|
3377
3435
|
);
|
|
@@ -6948,6 +7006,14 @@ async function runWrapupCommitAll(data, cachedSuggestions) {
|
|
|
6948
7006
|
author: `agent:${sessionId}`,
|
|
6949
7007
|
sessionId
|
|
6950
7008
|
});
|
|
7009
|
+
if (result?.status === "coherency_refused") {
|
|
7010
|
+
results.push({
|
|
7011
|
+
entryId: draft.entryId,
|
|
7012
|
+
ok: false,
|
|
7013
|
+
error: `coherency gate refused this accept \u2014 ${result.refusal?.reason ?? "refused by the coherency gate"}`
|
|
7014
|
+
});
|
|
7015
|
+
continue;
|
|
7016
|
+
}
|
|
6951
7017
|
const proposed = result?.status === "proposal_created";
|
|
6952
7018
|
if (!proposed) {
|
|
6953
7019
|
await recordSessionActivity({ entryModified: draft.docId });
|
|
@@ -9186,12 +9252,26 @@ function parseListOutput(output) {
|
|
|
9186
9252
|
// src/tools/facilitate.ts
|
|
9187
9253
|
import { z as z14 } from "zod";
|
|
9188
9254
|
var FACILITATE_ACTIONS = ["resume", "commit-constellation"];
|
|
9255
|
+
var coherencyAcknowledgementSchema = z14.object({
|
|
9256
|
+
response: z14.string().describe("Acknowledgement response per offender: 'linked' | 'accepted-fix' | 'diverged'."),
|
|
9257
|
+
entryId: z14.string().optional().describe("Entry the acknowledgement links to (e.g. the strategic spine entry)."),
|
|
9258
|
+
reason: z14.string().optional().describe("Free-text justification, required for a 'diverged' response."),
|
|
9259
|
+
subjectEntryId: z14.string().optional().describe("The refused entry this acknowledgement answers.")
|
|
9260
|
+
});
|
|
9189
9261
|
var facilitateSchema = z14.object({
|
|
9190
9262
|
action: z14.enum(FACILITATE_ACTIONS).describe(
|
|
9191
9263
|
"'resume': load session state from an existing bet entry. 'commit-constellation': atomically accept a bet and all its linked draft entries in one call. Requires betEntryId."
|
|
9192
9264
|
),
|
|
9193
9265
|
betEntryId: z14.string().optional().describe("Bet entry ID. Required for both actions."),
|
|
9194
|
-
operationId: z14.string().optional().describe("Optional idempotency key for commit-constellation retries.")
|
|
9266
|
+
operationId: z14.string().optional().describe("Optional idempotency key for commit-constellation retries."),
|
|
9267
|
+
// WP-465 slice ⑤: coherency retry controls for a COHERENCY_REFUSED constellation hold.
|
|
9268
|
+
// Forwarded verbatim to agentKnowledge.facilitateEnvelope (validation lives at the gate).
|
|
9269
|
+
coherencyAcknowledgements: z14.array(coherencyAcknowledgementSchema).optional().describe(
|
|
9270
|
+
"Per-offender acknowledgements to retry a constellation held under standard/strict coherency mode. Each: {subjectEntryId, response: 'linked' | 'accepted-fix' | 'diverged', entryId?, reason?}."
|
|
9271
|
+
),
|
|
9272
|
+
steeringOverrideReason: z14.string().optional().describe(
|
|
9273
|
+
"Typed override reason (>= 12 chars) to push a constellation past a coherency hold instead of acknowledging."
|
|
9274
|
+
)
|
|
9195
9275
|
});
|
|
9196
9276
|
function buildCortexUrl(workspaceSlug, entryId) {
|
|
9197
9277
|
const appUrl = process.env.PRODUCTBRAIN_APP_URL ?? "https://work.productbrain.io";
|
|
@@ -9340,11 +9420,39 @@ async function handleCommitConstellation(args) {
|
|
|
9340
9420
|
betEntryId: betId,
|
|
9341
9421
|
operationId,
|
|
9342
9422
|
sessionId: sessionId ?? void 0,
|
|
9343
|
-
author: sessionId ? `agent:${sessionId}` : "kernel:facilitate"
|
|
9423
|
+
author: sessionId ? `agent:${sessionId}` : "kernel:facilitate",
|
|
9424
|
+
// WP-465 slice ⑤ (TEN-2439, §3.7): relay the coherency retry controls so a
|
|
9425
|
+
// COHERENCY_REFUSED constellation hold is actually retryable through MCP.
|
|
9426
|
+
...args.coherencyAcknowledgements ? { coherencyAcknowledgements: args.coherencyAcknowledgements } : {},
|
|
9427
|
+
...args.steeringOverrideReason ? { steeringOverrideReason: args.steeringOverrideReason } : {}
|
|
9344
9428
|
});
|
|
9345
9429
|
} catch (err) {
|
|
9346
9430
|
const msg = err instanceof Error ? err.message : String(err);
|
|
9431
|
+
const code = err?.code;
|
|
9347
9432
|
const diagnostics = err?.diagnostics;
|
|
9433
|
+
if (code === "COHERENCY_REFUSED") {
|
|
9434
|
+
const coherencyRefusals = Array.isArray(diagnostics?.coherencyRefusals) ? diagnostics.coherencyRefusals : [];
|
|
9435
|
+
const offenderLines = coherencyRefusals.map((r) => `- \`${r.entryId}\` ${r.name}: ${String(r.refusal?.reason ?? "coherency challenge unsatisfied")}`).join("\n");
|
|
9436
|
+
const count = coherencyRefusals.length;
|
|
9437
|
+
return {
|
|
9438
|
+
content: [{
|
|
9439
|
+
type: "text",
|
|
9440
|
+
text: [
|
|
9441
|
+
`# Constellation held by the coherency gate`,
|
|
9442
|
+
"",
|
|
9443
|
+
`\`${betId}\` was not accepted \u2014 ${count} entr${count === 1 ? "y" : "ies"} refused. Nothing was committed; drafts persist.`,
|
|
9444
|
+
...offenderLines ? ["", offenderLines] : []
|
|
9445
|
+
].join("\n")
|
|
9446
|
+
}],
|
|
9447
|
+
structuredContent: failure(
|
|
9448
|
+
"COHERENCY_REFUSED",
|
|
9449
|
+
`Constellation held: ${count} entr${count === 1 ? "y" : "ies"} refused by the coherency gate \u2014 nothing was committed, drafts persist.`,
|
|
9450
|
+
"Respond per offender and retry commit-constellation: link the entry to the strategic spine, pass coherencyAcknowledgements [{subjectEntryId, response: 'linked' | 'accepted-fix' | 'diverged', entryId?, reason?}], or supply a typed steeringOverrideReason (at least 12 characters).",
|
|
9451
|
+
[{ tool: "facilitate", description: "Retry with coherency acknowledgements", parameters: { action: "commit-constellation", betEntryId: betId } }],
|
|
9452
|
+
{ coherencyRefusals }
|
|
9453
|
+
)
|
|
9454
|
+
};
|
|
9455
|
+
}
|
|
9348
9456
|
return {
|
|
9349
9457
|
content: [{
|
|
9350
9458
|
type: "text",
|
|
@@ -9688,6 +9796,7 @@ function registerVerifyTools(server) {
|
|
|
9688
9796
|
});
|
|
9689
9797
|
const fixes = [];
|
|
9690
9798
|
const fixUpdateWarnings = [];
|
|
9799
|
+
const fixRefusals = [];
|
|
9691
9800
|
if (mode === "fix") {
|
|
9692
9801
|
const driftedByEntry = /* @__PURE__ */ new Map();
|
|
9693
9802
|
for (const mc of mappingChecks) {
|
|
@@ -9706,6 +9815,13 @@ function registerVerifyTools(server) {
|
|
|
9706
9815
|
entryId: entry.entryId,
|
|
9707
9816
|
data: { codeMapping: updated }
|
|
9708
9817
|
});
|
|
9818
|
+
if (updateResult.outcome === "refused") {
|
|
9819
|
+
fixRefusals.push({
|
|
9820
|
+
entryId: entry.entryId,
|
|
9821
|
+
reason: updateResult.refusal?.reason ?? "coherency gate refused this update"
|
|
9822
|
+
});
|
|
9823
|
+
continue;
|
|
9824
|
+
}
|
|
9709
9825
|
if (updateResult.normalizationWarnings.length > 0 || updateResult.validationWarnings.length > 0) {
|
|
9710
9826
|
fixUpdateWarnings.push({
|
|
9711
9827
|
entryId: entry.entryId,
|
|
@@ -9735,6 +9851,13 @@ function registerVerifyTools(server) {
|
|
|
9735
9851
|
projectRoot
|
|
9736
9852
|
);
|
|
9737
9853
|
let reportText = report;
|
|
9854
|
+
if (fixRefusals.length > 0) {
|
|
9855
|
+
reportText += "\n\n---\n\n\u{1F6D1} **Coherency refusals (fix NOT applied \u2014 entry unchanged):**";
|
|
9856
|
+
for (const r of fixRefusals) {
|
|
9857
|
+
reportText += `
|
|
9858
|
+
- **${r.entryId}**: ${r.reason}`;
|
|
9859
|
+
}
|
|
9860
|
+
}
|
|
9738
9861
|
if (fixUpdateWarnings.length > 0) {
|
|
9739
9862
|
reportText += "\n\n---\n\n\u26A0\uFE0F **Fix update warnings:**";
|
|
9740
9863
|
for (const w of fixUpdateWarnings) {
|
|
@@ -9764,6 +9887,7 @@ function registerVerifyTools(server) {
|
|
|
9764
9887
|
refsValid,
|
|
9765
9888
|
refsBroken,
|
|
9766
9889
|
fixesApplied: fixes.length,
|
|
9890
|
+
...fixRefusals.length > 0 ? { fixesRefused: fixRefusals.length, coherencyRefusals: fixRefusals } : {},
|
|
9767
9891
|
mode
|
|
9768
9892
|
}
|
|
9769
9893
|
)
|
|
@@ -10040,48 +10164,27 @@ function buildDocCompletenessSection(collections) {
|
|
|
10040
10164
|
const lines = renderDocCompletenessLines(report);
|
|
10041
10165
|
return { lines, errorCount: report.summary.errors, warningCount: report.summary.warnings };
|
|
10042
10166
|
}
|
|
10043
|
-
|
|
10044
|
-
|
|
10045
|
-
const
|
|
10046
|
-
|
|
10047
|
-
|
|
10048
|
-
|
|
10049
|
-
|
|
10050
|
-
|
|
10051
|
-
|
|
10052
|
-
}
|
|
10053
|
-
const betHits = [];
|
|
10054
|
-
for (const e of taskContextHits ?? []) {
|
|
10055
|
-
if (e.collectionSlug && await isWorkPlanningCollection(e.collectionSlug)) {
|
|
10056
|
-
betHits.push(e);
|
|
10167
|
+
function buildTaskAlignmentLines(ta) {
|
|
10168
|
+
if (!ta) return [];
|
|
10169
|
+
const lines = ["## Alignment Check"];
|
|
10170
|
+
lines.push(ta.wording);
|
|
10171
|
+
if (ta.candidates.length > 0) {
|
|
10172
|
+
lines.push("");
|
|
10173
|
+
lines.push("**Candidate authorizing entries:**");
|
|
10174
|
+
for (const c of ta.candidates) {
|
|
10175
|
+
lines.push(`- \`${c.entryId}\` [${c.collectionSlug}] ${c.name} (${Math.round(c.overlapRatio * 100)}% overlap)`);
|
|
10057
10176
|
}
|
|
10058
10177
|
}
|
|
10059
|
-
if (
|
|
10060
|
-
|
|
10178
|
+
if (ta.escapeRoutes.length > 0) {
|
|
10179
|
+
lines.push("");
|
|
10180
|
+
lines.push("**Your routes:**");
|
|
10181
|
+
for (let i = 0; i < ta.escapeRoutes.length; i++) {
|
|
10182
|
+
lines.push(`${i + 1}. **${ta.escapeRoutes[i].kind}** \u2014 ${ta.escapeRoutes[i].instruction}`);
|
|
10183
|
+
}
|
|
10061
10184
|
}
|
|
10062
|
-
|
|
10063
|
-
|
|
10064
|
-
|
|
10065
|
-
const lines = ["## Alignment Check"];
|
|
10066
|
-
if (result.aligned && result.matchSource === "active_bet" && result.matchedBet) {
|
|
10067
|
-
lines.push(
|
|
10068
|
-
`Task aligns with active bet: **${result.matchedBet}**. Proceed.`
|
|
10069
|
-
);
|
|
10070
|
-
} else if (result.aligned && result.matchSource === "task_context" && result.matchedBet) {
|
|
10071
|
-
const noActiveBets = result.betNames.length === 0;
|
|
10072
|
-
lines.push(
|
|
10073
|
-
`Task related to **${result.matchedBet}** via task context${noActiveBets ? " (no active bets in horizon=now)" : ""}. Proceed with caution \u2014 confirm scope with the user if uncertain.`
|
|
10074
|
-
);
|
|
10075
|
-
} else if (result.betNames.length === 0) {
|
|
10076
|
-
lines.push(
|
|
10077
|
-
"No active bets in workspace. Consider shaping a bet before building."
|
|
10078
|
-
);
|
|
10079
|
-
} else {
|
|
10080
|
-
lines.push("**This task does not match any active bet.**");
|
|
10081
|
-
lines.push(`Active bets: ${result.betNames.join(", ")}`);
|
|
10082
|
-
lines.push(
|
|
10083
|
-
"Stop and confirm with the user before designing. This may be out of scope."
|
|
10084
|
-
);
|
|
10185
|
+
if (ta.verdict === "misaligned" && ta.citedRule) {
|
|
10186
|
+
lines.push("");
|
|
10187
|
+
lines.push(`_Workspace rule: \`${ta.citedRule.entryId ?? ""}\` ${ta.citedRule.name}._`);
|
|
10085
10188
|
}
|
|
10086
10189
|
lines.push("");
|
|
10087
10190
|
return lines;
|
|
@@ -10102,17 +10205,6 @@ function provenanceMark(p) {
|
|
|
10102
10205
|
}
|
|
10103
10206
|
var MAX_ENTRIES_NO_TASK = 3;
|
|
10104
10207
|
var MAX_ENTRIES_WITH_TASK = 5;
|
|
10105
|
-
function extractKeywords(text) {
|
|
10106
|
-
const normalized = text.toLowerCase().replace(/[^\w\s-]/g, " ");
|
|
10107
|
-
const tokens = [];
|
|
10108
|
-
for (const raw of normalized.split(/\s+/)) {
|
|
10109
|
-
if (!raw) continue;
|
|
10110
|
-
const parts = raw.split(/[-_]/);
|
|
10111
|
-
if (parts.length > 1) tokens.push(raw.replace(/[-_]/g, ""));
|
|
10112
|
-
for (const p of parts) if (p) tokens.push(p);
|
|
10113
|
-
}
|
|
10114
|
-
return [...new Set(tokens.filter((w) => w.length > 2))];
|
|
10115
|
-
}
|
|
10116
10208
|
function formatGovernanceEntry(entry) {
|
|
10117
10209
|
const id = entry.entryId ?? entry.name;
|
|
10118
10210
|
const desc = entry.description ? ` \u2014 ${entry.description.slice(0, 120)}${entry.description.length > 120 ? "..." : ""}` : "";
|
|
@@ -12026,6 +12118,9 @@ async function _handleOrient({ mode = "full", tier, task, scope }) {
|
|
|
12026
12118
|
lines.push(`\u26A0\uFE0F ${orientView.taskContext.groundingNote}`);
|
|
12027
12119
|
}
|
|
12028
12120
|
}
|
|
12121
|
+
if (orientView?.taskAlignment) {
|
|
12122
|
+
lines.push(`Task alignment: ${orientView.taskAlignment.verdict} \u2014 ${orientView.taskAlignment.wording.replace(/\*\*/g, "")}`);
|
|
12123
|
+
}
|
|
12029
12124
|
if (orientView?.startup?.domainRetrieval) {
|
|
12030
12125
|
const retrieval = orientView.startup.domainRetrieval;
|
|
12031
12126
|
const scopedTo = retrieval.resolvedDomainSlug ? ` (${retrieval.resolvedDomainSlug})` : "";
|
|
@@ -12166,6 +12261,8 @@ async function _handleOrient({ mode = "full", tier, task, scope }) {
|
|
|
12166
12261
|
taskGroundingRequired: !hasTaskGrounding,
|
|
12167
12262
|
// STD-219 §4 (DEC-1147): machine-readable stub flag for agent consumers.
|
|
12168
12263
|
...orientView?.taskContext?.isGroundingStub ? { groundingStub: true } : {},
|
|
12264
|
+
// WP-465 slice ③ (§4.1): served verbatim — identical on CLI and MCP.
|
|
12265
|
+
...orientView?.taskAlignment ? { taskAlignment: orientView.taskAlignment } : {},
|
|
12169
12266
|
orientationStatus: orientationStatus2,
|
|
12170
12267
|
nextStep: hasTaskGrounding ? void 0 : 'Run `orient task="describe the work"` before substantive work.',
|
|
12171
12268
|
...orientView?._budget ? { _budget: orientView._budget } : {}
|
|
@@ -12337,12 +12434,7 @@ async function _handleOrient({ mode = "full", tier, task, scope }) {
|
|
|
12337
12434
|
lines.push("");
|
|
12338
12435
|
}
|
|
12339
12436
|
if (orientView) {
|
|
12340
|
-
|
|
12341
|
-
task,
|
|
12342
|
-
orientView.activeWorkPackages ?? [],
|
|
12343
|
-
orientView.taskContext?.context
|
|
12344
|
-
);
|
|
12345
|
-
lines.push(...buildAlignmentCheckLines(result));
|
|
12437
|
+
lines.push(...buildTaskAlignmentLines(orientView.taskAlignment));
|
|
12346
12438
|
lines.push(...formatInitiativeStatusLines(orientView.initiativeStatus));
|
|
12347
12439
|
lines.push(...formatWorkstreamHealthLines(orientView.workstreamHealth));
|
|
12348
12440
|
lines.push(...formatWhatNeedsAttentionLines(orientView.whatNeedsAttention));
|
|
@@ -12579,6 +12671,8 @@ async function _handleOrient({ mode = "full", tier, task, scope }) {
|
|
|
12579
12671
|
taskGroundingRequired: !hasTaskGrounding,
|
|
12580
12672
|
// STD-219 §4 (DEC-1147): machine-readable stub flag for agent consumers.
|
|
12581
12673
|
...orientView?.taskContext?.isGroundingStub ? { groundingStub: true } : {},
|
|
12674
|
+
// WP-465 slice ③ (§4.1): served verbatim — identical on CLI and MCP.
|
|
12675
|
+
...orientView?.taskAlignment ? { taskAlignment: orientView.taskAlignment } : {},
|
|
12582
12676
|
domainRetrieval: orientView?.startup?.domainRetrieval,
|
|
12583
12677
|
orientationStatus,
|
|
12584
12678
|
nextStep: hasTaskGrounding ? void 0 : 'Run `orient task="describe the work"` before substantive work.',
|
|
@@ -14472,4 +14566,4 @@ export {
|
|
|
14472
14566
|
createProductBrainServer,
|
|
14473
14567
|
initFeatureFlags
|
|
14474
14568
|
};
|
|
14475
|
-
//# sourceMappingURL=chunk-
|
|
14569
|
+
//# sourceMappingURL=chunk-GL6INEHP.js.map
|