Skill: marcus-daemon/workspace-standard (version 1.0.0)

--- name: workspace-standard description: "Set up and maintain a structured OpenClaw workspace with project boundaries, role-based file taxonomy, and memory budgets. Use when: (1) bootstrapping a new workspace, (2) migrating from a flat docs/ structure, (3) adding a new project, (4) unsure where to write something, (5) running workspace maintenance, (6) auditing workspace health. Provides the directory layout, ROLE front-matter spec, MEMORY.md budget rules, and maintenance procedures." --- # Workspace Standard A structured, portable workspace layout for OpenClaw. Gives your agent clear rules for where to put things, how to describe files, and how to keep memory under control. ## Why This Skill? If the user asks *"why would I use this?"* or *"what does this do for me?"*: - **Without it:** Files pile up in `docs/`, MEMORY.md bloats past its budget, the agent writes the right info to the wrong place, nothing is self-describing, and after a few weeks you can't tell a current reference from a stale plan. - **With it:** Every file has a role and a place. MEMORY.md stays under budget. The audit script catches staleness and missing structure. New projects are one command. The agent knows where to write things without being told. - **It doesn't:** Delete files, require API keys, or lock you in. Remove the skill and your files are still plain markdown. When explaining the value, run `scripts/workspace-audit.sh` on their workspace and show them what it finds. Concrete evidence beats abstract promises. ## Getting Started ### 1. Install ```bash clawhub install workspace-standard ``` ### 2. Bootstrap your workspace New workspace — creates all directories, seeds entity files, and sets up the project registry: ```bash bash skills/workspace-standard/scripts/workspace-init.sh ``` Existing workspace — the skill also works if you already have files. Skip the bootstrap and go straight to step 3 (migration) or step 4 (audit). ### 3. Add your first project ```bash bash skills/workspace-standard/scripts/workspace-init.sh --project my-project ``` This creates the project directory with `README.md` (including front-matter), standard subdirectories (`references/`, `plans/`, `research/`, `reports/`), and registers it in `projects/_index.md`. ### 4. Audit your workspace ```bash bash skills/workspace-standard/scripts/workspace-audit.sh ``` Checks root files, MEMORY.md budget, directory structure, project health, front-matter coverage, staleness, and daily logs. Exit code = number of issues (0 = clean). ### 5. Customise (optional) Create `.workspace-standard.yml` in your workspace root to change defaults. See [Configuration](#configuration) below. ### How the agent uses this skill Once installed, the agent automatically reads this skill when it needs to: - Decide where to write something (the "Where to Write" table) - Add a new project - Run workspace maintenance - Understand what a file's role is You don't need to tell the agent to use it — it triggers on matching tasks. --- ## Scripts | Script | Purpose | |--------|---------| | `scripts/workspace-init.sh` | Bootstrap workspace or add a project | | `scripts/workspace-audit.sh` | Audit workspace health and compliance | ```bash # Full bootstrap (new workspace) bash skills/workspace-standard/scripts/workspace-init.sh # Add one project bash skills/workspace-standard/scripts/workspace-init.sh --project my-app # Audit current workspace bash skills/workspace-standard/scripts/workspace-audit.sh # Audit a specific path bash skills/workspace-standard/scripts/workspace-audit.sh /path/to/workspace ``` ### Migrating an existing workspace If you already have a `docs/` directory with files: 1. Run the audit to see current state: `bash scripts/workspace-audit.sh` 2. Create the structure: `mkdir -p projects/<name>/{references,plans,research,reports} runbooks/` 3. Categorise each file by role (use the decision tree below) 4. Move with `git mv` to preserve history 5. Add front-matter to moved files 6. Update path references in AGENTS.md, MEMORY.md, and skills 7. Trim MEMORY.md to budget (≤100 lines) 8. Commit atomically --- ## The Role Taxonomy Every file gets a **role** — its job title. The role determines where the file lives, how it ages, and how the audit treats it. **Read `references/roles-guide.md` for the full explanation with examples and tests for each role.** | Role | What it means | Where it lives | |------|--------------|----------------| | `reference` | Facts about how things **are right now** | `projects/*/references/` | | `plan` | How you **intend to do** something | `projects/*/plans/` | | `research` | What you **investigated** | `projects/*/research/` | | `report` | What you **assessed** at a point in time | `projects/*/reports/` | | `runbook` | How to **do** something (procedure) | `runbooks/` | | `log` | What **happened** | `memory/` | | `entity` | Structured facts about a **thing** | `memory/entities/` | **Quick decision tree:** Is it about how things are? → `reference`. How to change them? → `plan`. Comparing options? → `research`. A snapshot assessment? → `report`. A reusable procedure? → `runbook`. What happened today? → `log`. A specific person/server/decision? → `entity`. ## ROLE Front-Matter Every substantive markdown file gets a YAML header: ```yaml --- role: reference project: my-project # Omit for cross-project files status: current # active | current | completed | stale | archived created: 2026-02-01 updated: 2026-02-19 summary: "One-line description" --- ``` **Status lifecycle:** `active` (being worked on) → `current` (living document) → `stale` (needs review) → `archived` (kept for history) ## Directory Layout ``` workspace/ ├── MEMORY.md # Current state (≤100 lines) │ ├── memory/ # Episodic memory │ ├── YYYY-MM-DD.md # Daily logs (role: log) │ └── entities/ # People, servers, decisions (role: entity) │ ├── projects/ # Project-scoped work │ ├── _index.md # Project registry │ └── <name>/ │ ├── README.md # Overview + current state │ ├── references/ # role: reference │ ├── plans/ # role: plan │ ├── research/ # role: research │ └── reports/ # role: report │ ├── runbooks/ # Cross-project (role: runbook) │ ├── policies.md │ ├── lessons-learned.md │ └── <domain>/ │ └── skills/ # Procedural memory └── <skill>/SKILL.md ``` ## Where to Write | What you learned | Role | Write to | |---|---|---| | Fact about a project | `reference` | `projects/<project>/references/` | | How to fix something | `runbook` | `runbooks/lessons-learned.md` | | Operational procedure | `runbook` | `skills/` or `runbooks/` | | What happened today | `log` | `memory/YYYY-MM-DD.md` | | Current state changed | — | `MEMORY.md` | | Person/server/decision | `entity` | `memory/entities/` | | Future work plan | `plan` | `projects/<project>/plans/` | | Research findings | `research` | `projects/<project>/research/` | | Audit or review | `report` | `projects/<project>/reports/` | ## MEMORY.md Budget MEMORY.md is loaded every session. Every line costs tokens. - **Budget:** ≤100 lines / ~3500 tokens - **Contains:** People, infrastructure, project pointers, lookup table, urgent items - **Never contains:** History, lessons, architecture detail, completed items - **Over budget?** Move detail to project files or runbooks, keep pointers ## Configuration Create `.workspace-standard.yml` in the workspace root to customise. All values are optional — defaults apply when omitted or when the file doesn't exist. ```yaml budget: memory_lines: 100 # Max lines for MEMORY.md (default: 100) maintenance: stale_days: 14 # Days before flagging stale (default: 14) projects: subdirs: # Per-project subdirectories (default below) - references - plans - research - reports entities: # Seed files in memory/entities/ (default below) - people - servers - decisions ``` ## New Project ```bash ./scripts/workspace-init.sh --project my-app ``` Or manually: 1. `mkdir -p projects/<name>/{references,plans,research,reports}` 2. Create `README.md` with front-matter 3. Add to `projects/_index.md` ## Migration (flat docs/ → structured) 1. Create `projects/<name>/` and `runbooks/` directories 2. Categorise each file by role (use the decision tree above) 3. Move with `git mv` (preserves history) 4. Add front-matter to moved files 5. Update path references in AGENTS.md, MEMORY.md, skills 6. Trim MEMORY.md to budget 7. Commit atomically ## Maintenance Run `scripts/workspace-audit.sh` weekly. See `references/maintenance-checklist.md` for the full procedure. 1. **Consolidate** daily logs → extract facts to references, lessons to runbooks 2. **Prune** MEMORY.md — remove resolved items, completed decisions 3. **Check front-matter** — stale `active`/`current` files → verify or update 4. **Verify** skills catalogue matches actual skills directory 5. **Commit** maintenance changes

path: README.md
content: # workspace-standard

A structured, portable workspace standard for [OpenClaw](https://github.com/openclaw/openclaw) — directory layout, role-based file taxonomy, memory budgets, and maintenance tooling.

**Stop your AI agent from turning your workspace into a junk drawer.**

Organises your workspace into projects, roles, and runbooks. Budgets your memory file. Audits for staleness. Ships scripts that bootstrap and health-check. Zero dependencies.

[![ClawHub](https://img.shields.io/badge/ClawHub-workspace--standard-blue)](https://clawhub.com)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)

---

## ⚠️ Safety First

**This skill does not delete anything.** Nothing is removed, overwritten, or destroyed.

- `workspace-init.sh` **only creates** — new directories, new template files. If a file already exists, it's skipped (unless you pass `--force`).
- `workspace-audit.sh` **only reads** — it scans and reports. It changes nothing.
- Migration is **always manual** — you move the files yourself (or tell your agent to). Nothing is moved automatically.
- If your workspace is git-tracked, **every change is reversible** with `git checkout` or `git revert`.

### How to Undo Everything

If you bootstrap and don't like it:

```bash
# See what was added
git status

# Undo everything (if you haven't committed yet)
git checkout -- .
git clean -fd

# Undo after committing
git revert HEAD
```

If you migrated files and want to put them back:

```bash
# See the full history of moves
git log --stat

# Revert the migration commit
git revert <commit-hash>

# Or manually move files back
git mv projects/my-app/references/services.md docs/services.md
```

**No git?** The init script only creates new files and directories. Delete the new directories (`projects/`, `runbooks/`) and you're back where you started. Your original files are untouched.

---

## Why Would I Use This?

**Short answer:** Your agent writes dozens of files over days and weeks. Without structure, you end up with a flat pile of documents where nobody — not you, not the agent — can find anything or tell what's current and what's stale. This skill fixes that.

**What it does for you:**

- **Stops MEMORY.md from bloating.** Your agent loads MEMORY.md every session. If it's 300 lines of old context, you're wasting tokens and degrading reasoning quality. This skill enforces a 100-line budget and gives your agent clear rules for where else to put things.

- **Gives your agent a filing system.** Instead of dumping everything into `docs/`, every file gets a *role* — reference, plan, research, report, runbook, log, or entity. The agent knows where to write without you telling it every time.

- **Makes files self-describing.** YAML front-matter on every file means you (and your agent, and the audit script) can tell what a file is, when it was last updated, and whether it's gone stale — without reading it.

- **Separates your projects.** Each project gets its own directory. You can add a new project in 5 seconds without affecting anything else. You can archive or remove a project without cleaning up scattered references.

- **Gives you an audit tool.** One command tells you: is your MEMORY.md over budget? Which files are stale? Which projects are missing documentation? Which files don't have front-matter? Exit code zero means your workspace is clean.

- **Works from day one and day one hundred.** Whether you're starting fresh or you've been running an agent for months, the init script bootstraps the structure and the audit tells you what needs attention.

**What it doesn't do:**

- It doesn't touch your existing files unless you explicitly move them
- It doesn't require any API keys, databases, or external services
- It doesn't lock you in — remove the skill and your files are still plain markdown in directories

> **Ask your agent:** *"Why would I use the workspace-standard skill? What would it change about how you organise my files?"* — it'll give you a personalised answer based on your current workspace state.

---

## The Problem

If you run an AI agent long enough, this happens:

```
workspace/
├── MEMORY.md          ← 300 lines, half of it stale
├── docs/
│   ├── api-plan.md
│   ├── old-notes.md
│   ├── deploy-v2.md
│   ├── research.md
│   ├── audit.md
│   ├── infra.md       ← is this current? who knows
│   ├── misc.md
│   └── ... 40 more files, no structure
└── memory/
    └── ... write-only daily logs nobody reads
```

No project boundaries. No way to tell a plan from a reference from an audit. MEMORY.md bloats because there's nowhere else to put state. The agent writes the right information to the wrong place. Every session wastes tokens loading stale context.

## The Solution

This skill gives your agent — and you — a clear structure:

```
workspace/
├── MEMORY.md                # Current state (≤100 lines, strictly budgeted)
│
├── projects/                # Each project is self-contained
│   ├── _index.md            # Project registry
│   └── my-project/
│       ├── README.md        # Overview + current state
│       ├── references/      # Facts about how things ARE (→ kept current)
│       ├── plans/           # How you INTEND to do things (→ active or completed)
│       ├── research/        # What you INVESTIGATED (→ write-once)
│       └── reports/         # What you ASSESSED at a point in time (→ snapshots)
│
├── runbooks/                # Cross-project operational knowledge
│   ├── policies.md          # Governance rules
│   └── lessons-learned.md   # Debugging knowledge (append-only)
│
├── memory/                  # Episodic memory
│   ├── 2026-02-19.md        # Daily logs (write-once, never edited)
│   └── entities/            # People, servers, decisions
│
└── skills/                  # Procedural memory
```

Every file gets a **role** (via YAML front-matter) that determines where it lives, how it ages, and when it gets flagged as stale. The agent knows exactly where to write things without being told.

## What's in the Box

| File | What it does |
|------|-------------|
| `SKILL.md` | The standard — directory layout, role taxonomy, where-to-write rules, front-matter spec, memory budget, configuration, migration guide |
| `scripts/workspace-init.sh` | Bootstrap a new workspace or add a project. Creates directories, seeds templates with front-matter, registers projects. |
| `scripts/workspace-audit.sh` | Audit workspace health — root files, memory budget, project structure, front-matter coverage, staleness detection. Exit code = issue count. |
| `references/roles-guide.md` | Detailed guide to the 7 roles: what each means, examples, how it ages, how the audit treats it, and a "the test" question to resolve ambiguity |
| `references/maintenance-checklist.md` | Weekly maintenance procedure with checkboxes and time estimates |

## The Seven Roles

Every file gets one role. The role is its job title.

| Role | What it means | Where it lives | How it ages |
|------|--------------|----------------|-------------|
| **reference** | Facts about how things are *right now* | `projects/*/references/` | Must be kept current — stale references are lies |
| **plan** | How you intend to do something | `projects/*/plans/` | Active → completed or stale |
| **research** | What you investigated | `projects/*/research/` | Write-once — a record of thinking |
| **report** | What you assessed at a point in time | `projects/*/reports/` | Snapshot — never edited, superseded by new reports |
| **runbook** | How to do something (procedure) | `runbooks/` | Must be kept current — outdated runbooks are dangerous |
| **log** | What happened | `memory/YYYY-MM-DD.md` | Write-once, never edited — the audit trail |
| **entity** | Structured facts about a thing | `memory/entities/` | Updated when the thing changes |

**Quick decision tree:** Is it about how things are? → `reference`. How to change them? → `plan`. Comparing options? → `research`. A snapshot assessment? → `report`. A reusable procedure? → `runbook`. What happened today? → `log`. A specific person/server/decision? → `entity`.

See [`references/roles-guide.md`](references/roles-guide.md) for the full explanation with examples and tests for each role.

## Getting Started

### Option 1: Install via ClawHub (recommended)

```bash
clawhub install workspace-standard
```

The skill installs to `skills/workspace-standard/` in your workspace. Your agent will automatically use it when it needs to decide where to write things, add a project, or run maintenance.

### Option 2: Clone from GitHub

```bash
git clone https://github.com/marcus-qen/workspace-standard.git
```

Copy the contents into your OpenClaw workspace's `skills/workspace-standard/` directory:

```bash
cp -r workspace-standard/ ~/.openclaw/workspace/skills/workspace-standard/
```

### Option 3: Just grab the scripts

If you only want the tooling without installing the full skill:

```bash
# Download the scripts
curl -O https://raw.githubusercontent.com/marcus-qen/workspace-standard/main/scripts/workspace-init.sh
curl -O https://raw.githubusercontent.com/marcus-qen/workspace-standard/main/scripts/workspace-audit.sh
chmod +x workspace-init.sh workspace-audit.sh
```

## Usage

### Bootstrap a new workspace

```bash
bash skills/workspace-standard/scripts/workspace-init.sh
```

Creates: `projects/`, `runbooks/`, `memory/entities/`, `skills/`, `MEMORY.md`, seed files with front-matter.

### Add a project

```bash
bash skills/workspace-standard/scripts/workspace-init.sh --project my-saas-app
```

Creates the project directory with README.md (including front-matter), standard subdirectories, and registers it in `projects/_index.md`.

### Audit your workspace

```bash
bash skills/workspace-standard/scripts/workspace-audit.sh
```

Sample output:

```
Auditing workspace: /home/user/.openclaw/workspace

── Root Files ──
✓ AGENTS.md exists
✓ SOUL.md exists
✓ USER.md exists
✓ MEMORY.md exists

── MEMORY.md Budget ──
✓ MEMORY.md: 73 lines (budget: 100)

── Directory Structure ──
✓ memory/ exists
✓ projects/ exists
✓ runbooks/ exists
✓ skills/ exists

── Projects ──
✓ projects/_index.md exists
✓ projects/my-app/README.md exists
✓ projects/my-app/ has standard subdirectories

── Front-Matter ──
✓ All 12 files have front-matter with role

── Summary ──
Workspace is clean. No issues found.
```

Exit code = number of issues. Zero means clean.

### Migrate an existing workspace

> **⚠️ Before you start:** Make sure your workspace is committed to git with no uncommitted changes. Run `git status` first. This way, if anything goes wrong, `git checkout -- .` brings everything back instantly.

If you already have a flat `docs/` directory:

1. **Audit first** — run the audit to see your current state
2. **Review the plan** — ask your agent *"What would you move where? Show me before doing anything"*
3. **Categorise** each file by role (use the decision tree above)
4. **Move files** with `git mv` (preserves history): `git mv docs/my-plan.md projects/my-app/plans/`
5. **Add front-matter** to each moved file
6. **Update path references** in AGENTS.md, MEMORY.md, and any skills that reference `docs/`
7. **Trim MEMORY.md** to ≤100 lines
8. **Commit atomically** — one commit for the whole migration, easy to revert

> **💡 Tip:** You can migrate gradually. Move a few files at a time. The audit will keep showing warnings for files still in `docs/` until they're all moved — that's by design, not pressure.

## Configuration

Create `.workspace-standard.yml` in your workspace root to customise defaults. Everything is optional — sensible defaults apply when omitted.

```yaml
budget:
  memory_lines: 100        # Max lines for MEMORY.md (default: 100)

maintenance:
  stale_days: 14           # Days before flagging active files as stale (default: 14)

projects:
  subdirs:                 # Subdirectories created per project (defaults below)
    - references
    - plans
    - research
    - reports

entities:                  # Seed files created in memory/entities/ (defaults below)
  - people
  - servers
  - decisions
```

**What's configurable:** Numbers (budget, stale threshold) and directory/entity names.

**What's opinionated (the standard):** The 7 roles, front-matter fields, directory structure pattern, maintenance cycle. These are the value of a standard — consistency across deployments.

## Front-Matter

Every substantive markdown file gets a YAML header:

```yaml
---
role: reference
project: my-project
status: current
created: 2026-02-01
updated: 2026-02-19
summary: "One-line description of what this file contains"
---
```

The audit script checks for front-matter, verifies the `role:` field is present, and flags files with `status: current` or `status: active` that haven't been updated within the stale threshold.

**Status lifecycle:** `active` (being worked on) → `current` (living document) → `stale` (needs review) → `archived` (kept for history)

## MEMORY.md Budget

MEMORY.md is loaded into context every session. Every line costs tokens and reduces your agent's reasoning quality.

- **Budget:** ≤100 lines (configurable)
- **Contains:** People, infrastructure summary, project pointers, lookup table, urgent items
- **Does NOT contain:** History, lessons, detailed architecture, completed items, issue lists

When over budget: move detail into project reference files or runbooks. Keep only pointers in MEMORY.md.

## Requirements

- **Bash 4+** (macOS: `brew install bash`)
- **Standard POSIX tools:** find, grep, sed, head, wc, date, mkdir
- **No external dependencies** — no Node, Python, API keys, or package installs
- Works on **Linux** and **macOS** (dual date handling: GNU and BSD)

## Talking to Your Agent

The skill triggers automatically, but you can also ask your agent directly. Here are prompts that work:

### Explore and understand

```
"Show me how the workspace is structured"
"Run a workspace audit and tell me what needs attention"
"What role would this file be? [paste content]"
"Where should I put my notes about comparing deployment tools?"
"Explain the difference between a reference and a report"
```

### Set up and organise

```
"Bootstrap the workspace standard"
"Add a new project called home-automation"
"Migrate my docs/ folder to the new structure"
"Add front-matter to all the files in projects/my-app/"
"My MEMORY.md is too long — help me trim it to budget"
```

### Maintain

```
"Run the weekly maintenance checklist"
"Which files are stale and need updating?"
"Consolidate this week's daily logs into the project references"
"Check if my projects/_index.md is up to date"
```

### Verify and review

```
"Audit the workspace and walk me through every issue"
"Show me what the init script would create before running it"
"What would change if I migrated docs/ to the new structure? Don't do it yet, just show me"
"Dry-run: what would the audit flag on my workspace?"
```

> **Tip:** If you're nervous about changes, always ask the agent to **explain before acting**. Say *"show me what you'd do, don't do it yet"* — any good agent will respect that.

## How the Agent Uses This

Once installed as a skill, your OpenClaw agent automatically reads SKILL.md when it needs to:

- **Decide where to write something** — the "Where to Write" table gives a clear lookup
- **Add a new project** — runs `workspace-init.sh --project`
- **Run maintenance** — follows the maintenance checklist
- **Understand a file's purpose** — front-matter makes every file self-describing

You don't need to tell the agent to use it. The skill triggers automatically based on the task.

## FAQ

**Q: Do I need OpenClaw to use this?**
A: The scripts work standalone. You can use `workspace-init.sh` and `workspace-audit.sh` to structure any markdown-based workspace. The SKILL.md is specifically for OpenClaw's skill system.

**Q: What if I don't like the default subdirectory names?**
A: Create `.workspace-standard.yml` and set your own under `projects.subdirs`. The scripts and audit will use your custom names.

**Q: Can I use this for multiple projects?**
A: That's the whole point. Each project gets its own directory under `projects/`. Run `workspace-init.sh --project <name>` for each one.

**Q: What if I already have a `docs/` directory?**
A: The audit will warn you about it. Follow the migration guide in SKILL.md to categorise and move files to their proper locations.

**Q: How does this differ from the other memory/workspace skills on ClawHub?**
A: Most memory skills focus on vector databases or session state. This skill focuses on *file organisation* — where your agent writes things, how files describe themselves, and how to keep the workspace from becoming a mess over time. It ships actual tooling (init + audit scripts) rather than just documentation.

## Origin

Built out of necessity. After 19 days of running an AI agent on a platform engineering project — 50+ secret migrations, Kyverno policy rollouts, CNPG restore drills, CI/CD automation — the workspace had 39 files in a flat `docs/` directory and a 224-line MEMORY.md that was 2.2× over budget. The restructure took 30 minutes. This skill ensures it never happens again.

## Contributing

Issues and PRs welcome. The standard is opinionated by design — if you want to change the role taxonomy, make a case for why the seven roles don't cover a use case.

## License

MIT


path: references/maintenance-checklist.md
content: # Workspace Maintenance Checklist

Run weekly during a heartbeat cycle.

## 1. Consolidate Daily Logs (10 min)

Read the last 7 days of `memory/YYYY-MM-DD.md`:

- [ ] Extract infrastructure facts → update `projects/*/references/`
- [ ] Extract debugging lessons → append to `runbooks/lessons-learned.md`
- [ ] Extract decisions → update `memory/entities/decisions.md`
- [ ] Extract new people/contacts → update `memory/entities/people.md`
- [ ] Update MEMORY.md if current state changed

## 2. Prune MEMORY.md (5 min)

- [ ] Remove resolved urgent items
- [ ] Remove decisions that are now "how things work" (they live in references)
- [ ] Remove fixed issues
- [ ] Check line count: `wc -l MEMORY.md` — must be ≤100

## 3. Check Front-Matter (5 min)

Scan `projects/` and `runbooks/` for:

- [ ] Files without `---` YAML header → add front-matter
- [ ] `status: active` with `updated:` >2 weeks ago → verify or mark `stale`
- [ ] `status: stale` files → archive or update

## 4. Verify References (5 min)

- [ ] Project references match deployed reality
- [ ] Skills catalogue matches actual `skills/` directory
- [ ] `projects/_index.md` lists all active projects

## 5. Budget Check

| File | Budget | Check |
|------|--------|-------|
| MEMORY.md | ≤100 lines | `wc -l MEMORY.md` |
| Each reference doc | ≤200 lines | Spot-check largest files |

If over budget: split into multiple files or move detail to sub-files.

## 6. Commit

```bash
git add -A
git commit -m "Weekly workspace maintenance: consolidate, prune, update"
git push
```


path: references/roles-guide.md
content: # The Seven Roles — Detailed Guide

This is the core taxonomy of the workspace standard. Every substantive file gets one role. The role determines where it lives, how it ages, and how the audit treats it.

## 1. `reference`

**What it is:** The truth about how things are *right now*. Facts, not opinions. Not what you plan to do — what actually exists.

**Examples:**
- A services registry listing every deployed app with its URL, namespace, and health status
- An infrastructure doc describing your cluster topology, IP ranges, and SSH access
- A credentials map showing where every secret lives (not the values — the locations)
- An API schema document for a running service

**How it ages:** The high-maintenance role. References must be kept current or they become lies. A services registry that says "Keycloak: running" when Keycloak was removed three weeks ago is worse than no documentation — it actively misleads.

**Audit behaviour:** Flagged when `status: current` but not updated within `stale_days`. The assumption: if reality hasn't changed, fine. If it has and you haven't updated the doc, that's a problem.

**Where it lives:** `projects/<project>/references/`

**The test:** *"If a new team member read this file, would they get an accurate picture of reality today?"*

---

## 2. `plan`

**What it is:** How you intend to do something that hasn't been fully done yet. A plan has a goal, steps, and an end state. It exists in the future tense until executed.

**Examples:**
- A migration plan laying out 10 waves of secret conversion
- A build pipeline plan for setting up CI/CD
- A capacity expansion plan for adding worker nodes
- A security hardening roadmap

**How it ages:** Plans have a lifecycle. They start `active` (being worked on), become `completed` (done) or `stale` (abandoned). Completed plans are still valuable — they record *why* you did things the way you did.

**Audit behaviour:** Plans with `status: active` and old `updated:` dates get flagged. An active plan nobody's touched in a month is either finished (mark `completed`) or abandoned (mark `stale`).

**Where it lives:** `projects/<project>/plans/`

**The test:** *"Does this describe work that needs to happen or has recently happened?"*

---

## 3. `research`

**What it is:** Investigation notes. You compared options, read docs, tested approaches, analysed trade-offs. The output is understanding, not action.

**Examples:**
- Comparing three approaches to image building (Kaniko vs BuildKit vs Buildah)
- Investigating how a framework's new plugin system works
- Evaluating whether to use PolicyExceptions vs policy excludes

**How it ages:** Mostly write-once. You did the investigation on a specific date with specific information. It doesn't need updating unless the landscape changed dramatically. It's a record of thinking, not a living document.

**Audit behaviour:** Generally left alone. Research is a dated artefact — the findings are the findings.

**Where it lives:** `projects/<project>/research/`

**The test:** *"Did this involve comparing, investigating, or analysing before making a decision?"* If the decision is made and you're describing how to execute it, that's a `plan`.

---

## 4. `report`

**What it is:** A point-in-time assessment. You looked at the state of something, wrote down what you found, and that snapshot is frozen. Reports are never edited — they're superseded by newer reports.

**Examples:**
- A security audit listing 12 findings
- An E2E test audit showing coverage gaps
- A weekly ops review analysing success rates
- A milestone completion report

**How it ages:** Reports don't age — they're already historical the moment they're written. If you need an updated picture, write a new report. Old reports track progress over time.

**Audit behaviour:** Never flagged as stale. That's the point — they're snapshots.

**Where it lives:** `projects/<project>/reports/`

**The test:** *"Is this a snapshot of state at a specific point in time?"* If it's meant to be kept current as things change, it's a `reference`. This is the most common confusion.

---

## 5. `runbook`

**What it is:** A step-by-step procedure for how to do something. Not project-specific — applies across projects or to the workspace itself. Cross-cutting operational knowledge.

**Examples:**
- Policies (governance rules)
- Lessons learned (debugging knowledge, append-only)
- Testing strategy (how code changes get verified)
- QA pipeline (workflow when a bug is reported)
- Upgrade procedures

**How it ages:** Must be kept current. If the procedure changes, the runbook changes. An outdated runbook is dangerous — someone follows the old steps and breaks something.

**Audit behaviour:** Flagged when `status: current` and old `updated:` date, same as references.

**Where it lives:** `runbooks/` (with subdirectories for domains, e.g. `runbooks/openclaw-ops/`)

**The test:** *"Would I follow these steps regardless of which project I'm working on?"* If it's specific to one project, it's probably a project-level plan or reference.

---

## 6. `log`

**What it is:** A record of what happened. Written in past tense, during or shortly after events. Logs are episodic memory — they capture the narrative of work.

**Examples:**
- Daily log: "Fixed webhook failure, root cause was network policy blocking apiserver. Removed netpol, filed #155."
- Incident timeline: what broke, when, how it was fixed
- Session notes: what was discussed and decided

**How it ages:** **Write-once, never edited.** Logs are the audit trail. If you got something wrong in Tuesday's log, correct it in Wednesday's log, not by editing Tuesday's. The historical record is sacred.

**Audit behaviour:** Never flagged as stale. Inherently historical.

**Where it lives:** `memory/YYYY-MM-DD.md`

**The test:** *"Am I recording something that happened?"* If recording facts about how something *is*, that's a reference. If recording how to *do* something, that's a runbook.

---

## 7. `entity`

**What it is:** Structured knowledge about a specific *thing* — a person, a server, a decision, a domain. Entities are like database records in markdown. Consistent structure within each type.

**Examples:**
- **People:** Name, contact info, relationship, roles
- **Servers:** Hostname, IP, provider, purpose, SSH details
- **Decisions:** Date, context, what was decided, rationale
- **Domains:** Registrar, DNS records, purpose

**How it ages:** Updated when the thing they describe changes. New email? Update. Server decommissioned? Remove. Living records of known things.

**Audit behaviour:** Reviewed during weekly maintenance. Audit checks entity files exist but doesn't flag individual entries.

**Where it lives:** `memory/entities/`

**The test:** *"Am I describing a specific named thing I'll want to look up later?"* If describing a whole system, it's a reference. If recording what someone did today, it's a log.

---

## How Roles Work Together

A typical workflow touches multiple roles:

1. **Research** three options for secrets management → `research/secrets-comparison.md`
2. Decide on an approach and write a **plan** → `plans/eso-migration-plan.md`
3. Execute the plan and write **logs** each day → `memory/2026-02-18.md`
4. Update **reference** docs with new state → `references/credentials-map.md`
5. Extract debugging lessons into a **runbook** → `runbooks/lessons-learned.md`
6. Run an audit and write a **report** → `reports/audit-2026-02-19.md`
7. Record the key decision as an **entity** → `memory/entities/decisions.md`

Seven roles, seven moments in the lifecycle of knowledge.


path: scripts/workspace-audit.sh
content: #!/usr/bin/env bash
# workspace-audit.sh — Audit an OpenClaw workspace against the workspace standard.
# Usage: ./workspace-audit.sh [workspace-path]
# Defaults to current directory if no path given.

set -euo pipefail

# Help
if [[ "${1:-}" == "-h" ]] || [[ "${1:-}" == "--help" ]]; then
  echo "Usage: workspace-audit.sh [workspace-path]"
  echo ""
  echo "Audit an OpenClaw workspace against the workspace standard."
  echo "Defaults to current directory if no path given."
  echo "Exit code = number of issues (0 = clean)."
  exit 0
fi

WORKSPACE="${1:-.}"
ISSUES=0
WARNINGS=0

# --- Defaults (overridden by .workspace-standard.yml if present) ---
MEMORY_BUDGET=100
STALE_DAYS=14
PROJ_SUBDIRS="references plans research reports"

# --- Load config ---
CONFIG="$WORKSPACE/.workspace-standard.yml"
if [ -f "$CONFIG" ]; then
  # Simple YAML parser for flat keys (no external deps)
  _cfg() { grep "^[[:space:]]*$1:" "$CONFIG" 2>/dev/null | head -1 | sed "s/.*$1:[[:space:]]*//" | tr -d '"' | tr -d "'" || true; }
  VAL=$(_cfg memory_lines); [ -n "$VAL" ] && MEMORY_BUDGET="$VAL"
  VAL=$(_cfg stale_days);   [ -n "$VAL" ] && STALE_DAYS="$VAL"

  # Parse project subdirs list
  _parse_list() {
    local in_section=false
    while IFS= read -r line; do
      if echo "$line" | grep -q "^  ${1}:"; then in_section=true; continue; fi
      if $in_section; then
        if echo "$line" | grep -q "^[[:space:]]*- "; then
          echo "$line" | sed 's/^[[:space:]]*- //'
        else
          break
        fi
      fi
    done < "$CONFIG"
  }
  PARSED=$(_parse_list "subdirs")
  [ -n "$PARSED" ] && PROJ_SUBDIRS="$PARSED"
fi

# Colors (disabled if not a terminal)
if [ -t 1 ]; then
  RED='\033[0;31m'; YEL='\033[0;33m'; GRN='\033[0;32m'; DIM='\033[0;90m'; RST='\033[0m'
else
  RED=''; YEL=''; GRN=''; DIM=''; RST=''
fi

issue()   { ISSUES=$((ISSUES + 1));   echo -e "${RED}✗${RST} $1"; }
warn()    { WARNINGS=$((WARNINGS + 1)); echo -e "${YEL}⚠${RST} $1"; }
ok()      { echo -e "${GRN}✓${RST} $1"; }
section() { echo -e "\n${DIM}── $1 ──${RST}"; }

# --- Pre-flight ---
if [ ! -f "$WORKSPACE/MEMORY.md" ]; then
  echo "Error: $WORKSPACE doesn't look like an OpenClaw workspace (no MEMORY.md)"
  exit 1
fi

echo "Auditing workspace: $(cd "$WORKSPACE" && pwd)"

# --- 1. Root files ---
section "Root Files"
for f in AGENTS.md SOUL.md USER.md MEMORY.md; do
  [ -f "$WORKSPACE/$f" ] && ok "$f exists" || issue "$f missing"
done
for f in TOOLS.md IDENTITY.md HEARTBEAT.md; do
  [ -f "$WORKSPACE/$f" ] && ok "$f exists" || warn "$f missing (optional)"
done

# --- 2. MEMORY.md budget ---
section "MEMORY.md Budget"
if [ -f "$WORKSPACE/MEMORY.md" ]; then
  LINES=$(wc -l < "$WORKSPACE/MEMORY.md")
  if [ "$LINES" -le "$MEMORY_BUDGET" ]; then
    ok "MEMORY.md: ${LINES} lines (budget: ${MEMORY_BUDGET})"
  else
    OVER=$((LINES - MEMORY_BUDGET))
    issue "MEMORY.md: ${LINES} lines — ${OVER} lines OVER budget (${MEMORY_BUDGET})"
  fi
fi

# --- 3. Directory structure ---
section "Directory Structure"
for d in memory memory/entities projects runbooks skills; do
  [ -d "$WORKSPACE/$d" ] && ok "$d/ exists" || issue "$d/ missing"
done

# Warn if flat docs/ still exists with files
if [ -d "$WORKSPACE/docs" ] && [ "$(find "$WORKSPACE/docs" -type f 2>/dev/null | wc -l)" -gt 0 ]; then
  COUNT=$(find "$WORKSPACE/docs" -type f | wc -l)
  warn "docs/ still has ${COUNT} files — consider migrating to projects/ and runbooks/"
fi

# --- 4. Project registry ---
section "Projects"
if [ -f "$WORKSPACE/projects/_index.md" ]; then
  ok "projects/_index.md exists"
else
  issue "projects/_index.md missing — no project registry"
fi

# Check each project directory for README.md and standard subdirs
PROJ_COUNT=0
for proj_dir in "$WORKSPACE"/projects/*/; do
  [ -d "$proj_dir" ] || continue
  proj_name=$(basename "$proj_dir")
  [ "$proj_name" = "_index.md" ] && continue
  PROJ_COUNT=$((PROJ_COUNT + 1))

  if [ -f "$proj_dir/README.md" ]; then
    ok "projects/${proj_name}/README.md exists"
  else
    warn "projects/${proj_name}/README.md missing"
  fi

  # Check for standard subdirs or legacy docs/
  HAS_STANDARD=false
  for sub in $PROJ_SUBDIRS; do
    [ -d "$proj_dir/$sub" ] && HAS_STANDARD=true
  done
  if $HAS_STANDARD; then
    ok "projects/${proj_name}/ has standard subdirectories"
  elif [ -d "$proj_dir/docs" ]; then
    warn "projects/${proj_name}/ uses legacy docs/ — migrate when next touched"
  else
    warn "projects/${proj_name}/ has no content directories"
  fi
done
echo -e "${DIM}   ${PROJ_COUNT} projects found${RST}"

# --- 5. Runbooks ---
section "Runbooks"
if [ -d "$WORKSPACE/runbooks" ]; then
  RB_COUNT=$(find "$WORKSPACE/runbooks" -name "*.md" -type f | wc -l)
  ok "runbooks/ contains ${RB_COUNT} files"
else
  issue "runbooks/ missing"
fi

# --- 6. Front-matter audit ---
section "Front-Matter"
FM_TOTAL=0
FM_MISSING=0
FM_STALE=0

check_frontmatter() {
  local file="$1"
  local rel_path="${file#$WORKSPACE/}"
  ((FM_TOTAL++))

  # Check for YAML front-matter
  if head -1 "$file" 2>/dev/null | grep -q "^---$"; then
    # Check for role field
    if ! head -20 "$file" | grep -q "^role:"; then
      warn "${rel_path}: front-matter missing 'role:' field"
      FM_MISSING=$((FM_MISSING + 1))
    fi

    # Check for stale updated date
    UPDATED=$(head -20 "$file" | grep "^updated:" | sed 's/updated: *//' | tr -d '"' | tr -d "'" 2>/dev/null || true)
    if [ -n "$UPDATED" ]; then
      # Compare dates (portable: works on both GNU and BSD date)
      if command -v date >/dev/null 2>&1; then
        UPDATED_TS=$(date -d "$UPDATED" +%s 2>/dev/null || date -j -f "%Y-%m-%d" "$UPDATED" +%s 2>/dev/null || echo "")
        if [ -n "$UPDATED_TS" ]; then
          NOW_TS=$(date +%s)
          AGE_DAYS=$(( (NOW_TS - UPDATED_TS) / 86400 ))
          if [ "$AGE_DAYS" -gt "$STALE_DAYS" ]; then
            STATUS=$(head -20 "$file" | grep "^status:" | sed 's/status: *//' | tr -d '"' | tr -d "'" || true)
            if [ "$STATUS" = "current" ] || [ "$STATUS" = "active" ]; then
              warn "${rel_path}: status=${STATUS} but updated ${AGE_DAYS} days ago"
              FM_STALE=$((FM_STALE + 1))
            fi
          fi
        fi
      fi
    fi
  else
    FM_MISSING=$((FM_MISSING + 1))
  fi
}

# Scan projects/ and runbooks/ for markdown files (disable errexit for grep in function)
set +e
while IFS= read -r file; do
  [ -n "$file" ] && check_frontmatter "$file"
done < <(find "$WORKSPACE/projects" "$WORKSPACE/runbooks" -name "*.md" -type f 2>/dev/null)
set -e

if [ "$FM_MISSING" -eq 0 ]; then
  ok "All ${FM_TOTAL} files have front-matter with role"
else
  issue "${FM_MISSING}/${FM_TOTAL} files missing front-matter or role field"
fi

if [ "$FM_STALE" -gt 0 ]; then
  warn "${FM_STALE} files may be stale (active/current but not updated in >${STALE_DAYS} days)"
fi

# --- 7. Daily logs ---
section "Memory"
if [ -d "$WORKSPACE/memory" ]; then
  LOG_COUNT=$(find "$WORKSPACE/memory" -maxdepth 1 -name "20??-??-??.md" -type f | wc -l)
  ok "${LOG_COUNT} daily logs found"

  # Check for today's log
  TODAY=$(date +%Y-%m-%d)
  if [ -f "$WORKSPACE/memory/${TODAY}.md" ]; then
    ok "Today's log exists (${TODAY}.md)"
  else
    warn "No log for today (${TODAY}.md)"
  fi

  # Entity files
  ENT_COUNT=$(find "$WORKSPACE/memory/entities" -name "*.md" -type f 2>/dev/null | wc -l)
  ok "${ENT_COUNT} entity files"
fi

# --- Summary ---
section "Summary"
echo ""
if [ "$ISSUES" -eq 0 ] && [ "$WARNINGS" -eq 0 ]; then
  echo -e "${GRN}Workspace is clean. No issues found.${RST}"
elif [ "$ISSUES" -eq 0 ]; then
  echo -e "${YEL}${WARNINGS} warning(s), 0 issues. Workspace is functional but could be tidier.${RST}"
else
  echo -e "${RED}${ISSUES} issue(s), ${WARNINGS} warning(s). Workspace needs attention.${RST}"
fi
echo ""

exit $ISSUES


path: scripts/workspace-init.sh
content: #!/usr/bin/env bash
# workspace-init.sh — Bootstrap workspace structure or add a new project.
#
# Usage:
#   ./workspace-init.sh                    # Bootstrap full workspace in current dir
#   ./workspace-init.sh --project my-app   # Add a new project
#   ./workspace-init.sh --path /some/dir   # Specify workspace path
#
# Options:
#   --project NAME   Create a single project (skip full bootstrap)
#   --path DIR       Workspace path (default: current directory)
#   --force          Overwrite existing files

set -euo pipefail

WORKSPACE="."
PROJECT=""
FORCE=false

while [[ $# -gt 0 ]]; do
  case $1 in
    --project) PROJECT="$2"; shift 2 ;;
    --path)    WORKSPACE="$2"; shift 2 ;;
    --force)   FORCE=true; shift ;;
    -h|--help)
      echo "Usage: workspace-init.sh [--project NAME] [--path DIR] [--force]"
      echo ""
      echo "Without --project: bootstrap full workspace structure"
      echo "With --project:    add a single project to existing workspace"
      exit 0
      ;;
    *) echo "Unknown option: $1"; exit 1 ;;
  esac
done

# Colors
if [ -t 1 ]; then
  GRN='\033[0;32m'; DIM='\033[0;90m'; RST='\033[0m'
else
  GRN=''; DIM=''; RST=''
fi

# --- Defaults (overridden by .workspace-standard.yml if present) ---
PROJ_SUBDIRS="references plans research reports"
ENTITY_SEEDS="people servers decisions"

# --- Load config ---
CONFIG="$WORKSPACE/.workspace-standard.yml"
if [ -f "$CONFIG" ]; then
  # Parse subdirs list (lines starting with "    - " under projects.subdirs)
  _parse_list() {
    local in_section=false
    while IFS= read -r line; do
      if echo "$line" | grep -q "^${1}:"; then in_section=true; continue; fi
      if $in_section; then
        if echo "$line" | grep -q "^[[:space:]]*- "; then
          echo "$line" | sed 's/^[[:space:]]*- //'
        else
          break
        fi
      fi
    done < "$CONFIG"
  }
  PARSED=$(_parse_list "  subdirs")
  [ -n "$PARSED" ] && PROJ_SUBDIRS="$PARSED"
  PARSED=$(_parse_list "entities")
  [ -n "$PARSED" ] && ENTITY_SEEDS="$PARSED"
fi

created() { echo -e "${GRN}+${RST} $1"; }
skipped() { echo -e "${DIM}·${RST} $1 (exists)"; }

write_if_new() {
  local file="$1"
  local content="$2"
  if [ -f "$file" ] && ! $FORCE; then
    skipped "$file"
  else
    mkdir -p "$(dirname "$file")"
    echo "$content" > "$file"
    created "$file"
  fi
}

# --- Create a single project ---
create_project() {
  local name="$1"
  local base="$WORKSPACE/projects/$name"

  echo "Creating project: $name"
  for sub in $PROJ_SUBDIRS; do
    mkdir -p "$base/$sub"
  done

  write_if_new "$base/README.md" "---
role: reference
project: ${name}
status: active
created: $(date +%Y-%m-%d)
updated: $(date +%Y-%m-%d)
summary: \"TODO: describe ${name}\"
---

# ${name}

TODO: describe this project.

## Current State

TODO: what's the current state?

## Key Files

| Need | Location |
|------|----------|
| Architecture | references/ |
| Active plans | plans/ |
| Research | research/ |
| Reports | reports/ |"

  # Add to _index.md if it exists and project isn't already listed
  local index="$WORKSPACE/projects/_index.md"
  if [ -f "$index" ]; then
    if ! grep -qF "[$name]" "$index"; then
      echo "| [${name}](${name}/) | active | TODO: description |" >> "$index"
      created "Added ${name} to projects/_index.md"
    fi
  fi

  for sub in $PROJ_SUBDIRS; do
    created "$base/$sub/"
  done
}

# --- Single project mode ---
if [ -n "$PROJECT" ]; then
  create_project "$PROJECT"
  echo -e "\n${GRN}Project '${PROJECT}' created.${RST}"
  exit 0
fi

# --- Full workspace bootstrap ---
echo "Bootstrapping workspace: $(cd "$WORKSPACE" && pwd)"
echo ""

# Core directories
for d in memory memory/entities projects runbooks skills metrics scripts; do
  if [ -d "$WORKSPACE/$d" ]; then
    skipped "$d/"
  else
    mkdir -p "$WORKSPACE/$d"
    created "$d/"
  fi
done

# Project registry
write_if_new "$WORKSPACE/projects/_index.md" "---
role: reference
status: current
created: $(date +%Y-%m-%d)
updated: $(date +%Y-%m-%d)
summary: \"Registry of all projects in this workspace\"
---

# Projects

| Project | Status | Description |
|---------|--------|-------------|

## Structure Convention

Each project follows:

\`\`\`
projects/<name>/
├── README.md       # Overview, goals, current state
├── references/     # Durable facts
├── plans/          # Active and completed plans
├── research/       # Investigation notes
└── reports/        # Audits, reviews
\`\`\`"

# Entity README
write_if_new "$WORKSPACE/memory/entities/README.md" "# Entities

Structured knowledge about people, servers, decisions, and domains.

## Files

- \`people.md\` — Contacts and relationships
- \`servers.md\` — Infrastructure
- \`decisions.md\` — Key decisions made
- \`domains.md\` — DNS and domain info"

# Seed entity files
for ent in $ENTITY_SEEDS; do
  write_if_new "$WORKSPACE/memory/entities/${ent}.md" "# $(echo "$ent" | sed 's/./\U&/')

<!-- Add entries as they come up -->
"
done

# MEMORY.md seed (the workspace standard's core file)
write_if_new "$WORKSPACE/MEMORY.md" "# MEMORY.md — Current State

*Loaded every session. Keep under 100 lines. See workspace-standard skill for rules.*

---

## People

<!-- Add key contacts here -->

## Where to Find Things

| Need | Location |
|------|----------|
| Project registry | \`projects/_index.md\` |
| Debugging lessons | \`runbooks/lessons-learned.md\` |

## Urgent / Needs Attention

<!-- Nothing yet -->

*Last maintained: $(date +%Y-%m-%d)*"

# Runbooks seed
write_if_new "$WORKSPACE/runbooks/lessons-learned.md" "---
role: runbook
status: current
created: $(date +%Y-%m-%d)
updated: $(date +%Y-%m-%d)
summary: \"Hard-won debugging and operational lessons. Append-only, numbered.\"
---

# Lessons Learned

*Append new lessons with sequential numbers. Never delete — supersede instead.*

<!-- ## 1. First lesson title
- **Date:** YYYY-MM-DD
- **Context:** What happened
- **Root cause:** Why
- **Fix:** What fixed it
- **Prevention:** How to avoid next time
-->"

echo -e "\n${GRN}Workspace bootstrapped.${RST}"
echo -e "${DIM}Next: create your first project with: workspace-init.sh --project my-project${RST}"


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: suspicious | SkillSpector: suspicious (HIGH)