# Self-improvement loop

> Task ## Outcome evidence, learning beliefs, skill-proposal accept/reject flow, checkAt followups, and the rule that agents never edit skills directly.

- Repository: superdesigndev/loopany
- GitHub: https://github.com/superdesigndev/loopany
- Human docs: https://grok-wiki.com/public/docs/superdesigndev-loopany-97bd9ab97ae8
- Complete Markdown: https://grok-wiki.com/public/docs/superdesigndev-loopany-97bd9ab97ae8/llms-full.txt

## Source Files

- `skills/loopany-reflect/SKILL.md`
- `skills/loopany-core/kinds/learning.md`
- `skills/loopany-core/kinds/skill-proposal.md`
- `skills/loopany-core/kinds/task.md`
- `CLAUDE.md`
- `src/commands/followups.ts`

---

---
title: "Self-improvement loop"
description: "Task ## Outcome evidence, learning beliefs, skill-proposal accept/reject flow, checkAt followups, and the rule that agents never edit skills directly."
---

loopany’s self-improvement loop is implemented as markdown artifacts plus skills (`loopany-capture`, `loopany-reflect`, `loopany-review`): completed `task` records supply `## Outcome` evidence, `loopany-reflect` distills `learning` beliefs and optional `skill-proposal` artifacts, humans accept or reject proposals before any `SKILL.md` edit is applied and committed, and `checkAt` on learnings or accepted proposals drives `loopany followups` closure via daily review.

## Components

| Piece | Kind / command | Role |
|-------|----------------|------|
| Evidence | `task` (`done` / `failed`) | Immutable `## Outcome` body; substrate for reflect |
| Belief | `learning` (`active` → `superseded` / `archived`) | Declarative hypothesis with `evidence[]` |
| Behavior change | `skill-proposal` (`pending` → `accepted` / `rejected`) | Contract for a skill edit; only path to mutate skills |
| Discovery | `skills/loopany-reflect/SKILL.md` | Pattern thresholds, write learnings/proposals, apply accept/reject |
| Scheduling | `checkAt` + `loopany followups` | Due-item query; daily review closes the loop |
| Capture gate | `skills/loopany-capture/SKILL.md` | End-of-work routing; refuses weak outcomes |

Kinds are defined under `skills/loopany-core/kinds/` and copied into `$LOOPANY_HOME/kinds/` at init. Runtime parses them into Zod frontmatter validators and status machines (`src/core/kind-registry.ts`); the CLI enforces **status transitions**, not body-section presence (section rules are kind contracts enforced by agent skills).

## End-to-end flow

```mermaid
sequenceDiagram
  participant Work as Agent work
  participant Cap as loopany-capture
  participant Store as artifacts/*.md
  participant Ref as loopany-reflect
  participant User as Human
  participant Skill as skills/*/SKILL.md
  participant Git as git

  Work->>Cap: substantive work ends
  Cap->>Store: append ## Outcome; status done|failed
  Ref->>Store: list done tasks, dismissed signals
  Ref->>Store: create learning (+ optional skill-proposal)
  User->>Ref: accept|reject proposal
  alt accepted
    Ref->>Skill: apply ## Proposed change only
    Ref->>Store: append ## Outcome; status accepted
    Ref->>Git: commit skill + proposal
  else rejected
    Ref->>Store: append ## Outcome; status rejected
  end
  Store->>Store: checkAt due
  Note over Store: loopany followups + loopany-review daily
```

<Note>
Reflect looks **forward** (new patterns). `loopany-review` daily revalidates **due** `checkAt` on existing learnings and proposals — do not mix scopes.
</Note>

## Task outcomes as evidence

Every terminal `task` must carry a `## Outcome` section before `done` or `failed` (kind contract in `skills/loopany-core/kinds/task.md`). The section answers what shipped or failed, whether observable evidence moved, and what you would do differently. Optional `## Before` is strongly recommended for metric work so reflect can falsify beliefs.

Terminal transition pattern:

```bash
loopany artifact append <task-slug> --section Outcome --content "..."
loopany artifact status <task-slug> done --reason "<one line>"
```

`loopany-capture` is the quality gate at work boundaries: skip capture when you cannot write a one-sentence outcome, when the event is internal tooling noise, or when `loopany artifact list --contains "<phrase>"` finds a duplicate. Beliefs from fewer than two data points route to reflect, not ad-hoc `learning` creation during capture.

<Warning>
`artifact status` validates the kind **status machine** only (`src/core/artifact-store.ts` `setStatus`). It does not block `done` without `## Outcome` — agents must append Outcome first or pollute the reflect substrate.
</Warning>

## Reflect: evidence → pattern → artifacts

`skills/loopany-reflect/SKILL.md` runs in two modes: **reflect** (discover) and **proposal-apply** (accept/reject).

### When to reflect

- User: “reflect”, “what have we learned”, “improve yourself”
- Weekly cadence (paired with `loopany-review`; monthly structural review stays in review)
- After ≥ 3 tasks reach `done` in a short window

Do **not** reflect after every single task.

### Gather and dedupe

```bash
loopany artifact list --kind task --status done
loopany artifact list --kind signal
loopany artifact list --kind signal --status dismissed
loopany artifact list --kind learning --status active
loopany artifact list --kind skill-proposal --status rejected
```

Filter to a recent window (~1 week, `createdAt` newest first). Subtract artifact IDs already listed in `evidence` on active learnings and non-rejected proposals so reflect does not duplicate work.

### Pattern thresholds

| Pattern | Threshold |
|---------|-----------|
| Same class of outcome | ≥ 3 tasks |
| Belief refuted | ≥ 2 tasks contradicting an active learning |
| Belief needs caveat | ≥ 2 tasks |
| Dismissed signal keeps recurring | ≥ 3 dismissals over ≥ 2 weeks |

Below threshold: report insufficient evidence (skill regression scenario 8 expects **no** new `lrn-*` files). Do not create a `learning` from one bad outcome or re-propose a `rejected` skill-proposal.

## Learning artifacts

`learning` stores a **belief**, not a behavior change. Title is the belief sentence. Frontmatter (camelCase since v0.2):

| Field | Notes |
|-------|-------|
| `title` | Required — declarative belief |
| `evidence` | String array; ≥ 2 artifact slugs at creation time |
| `checkAt` | Date; 1–3 months; concrete revalidation question in body |
| `supersedes` | Slug of prior learning when belief shifts |
| `status` | `active` (default) → `superseded` → `archived` |
| `mentions` | Optional structural links |

Required body sections at creation: `## Observation`, `## Evidence`, `## Scope`, `## Check-at`.

Create example:

```bash
loopany artifact create --kind learning \
  --slug short-attention-spans-2026 \
  --title "Deals with more than three stakeholders close 2.5x slower" \
  --evidence "task-a,task-b,task-c" \
  --mentions "fundraising-2027" \
  --check-at 2026-07-22 \
  --content "$(cat <<'EOF'
## Observation
...

## Evidence
- task-a — "..."
- task-b — "..."

## Scope
...

## Check-at
...
EOF
)"
```

When understanding changes, **do not edit** the old learning. Create a new learning, link `loopany refs add --from <new> --to <old> --relation supersedes`, and `loopany artifact status <old> superseded --reason "superseded by <new>"`. Terminal `superseded` / `archived` require `## Outcome` on the learning kind.

Many learnings stop at “now we know” with no skill change.

```mermaid
stateDiagram-v2
  [*] --> active
  active --> superseded: belief revised
  active --> archived
  superseded --> archived
```

## Skill-proposal artifacts

`skill-proposal` is the **only** path from agent judgment to skill file changes (`skills/loopany-core/kinds/skill-proposal.md`, `CLAUDE.md` architectural constraint). Agents must not edit `SKILL.md` files directly.

| Field | Notes |
|-------|-------|
| `targetSkill` | Path to `SKILL.md` (existing for `modify`/`remove`; planned path for `add`) |
| `changeType` | `modify` (default), `add`, `remove` |
| `status` | `pending` → `accepted` \| `rejected` |
| `evidence` | Supporting artifact slugs |
| `checkAt` | On accept: schedule “did this help?” review |

Required body before pending review: `## Motivation` (cite learning), `## Proposed change`, `## Expected effect`, `## Check-at`. For `changeType: add`, also `## Skill draft` (full new `SKILL.md`) and `## Resolver entry` (row for `skills/loopany-resolver/SKILL.md`).

After accept or reject, body must include `## Outcome` before the status flip.

```mermaid
stateDiagram-v2
  [*] --> pending
  pending --> accepted: human accept + skill edit + git commit
  pending --> rejected: human reject + Outcome reason
```

Verify the chain:

```bash
loopany trace <proposal-slug> --direction backward
loopany refs <proposal-slug> --direction out --relation mentions
```

## Accept and reject flows

Proposal-apply mode (`loopany-reflect` Part 2):

```bash
loopany artifact list --kind skill-proposal --status pending
loopany artifact get <proposal-slug>
```

<Steps>
  <Step title="Accept">
    Read proposal, cited learning (`refs` / `mentions`), and current `targetSkill` file. Apply **only** the described change. Append `## Outcome` to the proposal (literal diff summary). Run `loopany artifact status <proposal-slug> accepted --reason "..."`. Git-commit the skill file and proposal artifact together.
  </Step>
  <Step title="Reject">
    Read proposal. Append `## Outcome` with a clear reason (future reflect reads this). `loopany artifact status <proposal-slug> rejected --reason "..."`.
  </Step>
</Steps>

Edge cases from the reflect skill: reject if target file missing, cited learning was superseded, or multiple pending proposals touch the same file (accept one at a time, re-read target between).

<Tip>
Resolver routing for proposals: `skills/loopany-resolver/SKILL.md` maps “accept &lt;proposal-slug&gt;” / “reject &lt;proposal-slug&gt;” to `loopany-reflect`.
</Tip>

## checkAt and followups

`checkAt` is indexed frontmatter on `task`, `learning`, and other kinds that declare it. Set only when there is a concrete future question; missing dates are better than ignored ones.

```bash
loopany followups --due today
loopany followups --due overdue
loopany followups --due next-7d
loopany followups --due today --include-done true
```

Implementation (`src/commands/followups.ts`, `src/core/index.ts` `followups()`):

- Returns artifacts whose `checkAt` date is on or before the cutoff.
- **Default:** hides artifacts in a **terminal** status (no outgoing transitions in the kind status machine — e.g. `task` `done`, `skill-proposal` `accepted`).
- `overdue` further restricts to dates strictly before today.

Daily review (`skills/loopany-review/references/daily.md`) runs `loopany followups --due today` only (not overdue — weekly’s job). For each due learning, `loopany trace <learning-slug> --direction backward` informs revalidation. Closure gate: every surfaced item ends resolved, deferred (`checkAt` pushed with reason), or retired (`checkAt` removed with note).

Weekly review nudges pending proposals (`artifact list --kind skill-proposal --status pending`; >5 pending → nudge) and suggests reflect when ≥3 resolutions occurred in the pass.

## Cadence (skills, not CLI cron)

| Cadence | Skill | Self-improvement role |
|---------|-------|------------------------|
| End of substantive work | `loopany-capture` | Write/refine task outcomes |
| Weekly | `loopany-reflect` | New learnings + proposals |
| Daily | `loopany-review` | Close due `checkAt` items |
| Weekly | `loopany-review` | Overdue sweep, doctor, feed reflect |
| On demand | `loopany-reflect` proposal-apply | Accept/reject pending proposals |

Coding CLI hosts often use session-boundary prompts instead of durable cron (`INSTALL_FOR_AGENTS.md`); judgment stays in skills, queries stay in `loopany` CLI.

## Quick reference

```text
CAPTURE:  work ends → quality gate → append Outcome → task done|failed
REFLECT:  list evidence → pattern? → learning → (optional) skill-proposal pending
ACCEPT:   read spr → read lrn → edit targetSkill → Outcome → accepted → git commit
REJECT:   read spr → Outcome (reason) → rejected
FOLLOWUP: checkAt due → followups → review classify → resolve|defer|retire
INVARIANT: never edit skills except via accepted skill-proposal
```

<Check>
Self-improvement needs no separate “lesson” entity: outcomes, learnings, proposals, graph edges (`supersedes`, `mentions`, `cites`), and git-backed skill files are the full loop.
</Check>

## Related pages

<CardGroup>
  <Card title="Reflect workflow" href="/reflect-workflow">
    Step-by-step reflect and proposal-apply procedures.
  </Card>
  <Card title="Capture workflow" href="/capture-workflow">
    Event routing and the Outcome quality gate at task close.
  </Card>
  <Card title="Periodic review" href="/periodic-review">
    Daily followups, weekly doctor/overdue, monthly mission checks.
  </Card>
  <Card title="Self-improvement example" href="/self-improvement-example">
    Recipe: three done tasks → reflect → accept proposal → git diff.
  </Card>
  <Card title="Kinds and validation" href="/kinds-and-validation">
    Kind markdown, status machines, and frontmatter validators.
  </Card>
  <Card title="Skills library" href="/skills-library">
    Resolver, core, capture, reflect, and review skill packs.
  </Card>
</CardGroup>
