@a-company/paradigm 6.2.1 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-32XL3FIQ.js +2 -0
- package/dist/{chunk-MA75GS7J.js → chunk-SRWROALW.js} +68 -37
- package/dist/{enforcement-46XWPNSA.js → enforcement-FXO6IYYE.js} +1 -1
- package/dist/{enforcement-BEGPQIUN.js → enforcement-VRE3WZOI.js} +1 -1
- package/dist/index.js +2 -2
- package/dist/mcp.js +1 -1
- package/dist/rune-promotion-3JQ5LMWK.js +3 -0
- package/dist/{shift-3ATE2ONQ.js → shift-6Y3KQP62.js} +2 -2
- package/dist/{tools-BPEKRC2U.js → tools-2XPMZZBT.js} +1 -1
- package/dist/university-content/notes/N-para-001-shift-setup.md +2 -2
- package/dist/university-content/notes/N-para-301-enforcement-levels.md +18 -11
- package/dist/university-content/notes/N-para-301-paradigm-shift.md +2 -2
- package/dist/university-content/notes/N-para-301-rune-promotion.md +69 -0
- package/dist/university-content/notes/N-para-501-hook-enforcement.md +3 -1
- package/dist/university-content/notes/N-para-701-orchestration-enforcement.md +10 -1
- package/dist/university-content/quizzes/Q-para-301-enforcement-levels.yaml +21 -1
- package/dist/university-content/quizzes/Q-para-701-orchestration-enforcement.yaml +11 -1
- package/package.json +1 -1
- package/dist/chunk-KYA4TP26.js +0 -2
|
@@ -48,7 +48,7 @@ Generated by paradigm shift.
|
|
|
48
48
|
|
|
49
49
|
Generated by paradigm shift.
|
|
50
50
|
`},{path:".cursor/rules/",defaultContent:"",isDir:true},{path:".claude/hooks/",defaultContent:"",isDir:true}];async function Q(o){let n=[],l=[];for(let r of ae){let f=d.join(o,r.path);if(r.isDir)await X(f)?l.push(r.path):(await C.mkdir(f,{recursive:true}),n.push(r.path));else if(await X(f))l.push(r.path);else {let i=d.dirname(f);await C.mkdir(i,{recursive:true}),await C.writeFile(f,r.defaultContent,"utf-8"),n.push(r.path);}}return {created:n,existed:l}}async function X(o){try{return await C.access(o),!0}catch{return false}}var ie=4,se=50,ce=['description: ""',"components: []","description: ''"],le={"claude-code":["opus","sonnet","haiku"],cursor:["sonnet","sonnet","haiku"],fallback:["sonnet","sonnet","sonnet"]};async function Z(o){let n=await Promise.allSettled([de(o),pe(o),fe(o),me(o),ue(o),ge(o),ye(o),he(o),we()]),l=[];for(let i of n)i.status==="fulfilled"&&i.value&&l.push(i.value);l.sort((i,b)=>i.priority-b.priority);let r=l.filter(i=>i.type==="action"),f=l.filter(i=>i.type==="info");return [...r.slice(0,ie),...f]}function ee(o){if(o.length===0)return "";let n=o.filter(m=>m.type==="action"),l=o.filter(m=>m.type==="info"),r=[];r.push(""),r.push(e.bold(" Recommendations")),r.push(e.gray(" "+"\u2500".repeat(49)));for(let m=0;m<n.length;m++){let i=n[m],b=e.white(` ${m+1}. `),S=e.white(i.message);i.command?(r.push(b+S),r.push(" "+e.cyan(i.command))):r.push(b+S);}if(l.length>0){r.push("");for(let m of l)r.push(e.dim(" "+m.message));}let f=n.length;if(f>0){r.push("");let m=f===1?"item needs":"items need";r.push(e.dim(` ${f} ${m} attention.`));}return r.push(""),r.join(`
|
|
51
|
-
`)}async function de(o){let n=d.join(o,".purpose");try{let l=await C.readFile(n,"utf-8");if(l.trim().length<se)return {id:"empty-purpose",priority:1,message:"Edit `.purpose` to define your project's features",command:void 0,type:"action"};if(ce.some(f=>l.includes(f)))return {id:"empty-purpose",priority:1,message:"Edit `.purpose` to define your project's features",command:void 0,type:"action"}}catch{return {id:"empty-purpose",priority:1,message:"Edit `.purpose` to define your project's features",command:void 0,type:"action"}}return null}async function pe(o){let n=["src","packages","apps"];for(let r of n){let f=d.join(o,r);if(!a.existsSync(f))continue;if(await te(f))return null}return n.some(r=>a.existsSync(d.join(o,r)))?{id:"no-sub-purpose",priority:2,message:"Add `.purpose` files to feature directories",command:void 0,type:"action"}:null}async function fe(o){let n=d.join(o,"portal.yaml");try{let l=await C.readFile(n,"utf-8"),r=l.includes("gates:")&&!l.match(/gates:\s*(\[\]|\{\})\s*$/m)&&!l.match(/gates:\s*(\[\]|\{\})\s*\n/),f=l.includes("routes:")&&!l.match(/routes:\s*(\[\]|\{\})\s*$/m)&&!l.match(/routes:\s*(\[\]|\{\})\s*\n/);if(!r&&!f)return {id:"empty-portal",priority:3,message:"Define auth gates in `portal.yaml` if your project has auth",command:void 0,type:"action"}}catch{return {id:"empty-portal",priority:3,message:"Define auth gates in `portal.yaml` if your project has auth",command:void 0,type:"action"}}return null}async function me(o){let n=d.join(o,".paradigm","agents.yaml");try{let l=await C.readFile(n,"utf-8");if(l.includes("agents: []")||l.trim().length<40)return {id:"agents-unconfigured",priority:4,message:"Review agent roles",command:"paradigm agent list",type:"action"}}catch{return null}return null}async function ue(o){let n=d.join(o,".paradigm",".pending-scope-reviews");return a.existsSync(n)?{id:"pending-scope-reviews",priority:2,message:"Review agent scopes",command:"paradigm agent review",type:"action"}:null}async function ge(o){let n=d.join(o,".paradigm","config.yaml");try{let l=await C.readFile(n,"utf-8");if(!l.includes("model-resolution"))return null;let r=l.match(/tier-1:\s*(\S+)/),f=l.match(/tier-2:\s*(\S+)/),m=l.match(/tier-3:\s*(\S+)/);if(!r||!f||!m)return null;let i=[r[1].replace(/['"]/g,""),f[1].replace(/['"]/g,""),m[1].replace(/['"]/g,"")];if(Object.values(le).some(S=>S[0]===i[0]&&S[1]===i[1]&&S[2]===i[2]))return {id:"model-tiers-default",priority:5,message:"Fine-tune model tiers",command:"paradigm team models",type:"action"}}catch{return null}return null}async function ye(o){let n=d.join(o,".paradigm","lore","entries");try{if((await C.readdir(n)).filter(f=>!f.startsWith(".")).length===0)return {id:"no-lore",priority:8,message:"Lore records automatically as you work",command:void 0,type:"info"}}catch{return {id:"no-lore",priority:8,message:"Lore records automatically as you work",command:void 0,type:"info"}}return null}async function he(o){let n=d.join(o,".paradigm","notebooks");try{if((await C.readdir(n)).filter(f=>!f.startsWith(".")).length===0)return {id:"no-notebooks",priority:8,message:"Agent notebooks build over time",command:void 0,type:"info"}}catch{return {id:"no-notebooks",priority:8,message:"Agent notebooks build over time",command:void 0,type:"info"}}return null}async function we(){return {id:"verify-not-run",priority:6,message:"Verify setup health",command:"paradigm doctor --verify",type:"action"}}async function te(o,n=0){if(n>4)return false;try{let l=await C.readdir(o,{withFileTypes:!0});for(let r of l)if(!(r.isDirectory()&&["node_modules","dist",".git",".next",".paradigm","build","out","target",".turbo"].includes(r.name))&&(r.name===".purpose"&&!r.isDirectory()||r.isDirectory()&&await te(d.join(o,r.name),n+1)))return !0}catch{a$1.operation("shift-recommendations").debug("Could not read directory",{dir:o});}return false}var oe=new Set(["architect","builder","reviewer","security","advocate","tester","compliance","documentor"]),I={architect:{nickname:"Apex",role:"System design, specifications"},builder:{nickname:"Kit",role:"Implementation, tests"},reviewer:{nickname:"Judge",role:"Code quality, compliance"},security:{nickname:"Aegis",role:"Auth flows, vulnerability scanning"},advocate:{nickname:"Jinx",role:"Stress testing, edge cases"},tester:{nickname:"Probe",role:"Unit and integration tests"},compliance:{nickname:"Rune",role:"Symbol compliance enforcement"},documentor:{nickname:"Scribe",role:".purpose, portal.yaml maintenance"}};function ke(o){let n=[],l=d.join(ne.homedir(),".paradigm","agents");for(let[r,f]of Object.entries(o.agents)){let m,i=r,b=d.join(l,`${r}.agent`);if(a.existsSync(b))try{let v=a.readFileSync(b,"utf8"),E=h.load(v);E?.nickname&&(m=E.nickname),E?.role&&(i=E.role);}catch{}!m&&I[r]&&(m=I[r].nickname,i=I[r].role);let S=f.source==="core"||f.source==="ecosystem"?f.source:oe.has(r)?"core":"ecosystem";n.push({id:r,nickname:m,role:i,source:S});}return n}async function be(o,n,l){if(!a.existsSync(n))return;let r;try{r=h.load(a.readFileSync(n,"utf8"))??{active:[]};}catch{return}let f=Array.isArray(r.active)?r.active:[];if(f.includes("compliance"))return;let{isCohortC:m}=await import('./migration-notices-MRZ6PVDS.js');if(!m(o))return;let i=d.join(o,".paradigm",".compliance-nomination-skipped");if(a.existsSync(i)&&!l.force)return;if(!process.stdin.isTTY||l.prompt===false){try{a.writeFileSync(i,"","utf8");}catch{}return}console.log(""),console.log(e.cyan("Step 2c-nominate/6: Symbol enforcement")),console.log(""),console.log(" This project defines ~aspects but no compliance-archetype agent"),console.log(" (Rune) is on the roster."),console.log(""),console.log(" Without a claimant, paradigm 6.0.4 no longer enforces aspect"),console.log(" coverage. You can:"),console.log(""),console.log(` ${e.green("[Y]")} Add Rune (compliance) to the roster \u2014 recommended`),console.log(" Authority defaults will be written to .paradigm/authority.yaml."),console.log(" Default mode: advise (Rune surfaces findings, never blocks)."),console.log(""),console.log(` ${e.yellow("[N]")} Skip \u2014 opt out of aspect enforcement for this project`),console.log(" This decision is remembered. Re-run with --force to revisit."),console.log("");let S=(await import('readline/promises')).createInterface({input:process.stdin,output:process.stdout}),v="";try{v=(await S.question(" Add Rune to roster? [Y/n]: ")).trim().toLowerCase();}catch{v="";}finally{S.close();}if(v===""||v==="y"||v==="yes"){r.active=[...f,"compliance"].sort();try{a.writeFileSync(n,h.dump(r,{lineWidth:-1,noRefs:!0}),"utf8"),console.log(e.green(" \u2713 Rune (compliance) added to roster"));}catch(
|
|
51
|
+
`)}async function de(o){let n=d.join(o,".purpose");try{let l=await C.readFile(n,"utf-8");if(l.trim().length<se)return {id:"empty-purpose",priority:1,message:"Edit `.purpose` to define your project's features",command:void 0,type:"action"};if(ce.some(f=>l.includes(f)))return {id:"empty-purpose",priority:1,message:"Edit `.purpose` to define your project's features",command:void 0,type:"action"}}catch{return {id:"empty-purpose",priority:1,message:"Edit `.purpose` to define your project's features",command:void 0,type:"action"}}return null}async function pe(o){let n=["src","packages","apps"];for(let r of n){let f=d.join(o,r);if(!a.existsSync(f))continue;if(await te(f))return null}return n.some(r=>a.existsSync(d.join(o,r)))?{id:"no-sub-purpose",priority:2,message:"Add `.purpose` files to feature directories",command:void 0,type:"action"}:null}async function fe(o){let n=d.join(o,"portal.yaml");try{let l=await C.readFile(n,"utf-8"),r=l.includes("gates:")&&!l.match(/gates:\s*(\[\]|\{\})\s*$/m)&&!l.match(/gates:\s*(\[\]|\{\})\s*\n/),f=l.includes("routes:")&&!l.match(/routes:\s*(\[\]|\{\})\s*$/m)&&!l.match(/routes:\s*(\[\]|\{\})\s*\n/);if(!r&&!f)return {id:"empty-portal",priority:3,message:"Define auth gates in `portal.yaml` if your project has auth",command:void 0,type:"action"}}catch{return {id:"empty-portal",priority:3,message:"Define auth gates in `portal.yaml` if your project has auth",command:void 0,type:"action"}}return null}async function me(o){let n=d.join(o,".paradigm","agents.yaml");try{let l=await C.readFile(n,"utf-8");if(l.includes("agents: []")||l.trim().length<40)return {id:"agents-unconfigured",priority:4,message:"Review agent roles",command:"paradigm agent list",type:"action"}}catch{return null}return null}async function ue(o){let n=d.join(o,".paradigm",".pending-scope-reviews");return a.existsSync(n)?{id:"pending-scope-reviews",priority:2,message:"Review agent scopes",command:"paradigm agent review",type:"action"}:null}async function ge(o){let n=d.join(o,".paradigm","config.yaml");try{let l=await C.readFile(n,"utf-8");if(!l.includes("model-resolution"))return null;let r=l.match(/tier-1:\s*(\S+)/),f=l.match(/tier-2:\s*(\S+)/),m=l.match(/tier-3:\s*(\S+)/);if(!r||!f||!m)return null;let i=[r[1].replace(/['"]/g,""),f[1].replace(/['"]/g,""),m[1].replace(/['"]/g,"")];if(Object.values(le).some(S=>S[0]===i[0]&&S[1]===i[1]&&S[2]===i[2]))return {id:"model-tiers-default",priority:5,message:"Fine-tune model tiers",command:"paradigm team models",type:"action"}}catch{return null}return null}async function ye(o){let n=d.join(o,".paradigm","lore","entries");try{if((await C.readdir(n)).filter(f=>!f.startsWith(".")).length===0)return {id:"no-lore",priority:8,message:"Lore records automatically as you work",command:void 0,type:"info"}}catch{return {id:"no-lore",priority:8,message:"Lore records automatically as you work",command:void 0,type:"info"}}return null}async function he(o){let n=d.join(o,".paradigm","notebooks");try{if((await C.readdir(n)).filter(f=>!f.startsWith(".")).length===0)return {id:"no-notebooks",priority:8,message:"Agent notebooks build over time",command:void 0,type:"info"}}catch{return {id:"no-notebooks",priority:8,message:"Agent notebooks build over time",command:void 0,type:"info"}}return null}async function we(){return {id:"verify-not-run",priority:6,message:"Verify setup health",command:"paradigm doctor --verify",type:"action"}}async function te(o,n=0){if(n>4)return false;try{let l=await C.readdir(o,{withFileTypes:!0});for(let r of l)if(!(r.isDirectory()&&["node_modules","dist",".git",".next",".paradigm","build","out","target",".turbo"].includes(r.name))&&(r.name===".purpose"&&!r.isDirectory()||r.isDirectory()&&await te(d.join(o,r.name),n+1)))return !0}catch{a$1.operation("shift-recommendations").debug("Could not read directory",{dir:o});}return false}var oe=new Set(["architect","builder","reviewer","security","advocate","tester","compliance","documentor"]),I={architect:{nickname:"Apex",role:"System design, specifications"},builder:{nickname:"Kit",role:"Implementation, tests"},reviewer:{nickname:"Judge",role:"Code quality, compliance"},security:{nickname:"Aegis",role:"Auth flows, vulnerability scanning"},advocate:{nickname:"Jinx",role:"Stress testing, edge cases"},tester:{nickname:"Probe",role:"Unit and integration tests"},compliance:{nickname:"Rune",role:"Symbol compliance enforcement"},documentor:{nickname:"Scribe",role:".purpose, portal.yaml maintenance"}};function ke(o){let n=[],l=d.join(ne.homedir(),".paradigm","agents");for(let[r,f]of Object.entries(o.agents)){let m,i=r,b=d.join(l,`${r}.agent`);if(a.existsSync(b))try{let v=a.readFileSync(b,"utf8"),E=h.load(v);E?.nickname&&(m=E.nickname),E?.role&&(i=E.role);}catch{}!m&&I[r]&&(m=I[r].nickname,i=I[r].role);let S=f.source==="core"||f.source==="ecosystem"?f.source:oe.has(r)?"core":"ecosystem";n.push({id:r,nickname:m,role:i,source:S});}return n}async function be(o,n,l){if(!a.existsSync(n))return;let r;try{r=h.load(a.readFileSync(n,"utf8"))??{active:[]};}catch{return}let f=Array.isArray(r.active)?r.active:[];if(f.includes("compliance"))return;let{isCohortC:m}=await import('./migration-notices-MRZ6PVDS.js');if(!m(o))return;let i=d.join(o,".paradigm",".compliance-nomination-skipped");if(a.existsSync(i)&&!l.force)return;if(!process.stdin.isTTY||l.prompt===false){try{a.writeFileSync(i,"","utf8");}catch{}return}console.log(""),console.log(e.cyan("Step 2c-nominate/6: Symbol enforcement")),console.log(""),console.log(" This project defines ~aspects but no compliance-archetype agent"),console.log(" (Rune) is on the roster."),console.log(""),console.log(" Without a claimant, paradigm 6.0.4 no longer enforces aspect"),console.log(" coverage. You can:"),console.log(""),console.log(` ${e.green("[Y]")} Add Rune (compliance) to the roster \u2014 recommended`),console.log(" Authority defaults will be written to .paradigm/authority.yaml."),console.log(" Default mode: advise (Rune surfaces findings, never blocks)."),console.log(""),console.log(` ${e.yellow("[N]")} Skip \u2014 opt out of aspect enforcement for this project`),console.log(" This decision is remembered. Re-run with --force to revisit."),console.log("");let S=(await import('readline/promises')).createInterface({input:process.stdin,output:process.stdout}),v="";try{v=(await S.question(" Add Rune to roster? [Y/n]: ")).trim().toLowerCase();}catch{v="";}finally{S.close();}if(v===""||v==="y"||v==="yes"){r.active=[...f,"compliance"].sort();try{a.writeFileSync(n,h.dump(r,{lineWidth:-1,noRefs:!0}),"utf8"),console.log(e.green(" \u2713 Rune (compliance) added to roster"));}catch(R){a$1.operation("shift").debug("Roster update failed",{error:R.message});return}try{let{writeArchetypeDefaults:R}=await import('./authority-GCMPX7RW.js');await R(o,"archetype-default"),console.log(e.gray(" \u2713 Authority defaults written to .paradigm/authority.yaml"));}catch(R){a$1.operation("shift").debug("Authority defaults write failed",{error:R.message});}if(a.existsSync(i))try{a.unlinkSync(i);}catch{}}else {try{a.writeFileSync(i,"","utf8");}catch{}console.log(e.gray(" Skipped \u2014 opt out of aspect enforcement for this project"));}}async function Le(o={}){let n=process.cwd(),l=d.basename(n),r=d.join(n,".paradigm"),f$1=a.existsSync(r)&&a.statSync(r).isDirectory();console.log(e.blue(`
|
|
52
52
|
\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510`)),console.log(e.blue("\u2502")+e.white.bold(" paradigm shift ")+e.blue("\u2502")),console.log(e.blue("\u2502")+e.gray(" Full project setup in one command ")+e.blue("\u2502")),console.log(e.blue(`\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
|
|
53
53
|
`)),console.log(e.white(` \u{1F4C1} Project: ${e.cyan(l)}`)),console.log(e.white(` \u{1F4CD} Status: ${f$1?e.green("Paradigm detected"):e.yellow("New project")}`)),console.log("");let m=a$1.command("shift").start("Running paradigm shift",{project:l}),i=Se();if(!f$1||o.force){i.start("Step 1/6: Initializing Paradigm...");try{await a$2({force:o.force,quick:!0,name:l,stack:o.stack}),i.succeed(e.green("Paradigm initialized"));}catch(t){i.fail(e.red(`Init failed: ${t.message}`)),m.error("Shift failed at init",{error:t.message});return}}else {i.succeed(e.gray("Step 1/6: Already initialized (use --force to reinit)"));let t=d.join(r,"config.yaml");if(a.existsSync(t))try{let s=a.readFileSync(t,"utf8"),c=h.load(s);if(!c.discipline||c.discipline==="auto"){let p=a$3(n);if(p!=="backend"){let u=s.replace(/^discipline:\s*auto\b.*$/m,`discipline: ${p}`);u!==s&&(a.writeFileSync(t,u,"utf8"),console.log(e.green(` \u2713 Detected discipline: ${e.cyan(p)} (updated config.yaml)`)));}else if(!c.discipline){let u=s.replace(/^(project:\s*.+)$/m,`$1
|
|
54
54
|
discipline: ${p}`);u!==s&&(a.writeFileSync(t,u,"utf8"),console.log(e.green(` \u2713 Added discipline: ${e.cyan(p)} to config.yaml`)));}}}catch(s){a$1.operation("shift").debug("Discipline detection failed",{error:s.message});}}if(f$1){i.start("Step 1b/6: Checking for migrations...");try{let{migrateCommand:t}=await import('./migrate-R64OQGSM.js');await t({apply:!0,quiet:!0,noSync:!0}),i.succeed(e.green("Migrations applied"));}catch(t){i.warn(e.yellow(`Migration warning: ${t.message}`));}}{let t=d.join(r,"config.yaml");if(o.workspace&&a.existsSync(t)){let s=o.workspacePath?d.resolve(n,o.workspacePath):d.join(d.dirname(n),".paradigm-workspace");if(a.existsSync(s))try{let c=h.load(a.readFileSync(s,"utf8")),p=d.basename(n),u=d.dirname(s),g="./"+d.relative(u,n);if(c.members.some(j=>d.resolve(u,j.path)===n))console.log(e.green(` \u2713 Already a member of workspace: ${e.cyan(c.name)}`));else {let j=d$1(p,n);c.members.push({name:p,path:g,...j&&{role:j}}),a.writeFileSync(s,h.dump(c,{indent:2,lineWidth:120,noRefs:!0,sortKeys:!1,quotingType:'"'}),"utf8"),console.log(e.green(` \u2713 Joined workspace: ${e.cyan(c.name)} (added as member)`));}}catch(c){console.log(e.yellow(` \u26A0 Failed to join workspace: ${c.message}`));}else try{let c=d.basename(n),p=d.dirname(s),u="./"+d.relative(p,n),g=d$1(c,n),y={version:"1.0",name:o.workspace,members:[{name:c,path:u,...g&&{role:g}}]};a.mkdirSync(d.dirname(s),{recursive:!0}),a.writeFileSync(s,h.dump(y,{indent:2,lineWidth:120,noRefs:!0,sortKeys:!1,quotingType:'"'}),"utf8"),console.log(e.green(` \u2713 Created workspace: ${e.cyan(o.workspace)} at ${e.gray(d.relative(n,s))}`));}catch(c){console.log(e.yellow(` \u26A0 Failed to create workspace: ${c.message}`));}try{let c=a.readFileSync(t,"utf8"),p=h.load(c),u=d.relative(n,s);if(p.workspace!==u){if(p.workspace){let g=c.replace(/^workspace:\s*.*$/m,`workspace: "${u}"`);a.writeFileSync(t,g,"utf8");}else {let g=c.trimEnd()+`
|
|
@@ -57,4 +57,4 @@ workspace: "${u}"
|
|
|
57
57
|
workspace: "${j}"
|
|
58
58
|
`;a.writeFileSync(t,re,"utf8"),console.log(e.green(` \u2713 Found workspace: ${e.cyan(j)} (added to config.yaml)`));break}let y=d.dirname(p);if(y===p)break;p=y;}}}catch(s){a$1.operation("shift").debug("Workspace auto-detect failed",{error:s.message});}}if(!d$2(n)||o.force){console.log(e.cyan(" Step 2/6: Initializing team configuration..."));try{await b(n,{force:o.force,json:!1,configureModels:o.configureModels||!1,noConfigureModels:!o.configureModels}),console.log(e.green(` \u2713 Team configuration initialized
|
|
59
59
|
`));}catch(t){console.log(e.yellow(` \u26A0 Team init warning: ${t.message}
|
|
60
|
-
`));}}else i.succeed(e.gray("Step 2/6: Team already configured (use --force to reinit)"));if(o.force){let t=d.join(n,".paradigm",".compliance-nomination-skipped");if(a.existsSync(t))try{a.unlinkSync(t);}catch{}}let S=d.join(n,".paradigm","roster.yaml");if(!a.existsSync(S)||o.force)try{let t=a$4(n),s=b$1[t]||b$1.generic,c={version:"1.0",project:l,type:t,active:s.sort()};a.writeFileSync(S,h.dump(c,{lineWidth:-1,noRefs:!0}),"utf8"),console.log(e.green(` \u2713 Agent roster set: ${e.cyan(s.length)} agents for ${e.cyan(t)}`));}catch(t){a$1.operation("shift").debug("Roster setup failed",{error:t.message});}else try{let s=h.load(a.readFileSync(S,"utf8"))?.active?.length??0;console.log(e.gray(` \u2713 Agent roster exists (${s} agents active)`));}catch{console.log(e.gray(" \u2713 Agent roster exists"));}await be(n,S,o);{let t=d.join(n,".paradigm","adoptions.yaml"),s=a.existsSync(t);try{let c=a$4(n),p=s?await a$5(n):null,u=p&&Object.keys(p.agents).length>0;if(!u&&a.existsSync(S))p=await d$3(n),await b$2(n,p),a$1.operation("shift").debug("Migrated roster to adoptions",{count:Object.keys(p.agents).length});else if(!u){p=e$1(c);let g=a.existsSync(S)?h.load(a.readFileSync(S,"utf8")):{active:[]},y=new Date().toISOString();for(let j of g.active||[])p.agents[j]={adopted:y,source:oe.has(j)?"core":"ecosystem",defaultsAccepted:!0};Object.keys(p.agents).length>0&&await b$2(n,p);}if(p&&Object.keys(p.agents).length>0){let g=ke(p),y=f(g,c);console.log(y),console.log(e.green(` \u2713 ${Object.keys(p.agents).length} agents adopted`));}if(p&&p.agents.compliance){let g=d.join(n,".paradigm","authority.yaml");if(!a.existsSync(g))try{let{writeArchetypeDefaults:y}=await import('./authority-GCMPX7RW.js');await y(n,"archetype-default"),a$1.operation("shift").debug("Wrote archetype-default authority.yaml",{source:"default-adoption"});}catch(y){a$1.operation("shift").debug("Authority defaults write failed",{error:y.message});}}}catch(c){a$1.operation("shift").debug("Adoption ceremony failed",{error:c.message});}}{let t=d.join(r,"config.yaml");if(a.existsSync(t))try{let s=a.readFileSync(t,"utf8"),c=h.load(s);if(!c["model-resolution"]||o.force){let{ModelDiscovery:p}=await import('./model-discovery-HMB3YI4L.js'),g=new p(n).detectEnvironment(),y;g==="claude-code"?y={"tier-1":"opus","tier-2":"sonnet","tier-3":"haiku"}:g==="cursor"?y={"tier-1":"sonnet","tier-2":"sonnet","tier-3":"haiku"}:y={"tier-1":"sonnet","tier-2":"sonnet","tier-3":"sonnet"},c["model-resolution"]=y,a.writeFileSync(t,h.dump(c,{lineWidth:-1,noRefs:!0}),"utf8"),console.log(e.green(` \u2713 Model tiers configured for ${e.cyan(g)}: tier-1=${y["tier-1"]}, tier-2=${y["tier-2"]}, tier-3=${y["tier-3"]}`));}}catch(s){a$1.operation("shift").debug("Model tier config failed",{error:s.message});}}try{let{ensureEnforcementDefaults:t}=await import('./enforcement-
|
|
60
|
+
`));}}else i.succeed(e.gray("Step 2/6: Team already configured (use --force to reinit)"));if(o.force){let t=d.join(n,".paradigm",".compliance-nomination-skipped");if(a.existsSync(t))try{a.unlinkSync(t);}catch{}}let S=d.join(n,".paradigm","roster.yaml");if(!a.existsSync(S)||o.force)try{let t=a$4(n),s=b$1[t]||b$1.generic,c={version:"1.0",project:l,type:t,active:s.sort()};a.writeFileSync(S,h.dump(c,{lineWidth:-1,noRefs:!0}),"utf8"),console.log(e.green(` \u2713 Agent roster set: ${e.cyan(s.length)} agents for ${e.cyan(t)}`));}catch(t){a$1.operation("shift").debug("Roster setup failed",{error:t.message});}else try{let s=h.load(a.readFileSync(S,"utf8"))?.active?.length??0;console.log(e.gray(` \u2713 Agent roster exists (${s} agents active)`));}catch{console.log(e.gray(" \u2713 Agent roster exists"));}await be(n,S,o);{let t=d.join(n,".paradigm","adoptions.yaml"),s=a.existsSync(t);try{let c=a$4(n),p=s?await a$5(n):null,u=p&&Object.keys(p.agents).length>0;if(!u&&a.existsSync(S))p=await d$3(n),await b$2(n,p),a$1.operation("shift").debug("Migrated roster to adoptions",{count:Object.keys(p.agents).length});else if(!u){p=e$1(c);let g=a.existsSync(S)?h.load(a.readFileSync(S,"utf8")):{active:[]},y=new Date().toISOString();for(let j of g.active||[])p.agents[j]={adopted:y,source:oe.has(j)?"core":"ecosystem",defaultsAccepted:!0};Object.keys(p.agents).length>0&&await b$2(n,p);}if(p&&Object.keys(p.agents).length>0){let g=ke(p),y=f(g,c);console.log(y),console.log(e.green(` \u2713 ${Object.keys(p.agents).length} agents adopted`));}if(p&&p.agents.compliance){let g=d.join(n,".paradigm","authority.yaml");if(!a.existsSync(g))try{let{writeArchetypeDefaults:y}=await import('./authority-GCMPX7RW.js');await y(n,"archetype-default"),a$1.operation("shift").debug("Wrote archetype-default authority.yaml",{source:"default-adoption"});}catch(y){a$1.operation("shift").debug("Authority defaults write failed",{error:y.message});}}}catch(c){a$1.operation("shift").debug("Adoption ceremony failed",{error:c.message});}}{let t=d.join(r,"config.yaml");if(a.existsSync(t))try{let s=a.readFileSync(t,"utf8"),c=h.load(s);if(!c["model-resolution"]||o.force){let{ModelDiscovery:p}=await import('./model-discovery-HMB3YI4L.js'),g=new p(n).detectEnvironment(),y;g==="claude-code"?y={"tier-1":"opus","tier-2":"sonnet","tier-3":"haiku"}:g==="cursor"?y={"tier-1":"sonnet","tier-2":"sonnet","tier-3":"haiku"}:y={"tier-1":"sonnet","tier-2":"sonnet","tier-3":"sonnet"},c["model-resolution"]=y,a.writeFileSync(t,h.dump(c,{lineWidth:-1,noRefs:!0}),"utf8"),console.log(e.green(` \u2713 Model tiers configured for ${e.cyan(g)}: tier-1=${y["tier-1"]}, tier-2=${y["tier-2"]}, tier-3=${y["tier-3"]}`));}}catch(s){a$1.operation("shift").debug("Model tier config failed",{error:s.message});}}try{let{ensureEnforcementDefaults:t}=await import('./enforcement-VRE3WZOI.js');t(n)&&(console.log(e.green(` \u2713 Enforcement config initialized (${e.cyan("none")} preset)`)),console.log(e.dim(" Enforcement: none \u2014 symbol tracking available when you're ready. Rune will guide you.")));}catch(t){a$1.operation("shift").debug("Enforcement config setup failed",{error:t.message});}{i.start("Ensuring core files...");try{let{created:t,existed:s}=await Q(n);i.succeed(e.green(`Core files ensured: ${e.cyan(String(t.length))} created, ${e.cyan(String(s.length))} already existed`));}catch(t){i.warn(e.yellow(`Guaranteed files warning: ${t.message}`));}}if(o.quick)i.succeed(e.gray("Step 3/6: Skipped scan (--quick mode)"));else {i.start("Step 3/6: Scanning and indexing symbols...");try{await b$3(n,{quiet:!0}),i.succeed(e.green("Symbols indexed"));}catch(t){i.warn(e.yellow(`Scan warning: ${t.message}`));}}{let t=d.join(r,"config.yaml");if(a.existsSync(t))try{if(h.load(a.readFileSync(t,"utf8")).workspace){i.start("Step 3b/6: Reindexing workspace members...");try{let{workspaceReindexCommand:c}=await import('./workspace-VMSPYIBV.js');await c({quiet:!0}),i.succeed(e.green("Workspace members reindexed"));}catch(c){i.warn(e.yellow(`Workspace reindex: ${c.message}`));}}}catch(s){a$1.operation("shift").debug("Workspace config read failed",{error:s.message});}}let v=d.join(n,"portal.yaml");a.existsSync(v)||a.writeFileSync(v,h.dump({version:"1.0.0",gates:{},routes:{}},{lineWidth:-1,noRefs:true}),"utf8");let E=d.join(n,".paradigm","lore");a.existsSync(E)||a.mkdirSync(E,{recursive:true});let R=d.join(n,".paradigm","university");for(let t of ["content/notes","content/policies","content/quizzes","content/paths","diplomas"]){let s=d.join(R,t);a.existsSync(s)||a.mkdirSync(s,{recursive:true});}let N=d.join(R,"config.yaml");if(!a.existsSync(N)){let t="Project";try{let c=d.join(n,".paradigm","config.yaml");if(a.existsSync(c)){let p=h.load(a.readFileSync(c,"utf8"));p.project&&typeof p.project=="string"&&(t=p.project);}}catch{}let s={branding:{name:`${t} University`,tagline:`Learn the ${t} codebase`,institution:t},theme:{primary:"#6366f1",secondary:"#8b5cf6",accent:"#f59e0b",background:"#0f172a",surface:"#1e293b",text:"#f8fafc",textMuted:"#94a3b8",success:"#22c55e",error:"#ef4444",font:"Inter, system-ui, sans-serif"},content:{categories:[],defaultDifficulty:"beginner",requireApproval:false},diplomas:{includeGlobalPLSAT:true}};a.writeFileSync(N,h.dump(s,{lineWidth:-1,noRefs:true}),"utf8");}i.start("Step 4/6: Syncing IDE configurations...");try{let t=o.ide?[o.ide]:["claude","cursor","copilot","windsurf","agents"],s=[];for(let c of t)try{await a$6(c,{quiet:!0,force:!0}),s.push(c);}catch{}s.length>0?i.succeed(e.green(`IDE configs synced: ${s.join(", ")}`)):i.warn(e.yellow("No IDE configs to sync"));}catch(t){i.warn(e.yellow(`Sync warning: ${t.message}`));}i.start("Step 5/6: Installing hooks...");try{await a$7({force:o.force}),i.succeed(e.green("Hooks installed (git + Claude Code + Cursor)"));}catch(t){i.warn(e.yellow(`Hooks warning: ${t.message}`));}if(o.verify){i.start("Step 6/6: Running health checks...");try{await a$8({quiet:!0})?i.succeed(e.green("All health checks passed")):i.warn(e.yellow("Some health checks need attention"));}catch(t){i.warn(e.yellow(`Doctor warning: ${t.message}`));}}else i.succeed(e.gray("Step 6/6: Skipped verify (use --verify to check health)"));console.log(""),console.log(e.blue("\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510")),console.log(e.blue("\u2502")+e.white.bold(" \u2728 Paradigm shift complete! ")+e.blue("\u2502")),console.log(e.blue("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518")),console.log(""),console.log(e.white(" Created/Updated:")),console.log(e.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));let O=[{path:".paradigm/config.yaml",desc:"Project configuration"},{path:".paradigm/navigator.yaml",desc:"Symbol navigation map"},{path:".paradigm/agents.yaml",desc:"Team agent configuration"},{path:".paradigm/adoptions.yaml",desc:"Agent adoption records"},{path:".purpose",desc:"Root feature definitions"},{path:".paradigm/lore/",desc:"Project lore timeline",isDir:true},{path:"portal.yaml",desc:"Authorization gates"},{path:".paradigm/roster.yaml",desc:"Agent roster for this project"},{path:"CLAUDE.md",desc:"Claude Code AI instructions"},{path:"AGENTS.md",desc:"Universal AI agent instructions"},{path:".cursor/rules/",desc:"Cursor AI instructions",isDir:true},{path:".claude/hooks/",desc:"Claude Code enforcement hooks",isDir:true,optional:true},{path:".cursor/hooks/",desc:"Cursor enforcement hooks",isDir:true,optional:true}],W=d.join(r,"config.yaml");if(a.existsSync(W))try{let t=h.load(a.readFileSync(W,"utf8"));if(typeof t.workspace=="string"){let s=d.resolve(n,t.workspace),c=d.relative(n,s);O.push({path:c,desc:"Multi-project workspace",optional:!0});}}catch(t){a$1.operation("shift").debug("Summary config read failed",{error:t.message});}for(let t of O){let s=d.join(n,t.path);a.existsSync(s)?console.log(e.green(" \u2713 ")+e.white(t.path.padEnd(28))+e.gray(t.desc)):t.optional||console.log(e.yellow(" \u25CB ")+e.gray(t.path.padEnd(28))+e.gray(`(${t.desc})`));}try{let t=await Z(n),s=ee(t);s&&console.log(s);}catch(t){a$1.operation("shift").debug("Recommendations engine failed",{error:t.message}),console.log(""),console.log(e.white(" Next steps:")),console.log(e.gray(" "+"\u2500".repeat(49))),console.log(e.white(" 1. ")+e.gray("Edit ")+e.cyan(".purpose")+e.gray(" to define your features")),console.log(e.white(" 2. ")+e.gray("Run ")+e.cyan("paradigm shift --verify")+e.gray(" to check health")),console.log("");}try{let{captureSnapshot:t,seedMetricsConsent:s}=await import('./metrics-UESGUHTA.js');s(n),t(n);}catch(t){a$1.operation("shift").debug("metrics snapshot failed",{error:t.message});}m.success("Paradigm shift complete",{project:l});}export{be as runComplianceNominationStep,Le as shiftCommand};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
export{h as registerTools}from'./chunk-
|
|
2
|
+
export{h as registerTools}from'./chunk-SRWROALW.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';
|
|
@@ -4,7 +4,7 @@ title: Your First paradigm shift
|
|
|
4
4
|
type: note
|
|
5
5
|
author: paradigm
|
|
6
6
|
created: '2026-04-22'
|
|
7
|
-
updated: '2026-04
|
|
7
|
+
updated: '2026-05-04'
|
|
8
8
|
tags:
|
|
9
9
|
- course
|
|
10
10
|
- para-001
|
|
@@ -59,7 +59,7 @@ Each file has a specific job:
|
|
|
59
59
|
|
|
60
60
|
`paradigm shift` also installed Git hooks and Claude Code hooks. These run automatically when you commit or finish a task, checking that your Paradigm metadata stays in sync with your code.
|
|
61
61
|
|
|
62
|
-
By default, hooks use **
|
|
62
|
+
By default, hooks use **none enforcement** — all 13 compliance checks are off, so you will never see a blocking warning simply from working. Hooks are there and ready; they only activate if you choose a higher enforcement level. As you get comfortable with Paradigm's symbol system, you can enable compliance guidance — starting with `minimal` (warn-only) and working up from there. The compliance agent Rune will invite you when you seem ready.
|
|
63
63
|
|
|
64
64
|
### Try It: Explore What Was Created
|
|
65
65
|
|
|
@@ -4,12 +4,12 @@ title: Enforcement Levels
|
|
|
4
4
|
type: note
|
|
5
5
|
author: paradigm
|
|
6
6
|
created: '2026-04-22'
|
|
7
|
-
updated: '2026-04
|
|
7
|
+
updated: '2026-05-04'
|
|
8
8
|
tags:
|
|
9
9
|
- course
|
|
10
10
|
- para-301
|
|
11
|
-
-
|
|
12
|
-
-
|
|
11
|
+
- four-enforcement-levels
|
|
12
|
+
- none-is-the
|
|
13
13
|
- 13-checks-control
|
|
14
14
|
symbols: []
|
|
15
15
|
difficulty: beginner
|
|
@@ -20,13 +20,19 @@ origin: imported
|
|
|
20
20
|
source: courses/para-301.json
|
|
21
21
|
---
|
|
22
22
|
|
|
23
|
-
## The
|
|
23
|
+
## The Four Enforcement Levels
|
|
24
24
|
|
|
25
25
|
Paradigm enforcement is configurable. Not every project needs the same rigor — a weekend prototype has different needs than a healthcare platform. Enforcement levels control which compliance checks **block** (stop you), **warn** (notify but continue), or are **off** (silent).
|
|
26
26
|
|
|
27
|
+
### None — The Default
|
|
28
|
+
|
|
29
|
+
`none` is the default for all new projects created by `paradigm shift`. All 13 checks are set to `off`. Hooks install but never trigger compliance violations. You can build freely with agents, Sentinel, or Conductor without seeing a compliance warning.
|
|
30
|
+
|
|
31
|
+
This is intentional. Many teams adopt Paradigm for agent orchestration, session memory, or ambient intelligence — not for symbol compliance. When you are ready to add symbol tracking, the compliance agent Rune will invite you. See [Rune's Promotion Model](N-para-301-rune-promotion.md).
|
|
32
|
+
|
|
27
33
|
### Minimal — For Learning and Prototyping
|
|
28
34
|
|
|
29
|
-
Minimal enforcement is the default
|
|
35
|
+
Minimal enforcement is not the default — you opt into it when you are ready to start symbol tracking. Only two checks are active, both as warnings:
|
|
30
36
|
|
|
31
37
|
- `purpose-coverage` — warns if source directories lack `.purpose` files
|
|
32
38
|
- `habits-blocking` — warns if defined habits are being violated
|
|
@@ -58,7 +64,7 @@ Set the level in `.paradigm/config.yaml`:
|
|
|
58
64
|
|
|
59
65
|
```yaml
|
|
60
66
|
enforcement:
|
|
61
|
-
level: balanced # minimal | balanced | strict
|
|
67
|
+
level: balanced # none | minimal | balanced | strict
|
|
62
68
|
```
|
|
63
69
|
|
|
64
70
|
Override individual checks when a preset does not quite fit:
|
|
@@ -93,10 +99,11 @@ Per-check overrides take precedence over the preset. This lets you start with a
|
|
|
93
99
|
|
|
94
100
|
## Progression Strategy
|
|
95
101
|
|
|
96
|
-
|
|
102
|
+
The default progression is opt-in, not imposed:
|
|
97
103
|
|
|
98
|
-
1. **Start
|
|
99
|
-
2. **
|
|
100
|
-
3. **
|
|
104
|
+
1. **Start at none** — Build freely. Agents, Sentinel, and Conductor all work without compliance warnings.
|
|
105
|
+
2. **Rune invites you to minimal** — When you show readiness signals (referencing symbol syntax, asking about auth gates, touching 3+ files), Rune invites you to enable `minimal` enforcement. You are not forced — you choose when you want guidance.
|
|
106
|
+
3. **Move to balanced** after you have adopted symbol-writing habits — catch issues early, still flexible.
|
|
107
|
+
4. **Upgrade to strict** for production-critical or regulated codebases.
|
|
101
108
|
|
|
102
|
-
You can change levels at any time.
|
|
109
|
+
You can change levels at any time. Teams adopting Paradigm purely for agents or Sentinel can stay at `none` indefinitely.
|
|
@@ -4,7 +4,7 @@ title: The paradigm shift Command
|
|
|
4
4
|
type: note
|
|
5
5
|
author: paradigm
|
|
6
6
|
created: '2026-04-22'
|
|
7
|
-
updated: '2026-04
|
|
7
|
+
updated: '2026-05-04'
|
|
8
8
|
tags:
|
|
9
9
|
- course
|
|
10
10
|
- para-301
|
|
@@ -80,7 +80,7 @@ After `paradigm shift`, your project has:
|
|
|
80
80
|
|
|
81
81
|
```
|
|
82
82
|
.paradigm/
|
|
83
|
-
config.yaml # Project configuration
|
|
83
|
+
config.yaml # Project configuration (enforcement.level: none by default)
|
|
84
84
|
tags.yaml # Tag taxonomy
|
|
85
85
|
roster.yaml # Agent team roster
|
|
86
86
|
agents.yaml # Agent tier assignments
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: N-para-301-rune-promotion
|
|
3
|
+
title: "Rune's Promotion Model"
|
|
4
|
+
type: note
|
|
5
|
+
author: paradigm
|
|
6
|
+
created: '2026-05-04'
|
|
7
|
+
updated: '2026-05-04'
|
|
8
|
+
tags:
|
|
9
|
+
- course
|
|
10
|
+
- para-301
|
|
11
|
+
- rune-promotion
|
|
12
|
+
- none-enforcement
|
|
13
|
+
- readiness-signals
|
|
14
|
+
symbols: []
|
|
15
|
+
difficulty: beginner
|
|
16
|
+
estimatedMinutes: 3
|
|
17
|
+
prerequisites:
|
|
18
|
+
- N-para-301-enforcement-levels
|
|
19
|
+
category: paradigm-core
|
|
20
|
+
origin: authored
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Enforcement You Earn, Not Enforcement You Endure
|
|
24
|
+
|
|
25
|
+
New Paradigm projects start at `none` enforcement — all 13 compliance checks off. This is deliberate. Teams using Paradigm for agent orchestration, Sentinel, or Conductor should not be interrupted by symbol-coverage warnings they never asked for.
|
|
26
|
+
|
|
27
|
+
But compliance tracking has real value once you are writing `.purpose` files and referencing symbols. The challenge is knowing when a team has crossed that threshold.
|
|
28
|
+
|
|
29
|
+
Rune — the compliance archetype agent — solves this with a promotion model. Instead of waiting for developers to read documentation and manually edit `config.yaml`, Rune watches for behavioral signals that indicate readiness and extends an invitation.
|
|
30
|
+
|
|
31
|
+
## Readiness Signals
|
|
32
|
+
|
|
33
|
+
Rune monitors the active session for signals that suggest the developer is already thinking in Paradigm terms:
|
|
34
|
+
|
|
35
|
+
- **Symbol syntax usage** — The developer references `#component`, `$flow`, `^gate`, `!signal`, or `~aspect` in prompts or commit messages
|
|
36
|
+
- **Auth and dependency questions** — The developer asks about protecting routes, declaring gates, or understanding component dependencies
|
|
37
|
+
- **Multi-file reach** — The session touches 3 or more source files, which is the threshold where `.purpose` coverage starts to matter
|
|
38
|
+
|
|
39
|
+
Any one of these signals suggests the developer is past the "I'm just exploring" stage. Two or more Tier B signals (or any Tier A signal) trigger Rune's invitation.
|
|
40
|
+
|
|
41
|
+
## The Invitation
|
|
42
|
+
|
|
43
|
+
When readiness signals accumulate, Rune surfaces a single, non-blocking message:
|
|
44
|
+
|
|
45
|
+
> Paradigm's symbol system (#components, $flows, ^gates, !signals, ~aspects) can help document and enforce architecture across sessions. Enforcement is currently **none** — all checks are off. Would you like to enable symbol tracking?
|
|
46
|
+
>
|
|
47
|
+
> Options: `minimal` (warn-only), `balanced` (blocks on missing purpose files), `snooze` (ask in 7 days), or `never` (don't ask again).
|
|
48
|
+
|
|
49
|
+
Rune does not repeat the invitation more than once per session.
|
|
50
|
+
|
|
51
|
+
## Why This Approach
|
|
52
|
+
|
|
53
|
+
Starting at `none` and inviting up avoids the "turned off warnings I found annoying" decay pattern. A developer who has never been interrupted by a compliance warning has no reason to resent Rune's invitation. The invitation arrives as helpful context — not friction.
|
|
54
|
+
|
|
55
|
+
Teams that never reference symbols, never ask about gates, and never touch 3+ files in a session will never see Rune's invitation. This is correct behavior — they do not need compliance tracking.
|
|
56
|
+
|
|
57
|
+
## After Accepting
|
|
58
|
+
|
|
59
|
+
When a developer accepts, Paradigm updates `enforcement.level` in `.paradigm/config.yaml` immediately. The developer can always return to `none` at any time.
|
|
60
|
+
|
|
61
|
+
## The Progression Path
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
none → minimal → balanced → strict
|
|
65
|
+
(Rune (team (regulated
|
|
66
|
+
invites) ready) domains)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
There is no mandatory progression. Many teams run at `balanced` indefinitely. Strict is reserved for regulated domains where compliance is not optional.
|
|
@@ -4,7 +4,7 @@ title: Hook Enforcement & Automation
|
|
|
4
4
|
type: note
|
|
5
5
|
author: paradigm
|
|
6
6
|
created: '2026-04-22'
|
|
7
|
-
updated: '2026-04
|
|
7
|
+
updated: '2026-05-04'
|
|
8
8
|
tags:
|
|
9
9
|
- course
|
|
10
10
|
- para-501
|
|
@@ -26,6 +26,8 @@ Paradigm's value depends on discipline. Purpose files must be updated when code
|
|
|
26
26
|
|
|
27
27
|
Hooks close this gap. They are automated checks that run at specific points in the development workflow, catching violations before they become technical debt. Paradigm uses three hooks, each with a distinct role and severity.
|
|
28
28
|
|
|
29
|
+
One important nuance: the stop hook's compliance checks are gated by your project's enforcement level. On the default level (`none`), all 13 checks are `off` — the hook runs but nothing fires. Compliance checking only begins when you move to `minimal` or higher. If you are at `none` and want to see what the stop hook would catch, run `paradigm doctor` — it runs all checks regardless of enforcement level.
|
|
30
|
+
|
|
29
31
|
## The Stop Hook
|
|
30
32
|
|
|
31
33
|
The stop hook is the primary enforcer. It runs before an agent session completes and can **block** the session from finishing if compliance checks fail.
|
|
@@ -4,7 +4,7 @@ title: 'Lesson 7: Orchestration Enforcement'
|
|
|
4
4
|
type: note
|
|
5
5
|
author: paradigm
|
|
6
6
|
created: '2026-04-22'
|
|
7
|
-
updated: '2026-04
|
|
7
|
+
updated: '2026-05-04'
|
|
8
8
|
tags:
|
|
9
9
|
- course
|
|
10
10
|
- para-701
|
|
@@ -54,6 +54,15 @@ This habit fires at **preflight** (session start). It checks whether `paradigm_o
|
|
|
54
54
|
|
|
55
55
|
The severity is `warn`, not `block`. This is deliberate. Blocking on orchestration would prevent quick fixes, hot patches, and simple tasks that genuinely do not need multi-agent coordination. The warning surfaces the recommendation; the human decides whether to follow it.
|
|
56
56
|
|
|
57
|
+
Note: on the default enforcement level (`none`), this check is `off` — no warning fires. It activates at `minimal` or higher. To get orchestration nudges on a `none` project without enabling all checks, override just this one:
|
|
58
|
+
|
|
59
|
+
```yaml
|
|
60
|
+
enforcement:
|
|
61
|
+
level: none
|
|
62
|
+
checks:
|
|
63
|
+
orchestration-required: warn
|
|
64
|
+
```
|
|
65
|
+
|
|
57
66
|
### 2. agent-coverage-validated (postflight, advisory)
|
|
58
67
|
|
|
59
68
|
```typescript
|
|
@@ -3,7 +3,7 @@ title: 'PARA 301: Operations — Enforcement Levels'
|
|
|
3
3
|
description: 'Quiz for lesson: Enforcement Levels'
|
|
4
4
|
author: paradigm
|
|
5
5
|
created: '2026-04-22'
|
|
6
|
-
updated: '2026-04
|
|
6
|
+
updated: '2026-05-04'
|
|
7
7
|
tags:
|
|
8
8
|
- course
|
|
9
9
|
- para-301
|
|
@@ -44,3 +44,23 @@ questions:
|
|
|
44
44
|
E: aspect-anchors check failed — aspects in src/payments/ have broken anchors
|
|
45
45
|
correct: B
|
|
46
46
|
explanation: 'On balanced enforcement, purpose-coverage is the only check set to block (besides habits-blocking). The error message says "missing .purpose file" which means the directory lacks one entirely — that is purpose-coverage, not purpose-exists (which checks that referenced files exist) or purpose-freshness (which checks staleness). Fix: create a .purpose file in src/payments/ describing its components.'
|
|
47
|
+
- id: q4
|
|
48
|
+
question: A developer runs `paradigm shift` on a brand-new project. What enforcement level is active by default?
|
|
49
|
+
choices:
|
|
50
|
+
A: Minimal — warn-only enforcement so the developer can learn without getting blocked
|
|
51
|
+
B: Balanced — the practical default for most development teams
|
|
52
|
+
C: None — all 13 checks are off; hooks install but never trigger compliance violations
|
|
53
|
+
D: Strict — the safest default for new projects
|
|
54
|
+
E: No enforcement section is created — the developer must configure it manually
|
|
55
|
+
correct: C
|
|
56
|
+
explanation: "Since the `none` preset was introduced, fresh `paradigm shift` produces `enforcement.level: none`. All 13 checks start at off. This means teams adopting Paradigm for agent orchestration, Sentinel, or Conductor never see compliance warnings unless they explicitly enable them."
|
|
57
|
+
- id: q5
|
|
58
|
+
question: A developer at `none` enforcement starts referencing symbol syntax in their prompts and asks about authentication gates. What happens next?
|
|
59
|
+
choices:
|
|
60
|
+
A: Nothing — `none` is permanent until the developer edits config.yaml manually
|
|
61
|
+
B: The stop hook automatically upgrades enforcement to minimal
|
|
62
|
+
C: Rune detects these readiness signals and proactively invites the developer to enable `minimal` or `balanced` enforcement
|
|
63
|
+
D: Paradigm blocks the session until the developer chooses an enforcement level
|
|
64
|
+
E: The developer must run `paradigm doctor` to trigger enforcement selection
|
|
65
|
+
correct: C
|
|
66
|
+
explanation: "Rune's promotion model monitors behavioral signals — using symbol syntax, asking about auth or dependencies, touching 3+ files. When these appear, Rune invites (never forces) the developer to step up to `minimal` or `balanced`. The developer chooses whether to accept."
|
|
@@ -3,7 +3,7 @@ title: 'PARA 701: Agent Mastery — Lesson 7: Orchestration Enforcement'
|
|
|
3
3
|
description: 'Quiz for lesson: Lesson 7: Orchestration Enforcement'
|
|
4
4
|
author: paradigm
|
|
5
5
|
created: '2026-04-22'
|
|
6
|
-
updated: '2026-04
|
|
6
|
+
updated: '2026-05-04'
|
|
7
7
|
tags:
|
|
8
8
|
- course
|
|
9
9
|
- para-701
|
|
@@ -54,6 +54,16 @@ questions:
|
|
|
54
54
|
E: Remove all agents from the roster except the orchestrator
|
|
55
55
|
correct: B
|
|
56
56
|
explanation: 'Habit severity is tunable per project. Changing `orchestration-required` from `warn` to `block` in the project''s habits override means the habit will block session completion if `paradigm_orchestrate_inline` was not called. This is the designed customization path: the seed habit provides a sensible default (`warn`), and projects can upgrade to `block` if they need strict enforcement. No source code modification is needed.'
|
|
57
|
+
- id: q6
|
|
58
|
+
question: A developer's project is at `none` enforcement. They add a 5-file feature. Does the `orchestration-required` habit fire a preflight warning?
|
|
59
|
+
choices:
|
|
60
|
+
A: Yes — the habit always fires regardless of enforcement level because it is a seed habit
|
|
61
|
+
B: No — on `none` enforcement, the `orchestration-required` check is off, so no warning appears
|
|
62
|
+
C: Yes — but only if the task description mentions security or auth
|
|
63
|
+
D: No — but only because `none` enforcement disables all habit evaluation entirely
|
|
64
|
+
E: Yes — but the warning is demoted to an informational note instead of a `warn`
|
|
65
|
+
correct: B
|
|
66
|
+
explanation: "The `orchestration-required` habit corresponds to the enforcement check of the same name. On `none` enforcement, that check is off. Teams at `none` can override just that check to `warn` to get orchestration nudges without enabling the rest of the enforcement suite."
|
|
57
67
|
- id: q5
|
|
58
68
|
question: The `agent-coverage-validated` habit checks for which tools in its evaluation?
|
|
59
69
|
choices:
|
package/package.json
CHANGED
package/dist/chunk-KYA4TP26.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import*as i from'fs';import*as u from'path';import*as f from'js-yaml';var s=["purpose-coverage","purpose-exists","portal-gates","aspect-anchors","purpose-freshness","aspect-advisory","lore-required","habits-blocking","purpose-required-patterns","drift-detection","portal-compliance","graduation-tracking","orchestration-required"];var A={"purpose-coverage":"block","purpose-exists":"block","portal-gates":"block","aspect-anchors":"block","purpose-freshness":"warn","aspect-advisory":"warn","lore-required":"block","habits-blocking":"block","purpose-required-patterns":"block","drift-detection":"block","portal-compliance":"block","graduation-tracking":"warn","orchestration-required":"block"},O={"purpose-coverage":"block","purpose-exists":"warn","portal-gates":"warn","aspect-anchors":"warn","purpose-freshness":"warn","aspect-advisory":"off","lore-required":"warn","habits-blocking":"block","purpose-required-patterns":"warn","drift-detection":"warn","portal-compliance":"warn","graduation-tracking":"off","orchestration-required":"warn"},P={"purpose-coverage":"warn","purpose-exists":"off","portal-gates":"off","aspect-anchors":"off","purpose-freshness":"off","aspect-advisory":"off","lore-required":"off","habits-blocking":"warn","purpose-required-patterns":"off","drift-detection":"off","portal-compliance":"off","graduation-tracking":"off","orchestration-required":"off"},x={strict:A,balanced:O,minimal:P};function p(e){return {...x[e]}}function V(e,t){return x[e][t]}function b(e){return s.includes(e)}function E(e){return e==="block"||e==="warn"||e==="off"}function S(e){return e==="strict"||e==="balanced"||e==="minimal"}var L="minimal",j={threshold:3,detection:"git-diff",exempt:["*.md","*.yaml","*.yml",".purpose"]};function T(e){let t=u.join(e,".paradigm","config.yaml");if(!i.existsSync(t))return h();try{let n=i.readFileSync(t,"utf8"),r=f.load(n);if(!r||typeof r!="object")return h();let o=r.enforcement;if(!o||typeof o!="object")return h();let y=o.level,q=typeof y=="string"&&S(y)?y:L,v=o.checks,w={};if(v&&typeof v=="object")for(let[d,C]of Object.entries(v))b(d)&&typeof C=="string"&&E(C)&&(w[d]=C);let c=o.orchestration,l={...j};return c&&typeof c=="object"&&(typeof c.threshold=="number"&&(l.threshold=c.threshold),typeof c.detection=="string"&&(l.detection=c.detection),Array.isArray(c.exempt)&&(l.exempt=c.exempt.filter(d=>typeof d=="string"))),{level:q,checks:w,orchestration:l}}catch{return h()}}function h(){return {level:L,checks:{},orchestration:{...j}}}function _(e,t){let n=e.checks[t];return n!==void 0?n:p(e.level)[t]}function D(e){let t=p(e.level);for(let n of s){let r=e.checks[n];r!==void 0&&(t[n]=r);}return t}function k(e){let t=u.join(e,".paradigm","config.yaml");if(!i.existsSync(t))throw new Error(`Config not found: ${t}`);let n=i.readFileSync(t,"utf8"),r=f.load(n);if(!r||typeof r!="object")throw new Error("Config is not a valid YAML object");return [r,n]}function a(e,t){let n=u.join(e,".paradigm","config.yaml"),r=f.dump(t,{lineWidth:-1,noRefs:true,sortKeys:false,quotingType:"'"});i.writeFileSync(n,r,"utf8");}function g(e){return (!e.enforcement||typeof e.enforcement!="object")&&(e.enforcement={level:"minimal",checks:{}}),e.enforcement}function F(e,t){let[n]=k(e),r=g(n);r.level=t,a(e,n);}function H(e,t,n){let[r]=k(e),o=g(r);(!o.checks||typeof o.checks!="object")&&(o.checks={}),o.checks[t]=n,a(e,r);}function K(e,t){let[n]=k(e),r=g(n);r.checks&&typeof r.checks=="object"&&delete r.checks[t],a(e,n);}function M(e){let[t]=k(e),n=g(t);n.checks={},a(e,t);}function N(e){let t=u.join(e,".paradigm","config.yaml");if(!i.existsSync(t))return false;try{let n=i.readFileSync(t,"utf8"),r=f.load(n);return !r||typeof r!="object"||r.enforcement?!1:(r.enforcement={level:"balanced",checks:{},orchestration:{threshold:3,detection:"git-diff",exempt:["*.md","*.yaml","*.yml",".purpose"]}},a(e,r),!0)}catch{return false}}export{s as a,p as b,V as c,b as d,E as e,S as f,T as g,_ as h,D as i,F as j,H as k,K as l,M as m,N as n};
|