- Create scripts/utils/propose-pattern.js to propose new patterns or extend existing ones based on a newly applied workaround/fix. - Default to dry-run preview; --apply writes files only after human review. - Matches against existing patterns via keyword overlap and proposes an update when the shape is similar enough, or a new pattern file otherwise. - Update patterns/README.md with feedback-loop instructions. - Update MEMORY.md to document the plasticity loop. - Update CONTEXT.md decisions log and current tasks.
135 lines
10 KiB
Markdown
135 lines
10 KiB
Markdown
# MEMORY.md
|
|
|
|
## Purpose
|
|
|
|
This defines how I store, retrieve, and update memory for software/app development projects. Memory exists so no project ever has to be re-explained from scratch — to me in a new session, or to another agent picking up the work.
|
|
|
|
Memory is not a log for its own sake. Every entry should answer a question someone will actually ask later: *what's the current state, why was it built this way, what broke before, what's still open.*
|
|
|
|
## Memory Structure
|
|
|
|
Each project gets its own memory set, kept together rather than scattered:
|
|
|
|
```
|
|
/project-root/memory/
|
|
STATUS.md — current state, what's in progress, what's blocked
|
|
DECISIONS.md — architectural/technical decisions and why
|
|
ISSUES.md — known bugs, fragile spots, workarounds in place
|
|
RUNBOOK.md — how to start/stop/restart/deploy/roll back this project
|
|
CHANGELOG.md — dated record of completed work
|
|
```
|
|
|
|
For projects tracked in NocoDB (multi-agent runs, workflow executions), the database is the source of truth for structured run/task data; these markdown files are the source of truth for narrative context a table can't hold well.
|
|
|
|
## What Goes Where
|
|
|
|
**STATUS.md** — Rewritten, not appended. Always reflects *right now*: active work, what's blocked and on what, what's deployed where (dev/staging/prod), next planned step. Stale status is worse than no status — I keep this current every session, not periodically.
|
|
|
|
**DECISIONS.md** — Appended, never rewritten. One entry per non-obvious decision: what was chosen, what the alternatives were, why this one won. Prevents re-litigating settled questions and gives future-me (or another agent) the "why," not just the "what."
|
|
|
|
**ISSUES.md** — Living list of known bugs, fragile integrations, and deliberate workarounds. Includes recurring patterns even when a specific instance is "fixed," because the pattern will resurface (e.g., small local Ollama models producing malformed JSON — logged as a standing pattern, not closed out each time it's patched).
|
|
|
|
**RUNBOOK.md** — Operational, not narrative: exact commands to start/stop/restart/deploy/roll back, log locations, health-check steps. Written so it can be followed under time pressure without re-deriving anything.
|
|
|
|
**CHANGELOG.md** — Short, dated entries per completed unit of work: what changed, why, how it was verified. This is the audit trail — every "done" I've reported should have a corresponding line here.
|
|
|
|
## Update Discipline
|
|
|
|
**Before starting work on a project:**
|
|
1. Read STATUS.md first — orient to current state before touching anything
|
|
2. Check DECISIONS.md for anything relevant to the task at hand
|
|
3. Check ISSUES.md for known fragile spots in the area being touched
|
|
|
|
**During work:**
|
|
- If a new architectural or technical decision gets made, it goes into DECISIONS.md immediately — not reconstructed from memory later
|
|
- If a workaround gets applied, it goes into ISSUES.md with what it's working around and why the root cause wasn't fixed instead
|
|
|
|
**After completing work:**
|
|
1. Update STATUS.md to reflect the new current state
|
|
2. Add a CHANGELOG.md entry: what changed, why, how verified
|
|
3. Update RUNBOOK.md if operational procedure changed
|
|
4. Confirm nothing in ISSUES.md was silently resolved without being marked as such
|
|
|
|
## What I Do Not Store in Memory
|
|
|
|
- Secrets, credentials, API keys, or tokens — these belong in the vault/secrets manager, never in a markdown file, even as an example or placeholder that looks real
|
|
- Verbose blow-by-blow of exploratory debugging — memory holds the conclusion and the fix, not the full transcript of getting there
|
|
- Speculative future plans dressed up as decisions — DECISIONS.md is for choices actually made, not options being considered
|
|
|
|
## Cross-Project Patterns
|
|
|
|
### PowerShell Nested-Module WhatIf Propagation
|
|
|
|
When a PowerShell module imports helper modules via `Import-Module`, `$WhatIfPreference` does **not** automatically propagate across the nested-module boundary. If a root-module orchestrator calls a function in a nested module with `-WhatIf`, nested functions must either be in the same module scope or receive `-WhatIf:$WhatIfPreference` explicitly. Functions that themselves use `[CmdletBinding(SupportsShouldProcess=$true)]` will throw a duplicate-parameter error if passed `-WhatIf` explicitly, so Graph-dispatch helpers should use an explicit `[switch]$WhatIf` parameter instead.
|
|
|
|
Learned during: M365 Admin Toolkit Deployment Framework (2026-07-29).
|
|
|
|
### Cross-Project Pattern Registry
|
|
|
|
A centralized pattern registry now lives at `patterns/` in the workspace. It captures recurring technical lessons, workarounds, and failure modes across projects so agents can recognize known shapes and apply proven countermeasures.
|
|
|
|
See:
|
|
- `patterns/README.md` — registry guide and template
|
|
- `patterns/patterns.json` — machine-readable manifest
|
|
- `patterns/*.md` — individual pattern files
|
|
|
|
Patterns are automatically loaded by `architecture/pipeline.js` when the task input matches a pattern's tags or affected projects. This is the generalization layer of the agent continual-learning system.
|
|
|
|
**Feedback loop:** when an agent applies a reusable workaround or fix, it should run `scripts/utils/propose-pattern.js` to propose a new pattern or extend an existing one. The helper is dry-run by default; use `--apply` only after human review. This is the plasticity layer — the registry grows from real work instead of being reconstructed from memory later.
|
|
|
|
Established: 2026-08-06.
|
|
|
|
### Small Local Ollama Models and Malformed JSON
|
|
|
|
Standing, deliberate fix: a JavaScript Code node with regex-based JSON extraction as a safety net. Document it as a workaround where applied.
|
|
|
|
Pattern file: `patterns/ollama-structured-output-fallback.md`.
|
|
|
|
### JSON Escaping for LLM-Generated Downstream API Payloads
|
|
|
|
Defensive handling by default when passing LLM output into API calls (LinkedIn posts, video generation payloads, etc.).
|
|
|
|
Pattern file: `patterns/json-escaping-downstream-api.md`.
|
|
|
|
### Coding Task Delegation Default
|
|
|
|
**Default to native OpenClaw subagents (`runtime: "subagent"`) for routine coding tasks.**
|
|
|
|
- Background ACP runs (`runtime: "acp"`, `mode: "run"`) fail in this environment with `AcpRuntimeError [ACP_TURN_FAILED]: Permission prompt unavailable in non-interactive mode` because the host cannot display approval prompts for unattended ACP turns.
|
|
- Native subagents inherit `agents.defaults.model.primary`, currently `ollama/kimi-k2.6:cloud`, which is sufficient for well-scoped coding work.
|
|
- Use ACP / OpenCode / Claude Code / Codex harnesses **only when explicitly requested** and run them in a chat-bound/foreground context rather than background mode.
|
|
|
|
Established: 2026-08-02.
|
|
|
|
### API Version Deprecation
|
|
|
|
Note the API version in use and where to check for deprecation notices for any new integration.
|
|
|
|
## Failure Mode I'm Guarding Against
|
|
|
|
The single worst outcome for this system is confident, stale memory — a STATUS.md that says something is fine when it isn't, or a RUNBOOK.md that no longer matches how the app actually deploys. When I'm not sure memory is current, I verify against the live system before trusting it, and I correct the record immediately if it's wrong. Memory that isn't kept honest is worse than no memory at all.
|
|
|
|
## Promoted From Short-Term Memory (2026-08-02)
|
|
|
|
<!-- openclaw-memory-promotion:memory:memory/2026-07-25.md:1:38 -->
|
|
- # Memory: 2026-07-25 ## Nextcloud AIO Setup (bve.beawit.net) ### VM Configuration - **VMID**: 102 (Proxmox on bve.beawit.net) - **Hostname**: nextcloud-aio - **IP**: 192.168.0.149 - **RAM**: 16GB (resized from 8GB for production use) - **Disk**: 100GB - **Swap**: 4GB file at `/swapfile` - **OS**: Debian 12 cloud-init ### AIO Configuration - Running with `--network host` so Apache binds directly to VM IP (avoids Docker network complexity for NPM reverse proxy) - `APACHE_PORT=11000`, `APACHE_IP_BINDING=0.0.0.0`, `SKIP_DOMAIN_VALIDATION=true` - All optional services enabled: ClamAV, Collabora, Talk, Imaginary, Whiteboard,... [score=0.905 recalls=3 avg=0.634 source=memory/2026-07-25.md:1-38]
|
|
<!-- openclaw-memory-promotion:memory:memory/2026-07-26.md:27:27 -->
|
|
- Nextcloud AIO Setup (bve.beawit.net): **Talk Backend Version Mismatch**: Talk app 24.0.3 vs signaling server 2.1.1~docker — requires AIO update to resolve (non-critical) [score=0.812 recalls=0 avg=0.620 source=memory/2026-07-26.md:27-27]
|
|
<!-- openclaw-memory-promotion:memory:memory/2026-07-27.md:12:14 -->
|
|
- Solution Implemented: Installed `pexpect` on the server (pty-enabled subprocess); Wrote `app_pexpect.py` that uses `pexpect.spawn()` with PTY to capture console output; Need to deploy this version to the server [score=0.812 recalls=0 avg=0.620 source=memory/2026-07-27.md:12-14]
|
|
<!-- openclaw-memory-promotion:memory:memory/2026-07-27.md:6:6 -->
|
|
- Problem: When running a check from the web app, PowerShell hangs at `Connect-MgGraph -UseDeviceAuthentication` because the device code output is NOT being captured/displayed. The user never sees the code to enter in their browser. [score=0.812 recalls=0 avg=0.620 source=memory/2026-07-27.md:6-6]
|
|
<!-- openclaw-memory-promotion:memory:memory/2026-07-27.md:9:9 -->
|
|
- Root Cause: `Connect-MgGraph -UseDeviceAuthentication` writes the device code using PowerShell's **console host**, not stdout. When run via `subprocess.Popen` without a PTY (pseudo-terminal), the console output is not captured. [score=0.812 recalls=0 avg=0.620 source=memory/2026-07-27.md:9-9]
|
|
<!-- openclaw-memory-promotion:memory:memory/2026-07-27.md:21:21 -->
|
|
- Files Ready for Deploy: `/tmp/defender_status.ps1` — PowerShell with device code auth [score=0.812 recalls=0 avg=0.620 source=memory/2026-07-27.md:21-21]
|
|
<!-- openclaw-memory-promotion:memory:memory/2026-07-27.md:24:27 -->
|
|
- Next Steps: Deploy `app_pexpect.py` to `/home/jcbeasley/applications/active/intune-inspector/app.py`; Copy PowerShell `.ps1` files to `powershell/` directory; Kill any stuck PowerShell processes; Restart the app [score=0.812 recalls=0 avg=0.620 source=memory/2026-07-27.md:24-27]
|
|
<!-- openclaw-memory-promotion:memory:memory/2026-07-27.md:17:20 -->
|
|
- Files Ready for Deploy: `/tmp/app_pexpect.py` — Flask app with pexpect PTY support; `/tmp/intune_enrollment.ps1` — PowerShell with device code auth; `/tmp/conditional_access.ps1` — PowerShell with device code auth; `/tmp/security_defaults.ps1` — PowerShell with device code auth [score=0.812 recalls=0 avg=0.620 source=memory/2026-07-27.md:17-20]
|
|
|
|
## Promoted From Short-Term Memory (2026-08-03)
|
|
|
|
<!-- openclaw-memory-promotion:memory:memory/2026-07-27.md:28:28 -->
|
|
- Next Steps: Test device code capture [score=0.802 recalls=0 avg=0.620 source=memory/2026-07-27.md:28-28]
|