Backend (Spring Boot 3.2 / Java 21 / PostgreSQL): - JWT auth with BCrypt password hashing - User profile + Mifflin-St Jeor BMR calculator - Food search + barcode via OpenFoodFacts API with local cache - Meal CRUD with user data isolation and ownership checks - AI photo analysis (OpenAI Vision) with confidence intervals - AI correction feedback loop for personalisation - Flyway DB migrations + RFC-7807 error responses Mobile (React Native / TypeScript): - Full navigation stack (Auth → Tabs → Home stack) - Design tokens (WCAG 2.2 AA colours, 8px grid, 48px touch targets) - 10 screens: Login, Register, Home, Search, Camera, AI Result, Edit Meal, Daily Details, History, Profile - Confidence-aware calorie display (kcal ± range) - Repeat last meal shortcut + macro tracking Docs: - docs/PLAN-AND-REQUIREMENTS.md - docs/traceability.csv (35 requirements, all Implemented)
17 KiB
Three layers enforce governance: Agent (behavior), MCP (validation), Extension (interception). All use stdio transport.
Integration Patterns - Virsaitis Layers
Module: Integration Patterns Load: When working across multiple components Version: 3.0.0 Updated: 2026-02-17
🎯 Purpose
Defines integration patterns between Agent, MCP, Extension, and Skills layers for seamless governance enforcement.
🤖 Machine Policy
[INTEGRATION_ARCHITECTURE]
LAYER_1=agent (behavioral guidance)
LAYER_2=mcp_server (validation enforcement)
LAYER_3=extension (user action interception)
LAYER_4=skills (domain-specific rules)
[COMMUNICATION_PATTERNS]
AGENT_TO_MCP=tool_calls
MCP_TO_EXTENSION=stdio
AGENT_TO_SKILLS=progressive_disclosure
EXTENSION_TO_MCP=validation_requests
[PRECEDENCE]
TIER_0_SOURCE=agent_md (authoritative)
TECHNICAL_ENFORCEMENT=mcp + extension
DOMAIN_RULES=skills
🏗️ Three-Layer Architecture
Overview
┌─────────────────────────────────────┐
│ Layer 1: Agent (Atomic Markdown) │ ← AI Self-Regulation
│ .github/agents/Virsaitis.agent.md │
└──────────────┬──────────────────────┘
│ References/Delegates
↓
┌─────────────────────────────────────┐
│ Layer 4: Skills (Native VS Code) │ ← Domain-Specific Rules
│ .github/skills/*/SKILL.md │
└──────────────┬──────────────────────┘
│ Calls MCP Tools
↓
┌─────────────────────────────────────┐
│ Layer 2: MCP Server (TypeScript) │ ← Validation Enforcement
│ virsaitis-mcp/ │
└──────────────┬──────────────────────┘
│ Provides Results
↑
│ Queries for Validation
┌──────────────┴──────────────────────┐
│ Layer 3: Extension (TypeScript) │ ← User Action Interception
│ virsaitis-extension/ │
└─────────────────────────────────────┘
🔗 Agent ↔ Skills Integration
Agent References Skills
Agent.md pattern:
## File Operation Guidelines
For domain-specific file operations, activate relevant skills:
- Python files: Activate python-development skill
- Security review: Activate security-controls skill
- Requirements: Activate requirements-engineering skill
Skills provide detailed procedures and validation commands.
Agent provides TIER-0 enforcement rules.
Skills defer to Agent for conflicts.
Skills Reference Agent
SKILL.md pattern:
---
name: python-development
description: Python coding standards and file creation workflow
metadata:
tier: TIER-1
---
## TIER-0 Rules (Enforced by Agent)
This skill operates under Agent.md TIER-0 rules:
- Never use `create_file` for .py files (Agent TIER-0.3)
- Never commit secrets (Agent TIER-0.3)
- Use MCP tools for governance operations (Agent TIER-0.4)
**Precedence**: Agent.md TIER-0 > Skill TIER-1 rules
## TIER-1 Rules (Skill-Specific)
- 4-space indentation (PEP 8)
- UTF-8 encoding without BOM
- Black formatter required
Progressive Disclosure
VS Code loads in 3 levels:
LEVEL 1: Metadata (~100 tokens, always loaded):
---
name: python-development
description: Python coding standards including 4-space indentation...
---
LEVEL 2: Instructions (<5000 tokens, on activation):
## Standards & Rules
[Full detailed rules]
## Procedures
[Step-by-step workflows]
LEVEL 3: Resources (on-demand):
.github/skills/python-development/
├── SKILL.md (loaded on activation)
├── scripts/ (loaded when referenced)
│ └── validate-python.sh
└── references/ (loaded when referenced)
└── pep8-full-spec.md
🔌 Agent/Skills → MCP Integration
Agent/Skills Call MCP Tools
FROM AGENT.MD:
Before editing protected file:
1. Call `mcp_virsaitis_validate_operation` tool
2. Pass operation type and file path
3. Tool returns validation result
4. If not allowed, respond with TIER-0 VIOLATION PREVENTED
5. If allowed, proceed with operation
FROM SKILL.MD:
### Validate File Operation Procedure
1. Call MCP tool:
mcp_virsaitis_validate_operation({ operation: "write", filePath: "/path/to/file.py" })
2. Check response:
- If `allowed: false` → STOP, show consequences
- If `allowed: true` → PROCEED with operation
3. Log operation in audit trail
MCP Tool Interface
TOOL SCHEMA:
{
name: 'mcp_virsaitis_validate_operation',
description: 'Validates if an operation is allowed by governance policy',
inputSchema: {
type: 'object',
properties: {
operation: {
type: 'string',
enum: ['read', 'write', 'delete', 'execute'],
description: 'Operation type',
},
filePath: {
type: 'string',
description: 'Absolute file path',
},
},
required: ['operation', 'filePath'],
},
}
TOOL RESPONSE:
⚡ CHECKPOINT — All layer communication uses stdio transport. No HTTP REST between extension and MCP.
interface ValidationResponse {
allowed: boolean;
tier?: 'TIER-0' | 'TIER-1' | 'TIER-2' | 'TIER-3';
reason?: string;
consequences?: {
operation: string;
userImpact: string;
technicalImpact: string;
businessImpact: string;
remediation: string;
};
}
Available MCP Tools
MCP TOOLS (8 total):
mcp_virsaitis_validate_operation- Validate file operation against TIER policymcp_virsaitis_read_governance- Load governance rules from workspacemcp_virsaitis_reload_cache- Refresh in-memory governance rule cachemcp_virsaitis_scan_secrets- Detect hardcoded secrets in contentmcp_virsaitis_validate_path- Check path for traversal and boundary violationsmcp_virsaitis_validate_command- Whitelist-check commands and escape argumentsmcp_virsaitis_read_audit_log- Read recent governance audit log entriesmcp_virsaitis_iteration_complete- Post-iteration compliance check (traceability, CHANGELOG, README)
🔧 Extension ↔ MCP Integration
Extension Queries MCP
FILE SAVE INTERCEPTION:
// extension/src/governance/file-interceptor.ts
export class FileInterceptor {
private _mcpClient: MCPClient;
constructor() {
this._mcpClient = new MCPClient();
vscode.workspace.onWillSaveTextDocument(async (e) => {
// Query MCP for validation
const validation = await this._mcpClient.validateOperation(
'write',
e.document.uri.fsPath
);
// Enforce based on TIER
if (!validation.allowed && validation.tier === 'TIER-0') {
// BLOCK: Prevent save
e.waitUntil(this.blockSave(validation));
} else if (!validation.allowed && validation.tier === 'TIER-1') {
// WARN: Show confirmation dialog
await this.warnUser(validation);
}
});
}
private async blockSave(validation: ValidationResponse): Promise<void> {
const message = `TIER-0 VIOLATION: ${validation.reason}\n\n` +
`Remediation: ${validation.consequences?.remediation}`;
await vscode.window.showErrorMessage(message, { modal: true });
throw new Error(message); // Prevents save
}
}
MCP Client Implementation
STDIO TRANSPORT CLIENT (MCP standard — not HTTP):
// extension/src/governance/mcp-client.ts
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
export class MCPClient {
private _client: Client;
private _transport: StdioClientTransport;
constructor() {
const config = vscode.workspace.getConfiguration('virsaitis');
const command = config.get<string>('mcpServerCommand', 'node');
const args = config.get<string[]>('mcpServerArgs', ['build/index.js']);
this._transport = new StdioClientTransport({ command, args });
this._client = new Client({ name: 'virsaitis-extension', version: '3.0.0' });
}
async connect(): Promise<void> {
await this._client.connect(this._transport);
}
async validateOperation(
operation: string,
filePath: string
): Promise<ValidationResponse> {
try {
const result = await this._client.callTool({
name: 'validate_operation',
arguments: { operation, filePath },
});
return JSON.parse(result.content[0].text as string);
} catch (error) {
console.error('MCP client error:', error);
// Fail-open: Allow operation if MCP unavailable
// (Alternative: Fail-closed for stricter enforcement)
return {
allowed: true,
reason: 'MCP server unavailable (fail-open)',
};
}
}
}
🎨 Extension UI Integration
Shield Icon Decoration
PROTECTED FILE INDICATOR:
// extension/src/ui/shield-decorator.ts
export class ShieldDecorator {
private _decorationType: vscode.TextEditorDecorationType;
constructor() {
this._decorationType = vscode.window.createTextEditorDecorationType({
gutterIconPath: vscode.Uri.file('resources/icons/shield.svg'),
gutterIconSize: '80%',
});
// Update on editor change
vscode.window.onDidChangeActiveTextEditor(editor => {
if (editor && this.isProtectedFile(editor.document.uri)) {
this.applyDecoration(editor);
}
});
}
private isProtectedFile(uri: vscode.Uri): boolean {
const protectedPatterns = [
'.github/copilot-instructions.md',
'.github/copilot-modules/',
'.github/agents/',
'virsaitis-development/virsaitis-requirements/',
];
return protectedPatterns.some(pattern => uri.fsPath.includes(pattern));
}
private applyDecoration(editor: vscode.TextEditor): void {
const range = new vscode.Range(0, 0, 0, 0);
editor.setDecorations(this._decorationType, [{ range }]);
}
}
Status Bar Integration
GOVERNANCE STATUS INDICATOR:
// extension/src/ui/status-bar.ts
export class GovernanceStatusBar {
private _statusBarItem: vscode.StatusBarItem;
constructor() {
this._statusBarItem = vscode.window.createStatusBarItem(
vscode.StatusBarAlignment.Right,
100
);
this._statusBarItem.command = 'virsaitis.showGovernanceStatus';
this._statusBarItem.text = '$(shield) Virsaitis: Active';
this._statusBarItem.show();
}
public updateStatus(mcpConnected: boolean): void {
if (mcpConnected) {
this._statusBarItem.text = '$(shield) Virsaitis: Active';
this._statusBarItem.backgroundColor = undefined;
} else {
this._statusBarItem.text = '$(warning) Virsaitis: MCP Disconnected';
this._statusBarItem.backgroundColor = new vscode.ThemeColor(
'statusBarItem.warningBackground'
);
}
}
}
📋 MCP → Agent Integration
MCP Reads Agent.md
⚡ CHECKPOINT — Three layers enforce governance: Agent (behavior), MCP (validation), Extension (interception). All connected.
GOVERNANCE RULES LOADING:
// mcp/src/governance/rules-loader.ts
export class GovernanceRulesLoader {
private _agentPath = '.github/agents/Virsaitis.agent.md';
async loadTierDefinitions(): Promise<TierDefinition[]> {
// Read Agent.md
const agentContent = await fs.promises.readFile(this._agentPath, 'utf-8');
// Parse TIER definitions
const tiers = this.parseTierSections(agentContent);
return tiers;
}
private parseTierSections(content: string): TierDefinition[] {
// Extract TIER-0, TIER-1, TIER-2, TIER-3 sections
const tierPatterns = [
/## TIER-0:(.+?)(?=## TIER-1|$)/s,
/## TIER-1:(.+?)(?=## TIER-2|$)/s,
/## TIER-2:(.+?)(?=## TIER-3|$)/s,
/## TIER-3:(.+?)(?=##|$)/s,
];
return tierPatterns.map((pattern, index) => {
const match = content.match(pattern);
return {
tier: `TIER-${index}` as TierLevel,
content: match ? match[1].trim() : '',
};
});
}
}
MCP Validates Against Agent Rules
VALIDATION ENGINE:
// mcp/src/governance/validator.ts
export class GovernanceValidator {
private _rules: GovernanceRules;
constructor() {
this._rules = new GovernanceRulesLoader().loadRules();
}
validateFileOperation(operation: string, filePath: string): ValidationResult {
// Check TIER-0 protected patterns (from Agent.md)
const protectedPatterns = this._rules.tier0.protectedFilePatterns;
const isProtected = protectedPatterns.some(pattern =>
filePath.includes(pattern)
);
if (isProtected && operation === 'write') {
return {
allowed: false,
tier: 'TIER-0',
reason: 'Protected file modification blocked',
consequences: this._rules.tier0.consequences,
};
}
// Check TIER-1 rules...
// Check TIER-2 rules...
return { allowed: true };
}
}
🔄 Data Flow Patterns
User Edits Protected File
1. USER: Attempts to save .github/copilot-instructions.md
↓
2. EXTENSION: onWillSaveTextDocument event fires
↓
3. EXTENSION: Calls MCP validateOperation()
↓
4. MCP: Loads Agent.md TIER-0 rules
↓
5. MCP: Checks file against protected patterns
↓
6. MCP: Returns { allowed: false, tier: 'TIER-0' }
↓
7. EXTENSION: Blocks save (throw error)
↓
8. EXTENSION: Shows modal error with consequences
↓
9. USER: Sees TIER-0 VIOLATION message
AI Generates Code with Secret
1. AGENT: About to suggest code with API key
↓
2. AGENT: Calls mcp_virsaitis_validate_operation (hypothetical)
↓
3. MCP: Scans code for secret patterns
↓
4. MCP: Detects API key pattern
↓
5. MCP: Returns { allowed: false, tier: 'TIER-0', reason: 'Secret detected' }
↓
6. AGENT: Responds to user: "TIER-0 VIOLATION PREVENTED: Secret detected"
↓
7. AGENT: Suggests environment variable approach
⚖️ Precedence & Conflict Resolution
Rule Hierarchy
TIER-0 (Agent.md) ────► HIGHEST AUTHORITY
↓
TIER-1/2/3 (Agent.md) ─► Core Rules
↓
Skills (TIER-1/2/3) ───► Domain-Specific Rules
↓
Component Standards ───► Language/Framework Rules
Conflict Resolution
IF CONFLICT BETWEEN:
- Agent TIER-0 vs Skill TIER-1 → Agent wins (always)
- Agent TIER-1 vs Skill TIER-1 → Agent wins (authoritative)
- Skill A TIER-1 vs Skill B TIER-2 → TIER-1 wins (higher priority)
- Two skills same TIER → User chooses (ambiguous)
EXAMPLE CONFLICT:
# Agent.md TIER-0
Never use create_file for .agent.md files
# skill.md (hypothetical) TIER-1
Use automated tools for file creation
RESOLUTION: Agent TIER-0 wins (higher precedence)
AI MUST: Use manual paste workflow, ignore skill suggestion
💡 Best Practices
Loose Coupling
PREFER:
- Agent → MCP: Tool calls (loose coupling)
- Extension → MCP: HTTP API (loose coupling)
- Skills → Agent: References only (no dependencies)
AVOID:
- Direct file system access across layers
- Tight coupling between Agent and Extension
- Circular dependencies
Fail-Safe Defaults
IF MCP UNAVAILABLE:
- Agent: Continue with degraded governance (warn user)
- Extension: Fail-open (allow operations) OR Fail-closed (block operations)
CHOOSE BASED ON:
- Fail-open: Better UX, lower security
- Fail-closed: Better security, worse UX when MCP down
VIRSAITIS DEFAULT: Fail-open for non-TIER-0, fail-closed for TIER-0
Audit Logging
LOG AT EACH LAYER:
- Agent: Log MCP tool calls
- MCP: Log all validation requests
- Extension: Log user actions blocked/allowed
BENEFITS:
- Troubleshooting integration issues
- Compliance audit trail
- Performance monitoring
📚 Quick Reference
| Integration | Pattern | Interface |
|---|---|---|
| Agent → Skills | Progressive disclosure | VS Code native loading |
| Agent → MCP | Tool calls | MCP protocol |
| Skills → MCP | Tool calls | MCP protocol |
| Extension → MCP | stdio client | MCP SDK StdioClientTransport |
| MCP → Agent | File read | Markdown parser |
Integration Patterns Module v3.0.0 Seamless three-layer governance integration
Key Rules From This Module
- Three layers: Agent (behavioral), MCP (validation), Extension (interception).
- All MCP communication uses stdio transport. No HTTP REST endpoints.
- Extension calls MCP via StdioClientTransport from @modelcontextprotocol/sdk.
- Fail-open by default if MCP unavailable. Document when fail-closed is required.
- Definitions:
.github/virsaitis-definition-library.md
Return to hub: .github/copilot-instructions.md