Files
JC Beasley 66215eaf76 Add feedback loop for cross-project pattern registry
- 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.
2026-08-06 12:52:47 -07:00

10 KiB

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)

  • 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]

  • 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]
  • 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]
  • 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]
  • 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]
  • 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]
  • 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]
  • 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)

  • Next Steps: Test device code capture [score=0.802 recalls=0 avg=0.620 source=memory/2026-07-27.md:28-28]