Repository navigation
Dreamer policy is hardcoded to software-development workflows — make per-project policy configurable (task prompts, memory categories, maintained docs) #358
Description
Short description
Magic Context's memory machinery (historian, dreamer, injection) works well as a mechanism, but its policy layer is hardcoded to software development: the dreamer task prompts, the memory taxonomy, and the maintained docs list are compiled into the plugin and cannot be adapted to non-code projects (security, research, operations, writing, etc.). For a project that is not a code repository, the system still classifies memories with development-oriented categories and maintains ARCHITECTURE.md / STRUCTURE.md as if every project were a repo.
What problem does this solve?
The plugin manages each project's memory with a fixed policy designed for
software repositories. That policy shows up in three places:
-
The dreamer runs its tasks (curation, verification, user-memory review,
documentation maintenance) with internal prompts written in development
language. For a project that is not code, the agent classifies and
organizes memory with the wrong perspective: it looks for "testing
conventions", "releases" or "commits" where none exist. -
Memory categories are locked to a development taxonomy (PROJECT_RULES,
ARCHITECTURE, CONSTRAINTS, CONFIG_VALUES, NAMING). Memories from other
domains get forced into categories that do not represent their real
work, degrading curation usefulness. -
Documentation maintenance is fixed to ARCHITECTURE.md and STRUCTURE.md,
software architecture files. Projects that are not code repositories
receive documentation that does not fit them, or cannot maintain the
documentation that would actually serve them.
The result: the memory mechanism (historian, compaction, injection) works
for any project, but the policy layer limits it to development projects.
Users from other domains end up with less useful classification, irrelevant
documentation, and dreamer prompts that do not understand their work.
Proposed solution
Decouple the MECHANISM (historian, compaction, injection, storage — the core
of how the plugin stores, organizes and recalls memory) from the POLICY (how
the dreamer should think about THIS project). The core must remain intact;
the proposal is to open the policy layer to configuration so each project
can adapt it to its domain:
-
Project awareness for the dreamer.
The dreamer runs tasks (curation, verification, user-memory review, doc
maintenance, etc.), each with an internal system prompt. Today those
prompts are fixed and speak in development language (codebase, repo,
releases, testing). The proposal: let the user give the dreamer an
orientation about what this project is and how it should treat its
memories, without replacing the task mechanism — only adapting the
perspective with which tasks are executed. -
Configurable memory categories.
The category taxonomy is fixed (PROJECT_RULES, ARCHITECTURE, CONSTRAINTS,
CONFIG_VALUES, NAMING) and oriented to software repositories. The
proposal: let the user define the categories their project uses, so
curation classifies memories into the categories that actually exist in
their work. -
Configurable maintained docs.
Documentation maintenance is fixed to ARCHITECTURE.md and STRUCTURE.md.
The proposal: let the user choose which documentation files should be
maintained (and with what content instructions for each), instead of a
fixed list. -
Non-code project mode (optional).
A convenience mode that pre-configures the points above for projects
that are not code repositories: disables development-oriented language
and repo doc maintenance, keeps memory curation with user-defined
categories, and focuses historian/review prompts on the project's real
work type. It would solve the root problem for those who want it, but
it is optional.
graph TD;
A[TODAY - Policy welded to code] --> B[Dreamer task prompts fixed with dev-oriented language];
A --> C[Memory categories fixed to dev taxonomy];
A --> D[Maintained docs fixed to ARCHITECTURE.md and STRUCTURE.md];
B --> E[Dreamer agent thinks in codebase / repo / releases];
C --> E;
D --> E;
E --> F[Result: less useful curation and irrelevant docs for non-code projects];
G[PROPOSAL - Configurable per-project policy] --> H[Project awareness - user tells the dreamer what this project is];
G --> I[Memory categories defined by the user];
G --> J[Maintained docs chosen by the user with content rules];
G --> K[Non-code project mode - optional, pre-configures everything];
H --> L[Dreamer agent understands your domain];
I --> L;
J --> L;
L --> M[Result: useful curation and relevant docs for any project];
E --> N{Transition};
N -->|decouple mechanism from policy| H;
Alternatives considered
-
Fork the plugin and maintain it ourselves.
Rejected: a fork forces perpetual sync with upstream for what is a
configurability change. -
Externalize dreamer prompts to files (templates/).
Viable as an implementation, but less discoverable than the existing
magic-context.jsonc configuration, which is the pattern the plugin
already uses (schedules, models, thresholds). -
Do nothing and use the plugin with defaults only.
Rejected for non-dev projects: classifying into development categories
and maintaining repo docs adds noise and tokens to projects that don't
need them. -
Hardcode a domain-specific category set as an additional option.
Rejected: it would solve one specific case but reproduce the same
problem for the next domain. The right fix is letting the user define
their own categories.
Area
OpenCode plugin
Additional context
Real use case: a work project that is not a code repository — it contains
per-topic work folders, findings, operational data and methodology, with no
source code, commits or releases. Current behavior:
- Curation classifies memories into development categories that do not map
to the project's real work (result: less useful curation, forced or
skipped classification). - Doc maintenance keeps ARCHITECTURE.md and STRUCTURE.md in sync even
though those files describe software layers the project does not have. - User memories accumulate slowly because the review prompt is tuned for
recurring dev workflows, not for other types of work sessions.
Acceptance criteria:
- The dreamer receives configurable orientation about the project type
- Memory categories are user-configurable
- The maintained docs list and their content instructions are configurable
- Default behavior unchanged when no custom config is present
- Documented in the config schema and README
Activity
Ema-prowler commentedon Aug 22, 2026
Efficiency impact
The development-oriented policy does not only produce less useful
classification — it also consumes resources unnecessarily:
Wasted tokens. The dreamer runs its tasks with long system prompts
written for software development. For a non-code project, much of that
context does not apply: the agent reads, analyzes and classifies
memories looking for concepts that do not exist in the project
(releases, commits, testing). Every run spends tokens on a frame that
does not fit.
Fewer iterations. By aligning the dreamer prompt with the project's
real domain, the agent classifies and decides correctly the first
time: no back-and-forth to reinterpret memories that do not fit dev
categories, and no corrective re-curation.
Less dreamer workload. By disabling what does not apply (repo doc
maintenance, dev categories) and focusing tasks on what does, each run
processes less volume with more accuracy.
More speed. Shorter, focused prompts = faster model responses on every
dreamer task.
Dreamer at higher frequency. By reducing the per-run cost (tokens and
time), running the dreamer more often becomes viable — for example on
active projects where today it makes sense to space runs out because
each one spends too much on context that does not apply.
The result: the same memory quality with less consumption, or more
maintenance frequency with the same token budget.
magic-alfonso commentedon Aug 23, 2026
You've read the architecture correctly, and we're committing to fixing it the way you suggest: the compaction/memory/dreamer machinery is genuinely domain-neutral, and the software-development shape lives in a thin, enumerable policy layer (the memory taxonomy, the historian's fact-extraction fragment, the dreamer task set and its maintained-docs targets, commit detection). That layer will become configurable.
The shape we've settled on is versioned policy packs rather than per-field configuration:
Why free-form categories lose to packs: category names look like display strings but actually key memory dedup, workspace sharing gates, cross-category merge protection, and classification calibration. An open set fragments memory pools and silently breaks sharing semantics; a closed per-pack set keeps every project internally coherent.
On timing, honestly: no date. This lands after an engine consolidation we're mid-way through — Magic Context's transform and background machinery is moving into a shared native engine (the Rust workspace in this repo), with the TypeScript plugin reducing to thin host hooks. Policy packs will be implemented once, in that engine, served identically to every harness — rather than twice in a layer that's being retired. When the pack format spec is written we'll link it here; design input on it is welcome, and a domain pack authored by someone who actually lives in that domain would be a first-class contribution.
coleleavitt commentedon Sep 13, 2026
Current-baseline audit against v0.42.3 (
5bf26e65): keep open. The accepted policy-pack seam is still absent:memory/types.tsexposes the closed five-category taxonomy, compartment parsing expects those fixed tags, Dreamer prompts retain repository/testing/release policy, and maintain-docs protection remains tied toARCHITECTURE.md/STRUCTURE.md.dreamer.inject_docsonly toggles injection and does not make policy or maintained targets configurable.G0-0000 commentedon Sep 16, 2026
Our Experience with Custom 6-Category Taxonomy
We've been using a custom 6-category taxonomy (OPS_RULES / ENV_STATE / CONFIG_VALUES / INCIDENTS / RESEARCH / MODEL_KNOWLEDGE) based on this issue for ~2 weeks. Here's what we learned:
1. Adoption Status
dist/index.jscontains 0 occurrences of our new category strings;CATEGORY_PRIORITYstill hardcodes default programming-oriented 5 categories2. Key Findings
classify-memoriestask name is misleading — it's actually a scoring task (writesimportance/scope/shareable/classified_at), never writescategorycategoryis 100% free-text fromctx_memory write— no automated pipeline manages itretrospectivetask prompt still uses old 5-category names (PROJECT_RULES/NAMING), causing 3 legacy memories to persist3. Runtime Status
incompletefailures + 2× manifest parse errors (self-healed)4. Suggestions for Upstream
CATEGORY_PRIORITYconstant needs to be configurable (currently hardcoded)classify-memoriesor documenting that it doesn't classify categoriesHope this helps! Happy to share more details if needed.
G0-0000 commentedon Sep 19, 2026
Follow-up: 6-category field report + an idea for the pack-format spec
Continuing from my field report above. Three pain points emerged after ~2 more weeks on the custom 6-category taxonomy, and they point at what I'd like to put on the table as design input for the policy-pack format — not an implementation request.
Pain points
The taxonomy feels rigid. A single mutually-exclusive dimension forces every memory into exactly one slot, and the right granularity only becomes visible after use.
Cross-cutting is the norm, not the exception. Memories behave more like entities than wiki pages. "A model-config issue discovered during an incident" is simultaneously INCIDENTS, ENV_STATE, CONFIG_VALUES and MODEL_KNOWLEDGE. One-dimensional classification is a mismatch for entity-like content: it creates write-time friction (which slot?) and recall misses (the memory is only reachable from 1/N of the entry points it belongs to).
The dreamer lacks tools for restructuring. Today it has free-text
ctx_memory writeand embedding search, but no way to relate memories: no link creation, no grouping, no graph traversal. As noted above,categoryis 100% free-text from write-time and no automated pipeline maintains it afterwards — classification quality depends entirely on the writer's momentary judgment.The idea: links and composites as first-class, self-managed memory blocks
The diagnosis is "only one organizational dimension exists", not "the categories are wrong" (92.7% write-side adoption says they're roughly right). So rather than refining the taxonomy dimension, add derived dimensions on top:
cursormetadata field is arguably the valuable part: where in the cycle am I now) are all special cases of one primitive, not three block types.Crucially, both primitives would live outside the mechanisms your earlier comment reserved for the closed taxonomy: they don't key dedup, workspace sharing gates, or cross-category merge protection — the "open set fragments memory pools" argument doesn't apply to them. And they'd be managed by the existing machinery: links and composites get compressed, expired and merged by the historian/dreamer like any memory (e.g. 50 fragments + 100 links → one summary block + one summary edge). No new subsystem; the graph maintains itself.
This is the hippocampus model rather than a wiki: structure as a product of consolidation, derived by the dreamer after the fact, with cue-driven associative recall — not a hierarchy that must be decided before writing.
Open questions (for the maintainers, when the pack spec is written)
Happy to freeze this here as material — I can adapt to whatever shape the spec takes, or help author a pack for non-software operational domains once the format exists.