mirror of
https://github.com/PR0M3TH3AN/TORCH.git
synced 2026-10-27 07:51:52 +00:00
Harden memory workflow to reduce merge conflicts
This commit is contained in:
1 parent
561bc9b4bd
commit
811f45b3af
8 files changed
+84
-10
No files matched your search
@@ -1,2 +1,7 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
# Reduce merge conflicts for append-style memory artifacts.
|
||||
memory-updates/*.md merge=union
|
||||
.scheduler-memory/latest/daily/memories.md merge=union
|
||||
.scheduler-memory/latest/weekly/memories.md merge=union
|
||||
@@ -0,0 +1,66 @@
|
||||
# Memory Architecture Report - 2026-02-26
|
||||
|
||||
## Problem
|
||||
Recurring merge conflicts come from shared write-hotspot files (`memory-update.md`, aggregate `memories.md`) being edited by many branches/runs.
|
||||
|
||||
## Goals
|
||||
- Preserve reliable short-term and long-term memory for agents.
|
||||
- Keep memory artifacts traceable in git.
|
||||
- Minimize manual merge work and conflict risk.
|
||||
|
||||
## Core Learnings
|
||||
1. Shared mutable files are conflict magnets.
|
||||
2. Per-run immutable files are merge-friendly and auditable.
|
||||
3. Aggregate views should be generated artifacts, not canonical sources of truth.
|
||||
4. Reliable memory quality comes from deterministic ingestion and stable schema, not from one giant markdown file.
|
||||
|
||||
## Recommended Structure
|
||||
- Source of truth (tracked): `memory-updates/<timestamp>__<agent>.md`
|
||||
- Optional index/metadata (tracked): machine-readable pointers (run id, agent, cadence, tags, embedding/version).
|
||||
- Generated read model (tracked or regenerated): `.scheduler-memory/latest/<cadence>/memories.md`
|
||||
|
||||
Canonical rule:
|
||||
- Write path: only per-run file (`$SCHEDULER_MEMORY_FILE`).
|
||||
- Read path: generated latest aggregate and/or retrieval service.
|
||||
- Never write directly to shared aggregate files from agents.
|
||||
|
||||
## Merge Policy
|
||||
- Keep `memory-updates/*.md` append-style and use `merge=union` to reduce non-overlapping merge collisions.
|
||||
- For generated aggregates (`.scheduler-memory/latest/*/memories.md`):
|
||||
- Prefer keeping one side during merge, then regenerate from source files.
|
||||
- Treat as a cache/read model, not primary truth.
|
||||
|
||||
## Determinism and Reliability Controls
|
||||
- Stable timestamp format (`YYYY-MM-DDTHH-MM-SSZ`) and agent-id naming.
|
||||
- Ingestion writes structured metadata (agent, cadence, run id, tags, source path).
|
||||
- Retrieval/storage must emit verifiable markers/artifacts (`MEMORY_RETRIEVED`, `MEMORY_STORED`, JSON evidence).
|
||||
- Avoid retries/sleeps as correctness fixes; remove nondeterminism at source.
|
||||
|
||||
## Short-Term Memory Design
|
||||
- Scope by cadence and recent window in retrieval queries.
|
||||
- Prioritize high-signal recent memories by recency + importance + semantic match.
|
||||
- Keep run-local context in artifacts (`context/`, `todo/`, `decisions/`, `test_logs/`) and link memory entries to those artifacts.
|
||||
|
||||
## Long-Term Memory Design
|
||||
- Periodic consolidation jobs should summarize repeated findings into durable patterns.
|
||||
- Promote stable insights to a curated long-term layer (policy/decision docs or pinned memory records).
|
||||
- Keep provenance: every promoted insight references original run files.
|
||||
|
||||
## Suggested Evolution Path
|
||||
1. Enforce write contract: only `$SCHEDULER_MEMORY_FILE` in `memory-updates/`.
|
||||
2. Regenerate aggregates from `memory-updates/` in scheduler cycle.
|
||||
3. Add lightweight memory manifest for faster deterministic rebuilds.
|
||||
4. Add pruning/compaction rules that preserve high-value long-term insights.
|
||||
5. Add integrity checks: fail if agents write to deprecated shared files.
|
||||
|
||||
## Operational Playbook for Conflicts
|
||||
When conflicts involve memory files:
|
||||
1. Resolve source files (`memory-updates/*`) by keeping both sides when possible.
|
||||
2. Resolve aggregate files (`.scheduler-memory/latest/*/memories.md`) by choosing one side.
|
||||
3. Regenerate aggregates from source files.
|
||||
4. Run memory policy tests before merge completion.
|
||||
|
||||
## Success Criteria
|
||||
- Significant drop in memory-related merge conflicts.
|
||||
- No loss in retrieval quality for recent and historical tasks.
|
||||
- Rebuild of aggregate memory is deterministic from tracked source files.
|
||||
@@ -8,10 +8,14 @@ const ROOT_DIR = path.resolve(__dirname, '../../');
|
||||
const DAILY_DIR = path.join(ROOT_DIR, 'src/prompts/daily');
|
||||
const WEEKLY_DIR = path.join(ROOT_DIR, 'src/prompts/weekly');
|
||||
const REPORT_DIR = path.join(ROOT_DIR, 'reports/prompt-safety');
|
||||
const MEMORY_DIR = path.join(ROOT_DIR, 'memory-updates');
|
||||
|
||||
if (!fs.existsSync(REPORT_DIR)) {
|
||||
fs.mkdirSync(REPORT_DIR, { recursive: true });
|
||||
}
|
||||
if (!fs.existsSync(MEMORY_DIR)) {
|
||||
fs.mkdirSync(MEMORY_DIR, { recursive: true });
|
||||
}
|
||||
|
||||
const SAFETY_KEYWORDS = [
|
||||
'FAILURE MODES',
|
||||
@@ -96,8 +100,9 @@ function runAudit() {
|
||||
memoryContent += `Flagged prompts: ${results.filter(r => r.status === 'NEEDS_REVIEW').map(r => r.filename).join(', ')}\n`;
|
||||
}
|
||||
|
||||
fs.writeFileSync(path.join(ROOT_DIR, 'memory-update.md'), memoryContent);
|
||||
console.log('Memory update written to memory-update.md');
|
||||
const memoryFile = path.join(MEMORY_DIR, `${timestamp}__prompt-safety-audit-agent.md`);
|
||||
fs.writeFileSync(memoryFile, memoryContent);
|
||||
console.log(`Memory update written to ${memoryFile}`);
|
||||
}
|
||||
|
||||
runAudit();
|
||||
@@ -69,7 +69,7 @@ async function main() {
|
||||
const runner = resolveRunner(promptMarkdown);
|
||||
|
||||
// Compute a stable, per-run memory output file path so agents know where to write learnings.
|
||||
// store.mjs reads this env var; if absent it falls back to the root memory-update.md placeholder.
|
||||
// store.mjs reads this env var and ingests this file.
|
||||
const agentName = process.env.SCHEDULER_AGENT || 'unknown-agent';
|
||||
const runTs = new Date().toISOString().replace(/:/g, '-').replace(/\.\d+Z$/, 'Z');
|
||||
const memoryFile = `memory-updates/${runTs}__${agentName}.md`;
|
||||
|
||||
@@ -35,9 +35,7 @@ const cliArgs = process.argv.slice(2);
|
||||
const fileArgIndex = cliArgs.indexOf('--file');
|
||||
const explicitFile = fileArgIndex !== -1 ? cliArgs[fileArgIndex + 1] : null;
|
||||
const envFile = process.env.SCHEDULER_MEMORY_FILE;
|
||||
const defaultFile = 'memory-update.md';
|
||||
|
||||
const targetFile = explicitFile || (envFile && existsSync(envFile) ? envFile : (existsSync(defaultFile) ? defaultFile : null));
|
||||
const targetFile = explicitFile || (envFile && existsSync(envFile) ? envFile : null);
|
||||
|
||||
if (targetFile) {
|
||||
try {
|
||||
@@ -71,7 +69,7 @@ if (memoryContent) {
|
||||
} else {
|
||||
// No memory file found — skip ingest rather than storing meaningless placeholder events.
|
||||
// Placeholder events pollute the store and degrade retrieval quality on future runs.
|
||||
console.warn(`No memory input found (checked --file, env SCHEDULER_MEMORY_FILE=${envFile}, and default ${defaultFile}). Skipping ingest.`);
|
||||
console.warn(`No memory input found (checked --file and env SCHEDULER_MEMORY_FILE=${envFile}). Skipping ingest.`);
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ import { detectTorchInstallDir } from './cmd-remove.mjs';
|
||||
|
||||
const MEMORY_HEADING = '## TORCH Memory Integration';
|
||||
const MEMORY_READ_LINE = '`.scheduler-memory/latest/${cadence}/memories.md`';
|
||||
const MEMORY_WRITE_LINE = '`memory-update.md`';
|
||||
const MEMORY_WRITE_LINE = '`$SCHEDULER_MEMORY_FILE`';
|
||||
|
||||
function parseMajorNodeVersion(version) {
|
||||
const major = Number.parseInt(String(version).split('.')[0], 10);
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ const MEMORY_INTEGRATION_HEADING = '## TORCH Memory Integration';
|
||||
const MEMORY_INTEGRATION_BLOCK = `${MEMORY_INTEGRATION_HEADING}
|
||||
You have access to the TORCH memory system.
|
||||
1. READ: Check \`.scheduler-memory/latest/\${cadence}/memories.md\` for past learnings.
|
||||
2. WRITE: Before exiting, save new insights to \`memory-update.md\` so future runs can learn from this session.`;
|
||||
2. WRITE: Before exiting, save new insights to \`$SCHEDULER_MEMORY_FILE\` (for example \`memory-updates/<timestamp>__<agent>.md\`) so future runs can learn from this session.`;
|
||||
|
||||
/**
|
||||
* Resolves the absolute paths for the installation.
|
||||
|
||||
@@ -57,7 +57,7 @@ Every agent prompt invoked by the schedulers (daily/weekly) MUST enforce this co
|
||||
- Write only facts that will help the **same agent** on its **next run**. Skip meta-commentary about the task structure.
|
||||
- Run configured memory storage workflow after prompt execution (for example via `scheduler.memoryPolicyByCadence.<cadence>.storeCommand`)
|
||||
- Storage command MUST call real memory services (`src/services/memory/index.js#ingestEvents`, which uses ingestor/summarizer pipeline) and MUST emit deterministic marker `MEMORY_STORED`.
|
||||
- Storage command MUST ingest content from the file at `$SCHEDULER_MEMORY_FILE` (or fallback to `memory-update.md` if present).
|
||||
- Storage command MUST ingest content from the file at `$SCHEDULER_MEMORY_FILE`.
|
||||
- Storage command MUST write cadence-scoped evidence artifacts:
|
||||
- `.scheduler-memory/store-<cadence>.ok`
|
||||
- `.scheduler-memory/store-<cadence>.json` containing operation inputs/outputs (`agentId`, input event count, stored count, generated summaries).
|
||||
|
||||
Reference in new issue
Block a user