@jigyasudham/veto 1.4.0 → 1.4.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/README.md +72 -0
- package/dist/council/decision-engine.d.ts.map +1 -1
- package/dist/council/decision-engine.js +20 -0
- package/dist/council/decision-engine.js.map +1 -1
- package/dist/council/decision-extractor.d.ts +13 -0
- package/dist/council/decision-extractor.d.ts.map +1 -0
- package/dist/council/decision-extractor.js +66 -0
- package/dist/council/decision-extractor.js.map +1 -0
- package/dist/council/devil-advocate.d.ts.map +1 -1
- package/dist/council/devil-advocate.js +12 -1
- package/dist/council/devil-advocate.js.map +1 -1
- package/dist/council/lead-developer.d.ts.map +1 -1
- package/dist/council/lead-developer.js +34 -14
- package/dist/council/lead-developer.js.map +1 -1
- package/dist/council/legal-compliance.d.ts.map +1 -1
- package/dist/council/legal-compliance.js +44 -24
- package/dist/council/legal-compliance.js.map +1 -1
- package/dist/council/llm-council.d.ts.map +1 -1
- package/dist/council/llm-council.js +41 -18
- package/dist/council/llm-council.js.map +1 -1
- package/dist/council/product-manager.d.ts.map +1 -1
- package/dist/council/product-manager.js +33 -13
- package/dist/council/product-manager.js.map +1 -1
- package/dist/council/security.d.ts.map +1 -1
- package/dist/council/security.js +44 -24
- package/dist/council/security.js.map +1 -1
- package/dist/council/system-architect.d.ts.map +1 -1
- package/dist/council/system-architect.js +33 -13
- package/dist/council/system-architect.js.map +1 -1
- package/dist/council/ux-designer.d.ts.map +1 -1
- package/dist/council/ux-designer.js +47 -26
- package/dist/council/ux-designer.js.map +1 -1
- package/dist/server.js +43 -9
- package/dist/server.js.map +1 -1
- package/dist/skills/memory/skill-session-restore.d.ts.map +1 -1
- package/dist/skills/memory/skill-session-restore.js +19 -24
- package/dist/skills/memory/skill-session-restore.js.map +1 -1
- package/dist/skills/memory/skill-session-save.js +4 -4
- package/dist/skills/memory/skill-session-save.js.map +1 -1
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { decide, formatDebate } from './decision-engine.js';
|
|
5
5
|
import { buildContextString } from '../context/reader.js';
|
|
6
6
|
import { searchKnowledge } from '../memory/local.js';
|
|
7
|
+
import { extractDecision } from './decision-extractor.js';
|
|
7
8
|
// Deterministic fallbacks — one per agent
|
|
8
9
|
import { analyze as leadDevFallback } from './lead-developer.js';
|
|
9
10
|
import { analyze as pmFallback } from './product-manager.js';
|
|
@@ -16,32 +17,46 @@ import { analyze as securityFallback } from './security.js';
|
|
|
16
17
|
const SYSTEM_PROMPTS = {
|
|
17
18
|
lead_dev: `You are the Lead Developer in a software council. Assess technical feasibility, code quality, implementation risk, and engineering best practices. Be pragmatic — approve sound work, warn about concerning patterns, block only when something is technically broken or creates severe technical debt.
|
|
18
19
|
|
|
20
|
+
IMPORTANT: If the task presents two specific options (e.g. "A vs B" or "should we X or Y"), your recommendation MUST explicitly state which option you prefer and why — do not give generic advice that applies to both. Name the option you prefer in your recommendation field.
|
|
21
|
+
|
|
19
22
|
Return ONLY valid JSON, no other text:
|
|
20
|
-
{"verdict":"approve"|"warn"|"block","reason":"one sentence","concerns":["
|
|
23
|
+
{"verdict":"approve"|"warn"|"block","reason":"one sentence directly addressing the task","concerns":["specific concern"],"recommendation":"Prefer [named option] — reason specific to your domain"}`,
|
|
21
24
|
pm: `You are the Product Manager in a software council. Assess user value, business alignment, scope clarity, and product-market fit. Approve features that deliver clear value, warn when scope is vague or requirements are incomplete, block only when something contradicts core product goals.
|
|
22
25
|
|
|
26
|
+
IMPORTANT: If the task presents two specific options (e.g. "A vs B" or "should we X or Y"), your recommendation MUST explicitly state which option you prefer and why — do not give generic advice that applies to both. Name the option you prefer in your recommendation field.
|
|
27
|
+
|
|
23
28
|
Return ONLY valid JSON, no other text:
|
|
24
|
-
{"verdict":"approve"|"warn"|"block","reason":"one sentence","concerns":["
|
|
29
|
+
{"verdict":"approve"|"warn"|"block","reason":"one sentence directly addressing the task","concerns":["specific concern"],"recommendation":"Prefer [named option] — reason specific to your domain"}`,
|
|
25
30
|
architect: `You are the System Architect in a software council. Assess scalability, maintainability, system design, coupling, and architectural integrity. Approve decisions that fit the architecture well, warn about complexity or coupling risks, block breaking changes that violate architectural principles.
|
|
26
31
|
|
|
32
|
+
IMPORTANT: If the task presents two specific options (e.g. "A vs B" or "should we X or Y"), your recommendation MUST explicitly state which option you prefer and why — do not give generic advice that applies to both. Name the option you prefer in your recommendation field.
|
|
33
|
+
|
|
27
34
|
Return ONLY valid JSON, no other text:
|
|
28
|
-
{"verdict":"approve"|"warn"|"block","reason":"one sentence","concerns":["
|
|
35
|
+
{"verdict":"approve"|"warn"|"block","reason":"one sentence directly addressing the task","concerns":["specific concern"],"recommendation":"Prefer [named option] — reason specific to your domain"}`,
|
|
29
36
|
ux: `You are the UX Designer in a software council. Assess usability, accessibility, user flow, and experience quality. Approve changes that improve or maintain UX, warn about confusing patterns or missing states, block changes that harm users or violate accessibility standards.
|
|
30
37
|
|
|
38
|
+
IMPORTANT: If the task presents two specific options (e.g. "A vs B" or "should we X or Y"), your recommendation MUST explicitly state which option you prefer and why — do not give generic advice that applies to both. Name the option you prefer in your recommendation field.
|
|
39
|
+
|
|
31
40
|
Return ONLY valid JSON, no other text:
|
|
32
|
-
{"verdict":"approve"|"warn"|"block","reason":"one sentence","concerns":["
|
|
41
|
+
{"verdict":"approve"|"warn"|"block","reason":"one sentence directly addressing the task","concerns":["specific concern"],"recommendation":"Prefer [named option] — reason specific to your domain"}`,
|
|
33
42
|
devil: `You are the Devil's Advocate in a software council. Your job is to find problems others miss — edge cases, failure modes, hidden dependencies, unintended consequences, and flawed assumptions. Be incisive. Warn about risks that compound over time. Block when you identify a fatal flaw.
|
|
34
43
|
|
|
44
|
+
IMPORTANT: If the task presents two specific options, challenge the one that looks more attractive or ambitious. Ask: what breaks first? What's the worst-case failure mode of the preferred option? Name the option you are challenging in your reason.
|
|
45
|
+
|
|
35
46
|
Return ONLY valid JSON, no other text:
|
|
36
|
-
{"verdict":"approve"|"warn"|"block","reason":"one sentence","concerns":["
|
|
47
|
+
{"verdict":"approve"|"warn"|"block","reason":"one sentence challenging the specific proposed option","concerns":["failure mode 1","failure mode 2"],"recommendation":"actionable mitigation for the named option"}`,
|
|
37
48
|
legal: `You are the Legal & Compliance officer in a software council. Assess regulatory risk, data privacy (GDPR, CCPA), licensing conflicts, and compliance requirements. Approve decisions within legal boundaries, warn about grey areas, block anything that creates clear legal liability or compliance violations.
|
|
38
49
|
|
|
50
|
+
IMPORTANT: If the task presents two specific options (e.g. "A vs B" or "should we X or Y"), your recommendation MUST explicitly state which option has lower legal risk and why — do not give generic advice that applies to both. Name the safer option in your recommendation field.
|
|
51
|
+
|
|
39
52
|
Return ONLY valid JSON, no other text:
|
|
40
|
-
{"verdict":"approve"|"warn"|"block","reason":"one sentence","concerns":["
|
|
53
|
+
{"verdict":"approve"|"warn"|"block","reason":"one sentence directly addressing the task","concerns":["specific legal concern"],"recommendation":"Prefer [named option] — reason specific to your domain"}`,
|
|
41
54
|
security: `You are the Security Engineer in a software council. Assess security implications using OWASP Top 10 and security best practices. Approve secure designs, warn about potential vulnerabilities, block anything that introduces clear security risks — injection, broken auth, sensitive data exposure, or insecure design.
|
|
42
55
|
|
|
56
|
+
IMPORTANT: If the task presents two specific options (e.g. "A vs B" or "should we X or Y"), your recommendation MUST explicitly state which option is more secure and why — do not give generic advice that applies to both. Name the more secure option in your recommendation field.
|
|
57
|
+
|
|
43
58
|
Return ONLY valid JSON, no other text:
|
|
44
|
-
{"verdict":"approve"|"warn"|"block","reason":"one sentence","concerns":["
|
|
59
|
+
{"verdict":"approve"|"warn"|"block","reason":"one sentence directly addressing the task","concerns":["specific vulnerability"],"recommendation":"Prefer [named option] — reason specific to your domain"}`,
|
|
45
60
|
};
|
|
46
61
|
const FALLBACKS = {
|
|
47
62
|
lead_dev: leadDevFallback,
|
|
@@ -85,10 +100,13 @@ function buildMemoryContext(task, project_dir) {
|
|
|
85
100
|
}
|
|
86
101
|
}
|
|
87
102
|
// ─── Core: one LLM sampling call per agent ────────────────────────────────────
|
|
88
|
-
async function callAgentLlm(server, agentKey, task, memoryContext) {
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
103
|
+
async function callAgentLlm(server, agentKey, task, memoryContext, decisionContext) {
|
|
104
|
+
const parts = [`Task to evaluate:\n${task}`];
|
|
105
|
+
if (decisionContext)
|
|
106
|
+
parts.push(`\nARCHITECTURAL CHOICE DETECTED:\n${decisionContext}\nYour response MUST address this specific choice — name the option you prefer in your recommendation.`);
|
|
107
|
+
if (memoryContext)
|
|
108
|
+
parts.push(`\nRelevant past council decisions:\n${memoryContext}`);
|
|
109
|
+
const userText = parts.join('\n');
|
|
92
110
|
try {
|
|
93
111
|
const result = await server.createMessage({
|
|
94
112
|
messages: [{ role: 'user', content: { type: 'text', text: userText } }],
|
|
@@ -109,15 +127,20 @@ export async function runLlmDebate(server, input) {
|
|
|
109
127
|
const enrichedContext = buildContextString(input.project_dir, input.context);
|
|
110
128
|
const fullText = enrichedContext ? `${input.task}\n\n${enrichedContext}` : input.task;
|
|
111
129
|
const memoryContext = buildMemoryContext(input.task, input.project_dir);
|
|
130
|
+
// Extract architectural choice if present — inject into every LLM call
|
|
131
|
+
const decision = extractDecision(input.task);
|
|
132
|
+
const decisionContext = decision.isDecisionTask
|
|
133
|
+
? `Option A: "${decision.optionA}" vs Option B: "${decision.optionB}"`
|
|
134
|
+
: undefined;
|
|
112
135
|
// All 7 agents run in parallel — each falls back individually on sampling failure
|
|
113
136
|
const [lead_dev, pm, architect, ux, devil, legal, security] = await Promise.all([
|
|
114
|
-
callAgentLlm(server, 'lead_dev', fullText, memoryContext),
|
|
115
|
-
callAgentLlm(server, 'pm', fullText, memoryContext),
|
|
116
|
-
callAgentLlm(server, 'architect', fullText, memoryContext),
|
|
117
|
-
callAgentLlm(server, 'ux', fullText, memoryContext),
|
|
118
|
-
callAgentLlm(server, 'devil', fullText, memoryContext),
|
|
119
|
-
callAgentLlm(server, 'legal', fullText, memoryContext),
|
|
120
|
-
callAgentLlm(server, 'security', fullText, memoryContext),
|
|
137
|
+
callAgentLlm(server, 'lead_dev', fullText, memoryContext, decisionContext),
|
|
138
|
+
callAgentLlm(server, 'pm', fullText, memoryContext, decisionContext),
|
|
139
|
+
callAgentLlm(server, 'architect', fullText, memoryContext, decisionContext),
|
|
140
|
+
callAgentLlm(server, 'ux', fullText, memoryContext, decisionContext),
|
|
141
|
+
callAgentLlm(server, 'devil', fullText, memoryContext, decisionContext),
|
|
142
|
+
callAgentLlm(server, 'legal', fullText, memoryContext, decisionContext),
|
|
143
|
+
callAgentLlm(server, 'security', fullText, memoryContext, decisionContext),
|
|
121
144
|
]);
|
|
122
145
|
const votes = { lead_dev, pm, architect, ux, devil, legal, security };
|
|
123
146
|
const { final_verdict, block_reasons, warnings, recommended } = decide(votes);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm-council.js","sourceRoot":"","sources":["../../src/council/llm-council.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,4EAA4E;AAC5E,iFAAiF;AAIjF,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"llm-council.js","sourceRoot":"","sources":["../../src/council/llm-council.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"product-manager.d.ts","sourceRoot":"","sources":["../../src/council/product-manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"product-manager.d.ts","sourceRoot":"","sources":["../../src/council/product-manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAmG5C,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAqD/C"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { extractDecision, pickSide, reframeVote } from './decision-extractor.js';
|
|
1
2
|
const BLOCK_RULES = [
|
|
2
3
|
{
|
|
3
4
|
pattern: /rewrite.{0,20}from.{0,10}scratch/i,
|
|
@@ -108,32 +109,51 @@ export function analyze(task) {
|
|
|
108
109
|
recommendations.push(rule.recommendation);
|
|
109
110
|
}
|
|
110
111
|
}
|
|
112
|
+
let vote;
|
|
111
113
|
if (blocks.length > 0) {
|
|
112
|
-
|
|
114
|
+
vote = {
|
|
113
115
|
verdict: 'block',
|
|
114
116
|
reason: blocks[0].reason,
|
|
115
117
|
concerns: blocks.slice(1).map(b => b.reason),
|
|
116
118
|
recommendation: blocks.map(b => b.recommendation).join(' | '),
|
|
117
119
|
};
|
|
118
120
|
}
|
|
119
|
-
if (concerns.length > 0) {
|
|
120
|
-
|
|
121
|
+
else if (concerns.length > 0) {
|
|
122
|
+
vote = {
|
|
121
123
|
verdict: 'warn',
|
|
122
124
|
reason: `${concerns.length} product risk${concerns.length > 1 ? 's' : ''} — scope or complexity concern.`,
|
|
123
125
|
concerns,
|
|
124
126
|
recommendation: recommendations[0],
|
|
125
127
|
};
|
|
126
128
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
129
|
+
else {
|
|
130
|
+
const matched = TOPIC_INSIGHTS.filter(t => t.pattern.test(task));
|
|
131
|
+
if (matched.length > 0) {
|
|
132
|
+
const top = matched.slice(0, 2);
|
|
133
|
+
vote = {
|
|
134
|
+
verdict: 'warn',
|
|
135
|
+
reason: top[0].concern,
|
|
136
|
+
concerns: top.slice(1).map(t => t.concern),
|
|
137
|
+
recommendation: top.map(t => t.recommendation).join(' | '),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
vote = { verdict: 'approve', reason: 'Reasonable scope. Ship it.', concerns: [] };
|
|
142
|
+
}
|
|
136
143
|
}
|
|
137
|
-
return
|
|
144
|
+
return applyDecisionStance(vote, task);
|
|
145
|
+
}
|
|
146
|
+
// PM risk: options that add scope, infrastructure, or delay time-to-value
|
|
147
|
+
const PM_RISK = /\b(http|express|rest.?api|api.?layer|new\s+(server|layer|transport)|oauth|auth.?system|bundl)\b/i;
|
|
148
|
+
function applyDecisionStance(vote, task) {
|
|
149
|
+
const ctx = extractDecision(task);
|
|
150
|
+
if (!ctx.isDecisionTask)
|
|
151
|
+
return vote;
|
|
152
|
+
const { optionA, optionB } = ctx;
|
|
153
|
+
const side = pickSide(optionA, optionB, PM_RISK);
|
|
154
|
+
const advice = side
|
|
155
|
+
? `"${side.preferred}" ships faster and has lower scope risk. Defer "${side.avoided}" until users explicitly request it and usage data justifies the investment.`
|
|
156
|
+
: `Evaluate which option delivers user value sooner. Ship the simpler path; add complexity only once real demand is confirmed.`;
|
|
157
|
+
return reframeVote(vote, ctx, side?.preferred ?? null, advice);
|
|
138
158
|
}
|
|
139
159
|
//# sourceMappingURL=product-manager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"product-manager.js","sourceRoot":"","sources":["../../src/council/product-manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"product-manager.js","sourceRoot":"","sources":["../../src/council/product-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../src/council/security.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../src/council/security.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAmI5C,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CA4F/C"}
|
package/dist/council/security.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { extractDecision, pickSide, reframeVote } from './decision-extractor.js';
|
|
1
2
|
const BLOCK_RULES = [
|
|
2
3
|
{
|
|
3
4
|
pattern: /(no.{0,25}rate.?limit|(auth|login|password|signin|otp|2fa|token|reset).{0,50}no.{0,20}rate.?limit|no.{0,25}rate.?limit.{0,50}(auth|login|password|signin|otp|2fa))/i,
|
|
@@ -141,22 +142,6 @@ export function analyze(task) {
|
|
|
141
142
|
recommendations.push(rule.recommendation);
|
|
142
143
|
}
|
|
143
144
|
}
|
|
144
|
-
if (blocks.length > 0) {
|
|
145
|
-
return {
|
|
146
|
-
verdict: 'block',
|
|
147
|
-
reason: blocks[0].reason,
|
|
148
|
-
concerns: blocks.slice(1).map(b => b.reason),
|
|
149
|
-
recommendation: blocks.map(b => b.recommendation).join(' | '),
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
if (concerns.length > 0) {
|
|
153
|
-
return {
|
|
154
|
-
verdict: 'warn',
|
|
155
|
-
reason: `${concerns.length} security concern${concerns.length > 1 ? 's' : ''} — threat model flagged issues.`,
|
|
156
|
-
concerns,
|
|
157
|
-
recommendation: recommendations[0],
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
145
|
// Topic-based security analysis for tasks with no specific pattern matches
|
|
161
146
|
const TOPIC_INSIGHTS = [
|
|
162
147
|
{
|
|
@@ -195,16 +180,51 @@ export function analyze(task) {
|
|
|
195
180
|
recommendation: 'For every new tool: define input validation, define maximum input size, consider what the worst-case malicious input looks like, and write a security note in the tool description.',
|
|
196
181
|
},
|
|
197
182
|
];
|
|
198
|
-
|
|
199
|
-
if (
|
|
200
|
-
|
|
201
|
-
|
|
183
|
+
let vote;
|
|
184
|
+
if (blocks.length > 0) {
|
|
185
|
+
vote = {
|
|
186
|
+
verdict: 'block',
|
|
187
|
+
reason: blocks[0].reason,
|
|
188
|
+
concerns: blocks.slice(1).map(b => b.reason),
|
|
189
|
+
recommendation: blocks.map(b => b.recommendation).join(' | '),
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
else if (concerns.length > 0) {
|
|
193
|
+
vote = {
|
|
202
194
|
verdict: 'warn',
|
|
203
|
-
reason:
|
|
204
|
-
concerns
|
|
205
|
-
recommendation:
|
|
195
|
+
reason: `${concerns.length} security concern${concerns.length > 1 ? 's' : ''} — threat model flagged issues.`,
|
|
196
|
+
concerns,
|
|
197
|
+
recommendation: recommendations[0],
|
|
206
198
|
};
|
|
207
199
|
}
|
|
208
|
-
|
|
200
|
+
else {
|
|
201
|
+
const topicMatched = TOPIC_INSIGHTS.filter(t => t.pattern.test(task));
|
|
202
|
+
if (topicMatched.length > 0) {
|
|
203
|
+
const top = topicMatched.slice(0, 2);
|
|
204
|
+
vote = {
|
|
205
|
+
verdict: 'warn',
|
|
206
|
+
reason: top[0].concern,
|
|
207
|
+
concerns: top.slice(1).map(t => t.concern),
|
|
208
|
+
recommendation: top.map(t => t.recommendation).join(' | '),
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
vote = { verdict: 'approve', reason: 'No security threats identified in threat model.', concerns: [] };
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return applyDecisionStance(vote, task);
|
|
216
|
+
}
|
|
217
|
+
// Security risk: options that expose the server to the network or add new untrusted input paths
|
|
218
|
+
const SEC_RISK = /\b(http|rest.?api|express|network|port|remote|transport|oauth|token.?endpoint|api.?key)\b/i;
|
|
219
|
+
function applyDecisionStance(vote, task) {
|
|
220
|
+
const ctx = extractDecision(task);
|
|
221
|
+
if (!ctx.isDecisionTask)
|
|
222
|
+
return vote;
|
|
223
|
+
const { optionA, optionB } = ctx;
|
|
224
|
+
const side = pickSide(optionA, optionB, SEC_RISK);
|
|
225
|
+
const advice = side
|
|
226
|
+
? `"${side.preferred}" keeps the threat model local-only. "${side.avoided}" changes Veto from a local tool to a network service — auth, TLS, rate-limiting, and input validation become mandatory from day one.`
|
|
227
|
+
: `Both options carry network exposure risk. Confirm: can this be done without opening a network port? If not, auth and TLS are non-negotiable.`;
|
|
228
|
+
return reframeVote(vote, ctx, side?.preferred ?? null, advice);
|
|
209
229
|
}
|
|
210
230
|
//# sourceMappingURL=security.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/council/security.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/council/security.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-architect.d.ts","sourceRoot":"","sources":["../../src/council/system-architect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"system-architect.d.ts","sourceRoot":"","sources":["../../src/council/system-architect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAsI5C,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAqD/C"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { extractDecision, pickSide, reframeVote } from './decision-extractor.js';
|
|
1
2
|
const BLOCK_RULES = [
|
|
2
3
|
{
|
|
3
4
|
pattern: /\bdrop\s+table\b/i,
|
|
@@ -143,32 +144,51 @@ export function analyze(task) {
|
|
|
143
144
|
recommendations.push(rule.recommendation);
|
|
144
145
|
}
|
|
145
146
|
}
|
|
147
|
+
let vote;
|
|
146
148
|
if (blocks.length > 0) {
|
|
147
|
-
|
|
149
|
+
vote = {
|
|
148
150
|
verdict: 'block',
|
|
149
151
|
reason: blocks[0].reason,
|
|
150
152
|
concerns: blocks.slice(1).map(b => b.reason),
|
|
151
153
|
recommendation: blocks.map(b => b.recommendation).join(' | '),
|
|
152
154
|
};
|
|
153
155
|
}
|
|
154
|
-
if (concerns.length > 0) {
|
|
155
|
-
|
|
156
|
+
else if (concerns.length > 0) {
|
|
157
|
+
vote = {
|
|
156
158
|
verdict: 'warn',
|
|
157
159
|
reason: `${concerns.length} structural concern${concerns.length > 1 ? 's' : ''} — review before building.`,
|
|
158
160
|
concerns,
|
|
159
161
|
recommendation: recommendations[0],
|
|
160
162
|
};
|
|
161
163
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
164
|
+
else {
|
|
165
|
+
const matched = TOPIC_INSIGHTS.filter(t => t.pattern.test(task));
|
|
166
|
+
if (matched.length > 0) {
|
|
167
|
+
const top = matched.slice(0, 2);
|
|
168
|
+
vote = {
|
|
169
|
+
verdict: 'warn',
|
|
170
|
+
reason: top[0].concern,
|
|
171
|
+
concerns: top.slice(1).map(t => t.concern),
|
|
172
|
+
recommendation: top.map(t => t.recommendation).join(' | '),
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
vote = { verdict: 'approve', reason: 'Architecture looks sound. No structural concerns identified.', concerns: [] };
|
|
177
|
+
}
|
|
171
178
|
}
|
|
172
|
-
return
|
|
179
|
+
return applyDecisionStance(vote, task);
|
|
180
|
+
}
|
|
181
|
+
// Architect risk: options that tighten coupling or introduce new architectural layers
|
|
182
|
+
const ARCH_RISK = /\b(bundl|integrat\s+into|embed|inline|http|express|new\s+(server|layer|transport|protocol)|microservice)\b/i;
|
|
183
|
+
function applyDecisionStance(vote, task) {
|
|
184
|
+
const ctx = extractDecision(task);
|
|
185
|
+
if (!ctx.isDecisionTask)
|
|
186
|
+
return vote;
|
|
187
|
+
const { optionA, optionB } = ctx;
|
|
188
|
+
const side = pickSide(optionA, optionB, ARCH_RISK);
|
|
189
|
+
const advice = side
|
|
190
|
+
? `"${side.preferred}" preserves separation of concerns and keeps the boundary clean. "${side.avoided}" creates coupling that is difficult to undo later — the caller now depends on implementation details.`
|
|
191
|
+
: `Evaluate which option maintains the cleaner boundary. Prefer the path that adds no new coupling between existing components.`;
|
|
192
|
+
return reframeVote(vote, ctx, side?.preferred ?? null, advice);
|
|
173
193
|
}
|
|
174
194
|
//# sourceMappingURL=system-architect.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-architect.js","sourceRoot":"","sources":["../../src/council/system-architect.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"system-architect.js","sourceRoot":"","sources":["../../src/council/system-architect.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ux-designer.d.ts","sourceRoot":"","sources":["../../src/council/ux-designer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"ux-designer.d.ts","sourceRoot":"","sources":["../../src/council/ux-designer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAsE5C,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAkG/C"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { extractDecision, pickSide, reframeVote } from './decision-extractor.js';
|
|
1
2
|
// Backend-only tasks: UX approves without friction
|
|
2
3
|
const BACKEND_ONLY = /\b(api|backend|server|database|db|query|schema|migration|auth.*middleware|jwt|oauth|cron|cli|script|worker|queue|cache|redis|sql|index|trigger|webhook)\b/i;
|
|
3
4
|
const FRONTEND_SIGNALS = /\b(ui|ux|form|button|modal|page|screen|component|view|layout|menu|nav|input|field|label|error.?message|loading|user.?interface|frontend|react|vue|svelte|html|css)\b/i;
|
|
@@ -65,14 +66,15 @@ export function analyze(task) {
|
|
|
65
66
|
if (TRIVIAL.test(task.trim())) {
|
|
66
67
|
return { verdict: 'approve', reason: 'Trivial change — no UX concerns.', concerns: [] };
|
|
67
68
|
}
|
|
68
|
-
// Pure backend tasks get a light pass
|
|
69
|
+
// Pure backend tasks get a light pass — but still apply decision stance
|
|
69
70
|
const isBackend = BACKEND_ONLY.test(task) && !FRONTEND_SIGNALS.test(task);
|
|
70
71
|
if (isBackend) {
|
|
71
|
-
|
|
72
|
+
const backendVote = {
|
|
72
73
|
verdict: 'approve',
|
|
73
74
|
reason: 'Backend task — no direct UX concerns. Ensure API errors surface clearly to users.',
|
|
74
75
|
concerns: [],
|
|
75
76
|
};
|
|
77
|
+
return applyDecisionStance(backendVote, task);
|
|
76
78
|
}
|
|
77
79
|
const blocks = [];
|
|
78
80
|
const concerns = [];
|
|
@@ -88,22 +90,6 @@ export function analyze(task) {
|
|
|
88
90
|
recommendations.push(rule.recommendation);
|
|
89
91
|
}
|
|
90
92
|
}
|
|
91
|
-
if (blocks.length > 0) {
|
|
92
|
-
return {
|
|
93
|
-
verdict: 'block',
|
|
94
|
-
reason: blocks[0].reason,
|
|
95
|
-
concerns: blocks.slice(1).map(b => b.reason),
|
|
96
|
-
recommendation: blocks.map(b => b.recommendation).join(' | '),
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
if (concerns.length > 0) {
|
|
100
|
-
return {
|
|
101
|
-
verdict: 'warn',
|
|
102
|
-
reason: `${concerns.length} UX concern${concerns.length > 1 ? 's' : ''} — real users will notice this.`,
|
|
103
|
-
concerns,
|
|
104
|
-
recommendation: recommendations[0],
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
93
|
// Topic-based UX analysis for tasks with no direct frontend signals
|
|
108
94
|
const TOPIC_INSIGHTS = [
|
|
109
95
|
{
|
|
@@ -137,16 +123,51 @@ export function analyze(task) {
|
|
|
137
123
|
recommendation: 'Show progress for any operation over 500ms. For long operations, stream partial results or show a "working..." status. Never leave the user in silence.',
|
|
138
124
|
},
|
|
139
125
|
];
|
|
140
|
-
|
|
141
|
-
if (
|
|
142
|
-
|
|
143
|
-
|
|
126
|
+
let vote;
|
|
127
|
+
if (blocks.length > 0) {
|
|
128
|
+
vote = {
|
|
129
|
+
verdict: 'block',
|
|
130
|
+
reason: blocks[0].reason,
|
|
131
|
+
concerns: blocks.slice(1).map(b => b.reason),
|
|
132
|
+
recommendation: blocks.map(b => b.recommendation).join(' | '),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
else if (concerns.length > 0) {
|
|
136
|
+
vote = {
|
|
144
137
|
verdict: 'warn',
|
|
145
|
-
reason:
|
|
146
|
-
concerns
|
|
147
|
-
recommendation:
|
|
138
|
+
reason: `${concerns.length} UX concern${concerns.length > 1 ? 's' : ''} — real users will notice this.`,
|
|
139
|
+
concerns,
|
|
140
|
+
recommendation: recommendations[0],
|
|
148
141
|
};
|
|
149
142
|
}
|
|
150
|
-
|
|
143
|
+
else {
|
|
144
|
+
const topicMatched = TOPIC_INSIGHTS.filter(t => t.pattern.test(task));
|
|
145
|
+
if (topicMatched.length > 0) {
|
|
146
|
+
const top = topicMatched.slice(0, 2);
|
|
147
|
+
vote = {
|
|
148
|
+
verdict: 'warn',
|
|
149
|
+
reason: top[0].concern,
|
|
150
|
+
concerns: top.slice(1).map(t => t.concern),
|
|
151
|
+
recommendation: top.map(t => t.recommendation).join(' | '),
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
vote = { verdict: 'approve', reason: 'UX looks solid. No user experience concerns identified.', concerns: [] };
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return applyDecisionStance(vote, task);
|
|
159
|
+
}
|
|
160
|
+
// UX risk: options that add setup friction, credentials, or configuration overhead
|
|
161
|
+
const UX_RISK = /\b(http|api.?key|auth|oauth|port|server\s+config|credentials|token|setup.{0,15}required|install.{0,15}extra)\b/i;
|
|
162
|
+
function applyDecisionStance(vote, task) {
|
|
163
|
+
const ctx = extractDecision(task);
|
|
164
|
+
if (!ctx.isDecisionTask)
|
|
165
|
+
return vote;
|
|
166
|
+
const { optionA, optionB } = ctx;
|
|
167
|
+
const side = pickSide(optionA, optionB, UX_RISK);
|
|
168
|
+
const advice = side
|
|
169
|
+
? `"${side.preferred}" keeps the developer experience simpler — no extra setup or credentials. "${side.avoided}" adds friction that will silently reduce adoption.`
|
|
170
|
+
: `Evaluate which option requires fewer steps for a first-time user. The shorter happy path wins on developer experience.`;
|
|
171
|
+
return reframeVote(vote, ctx, side?.preferred ?? null, advice);
|
|
151
172
|
}
|
|
152
173
|
//# sourceMappingURL=ux-designer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ux-designer.js","sourceRoot":"","sources":["../../src/council/ux-designer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ux-designer.js","sourceRoot":"","sources":["../../src/council/ux-designer.ts"],"names":[],"mappings":"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"}
|