@brainmcp/brainmcp 0.1.17 → 0.1.19

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/README.md CHANGED
@@ -71,7 +71,7 @@ No API keys or OAuth secrets are written to config files.
71
71
 
72
72
  ## Guidance included in the next release
73
73
 
74
- Local source version `0.1.17` bundles guidance `2026.09.29`: knowledge classes, workspace
74
+ Local source version `0.1.19` bundles guidance `2026.09.30`: knowledge classes, workspace
75
75
  inference (pick an authorized workspace and continue instead of asking which one), Context Paths
76
76
  (save an explanation only when asked, and only when `brain_context_path_create` is advertised),
77
77
  proactive proposals during authorized work, explicit Rule/account-library write limits, and
@@ -82,8 +82,9 @@ MCP handshake carry the full authoring workflow. Every graph change still uses t
82
82
  proposal pipeline. Sectors classify Cores/Neurons across hierarchy; Unassigned means no effective
83
83
  primary, including nodes with secondary memberships.
84
84
 
85
- Registry and tarball verified on 2026-09-29: npm `latest` is `0.1.16` (published 2026-09-21),
86
- which bundles guidance `2026.09.19`. The guidance described above needs a new `0.1.17` release.
85
+ Registry checked on 2026-10-02: npm `latest` is `0.1.18` (published 2026-09-30). Source `0.1.19`
86
+ adds companion dead-grant handling (see Credential storage and safety boundaries); published
87
+ versions cannot be reused.
87
88
 
88
89
  Publication and server deployment are separate: `@latest` downloads the published npm version,
89
90
  not unpublished repository source. After the release is published, rerun the setup command below
@@ -119,6 +120,22 @@ read-only agent verification prompt for that final check.
119
120
  The guidance teaches agents to reuse fresh context, recover omitted Rules, stop retrieving once
120
121
  the task is grounded, amend existing concepts, and distinguish applied proposals from pending review.
121
122
 
123
+ Answer grounding is part of every installed managed block and the MCP workflow. Agents must connect
124
+ material claims to sources they actually read, separate direct source statements from inferences,
125
+ assumptions, and unknowns, and state when Brain does not supply the answer. A related search hit is
126
+ not evidence for an outcome. Quotations, delivery receipts, saved explanations, and applied proposals
127
+ do not independently verify factual truth or an earlier agent's motivation. Context Paths must not
128
+ pad steps or sources, invent requirements, or turn expected benefits into measured results.
129
+
130
+ Companion orientation is a bounded packet. It identifies workspace ids and active refs,
131
+ labels Rule excerpts and omitted context, and reports failed or mismatched workspace responses.
132
+ Grounding and recovery instructions survive the shared 2,400-character cap; up to eight workspace
133
+ packets share the remaining budget, with additional omissions disclosed. Agents still read overview
134
+ for full binding context. Read-only or unknown companion grants do not receive write-back instructions;
135
+ host MCP permissions are checked independently.
136
+ These instructions are intended to reduce unsupported claims. Delivery regressions verify their
137
+ presence; actual model behavior requires separate evaluation.
138
+
122
139
  Check one client's exact schema and placement, managed guidance, canonical and compatibility OAuth
123
140
  metadata, PKCE/DCR/refresh capabilities, and strict scoped 401 challenge. For Cursor, VS Code,
124
141
  GitHub Copilot CLI, and Antigravity, doctor also fails when the reserved `brain` entry exists in
@@ -271,6 +288,7 @@ set both variables independently.
271
288
  - `capture now` and its dry run select the latest ledger for the current project. Delivery also requires the same workspace and capture-consent revision. Older ledgers without a project binding need fresh hook activity before manual capture. A nudge-only ledger stores counters, never prompts, summaries, edited paths, or model labels.
272
289
  - Capture retries reserve a delivery lease and reuse the same digest ID. Concurrent hooks cannot enqueue the same session slice twice or send a manual item in the background. Consent and authorization are checked again immediately before sending, including after token refresh.
273
290
  - API and OAuth requests enforce deadlines through refresh and response-body reads, reject redirects, and keep remote error bodies out of diagnostics. Stored OAuth takes precedence over the service-token environment fallback; replacing a login verifies the newly issued token explicitly.
291
+ - Once a refresh request is sent, the companion waits for the response and stores the rotated tokens even after the calling hook's deadline, so a refresh token the server already rotated is never discarded. When the token endpoint rejects the grant (`invalid_grant`, `invalid_client`, or `unauthorized_client`), the companion marks it for re-login: hooks stop sending requests, SessionStart tells the agent to orient through the host `brain_*` tools and to ask the user to run `brainmcp login` (no `--force` needed for a rejected grant), and `whoami` and `doctor` report it. Other orientation failures name their cause (`timeout`, `forbidden`, `http_<status>`, `network`) in the packet and in `orient_fetch_failed` diagnostics. A lapsed hourly access token with a refresh token is healthy.
274
292
  - Cloud environments (e.g. Cursor Cloud Agents, GitHub Codespaces without a local browser) do not share this machine's `~/.brainmcp` state; configure service tokens or dashboard connections for those environments.
275
293
 
276
294
  ## What gets written
@@ -60,7 +60,17 @@ export const BRAIN_MCP_INITIAL_SCOPES = [
60
60
  'workflows:read',
61
61
  ];
62
62
  /** Bump when always-on guidance text changes in a way clients should refresh. */
63
- export const GUIDANCE_VERSION = '2026.09.29';
63
+ export const GUIDANCE_VERSION = '2026.09.30';
64
+ /** Answer grounding is shared by installed guidance, MCP surfaces, and compact hooks. */
65
+ export const ANSWER_GROUNDING_GUIDANCE = [
66
+ 'Ground material factual claims in source content you actually read, current code or observed tool/test results. Attribute unchecked Brain statements to their source; stored or applied does not mean independently verified.',
67
+ 'For a why-answer or recommendation, name the source premise and explain the connection to the choice. Separate what the source states from your inference and any assumption. A source about the same topic, a search rank, or a graph link does not establish the claimed reason or outcome.',
68
+ 'Cite the actual relevant source or field beside the claim. Read exact content and needed continuations before quoting or relying on omitted details. Verify changeable claims against current source or live evidence; disclose stale, conflicting, or incomplete evidence instead of silently choosing a convenient version.',
69
+ 'If support is missing, say I cannot determine this from the available Brain context, identify what is known and unknown, and label any general reasoning separately. Continue independent work; ask for missing information only when it blocks the decision. Never fill an evidence gap with a plausible story.',
70
+ 'Never fabricate facts, metrics, citations, links, requirements, user intentions, historical actions, rejected alternatives, or reasons an earlier agent acted. Label hypotheses and illustrative examples; do not present expected benefits as measured results or assumptions as established knowledge.',
71
+ 'A saved Context Path is an agent account, not independent proof. Text matches and delivery receipts verify text or delivery, not factual truth or influence. An assumption, digest candidate, unreviewed proposal, or repeated agent claim does not become a verified fact merely by being saved or cited again.',
72
+ ].join(' ');
73
+ export const ANSWER_GROUNDING_BRIEF_GUIDANCE = 'Ground claims in sources you actually read. Separate source statements, inferences, assumptions, and unknowns; cite relevant evidence. Missing support means say you cannot determine it, not invent a reason. Stored text, search rank, and receipts do not verify truth or influence.';
64
74
  export const BRAIN_HANDLE_CATALOG = [
65
75
  { idParameter: 'activityId', kind: 'activity', scope: 'workspace', template: 'brain://workspace/{workspaceId}/activity/{activityId}', resolver: 'the Activity historical-read resource (explicit graph:read and changes:read consent; follow continuation.resourceUri for complete evidence; the reference does not authorize a revert)' },
66
76
  { idParameter: 'nodeId', kind: 'node', scope: 'workspace', template: 'brain://workspace/{workspaceId}/ref/live/node/{nodeId}', resolver: 'brain_node_read or the live-node MCP resource' },
@@ -113,6 +123,8 @@ export const BRAIN_REPORTING_GUIDE_MARKDOWN = [
113
123
  '',
114
124
  'Reports require `title`, `text`, and `html`. The `text` field is a 1-3 sentence summary shown in feeds and returned in comment lists; make it useful without opening the full report.',
115
125
  '',
126
+ ANSWER_GROUNDING_GUIDANCE,
127
+ '',
116
128
  'HTML reports are sanitized and rendered in a sandboxed frame. Use inline styles only. Scripts, event handlers, external resources, and links are removed. Data-URI images are allowed under the report size cap.',
117
129
  '',
118
130
  'Supported report HTML includes common text/table tags, `figure`/`figcaption`, data-URI `img`, and inline SVG chart primitives: `svg`, `g`, `defs`, `circle`, `ellipse`, `rect`, `line`, `path`, `polyline`, `polygon`, `text`, and `tspan` with chart attributes such as `points`, `rx`, `ry`, `stroke-width`, opacity, transform, text anchor, and font sizing.',
@@ -253,18 +265,19 @@ export const WORKSPACE_INFERENCE_GUIDANCE = 'Honor an explicit workspace selecti
253
265
  */
254
266
  export const CONTEXT_PATH_GUIDANCE = [
255
267
  'Call brain_context_path_create only when the user asks for a saved Context Path or Brain explanation link, or has established that preference for the task; an ordinary chat explanation saves nothing. Use the tool only when it is advertised. If unavailable, explain the limitation and answer in chat without inventing a link. Saving is an immediate private artifact write, separate from graph proposals; it requires context-paths:read and context-paths:write consent.',
256
- 'Use a few decision steps, usually 3–7, with concise, checkable action summaries and source influences. Never expose hidden reasoning traces or secrets. Cite each source with its kind (brain_node, workspace_rule, account_rule, workspace_skill, account_skill, user_instruction, agent_assumption) and role. A workspace Skill uses workspace_skill plus the node id; a Rule uses ruleId; an account Skill uses skillId. Use the returned activeRef for the path; workspace nodes and Skills follow that ref, while Rules and account Skills remain live. Multiple passages from one source may support a step.',
268
+ 'Use only supported decision steps, usually 3–7 when the record supports that many; a shorter honest path is valid. Never pad steps or sources to meet a count. Ground the short answer, outcome, explanation, and influence in actual source premises and observable actions; distinguish direct support, your inference, and assumptions. When a specific reason cannot be reconstructed, say so and use uncertainty rather than inventing it. A later-found source can support a present assessment but cannot prove earlier influence. Give each influence as a concrete, checkable connection; use constrains only for an actual requirement or limit in the source. Never invent a mandatory rule from a contextual preference. Use concise, checkable action summaries and source influences. Never expose hidden reasoning traces or secrets. Cite each source with its kind (brain_node, workspace_rule, account_rule, workspace_skill, account_skill, user_instruction, agent_assumption) and role. A workspace Skill uses workspace_skill plus the node id; a Rule uses ruleId; an account Skill uses skillId. Use the returned activeRef for the path; workspace nodes and Skills follow that ref, while Rules and account Skills remain live. Multiple passages from one source may support a step.',
257
269
  'Use creationMode during_work while the task is still running and reconstructed_after_work when explaining finished work. Mark a passage verbatim only when it is an exact quote; anything paraphrased is a summary. Attach a deliveryReceipt only when a read returned deliveryReceipts through this same authorization for the cited workspace, ref, source, and field. Copy the exact signed passage: receipt start/end are Unicode code-point offsets in the original field and may cover only a prefix of a returned page, up to 2,000 code points. Do not shorten that passage or pair the receipt with a summary; otherwise omit the receipt and report the evidence gap. Receipts prove delivery, source_match proves a current text match, and neither proves that a source caused a decision. Reading a source while writing the path is later_review, even with a receipt. Label assumptions as assumptions, keep the expectation origin honest (user_stated versus agent_inferred), and never invent alternatives; "I cannot reconstruct this decision from the available history" is a valid explanation.',
258
270
  'For a timeout or unknown outcome, retry the unchanged payload with the same idempotencyKey. For context_path_retry or context_path_in_progress, honor retryAfterMs when supplied and use bounded backoff; do not loop indefinitely. usage_allotment_reached records no debit for that denial; retry the unchanged request with the same key after allowance returns. context_path_capacity requires freeing storage before retrying; do not delete paths without authorization. A definitive context_path_invalid rejection names the field to repair: a changed payload needs a new idempotencyKey. For context_path_receipts_unsupported, omit the receipt, retain the passage, disclose the missing delivery evidence, and submit with a new key. context_path_receipt_invalid is never a silent downgrade: repair the receipt binding or report the failure. Never rotate keys while the original outcome is unknown, or to bypass context_path_idempotency_conflict.',
259
271
  'Return the server-provided link with one sentence on evidence gaps: it opens only for its creator unless shared in the dashboard, and saved content is historical data, not current knowledge. A pasted "Context Path step: brain://workspace/{workspaceId}/context-path/{pathId}/step/{stepId}" message is a correction handoff: read that step resource and follow any continuation, then follow the stated intention. "Revise this task" means redo the current work with the correction; "Propose a context update" means read the current Rule, Skill, or Neuron and use the proposal pipeline. The saved narrative itself is not editable. Save a replacement or follow-up path only when requested, linking it with supersedesPathId or followUpToPathId and, when relevant, predecessorStepId.',
260
272
  ].join(' ');
261
- export const CONTEXT_PATH_BRIEF_GUIDANCE = 'Call brain_context_path_create only when the user asks for a saved Context Path or Brain explanation link, or has established that preference for the task; an ordinary chat explanation saves nothing. Use the tool only when it is advertised; otherwise explain the limitation without inventing a link. Saving is an immediate private artifact write. Cite each source with its kind and role (a workspace Skill is workspace_skill plus the node id), summarize observable actions and source influences, label assumptions, and never invent alternatives. Mark passages verbatim only for exact quotes and timing honestly: reading a source while writing the path is later_review. Evidence of delivery or a text match does not prove influence. Retry an unchanged request with the same idempotencyKey and bounded backoff; honor retryAfterMs. A repaired payload after a definitive rejection needs a new key; never change keys while the outcome is unknown. Return the server-provided link with one sentence on evidence gaps; it opens only for its creator unless shared in the dashboard, and saved content is historical, not current knowledge. A pasted context-path step reference is a correction handoff: read that step resource and its continuations, then follow the stated intention (revise this task, or read current context and propose an update).';
262
- export const KNOWLEDGE_QUALITY_GUIDANCE = 'Before saving, ask whether a future agent would make a better decision with this knowledge. Search for an existing concept first: amend a matching Neuron instead of creating a near-duplicate; exact duplicate detection is not semantic deduplication. Save focused decisions, rationale, constraints, verified procedures, and recurring failure lessons with relevant paths/evidence and dated status where changeable. Append an additive learning; replace only after reading the complete current content and preserving still-valid knowledge. Do not turn every completed task into a node or save unsupported guesses. For an uncertain write outcome, reuse the same idempotencyKey only for the same unchanged request; inspect returned status before retrying. Report what was applied versus pending, or briefly explain abstention when write-back was requested.';
273
+ export const CONTEXT_PATH_BRIEF_GUIDANCE = 'Call brain_context_path_create only when the user asks for a saved Context Path or Brain explanation link, or has established that preference for the task; an ordinary chat explanation saves nothing. Use the tool only when it is advertised; otherwise explain the limitation without inventing a link. Saving is an immediate private artifact write. Cite each source with its kind and role (a workspace Skill is workspace_skill plus the node id), ground the answer and source influences in read premises and observable actions, separate inferences and assumptions, and state missing support. Never invent requirements, earlier reasons, or alternatives; never pad steps or sources to meet a count. Mark passages verbatim only for exact quotes and timing honestly: reading a source while writing the path is later_review. Evidence of delivery or a text match does not prove influence. Retry an unchanged request with the same idempotencyKey and bounded backoff; honor retryAfterMs. A repaired payload after a definitive rejection needs a new key; never change keys while the outcome is unknown. Return the server-provided link with one sentence on evidence gaps; it opens only for its creator unless shared in the dashboard, and saved content is historical, not current knowledge. A pasted context-path step reference is a correction handoff: read that step resource and its continuations, then follow the stated intention (revise this task, or read current context and propose an update).';
274
+ export const KNOWLEDGE_QUALITY_GUIDANCE = 'Before saving, ask whether a future agent would make a better decision with this knowledge. Search for an existing concept first: amend a matching Neuron instead of creating a near-duplicate; exact duplicate detection is not semantic deduplication. Save focused decisions, rationale, constraints, verified procedures, and recurring failure lessons with relevant paths/evidence and dated status where changeable. Append an additive learning; replace only after reading the complete current content and preserving still-valid knowledge. Preserve evidence provenance and uncertainty in saved knowledge. An agent assumption or suggested benefit is not an established project fact. Do not turn every completed task into a node or save unsupported guesses. For an uncertain write outcome, reuse the same idempotencyKey only for the same unchanged request; inspect returned status before retrying. Report what was applied versus pending, or briefly explain abstention when write-back was requested.';
263
275
  /** Read-only proof prompt shared by setup output and documentation consumers. */
264
276
  export function buildBrainVerificationPrompt(options) {
265
277
  const target = options?.workspaceId?.trim();
266
278
  return [
267
279
  'Use brain to verify this connection without writing anything.',
280
+ ANSWER_GROUNDING_BRIEF_GUIDANCE,
268
281
  target ? `Call brain_workspace_overview for workspaceId=${JSON.stringify(target)}.` : `Call brain_workspace_overview for the intended project. ${WORKSPACE_INFERENCE_GUIDANCE} You may omit workspaceId when the authorization default fits the task.`,
269
282
  'Report the resolved workspace and activeRef when returned, applicable Rules, and actions requiring attention. If populated, search for this project and report one relevant result, fetching missing exact content only if needed. If empty, say so and offer bootstrap without performing it. Do not create proposals, claim digests, enable capture, or record workflow runs. Separate configuration/discovery success from a successful authenticated Brain read.',
270
283
  ].join(' ');
@@ -274,7 +287,7 @@ export const CANONICAL_WORKFLOW_STEPS = [
274
287
  'Pick workspace (brain_workspaces_list if needed; infer the best authorized candidate instead of asking; overview may omit workspaceId when a default is configured)',
275
288
  'Orient with brain_workspace_overview and follow recommendedNextActions',
276
289
  'Pull context (start with the bounded brain_node_search working set; use exact reads when needed; resolve Skills and due Workflows when recommended)',
277
- 'Do the work outside brain',
290
+ 'Do the work outside brain; ground answers in read evidence and separate inferences, assumptions, and unknowns',
278
291
  'Write back only new durable learnings (brain_remember / brain_amend / brain_change_propose, or abstain; never store secrets, raw transcripts, or temporary output; digest only as disclosed fallback)',
279
292
  ];
280
293
  /** Overview payload canonicalWorkflow strings (stable, short). */
@@ -287,6 +300,7 @@ export const OVERVIEW_CANONICAL_WORKFLOW = [
287
300
  'Use brain_node_read for exact content before editing a truncated root; use brain_context_handoff or brain_graph_read only when the task needs broader context.',
288
301
  CONTEXT_RETRIEVAL_GUIDANCE,
289
302
  CONTEXT_RECOVERY_GUIDANCE,
303
+ ANSWER_GROUNDING_GUIDANCE,
290
304
  KNOWLEDGE_QUALITY_GUIDANCE,
291
305
  KNOWLEDGE_CLASS_GUIDANCE,
292
306
  KNOWLEDGE_WRITE_LIMITS,
@@ -321,7 +335,7 @@ export function buildProjectInstructionBlock(options) {
321
335
  if (workspaceId) {
322
336
  lines.push(`Workspace id: ${workspaceId}`);
323
337
  }
324
- lines.push('', '- Connection honesty: if brain_* tools are unavailable or authorization is required, say that no live brain context was loaded, help the user reconnect/login, and continue only with clearly labeled local context. Never pretend Brain was read.', `- Orient at session start: call brain_workspace_overview (workspaceId optional when this authorization has a default). Follow recommendedNextActions and treat returned Rules/Skills/Workflows as binding. Action flags: ${buildActionFlagGuidance()}`, `- ${WORKSPACE_INFERENCE_GUIDANCE}`, '- Before non-trivial work, call brain_node_search with the task intent. Its default working set includes bounded top-node content and one-hop context; use brain_node_read for exact truncated content and broader reads only when needed.', `- ${EMPTY_WORKSPACE_RESPONSE_REQUIREMENT}`, `- ${AUTHORIZED_BOOTSTRAP_DETAIL_REQUIREMENT}`, '- Before a related proposal, apply rejection guidance from learningSignals.recentDecisions. Exact duplicate creates can be blocked; update or reuse the matched item instead of retrying.', '- After meaningful work, propose only genuinely new durable project knowledge (decisions, architecture, conventions, fixes, and operational lessons). Never store secrets, credentials, personal data, raw transcripts, or temporary build/log output. If nothing reusable changed, do not propose.', `- ${CONTEXT_RETRIEVAL_GUIDANCE}`, `- ${CONTEXT_RECOVERY_GUIDANCE}`, `- ${KNOWLEDGE_QUALITY_GUIDANCE}`, `- Knowledge classes: ${KNOWLEDGE_CLASS_GUIDANCE}`, `- Write support: ${KNOWLEDGE_WRITE_LIMITS}`, `- Agent responsibility: ${PROACTIVE_WRITE_BACK_GUIDANCE}`, `- ${SECTOR_GUIDANCE}`, `- ${GRAPH_WRITE_GUIDANCE}`, `- Context Paths: ${CONTEXT_PATH_BRIEF_GUIDANCE}`, '- Use brain_session_digest only as a disclosed fallback when the user explicitly asks to capture unstructured session learnings — never as an automatic dump of every session.', '', `Guidance version: ${GUIDANCE_VERSION}`);
338
+ lines.push('', '- Connection honesty: if brain_* tools are unavailable or authorization is required, say that no live brain context was loaded, help the user reconnect/login, and continue only with clearly labeled local context. Never pretend Brain was read.', `- Orient at session start: call brain_workspace_overview (workspaceId optional when this authorization has a default). Follow recommendedNextActions and treat returned Rules/Skills/Workflows as binding. Action flags: ${buildActionFlagGuidance()}`, `- ${WORKSPACE_INFERENCE_GUIDANCE}`, '- Before non-trivial work, call brain_node_search with the task intent. Its default working set includes bounded top-node content and one-hop context; use brain_node_read for exact truncated content and broader reads only when needed.', `- ${EMPTY_WORKSPACE_RESPONSE_REQUIREMENT}`, `- ${AUTHORIZED_BOOTSTRAP_DETAIL_REQUIREMENT}`, '- Before a related proposal, apply rejection guidance from learningSignals.recentDecisions. Exact duplicate creates can be blocked; update or reuse the matched item instead of retrying.', '- After meaningful work, propose only genuinely new durable project knowledge (decisions, architecture, conventions, fixes, and operational lessons). Never store secrets, credentials, personal data, raw transcripts, or temporary build/log output. If nothing reusable changed, do not propose.', `- ${CONTEXT_RETRIEVAL_GUIDANCE}`, `- ${CONTEXT_RECOVERY_GUIDANCE}`, `- Answer grounding: ${ANSWER_GROUNDING_GUIDANCE}`, `- ${KNOWLEDGE_QUALITY_GUIDANCE}`, `- Knowledge classes: ${KNOWLEDGE_CLASS_GUIDANCE}`, `- Write support: ${KNOWLEDGE_WRITE_LIMITS}`, `- Agent responsibility: ${PROACTIVE_WRITE_BACK_GUIDANCE}`, `- ${SECTOR_GUIDANCE}`, `- ${GRAPH_WRITE_GUIDANCE}`, `- Context Paths: ${CONTEXT_PATH_BRIEF_GUIDANCE}`, '- Use brain_session_digest only as a disclosed fallback when the user explicitly asks to capture unstructured session learnings — never as an automatic dump of every session.', '', `Guidance version: ${GUIDANCE_VERSION}`);
325
339
  return lines.join('\n');
326
340
  }
327
341
  /** Compact proactive reminder injected by SessionStart / post-compaction hooks. */
@@ -332,11 +346,12 @@ export function buildLifecycleOrientationReminder(options) {
332
346
  return [
333
347
  'brainMCP reminder: verify the connection honestly, orient with brain_workspace_overview, pull the bounded brain_node_search working set before non-trivial work, follow Rules/Skills/Workflows and recent review feedback, and propose only new durable changes after meaningful work.',
334
348
  'Reuse fresh context within a task; recover omitted Rules before dependent work and stop reading when the task is sufficiently grounded. During authorized project work, propose useful changes without waiting for a separate save request; honor read-only requests. Amend existing knowledge before creating duplicates. Session digests are a disclosed fallback, not an automatic dump. Create a Context Path only when asked and the tool is advertised.',
349
+ ANSWER_GROUNDING_BRIEF_GUIDANCE,
335
350
  workspaceHint.trim(),
336
351
  `Guidance ${GUIDANCE_VERSION}.`,
337
352
  ].join(' ');
338
353
  }
339
- export const WRITE_BACK_REMINDER = GRAPH_WRITE_GUIDANCE + ' ' + PROACTIVE_WRITE_BACK_GUIDANCE + ' Never store secrets, personal data, raw transcripts, or temporary output. Exact duplicate creates may be blocked, so update or reuse the matched item. Use brain_session_digest only when the user explicitly asks to capture unstructured session learnings as a pending digest — not as an automatic dump of every session.';
354
+ export const WRITE_BACK_REMINDER = GRAPH_WRITE_GUIDANCE + ' ' + PROACTIVE_WRITE_BACK_GUIDANCE + ' ' + ANSWER_GROUNDING_BRIEF_GUIDANCE + ' Never store secrets, personal data, raw transcripts, or temporary output. Exact duplicate creates may be blocked, so update or reuse the matched item. Use brain_session_digest only when the user explicitly asks to capture unstructured session learnings as a pending digest — not as an automatic dump of every session.';
340
355
  export const AGENT_SKILL_NAME = 'using-brainmcp';
341
356
  export const AGENT_SKILL_DESCRIPTION = 'Use brain / brainmcp shared project memory: orient, pull context before work, follow Rules/Skills/Workflows, write durable learnings back as reviewable proposals, and save a Context Path only when asked for an explanation link.';
342
357
  export function buildAgentSkillMarkdown(options) {
@@ -367,6 +382,8 @@ export function buildAgentSkillMarkdown(options) {
367
382
  '## Task examples',
368
383
  '',
369
384
  '- Fix a bug: search the component and its constraints, read relevant exact content, inspect current code, then save only a reusable cause or decision that is not already captured.',
385
+ '- Explain a marketing recommendation: if a source says visitors need an understandable example, you may infer that a walkthrough could help. Label that connection as your inference; do not claim a measured conversion increase unless a source actually provides it. If the source says nothing about the proposed channel or outcome, disclose the gap.',
386
+ '- Explain an earlier decision: report only observable actions and available source context. A source found now can support a present assessment, but cannot establish the earlier agent used it. Say when the earlier reason cannot be reconstructed.',
370
387
  '- Save a decision: search for the existing concept; amend its Neuron if present, otherwise remember one focused Neuron with rationale and evidence.',
371
388
  '- Preserve a reusable procedure: propose a workspace Skill; create a Workflow when there is work to execute with steps or a schedule. Keep the underlying decision in its Neuron and reference it.',
372
389
  '- Recommend a behavioral constraint: search existing Rules, read the exact item (including revision), then propose create_workspace_rule/update_workspace_rule or account-library Rule operations through brain_change_propose. Workspace Rules and account-library items always wait for human review.',
@@ -378,6 +395,7 @@ export function buildAgentSkillMarkdown(options) {
378
395
  '',
379
396
  '- Assume MCP server instructions are already in context — still call overview.',
380
397
  '- Claim Brain context was loaded when tools were unavailable or authorization failed.',
398
+ '- Attach a relevant-sounding source to an unsupported conclusion, invent a concrete requirement from a vague quote, or save an assumption as a verified fact.',
381
399
  '- Stop to ask which workspace to use merely because several authorized workspaces are plausible; infer, state the assumption, verify, and continue.',
382
400
  '- Dump every session into a digest automatically.',
383
401
  '- Store secrets, credentials, personal data, raw transcripts, or temporary build/log output.',
@@ -664,13 +682,14 @@ export function buildServerInstructions() {
664
682
  `2. Pick the target workspace — MCP OAuth is account-scoped, so one authorization can access consented workspaces only. ${WORKSPACE_INFERENCE_GUIDANCE} brain_workspace_overview may omit workspaceId when this authorization has a default workspace.`,
665
683
  `3. Orient — call brain_workspace_overview for the chosen workspace. It returns identity, review policy, graph health, pending review, due work, writeBackReminder, and ordered recommendedNextActions; follow them. Action flags: ${buildActionFlagGuidance()}`,
666
684
  '4. Pull — brain_node_search returns a bounded working set by default: ranked roots with content plus one-hop summaries around the selected root. Pass aroundRootId to choose that root explicitly, and inspect retrievalMode to distinguish hybrid, FTS-only, and graph-expansion results. Use responseMode=snippets for discovery, brain_node_read for exact truncated content, and graph_read/context_handoff only when broader context is genuinely needed. Resolve Skills (brain_skill_resolve) and due Workflows (brain_workflow_due) when recommended.',
667
- '5. Do the work outside brain.',
685
+ '5. Do the work outside brain; apply the answer-grounding contract below before presenting conclusions.',
668
686
  '6. Write back — first apply learningSignals.recentDecisions. Use the audited proposal pipeline only for new durable project-specific graph learnings (reviewable proposals), and abstain when nothing reusable changed. Never store secrets, credentials, personal data, raw transcripts, or temporary build/log output. Exact duplicate creates can be blocked; update/reuse the matched item or wait for the existing pending proposal instead of retrying. Report the proposal id/status. brain_session_digest remains an explicitly user-requested disclosed fallback, not an automatic dump; brain_tags_set organizes via proposals; brain_comment_create leaves an immediate human note/report; brain_workflow_record_run records a due Workflow. To create and link new nodes in one proposal, pre-assign UUID targetIds and reference them from later operations.',
669
687
  '',
670
688
  'CROSS-AGENT CLIPBOARD: brain_copy immediately stores the current relevant message/output (or something the user names) on an account-wide clipboard; brain_paste retrieves the latest clip or the last N (newest first, max 10). No workspaceId is required. Use this to move working context between agents or workspaces without manual copy/paste.',
671
689
  '',
672
690
  `RETRIEVAL: ${CONTEXT_RETRIEVAL_GUIDANCE}`,
673
691
  `RECOVERY: ${CONTEXT_RECOVERY_GUIDANCE}`,
692
+ `ANSWER GROUNDING: ${ANSWER_GROUNDING_GUIDANCE}`,
674
693
  `QUALITY: ${KNOWLEDGE_QUALITY_GUIDANCE}`,
675
694
  `KNOWLEDGE CLASSES: ${KNOWLEDGE_CLASS_GUIDANCE}`,
676
695
  `WRITE SUPPORT: ${KNOWLEDGE_WRITE_LIMITS}`,
@@ -713,7 +732,7 @@ export function buildCanonicalWorkflowMarkdown(options) {
713
732
  `2. **Pick workspace** — OAuth is account-scoped and limited to consented workspaces. ${WORKSPACE_INFERENCE_GUIDANCE} \`brain_workspace_overview\` may omit \`workspaceId\` when a default is configured.`,
714
733
  `3. **Orient** — \`brain_workspace_overview\` returns identity, review policy, graph health, pending review, due work, \`writeBackReminder\`, and \`recommendedNextActions\`. Follow them. Action flags: ${buildActionFlagGuidance()}`,
715
734
  '4. **Pull** — `brain_node_search` returns bounded roots plus one-hop context by default. Use `responseMode="snippets"` for discovery, `brain_node_read` for exact truncated content, and `brain_graph_read` / `brain_context_handoff` only when broader scope is needed. Use `brain_skill_resolve` and `brain_workflow_due` when recommended.',
716
- '5. **Work** — do the task outside brain.',
735
+ '5. **Work** — do the task outside brain; apply the answer-grounding contract below before presenting conclusions.',
717
736
  '6. **Write back** — apply `learningSignals.recentDecisions`, then use the audited proposal pipeline only for new durable project-specific learnings. Never store secrets, personal data, raw transcripts, or temporary output. Report the proposal id/status and abstain when nothing reusable changed. Exact duplicate creates can be blocked; update/reuse the matched item or wait for its pending proposal. `brain_session_digest` remains an explicitly user-requested disclosed fallback; use tags/comments/workflow-run tools for their specific jobs.',
718
737
  '',
719
738
  '## Cross-agent clipboard',
@@ -726,6 +745,7 @@ export function buildCanonicalWorkflowMarkdown(options) {
726
745
  `- ${GRAPH_WRITE_GUIDANCE}`,
727
746
  `- ${CONTEXT_RETRIEVAL_GUIDANCE}`,
728
747
  `- ${CONTEXT_RECOVERY_GUIDANCE}`,
748
+ `- Answer grounding: ${ANSWER_GROUNDING_GUIDANCE}`,
729
749
  `- ${KNOWLEDGE_QUALITY_GUIDANCE}`,
730
750
  `- Knowledge classes: ${KNOWLEDGE_CLASS_GUIDANCE}`,
731
751
  `- Write support: ${KNOWLEDGE_WRITE_LIMITS}`,
@@ -0,0 +1,177 @@
1
+ export class ApiClientError extends Error {
2
+ status;
3
+ statusText;
4
+ body;
5
+ response;
6
+ constructor(response, body) {
7
+ super(`brain API request failed: ${response.status} ${response.statusText}`);
8
+ this.name = 'ApiClientError';
9
+ this.status = response.status;
10
+ this.statusText = response.statusText;
11
+ this.body = body;
12
+ this.response = response;
13
+ }
14
+ get isUnauthorized() {
15
+ return this.status === 401;
16
+ }
17
+ }
18
+ export class BrainCpApiClient {
19
+ baseUrl;
20
+ fetchImpl;
21
+ auth;
22
+ defaultHeaders;
23
+ constructor(options) {
24
+ this.baseUrl = normalizeBaseUrl(options.baseUrl);
25
+ this.fetchImpl = options.fetch ?? fetch;
26
+ this.auth = options.auth;
27
+ this.defaultHeaders = options.headers;
28
+ }
29
+ url(path, searchParams) {
30
+ return buildApiUrl(this.baseUrl, path, searchParams);
31
+ }
32
+ request(path, options = {}) {
33
+ const headers = mergeHeaders(this.defaultHeaders, options.headers);
34
+ return apiFetch(this.url(path, options.searchParams), {
35
+ ...options,
36
+ auth: options.auth ?? this.auth,
37
+ fetch: this.fetchImpl,
38
+ headers,
39
+ });
40
+ }
41
+ async json(path, options = {}) {
42
+ const response = await this.request(path, options);
43
+ return response.json();
44
+ }
45
+ createContextPath(workspaceId, body) {
46
+ return this.json(`/api/workspaces/${encodeURIComponent(workspaceId)}/context-paths`, { json: body, method: 'POST' });
47
+ }
48
+ listContextPaths(workspaceId, searchParams) {
49
+ return this.json(`/api/workspaces/${encodeURIComponent(workspaceId)}/context-paths`, { searchParams });
50
+ }
51
+ getContextPath(workspaceId, pathId, searchParams) {
52
+ return this.json(`/api/workspaces/${encodeURIComponent(workspaceId)}/context-paths/${encodeURIComponent(pathId)}`, { searchParams });
53
+ }
54
+ getContextPathStep(workspaceId, pathId, stepId) {
55
+ return this.json(`/api/workspaces/${encodeURIComponent(workspaceId)}/context-paths/${encodeURIComponent(pathId)}/steps/${encodeURIComponent(stepId)}`);
56
+ }
57
+ deleteContextPath(workspaceId, pathId) {
58
+ return this.json(`/api/workspaces/${encodeURIComponent(workspaceId)}/context-paths/${encodeURIComponent(pathId)}`, { method: 'DELETE' });
59
+ }
60
+ updateContextPathVisibility(workspaceId, pathId, body) {
61
+ return this.json(`/api/workspaces/${encodeURIComponent(workspaceId)}/context-paths/${encodeURIComponent(pathId)}/visibility`, { json: body, method: 'PATCH' });
62
+ }
63
+ }
64
+ export function createApiClient(options) {
65
+ return new BrainCpApiClient(options);
66
+ }
67
+ /**
68
+ * Encode a single path segment (workspace/node/proposal id, …) for safe
69
+ * interpolation into an API path. Use this at every `${value}` site rather than
70
+ * relying on the value looking like an id.
71
+ */
72
+ export function apiPathSegment(value) {
73
+ const encoded = encodeURIComponent(value);
74
+ // `encodeURIComponent` leaves `.` alone, so an all-dots value would still be
75
+ // a `.` / `..` path segment that the URL resolver collapses. Percent-encode
76
+ // those so the value is always a single opaque segment.
77
+ return /^\.+$/.test(encoded) ? encoded.replaceAll('.', '%2E') : encoded;
78
+ }
79
+ /**
80
+ * Build an API URL. The base origin is pinned as a string prefix — never via
81
+ * the two-argument `new URL(path, base)` resolver, which treats a `//host/…`
82
+ * path as scheme-relative and would forward the caller's bearer token to an
83
+ * attacker host. Paths must be clean absolute paths so a prompt-injected id
84
+ * containing `..` cannot retarget the request at a different endpoint than the
85
+ * caller intended.
86
+ */
87
+ export function buildApiUrl(baseUrl, path, searchParams) {
88
+ const normalizedBase = normalizeBaseUrl(baseUrl);
89
+ const cleanPath = path.startsWith('/') ? path.slice(1) : path;
90
+ const pathOnly = cleanPath.split('?')[0] ?? cleanPath;
91
+ if (pathOnly.startsWith('/') ||
92
+ pathOnly.includes('\\') ||
93
+ pathOnly.includes('//') ||
94
+ pathOnly.split('/').some((segment) => segment === '.' || segment === '..')) {
95
+ throw new Error(`Unsafe API request path: ${path}`);
96
+ }
97
+ const url = new URL(`${normalizedBase}/${cleanPath}`);
98
+ if (url.origin !== new URL(`${normalizedBase}/`).origin) {
99
+ throw new Error(`Unsafe API request path: ${path}`);
100
+ }
101
+ if (searchParams instanceof URLSearchParams) {
102
+ searchParams.forEach((value, key) => url.searchParams.append(key, value));
103
+ }
104
+ else if (searchParams) {
105
+ for (const [key, value] of Object.entries(searchParams)) {
106
+ if (value !== null && value !== undefined) {
107
+ url.searchParams.set(key, String(value));
108
+ }
109
+ }
110
+ }
111
+ return url;
112
+ }
113
+ export async function apiFetch(input, options = {}) {
114
+ const headers = new Headers(options.headers);
115
+ applyAuthHeaders(headers, options.auth);
116
+ let body = options.body;
117
+ if (options.json !== undefined) {
118
+ body = JSON.stringify(options.json);
119
+ if (!headers.has('content-type')) {
120
+ headers.set('content-type', 'application/json');
121
+ }
122
+ }
123
+ else if (body !== undefined && body !== null && !isBodyInit(body)) {
124
+ body = JSON.stringify(body);
125
+ if (!headers.has('content-type')) {
126
+ headers.set('content-type', 'application/json');
127
+ }
128
+ }
129
+ const fetchImpl = options.fetch ?? fetch;
130
+ const response = await fetchImpl(input, {
131
+ ...options,
132
+ body,
133
+ headers,
134
+ });
135
+ if (!response.ok) {
136
+ throw new ApiClientError(response, await response.clone().text());
137
+ }
138
+ return response;
139
+ }
140
+ export function applyAuthHeaders(headers, auth) {
141
+ if (!auth)
142
+ return headers;
143
+ if (auth.type === 'bearer') {
144
+ headers.set('authorization', `Bearer ${auth.token}`);
145
+ }
146
+ else if (auth.type === 'cookie') {
147
+ headers.set('cookie', auth.cookie);
148
+ }
149
+ else {
150
+ new Headers(auth.headers).forEach((value, key) => headers.set(key, value));
151
+ }
152
+ return headers;
153
+ }
154
+ function mergeHeaders(...parts) {
155
+ const merged = new Headers();
156
+ for (const part of parts) {
157
+ if (!part)
158
+ continue;
159
+ new Headers(part).forEach((value, key) => merged.set(key, value));
160
+ }
161
+ return merged;
162
+ }
163
+ function normalizeBaseUrl(baseUrl) {
164
+ const trimmed = baseUrl.trim();
165
+ if (!trimmed) {
166
+ throw new Error('API base URL is required.');
167
+ }
168
+ return trimmed.replace(/\/+$/, '');
169
+ }
170
+ function isBodyInit(value) {
171
+ return (typeof value === 'string' ||
172
+ value instanceof Blob ||
173
+ value instanceof ArrayBuffer ||
174
+ value instanceof FormData ||
175
+ value instanceof URLSearchParams ||
176
+ value instanceof ReadableStream);
177
+ }
@@ -54,7 +54,8 @@ export function resetCompanionLocalState(home) {
54
54
  export async function commitCompanionCredentials(input) {
55
55
  const commit = async () => {
56
56
  const previous = await input.store.get();
57
- if (previous && !input.force)
57
+ // A grant the server already rejected is not a session worth protecting.
58
+ if (previous && !input.force && !previous.reauthRequired)
58
59
  throw new Error('Already authenticated. Pass --force to replace the stored credentials.');
59
60
  const previousAccount = input.home ? getCurrentAccountId(input.home) : null;
60
61
  const accountId = input.credentials.userId;
@@ -143,7 +144,7 @@ export async function login(options = {}) {
143
144
  return;
144
145
  }
145
146
  const existing = await store.get();
146
- if (existing && !options.force) {
147
+ if (existing && !options.force && !existing.reauthRequired) {
147
148
  throw new Error('Already authenticated. Pass --force to replace the stored companion credentials.');
148
149
  }
149
150
  const scopes = [...BRAINMCP_CLI_DEFAULT_SCOPES];
@@ -345,8 +346,9 @@ export async function whoami(options = {}) {
345
346
  return;
346
347
  }
347
348
  const prefs = readPreferences(options.runtimeHome ?? process.env.BRAINMCP_HOME ?? process.env.BRAIN_HOME);
349
+ const reauthRequired = creds.authType === 'oauth' && Boolean(creds.reauthRequired);
348
350
  const responseEnvelope = {
349
- status: 'authenticated',
351
+ status: reauthRequired ? 'reauth_required' : 'authenticated',
350
352
  authType: creds.authType,
351
353
  userId: creds.userId ?? (creds.authType === 'service' ? SERVICE_ACCOUNT_ID : undefined),
352
354
  clientId: creds.clientId ?? (creds.authType === 'service' ? 'service-token' : BRAINMCP_CLI_CLIENT_ID),
@@ -364,7 +366,9 @@ export async function whoami(options = {}) {
364
366
  output(JSON.stringify(responseEnvelope, null, 2));
365
367
  }
366
368
  else {
367
- output(`Status: Authenticated (${creds.authType})`);
369
+ output(reauthRequired
370
+ ? 'Status: Sign-in expired or revoked. Run `brainmcp login` to sign in again.'
371
+ : `Status: Authenticated (${creds.authType})`);
368
372
  if (responseEnvelope.clientId) {
369
373
  output(`Client: ${responseEnvelope.clientId}`);
370
374
  }
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- export declare const HOOK_MANAGED_TAG = "brainmcp:managed:hook:v2026.09.29";
1
+ export declare const HOOK_MANAGED_TAG = "brainmcp:managed:hook:v2026.09.30";
2
2
  export interface HookInstallPlan {
3
3
  host: string;
4
4
  hookFile: string;
@@ -1,5 +1,15 @@
1
1
  import type { CredentialStore, StoredCredentials } from './credentials.js';
2
2
  import { OAuthClient } from './oauth-client.js';
3
+ /**
4
+ * The companion grant is dead (its refresh token was rejected) and only a new
5
+ * `brainmcp login` can restore it. `status` is 401 so existing auth-failure
6
+ * classifiers (capture retry, orientation) treat it as an auth problem.
7
+ */
8
+ export declare class CompanionReauthRequiredError extends Error {
9
+ readonly status = 401;
10
+ readonly code = "reauth_required";
11
+ constructor();
12
+ }
3
13
  export interface ApiClientOptions {
4
14
  apiUrl?: string;
5
15
  store: CredentialStore;
@@ -1,7 +1,20 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
  import { describeMisdirectedCompanionApi, resolveCompanionApiUrl } from './endpoints.js';
3
- import { grantedCliScopes, OAuthClient } from './oauth-client.js';
3
+ import { grantedCliScopes, OAuthClient, OAuthGrantRejectedError } from './oauth-client.js';
4
4
  import { validateHttpUrl, withRequestDeadline } from './http.js';
5
+ /**
6
+ * The companion grant is dead (its refresh token was rejected) and only a new
7
+ * `brainmcp login` can restore it. `status` is 401 so existing auth-failure
8
+ * classifiers (capture retry, orientation) treat it as an auth problem.
9
+ */
10
+ export class CompanionReauthRequiredError extends Error {
11
+ status = 401;
12
+ code = 'reauth_required';
13
+ constructor() {
14
+ super('BrainMCP CLI sign-in expired or was revoked. Run `brainmcp login` to sign in again.');
15
+ this.name = 'CompanionReauthRequiredError';
16
+ }
17
+ }
5
18
  export class ApiClient {
6
19
  apiUrl;
7
20
  store;
@@ -42,6 +55,9 @@ export class ApiClient {
42
55
  if (options.expectedAuthorizationId && creds?.authorizationId !== options.expectedAuthorizationId) {
43
56
  throw new Error('Companion authorization changed before the request.');
44
57
  }
58
+ if (creds?.authType === 'oauth' && creds.reauthRequired) {
59
+ throw new CompanionReauthRequiredError();
60
+ }
45
61
  const url = new URL(path, `${this.apiUrl}/`);
46
62
  if (url.origin !== new URL(this.apiUrl).origin || url.username || url.password) {
47
63
  throw new Error('API requests must use the configured API origin.');
@@ -153,14 +169,19 @@ export class ApiClient {
153
169
  if (!refreshToken)
154
170
  return null;
155
171
  try {
172
+ // Discovery has no side effects, so it stays under the caller's deadline.
156
173
  const endpoints = await this.oauthClient.discoverEndpoints(signal);
174
+ signal.throwIfAborted();
175
+ // Once the refresh token is on the wire the server may rotate it, which
176
+ // invalidates the stored one. The caller's deadline must not abandon that
177
+ // response or the persist below: dropping it strands the only valid
178
+ // refresh token and kills the grant. The OAuth client's own timeout still
179
+ // bounds the exchange; a timed-out caller just stops waiting for it.
157
180
  const tokenResponse = await this.oauthClient.refreshAccessToken({
158
181
  tokenEndpoint: endpoints.tokenEndpoint,
159
182
  refreshToken,
160
- signal,
161
183
  });
162
184
  return await this.store.withRefreshLock(async (current) => {
163
- signal.throwIfAborted();
164
185
  if (!current || current.authType !== 'oauth' || current.authorizationId !== original.authorizationId || current.userId !== original.userId)
165
186
  return null;
166
187
  if (current.refreshLease?.leaseHolder !== leaseHolder) {
@@ -191,16 +212,21 @@ export class ApiClient {
191
212
  });
192
213
  }
193
214
  catch (error) {
215
+ const rejection = error instanceof OAuthGrantRejectedError ? error : null;
194
216
  await this.store.withRefreshLock(async (current) => {
195
217
  if (current?.authType === 'oauth' && current.refreshLease?.leaseHolder === leaseHolder) {
196
218
  await this.store.set({
197
219
  ...current,
198
220
  refreshLease: undefined,
221
+ // Mark the grant dead only if no other process rotated it meanwhile.
222
+ ...(rejection && current.refreshToken === refreshToken
223
+ ? { reauthRequired: { reason: 'refresh_rejected', oauthError: rejection.oauthError, detectedAt: new Date().toISOString() } }
224
+ : {}),
199
225
  updatedAt: new Date().toISOString(),
200
226
  });
201
227
  }
202
228
  });
203
- throw error;
229
+ throw rejection ? new CompanionReauthRequiredError() : error;
204
230
  }
205
231
  }
206
232
  }