@productbrain/mcp 0.0.1-beta.65 → 0.0.1-beta.66

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.
@@ -3166,6 +3166,7 @@ var IMPLEMENTATION_REVIEW_WORKFLOW_DESCRIPTOR = {
3166
3166
  ## Review scope (CRITICAL)
3167
3167
 
3168
3168
  - **Default scope is this conversation only.** Only the work discussed or produced in this conversation is in scope. Do not review or touch files, BETs, or work outside that scope unless the user explicitly expands it (e.g. "also review the auth module").
3169
+ - **Every file touched must be explicit.** Scope is not complete until you have listed every file that was touched (created, modified, or deleted) in the work under review. Use git status/diff and conversation context to enumerate them. The review then assesses holistic coherence: does this set of changes fit our system, bring us closer to our vision, and make our code and architecture cleaner?
3169
3170
  - **Infer scope first.** Use conversation context, git status/diff, and recent edits to determine which BET, feature, or files are in scope. Call orient/start and \`context action=gather\` with the inferred scope; do not ask the user to pick what to review unless it's ambiguous.
3170
3171
  - **Ask only to clarify boundaries.** If scope is ambiguous after inference, ask a single, focused question to clarify (e.g. "Should this review include only the changes we just made, or the whole feature?"). Do not ask open-ended "what should we review?" or "which work area?" unless inference failed.
3171
3172
  - **State scope explicitly in Round 01.** After orient and context gather, state in one sentence what is in scope (e.g. "Scope: changes in this conversation for BET-72" or "Scope: files X, Y and BET-72"). Confirm only if the user might reasonably expect something else.
@@ -3200,11 +3201,11 @@ When reviewing test results: (a) test staleness \u2014 code changed, test not up
3200
3201
  num: "01",
3201
3202
  label: "Orient & Scope",
3202
3203
  type: "open",
3203
- instruction: "Apply the Review scope rules: infer scope from this conversation, git diff, and recent edits (default = work in this conversation only). Call orient or start, then context action=gather for the inferred BET/feature. State scope in one explicit sentence. Only ask the participant if scope is ambiguous.",
3204
- facilitatorGuidance: "Infer scope from conversation context, git status/diff, and recent edits \u2014 default is work in this conversation only. Call orient or start to load governance and active bets. Use context action=gather task='implementation review for [inferred-BET-or-feature]' to load related entries. State scope explicitly in one sentence (e.g. 'Scope: changes in this conversation for BET-72'). Present: stated scope, relevant BETs/DECs/BRs, and any stale entries orient surfaces. Ask the participant only if scope is ambiguous (e.g. 'Only the files we changed, or the whole feature?').",
3204
+ instruction: "Apply the Review scope rules: infer scope from this conversation, git diff, and recent edits (default = work in this conversation only). Enumerate every file touched (created, modified, deleted). Call orient or start, then context action=gather for the inferred BET/feature. State scope in one explicit sentence and list all files in scope. Only ask the participant if scope is ambiguous. The review will assess: holistic coherence with our system, whether this brings us closer to our vision, and whether it makes our code and architecture cleaner.",
3205
+ facilitatorGuidance: "Infer scope from conversation context, git status/diff, and recent edits \u2014 default is work in this conversation only. List every file touched (created, modified, or deleted) in the work under review; scope is not complete without this list. Call orient or start to load governance and active bets. Use context action=gather task='implementation review for [inferred-BET-or-feature]' to load related entries. State scope explicitly in one sentence (e.g. 'Scope: changes in this conversation for BET-72'). Present: stated scope, the full list of files touched, relevant BETs/DECs/BRs, and any stale entries orient surfaces. Frame the review: we will assess holistic coherence with our system, whether this brings us closer to our vision, and whether it makes our code and architecture cleaner. Ask the participant only if scope is ambiguous (e.g. 'Only the files we changed, or the whole feature?').",
3205
3206
  outputSchema: {
3206
3207
  field: "scope",
3207
- description: "Explicit scope statement plus BET/feature IDs and related Chain context",
3208
+ description: "Explicit scope statement, every file touched, BET/feature IDs and related Chain context",
3208
3209
  format: "structured"
3209
3210
  },
3210
3211
  maxDurationHint: "3 min"
@@ -3256,8 +3257,8 @@ When reviewing test results: (a) test staleness \u2014 code changed, test not up
3256
3257
  num: "05",
3257
3258
  label: "Synthesis & Sign-Off",
3258
3259
  type: "commit",
3259
- instruction: "Summarize the review. Refactoring needed? Ship or conditional? End with BET/chain IDs.",
3260
- facilitatorGuidance: "Present the full synthesis: standards pass/fail, code grade, test honesty, chain validation. Recommend: ship, ship with conditions, or do not ship. CRITICAL: The output MUST end with one sentence: 'BET/feature IDs reviewed: [IDs]. [One-line summary].' Example: 'BET-xxx, STD-xxx reviewed. Conditional ship \u2014 fix [specific issues] and add [missing tests].'",
3260
+ instruction: "Summarize the review. Answer: Does this bring us closer to our vision and make our code and architecture cleaner? Refactoring needed? Ship or conditional? End with BET/chain IDs.",
3261
+ facilitatorGuidance: "Present the full synthesis: standards pass/fail, code grade, test honesty, chain validation. Explicitly answer: Does this bring us closer to our vision and make our code and architecture cleaner? Recommend: ship, ship with conditions, or do not ship. CRITICAL: The output MUST end with one sentence: 'BET/feature IDs reviewed: [IDs]. [One-line summary].' Example: 'BET-xxx, STD-xxx reviewed. Conditional ship \u2014 fix [specific issues] and add [missing tests].'",
3261
3262
  outputSchema: {
3262
3263
  field: "synthesis",
3263
3264
  description: "Full review synthesis with BET/chain IDs",
@@ -6974,13 +6975,14 @@ function buildAlignmentCheckLines(result) {
6974
6975
  lines.push("");
6975
6976
  return lines;
6976
6977
  }
6977
- var CORE_PROTOCOL = [
6978
+ var CORE_PROTOCOL_BASE = [
6978
6979
  '**Search before proposing.** Before suggesting new features, architecture, or changes, search the Chain: `entries action=search query="<relevant terms>"`. Build on what exists.',
6979
6980
  "**Reference by ID.** When discussing a topic that has Chain entries, cite them by entry ID (e.g. `DEC-50`, `PRI-3`). This keeps conversations grounded in shared knowledge.",
6980
6981
  "**Check scope.** If the proposed work doesn't fall under an active bet, stop and say so. Do not design implementation for out-of-scope work without explicit user go-ahead.",
6981
- `**Capture continuously.** When a decision, tension, insight, or new term surfaces during work, capture it as a draft immediately. Don't defer to "later."`,
6982
- "**Validate against governance.** Before proposing any solution, check it against the Workspace Governance directives below. If your proposal conflicts with a principle, standard, or business rule \u2014 stop, name the conflict, and get explicit user confirmation before proceeding."
6982
+ `**Capture continuously.** When a decision, tension, insight, or new term surfaces during work, capture it as a draft immediately. Don't defer to "later."`
6983
6983
  ];
6984
+ var RULE5_WITH_GOVERNANCE = "**Validate against governance.** Before proposing any solution, check it against the Workspace Governance directives below. If your proposal conflicts with a principle, standard, or business rule \u2014 stop, name the conflict, and get explicit user confirmation before proceeding.";
6985
+ var RULE5_COMPACT = '**Validate against governance.** Before proposing or building anything, call `orient task="<your task>"` to load relevant governance. If your proposal conflicts with a principle, standard, or business rule \u2014 stop, name the conflict, and get explicit user confirmation.';
6984
6986
  var MAX_ENTRIES_NO_TASK = 3;
6985
6987
  var MAX_ENTRIES_WITH_TASK = 5;
6986
6988
  function extractKeywords(text) {
@@ -6997,16 +6999,18 @@ function formatGovernanceEntry(entry) {
6997
6999
  }
6998
7000
  function buildOperatingProtocol(governanceOrStandards, task) {
6999
7001
  const governance = Array.isArray(governanceOrStandards) ? { standards: governanceOrStandards } : governanceOrStandards ?? {};
7002
+ const { principles = [], standards = [], businessRules = [] } = governance;
7003
+ const hasGovernance = principles.length > 0 || standards.length > 0 || businessRules.length > 0;
7004
+ const rule5 = hasGovernance ? RULE5_WITH_GOVERNANCE : RULE5_COMPACT;
7005
+ const protocol = [...CORE_PROTOCOL_BASE, rule5];
7000
7006
  const lines = [
7001
7007
  "## Operating Protocol",
7002
7008
  "_How to work in this workspace. Follow these before and during every task._",
7003
7009
  ""
7004
7010
  ];
7005
- for (let i = 0; i < CORE_PROTOCOL.length; i++) {
7006
- lines.push(`${i + 1}. ${CORE_PROTOCOL[i]}`);
7011
+ for (let i = 0; i < protocol.length; i++) {
7012
+ lines.push(`${i + 1}. ${protocol[i]}`);
7007
7013
  }
7008
- const { principles = [], standards = [], businessRules = [] } = governance;
7009
- const hasGovernance = principles.length > 0 || standards.length > 0 || businessRules.length > 0;
7010
7014
  if (hasGovernance) {
7011
7015
  lines.push("");
7012
7016
  lines.push("### Workspace governance directives");
@@ -7592,98 +7596,92 @@ async function buildOrientResponse(wsCtx, agentSessionId, errors, task) {
7592
7596
  try {
7593
7597
  const betEntries = await mcpQuery("chain.listEntries", { collectionSlug: "bets" });
7594
7598
  activeBets = (betEntries ?? []).filter((e) => e.status === "active" && e.data?.horizon === "now").slice(0, 8);
7599
+ } catch {
7600
+ }
7601
+ if (task) {
7595
7602
  if (activeBets.length > 0) {
7596
7603
  lines.push("");
7597
7604
  lines.push("## Active bets \u2014 current scope");
7598
- lines.push("_These define what you're building now. Work outside these bets requires explicit user confirmation before designing._");
7605
+ lines.push("_Work outside these bets requires explicit user confirmation._");
7599
7606
  lines.push("");
7600
7607
  for (const e of activeBets) {
7601
7608
  lines.push(`- \`${e.entryId ?? e.name}\` ${e.name}`);
7602
7609
  }
7603
7610
  lines.push("");
7604
7611
  }
7605
- } catch {
7606
- }
7607
- let wsPrinciples = [];
7608
- let wsStandards = [];
7609
- let wsBusinessRules = [];
7610
- try {
7611
- for (const slug of ["principles", "standards", "business-rules"]) {
7612
- const entries = await mcpQuery("chain.listEntries", { collectionSlug: slug });
7613
- const active = (entries ?? []).filter((e) => e.status === "active");
7614
- if (slug === "principles") wsPrinciples = active;
7615
- if (slug === "standards") wsStandards = active;
7616
- if (slug === "business-rules") wsBusinessRules = active;
7612
+ let wsPrinciples = [];
7613
+ let wsStandards = [];
7614
+ let wsBusinessRules = [];
7615
+ try {
7616
+ for (const slug of ["principles", "standards", "business-rules"]) {
7617
+ const entries = await mcpQuery("chain.listEntries", { collectionSlug: slug });
7618
+ const active = (entries ?? []).filter((e) => e.status === "active");
7619
+ if (slug === "principles") wsPrinciples = active;
7620
+ if (slug === "standards") wsStandards = active;
7621
+ if (slug === "business-rules") wsBusinessRules = active;
7622
+ }
7623
+ } catch {
7624
+ }
7625
+ const mapGovEntry = (e) => ({
7626
+ entryId: e.entryId,
7627
+ name: e.name,
7628
+ description: typeof e.data?.description === "string" ? e.data.description : typeof e.description === "string" ? e.description : void 0
7629
+ });
7630
+ lines.push(...buildOperatingProtocol({
7631
+ principles: wsPrinciples.map(mapGovEntry),
7632
+ standards: wsStandards.map(mapGovEntry),
7633
+ businessRules: wsBusinessRules.map(mapGovEntry)
7634
+ }, task));
7635
+ const plannedWork = await queryPlannedWork();
7636
+ if (hasPlannedWork(plannedWork)) {
7637
+ lines.push("");
7638
+ lines.push(...buildPlannedWorkSection(plannedWork, priorSessions, recoveryBlock));
7639
+ } else if (recoveryBlock) {
7640
+ lines.push("");
7641
+ lines.push(...formatRecoveryBlock(recoveryBlock));
7642
+ }
7643
+ try {
7644
+ const allEntries = await mcpQuery("chain.listEntries", {});
7645
+ const committed = (allEntries ?? []).filter(
7646
+ (e) => e.status === "active" && !e.seededByPlatform
7647
+ );
7648
+ const committedCollections = new Set(committed.map((e) => e.collectionId ?? e.collection));
7649
+ if (committed.length >= 10 && committedCollections.size >= 3) {
7650
+ lines.push("");
7651
+ lines.push(`_${committed.length} entries across ${committedCollections.size} collections on the Chain._`);
7652
+ }
7653
+ } catch {
7617
7654
  }
7618
- } catch {
7619
- }
7620
- const mapGovEntry = (e) => ({
7621
- entryId: e.entryId,
7622
- name: e.name,
7623
- description: typeof e.data?.description === "string" ? e.data.description : typeof e.description === "string" ? e.description : void 0
7624
- });
7625
- lines.push(...buildOperatingProtocol({
7626
- principles: wsPrinciples.map(mapGovEntry),
7627
- standards: wsStandards.map(mapGovEntry),
7628
- businessRules: wsBusinessRules.map(mapGovEntry)
7629
- }, task));
7630
- const plannedWork = await queryPlannedWork();
7631
- if (hasPlannedWork(plannedWork)) {
7632
7655
  lines.push("");
7633
- lines.push(...buildPlannedWorkSection(plannedWork, priorSessions, recoveryBlock));
7656
+ lines.push(`Working on: **${task}**`);
7657
+ lines.push("");
7634
7658
  } else {
7635
- const briefingItems = [];
7659
+ if (activeBets.length > 0) {
7660
+ lines.push("");
7661
+ lines.push("## Active bets \u2014 current scope");
7662
+ lines.push("_Work outside these bets requires explicit user confirmation._");
7663
+ lines.push("");
7664
+ for (const e of activeBets) {
7665
+ lines.push(`- \`${e.entryId ?? e.name}\` ${e.name}`);
7666
+ }
7667
+ lines.push("");
7668
+ }
7669
+ lines.push(...buildOperatingProtocol());
7636
7670
  if (priorSessions.length > 0 && !recoveryBlock) {
7637
7671
  const last = priorSessions[0];
7638
- const date = new Date(last.startedAt).toISOString().split("T")[0];
7672
+ const date = last.startedAt ? new Date(last.startedAt).toISOString().split("T")[0] : "unknown";
7639
7673
  const created = Array.isArray(last.entriesCreated) ? last.entriesCreated.length : last.entriesCreated ?? 0;
7640
7674
  const modified = Array.isArray(last.entriesModified) ? last.entriesModified.length : last.entriesModified ?? 0;
7641
- briefingItems.push(`**Last session** (${date}): ${created} created, ${modified} modified`);
7642
- }
7643
- if (readiness?.gaps?.length > 0) {
7644
- briefingItems.push(`**${readiness.gaps.length} gap${readiness.gaps.length === 1 ? "" : "s"}** remaining`);
7645
- }
7646
- if (briefingItems.length > 0) {
7647
- lines.push("");
7648
- lines.push("## Briefing");
7649
- for (const item of briefingItems) {
7650
- lines.push(`- ${item}`);
7651
- }
7675
+ lines.push(`_Last session (${date}): ${created} created, ${modified} modified._`);
7652
7676
  lines.push("");
7653
7677
  }
7654
7678
  if (recoveryBlock) {
7655
7679
  lines.push("");
7656
7680
  lines.push(...formatRecoveryBlock(recoveryBlock));
7657
7681
  }
7682
+ lines.push("**What are you working on?** Tell me and I'll load relevant governance and context.");
7683
+ lines.push("");
7658
7684
  }
7659
- try {
7660
- const allEntries = await mcpQuery("chain.listEntries", {});
7661
- const committed = (allEntries ?? []).filter(
7662
- (e) => e.status === "active" && !e.seededByPlatform
7663
- );
7664
- const committedCollections = new Set(committed.map((e) => e.collectionId ?? e.collection));
7665
- if (committed.length >= 10 && committedCollections.size >= 3) {
7666
- lines.push("");
7667
- lines.push("## Your workspace is activated");
7668
- lines.push(
7669
- `**${committed.length} entries** across **${committedCollections.size} collections** \u2014 your knowledge graph is alive.`
7670
- );
7671
- lines.push("");
7672
- lines.push(
7673
- `**Try it:** Ask me anything about your product \u2014 architecture, decisions, tensions \u2014 and I'll pull context from the graph.`
7674
- );
7675
- lines.push("");
7676
- if (wsCtx.workspaceSlug) {
7677
- lines.push(`**View in Studio:** \`/w/${wsCtx.workspaceSlug}/studio\``);
7678
- lines.push("");
7679
- }
7680
- lines.push("_Tip: Ask me to suggest connections between entries to unlock deeper context._");
7681
- lines.push("");
7682
- }
7683
- } catch {
7684
- }
7685
- lines.push("What would you like to work on?");
7686
- lines.push("");
7687
7685
  }
7688
7686
  if (errors.length > 0) {
7689
7687
  lines.push("## Errors");
@@ -10042,23 +10040,27 @@ function registerHealthTools(server) {
10042
10040
  lines.push(...formatRecoveryBlock(recoveryBlock));
10043
10041
  } else if (priorSessions.length > 0) {
10044
10042
  const last = priorSessions[0];
10045
- const date = new Date(last.startedAt).toISOString().split("T")[0];
10043
+ const date = last.startedAt ? new Date(last.startedAt).toISOString().split("T")[0] : "unknown";
10046
10044
  const created = Array.isArray(last.entriesCreated) ? last.entriesCreated.length : last.entriesCreated ?? 0;
10047
10045
  const modified = Array.isArray(last.entriesModified) ? last.entriesModified.length : last.entriesModified ?? 0;
10048
10046
  lines.push(`Last session (${date}): ${created} created, ${modified} modified`);
10049
10047
  }
10050
10048
  if (orientEntries) {
10051
- const mapGovernanceEntry = (e) => ({
10052
- entryId: e.entryId,
10053
- name: e.name,
10054
- description: typeof e.preview === "string" ? e.preview : void 0
10055
- });
10056
10049
  lines.push("");
10057
- lines.push(...buildOperatingProtocol({
10058
- principles: (orientEntries.principles ?? []).map(mapGovernanceEntry),
10059
- standards: (orientEntries.standards ?? []).map(mapGovernanceEntry),
10060
- businessRules: (orientEntries.businessRules ?? []).map(mapGovernanceEntry)
10061
- }, task));
10050
+ if (task) {
10051
+ const mapGovernanceEntry = (e) => ({
10052
+ entryId: e.entryId,
10053
+ name: e.name,
10054
+ description: typeof e.preview === "string" ? e.preview : void 0
10055
+ });
10056
+ lines.push(...buildOperatingProtocol({
10057
+ principles: (orientEntries.principles ?? []).map(mapGovernanceEntry),
10058
+ standards: (orientEntries.standards ?? []).map(mapGovernanceEntry),
10059
+ businessRules: (orientEntries.businessRules ?? []).map(mapGovernanceEntry)
10060
+ }, task));
10061
+ } else {
10062
+ lines.push(...buildOperatingProtocol());
10063
+ }
10062
10064
  }
10063
10065
  if (agentSessionId) {
10064
10066
  try {
@@ -10118,195 +10120,164 @@ function registerHealthTools(server) {
10118
10120
  lines.push("_Use `collections action=create` to add it, or ask me to propose collections for your domain._");
10119
10121
  lines.push("");
10120
10122
  } else if (readiness) {
10121
- lines.push(`**Brain stage: ${orientStage}.**`);
10122
- lines.push("");
10123
- if (orientEntries?.strategicContext) {
10124
- const sc = orientEntries.strategicContext;
10125
- lines.push("## Strategic Context");
10126
- if (sc.vision) lines.push(`**Vision:** ${sc.vision}`);
10127
- if (sc.purpose) lines.push(`**Purpose:** ${sc.purpose}`);
10128
- if (sc.productAreaCount != null && sc.productAreaCount > 0) {
10129
- lines.push(`**Product areas (${sc.productAreaCount}):** ${(sc.productAreas ?? []).join(", ")}`);
10130
- }
10131
- const betLine = sc.currentBet ? `**Current bet:** ${sc.currentBet}. ${sc.activeBetCount} active bet(s).` : "No active bets.";
10132
- lines.push(`${betLine} ${sc.activeTensionCount} open tension(s).`);
10133
- lines.push("");
10134
- }
10135
- if (orientEntries?.continuingFrom && orientEntries.continuingFrom.length > 0) {
10136
- lines.push("## Continuing from");
10137
- lines.push("_Prior-session entries most relevant to your task._");
10138
- lines.push("");
10139
- for (const e of orientEntries.continuingFrom) {
10140
- const id = e.entryId ?? e.name;
10141
- const type = e.canonicalKey ?? "generic";
10142
- const coll = e.collectionSlug ? ` [${e.collectionSlug}]` : "";
10143
- lines.push(`- \`${id}\` (score ${e.score}) [${type}]${coll} \u2014 ${e.name}`);
10144
- if (e.reasoning) lines.push(` _${e.reasoning}_`);
10145
- }
10146
- lines.push("");
10147
- }
10148
- if (orientEntries?.lastSessionTouched && orientEntries.lastSessionTouched.length > 0) {
10149
- lines.push("## Last session touched");
10150
- lines.push("_Entries created or modified in your most recent session._");
10151
- lines.push("");
10152
- for (const e of orientEntries.lastSessionTouched) {
10153
- const id = e.entryId ?? e.name;
10154
- const type = e.canonicalKey ?? "generic";
10155
- const coll = e.collectionSlug ? ` [${e.collectionSlug}]` : "";
10156
- lines.push(`- \`${id}\` [${type}]${coll} \u2014 ${e.name}`);
10157
- }
10158
- lines.push("");
10159
- }
10160
- if (orientEntries?.taskContext && orientEntries.taskContext.context.length > 0) {
10161
- const tc = orientEntries.taskContext;
10162
- lines.push("## Task Context");
10163
- lines.push(`_Task-scoped entries (${tc.confidence} confidence, ${tc.totalFound} relevant)`);
10123
+ const fmt = (e) => {
10124
+ const type = e.canonicalKey ?? "generic";
10125
+ const stratum = e.stratum ?? "?";
10126
+ return `- \`${e.entryId ?? e._id}\` [${type} \xB7 ${stratum}] ${e.name}`;
10127
+ };
10128
+ if (task) {
10129
+ lines.push(`**Brain stage: ${orientStage}.** Working on: **${task}**`);
10164
10130
  lines.push("");
10165
- for (const e of tc.context) {
10166
- const id = e.entryId ?? e.name;
10167
- const coll = e.collectionSlug ? ` [${e.collectionSlug}]` : "";
10168
- lines.push(`- \`${id}\` (score ${e.score})${coll}${e.name !== id ? ` \u2014 ${e.name}` : ""}`);
10131
+ if (orientEntries?.strategicContext) {
10132
+ const sc = orientEntries.strategicContext;
10133
+ lines.push("## Strategic Context");
10134
+ if (sc.vision) lines.push(`**Vision:** ${sc.vision}`);
10135
+ if (sc.purpose) lines.push(`**Purpose:** ${sc.purpose}`);
10136
+ if (sc.productAreaCount != null && sc.productAreaCount > 0) {
10137
+ lines.push(`**Product areas (${sc.productAreaCount}):** ${(sc.productAreas ?? []).join(", ")}`);
10138
+ }
10139
+ const betLine = sc.currentBet ? `**Current bet:** ${sc.currentBet}. ${sc.activeBetCount} active bet(s).` : "No active bets.";
10140
+ lines.push(`${betLine} ${sc.activeTensionCount} open tension(s).`);
10141
+ lines.push("");
10169
10142
  }
10170
- lines.push("");
10171
- }
10172
- if (task && orientEntries) {
10173
- const result = runAlignmentCheck(
10174
- task,
10175
- orientEntries.activeBets ?? [],
10176
- orientEntries.taskContext?.context
10177
- );
10178
- lines.push(...buildAlignmentCheckLines(result));
10179
- }
10180
- if (orientEntries) {
10181
- const fmt = (e) => {
10182
- const type = e.canonicalKey ?? "generic";
10183
- const stratum = e.stratum ?? "?";
10184
- return `- \`${e.entryId ?? e._id}\` [${type} \xB7 ${stratum}] ${e.name}`;
10185
- };
10186
- if (orientEntries.activeBets?.length > 0) {
10187
- lines.push("## Active bets \u2014 current scope");
10188
- lines.push("_These define what you're building now. Work outside these bets requires explicit user confirmation before designing._");
10143
+ if (orientEntries?.continuingFrom && orientEntries.continuingFrom.length > 0) {
10144
+ lines.push("## Continuing from");
10145
+ lines.push("_Prior-session entries most relevant to your task._");
10189
10146
  lines.push("");
10190
- for (const e of orientEntries.activeBets) {
10191
- lines.push(fmt(e));
10192
- const tensions = e.linkedTensions;
10193
- if (tensions?.length) {
10194
- const tensionLines = tensions.map((t) => {
10195
- const meta = [t.severity, t.priority].filter(Boolean).join(", ");
10196
- return `\`${t.entryId ?? t.name}\` (${t.name}${meta ? `, ${meta}` : ""})`;
10197
- });
10198
- lines.push(` Tensions: ${tensionLines.join("; ")}`);
10199
- } else {
10200
- lines.push(` Tensions: No linked tensions`);
10201
- }
10147
+ for (const e of orientEntries.continuingFrom) {
10148
+ const id = e.entryId ?? e.name;
10149
+ const type = e.canonicalKey ?? "generic";
10150
+ const coll = e.collectionSlug ? ` [${e.collectionSlug}]` : "";
10151
+ lines.push(`- \`${id}\` (score ${e.score}) [${type}]${coll} \u2014 ${e.name}`);
10152
+ if (e.reasoning) lines.push(` _${e.reasoning}_`);
10202
10153
  }
10203
10154
  lines.push("");
10204
10155
  }
10205
- if (orientEntries.activeGoals.length > 0) {
10206
- lines.push("## Active goals");
10207
- orientEntries.activeGoals.forEach((e) => lines.push(fmt(e)));
10156
+ if (orientEntries?.lastSessionTouched && orientEntries.lastSessionTouched.length > 0) {
10157
+ lines.push("## Last session touched");
10158
+ lines.push("_Entries created or modified in your most recent session._");
10208
10159
  lines.push("");
10209
- }
10210
- if (orientEntries.recentDecisions.length > 0) {
10211
- lines.push("## Recent decisions");
10212
- orientEntries.recentDecisions.forEach((e) => lines.push(fmt(e)));
10160
+ for (const e of orientEntries.lastSessionTouched) {
10161
+ const id = e.entryId ?? e.name;
10162
+ const type = e.canonicalKey ?? "generic";
10163
+ const coll = e.collectionSlug ? ` [${e.collectionSlug}]` : "";
10164
+ lines.push(`- \`${id}\` [${type}]${coll} \u2014 ${e.name}`);
10165
+ }
10213
10166
  lines.push("");
10214
10167
  }
10215
- if (orientEntries.recentlySuperseded.length > 0) {
10216
- lines.push("## Recently superseded");
10217
- orientEntries.recentlySuperseded.forEach((e) => lines.push(fmt(e)));
10168
+ if (orientEntries?.taskContext && orientEntries.taskContext.context.length > 0) {
10169
+ const tc = orientEntries.taskContext;
10170
+ lines.push("## Task Context");
10171
+ lines.push(`_Task-scoped entries (${tc.confidence} confidence, ${tc.totalFound} relevant)`);
10218
10172
  lines.push("");
10219
- }
10220
- if (orientEntries.staleEntries.length > 0) {
10221
- lines.push("## Needs confirmation");
10222
- lines.push(`_Domain stratum entries not confirmed in ${orientEntries.stalenessThresholdDays} days._`);
10223
- orientEntries.staleEntries.forEach((e) => lines.push(fmt(e)));
10173
+ for (const e of tc.context) {
10174
+ const id = e.entryId ?? e.name;
10175
+ const coll = e.collectionSlug ? ` [${e.collectionSlug}]` : "";
10176
+ lines.push(`- \`${id}\` (score ${e.score})${coll}${e.name !== id ? ` \u2014 ${e.name}` : ""}`);
10177
+ }
10224
10178
  lines.push("");
10225
10179
  }
10226
- if (orientEntries.architectureNotes.length > 0) {
10227
- lines.push("## Architecture notes");
10228
- orientEntries.architectureNotes.forEach((e) => lines.push(fmt(e)));
10229
- lines.push("");
10180
+ if (orientEntries) {
10181
+ const result = runAlignmentCheck(
10182
+ task,
10183
+ orientEntries.activeBets ?? [],
10184
+ orientEntries.taskContext?.context
10185
+ );
10186
+ lines.push(...buildAlignmentCheckLines(result));
10187
+ }
10188
+ if (orientEntries) {
10189
+ if (orientEntries.activeBets?.length > 0) {
10190
+ lines.push("## Active bets \u2014 current scope");
10191
+ lines.push("_Work outside these bets requires explicit user confirmation._");
10192
+ lines.push("");
10193
+ for (const e of orientEntries.activeBets) {
10194
+ lines.push(fmt(e));
10195
+ const tensions = e.linkedTensions;
10196
+ if (tensions?.length) {
10197
+ const tensionLines = tensions.map((t) => {
10198
+ const meta = [t.severity, t.priority].filter(Boolean).join(", ");
10199
+ return `\`${t.entryId ?? t.name}\` (${t.name}${meta ? `, ${meta}` : ""})`;
10200
+ });
10201
+ lines.push(` Tensions: ${tensionLines.join("; ")}`);
10202
+ }
10203
+ }
10204
+ lines.push("");
10205
+ }
10206
+ if (orientEntries.activeGoals?.length > 0) {
10207
+ lines.push("## Active goals");
10208
+ orientEntries.activeGoals.forEach((e) => lines.push(fmt(e)));
10209
+ lines.push("");
10210
+ }
10211
+ if (orientEntries.recentDecisions?.length > 0) {
10212
+ lines.push("## Recent decisions");
10213
+ orientEntries.recentDecisions.forEach((e) => lines.push(fmt(e)));
10214
+ lines.push("");
10215
+ }
10216
+ if (orientEntries.recentlySuperseded?.length > 0) {
10217
+ lines.push("## Recently superseded");
10218
+ orientEntries.recentlySuperseded.forEach((e) => lines.push(fmt(e)));
10219
+ lines.push("");
10220
+ }
10221
+ if (orientEntries.staleEntries?.length > 0) {
10222
+ lines.push("## Needs confirmation");
10223
+ lines.push(`_Domain stratum entries not confirmed in ${orientEntries.stalenessThresholdDays} days._`);
10224
+ orientEntries.staleEntries.forEach((e) => lines.push(fmt(e)));
10225
+ lines.push("");
10226
+ }
10227
+ if (orientEntries.architectureNotes?.length > 0) {
10228
+ lines.push("## Architecture notes");
10229
+ orientEntries.architectureNotes.forEach((e) => lines.push(fmt(e)));
10230
+ lines.push("");
10231
+ }
10232
+ const mapGovernanceEntry = (e) => ({
10233
+ entryId: e.entryId,
10234
+ name: e.name,
10235
+ description: typeof e.preview === "string" ? e.preview : void 0
10236
+ });
10237
+ lines.push(...buildOperatingProtocol({
10238
+ principles: (orientEntries.principles ?? []).map(mapGovernanceEntry),
10239
+ standards: (orientEntries.standards ?? []).map(mapGovernanceEntry),
10240
+ businessRules: (orientEntries.businessRules ?? []).map(mapGovernanceEntry)
10241
+ }, task));
10242
+ }
10243
+ let allEntries = [];
10244
+ try {
10245
+ allEntries = await mcpQuery("chain.listEntries", {}) ?? [];
10246
+ } catch {
10247
+ }
10248
+ const plannedWork = buildPlannedWork(allEntries);
10249
+ if (hasPlannedWork(plannedWork)) {
10250
+ lines.push(...buildPlannedWorkSection(plannedWork, priorSessions, recoveryBlock));
10251
+ } else if (recoveryBlock) {
10252
+ lines.push(...formatRecoveryBlock(recoveryBlock));
10230
10253
  }
10231
- const mapGovernanceEntry = (e) => ({
10232
- entryId: e.entryId,
10233
- name: e.name,
10234
- description: typeof e.preview === "string" ? e.preview : void 0
10235
- });
10236
- lines.push(...buildOperatingProtocol({
10237
- principles: (orientEntries.principles ?? []).map(mapGovernanceEntry),
10238
- standards: (orientEntries.standards ?? []).map(mapGovernanceEntry),
10239
- businessRules: (orientEntries.businessRules ?? []).map(mapGovernanceEntry)
10240
- }, task));
10241
- }
10242
- let allEntries = [];
10243
- try {
10244
- allEntries = await mcpQuery("chain.listEntries", {}) ?? [];
10245
- } catch {
10246
- }
10247
- const plannedWork = buildPlannedWork(allEntries);
10248
- if (hasPlannedWork(plannedWork)) {
10249
- lines.push(...buildPlannedWorkSection(plannedWork, priorSessions, recoveryBlock));
10250
10254
  } else {
10251
- const briefingItems = [];
10255
+ lines.push(`**Brain stage: ${orientStage}.**`);
10256
+ lines.push("");
10257
+ if (orientEntries?.activeBets?.length) {
10258
+ lines.push("## Active bets \u2014 current scope");
10259
+ lines.push("_Work outside these bets requires explicit user confirmation._");
10260
+ lines.push("");
10261
+ for (const e of orientEntries.activeBets) {
10262
+ lines.push(fmt(e));
10263
+ }
10264
+ lines.push("");
10265
+ }
10266
+ lines.push(...buildOperatingProtocol());
10252
10267
  if (priorSessions.length > 0 && !recoveryBlock) {
10253
10268
  const last = priorSessions[0];
10254
- const date = new Date(last.startedAt).toISOString().split("T")[0];
10269
+ const date = last.startedAt ? new Date(last.startedAt).toISOString().split("T")[0] : "unknown";
10255
10270
  const created = Array.isArray(last.entriesCreated) ? last.entriesCreated.length : last.entriesCreated ?? 0;
10256
10271
  const modified = Array.isArray(last.entriesModified) ? last.entriesModified.length : last.entriesModified ?? 0;
10257
- briefingItems.push(`**Last session** (${date}): ${created} created, ${modified} modified`);
10258
- }
10259
- if (readiness.gaps?.length > 0) {
10260
- briefingItems.push(`**${readiness.gaps.length} gap${readiness.gaps.length === 1 ? "" : "s"}** remaining`);
10261
- }
10262
- if (briefingItems.length > 0) {
10263
- lines.push("## Briefing");
10264
- for (const item of briefingItems) {
10265
- lines.push(`- ${item}`);
10266
- }
10272
+ lines.push(`_Last session (${date}): ${created} created, ${modified} modified._`);
10267
10273
  lines.push("");
10268
10274
  }
10269
10275
  if (recoveryBlock) {
10270
- lines.push("");
10271
10276
  lines.push(...formatRecoveryBlock(recoveryBlock));
10272
10277
  }
10273
- }
10274
- const activeEntries = allEntries.filter((e) => e.status === "active");
10275
- if (activeEntries.length > 0) {
10276
- const orgHealth = computeOrganisationHealth(activeEntries);
10277
- if (orgHealth.disagreements > 0) {
10278
- lines.push("## Organisation Health");
10279
- lines.push(...formatOrgHealthLines(orgHealth, 3));
10280
- lines.push("");
10281
- }
10282
- }
10283
- const epistemicEntries = activeEntries.filter(
10284
- (e) => e.collectionSlug === "insights" || e.collectionSlug === "assumptions"
10285
- );
10286
- if (epistemicEntries.length > 0) {
10287
- let validated = 0;
10288
- let evidenced = 0;
10289
- let hypotheses = 0;
10290
- let untested = 0;
10291
- for (const e of epistemicEntries) {
10292
- const ws = e.workflowStatus;
10293
- if (ws === "validated") validated++;
10294
- else if (ws === "evidenced") evidenced++;
10295
- else if (ws === "testing") evidenced++;
10296
- else if (ws === "invalidated") validated++;
10297
- else if (e.collectionSlug === "assumptions") untested++;
10298
- else hypotheses++;
10299
- }
10300
- const parts = [];
10301
- if (validated > 0) parts.push(`${validated} validated`);
10302
- if (evidenced > 0) parts.push(`${evidenced} evidenced`);
10303
- if (hypotheses > 0) parts.push(`${hypotheses} hypotheses`);
10304
- if (untested > 0) parts.push(`${untested} untested`);
10305
- lines.push(`**Epistemic health:** ${parts.join(" \xB7 ")} _(${epistemicEntries.length} claim-carrying entries)_`);
10278
+ lines.push("**What are you working on?** Tell me and I'll load relevant governance and context.");
10306
10279
  lines.push("");
10307
10280
  }
10308
- lines.push("What would you like to work on?");
10309
- lines.push("");
10310
10281
  }
10311
10282
  if (errors.length > 0) {
10312
10283
  lines.push("## Errors");
@@ -11704,4 +11675,4 @@ export {
11704
11675
  SERVER_VERSION,
11705
11676
  createProductBrainServer
11706
11677
  };
11707
- //# sourceMappingURL=chunk-VBKAAFR6.js.map
11678
+ //# sourceMappingURL=chunk-4IQ7A5R4.js.map