Implement consistency architecture (10-principle framework)

Adds:
- ARCHITECTURE.md: Full documentation of 3-layer system
- Context Pipeline: Preprocessing layer (pipeline.js)
- Workflow Router: 4 fixed workflows (coding, debug, deploy, audit)
- Validation Layer: Post-response quality gate (validator.js)
- Format Templates: Structured output templates
- TOOLS.md: Beavault connection documentation

Architecture:
- Layer 1: Behavior rules (always injected)
- Layer 2: Persistent facts (structured memory)
- Layer 3: Ephemeral context
- Priority enforcement: Rules > Prefs > Task > Chat
- Memory write policy: Only confirmed fixes, repeated preferences
This commit is contained in:
JC Beasley
2026-07-04 15:44:53 -07:00
parent 6ad8772e48
commit ed5dff8ebd
9 changed files with 829 additions and 0 deletions
+195
View File
@@ -0,0 +1,195 @@
#!/usr/bin/env node
/**
* Context Pipeline - Preprocessing Layer
*
* Every request flows through:
* 1. Load Rules → 2. Load Preferences → 3. Load Memory → 4. Build Packet
*/
const fs = require('fs');
const path = require('path');
class ContextPipeline {
constructor() {
this.rules = [];
this.preferences = [];
this.memory = [];
this.context = {};
}
/**
* Step 1: Load Behavior Rules (always injected)
*/
async loadRules() {
const ruleFiles = [
'SOUL.md',
'AGENTS.md',
'IDENTITY.md',
'MEMORY.md'
];
for (const file of ruleFiles) {
const content = await this.readFile(file);
if (content) {
this.rules.push({
source: file,
content: content,
priority: 100 // Absolute priority
});
}
}
// Load active workflow rules if specified
const workflow = process.env.ACTIVE_WORKFLOW;
if (workflow) {
const workflowRules = await this.readFile(`workflows/${workflow}.md`);
if (workflowRules) {
this.rules.push({
source: `workflows/${workflow}.md`,
content: workflowRules,
priority: 95
});
}
}
return this;
}
/**
* Step 2: Load Persistent Preferences (from structured memory)
*/
async loadPreferences() {
const prefFiles = [
'memory/items/mem_pref:communication_style.json',
'memory/items/mem_pref:format.json',
'memory/items/mem_pref:memory_persistence.json',
'memory/items/mem_identity:name.json',
'memory/items/mem_identity:role.json'
];
for (const file of prefFiles) {
const data = await this.readJson(file);
if (data) {
this.preferences.push({
source: file,
content: data.content,
priority: data.importance || 7,
tags: data.tags || []
});
}
}
return this;
}
/**
* Step 3: Load Relevant Memory
*/
async loadRelevantMemory(query, maxResults = 5) {
// For now, load recent episodic memories
// Future: implement vector search
const memoryFiles = [
'memory/2026-07-04.md',
'memory/2026-07-03.md'
];
for (const file of memoryFiles) {
const content = await this.readFile(file);
if (content) {
this.memory.push({
source: file,
content: content.substring(0, 2000), // Truncate
priority: 5
});
}
}
// Load project memory if PROJECT context set
const project = process.env.CURRENT_PROJECT;
if (project) {
const projectStatus = await this.readFile(`Projects/${project}/memory/STATUS.md`);
if (projectStatus) {
this.memory.push({
source: `Projects/${project}/memory/STATUS.md`,
content: projectStatus,
priority: 8
});
}
}
return this;
}
/**
* Step 4: Build Context Packet
*/
buildPacket(taskInput) {
// Sort by priority (highest first)
const allContext = [
...this.rules,
...this.preferences.sort((a, b) => b.priority - a.priority),
...this.memory
];
const packet = {
system: allContext.filter(c => c.priority >= 90).map(c => c.content).join('\n\n---\n\n'),
preferences: allContext.filter(c => c.priority >= 5 && c.priority < 90).map(c => c.content).join('\n\n'),
memory: allContext.filter(c => c.priority < 5).map(c => c.content).join('\n\n'),
task: taskInput,
metadata: {
rules_count: this.rules.length,
prefs_count: this.preferences.length,
memory_count: this.memory.length
}
};
return packet;
}
/**
* Utility: Read file from workspace
*/
async readFile(filepath) {
const fullPath = path.join('/home/jcbeasley/.openclaw/workspace', filepath);
try {
return fs.readFileSync(fullPath, 'utf8');
} catch (err) {
return null;
}
}
/**
* Utility: Read JSON file
*/
async readJson(filepath) {
const fullPath = path.join('/home/jcbeasley/.openclaw/workspace', filepath);
try {
const content = fs.readFileSync(fullPath, 'utf8');
return JSON.parse(content);
} catch (err) {
return null;
}
}
}
// Export for use
module.exports = ContextPipeline;
// CLI usage
if (require.main === module) {
const pipeline = new ContextPipeline();
pipeline
.loadRules()
.then(() => pipeline.loadPreferences())
.then(() => pipeline.loadRelevantMemory(process.argv[2] || ''))
.then(() => {
const packet = pipeline.buildPacket(process.argv[2] || 'No task specified');
console.log(JSON.stringify(packet, null, 2));
})
.catch(err => {
console.error('Pipeline error:', err);
process.exit(1);
});
}