Uvilo OS To Forge Research
Date: 2026-04-06 (rev 4) Scope: Architecture direction, memory strategy, platform identity, system prompt design, naming conventions, comparison with state-of-the-art agent systems Target scale: 300–500 files, 3–10 users within weeks
Executive Summary
The platform is now named Forge. This review incorporates three rounds of feedback and covers: system prompt composition, file naming conventions, the relationship between FORGE.md and the LibreChat Agent Instructions, LibreChat’s per-user memory feature, the INDEX.md/README.md split, and word-count-based budgets.
Key decisions made:
Assistant/→Forge/Uvilo_OS/→ merged intoForge/instructions.md→FORGE.md- Internal prompt files use UPPERCASE:
SKILL.md,LESSONS.md,README.md,INDEX.md - Every skill gets a co-located
LESSONS.md - Auto-generated file indexes become
INDEX.md;README.mdbecomes the human-written project description - Size budgets use word count, not line count
Key decisions pending:
- Whether to inline
FORGE.mdinto the Agent Instructions field - Whether to enable LibreChat per-user memory
- Exact structure of the minimal Artifact Instructions
- Timeline for the three-way split (Platform / Product / Business)
1. System Prompt Architecture
1.1 How LibreChat Composes the System Prompt
LibreChat assembles the system prompt from three concatenated parts, in this order:
1.2 The Case for Inlining FORGE.md into Agent Instructions
Current flow: Agent Instructions says “read instructions.md” → agent makes a tool call → reads the file → has the instructions.
Proposed flow: Agent Instructions contains the full contents of FORGE.md → agent has instructions immediately, no tool call needed.
Arguments for inlining:
- Prompt caching: Many LLM providers (OpenAI, Anthropic) auto-cache the common prefix of the system prompt. Since the system prompt is identical across all sessions for the same agent, the FORGE.md content gets cached at ~10% of normal token cost. When loaded via a tool call, the content arrives as a user-turn message, which is less likely to be cached.
- One fewer tool call per session: Today the agent’s first action is always “read instructions.md.” This costs a round-trip and wastes a tool call slot.
- Reliability: If the filesystem MCP server is slow or down, the agent still has its instructions.
- Consistency with Claude Code: Claude Code puts its CLAUDE.md content in the system prompt, not behind a tool call.
Arguments against:
- Agent Builder field limits: The Agent Instructions field in LibreChat’s UI may have practical size limits. At ~1,200 words, FORGE.md is manageable, but if it grows it could become unwieldy in the UI.
- Update friction: Changing the system prompt requires updating the Agent Builder (or running
/update-agents), not just editing a file. However, FORGE.md changes infrequently — that’s the whole point of the refactoring. - Visibility: The file in the repo remains the source of truth. The Agent Instructions field is a deployment copy, just like
librechat.yaml.
Recommendation: Yes, inline it. The caching benefit alone justifies this. Maintain FORGE.md in the repo as the source of truth. The /update-agents skill copies its contents into the Agent Instructions field during sync. This mirrors the existing pattern where librechat.yaml in the repo is the source of truth and /deploy-config copies it to the deployed location.
1.3 FORGE.md: What Changes
Rename instructions.md → FORGE.md. This is the platform’s operating contract — the equivalent of Claude Code’s CLAUDE.md. The name signals:
- It’s the Forge platform’s core file
- UPPERCASE naming matches other internal prompt files (SKILL.md, LESSONS.md)
- It’s instantly recognizable when open in an editor tab
Content remains the same as the current instructions.md (post-refactoring). The file lives at Forge/FORGE.md.
1.4 Minimal Artifact Instructions
The default LibreChat Artifact Instructions are ~1,600 words — mostly examples and format rules that don’t need to be in context every session. Proposed structure:
In the Agent Instructions (appended after FORGE.md content): A minimal 3–5 line pointer:
In Forge/Skills/Artifacts/SKILL.md: The full artifact format specification — type definitions (HTML, SVG, Markdown, Mermaid, React), available libraries (lucide-react, recharts, three.js, date-fns, shadcn/ui), the :::artifact directive syntax, and examples. Loaded on demand when the agent is about to create an artifact.
Risk: The agent may not know to load the skill before creating its first artifact in a session. Mitigation: The minimal pointer in the system prompt tells it where to look. Most LLMs are already trained on artifact patterns from their general training data; the skill fills in Forge-specific format details.
Alternative: Keep a medium-weight version (~400 words) in the system prompt covering the directive syntax and type list, with the skill holding only the examples and library details. This trades ~400 words of always-loaded context for more reliable first-artifact behavior.
Recommendation: Start with the medium-weight version. If artifact creation is reliable, trim further. If not, restore detail.
1.5 The Modular Pipeline (Updated)
Incorporating the system prompt composition model:
2. LibreChat Per-User Memory
2.1 How It Works
LibreChat has a built-in memory feature (since config v1.2.7). Key characteristics:
- Key/value store — not semantic search. Stores structured entries like
user_preferences: "prefers concise responses",learned_facts: "Erik is CEO of Uvilo". - Dedicated memory agent — a separate LLM call runs concurrently with every chat request. It reads the last N messages (
messageWindowSize), decides what to store/update/delete, and writes to the store. - Per-user — each user has their own memory store. Memory entries are injected into every request as context.
- Token-budgeted —
tokenLimitcaps how much memory can be stored (e.g., 2,000 tokens). - User-controllable — users can toggle memory on/off, and manually create/edit/delete entries via the UI.
- Costs a separate API call per request — the memory agent is an additional LLM invocation.
2.2 How It Could Help Forge
| Use case | Fit | Notes |
|---|---|---|
| Remembering user preferences (response style, verbosity) | ✅ Good | Exactly what it’s designed for |
| Storing per-user context (current project, role, department) | ✅ Good | Avoids each session needing to re-establish context |
| Replacing LESSONS.md | ❌ Poor | LESSONS.md is shared across all users; memory is per-user |
| Replacing project State/History | ❌ Poor | State files are project-scoped, not user-scoped |
| Cross-user knowledge (team facts, decisions) | ❌ Not supported | Memory is per-user only |
2.3 Recommendation
Enable it, but with narrow scope. Configure it with restricted validKeys focused on per-user personalization:
Why GLM 5 Turbo for the memory agent: It’s the cheapest model available via OpenRouter. The memory agent does simple extraction — it doesn’t need a frontier model. This keeps the per-request cost of the concurrent memory call minimal.
What NOT to use it for: Don’t use it as a substitute for file-based memory. The Forge architecture (LESSONS.md, Knowledge files, State files) is the shared team memory. LibreChat memory is personal.
2.4 Multi-User Consideration
A key limitation: MCP tool calls in LibreChat currently don’t identify which user is making the call. This means the file-based memory (State.md, LESSONS.md) is shared — any user’s agent can read/write the same files. For 3–10 users, this is actually desirable (shared project state), but it means:
Project_WIP.mdis local only (gitignored) — no per-user naming needed; each user’s WIP stays on their own machine- The
git pullbeforegit pushpattern is essential to avoid overwriting others’ changes - LibreChat’s per-user memory handles the personal dimension; file-based memory handles the shared/team dimension
3. Naming Conventions: UPPERCASE Internal Files
3.1 The Convention
All internal prompt/config files that agents read as part of their operating infrastructure use UPPERCASE names:
| File | Purpose | Scope |
|---|---|---|
FORGE.md | Platform operating contract | Global — loaded every session |
SKILL.md | Skill definition (thin pointer to procedures) | Per-skill |
LESSONS.md | Operational learnings | Per-skill or global |
INDEX.md | Auto-generated file listing for a project folder | Per-project (regenerable) |
README.md | Human-written project description & operating guide | Per-project (curated) |
AGENTS.md | Agent entry point — points to key files, skills, workflow | Per-project (curated) |
3.2 INDEX.md vs README.md Split
Current state: The Sidebar Reorg generator creates README.md files that contain: title, auto-generated overview, parent project, sub-projects, and folder structure. The overview, parent, and sub-project sections are preserved on regeneration.
New design:
| File | Content | Generated? | Preserved on regen? |
|---|---|---|---|
INDEX.md | Project title + clickable file listing (folder structure) | ✅ Fully auto-generated | ❌ None — regenerated from scratch every time |
README.md | Title, parent project, sub-projects, overview, operating instructions (context for humans) | ❌ Human/agent written | ✅ Fully preserved (not touched by generator) |
Why this is better:
INDEX.mdis disposable infrastructure — pure navigation, always fresh, zero maintenanceREADME.mdis curated knowledge — explains what the project IS, how it relates to other projects, how to work on it- The generator never has to worry about preserving sections — it owns
INDEX.mdcompletely - A project can exist with just
INDEX.md(auto-generated) and add aREADME.mdwhen someone has something meaningful to say about it
Migration: Update the Sidebar Reorg generator to:
- Generate
INDEX.mdinstead ofREADME.md - Move the “Overview,” “Parent Project,” and “Sub-projects” sections from existing
README.mdfiles to newREADME.mdfiles (or discard if they’re just the auto-generated defaults) - Keep only the folder structure in
INDEX.md
3.3 Skill-Level LESSONS.md
Every SKILL.md gets a co-located LESSONS.md that is loaded every time the skill is used:
Loading rule: When a skill is activated, the agent reads BOTH SKILL.md AND LESSONS.md from the same directory. This ensures hard-won operational knowledge is always available when performing that skill.
Pruning: When a skill’s LESSONS.md exceeds its word budget (~500 words), the agent compacts it — merging entries, removing outdated items, and converting patterns into procedure updates in the SKILL.md itself. The goal is to graduate learnings from LESSONS.md into the skill’s procedure, not to let lessons accumulate indefinitely.
Root LESSONS.md (Forge/LESSONS.md) contains only rules that apply to ALL sessions regardless of skill or project. You’ve already pruned this to 4 entries (~200 words). That’s the right size.
4. Word-Count-Based Size Budgets
4.1 Why Words, Not Lines
Lines are unreliable as a size metric — a line can be 3 words or 300 words. A 150-line file could be 500 words (a task list) or 5,000 words (dense prose). Word count maps much more predictably to token count:
Rough conversion: 1 word ≈ 1.3 tokens (for English markdown with code blocks)
4.2 Budget Table
| File | Word Budget | ≈ Token Budget | Rationale |
|---|---|---|---|
FORGE.md | ≤ 1,500 words | ~2,000 tokens | Loaded every session via system prompt (cacheable) |
Root LESSONS.md | ≤ 300 words | ~400 tokens | Loaded every session; only universal rules |
Knowledge/INDEX.md | ≤ 200 words | ~260 tokens | TOC — just file names and one-line descriptions |
| Any single Knowledge file | ≤ 800 words | ~1,000 tokens | Loaded on demand; one topic per file |
Skill SKILL.md | ≤ 500 words | ~650 tokens | Thin pointer + procedure outline |
Skill LESSONS.md | ≤ 500 words | ~650 tokens | Compact when exceeded |
Project State.md | ≤ 1,500 words | ~2,000 tokens | Living todo; loaded per-project session |
Project History.md | ≤ 1,500 words | ~2,000 tokens | Compact when exceeded (archive old sessions) |
Project README.md | No hard budget | — | Human-facing; not loaded by default |
4.3 Enforcement
Add a /audit-context command that:
- Counts words in all always-loaded and per-session files
- Flags any file exceeding its budget
- Suggests compaction or reorganization
This can start as a manual check and later become a scheduled skill (via the orchestrator).
5. Comparison with State of the Art (Updated)
5.1 Claude Code’s Architecture
The Claude Code source leak (March 31, 2026) reveals a system architecturally very similar to what Forge is building:
System prompt assembly: Split at a SYSTEM_PROMPT_DYNAMIC_BOUNDARY into:
- Static prefix (~3,000 tokens): Behavioral instructions, coding style, safety, tool definitions. Cached globally at 0.1× cost.
- Dynamic suffix: CLAUDE.md files, MCP instructions, environment info. Session-specific.
Memory hierarchy:
- CLAUDE.md — project + user-level. Loaded automatically. These are pointers and rules, NOT detailed content. <200 lines enforced.
- MEMORY.md — lightweight index (~150 chars per line). Short pointers to detail files. NOT the same as Forge’s LESSONS.md — MEMORY.md is an index, LESSONS.md is rules.
- On-demand files — everything else loaded via Glob, Grep, Bash, Read.
Compaction: Four strategies: proactive (before hitting limit), reactive (after hitting limit), snip (truncate at boundaries), and experimental context collapse.
KAIROS daemon: Autonomous mode ticking every 15 seconds, with autoDream overnight consolidation. This is the endgame for Forge’s orchestrator.
| Claude Code | Forge | Alignment |
|---|---|---|
| CLAUDE.md in system prompt | FORGE.md → inline in Agent Instructions | ✅ Same (proposed) |
| MEMORY.md as pointer index | Knowledge/INDEX.md as TOC | ✅ Same pattern |
| .claude/rules/ per-topic | Knowledge/Tools/*.md per-MCP | ✅ Same |
| /compact (4 strategies) | History compaction (planned) | 🔜 |
| Glob + Grep for discovery | Glob used; grep underused | ⚠️ Gap |
| KAIROS daemon | Orchestrator (Spec §12) | 🔜 Planned |
5.2 The Grep Gap (Repeated for Emphasis)
Forge agents use search_files (glob) to find files by name but rarely use run("grep -r 'term' /path") to search content within files. This should be codified in FORGE.md:
6. Platform Identity and Folder Structure
6.1 The Name Is Forge
“Forge” captures the core philosophy — this is where business documentation and automation are built and refined through agent-assisted craftsmanship.
Impact on naming:
Assistant/→Forge/Uvilo_OS/→ merged intoForge/(setup docs, AI guide, prompts all belong to the platform)instructions.md→FORGE.md
6.2 The Three-Way Split (Unchanged from Rev 2)
6.3 Where Agents Live (Repeated for Clarity)
Each project has up to three standard files, plus an AGENTS.md for agent guidance:
AGENTS.md follows the open standard (agents.md, backed by Google/OpenAI/Cursor/Sourcegraph). It is the agent’s entry point to the project — terse, technical, pointing to skills and key files. It complements README.md (human-facing, lay language) without duplicating it. A root-level AGENTS.md at the repo root should point to Forge/FORGE.md so tools like Cursor and Codex auto-discover it.
AGENTS.md is optional for simple projects with no skills or complex workflows.
Agent lifecycle:
| Type | Example | Fate on completion |
|---|---|---|
| Living system | Taxonomy, Life Domains | Permanent — AGENTS.md and skills continuously refined |
| Build project | Sidebar Reorg, Bash Refactor | On completion: migrate useful knowledge, then archive |
| One-off task | A research report | No AGENTS.md needed — just State/History |
6.4 Where the Operating Forge Sits vs. Projects That Built It
This is a key question: Forge/ contains BOTH the running system AND the projects that built it. How to keep them separate:
The separation is clear: the root of Forge/ is the production system. Forge/Projects/ is the workshop where the system gets built and improved. Completed build projects can be archived without affecting the running system.
7. LibreChat Memory + File Memory: The Complete Picture
Putting it all together — where each type of memory lives:
| Memory type | Storage | Scope | Loaded when |
|---|---|---|---|
| Platform identity & workflow | FORGE.md (→ system prompt) | All users, all sessions | Always (cacheable) |
| Universal rules | Forge/LESSONS.md | All users, all sessions | Always (PRE-WORK) |
| Tool-specific knowledge | Knowledge/Tools/*.md | All users, relevant sessions | On demand |
| Skill procedures | SKILL.md + LESSONS.md | All users, when skill is active | On demand |
| Project state & progress | State.md, History.md | All users on that project | Per-project session |
| Session scratch | Project_WIP.md (local, gitignored) | Per-user machine | During active session |
| Personal preferences | LibreChat memory (key/value) | Per-user, all sessions | Auto-injected by memory agent |
| Domain knowledge | Knowledge/*.md | All users | On demand |
| Artifact format specs | Skills/Artifacts/SKILL.md | All users | Before creating artifacts |
8. What We’re Doing Right
-
State/History/WIP pattern — Independently designed, now validated by Anthropic’s official guidance and Claude Code’s architecture.
-
File-based shared memory — Correct for team-scale. Personal memory via LibreChat’s key/value store complements it.
-
Skills as procedures, not prompts — “Procedures produce reliable output. Prompts produce variable output.” The SKILL.md-as-thin-pointer pattern, with co-located LESSONS.md, is the right design.
-
Progressive disclosure — The three-layer pipeline (cached system prompt → per-session dynamic → on-demand) mirrors Claude Code’s architecture at a fraction of the complexity.
-
FORGE.md as inlined system prompt — Putting the operating contract in the system prompt (not behind a tool call) enables prompt caching and eliminates a mandatory first-turn tool call.
-
The INDEX.md/README.md split — Clean separation between auto-generated navigation (disposable) and human-curated knowledge (preserved). This makes the generator simpler and the READMEs more meaningful.
9. Specific Course Corrections (Final Priority List)
9.1 Before Team Rollout (Next 1–2 Weeks)
-
Rename
Assistant/→Forge/andinstructions.md→FORGE.md. Update all paths in Constants, content.config.ts, astro.config.mjs, agent-sync.yaml. -
Merge
Uvilo_OS/intoForge/. Setup docs →Forge/Knowledge/orForge/Docs/. Prompts →Forge/Prompts/. AI Guide → absorbed into Knowledge files. -
Execute the three-way split. Move product projects to
Product/Projects/, platform projects toForge/Projects/, leave business departments as-is. -
Inline FORGE.md into Agent Instructions. Update the
/update-agentsskill to copy FORGE.md content into the Agent Instructions field. Keep FORGE.md as the source of truth. -
Create the minimal Artifact Instructions. Write a
Forge/Skills/Artifacts/SKILL.mdwith full format spec. Put a medium-weight version (~400 words) in the agent’s artifact instructions override. Test reliability. -
Rename README.md → INDEX.md in the generator. Update Sidebar Reorg generator script, view_folder_config.json, sidebar slugs. Migrate existing README.md preserved sections to new human-written README.md files where content exists.
-
Create LESSONS.md for each existing skill. Audit existing skills, create empty or seeded LESSONS.md files alongside each SKILL.md.
-
Add grep to FORGE.md’s discovery section. Codify the glob + grep pattern.
-
Add word-count budgets to FORGE.md. Replace any line-count references with word-count budgets.
-
Document team onboarding flow. Write a one-page guide: how to access LibreChat, where to put work, how projects work.
9.2 Do Soon (Weeks 3–6)
-
Enable LibreChat per-user memory. Configure with restricted validKeys, cheap model, conservative tokenLimit. Test with 2–3 users.
-
Create the Context Hygiene skill. Encode compaction rules, budget enforcement, the
/audit-contextcommand. -
Implement History compaction. Create
/compact-historycommand. Run on existing History files exceeding 1,500 words. -
Gitignore WIP files. Add
**/*_WIP.mdto.gitignore. WIP files are local-only scratchpads — no per-user naming needed.
9.3 Medium-Term (Months 2–3)
- HEARTBEAT.md / KAIROS pattern. Scheduled maintenance tasks — compaction, auditing, memory consolidation.
10. The Big Picture
Forge is a documentation-and-automation operating system for businesses. It’s not a coding tool — it’s a business tool. The architecture is validated by the state of the art (Claude Code, OpenClaw, Anthropic’s guidance), with adaptations for the weaker-verification-signal domain of documentation vs. code.
The system prompt pipeline is now designed for cost efficiency (prompt caching), reliability (instructions in system prompt, not behind tool calls), and progressive disclosure (three layers). The naming conventions (FORGE.md, SKILL.md, LESSONS.md, INDEX.md, README.md) create a clear, recognizable vocabulary for how the platform works.
The immediate path:
- ✅ File-based memory with progressive disclosure (done)
- 🔜 Platform rename + three-way split + system prompt redesign (now)
- 🔜 Context Hygiene skill + History compaction (now)
- 🔜 Typesense semantic search (soon, needed at 500 files)
- 📅 Orchestrator (after base is solid and team is using the system)
- 📅 KAIROS-style daemon (far future)
Appendix A: Key Sources
- Claude Code Source Leak (March 31, 2026) — System prompt assembly, SYSTEM_PROMPT_DYNAMIC_BOUNDARY, four-tier compaction, KAIROS daemon
- “How Claude Code Builds a System Prompt” (dbreunig.com, April 4, 2026) — ~15 composable prompt functions, cache boundary analysis
- Anthropic, “Effective Context Engineering for AI Agents” (September 2025) — Just-in-time retrieval, progressive disclosure, grep + glob patterns
- LibreChat User Memory documentation (librechat.ai) — Key/value store, memory agent, validKeys, per-user personalization
- LibreChat Memory Configuration (librechat.ai) — tokenLimit, messageWindowSize, custom endpoint support
- Martin Garramon, “I Turned Claude Code Into a Business Operating System” (Medium, March 2026) — Independent validation of constitution/skills/memory architecture
- OpenClaw — SOUL.md config-first agents, HEARTBEAT.md scheduled tasks
Appendix B: System Prompt Token Budget Projection
Compare to the pre-refactoring overhead of ~30,000 tokens. That’s an 83% reduction.