@jigyasudham/veto 0.8.2 → 1.0.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.
Files changed (111) hide show
  1. package/README.md +209 -52
  2. package/dist/agents/executor.js +36 -3
  3. package/dist/cli.js +350 -51
  4. package/dist/context/reader.js +113 -0
  5. package/dist/council/index.js +3 -1
  6. package/dist/plugins/loader.js +49 -0
  7. package/dist/router/index.js +2 -2
  8. package/dist/router/learning-updater.js +45 -1
  9. package/dist/server.js +478 -14
  10. package/dist/watcher/index.js +77 -0
  11. package/dist/workflow/pipeline.js +64 -0
  12. package/package.json +12 -3
  13. package/.claude/settings.local.json +0 -9
  14. package/src/adapters/claude.ts +0 -70
  15. package/src/adapters/codex.ts +0 -71
  16. package/src/adapters/gemini.ts +0 -71
  17. package/src/adapters/index.ts +0 -217
  18. package/src/agents/development/api.ts +0 -120
  19. package/src/agents/development/backend.ts +0 -85
  20. package/src/agents/development/coder.ts +0 -213
  21. package/src/agents/development/database.ts +0 -83
  22. package/src/agents/development/debugger.ts +0 -238
  23. package/src/agents/development/devops.ts +0 -86
  24. package/src/agents/development/frontend.ts +0 -85
  25. package/src/agents/development/migration.ts +0 -144
  26. package/src/agents/development/performance.ts +0 -144
  27. package/src/agents/development/refactor.ts +0 -86
  28. package/src/agents/development/reviewer.ts +0 -268
  29. package/src/agents/development/tester.ts +0 -151
  30. package/src/agents/executor.ts +0 -158
  31. package/src/agents/memory/context-manager.ts +0 -171
  32. package/src/agents/memory/decision-logger.ts +0 -160
  33. package/src/agents/memory/knowledge-base.ts +0 -124
  34. package/src/agents/memory/pattern-learner.ts +0 -143
  35. package/src/agents/memory/project-mapper.ts +0 -118
  36. package/src/agents/quality/accessibility.ts +0 -99
  37. package/src/agents/quality/code-quality.ts +0 -115
  38. package/src/agents/quality/compatibility.ts +0 -58
  39. package/src/agents/quality/documentation.ts +0 -105
  40. package/src/agents/quality/error-handling.ts +0 -96
  41. package/src/agents/research/competitor-analyzer.ts +0 -45
  42. package/src/agents/research/cost-analyzer.ts +0 -54
  43. package/src/agents/research/estimator.ts +0 -60
  44. package/src/agents/research/ethics-bias.ts +0 -113
  45. package/src/agents/research/researcher.ts +0 -114
  46. package/src/agents/research/risk-assessor.ts +0 -63
  47. package/src/agents/research/tech-advisor.ts +0 -55
  48. package/src/agents/security/auth.ts +0 -287
  49. package/src/agents/security/dependency-audit.ts +0 -337
  50. package/src/agents/security/penetration.ts +0 -262
  51. package/src/agents/security/privacy.ts +0 -285
  52. package/src/agents/security/scanner.ts +0 -322
  53. package/src/agents/security/secrets.ts +0 -249
  54. package/src/agents/types.ts +0 -66
  55. package/src/agents/workflow/automation.ts +0 -59
  56. package/src/agents/workflow/file-manager.ts +0 -52
  57. package/src/agents/workflow/git-agent.ts +0 -55
  58. package/src/agents/workflow/reporter.ts +0 -51
  59. package/src/agents/workflow/search-agent.ts +0 -40
  60. package/src/agents/workflow/task-coordinator.ts +0 -41
  61. package/src/agents/workflow/task-planner.ts +0 -47
  62. package/src/cli.ts +0 -135
  63. package/src/council/decision-engine.ts +0 -171
  64. package/src/council/devil-advocate.ts +0 -116
  65. package/src/council/index.ts +0 -44
  66. package/src/council/lead-developer.ts +0 -118
  67. package/src/council/legal-compliance.ts +0 -152
  68. package/src/council/product-manager.ts +0 -102
  69. package/src/council/security.ts +0 -172
  70. package/src/council/system-architect.ts +0 -132
  71. package/src/council/types.ts +0 -33
  72. package/src/council/ux-designer.ts +0 -121
  73. package/src/memory/local.ts +0 -305
  74. package/src/memory/schema.ts +0 -174
  75. package/src/memory/sync.ts +0 -274
  76. package/src/router/complexity-scorer.ts +0 -96
  77. package/src/router/context-compressor.ts +0 -74
  78. package/src/router/index.ts +0 -60
  79. package/src/router/learning-updater.ts +0 -271
  80. package/src/router/model-selector.ts +0 -83
  81. package/src/router/rate-monitor.ts +0 -103
  82. package/src/server.ts +0 -1038
  83. package/src/skills/development/skill-api-design.ts +0 -329
  84. package/src/skills/development/skill-auth.ts +0 -271
  85. package/src/skills/development/skill-ci-cd.ts +0 -0
  86. package/src/skills/development/skill-crud.ts +0 -209
  87. package/src/skills/development/skill-db-schema.ts +0 -0
  88. package/src/skills/development/skill-docker.ts +0 -0
  89. package/src/skills/development/skill-env-setup.ts +0 -0
  90. package/src/skills/development/skill-scaffold.ts +0 -323
  91. package/src/skills/intelligence/skill-complexity-score.ts +0 -69
  92. package/src/skills/intelligence/skill-cost-track.ts +0 -39
  93. package/src/skills/intelligence/skill-learning-loop.ts +0 -69
  94. package/src/skills/intelligence/skill-pattern-detect.ts +0 -38
  95. package/src/skills/intelligence/skill-rate-watch.ts +0 -61
  96. package/src/skills/memory/skill-context-compress.ts +0 -98
  97. package/src/skills/memory/skill-cross-sync.ts +0 -104
  98. package/src/skills/memory/skill-decision-log.ts +0 -119
  99. package/src/skills/memory/skill-session-restore.ts +0 -59
  100. package/src/skills/memory/skill-session-save.ts +0 -94
  101. package/src/skills/quality/skill-accessibility.ts +0 -0
  102. package/src/skills/quality/skill-code-review.ts +0 -84
  103. package/src/skills/quality/skill-docs-gen.ts +0 -0
  104. package/src/skills/quality/skill-perf-audit.ts +0 -0
  105. package/src/skills/quality/skill-security-scan.ts +0 -91
  106. package/src/skills/quality/skill-test-suite.ts +0 -290
  107. package/src/skills/workflow/skill-deploy.ts +0 -0
  108. package/src/skills/workflow/skill-git-workflow.ts +0 -0
  109. package/src/skills/workflow/skill-rollback.ts +0 -0
  110. package/src/skills/workflow/skill-task-breakdown.ts +0 -0
  111. package/tsconfig.json +0 -20
@@ -1,158 +0,0 @@
1
- import { AgentTask, AgentResult, WorkerAgentType } from './types.js';
2
-
3
- // Development agents
4
- import * as coder from './development/coder.js';
5
- import * as reviewer from './development/reviewer.js';
6
- import * as tester from './development/tester.js';
7
- import * as debugger_ from './development/debugger.js';
8
- import * as refactor from './development/refactor.js';
9
- import * as database from './development/database.js';
10
- import * as api from './development/api.js';
11
- import * as frontend from './development/frontend.js';
12
- import * as backend from './development/backend.js';
13
- import * as devops from './development/devops.js';
14
- import * as performance from './development/performance.js';
15
- import * as migration from './development/migration.js';
16
-
17
- // Security agents
18
- import * as securityScanner from './security/scanner.js';
19
- import * as auth from './security/auth.js';
20
- import * as privacy from './security/privacy.js';
21
- import * as secrets from './security/secrets.js';
22
- import * as dependencyAudit from './security/dependency-audit.js';
23
- import * as penetration from './security/penetration.js';
24
-
25
- // Memory agents
26
- import * as contextManager from './memory/context-manager.js';
27
- import * as decisionLogger from './memory/decision-logger.js';
28
- import * as projectMapper from './memory/project-mapper.js';
29
- import * as patternLearner from './memory/pattern-learner.js';
30
- import * as knowledgeBase from './memory/knowledge-base.js';
31
-
32
- // Research agents
33
- import * as researcher from './research/researcher.js';
34
- import * as techAdvisor from './research/tech-advisor.js';
35
- import * as costAnalyzer from './research/cost-analyzer.js';
36
- import * as competitorAnalyzer from './research/competitor-analyzer.js';
37
- import * as riskAssessor from './research/risk-assessor.js';
38
- import * as estimator from './research/estimator.js';
39
- import * as ethicsBias from './research/ethics-bias.js';
40
-
41
- // Quality agents
42
- import * as codeQuality from './quality/code-quality.js';
43
- import * as documentation from './quality/documentation.js';
44
- import * as accessibility from './quality/accessibility.js';
45
- import * as compatibility from './quality/compatibility.js';
46
- import * as errorHandling from './quality/error-handling.js';
47
-
48
- // Workflow agents
49
- import * as taskPlanner from './workflow/task-planner.js';
50
- import * as taskCoordinator from './workflow/task-coordinator.js';
51
- import * as fileManager from './workflow/file-manager.js';
52
- import * as gitAgent from './workflow/git-agent.js';
53
- import * as searchAgent from './workflow/search-agent.js';
54
- import * as reporter from './workflow/reporter.js';
55
- import * as automation from './workflow/automation.js';
56
-
57
- // Agents that support analyze()
58
- const ANALYZE_CAPABLE: Set<WorkerAgentType> = new Set([
59
- 'reviewer',
60
- 'security-scanner',
61
- 'secrets',
62
- 'dependency-audit',
63
- 'code-quality',
64
- 'documentation',
65
- 'accessibility',
66
- 'error-handling',
67
- ]);
68
-
69
- type AgentModule = {
70
- plan: (task: string, context?: string) => import('./types.js').AgentPlan;
71
- analyze?: (code: string, context?: string) => import('./types.js').AgentAnalysis;
72
- };
73
-
74
- function resolveAgent(agentType: WorkerAgentType): AgentModule {
75
- switch (agentType) {
76
- case 'coder': return coder;
77
- case 'reviewer': return reviewer;
78
- case 'tester': return tester;
79
- case 'debugger': return debugger_;
80
- case 'refactor': return refactor;
81
- case 'database': return database;
82
- case 'api': return api;
83
- case 'frontend': return frontend;
84
- case 'backend': return backend;
85
- case 'devops': return devops;
86
- case 'performance': return performance;
87
- case 'migration': return migration;
88
- case 'security-scanner': return securityScanner;
89
- case 'auth': return auth;
90
- case 'privacy': return privacy;
91
- case 'secrets': return secrets;
92
- case 'dependency-audit': return dependencyAudit;
93
- case 'penetration': return penetration;
94
- case 'context-manager': return contextManager;
95
- case 'decision-logger': return decisionLogger;
96
- case 'project-mapper': return projectMapper;
97
- case 'pattern-learner': return patternLearner;
98
- case 'knowledge-base': return knowledgeBase;
99
- case 'researcher': return researcher;
100
- case 'tech-advisor': return techAdvisor;
101
- case 'cost-analyzer': return costAnalyzer;
102
- case 'competitor-analyzer': return competitorAnalyzer;
103
- case 'risk-assessor': return riskAssessor;
104
- case 'estimator': return estimator;
105
- case 'ethics-bias': return ethicsBias;
106
- case 'code-quality': return codeQuality;
107
- case 'documentation': return documentation;
108
- case 'accessibility': return accessibility;
109
- case 'compatibility': return compatibility;
110
- case 'error-handling': return errorHandling;
111
- case 'task-planner': return taskPlanner;
112
- case 'task-coordinator': return taskCoordinator;
113
- case 'file-manager': return fileManager;
114
- case 'git-agent': return gitAgent;
115
- case 'search-agent': return searchAgent;
116
- case 'reporter': return reporter;
117
- case 'automation': return automation;
118
- default:
119
- throw new Error(`Unknown agent type: ${agentType}`);
120
- }
121
- }
122
-
123
- export async function executeOne(task: AgentTask): Promise<AgentResult> {
124
- const start = Date.now();
125
- try {
126
- const agent = resolveAgent(task.agent);
127
- const useAnalyze = task.code !== undefined && ANALYZE_CAPABLE.has(task.agent);
128
-
129
- if (useAnalyze && agent.analyze) {
130
- const analysis = agent.analyze(task.code!, task.context);
131
- return {
132
- id: task.id,
133
- agent: task.agent,
134
- analysis,
135
- duration_ms: Date.now() - start,
136
- };
137
- } else {
138
- const plan = agent.plan(task.task, task.context);
139
- return {
140
- id: task.id,
141
- agent: task.agent,
142
- plan,
143
- duration_ms: Date.now() - start,
144
- };
145
- }
146
- } catch (err) {
147
- return {
148
- id: task.id,
149
- agent: task.agent,
150
- duration_ms: Date.now() - start,
151
- error: err instanceof Error ? err.message : String(err),
152
- };
153
- }
154
- }
155
-
156
- export async function executeParallel(tasks: AgentTask[]): Promise<AgentResult[]> {
157
- return Promise.all(tasks.map(task => executeOne(task)));
158
- }
@@ -1,171 +0,0 @@
1
- import { AgentPlan, WorkerAgentType } from '../types.js';
2
-
3
- type ContextCategory = 'session-start' | 'mid-task' | 'context-switch' | 'compression' | 'general';
4
-
5
- function detectCategory(task: string): ContextCategory {
6
- const t = task.toLowerCase();
7
- if (t.includes('start') || t.includes('begin') || t.includes('new session') || t.includes('initialize')) return 'session-start';
8
- if (t.includes('compress') || t.includes('trim') || t.includes('reduce') || t.includes('shrink') || t.includes('token')) return 'compression';
9
- if (t.includes('switch') || t.includes('handoff') || t.includes('transfer') || t.includes('gemini') || t.includes('codex')) return 'context-switch';
10
- if (t.includes('mid') || t.includes('checkpoint') || t.includes('save') || t.includes('continue')) return 'mid-task';
11
- return 'general';
12
- }
13
-
14
- const categoryApproach: Record<ContextCategory, string> = {
15
- 'session-start': 'Load prior session via veto_session_restore. Identify the active project, last completed task, and immediate next action. Build a compact working context — goals, constraints, key files, recent decisions. Discard old context that no longer applies.',
16
- 'mid-task': 'Snapshot current progress to context: completed subtasks, in-progress work, emerging blockers. Trim historical conversation that is no longer load-bearing. Keep all active decisions and constraints live. Evaluate whether token budget warrants a save-and-compress cycle.',
17
- 'context-switch': 'Serialize current context to a portable session snapshot. Include task state, file manifest, active decisions, and next action. Write to veto_session_save. Confirm the receiving platform can restore and resume without re-reading source files.',
18
- 'compression': 'Identify context tiers: critical (keep verbatim), summarisable (compress to 1–3 sentences), droppable (no longer relevant). Apply the router\'s context-compressor module. Target < 30% of original token count while preserving all active constraints and decisions.',
19
- 'general': 'Audit the current context window for relevance. Remove completed subtasks, resolved blockers, and superseded decisions. Elevate forward-looking content — pending work, live constraints, open questions. Summarise historical content to 1–2 sentences per topic.',
20
- };
21
-
22
- const categorySteps: Record<ContextCategory, string[]> = {
23
- 'session-start': [
24
- 'Call veto_sessions_list to find the most recent session for this project directory',
25
- 'Call veto_session_restore with the session ID to load prior context',
26
- 'Parse the restored task_state to identify completed, in-progress, and remaining work',
27
- 'Call veto_memory_search with the project_dir to load relevant knowledge base entries',
28
- 'Call veto_project_map_get to load the current codebase structure',
29
- 'Synthesise a compact active-context object: goals, constraints, key files, decisions',
30
- 'Identify the single most important next action and make it the session focus',
31
- 'Discard any context older than the last significant decision or file change',
32
- ],
33
- 'mid-task': [
34
- 'List what has been completed since the last save',
35
- 'Identify what is currently in progress and what is blocked',
36
- 'Score each context item: critical | summarisable | droppable',
37
- 'Draft a compressed context string using summarisable items',
38
- 'Trigger a session save if token count exceeds 8,000 or a subtask just completed',
39
- 'Record any new decisions or discoveries to veto_memory_store',
40
- 'Update the project map if new files were created or deleted',
41
- 'Verify the next action is concrete and unambiguous',
42
- ],
43
- 'context-switch': [
44
- 'Freeze the current session: write final progress state',
45
- 'Call veto_session_save with full task_state including phase, progress, decisions',
46
- 'Note the session ID — give it to the human to paste into the receiving platform',
47
- 'Confirm the session summary is self-contained (receiving agent needs no prior context)',
48
- 'Include the file manifest for files that were read or modified this session',
49
- 'Include the single next action as the last line of the context',
50
- 'Verify the save by calling veto_sessions_list and inspecting the new row',
51
- ],
52
- 'compression': [
53
- 'Count current context tokens using the router\'s compressor estimate',
54
- 'Identify the compression target: what percentage reduction is needed?',
55
- 'Categorise each context block: verbatim | summarise | drop',
56
- 'Keep all active constraints, open blockers, and pending tasks verbatim',
57
- 'Summarise historical completed work to one sentence per subtask',
58
- 'Drop resolved blockers, superseded decisions, and read-back confirmations',
59
- 'Verify compressed context passes a completeness check: can the task still be continued?',
60
- 'Save the compressed state as a new session checkpoint',
61
- ],
62
- 'general': [
63
- 'Audit the context for items that are no longer relevant to the current task phase',
64
- 'Identify decisions that have been superseded and mark them deprecated',
65
- 'Summarise completed subtask history into single-sentence progress notes',
66
- 'Elevate forward-looking items to the top of the active context',
67
- 'Ensure all active file paths and module names are accurate (not stale)',
68
- 'Record new patterns or solutions to the knowledge base',
69
- 'Save the refined context as a session checkpoint',
70
- ],
71
- };
72
-
73
- const categoryChecklist: Record<ContextCategory, string[]> = {
74
- 'session-start': [
75
- '[ ] Prior session restored via veto_session_restore',
76
- '[ ] Task phase identified: planning | implementing | reviewing | blocked',
77
- '[ ] Completed subtasks listed — no re-doing finished work',
78
- '[ ] Remaining subtasks listed in priority order',
79
- '[ ] All active file paths verified to exist',
80
- '[ ] Active constraints and decisions loaded from session',
81
- '[ ] Knowledge base queried for relevant prior solutions',
82
- '[ ] Project map loaded — key modules and entry points known',
83
- '[ ] Next action is a single concrete step, not a vague direction',
84
- ],
85
- 'mid-task': [
86
- '[ ] Progress snapshot written: completed, in-progress, remaining',
87
- '[ ] New decisions or discoveries logged to knowledge base',
88
- '[ ] Stale context removed — no completed blockers still listed as active',
89
- '[ ] Session saved if checkpoint warranted (> 8k tokens or subtask complete)',
90
- '[ ] Project map updated if files were added or removed',
91
- '[ ] Next action re-confirmed: single concrete step',
92
- ],
93
- 'context-switch': [
94
- '[ ] Session saved with full task_state before switching platforms',
95
- '[ ] Session ID recorded and ready to give to receiving platform',
96
- '[ ] Summary is self-contained — receiving agent needs no prior context',
97
- '[ ] File manifest included in session save',
98
- '[ ] Next action is the final line of the context',
99
- '[ ] Receiving platform tested with veto_session_restore before committing to switch',
100
- ],
101
- 'compression': [
102
- '[ ] Original token count measured before compression',
103
- '[ ] Compression target set (aim for < 30% of original)',
104
- '[ ] All active constraints preserved verbatim',
105
- '[ ] Completed work compressed to one sentence per subtask',
106
- '[ ] No active blockers or decisions removed',
107
- '[ ] Compressed context passes completeness check',
108
- '[ ] Compressed state saved as new session checkpoint',
109
- ],
110
- 'general': [
111
- '[ ] Context audit completed — stale items removed',
112
- '[ ] All file paths verified to be current',
113
- '[ ] Decisions table up to date — no deprecated decisions still marked accepted',
114
- '[ ] Knowledge base updated with new findings',
115
- '[ ] Session saved with current state',
116
- '[ ] Next action is concrete and prioritised',
117
- ],
118
- };
119
-
120
- const categoryPitfalls: Record<ContextCategory, string[]> = {
121
- 'session-start': [
122
- 'Starting work before restoring prior session — redoing completed subtasks',
123
- 'Loading the session but ignoring the task_state — treating the session as read-only',
124
- 'Not checking the project map — assuming file structure from memory instead of current state',
125
- 'Taking the next action from the prior session without checking if it is still valid',
126
- ],
127
- 'mid-task': [
128
- 'Waiting until 50k tokens to compress — forces an emergency compression that risks losing context',
129
- 'Saving a session without a nextAction — the restoring agent starts from scratch',
130
- 'Not recording decisions to the knowledge base — the same decision gets relitigated next session',
131
- 'Updating the project map only on session end — missing interim file creates/deletes',
132
- ],
133
- 'context-switch': [
134
- 'Switching platforms without calling veto_session_save first — all progress lost',
135
- 'Including raw file contents in the session save instead of file paths — balloons token cost',
136
- 'Not testing restore on the receiving platform before committing to the switch',
137
- 'Switching while a destructive operation (migration, deploy) is in progress',
138
- ],
139
- 'compression': [
140
- 'Compressing active constraints as if they were completed work — causes silent constraint violations',
141
- 'Over-compressing: removing the rationale for active decisions — future agent reverses them',
142
- 'Not saving the compressed context — compression is lost at next context switch',
143
- 'Targeting a fixed token number without checking completeness — may cut load-bearing context',
144
- ],
145
- 'general': [
146
- 'Context drift: the active context describes a different version of the task than the current one',
147
- 'Stale file paths in context that no longer exist in the project',
148
- 'Decisions still listed as "proposed" that have already been implemented',
149
- 'Context growing monotonically without pruning — each session inherits all prior context',
150
- ],
151
- };
152
-
153
- export function plan(task: string, context?: string): AgentPlan {
154
- const category = detectCategory(task + ' ' + (context ?? ''));
155
- return {
156
- agent: 'context-manager' as WorkerAgentType,
157
- task,
158
- tier: 1,
159
- approach: categoryApproach[category],
160
- steps: categorySteps[category],
161
- checklist: categoryChecklist[category],
162
- pitfalls: categoryPitfalls[category],
163
- patterns: [
164
- 'Checkpoint pattern: save context at phase boundaries, not only at session end',
165
- 'Minimal viable context: enough to resume work, not a full transcript',
166
- 'Tiered retention: verbatim | summarised | dropped — never binary keep/delete',
167
- 'Forward-first ordering: next actions at the top, completed history at the bottom',
168
- ],
169
- duration_estimate: '5-15 minutes',
170
- };
171
- }
@@ -1,160 +0,0 @@
1
- import { AgentPlan, WorkerAgentType } from '../types.js';
2
-
3
- type DecisionCategory = 'architecture' | 'security' | 'data' | 'api' | 'general';
4
-
5
- function detectCategory(task: string): DecisionCategory {
6
- const t = task.toLowerCase();
7
- if (t.includes('architect') || t.includes('design') || t.includes('structure') || t.includes('pattern') || t.includes('framework')) return 'architecture';
8
- if (t.includes('auth') || t.includes('security') || t.includes('encrypt') || t.includes('permission') || t.includes('token')) return 'security';
9
- if (t.includes('schema') || t.includes('database') || t.includes('migration') || t.includes('model') || t.includes('table')) return 'data';
10
- if (t.includes('api') || t.includes('endpoint') || t.includes('contract') || t.includes('version') || t.includes('rest') || t.includes('graphql')) return 'api';
11
- return 'general';
12
- }
13
-
14
- const categoryApproach: Record<DecisionCategory, string> = {
15
- 'architecture': 'Document the architectural decision as an ADR. Capture context (what forces are in play), the decision made, full rationale, rejected alternatives with reasons, and positive/negative consequences. Store in veto_memory_store with type="decision". Link from code comments using the ADR ID.',
16
- 'security': 'Log the security decision with threat model context. State the attack surface being protected, the chosen control, why alternatives were rejected (too weak, too complex, operational burden), and any residual risk accepted. Tag with "security" for fast retrieval during reviews.',
17
- 'data': 'Record the data schema decision with migration path. Document the constraints that drove the schema choice (access patterns, cardinality, denormalisation trade-offs). Include the rollback plan if the decision proves wrong. Tag with "schema" and affected table names.',
18
- 'api': 'Log the API contract decision including versioning strategy. Capture backward-compatibility commitments, breaking-change triggers, and the client impact. Once an API contract is published, record it as immutable unless a version bump is logged.',
19
- 'general': 'Use the ADR format: context → decision → rationale → alternatives → consequences. Log to veto_memory_store (type="decision") and the local decisions table. Reference the ADR ID in code comments near the implementation.',
20
- };
21
-
22
- const categorySteps: Record<DecisionCategory, string[]> = {
23
- 'architecture': [
24
- 'Assign a sequential ADR ID (ADR-001, ADR-002, …)',
25
- 'Write the context: what forces, constraints, or requirements make this choice necessary?',
26
- 'State the decision in one unambiguous sentence',
27
- 'Document the rationale: why this option over alternatives?',
28
- 'List at least two alternatives that were genuinely considered',
29
- 'For each alternative: pros, cons, and the specific reason it was rejected',
30
- 'Document positive consequences: what does this decision enable?',
31
- 'Document negative consequences: what technical debt or constraints does it introduce?',
32
- 'Set status: proposed | accepted | deprecated | superseded-by:ADR-xxx',
33
- 'Add file references to the implementation',
34
- 'Call veto_memory_store with type="decision", title=ADR ID, tags=["architecture"]',
35
- 'Add // See ADR-001 comment near the implementation',
36
- ],
37
- 'security': [
38
- 'Describe the threat being mitigated (attack vector, affected asset, likelihood)',
39
- 'State the chosen security control in one sentence',
40
- 'Document why weaker alternatives were rejected (OWASP reference where applicable)',
41
- 'Document why stronger alternatives were not chosen (operational burden, complexity, cost)',
42
- 'Quantify residual risk: what attack surface remains after this control?',
43
- 'Reference relevant standards: OWASP, NIST, RFC',
44
- 'Set a review date — security decisions should be re-evaluated annually',
45
- 'Call veto_memory_store with type="decision", tags=["security", threat category]',
46
- 'Add SECURITY-DECISION comment near the implementation with a reference link',
47
- ],
48
- 'data': [
49
- 'Describe the access patterns this schema must support',
50
- 'State the chosen schema structure (table names, key columns, relationships)',
51
- 'Document denormalisation choices: what query performance trade-off justifies them?',
52
- 'Document normalisation choices: what integrity benefit justifies the join cost?',
53
- 'Write the migration plan: how to move existing data to the new schema?',
54
- 'Write the rollback plan: how to revert if the schema proves wrong?',
55
- 'Note index strategy: which columns need indexes and why?',
56
- 'Call veto_memory_store with type="decision", tags=["schema", table name]',
57
- 'Record the decision_id in the migration file comment',
58
- ],
59
- 'api': [
60
- 'Define the API contract: method, path, request shape, response shape',
61
- 'State the versioning strategy: URL path (/v1/), header, or content negotiation',
62
- 'Document backward-compatibility commitments for this version',
63
- 'List fields that must never be removed or renamed without a version bump',
64
- 'Define breaking-change criteria: what requires a new major version?',
65
- 'Document deprecation timeline if replacing an existing endpoint',
66
- 'Reference the OpenAPI spec file path',
67
- 'Call veto_memory_store with type="decision", tags=["api-contract", endpoint path]',
68
- 'Add OpenAPI operation ID that matches the decision ID for traceability',
69
- ],
70
- 'general': [
71
- 'Assign an ADR ID if this is a durable architectural decision',
72
- 'Write the context: what problem or constraint is being addressed?',
73
- 'State the decision clearly in one sentence',
74
- 'Document the rationale with at least two sentences of "why"',
75
- 'List alternatives that were considered and rejected',
76
- 'Identify the primary consequence: what does this decision make easier and harder?',
77
- 'Call veto_memory_store with type="decision", title, and relevant tags',
78
- 'If the decision affects code, add a reference comment near the implementation',
79
- 'Set a review trigger: what event should prompt re-evaluating this decision?',
80
- ],
81
- };
82
-
83
- const categoryChecklist: Record<DecisionCategory, string[]> = {
84
- 'architecture': [
85
- '[ ] ADR ID assigned sequentially',
86
- '[ ] Context section explains forces in play, not just the problem statement',
87
- '[ ] Decision stated in one clear sentence',
88
- '[ ] Rationale answers "why this over alternatives"',
89
- '[ ] At least two alternatives documented with rejection reason',
90
- '[ ] Positive consequences listed',
91
- '[ ] Negative consequences / technical debt acknowledged',
92
- '[ ] Status set to "accepted"',
93
- '[ ] Stored in veto_memory_store with type="decision"',
94
- '[ ] Code comment added: // See ADR-xxx',
95
- ],
96
- 'security': [
97
- '[ ] Threat clearly described: vector, asset, likelihood',
98
- '[ ] Chosen control stated',
99
- '[ ] Weaker alternatives rejected with reason',
100
- '[ ] Residual risk quantified',
101
- '[ ] OWASP or NIST reference included where applicable',
102
- '[ ] Review date set',
103
- '[ ] Stored with tags=["security"]',
104
- ],
105
- 'data': [
106
- '[ ] Access patterns documented before schema choice',
107
- '[ ] Schema decision stated with table/column names',
108
- '[ ] Migration plan included',
109
- '[ ] Rollback plan included',
110
- '[ ] Index strategy documented',
111
- '[ ] Stored with tags=["schema", table name]',
112
- '[ ] Migration file references the decision ID',
113
- ],
114
- 'api': [
115
- '[ ] Endpoint contract fully specified',
116
- '[ ] Versioning strategy stated',
117
- '[ ] Backward-compatibility commitments listed',
118
- '[ ] Breaking-change criteria defined',
119
- '[ ] Deprecation plan if replacing existing endpoint',
120
- '[ ] OpenAPI spec path referenced',
121
- '[ ] Stored with tags=["api-contract"]',
122
- ],
123
- 'general': [
124
- '[ ] Decision stated in one clear sentence',
125
- '[ ] Rationale documented',
126
- '[ ] Alternatives listed with rejection reasons',
127
- '[ ] Primary consequence identified',
128
- '[ ] Stored in veto_memory_store',
129
- '[ ] Code comment added if decision affects implementation',
130
- '[ ] Review trigger identified',
131
- ],
132
- };
133
-
134
- export function plan(task: string, context?: string): AgentPlan {
135
- const category = detectCategory(task + ' ' + (context ?? ''));
136
- return {
137
- agent: 'decision-logger' as WorkerAgentType,
138
- task,
139
- tier: 1,
140
- approach: categoryApproach[category],
141
- steps: categorySteps[category],
142
- checklist: categoryChecklist[category],
143
- pitfalls: [
144
- 'Logging the decision after the fact with hindsight bias — capture original thinking at decision time',
145
- 'Writing the "what" without the "why" — future engineers see the choice but not the reasoning',
146
- 'Only logging the chosen option without alternatives — looks like no deliberation happened',
147
- 'Forgetting to update the status when a decision is superseded — stale "accepted" entries cause confusion',
148
- 'Using vague titles like "Auth decision" instead of "Use JWT with rotating refresh tokens"',
149
- 'Not linking the ADR from the implementation — the decision and code drift apart',
150
- 'Logging trivial decisions (variable names) — reserve the log for non-obvious, hard-to-reverse choices',
151
- ],
152
- patterns: [
153
- 'ADR (Architecture Decision Record): context → decision → rationale → alternatives → consequences',
154
- 'Decision-in-context: co-locate decision reference with implementation via code comments',
155
- 'Living document: update status (deprecated / superseded-by) rather than deleting entries',
156
- 'Decision chain: reference prior ADRs that this decision builds on or overrides',
157
- ],
158
- duration_estimate: '15-30 minutes',
159
- };
160
- }
@@ -1,124 +0,0 @@
1
- import { AgentPlan, WorkerAgentType } from '../types.js';
2
-
3
- type KBCategory = 'store-solution' | 'search' | 'dedup' | 'general';
4
-
5
- function detectCategory(task: string): KBCategory {
6
- const t = task.toLowerCase();
7
- if (t.includes('store') || t.includes('save') || t.includes('record') || t.includes('add to') || t.includes('log solution')) return 'store-solution';
8
- if (t.includes('find') || t.includes('search') || t.includes('retrieve') || t.includes('look up') || t.includes('query')) return 'search';
9
- if (t.includes('dedup') || t.includes('duplicate') || t.includes('clean') || t.includes('merge')) return 'dedup';
10
- return 'general';
11
- }
12
-
13
- const categoryApproach: Record<KBCategory, string> = {
14
- 'store-solution': 'Before storing, check for a similar existing entry via veto_memory_search to avoid duplicates. If found, update the existing entry. If new, store via veto_memory_store with a precise title, type classification (solution/pattern/error/reference), relevant tags, and the project_dir for scoped retrieval. A good knowledge entry is self-contained: a future agent should understand and apply it without the original context.',
15
- 'search': 'Query the knowledge base via veto_memory_search before starting any task. Use type filters and tags to narrow results. Combine a keyword query with the project_dir filter for project-scoped results. Search for prior errors before debugging — the same error may already be solved. Search for patterns before writing code — the established style may already be documented.',
16
- 'dedup': 'Search for entries with similar titles using multiple keyword variants. Group semantically similar entries. Merge by: keeping the entry with higher relevance, combining the content, and deleting the duplicate. Update the merged entry\'s tags to include all tags from both entries.',
17
- 'general': 'Check the knowledge base at the start of every task (veto_memory_search). Store new solutions, discovered patterns, and resolved errors after every task. Keep entries self-contained and searchable. Prune stale entries that no longer apply to the current codebase version.',
18
- };
19
-
20
- const categorySteps: Record<KBCategory, string[]> = {
21
- 'store-solution': [
22
- 'Identify what type this entry is: solution | pattern | error | reference | decision | context',
23
- 'Write a precise, searchable title (not "Fixed the bug" — use "Fix: Node 22 sqlite binding fails on Windows without --experimental-sqlite flag")',
24
- 'Write content that is self-contained: problem statement → root cause → solution steps → outcome',
25
- 'Choose 3–5 tags that describe the topic, technology, and error category',
26
- 'Set project_dir if this is project-specific knowledge (not general programming knowledge)',
27
- 'Search veto_memory_search for similar entries before storing',
28
- 'If a similar entry exists: update it, do not create a duplicate',
29
- 'If new: call veto_memory_store with all fields populated',
30
- 'Confirm storage by searching for the entry by title',
31
- ],
32
- 'search': [
33
- 'Identify the key terms of what you are searching for',
34
- 'Call veto_memory_search with query=key terms, type filter if known',
35
- 'If results are empty: try synonyms or broader terms',
36
- 'Add project_dir filter for project-specific knowledge',
37
- 'Read the top 3 results — check relevance and recency',
38
- 'If an old result has been superseded by a newer approach, mark the old entry for deletion',
39
- 'Apply the found solution or pattern directly if the context matches',
40
- 'If the context is different from the stored entry, adapt the solution and update the entry with the new context',
41
- ],
42
- 'dedup': [
43
- 'Search for entries with the same title or very similar titles',
44
- 'Search for entries with the same tags to find topic overlap',
45
- 'Group semantically similar entries',
46
- 'For each duplicate group: identify the most complete and accurate entry to keep',
47
- 'Merge content: combine unique information from all entries into the survivor',
48
- 'Merge tags: union of all tags across the group',
49
- 'Set the survivor\'s relevance to the maximum of the group',
50
- 'Delete duplicate entries via veto_memory_search (note IDs) + internal delete',
51
- 'Confirm dedup by re-running the search — only one entry should appear per topic',
52
- ],
53
- 'general': [
54
- 'At session start: call veto_memory_search with the current task description',
55
- 'Review results for prior solutions, patterns, or errors that apply to this task',
56
- 'During the task: note any new solutions, patterns, or errors discovered',
57
- 'At session end: store all new knowledge via veto_memory_store',
58
- 'Check for duplicates before each store',
59
- 'Periodically review low-relevance entries and delete stale ones',
60
- 'Keep the knowledge base scoped: use project_dir for project-specific entries',
61
- ],
62
- };
63
-
64
- const categoryChecklist: Record<KBCategory, string[]> = {
65
- 'store-solution': [
66
- '[ ] Type classification chosen: solution | pattern | error | reference | decision | context',
67
- '[ ] Title is precise and searchable — not vague',
68
- '[ ] Content is self-contained (problem → root cause → solution)',
69
- '[ ] At least 3 tags chosen',
70
- '[ ] project_dir set if project-specific',
71
- '[ ] Duplicate search performed before storing',
72
- '[ ] Entry confirmed via follow-up search',
73
- ],
74
- 'search': [
75
- '[ ] Knowledge base queried before starting the task',
76
- '[ ] Synonyms tried if initial query returns empty results',
77
- '[ ] Top 3 results evaluated for relevance',
78
- '[ ] Stale results flagged for deletion',
79
- '[ ] Found solution adapted to current context if needed',
80
- ],
81
- 'dedup': [
82
- '[ ] Title-based and tag-based search performed',
83
- '[ ] Duplicate groups identified',
84
- '[ ] Best entry per group selected',
85
- '[ ] Content merged',
86
- '[ ] Tags merged',
87
- '[ ] Duplicates deleted',
88
- '[ ] Dedup confirmed by re-search',
89
- ],
90
- 'general': [
91
- '[ ] Knowledge base searched at session start',
92
- '[ ] New knowledge stored at session end',
93
- '[ ] No duplicates created',
94
- '[ ] Stale entries reviewed',
95
- ],
96
- };
97
-
98
- export function plan(task: string, context?: string): AgentPlan {
99
- const category = detectCategory(task + ' ' + (context ?? ''));
100
- return {
101
- agent: 'knowledge-base' as WorkerAgentType,
102
- task,
103
- tier: 1,
104
- approach: categoryApproach[category],
105
- steps: categorySteps[category],
106
- checklist: categoryChecklist[category],
107
- pitfalls: [
108
- 'Storing entries with vague titles — "Fixed bug" is not searchable; "Fix: X fails when Y" is',
109
- 'Creating duplicate entries — always search before storing',
110
- 'Storing entries without tags — makes retrieval rely entirely on full-text search',
111
- 'Storing project-specific knowledge without project_dir — it bleeds into unrelated projects',
112
- 'Not searching the knowledge base before starting a task — solving the same problem twice',
113
- 'Keeping stale entries after the codebase has moved on — old solutions become misleading',
114
- 'Storing too much: copying entire file contents instead of the key insight',
115
- ],
116
- patterns: [
117
- 'Search-first: always query the knowledge base before solving a problem from scratch',
118
- 'Self-contained entries: each entry stands alone — future agent needs no original context',
119
- 'Type-and-tag taxonomy: type (solution/pattern/error/reference/decision) + tags enables faceted retrieval',
120
- 'Dedup-on-write: search for duplicates before every store operation',
121
- ],
122
- duration_estimate: '5-15 minutes',
123
- };
124
- }