@a-company/paradigm 6.1.0 → 6.2.1
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/arch-5UVPSOG2.js +3 -0
- package/dist/arch-loader-T3TARMSO.js +2 -0
- package/dist/chunk-ARLB6YYW.js +3 -0
- package/dist/chunk-EMGJWT7D.js +111 -0
- package/dist/chunk-MA75GS7J.js +635 -0
- package/dist/chunk-SU5F5D4I.js +3 -0
- package/dist/index.js +6 -6
- package/dist/mcp.js +3 -52
- package/dist/reindex-PJVOMN57.js +2 -0
- package/dist/tools-BPEKRC2U.js +2 -0
- package/dist/university-content/notes/.purpose +14 -0
- package/dist/university-content/notes/N-para-701-arch-mcp-tools.md +149 -0
- package/dist/university-content/notes/N-para-701-arch-yaml-format.md +123 -0
- package/dist/university-content/notes/N-para-701-atlas-agent.md +83 -0
- package/dist/university-content/paths/.purpose +12 -0
- package/dist/university-content/paths/LP-para-701.yaml +15 -0
- package/dist/university-content/quizzes/.purpose +14 -0
- package/dist/university-content/quizzes/Q-para-701-arch-mcp-tools.yaml +66 -0
- package/dist/university-content/quizzes/Q-para-701-arch-yaml-format.yaml +66 -0
- package/dist/university-content/quizzes/Q-para-701-atlas-agent.yaml +66 -0
- package/dist/university-content/quizzes/Q-plsat-v3.yaml +126 -1
- package/dist/university-ui/assets/{index-CkgaxOXi.js → index-SNyIB61M.js} +2 -2
- package/dist/university-ui/assets/{index-CkgaxOXi.js.map → index-SNyIB61M.js.map} +1 -1
- package/dist/university-ui/index.html +1 -1
- package/package.json +1 -1
- package/dist/chunk-K7EQHFZP.js +0 -111
- package/dist/chunk-MOVDVBU7.js +0 -605
- package/dist/reindex-GSRV4MQO.js +0 -2
- package/dist/tools-VNDXOFXR.js +0 -2
package/dist/mcp.js
CHANGED
|
@@ -1,54 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {d,g,h,e,a as a$1,b as b$1,f,c}from'./chunk-MOVDVBU7.js';import'./chunk-4UJ4NIEQ.js';import'./chunk-4N56FRNE.js';import'./chunk-Q527BPUF.js';import'./chunk-KLBH26PA.js';import'./chunk-JNSJVCTU.js';import'./chunk-XROULIQN.js';import'./chunk-ZUAUFZRJ.js';import'./chunk-3KVVC4WV.js';import {m as m$1,n,p,h as h$1,i,ua}from'./chunk-K7EQHFZP.js';import'./chunk-M4UMM6DC.js';import'./chunk-GRZQIKST.js';import'./chunk-KAFQA7HV.js';import {j as j$1}from'./chunk-6QXBXZF6.js';import {b,a}from'./chunk-EK4ZRIFJ.js';import'./chunk-LAYBUKMB.js';import'./chunk-DVZWCXB6.js';import'./chunk-QGZRM6ZB.js';import'./chunk-K7X3Z3GL.js';import'./chunk-5TAVYPOV.js';import {Server}from'@modelcontextprotocol/sdk/server/index.js';import {StdioServerTransport}from'@modelcontextprotocol/sdk/server/stdio.js';import {ListResourcesRequestSchema,ReadResourceRequestSchema}from'@modelcontextprotocol/sdk/types.js';import*as l from'fs';import*as m from'path';function se(e){return {id:e.id,symbol:`^${e.id}`,description:e.description,locks:e.locks?.map(s=>({id:s.id,description:s.description,keys:s.keys?.map(n=>n.expression||n),mode:s.mode||"all"})),prizes:e.prizes?.map(s=>({id:s.id,oneTime:s.oneTime}))}}function F(e){let s=e.gateConfig?.gates||[],n=i(e.index,"gate"),t=new Map;for(let o of n){let i=o.symbol.replace(/^\^/,"");t.set(i,{id:i,symbol:o.symbol,description:o.description,source:"purpose",filePath:o.filePath,data:o.data});}for(let o of s)t.set(o.id,{...se(o),source:"portal.yaml"});return Array.from(t.values())}function I(e){let s=e.gateConfig?.flows||[],n=i(e.index,"flow"),t=new Map;for(let o of n){let i=o.symbol.replace(/^\$/,"");t.set(i,{id:i,symbol:o.symbol,description:o.description,source:"purpose",filePath:o.filePath,data:o.data});}for(let o of s)t.set(o.id,{id:o.id,symbol:`$${o.id}`,description:o.description,gates:o.gates,source:"portal.yaml"});return Array.from(t.values())}function U(){return [{uri:"paradigm://wisdom/preferences",name:"Wisdom - Preferences",description:"Team preferences for patterns, testing, and code style",mimeType:"application/json"},{uri:"paradigm://wisdom/antipatterns",name:"Wisdom - Antipatterns",description:"What NOT to do, with reasons and alternatives",mimeType:"application/json"},{uri:"paradigm://wisdom/decisions",name:"Wisdom - Decisions",description:"Architectural Decision Records (ADRs) index",mimeType:"application/json"}]}async function z(e$1,s){if(e$1==="wisdom/preferences"){let n=await e(s);return {handled:true,text:JSON.stringify({version:n.preferences?.version||"1.0",global:n.preferences?.global||{},by_symbol:n.preferences?.by_symbol||{},symbol_count:Object.keys(n.preferences?.by_symbol||{}).length},null,2)}}if(e$1.startsWith("wisdom/preferences/")){let n=decodeURIComponent(e$1.replace("wisdom/preferences/","")),t=await e(s),o=a$1(t,n);return {handled:true,text:JSON.stringify({symbol:n,preferences:o.preferences,global:t.preferences?.global||{}},null,2)}}if(e$1==="wisdom/antipatterns"){let n=await e(s);return {handled:true,text:JSON.stringify({count:n.antipatterns.length,antipatterns:n.antipatterns},null,2)}}if(e$1.startsWith("wisdom/antipatterns/")){let n=decodeURIComponent(e$1.replace("wisdom/antipatterns/","")),t=await e(s),o=a$1(t,n);return {handled:true,text:JSON.stringify({symbol:n,count:o.antipatterns.length,antipatterns:o.antipatterns},null,2)}}if(e$1==="wisdom/decisions"){let n=await e(s);return {handled:true,text:JSON.stringify({count:n.decisions.length,decisions:n.decisions.map(t=>({id:t.id,title:t.title,status:t.status,date:t.date,symbols:t.symbols}))},null,2)}}if(e$1.startsWith("wisdom/decision/")){let n=e$1.replace("wisdom/decision/",""),t=await e(s),o=t.decisions.find(i=>i.id===n);return o?{handled:true,text:JSON.stringify(o,null,2)}:{handled:true,text:JSON.stringify({error:"Decision not found",id:n,available:t.decisions.map(i=>i.id)},null,2)}}if(e$1.startsWith("wisdom/expertise/")){let n=decodeURIComponent(e$1.replace("wisdom/expertise/","")),t=await e(s),o=b$1(t,{symbol:n});return {handled:true,text:JSON.stringify({symbol:n,count:o.length,experts:o.map(i=>({name:i.name,symbols:i.symbols,areas:i.areas,contact:i.contact}))},null,2)}}return {handled:false,text:""}}function G(){return [{uri:"paradigm://history/fragile",name:"History - Fragile Symbols",description:"Symbols with high fragility that need extra care when modifying",mimeType:"application/json"},{uri:"paradigm://history/validation/summary",name:"History - Validation Summary",description:"Overall validation statistics and pass rates",mimeType:"application/json"}]}async function $(e,s){if(e.startsWith("history/symbol/")&&!e.endsWith("/recent")){let n=decodeURIComponent(e.replace("history/symbol/","")),t=await f(s),o=c(t,n);return {handled:true,text:JSON.stringify({symbol:n,summary:o.summary?{total_changes:o.summary.total_changes,last_modified:o.summary.last_modified,stability_score:o.summary.stability_score,fragility:o.summary.fragility,contributors:o.summary.contributors}:null,recent:o.recent,co_changes:o.co_changes,validation:o.validation},null,2)}}if(e.startsWith("history/symbol/")&&e.endsWith("/recent")){let n=decodeURIComponent(e.replace("history/symbol/","").replace("/recent","")),t=await f(s),o=c(t,n);return {handled:true,text:JSON.stringify({symbol:n,fragility:o.summary?.fragility||"unknown",stability_score:o.summary?.stability_score,recent:o.recent.slice(0,5)},null,2)}}if(e==="history/fragile"){let n=await f(s);return {handled:true,text:JSON.stringify({count:n.index?.fragile_symbols?.length||0,fragile_symbols:n.index?.fragile_symbols||[],recommendation:"Consider adding extra test coverage and reviewing recent changes before modifying these symbols"},null,2)}}if(e.startsWith("history/cochanges/")){let n=decodeURIComponent(e.replace("history/cochanges/","")),o=(await f(s)).index?.co_changes?.filter(i=>i.symbols.includes(n))||[];return {handled:true,text:JSON.stringify({symbol:n,count:o.length,co_changes:o.map(i=>({with:i.symbols.filter(r=>r!==n),frequency:i.frequency,correlation:i.correlation})),recommendation:o.length>0?"These symbols often change together - consider if they need updates too":"No strong co-change patterns detected"},null,2)}}if(e==="history/validation/summary"){let n=await f(s);return {handled:true,text:JSON.stringify({last_run:n.validation?.last_run,total_validations:n.validation?.total_validations||0,pass_rate:n.validation?.pass_rate||0,by_symbol:n.validation?.by_symbol||{}},null,2)}}return {handled:false,text:""}}function q(){return [{uri:"paradigm://context/agent-protocol",name:"Agent Protocol",description:"IMPORTANT: Read this first. Workflow instructions for using Paradigm MCP tools effectively.",mimeType:"text/markdown"},{uri:"paradigm://context/session",name:"Session Info",description:"Current MCP session statistics and context usage estimate",mimeType:"application/json"},{uri:"paradigm://context/handoff-guide",name:"Handoff Guide",description:"When and how to perform context handoffs",mimeType:"text/markdown"}]}async function H(e,s){if(e==="context/agent-protocol")return {handled:true,text:`# Agent Protocol for Paradigm MCP Tools
|
|
3
|
-
|
|
4
|
-
## Query Before Modify
|
|
5
|
-
|
|
6
|
-
**Always query before making changes** - this ensures you understand impact and dependencies.
|
|
7
|
-
|
|
8
|
-
| Before doing this... | Call this MCP tool |
|
|
9
|
-
|---------------------|-------------------|
|
|
10
|
-
| Modifying a symbol | \`paradigm_ripple\` with the symbol |
|
|
11
|
-
| Starting a session | \`paradigm_status\` for project overview |
|
|
12
|
-
| Understanding code | \`paradigm_navigate\` with explore intent |
|
|
13
|
-
| Checking dependencies | \`paradigm_related\` for connections |
|
|
14
|
-
|
|
15
|
-
## Example Workflow
|
|
16
|
-
|
|
17
|
-
1. **Get oriented**: Call \`paradigm_status\` to see project symbols and health
|
|
18
|
-
2. **Find relevant code**: Call \`paradigm_navigate\` with intent "find" or "explore"
|
|
19
|
-
3. **Before editing**: Call \`paradigm_ripple\` on symbols you'll modify
|
|
20
|
-
4. **Check context**: Call \`paradigm_session_health\` every 10-15 tool calls
|
|
21
|
-
|
|
22
|
-
## Benefits
|
|
23
|
-
|
|
24
|
-
- **Fresh data**: Always current from live project index
|
|
25
|
-
- **Precise**: Only get the data you need
|
|
26
|
-
- **Token-efficient**: ~100 tokens per query vs ~2000 for reading files
|
|
27
|
-
|
|
28
|
-
## Context Monitoring
|
|
29
|
-
|
|
30
|
-
Call \`paradigm_session_health\` periodically to monitor session health:
|
|
31
|
-
- **<50%**: Continue working
|
|
32
|
-
- **50-70%**: Plan a stopping point
|
|
33
|
-
- **70-85%**: Prepare handoff soon
|
|
34
|
-
- **>85%**: Handoff after current task
|
|
35
|
-
|
|
36
|
-
## Available Tools Summary
|
|
37
|
-
|
|
38
|
-
| Tool | Purpose |
|
|
39
|
-
|------|---------|
|
|
40
|
-
| \`paradigm_status\` | Project overview and health |
|
|
41
|
-
| \`paradigm_search\` | Find symbols by name/description |
|
|
42
|
-
| \`paradigm_ripple\` | Impact analysis before changes |
|
|
43
|
-
| \`paradigm_related\` | Symbol dependencies |
|
|
44
|
-
| \`paradigm_navigate\` | Codebase exploration |
|
|
45
|
-
| \`paradigm_session_health\` | Session health monitoring |
|
|
46
|
-
| \`paradigm_handoff_prepare\` | Prepare context handoff |
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
*This protocol ensures efficient, safe modifications to the codebase.*
|
|
51
|
-
`};if(e==="context/session"){let n=j$1(),t=n.getStats(),o=n.getDurationMinutes();return {handled:true,text:JSON.stringify({session:{durationMinutes:o,startTime:new Date(t.startTime).toISOString(),lastActivity:new Date(t.lastActivity).toISOString()},interactions:{toolCalls:t.totals.toolCallCount,resourceReads:t.totals.resourceReadCount,totalInteractions:t.totals.toolCallCount+t.totals.resourceReadCount},tokens:{estimatedMcpContribution:t.totals.totalTokens,note:"Use paradigm_session_health tool for full analysis with handoff recommendations"}},null,2)}}return e==="context/handoff-guide"?{handled:true,text:`# Context Handoff Guide
|
|
2
|
+
import {d,g,h,e,a as a$1,b as b$2,f,c}from'./chunk-MA75GS7J.js';import {b as b$1,ga}from'./chunk-EMGJWT7D.js';import'./chunk-4UJ4NIEQ.js';import'./chunk-4N56FRNE.js';import'./chunk-Q527BPUF.js';import'./chunk-KLBH26PA.js';import'./chunk-ARLB6YYW.js';import {p,q as q$1,k,l as l$1}from'./chunk-SU5F5D4I.js';import'./chunk-JNSJVCTU.js';import'./chunk-XROULIQN.js';import'./chunk-ZUAUFZRJ.js';import'./chunk-3KVVC4WV.js';import'./chunk-M4UMM6DC.js';import'./chunk-GRZQIKST.js';import'./chunk-KAFQA7HV.js';import {j as j$1}from'./chunk-6QXBXZF6.js';import {b,a}from'./chunk-EK4ZRIFJ.js';import'./chunk-LAYBUKMB.js';import'./chunk-DVZWCXB6.js';import'./chunk-QGZRM6ZB.js';import'./chunk-K7X3Z3GL.js';import'./chunk-5TAVYPOV.js';import {Server}from'@modelcontextprotocol/sdk/server/index.js';import {StdioServerTransport}from'@modelcontextprotocol/sdk/server/stdio.js';import {ListResourcesRequestSchema,ReadResourceRequestSchema}from'@modelcontextprotocol/sdk/types.js';import*as l from'fs';import*as m from'path';function se(e){return {id:e.id,symbol:`^${e.id}`,description:e.description,locks:e.locks?.map(s=>({id:s.id,description:s.description,keys:s.keys?.map(n=>n.expression||n),mode:s.mode||"all"})),prizes:e.prizes?.map(s=>({id:s.id,oneTime:s.oneTime}))}}function L(e){let s=e.gateConfig?.gates||[],n=l$1(e.index,"gate"),t=new Map;for(let o of n){let i=o.symbol.replace(/^\^/,"");t.set(i,{id:i,symbol:o.symbol,description:o.description,source:"purpose",filePath:o.filePath,data:o.data});}for(let o of s)t.set(o.id,{...se(o),source:"portal.yaml"});return Array.from(t.values())}function F(e){let s=e.gateConfig?.flows||[],n=l$1(e.index,"flow"),t=new Map;for(let o of n){let i=o.symbol.replace(/^\$/,"");t.set(i,{id:i,symbol:o.symbol,description:o.description,source:"purpose",filePath:o.filePath,data:o.data});}for(let o of s)t.set(o.id,{id:o.id,symbol:`$${o.id}`,description:o.description,gates:o.gates,source:"portal.yaml"});return Array.from(t.values())}function z(){return [{uri:"paradigm://wisdom/preferences",name:"Wisdom - Preferences",description:"Team preferences for patterns, testing, and code style",mimeType:"application/json"},{uri:"paradigm://wisdom/antipatterns",name:"Wisdom - Antipatterns",description:"What NOT to do, with reasons and alternatives",mimeType:"application/json"},{uri:"paradigm://wisdom/decisions",name:"Wisdom - Decisions",description:"Architectural Decision Records (ADRs) index",mimeType:"application/json"}]}async function U(e$1,s){if(e$1==="wisdom/preferences"){let n=await e(s);return {handled:true,text:JSON.stringify({version:n.preferences?.version||"1.0",global:n.preferences?.global||{},by_symbol:n.preferences?.by_symbol||{},symbol_count:Object.keys(n.preferences?.by_symbol||{}).length},null,2)}}if(e$1.startsWith("wisdom/preferences/")){let n=decodeURIComponent(e$1.replace("wisdom/preferences/","")),t=await e(s),o=a$1(t,n);return {handled:true,text:JSON.stringify({symbol:n,preferences:o.preferences,global:t.preferences?.global||{}},null,2)}}if(e$1==="wisdom/antipatterns"){let n=await e(s);return {handled:true,text:JSON.stringify({count:n.antipatterns.length,antipatterns:n.antipatterns},null,2)}}if(e$1.startsWith("wisdom/antipatterns/")){let n=decodeURIComponent(e$1.replace("wisdom/antipatterns/","")),t=await e(s),o=a$1(t,n);return {handled:true,text:JSON.stringify({symbol:n,count:o.antipatterns.length,antipatterns:o.antipatterns},null,2)}}if(e$1==="wisdom/decisions"){let n=await e(s);return {handled:true,text:JSON.stringify({count:n.decisions.length,decisions:n.decisions.map(t=>({id:t.id,title:t.title,status:t.status,date:t.date,symbols:t.symbols}))},null,2)}}if(e$1.startsWith("wisdom/decision/")){let n=e$1.replace("wisdom/decision/",""),t=await e(s),o=t.decisions.find(i=>i.id===n);return o?{handled:true,text:JSON.stringify(o,null,2)}:{handled:true,text:JSON.stringify({error:"Decision not found",id:n,available:t.decisions.map(i=>i.id)},null,2)}}if(e$1.startsWith("wisdom/expertise/")){let n=decodeURIComponent(e$1.replace("wisdom/expertise/","")),t=await e(s),o=b$2(t,{symbol:n});return {handled:true,text:JSON.stringify({symbol:n,count:o.length,experts:o.map(i=>({name:i.name,symbols:i.symbols,areas:i.areas,contact:i.contact}))},null,2)}}return {handled:false,text:""}}function $(){return [{uri:"paradigm://history/fragile",name:"History - Fragile Symbols",description:"Symbols with high fragility that need extra care when modifying",mimeType:"application/json"},{uri:"paradigm://history/validation/summary",name:"History - Validation Summary",description:"Overall validation statistics and pass rates",mimeType:"application/json"}]}async function G(e,s){if(e.startsWith("history/symbol/")&&!e.endsWith("/recent")){let n=decodeURIComponent(e.replace("history/symbol/","")),t=await f(s),o=c(t,n);return {handled:true,text:JSON.stringify({symbol:n,summary:o.summary?{total_changes:o.summary.total_changes,last_modified:o.summary.last_modified,stability_score:o.summary.stability_score,fragility:o.summary.fragility,contributors:o.summary.contributors}:null,recent:o.recent,co_changes:o.co_changes,validation:o.validation},null,2)}}if(e.startsWith("history/symbol/")&&e.endsWith("/recent")){let n=decodeURIComponent(e.replace("history/symbol/","").replace("/recent","")),t=await f(s),o=c(t,n);return {handled:true,text:JSON.stringify({symbol:n,fragility:o.summary?.fragility||"unknown",stability_score:o.summary?.stability_score,recent:o.recent.slice(0,5)},null,2)}}if(e==="history/fragile"){let n=await f(s);return {handled:true,text:JSON.stringify({count:n.index?.fragile_symbols?.length||0,fragile_symbols:n.index?.fragile_symbols||[],recommendation:"Consider adding extra test coverage and reviewing recent changes before modifying these symbols"},null,2)}}if(e.startsWith("history/cochanges/")){let n=decodeURIComponent(e.replace("history/cochanges/","")),o=(await f(s)).index?.co_changes?.filter(i=>i.symbols.includes(n))||[];return {handled:true,text:JSON.stringify({symbol:n,count:o.length,co_changes:o.map(i=>({with:i.symbols.filter(a=>a!==n),frequency:i.frequency,correlation:i.correlation})),recommendation:o.length>0?"These symbols often change together - consider if they need updates too":"No strong co-change patterns detected"},null,2)}}if(e==="history/validation/summary"){let n=await f(s);return {handled:true,text:JSON.stringify({last_run:n.validation?.last_run,total_validations:n.validation?.total_validations||0,pass_rate:n.validation?.pass_rate||0,by_symbol:n.validation?.by_symbol||{}},null,2)}}return {handled:false,text:""}}function q(){return [{uri:"paradigm://context/agent-protocol",name:"Agent Protocol",description:"IMPORTANT: Read this first. Workflow instructions for using Paradigm MCP tools effectively.",mimeType:"text/markdown"},{uri:"paradigm://context/session",name:"Session Info",description:"Current MCP session statistics and context usage estimate",mimeType:"application/json"},{uri:"paradigm://context/handoff-guide",name:"Handoff Guide",description:"When and how to perform context handoffs",mimeType:"text/markdown"}]}async function H(e,s){if(e==="context/agent-protocol")return {handled:true,text:'# Agent Protocol for Paradigm MCP Tools\n\n## What Paradigm Is\n\nParadigm adds a metadata layer (`.purpose` files + `portal.yaml`) to any codebase so AI agents can query architecture context via MCP instead of reading source files directly.\n\n**What it does**\n- Tracks codebase symbols: `#components`, `$flows`, `^gates`, `!signals`, `~aspects`\n- Answers queries about structure, dependencies, authorization, and history without file reads\n- Enforces coverage: hooks block sessions that modify code without updating `.purpose` files\n\n**Tool surface (50+ tools)**\n- Navigation: `paradigm_status`, `paradigm_search`, `paradigm_navigate`, `paradigm_related`\n- Impact: `paradigm_ripple`, `paradigm_flows_affected`\n- Authorization: `paradigm_gates_for_route`, `paradigm_portal_add_gate`\n- History: `paradigm_history_context`, `paradigm_lore_record`, `paradigm_lore_search`\n- Agents: `paradigm_agent_list`, `paradigm_orchestrate_inline`, `paradigm_ambient_events`\n- Compliance: `paradigm_aspect_check`, `paradigm_protocol_search`\n- Session: `paradigm_session_health`, `paradigm_handoff_prepare`\n\n**Setup** (if not already initialized)\nRun `paradigm shift` \u2014 auto-detects language/framework, creates `.paradigm/` config, scaffolds `.purpose` and `portal.yaml`, installs hooks.\n\n---\n\n## Query Before Modify\n\n**Always query before making changes** - this ensures you understand impact and dependencies.\n\n| Before doing this... | Call this MCP tool |\n|---------------------|-------------------|\n| Modifying a symbol | `paradigm_ripple` with the symbol |\n| Starting a session | `paradigm_status` for project overview |\n| Understanding code | `paradigm_navigate` with explore intent |\n| Checking dependencies | `paradigm_related` for connections |\n\n## Example Workflow\n\n1. **Get oriented**: Call `paradigm_status` to see project symbols and health\n2. **Find relevant code**: Call `paradigm_navigate` with intent "find" or "explore"\n3. **Before editing**: Call `paradigm_ripple` on symbols you\'ll modify\n4. **Check context**: Call `paradigm_session_health` every 10-15 tool calls\n\n## Benefits\n\n- **Fresh data**: Always current from live project index\n- **Precise**: Only get the data you need\n- **Token-efficient**: ~100 tokens per query vs ~2000 for reading files\n\n## Context Monitoring\n\nCall `paradigm_session_health` periodically to monitor session health:\n- **<50%**: Continue working\n- **50-70%**: Plan a stopping point\n- **70-85%**: Prepare handoff soon\n- **>85%**: Handoff after current task\n\n## Tool Surface by Category\n\n| Category | Tools |\n|----------|-------|\n| Navigation | `paradigm_status`, `paradigm_search`, `paradigm_navigate`, `paradigm_related` |\n| Impact analysis | `paradigm_ripple`, `paradigm_flows_affected` |\n| Authorization | `paradigm_gates_for_route`, `paradigm_portal_add_gate` |\n| History & lore | `paradigm_history_context`, `paradigm_lore_record`, `paradigm_lore_search` |\n| Agent team | `paradigm_agent_list`, `paradigm_orchestrate_inline`, `paradigm_captain_brief` |\n| Compliance | `paradigm_aspect_check`, `paradigm_protocol_search`, `paradigm_aspect_drift` |\n| Session | `paradigm_session_health`, `paradigm_handoff_prepare`, `paradigm_session_recover` |\n| Architecture | `paradigm_arch_status`, `paradigm_arch_diagram` |\n\n---\n\n*This protocol ensures efficient, safe modifications to the codebase.*\n'};if(e==="context/session"){let n=j$1(),t=n.getStats(),o=n.getDurationMinutes();return {handled:true,text:JSON.stringify({session:{durationMinutes:o,startTime:new Date(t.startTime).toISOString(),lastActivity:new Date(t.lastActivity).toISOString()},interactions:{toolCalls:t.totals.toolCallCount,resourceReads:t.totals.resourceReadCount,totalInteractions:t.totals.toolCallCount+t.totals.resourceReadCount},tokens:{estimatedMcpContribution:t.totals.totalTokens,note:"Use paradigm_session_health tool for full analysis with handoff recommendations"}},null,2)}}return e==="context/handoff-guide"?{handled:true,text:`# Context Handoff Guide
|
|
52
3
|
|
|
53
4
|
## When to Handoff
|
|
54
5
|
|
|
@@ -97,7 +48,7 @@ Call the \`paradigm_session_health\` tool to get:
|
|
|
97
48
|
- List specific file paths modified
|
|
98
49
|
- Include any blockers or decisions needed
|
|
99
50
|
- Reference relevant symbols (@feature, #component, etc.)
|
|
100
|
-
`}:{handled:false,text:""}}var ce={"add-feature":"Pathway for adding a new user-facing feature with proper symbol definitions","add-gate":"Add a new gate (portal) for authorization control","debug-auth":"Debug authentication and authorization issues","implement-ftux":"Implement First-Time User Experience (FTUX) flow","implement-sandbox":"Set up a sandbox environment for testing","read-docs":"Read and understand existing documentation",refactor:"Refactor existing code with proper planning","run-e2e-tests":"Run and debug end-to-end tests","trace-flow":"Trace a flow through the system","validate-portals":"Validate portal.yaml configuration"};function pe(e,s){let n=[m.join(__dirname,"../../../../paradigm/templates/paradigm",e),m.join(s.rootDir,"node_modules/@a-company/paradigm/templates/paradigm",e),m.join(s.rootDir,"../../packages/paradigm/templates/paradigm",e),m.join(process.env.HOME||"",".paradigm/templates",e),m.resolve(__dirname,"../../../paradigm/templates/paradigm",e)];for(let t of n)try{if(l.existsSync(t))return t}catch{}return null}function J(e){return pe("prompts",e)}function de(e){return Math.ceil(e.length/3.5)}function B(e){let s=J(e);if(!s)return [];try{return l.readdirSync(s).filter(t=>t.endsWith(".md")).map(t=>{let o=t.replace(".md",""),i=m.join(s,t),r=l.statSync(i),a=l.readFileSync(i,"utf8");return {name:o,description:ce[o]||`Prompt template: ${o}`,filename:t,size:r.size,tokens:de(a)}})}catch{return []}}function le(e,s){let n=J(s);if(!n)return {found:false,content:"",error:"Prompts directory not found. Ensure @a-company/paradigm is installed."};let t=m.join(n,`${e}.md`);try{if(!l.existsSync(t)){let i=B(s).map(r=>r.name);return {found:!1,content:"",error:`Prompt "${e}" not found. Available prompts: ${i.join(", ")}`}}return {content:l.readFileSync(t,"utf8"),found:!0}}catch(o){return {found:false,content:"",error:`Error reading prompt: ${o.message}`}}}function V(){return [{uri:"paradigm://prompts",name:"Prompts",description:"List all available prompt templates with metadata (name, description, size)",mimeType:"application/json"},{uri:"paradigm://prompts/{name}",name:"Prompt Content",description:"Get a specific prompt template content. Replace {name} with prompt name (e.g., add-feature)",mimeType:"text/markdown"}]}async function Y(e,s){let n=`paradigm://${e}`;if(e==="prompts"){let t=B(s),o=t.reduce((a,p)=>a+p.size,0),i=t.reduce((a,p)=>a+p.tokens,0),r=JSON.stringify({count:t.length,totalSize:o,totalTokens:i,prompts:t.map(a=>({name:a.name,description:a.description,size:a.size,tokens:a.tokens,uri:`paradigm://prompts/${a.name}`})),usage:"Read a specific prompt with paradigm://prompts/{name}"},null,2);return p(r.length,n),{handled:true,text:r,mimeType:"application/json"}}if(e.startsWith("prompts/")){let t=decodeURIComponent(e.replace("prompts/","")),{content:o,found:i,error:r}=le(t,s);if(!i){let a=JSON.stringify({error:r,name:t},null,2);return p(a.length,n),{handled:true,text:a,mimeType:"application/json"}}return p(o.length,n),{handled:true,text:o,mimeType:"text/markdown"}}return {handled:false,text:"",mimeType:"application/json"}}var A={disciplines:"Language and discipline-agnostic symbol mappings for different domains",scan:"Paradigm Probe protocol for visual discovery and UI-to-code mapping","context-tracking":"Context tracking system for session monitoring and handoffs"};function me(e,s){let n=[m.join(__dirname,"../../../../paradigm/templates/paradigm",e),m.join(s.rootDir,"node_modules/@a-company/paradigm/templates/paradigm",e),m.join(s.rootDir,"../../packages/paradigm/templates/paradigm",e),m.join(process.env.HOME||"",".paradigm/templates",e),m.resolve(__dirname,"../../../paradigm/templates/paradigm",e)];for(let t of n)try{if(l.existsSync(t))return t}catch{}return null}function Q(e){return me("specs",e)}function ge(e){return Math.ceil(e.length/3.5)}function ue(e){let s=Q(e);if(!s)return [];let n=[];for(let[t,o]of Object.entries(A)){let i=`${t}.md`,r=m.join(s,i);try{if(l.existsSync(r)){let a=l.statSync(r),p=l.readFileSync(r,"utf8");n.push({name:t,description:o,filename:i,size:a.size,tokens:ge(p)});}}catch{}}return n}function fe(e,s){if(!A[e]){let o=Object.keys(A);return {found:false,content:"",error:`"${e}" is not a reference spec. Reference specs available via MCP: ${o.join(", ")}. Project-specific specs should be read from .paradigm/specs/ directly.`}}let n=Q(s);if(!n)return {found:false,content:"",error:"Specs directory not found. Ensure @a-company/paradigm is installed."};let t=m.join(n,`${e}.md`);try{return l.existsSync(t)?{content:l.readFileSync(t,"utf8"),found:!0}:{found:!1,content:"",error:`Spec "${e}" file not found at expected location.`}}catch(o){return {found:false,content:"",error:`Error reading spec: ${o.message}`}}}function K(){return [{uri:"paradigm://specs",name:"Reference Specs",description:"List reference specifications (disciplines, scan, context-tracking)",mimeType:"application/json"},{uri:"paradigm://specs/{name}",name:"Spec Content",description:"Get a reference spec. Available: disciplines, scan, context-tracking",mimeType:"text/markdown"}]}async function X(e,s){let n=`paradigm://${e}`;if(e==="specs"){let t=ue(s),o=t.reduce((a,p)=>a+p.size,0),i=t.reduce((a,p)=>a+p.tokens,0),r=JSON.stringify({count:t.length,totalSize:o,totalTokens:i,note:"These are reference specs served via MCP. Project-specific specs (logger, symbols, etc.) should be read from .paradigm/specs/ directly.",specs:t.map(a=>({name:a.name,description:a.description,size:a.size,tokens:a.tokens,uri:`paradigm://specs/${a.name}`}))},null,2);return p(r.length,n),{handled:true,text:r,mimeType:"application/json"}}if(e.startsWith("specs/")&&e!=="specs/"){let t=decodeURIComponent(e.replace("specs/","")),{content:o,found:i,error:r}=fe(t,s);if(!i){let a=JSON.stringify({error:r,name:t},null,2);return p(a.length,n),{handled:true,text:a,mimeType:"application/json"}}return p(o.length,n),{handled:true,text:o,mimeType:"text/markdown"}}return {handled:false,text:"",mimeType:"application/json"}}var M={commands:"Complete CLI command reference with examples and usage guidance",queries:"jq query examples for querying the constellation symbol graph"};function he(e,s){let n=[m.join(__dirname,"../../../../paradigm/templates/paradigm",e),m.join(s.rootDir,"node_modules/@a-company/paradigm/templates/paradigm",e),m.join(s.rootDir,"../../packages/paradigm/templates/paradigm",e),m.join(process.env.HOME||"",".paradigm/templates",e),m.resolve(__dirname,"../../../paradigm/templates/paradigm",e)];for(let t of n)try{if(l.existsSync(t))return t}catch{}return null}function Z(e){return he("docs",e)}function ye(e){return Math.ceil(e.length/3.5)}function be(e){let s=Z(e);if(!s)return [];let n=[];for(let[t,o]of Object.entries(M)){let i=`${t}.md`,r=m.join(s,i);try{if(l.existsSync(r)){let a=l.statSync(r),p=l.readFileSync(r,"utf8");n.push({name:t,description:o,filename:i,size:a.size,tokens:ye(p)});}}catch{}}return n}function we(e,s){if(!M[e]){let o=Object.keys(M);return {found:false,content:"",error:`"${e}" is not a reference doc. Reference docs available via MCP: ${o.join(", ")}. Project-specific docs (patterns, troubleshooting, etc.) should be read from .paradigm/docs/ directly.`}}let n=Z(s);if(!n)return {found:false,content:"",error:"Docs directory not found. Ensure @a-company/paradigm is installed."};let t=m.join(n,`${e}.md`);try{return l.existsSync(t)?{content:l.readFileSync(t,"utf8"),found:!0}:{found:!1,content:"",error:`Doc "${e}" file not found at expected location.`}}catch(o){return {found:false,content:"",error:`Error reading doc: ${o.message}`}}}function ee(){return [{uri:"paradigm://docs",name:"Reference Docs",description:"List reference documentation (commands, queries)",mimeType:"application/json"},{uri:"paradigm://docs/{name}",name:"Doc Content",description:"Get a reference doc. Available: commands, queries",mimeType:"text/markdown"}]}async function te(e,s){let n=`paradigm://${e}`;if(e==="docs"){let t=be(s),o=t.reduce((a,p)=>a+p.size,0),i=t.reduce((a,p)=>a+p.tokens,0),r=JSON.stringify({count:t.length,totalSize:o,totalTokens:i,note:"These are reference docs served via MCP. Project-specific docs (patterns, troubleshooting, etc.) should be read from .paradigm/docs/ directly.",docs:t.map(a=>({name:a.name,description:a.description,size:a.size,tokens:a.tokens,uri:`paradigm://docs/${a.name}`}))},null,2);return p(r.length,n),{handled:true,text:r,mimeType:"application/json"}}if(e.startsWith("docs/")&&e!=="docs/"){let t=decodeURIComponent(e.replace("docs/","")),{content:o,found:i,error:r}=we(t,s);if(!i){let a=JSON.stringify({error:r,name:t},null,2);return p(a.length,n),{handled:true,text:a,mimeType:"application/json"}}return p(o.length,n),{handled:true,text:o,mimeType:"text/markdown"}}return {handled:false,text:"",mimeType:"application/json"}}var j={logging:{description:"Paradigm logger usage, symbol-to-method mapping by directory",generate:()=>"# Paradigm Logging Guide\n\n**IMPORTANT:** Use the Paradigm logger instead of raw console.log/print.\n\n## Usage Pattern\n\n```typescript\nlog.component('#login-handler').info('Starting login', { email });\nlog.component('#database').debug('Query executed', { duration });\nlog.gate('^authenticated').warn('Access denied', { userId });\nlog.signal('!login-success').info('User authenticated');\nlog.flow('$checkout').info('Flow step reached');\nlog.aspect('~audit-required').info('Audit triggered');\n```\n\n## Symbol Mapping by Directory\n\n| Directory | Symbol | Logger Method |\n|-----------|--------|---------------|\n| `features/**` | `#` | `log.component()` |\n| `routes/**` | `#` | `log.component()` |\n| `api/**` | `#` | `log.component()` |\n| `endpoints/**` | `#` | `log.component()` |\n| `commands/**` | `#` | `log.component()` |\n| `models/**` | `#` | `log.component()` |\n| `components/**` | `#` | `log.component()` |\n| `lib/**` | `#` | `log.component()` |\n| `utils/**` | `#` | `log.component()` |\n| `services/**` | `#` | `log.component()` |\n| `core/**` | `#` | `log.component()` |\n| `drivers/**` | `#` | `log.component()` |\n| `systems/**` | `#` | `log.component()` |\n| `integrations/**` | `#` | `log.component()` |\n| `external/**` | `#` | `log.component()` |\n| `vendors/**` | `#` | `log.component()` |\n| `stores/**` | `#` | `log.component()` |\n| `state/**` | `#` | `log.component()` |\n| `reducers/**` | `#` | `log.component()` |\n| `config/**` | `#` | `log.component()` |\n| `middleware/**` | `^` | `log.gate()` |\n| `auth/**` | `^` | `log.gate()` |\n| `guards/**` | `^` | `log.gate()` |\n| `policies/**` | `^` | `log.gate()` |\n| `events/**` | `!` | `log.signal()` |\n| `handlers/**` | `!` | `log.signal()` |\n| `listeners/**` | `!` | `log.signal()` |\n| `hooks/**` | `!` | `log.signal()` |\n| `flows/**` | `$` | `log.flow()` |\n| `sagas/**` | `$` | `log.flow()` |\n| `workflows/**` | `$` | `log.flow()` |\n| `pipelines/**` | `$` | `log.flow()` |\n| `aspects/**` | `~` | `log.aspect()` |\n| `rules/**` | `~` | `log.aspect()` |\n| `constraints/**` | `~` | `log.aspect()` |\n\nSee `.paradigm/specs/logger.md` for full specification."},portal:{description:"Portal protocol \u2014 authorization, gates, portal.yaml structure and workflow",generate:()=>`# Portal Protocol (Authorization)
|
|
51
|
+
`}:{handled:false,text:""}}var ce={"add-feature":"Pathway for adding a new user-facing feature with proper symbol definitions","add-gate":"Add a new gate (portal) for authorization control","debug-auth":"Debug authentication and authorization issues","implement-ftux":"Implement First-Time User Experience (FTUX) flow","implement-sandbox":"Set up a sandbox environment for testing","read-docs":"Read and understand existing documentation",refactor:"Refactor existing code with proper planning","run-e2e-tests":"Run and debug end-to-end tests","trace-flow":"Trace a flow through the system","validate-portals":"Validate portal.yaml configuration"};function de(e,s){let n=[m.join(__dirname,"../../../../paradigm/templates/paradigm",e),m.join(s.rootDir,"node_modules/@a-company/paradigm/templates/paradigm",e),m.join(s.rootDir,"../../packages/paradigm/templates/paradigm",e),m.join(process.env.HOME||"",".paradigm/templates",e),m.resolve(__dirname,"../../../paradigm/templates/paradigm",e)];for(let t of n)try{if(l.existsSync(t))return t}catch{}return null}function J(e){return de("prompts",e)}function pe(e){return Math.ceil(e.length/3.5)}function B(e){let s=J(e);if(!s)return [];try{return l.readdirSync(s).filter(t=>t.endsWith(".md")).map(t=>{let o=t.replace(".md",""),i=m.join(s,t),a=l.statSync(i),r=l.readFileSync(i,"utf8");return {name:o,description:ce[o]||`Prompt template: ${o}`,filename:t,size:a.size,tokens:pe(r)}})}catch{return []}}function le(e,s){let n=J(s);if(!n)return {found:false,content:"",error:"Prompts directory not found. Ensure @a-company/paradigm is installed."};let t=m.join(n,`${e}.md`);try{if(!l.existsSync(t)){let i=B(s).map(a=>a.name);return {found:!1,content:"",error:`Prompt "${e}" not found. Available prompts: ${i.join(", ")}`}}return {content:l.readFileSync(t,"utf8"),found:!0}}catch(o){return {found:false,content:"",error:`Error reading prompt: ${o.message}`}}}function V(){return [{uri:"paradigm://prompts",name:"Prompts",description:"List all available prompt templates with metadata (name, description, size)",mimeType:"application/json"},{uri:"paradigm://prompts/{name}",name:"Prompt Content",description:"Get a specific prompt template content. Replace {name} with prompt name (e.g., add-feature)",mimeType:"text/markdown"}]}async function Y(e,s){let n=`paradigm://${e}`;if(e==="prompts"){let t=B(s),o=t.reduce((r,d)=>r+d.size,0),i=t.reduce((r,d)=>r+d.tokens,0),a=JSON.stringify({count:t.length,totalSize:o,totalTokens:i,prompts:t.map(r=>({name:r.name,description:r.description,size:r.size,tokens:r.tokens,uri:`paradigm://prompts/${r.name}`})),usage:"Read a specific prompt with paradigm://prompts/{name}"},null,2);return b$1(a.length,n),{handled:true,text:a,mimeType:"application/json"}}if(e.startsWith("prompts/")){let t=decodeURIComponent(e.replace("prompts/","")),{content:o,found:i,error:a}=le(t,s);if(!i){let r=JSON.stringify({error:a,name:t},null,2);return b$1(r.length,n),{handled:true,text:r,mimeType:"application/json"}}return b$1(o.length,n),{handled:true,text:o,mimeType:"text/markdown"}}return {handled:false,text:"",mimeType:"application/json"}}var A={disciplines:"Language and discipline-agnostic symbol mappings for different domains",scan:"Paradigm Probe protocol for visual discovery and UI-to-code mapping","context-tracking":"Context tracking system for session monitoring and handoffs"};function me(e,s){let n=[m.join(__dirname,"../../../../paradigm/templates/paradigm",e),m.join(s.rootDir,"node_modules/@a-company/paradigm/templates/paradigm",e),m.join(s.rootDir,"../../packages/paradigm/templates/paradigm",e),m.join(process.env.HOME||"",".paradigm/templates",e),m.resolve(__dirname,"../../../paradigm/templates/paradigm",e)];for(let t of n)try{if(l.existsSync(t))return t}catch{}return null}function Q(e){return me("specs",e)}function ge(e){return Math.ceil(e.length/3.5)}function ue(e){let s=Q(e);if(!s)return [];let n=[];for(let[t,o]of Object.entries(A)){let i=`${t}.md`,a=m.join(s,i);try{if(l.existsSync(a)){let r=l.statSync(a),d=l.readFileSync(a,"utf8");n.push({name:t,description:o,filename:i,size:r.size,tokens:ge(d)});}}catch{}}return n}function fe(e,s){if(!A[e]){let o=Object.keys(A);return {found:false,content:"",error:`"${e}" is not a reference spec. Reference specs available via MCP: ${o.join(", ")}. Project-specific specs should be read from .paradigm/specs/ directly.`}}let n=Q(s);if(!n)return {found:false,content:"",error:"Specs directory not found. Ensure @a-company/paradigm is installed."};let t=m.join(n,`${e}.md`);try{return l.existsSync(t)?{content:l.readFileSync(t,"utf8"),found:!0}:{found:!1,content:"",error:`Spec "${e}" file not found at expected location.`}}catch(o){return {found:false,content:"",error:`Error reading spec: ${o.message}`}}}function K(){return [{uri:"paradigm://specs",name:"Reference Specs",description:"List reference specifications (disciplines, scan, context-tracking)",mimeType:"application/json"},{uri:"paradigm://specs/{name}",name:"Spec Content",description:"Get a reference spec. Available: disciplines, scan, context-tracking",mimeType:"text/markdown"}]}async function X(e,s){let n=`paradigm://${e}`;if(e==="specs"){let t=ue(s),o=t.reduce((r,d)=>r+d.size,0),i=t.reduce((r,d)=>r+d.tokens,0),a=JSON.stringify({count:t.length,totalSize:o,totalTokens:i,note:"These are reference specs served via MCP. Project-specific specs (logger, symbols, etc.) should be read from .paradigm/specs/ directly.",specs:t.map(r=>({name:r.name,description:r.description,size:r.size,tokens:r.tokens,uri:`paradigm://specs/${r.name}`}))},null,2);return b$1(a.length,n),{handled:true,text:a,mimeType:"application/json"}}if(e.startsWith("specs/")&&e!=="specs/"){let t=decodeURIComponent(e.replace("specs/","")),{content:o,found:i,error:a}=fe(t,s);if(!i){let r=JSON.stringify({error:a,name:t},null,2);return b$1(r.length,n),{handled:true,text:r,mimeType:"application/json"}}return b$1(o.length,n),{handled:true,text:o,mimeType:"text/markdown"}}return {handled:false,text:"",mimeType:"application/json"}}var M={commands:"Complete CLI command reference with examples and usage guidance",queries:"jq query examples for querying the constellation symbol graph"};function he(e,s){let n=[m.join(__dirname,"../../../../paradigm/templates/paradigm",e),m.join(s.rootDir,"node_modules/@a-company/paradigm/templates/paradigm",e),m.join(s.rootDir,"../../packages/paradigm/templates/paradigm",e),m.join(process.env.HOME||"",".paradigm/templates",e),m.resolve(__dirname,"../../../paradigm/templates/paradigm",e)];for(let t of n)try{if(l.existsSync(t))return t}catch{}return null}function Z(e){return he("docs",e)}function ye(e){return Math.ceil(e.length/3.5)}function be(e){let s=Z(e);if(!s)return [];let n=[];for(let[t,o]of Object.entries(M)){let i=`${t}.md`,a=m.join(s,i);try{if(l.existsSync(a)){let r=l.statSync(a),d=l.readFileSync(a,"utf8");n.push({name:t,description:o,filename:i,size:r.size,tokens:ye(d)});}}catch{}}return n}function _e(e,s){if(!M[e]){let o=Object.keys(M);return {found:false,content:"",error:`"${e}" is not a reference doc. Reference docs available via MCP: ${o.join(", ")}. Project-specific docs (patterns, troubleshooting, etc.) should be read from .paradigm/docs/ directly.`}}let n=Z(s);if(!n)return {found:false,content:"",error:"Docs directory not found. Ensure @a-company/paradigm is installed."};let t=m.join(n,`${e}.md`);try{return l.existsSync(t)?{content:l.readFileSync(t,"utf8"),found:!0}:{found:!1,content:"",error:`Doc "${e}" file not found at expected location.`}}catch(o){return {found:false,content:"",error:`Error reading doc: ${o.message}`}}}function ee(){return [{uri:"paradigm://docs",name:"Reference Docs",description:"List reference documentation (commands, queries)",mimeType:"application/json"},{uri:"paradigm://docs/{name}",name:"Doc Content",description:"Get a reference doc. Available: commands, queries",mimeType:"text/markdown"}]}async function te(e,s){let n=`paradigm://${e}`;if(e==="docs"){let t=be(s),o=t.reduce((r,d)=>r+d.size,0),i=t.reduce((r,d)=>r+d.tokens,0),a=JSON.stringify({count:t.length,totalSize:o,totalTokens:i,note:"These are reference docs served via MCP. Project-specific docs (patterns, troubleshooting, etc.) should be read from .paradigm/docs/ directly.",docs:t.map(r=>({name:r.name,description:r.description,size:r.size,tokens:r.tokens,uri:`paradigm://docs/${r.name}`}))},null,2);return b$1(a.length,n),{handled:true,text:a,mimeType:"application/json"}}if(e.startsWith("docs/")&&e!=="docs/"){let t=decodeURIComponent(e.replace("docs/","")),{content:o,found:i,error:a}=_e(t,s);if(!i){let r=JSON.stringify({error:a,name:t},null,2);return b$1(r.length,n),{handled:true,text:r,mimeType:"application/json"}}return b$1(o.length,n),{handled:true,text:o,mimeType:"text/markdown"}}return {handled:false,text:"",mimeType:"application/json"}}var j={logging:{description:"Paradigm logger usage, symbol-to-method mapping by directory",generate:()=>"# Paradigm Logging Guide\n\n**IMPORTANT:** Use the Paradigm logger instead of raw console.log/print.\n\n## Usage Pattern\n\n```typescript\nlog.component('#login-handler').info('Starting login', { email });\nlog.component('#database').debug('Query executed', { duration });\nlog.gate('^authenticated').warn('Access denied', { userId });\nlog.signal('!login-success').info('User authenticated');\nlog.flow('$checkout').info('Flow step reached');\nlog.aspect('~audit-required').info('Audit triggered');\n```\n\n## Symbol Mapping by Directory\n\n| Directory | Symbol | Logger Method |\n|-----------|--------|---------------|\n| `features/**` | `#` | `log.component()` |\n| `routes/**` | `#` | `log.component()` |\n| `api/**` | `#` | `log.component()` |\n| `endpoints/**` | `#` | `log.component()` |\n| `commands/**` | `#` | `log.component()` |\n| `models/**` | `#` | `log.component()` |\n| `components/**` | `#` | `log.component()` |\n| `lib/**` | `#` | `log.component()` |\n| `utils/**` | `#` | `log.component()` |\n| `services/**` | `#` | `log.component()` |\n| `core/**` | `#` | `log.component()` |\n| `drivers/**` | `#` | `log.component()` |\n| `systems/**` | `#` | `log.component()` |\n| `integrations/**` | `#` | `log.component()` |\n| `external/**` | `#` | `log.component()` |\n| `vendors/**` | `#` | `log.component()` |\n| `stores/**` | `#` | `log.component()` |\n| `state/**` | `#` | `log.component()` |\n| `reducers/**` | `#` | `log.component()` |\n| `config/**` | `#` | `log.component()` |\n| `middleware/**` | `^` | `log.gate()` |\n| `auth/**` | `^` | `log.gate()` |\n| `guards/**` | `^` | `log.gate()` |\n| `policies/**` | `^` | `log.gate()` |\n| `events/**` | `!` | `log.signal()` |\n| `handlers/**` | `!` | `log.signal()` |\n| `listeners/**` | `!` | `log.signal()` |\n| `hooks/**` | `!` | `log.signal()` |\n| `flows/**` | `$` | `log.flow()` |\n| `sagas/**` | `$` | `log.flow()` |\n| `workflows/**` | `$` | `log.flow()` |\n| `pipelines/**` | `$` | `log.flow()` |\n| `aspects/**` | `~` | `log.aspect()` |\n| `rules/**` | `~` | `log.aspect()` |\n| `constraints/**` | `~` | `log.aspect()` |\n\nSee `.paradigm/specs/logger.md` for full specification."},portal:{description:"Portal protocol \u2014 authorization, gates, portal.yaml structure and workflow",generate:()=>`# Portal Protocol (Authorization)
|
|
101
52
|
|
|
102
53
|
**Portal.yaml is REQUIRED when the project has protected routes.**
|
|
103
54
|
|
|
@@ -463,4 +414,4 @@ components:
|
|
|
463
414
|
| When | Tool | Purpose |
|
|
464
415
|
|------|------|---------|
|
|
465
416
|
| Starting any task | \`paradigm_pm_preflight\` | Get compliance plan |
|
|
466
|
-
| Finishing any task | _(handled by stop hook)_ | Auto-checks compliance |`}};function
|
|
417
|
+
| Finishing any task | _(handled by stop hook)_ | Auto-checks compliance |`}};function we(e){return Math.ceil(e.length/3.5)}function oe(){return [{uri:"paradigm://guidance",name:"Guidance Topics",description:"List all available on-demand guidance topics (logging, portal, flows, orchestration, etc.)",mimeType:"application/json"},{uri:"paradigm://guidance/{topic}",name:"Guidance Content",description:`Get guidance for a topic. Available: ${Object.keys(j).join(", ")}`,mimeType:"text/markdown"}]}async function ne(e,s){let n=`paradigm://${e}`;if(e==="guidance"){let t=Object.entries(j).map(([i,a])=>{let r=a.generate();return {name:i,description:a.description,tokens:we(r)}}),o=JSON.stringify({count:t.length,totalTokens:t.reduce((i,a)=>i+a.tokens,0),note:"These guidance topics were previously baked into CLAUDE.md. Load on-demand to save context.",topics:t.map(i=>({...i,uri:`paradigm://guidance/${i.name}`}))},null,2);return b$1(o.length,n),{handled:true,text:o,mimeType:"application/json"}}if(e.startsWith("guidance/")&&e!=="guidance/"){let t=decodeURIComponent(e.replace("guidance/","")),o=j[t];if(!o){let a=Object.keys(j),r=JSON.stringify({error:`Unknown guidance topic: "${t}"`,available:a},null,2);return b$1(r.length,n),{handled:true,text:r,mimeType:"application/json"}}let i=o.generate();return b$1(i.length,n),{handled:true,text:i,mimeType:"text/markdown"}}return {handled:false,text:"",mimeType:"application/json"}}function ie(e,s){e.setRequestHandler(ListResourcesRequestSchema,async()=>({resources:[{uri:"paradigm://symbols",name:"All Symbols",description:"Overview of all Paradigm symbols in the project",mimeType:"application/json"},{uri:"paradigm://symbols/type/feature",name:"Features",description:"All @feature symbols",mimeType:"application/json"},{uri:"paradigm://symbols/type/component",name:"Components",description:"All #component symbols",mimeType:"application/json"},{uri:"paradigm://symbols/type/gate",name:"Gates",description:"All ^gate symbols (authorization)",mimeType:"application/json"},{uri:"paradigm://symbols/type/flow",name:"Flows",description:"All $flow symbols (processes)",mimeType:"application/json"},{uri:"paradigm://symbols/type/signal",name:"Signals",description:"All !signal symbols (events)",mimeType:"application/json"},{uri:"paradigm://symbols/type/state",name:"States",description:"All %state symbols",mimeType:"application/json"},{uri:"paradigm://gates",name:"Gates (Detailed)",description:"All gates with locks, keys, and prizes from portal.yaml",mimeType:"application/json"},{uri:"paradigm://flows",name:"Flows (Detailed)",description:"All flows with gate sequences",mimeType:"application/json"},...z(),...$(),...q(),...V(),...K(),...ee(),...oe()]})),e.setRequestHandler(ReadResourceRequestSchema,async n=>{let t=n.params.uri;if(!t?.startsWith("paradigm://"))throw new Error(`Unknown URI scheme: ${t}`);let o=s(),i=t.replace("paradigm://","");if(i==="symbols"){let a=p(o.index),r=q$1(o.index),d=JSON.stringify({project:o.projectName,counts:a,total:Object.values(a).reduce((p,k)=>p+k,0),symbols:r.map(p=>({symbol:p.symbol,type:p.type,description:p.description}))},null,2);return b$1(d.length,t),{contents:[{uri:t,mimeType:"application/json",text:d}]}}if(i.startsWith("symbol/")){let a=decodeURIComponent(i.replace("symbol/","")),r=k(o.index,a);if(!r){let p=JSON.stringify({error:"Symbol not found",symbol:a,available:q$1(o.index).filter(k=>k.symbol.includes(a.slice(1))).slice(0,5).map(k=>k.symbol)},null,2);return b$1(p.length,t),{contents:[{uri:t,mimeType:"application/json",text:p}]}}let d=JSON.stringify({symbol:r.symbol,type:r.type,description:r.description,filePath:r.filePath,references:r.references,referencedBy:r.referencedBy,tags:r.tags,data:r.data},null,2);return b$1(d.length,t),{contents:[{uri:t,mimeType:"application/json",text:d}]}}if(i.startsWith("symbols/type/")){let a=i.replace("symbols/type/",""),r=l$1(o.index,a),d=JSON.stringify({type:a,count:r.length,symbols:r.map(p=>({symbol:p.symbol,description:p.description,filePath:p.filePath,referencesCount:p.references.length,referencedByCount:p.referencedBy.length}))},null,2);return b$1(d.length,t),{contents:[{uri:t,mimeType:"application/json",text:d}]}}if(i==="gates"){let a=L(o),r=JSON.stringify({count:a.length,gates:a},null,2);return b$1(r.length,t),{contents:[{uri:t,mimeType:"application/json",text:r}]}}if(i==="flows"){let a=F(o),r=JSON.stringify({count:a.length,flows:a},null,2);return b$1(r.length,t),{contents:[{uri:t,mimeType:"application/json",text:r}]}}if(i.startsWith("wisdom/")){let a=await U(i,o);if(a.handled)return b$1(a.text.length),{contents:[{uri:t,mimeType:"application/json",text:a.text}]}}if(i.startsWith("history/")){let a=await G(i,o);if(a.handled)return b$1(a.text.length),{contents:[{uri:t,mimeType:"application/json",text:a.text}]}}if(i.startsWith("context/")){let a=await H(i);if(a.handled)return b$1(a.text.length),{contents:[{uri:t,mimeType:a.text.startsWith("#")?"text/markdown":"application/json",text:a.text}]}}if(i==="prompts"||i.startsWith("prompts/")){let a=await Y(i,o);if(a.handled)return {contents:[{uri:t,mimeType:a.mimeType,text:a.text}]}}if(i==="specs"||i.startsWith("specs/")){let a=await X(i,o);if(a.handled)return {contents:[{uri:t,mimeType:a.mimeType,text:a.text}]}}if(i==="docs"||i.startsWith("docs/")){let a=await te(i,o);if(a.handled)return {contents:[{uri:t,mimeType:a.mimeType,text:a.text}]}}if(i==="guidance"||i.startsWith("guidance/")){let a=await ne(i);if(a.handled)return {contents:[{uri:t,mimeType:a.mimeType,text:a.text}]}}throw new Error(`Unknown resource: ${i}`)});}b();var v=process.argv[2]||process.cwd(),_=null;function ae(){if(!_)throw new Error("Project context not loaded");return _}async function je(){_=await d(v),ga(v,_).catch(e=>{a.component("#paradigm-mcp").warn("Background reindex failed",{error:e.message});});}async function Te(){a.component("#paradigm-mcp").info("Loading project",{projectDir:v});try{_=await d(v),j$1().setRootDir(_.rootDir),a.component("#paradigm-mcp").info("Project loaded",{symbols:_.aggregation.symbols.length,project:_.projectName});}catch(n){a.component("#paradigm-mcp").error("Error loading project",{error:n.message}),process.exit(1);}g(v);let e=new Server({name:"paradigm",version:"0.1.0"},{capabilities:{resources:{},tools:{}}});ie(e,ae),h(e,ae,je),e.onerror=n=>{a.component("#paradigm-mcp").error("Server error",{error:String(n)});};let s=new StdioServerTransport;await e.connect(s),a.component("#paradigm-mcp").info("Server running on stdio");}Te().catch(e=>{a.component("#paradigm-mcp").error("Fatal error",{error:e.message}),process.exit(1);});
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export{ea as getReindexToolsList,fa as handleReindexTool,ga as rebuildStaticFiles}from'./chunk-EMGJWT7D.js';import'./chunk-SU5F5D4I.js';import'./chunk-M4UMM6DC.js';import'./chunk-GRZQIKST.js';import'./chunk-6QXBXZF6.js';import'./chunk-EK4ZRIFJ.js';import'./chunk-LAYBUKMB.js';import'./chunk-5TAVYPOV.js';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export{h as registerTools}from'./chunk-MA75GS7J.js';import'./chunk-EMGJWT7D.js';import'./chunk-4UJ4NIEQ.js';import'./chunk-4N56FRNE.js';import'./chunk-Q527BPUF.js';import'./chunk-KLBH26PA.js';import'./chunk-ARLB6YYW.js';import'./chunk-SU5F5D4I.js';import'./chunk-JNSJVCTU.js';import'./chunk-XROULIQN.js';import'./chunk-ZUAUFZRJ.js';import'./chunk-3KVVC4WV.js';import'./chunk-M4UMM6DC.js';import'./chunk-GRZQIKST.js';import'./chunk-KAFQA7HV.js';import'./chunk-6QXBXZF6.js';import'./chunk-EK4ZRIFJ.js';import'./chunk-LAYBUKMB.js';import'./chunk-DVZWCXB6.js';import'./chunk-QGZRM6ZB.js';import'./chunk-K7X3Z3GL.js';import'./chunk-5TAVYPOV.js';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Auto-generated .purpose stub — created by Cid (captain debrief)
|
|
2
|
+
# Delegate to Scribe (Documentor) for rich documentation
|
|
3
|
+
name: notes
|
|
4
|
+
description: "TODO: describe what this directory/module does"
|
|
5
|
+
context:
|
|
6
|
+
- "Stub created by Cid during coverage audit — update with real context"
|
|
7
|
+
# Key files touched:
|
|
8
|
+
# - N-para-701-arch-yaml-format.md
|
|
9
|
+
# - N-para-701-atlas-agent.md
|
|
10
|
+
# - N-para-701-arch-mcp-tools.md
|
|
11
|
+
components:
|
|
12
|
+
notes:
|
|
13
|
+
description: "TODO: describe this component"
|
|
14
|
+
tags: []
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: N-para-701-arch-mcp-tools
|
|
3
|
+
title: 'Lesson 13: The arch MCP Tools'
|
|
4
|
+
type: note
|
|
5
|
+
author: paradigm
|
|
6
|
+
created: '2026-04-28'
|
|
7
|
+
updated: '2026-04-28'
|
|
8
|
+
tags:
|
|
9
|
+
- course
|
|
10
|
+
- para-701
|
|
11
|
+
- arch-tools
|
|
12
|
+
- mcp-tools
|
|
13
|
+
symbols: []
|
|
14
|
+
difficulty: intermediate
|
|
15
|
+
estimatedMinutes: 5
|
|
16
|
+
prerequisites:
|
|
17
|
+
- N-para-701-atlas-agent
|
|
18
|
+
category: paradigm-core
|
|
19
|
+
origin: imported
|
|
20
|
+
source: courses/para-701.json
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Overview
|
|
24
|
+
|
|
25
|
+
Paradigm exposes two MCP tools for architectural map queries. Both are read-only and operate on `.paradigm/arch.yaml`. They are available whenever the `arch.yaml` file exists — the tool registry auto-detects the file and activates the arch tool module.
|
|
26
|
+
|
|
27
|
+
The two tools are:
|
|
28
|
+
- `paradigm_arch_status` — tier summary + drift report
|
|
29
|
+
- `paradigm_arch_diagram` — Mermaid diagram string
|
|
30
|
+
|
|
31
|
+
There is also a CLI interface with the same functionality: `paradigm arch status` and `paradigm arch diagram`.
|
|
32
|
+
|
|
33
|
+
## paradigm_arch_status
|
|
34
|
+
|
|
35
|
+
**Purpose:** Get a complete summary of the architectural map, including tier details and drift report.
|
|
36
|
+
|
|
37
|
+
**Token cost:** ~200 tokens
|
|
38
|
+
|
|
39
|
+
**Input:** No required fields. The tool reads `arch.yaml` from the project root automatically.
|
|
40
|
+
|
|
41
|
+
**Output when arch.yaml exists:**
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"exists": true,
|
|
45
|
+
"version": "1.0",
|
|
46
|
+
"tierCount": 3,
|
|
47
|
+
"tiers": [
|
|
48
|
+
{
|
|
49
|
+
"id": "frontend",
|
|
50
|
+
"label": "Frontend",
|
|
51
|
+
"responsibility": "User interface and client-side logic",
|
|
52
|
+
"framework": "React",
|
|
53
|
+
"componentCount": 8,
|
|
54
|
+
"components": ["#auth-form", "#dashboard-view", "..."]
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
"links": [
|
|
58
|
+
{ "from": "frontend", "to": "backend", "via": "REST API" }
|
|
59
|
+
],
|
|
60
|
+
"drift": {
|
|
61
|
+
"unassigned": ["#analytics-service", "#export-worker"],
|
|
62
|
+
"missing_purpose": ["#legacy-gateway"],
|
|
63
|
+
"clean": false
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Output when arch.yaml is missing:**
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"exists": false,
|
|
72
|
+
"message": "No arch.yaml found. Create .paradigm/arch.yaml to start mapping your architecture."
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**When to call it:**
|
|
77
|
+
- At the start of an architectural review session
|
|
78
|
+
- After a large feature build to check for tier drift
|
|
79
|
+
- When a stakeholder asks for an architecture overview
|
|
80
|
+
- As part of a Context Brief when the task involves cross-tier work
|
|
81
|
+
|
|
82
|
+
## paradigm_arch_diagram
|
|
83
|
+
|
|
84
|
+
**Purpose:** Render the architectural map as a Mermaid diagram string.
|
|
85
|
+
|
|
86
|
+
**Token cost:** ~150 tokens
|
|
87
|
+
|
|
88
|
+
**Input:** Optional `format` field (only `"mermaid"` is supported; default: `"mermaid"`).
|
|
89
|
+
|
|
90
|
+
**Output when arch.yaml exists:**
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"format": "mermaid",
|
|
94
|
+
"diagram": "graph TD\n frontend[\"Frontend\\n(User interface)\"]\n backend[\"Backend\\n(Business logic)\"]\n database[\"Database\\n(Persistence)\"]\n frontend -->|\"REST API\"| backend\n backend -->|\"Prisma ORM\"| database"
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Output when arch.yaml is missing:**
|
|
99
|
+
```json
|
|
100
|
+
{
|
|
101
|
+
"error": "No arch.yaml found. Cannot render diagram."
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**When to call it:**
|
|
106
|
+
- To generate a diagram for inclusion in a pull request description
|
|
107
|
+
- When onboarding a new team member who needs a visual of the system
|
|
108
|
+
- When preparing architecture documentation
|
|
109
|
+
- After adding new tiers or links to verify the diagram renders correctly
|
|
110
|
+
|
|
111
|
+
## Choosing the Right Tool
|
|
112
|
+
|
|
113
|
+
| Goal | Tool to Use |
|
|
114
|
+
|---|---|
|
|
115
|
+
| "How many tiers do we have, and what are they?" | `paradigm_arch_status` |
|
|
116
|
+
| "Which new components are not yet in a tier?" | `paradigm_arch_status` → check `drift.unassigned` |
|
|
117
|
+
| "Which components in arch.yaml no longer exist?" | `paradigm_arch_status` → check `drift.missing_purpose` |
|
|
118
|
+
| "Generate a diagram I can paste into Confluence" | `paradigm_arch_diagram` |
|
|
119
|
+
| "Is the architecture clean (no drift)?" | `paradigm_arch_status` → check `drift.clean` |
|
|
120
|
+
|
|
121
|
+
Call `paradigm_arch_status` first in any architectural session. Call `paradigm_arch_diagram` when you need a visual. There is no need to call both unless you want both the summary data and the diagram string.
|
|
122
|
+
|
|
123
|
+
## The CLI Interface
|
|
124
|
+
|
|
125
|
+
The same functionality is available from the terminal:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# Show tier summary (default subcommand)
|
|
129
|
+
paradigm arch status
|
|
130
|
+
paradigm arch # same as above
|
|
131
|
+
|
|
132
|
+
# Output as JSON for scripting
|
|
133
|
+
paradigm arch status --json
|
|
134
|
+
|
|
135
|
+
# Print Mermaid diagram to stdout
|
|
136
|
+
paradigm arch diagram
|
|
137
|
+
paradigm arch diagram | pbcopy # macOS: copy to clipboard
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The CLI is useful for quick checks, for integrating into CI scripts that report on architectural health, and for generating diagrams in automated documentation workflows.
|
|
141
|
+
|
|
142
|
+
## Tool Detection
|
|
143
|
+
|
|
144
|
+
Both tools are registered in the `feature` tier of the MCP tool registry. They activate automatically when `.paradigm/arch.yaml` exists in the project root. If the file does not exist, the tools are not listed in the tool registry and do not consume token budget in tool-list payloads.
|
|
145
|
+
|
|
146
|
+
This means:
|
|
147
|
+
- Projects without `arch.yaml` will never see arch tools in their tool list
|
|
148
|
+
- Projects with `arch.yaml` always have both tools available without any configuration
|
|
149
|
+
- Creating `arch.yaml` is the only setup required to activate Atlas's full toolset
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: N-para-701-arch-yaml-format
|
|
3
|
+
title: 'Lesson 11: The arch.yaml Format'
|
|
4
|
+
type: note
|
|
5
|
+
author: paradigm
|
|
6
|
+
created: '2026-04-28'
|
|
7
|
+
updated: '2026-04-28'
|
|
8
|
+
tags:
|
|
9
|
+
- course
|
|
10
|
+
- para-701
|
|
11
|
+
- arch-yaml
|
|
12
|
+
- architectural-map
|
|
13
|
+
symbols: []
|
|
14
|
+
difficulty: intermediate
|
|
15
|
+
estimatedMinutes: 5
|
|
16
|
+
prerequisites:
|
|
17
|
+
- N-para-701-agent-roster
|
|
18
|
+
category: paradigm-core
|
|
19
|
+
origin: imported
|
|
20
|
+
source: courses/para-701.json
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## What Is arch.yaml?
|
|
24
|
+
|
|
25
|
+
The file `.paradigm/arch.yaml` is an optional architectural layer map. When it exists, Paradigm knows the intended tier structure of a project — which components belong to which layer, what each layer is responsible for, and how layers connect to each other. It is the source of truth for macro-level architecture.
|
|
26
|
+
|
|
27
|
+
The file is optional. Projects without it still work — symbol indexing, orchestration, and all other Paradigm features function normally. You create `arch.yaml` when you want to:
|
|
28
|
+
|
|
29
|
+
- Document the intended architectural layers of a project (frontend, backend, database, infrastructure)
|
|
30
|
+
- Detect drift between declared architecture and the live symbol index
|
|
31
|
+
- Render architecture diagrams for onboarding or architectural review
|
|
32
|
+
- Give Atlas (the cartographer agent) a map to audit against
|
|
33
|
+
|
|
34
|
+
## The Schema
|
|
35
|
+
|
|
36
|
+
```yaml
|
|
37
|
+
version: '1.0'
|
|
38
|
+
|
|
39
|
+
tiers:
|
|
40
|
+
- id: frontend
|
|
41
|
+
label: Frontend
|
|
42
|
+
responsibility: User interface and client-side logic
|
|
43
|
+
tech:
|
|
44
|
+
framework: React
|
|
45
|
+
libraries:
|
|
46
|
+
- zustand
|
|
47
|
+
- react-query
|
|
48
|
+
components:
|
|
49
|
+
- '#auth-form'
|
|
50
|
+
- '#dashboard-view'
|
|
51
|
+
- '#settings-panel'
|
|
52
|
+
|
|
53
|
+
- id: backend
|
|
54
|
+
label: Backend
|
|
55
|
+
responsibility: Business logic and API layer
|
|
56
|
+
tech:
|
|
57
|
+
framework: Express
|
|
58
|
+
libraries:
|
|
59
|
+
- zod
|
|
60
|
+
- prisma
|
|
61
|
+
components:
|
|
62
|
+
- '#auth-middleware'
|
|
63
|
+
- '#user-service'
|
|
64
|
+
- '#billing-service'
|
|
65
|
+
|
|
66
|
+
- id: database
|
|
67
|
+
label: Database
|
|
68
|
+
responsibility: Persistence and data access
|
|
69
|
+
tech:
|
|
70
|
+
framework: PostgreSQL
|
|
71
|
+
libraries:
|
|
72
|
+
- prisma
|
|
73
|
+
components:
|
|
74
|
+
- '#user-schema'
|
|
75
|
+
- '#billing-schema'
|
|
76
|
+
|
|
77
|
+
links:
|
|
78
|
+
- from: frontend
|
|
79
|
+
to: backend
|
|
80
|
+
via: REST API
|
|
81
|
+
- from: backend
|
|
82
|
+
to: database
|
|
83
|
+
via: Prisma ORM
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Fields Reference
|
|
87
|
+
|
|
88
|
+
**version** (required) — Schema version string. Use `'1.0'`.
|
|
89
|
+
|
|
90
|
+
**tiers** (required) — Array of architectural tiers. Each tier has:
|
|
91
|
+
|
|
92
|
+
- `id` (required) — Machine-readable identifier. Use kebab-case. Referenced by `links`.
|
|
93
|
+
- `label` (required) — Human-readable name shown in diagrams and summaries.
|
|
94
|
+
- `responsibility` (required) — One sentence describing what this tier owns.
|
|
95
|
+
- `tech` (optional) — Technology stack for this tier. `framework` is the primary runtime; `libraries` is a list of key dependencies.
|
|
96
|
+
- `components` (required) — List of Paradigm symbol IDs (prefixed with `#`) that belong to this tier.
|
|
97
|
+
|
|
98
|
+
**links** (required, can be empty array `[]`) — Array of directed edges between tiers. Each link has:
|
|
99
|
+
|
|
100
|
+
- `from` (required) — Tier ID of the caller or dependent.
|
|
101
|
+
- `to` (required) — Tier ID of the callee or dependency.
|
|
102
|
+
- `via` (optional) — Human-readable label for the connection (e.g., "REST API", "message queue", "gRPC"). Renders as an edge label in Mermaid diagrams.
|
|
103
|
+
|
|
104
|
+
## When to Create arch.yaml
|
|
105
|
+
|
|
106
|
+
Create `.paradigm/arch.yaml` when:
|
|
107
|
+
|
|
108
|
+
1. **Onboarding new team members** — a written tier map removes ambiguity about which code belongs where
|
|
109
|
+
2. **Planning a large refactor** — declaring the target architecture before refactoring makes drift detectable
|
|
110
|
+
3. **Architectural review** — stakeholders can read the YAML or view the rendered Mermaid diagram
|
|
111
|
+
4. **Drift detection** — once declared, Atlas can flag components that appear in the symbol index but are not assigned to any tier (unassigned), or components declared in a tier but not present in the index (missing_purpose)
|
|
112
|
+
|
|
113
|
+
You do NOT need `arch.yaml` for orchestration, symbol tracking, gate checking, or any other Paradigm feature. It is purely additive metadata.
|
|
114
|
+
|
|
115
|
+
## Drift Detection
|
|
116
|
+
|
|
117
|
+
Atlas computes two drift categories by comparing `arch.yaml` to the live symbol index:
|
|
118
|
+
|
|
119
|
+
**Unassigned** — Component symbols in the index that are not listed in any tier's `components` array. These components exist and are documented, but the architectural map has not categorized them. Common cause: new components added after the arch.yaml was last updated.
|
|
120
|
+
|
|
121
|
+
**Missing Purpose** — Component IDs listed in a tier's `components` array that do not appear in the symbol index. These components were planned or once existed, but are no longer indexed. Common cause: renamed or deleted components whose arch.yaml entry was not updated.
|
|
122
|
+
|
|
123
|
+
Neither drift category blocks the build. Atlas reports them as advisory findings so the team can update the map at their own pace.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: N-para-701-atlas-agent
|
|
3
|
+
title: 'Lesson 12: Atlas — The Cartographer Agent'
|
|
4
|
+
type: note
|
|
5
|
+
author: paradigm
|
|
6
|
+
created: '2026-04-28'
|
|
7
|
+
updated: '2026-04-28'
|
|
8
|
+
tags:
|
|
9
|
+
- course
|
|
10
|
+
- para-701
|
|
11
|
+
- atlas
|
|
12
|
+
- cartographer
|
|
13
|
+
symbols: []
|
|
14
|
+
difficulty: intermediate
|
|
15
|
+
estimatedMinutes: 5
|
|
16
|
+
prerequisites:
|
|
17
|
+
- N-para-701-arch-yaml-format
|
|
18
|
+
category: paradigm-core
|
|
19
|
+
origin: imported
|
|
20
|
+
source: courses/para-701.json
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Who Is Atlas?
|
|
24
|
+
|
|
25
|
+
Atlas is the Cartographer agent — archetype ID `cartographer`. He is agent #67 in the Paradigm roster, a tier-1 specialist whose single responsibility is architectural mapping. When a project has a `.paradigm/arch.yaml`, Atlas reads it, computes drift against the live symbol index, and renders diagrams. He does not implement code, does not write .purpose files, and does not block builds.
|
|
26
|
+
|
|
27
|
+
Atlas is advisory-only. His job is to make architectural drift visible, not to enforce it. The team decides when and how to resolve drift.
|
|
28
|
+
|
|
29
|
+
## Atlas's Personality
|
|
30
|
+
|
|
31
|
+
Atlas is **methodical** and **conservative**. He does not take risks with interpretation — if arch.yaml is ambiguous, he reports what he found rather than guessing intent. His verbosity is **concise**: tier summaries, a drift count, and the Mermaid diagram string. He does not produce lengthy analysis.
|
|
32
|
+
|
|
33
|
+
Model tier: **tier-1 (opus)**. Architectural reasoning requires deep understanding of symbol relationships and the ability to explain drift in context. Atlas earns his tier-1 slot by analyzing not just whether drift exists, but what it means for the project.
|
|
34
|
+
|
|
35
|
+
## When Atlas Fires
|
|
36
|
+
|
|
37
|
+
Atlas is triggered at two points in the orchestration lifecycle:
|
|
38
|
+
|
|
39
|
+
**After the Builder stage** — When the Builder completes implementation, Atlas checks whether new components introduced by the build have been assigned to a tier. If the project has `arch.yaml`, Atlas runs automatically as part of the post-build review pipeline and surfaces unassigned components before the Documentor runs.
|
|
40
|
+
|
|
41
|
+
**On-demand** — Any time the user or another agent calls `paradigm_arch_status` or `paradigm_arch_diagram`, Atlas fires. This is the most common path: an engineer asks for an architecture overview at the start of a planning session, or requests a diagram for a pull request description.
|
|
42
|
+
|
|
43
|
+
Atlas does **not** fire on every tool call. His attention threshold is low (0.35) because architectural drift is cheap to report and expensive to accumulate silently. His attention patterns match `#*` symbols and the `.paradigm/arch.yaml` path.
|
|
44
|
+
|
|
45
|
+
## Atlas vs. Documentor
|
|
46
|
+
|
|
47
|
+
Both Atlas and the Documentor run after builders complete. They have different responsibilities:
|
|
48
|
+
|
|
49
|
+
| Dimension | Atlas (Cartographer) | Documentor |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| What it reads | `.paradigm/arch.yaml`, symbol index | Source files, existing .purpose files |
|
|
52
|
+
| What it writes | Nothing | `.purpose` files, `portal.yaml` |
|
|
53
|
+
| What it reports | Architectural drift (tier-level) | Coverage gaps (symbol-level) |
|
|
54
|
+
| Blocking? | Never | Never (advisory) |
|
|
55
|
+
| Tier | 1 (opus) | 3 (haiku) |
|
|
56
|
+
|
|
57
|
+
The Documentor works at symbol granularity — "this directory has no .purpose file" or "this component is missing its description." Atlas works at tier granularity — "these 8 components were added but have not been assigned to any architectural layer."
|
|
58
|
+
|
|
59
|
+
They complement each other: the Documentor ensures every symbol is documented, Atlas ensures documented symbols are architecturally located.
|
|
60
|
+
|
|
61
|
+
## What Atlas Never Does
|
|
62
|
+
|
|
63
|
+
Atlas has strict constraints encoded in his agent profile:
|
|
64
|
+
|
|
65
|
+
- **Never blocks a build** — drift is informational. A project can ship with unassigned components.
|
|
66
|
+
- **Never writes source code** — he is read-only on `src/**`.
|
|
67
|
+
- **Never modifies .purpose files** — that is the Documentor's job.
|
|
68
|
+
- **Never modifies portal.yaml** — that is Aegis's domain.
|
|
69
|
+
- **Never modifies arch.yaml directly** — he reads it and reports on it. A human or the architect agent updates the map.
|
|
70
|
+
|
|
71
|
+
These constraints are deliberate. An advisory agent that occasionally blocks builds would undermine trust. Atlas stays in his lane so the team can rely on his reports without worrying about side effects.
|
|
72
|
+
|
|
73
|
+
## Resolving Drift
|
|
74
|
+
|
|
75
|
+
When Atlas reports drift, the team has three options:
|
|
76
|
+
|
|
77
|
+
1. **Update arch.yaml** — add unassigned components to the correct tier, remove missing_purpose entries for deleted components. This is the most common resolution.
|
|
78
|
+
|
|
79
|
+
2. **Ignore it** — Atlas does not block. If a component is intentionally unclassified (e.g., a utility shared across tiers), the team can leave it unassigned.
|
|
80
|
+
|
|
81
|
+
3. **Create arch.yaml entries for new tiers** — if new components don't fit existing tiers, the architect may declare a new tier. Atlas will then show the new tier in future runs.
|
|
82
|
+
|
|
83
|
+
Resolution is a human decision. Atlas surfaces the information; the architect makes the call.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Auto-generated .purpose stub — created by Cid (captain debrief)
|
|
2
|
+
# Delegate to Scribe (Documentor) for rich documentation
|
|
3
|
+
name: paths
|
|
4
|
+
description: "TODO: describe what this directory/module does"
|
|
5
|
+
context:
|
|
6
|
+
- "Stub created by Cid during coverage audit — update with real context"
|
|
7
|
+
# Key files touched:
|
|
8
|
+
# - LP-para-701.yaml
|
|
9
|
+
components:
|
|
10
|
+
paths:
|
|
11
|
+
description: "TODO: describe this component"
|
|
12
|
+
tags: []
|
|
@@ -62,3 +62,18 @@ steps:
|
|
|
62
62
|
- content: Q-para-701-agent-pods-nevrland
|
|
63
63
|
required: true
|
|
64
64
|
passRequired: true
|
|
65
|
+
- content: N-para-701-arch-yaml-format
|
|
66
|
+
required: true
|
|
67
|
+
- content: Q-para-701-arch-yaml-format
|
|
68
|
+
required: true
|
|
69
|
+
passRequired: true
|
|
70
|
+
- content: N-para-701-atlas-agent
|
|
71
|
+
required: true
|
|
72
|
+
- content: Q-para-701-atlas-agent
|
|
73
|
+
required: true
|
|
74
|
+
passRequired: true
|
|
75
|
+
- content: N-para-701-arch-mcp-tools
|
|
76
|
+
required: true
|
|
77
|
+
- content: Q-para-701-arch-mcp-tools
|
|
78
|
+
required: true
|
|
79
|
+
passRequired: true
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Auto-generated .purpose stub — created by Cid (captain debrief)
|
|
2
|
+
# Delegate to Scribe (Documentor) for rich documentation
|
|
3
|
+
name: quizzes
|
|
4
|
+
description: "TODO: describe what this directory/module does"
|
|
5
|
+
context:
|
|
6
|
+
- "Stub created by Cid during coverage audit — update with real context"
|
|
7
|
+
# Key files touched:
|
|
8
|
+
# - Q-para-701-arch-yaml-format.yaml
|
|
9
|
+
# - Q-para-701-atlas-agent.yaml
|
|
10
|
+
# - Q-para-701-arch-mcp-tools.yaml
|
|
11
|
+
components:
|
|
12
|
+
quizzes:
|
|
13
|
+
description: "TODO: describe this component"
|
|
14
|
+
tags: []
|