# Capture workflow

> End-of-task capture quality gate, event→kind routing (task/signal/note), subagent dispatch pattern, and duplicate detection via artifact list --contains.

- 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-capture/SKILL.md`
- `skills/loopany-core/kinds/task.md`
- `skills/loopany-core/kinds/signal.md`
- `src/commands/artifact-list.ts`
- `src/commands/artifact-create.ts`
- `skills/loopany-resolver/SKILL.md`

---

---
title: "Capture workflow"
description: "End-of-task capture quality gate, event→kind routing (task/signal/note), subagent dispatch pattern, and duplicate detection via artifact list --contains."
---

`skills/loopany-capture/SKILL.md` defines when an agent records completed work into `$LOOPANY_HOME`. The resolver routes here after substantive work ends; capture picks the artifact kind, runs a quality gate, deduplicates with `loopany artifact list --contains`, and delegates writes to a subagent when the host supports it. Creation and status transitions still go through `loopany-core` kind playbooks and the CLI.

## Placement in the skill stack

```text
  User request completes (substantive boundary)
           │
           ▼
  loopany-resolver  ──trigger: PR shipped, incident resolved, decision made──►
           │
           ▼
  loopany-capture     quality gate → kind choice → duplicate check
           │
           ├──► loopany-core (artifact create / append / status / refs)
           │
           └──► loopany-reflect (suggest after ≥3 captures in one session)
```

<Info>
Read `skills/loopany-resolver/SKILL.md` first in any loopany session. Capture does not replace core: it decides *whether* and *what kind*; core’s kind playbooks govern *how* to write the artifact.
</Info>

Bootstrap still applies before capture: an active `mission` must exist (`loopany artifact list --kind mission --status active`). Without one, onboarding (`ONBOARDING.md`) blocks other skills.

## When capture runs

Capture is **end-of-task**, not per message.

| Run capture | Skip capture |
|-------------|--------------|
| PR shipped or merged | Typo fix, whitespace, one-liner |
| Incident resolved | Internal agent work (grep, read files, answer questions) |
| Decision with rationale worth finding later | Feelings or opinions without observable evidence |
| Problem noticed but deferred | Work still in progress (no `## Outcome` yet) |
| User says “record this” / “log this outcome” | Speculation (at most a concrete `signal`) |

**Substantive** means the session produced evidence or a decision a future reader would need—not routine exploration.

## Event → kind routing

| Event | Target kind | Playbook |
|-------|-------------|----------|
| PR shipped / merged | `task` (typically `--status done`) | `skills/loopany-core/kinds/task.md` |
| Incident resolved | `task` | same |
| Problem noticed, not acting now | `signal` | `skills/loopany-core/kinds/signal.md` |
| Outcome for an existing open task | append `## Outcome`, then terminal status | `task.md` § Playbook |
| Decision with rationale | `note` or closed `task` | flowchart below |
| Belief from ≥ 2 data points | `learning` | via `loopany-reflect`, not inline capture |

### Decision branches

```mermaid
flowchart TD
  A[Work concluded] --> B{Resolved a pending signal?}
  B -->|yes| C["task --status done + addressed edge"]
  B -->|no| D{Produced something shippable?}
  D -->|yes| E["task --status done with ## Outcome"]
  D -->|no| F{Reasoned preference / principle?}
  F -->|yes| G["note: decided: X over Y because Z"]
  F -->|no| H{Belief from ≥2 data points?}
  H -->|yes| I[learning via loopany-reflect]
  H -->|no| J[Default: note or skip quality gate]
```

<Note>
When unsure between `note` and a structured kind, default to `note` (`skills/loopany-capture/SKILL.md`). Use `task` only when you can write a one-sentence `## Outcome`.
</Note>

Core’s parallel routing table (`skills/loopany-core/SKILL.md`) aligns: acting now → `task`; deferred → `signal`; pattern beliefs → `learning` through reflect; duplicate → append, don’t fork.

## Quality gate

Apply **before** any `artifact create`. Skip when any gate fails:

| Gate | Rule |
|------|------|
| Observable | Must be fact-backed (path, session, commit, metric)—not mood |
| Already captured | `loopany artifact list --contains "<phrase>"` → append to match |
| Too small | Trivial edits don’t belong in the brain |
| Speculation | No concrete signal; weak “might be” items stay out |
| Internal work | Tooling and Q&A are not capture events |

**Outcome test:** if you cannot draft a one-sentence `## Outcome`, do not create a closing `task`.

`test/skill-regression.sh` scenario 4 encodes this: a README typo fix must not increase artifact count after the gate. Scenario 5 expects a shipped PR (rate limiting, metrics) to become a `task`.

<Warning>
Skipping the gate pollutes the workspace and downstream reflect. Noisy artifacts dilute pattern detection.
</Warning>

## Duplicate detection with `--contains`

Dedup is a **search-then-append** step, not a separate command.

<ParamField body="--contains" type="string">
Case-insensitive substring filter on `loopany artifact list`. Applied **after** `--kind`, `--status`, `--domain`, and other field filters narrow the candidate set.
</ParamField>

**Search order** (`src/commands/artifact-list.ts`):

1. Seed candidates from indexes (`byKind`, `byStatus`, `byDomain`, or `all`).
2. Apply frontmatter field filters (indexed fields use O(1) intersection when `--kind` is set).
3. For each remaining row: match string/`string[]` frontmatter values, else read body and match substring.

**Recommended queries** (kind playbooks):

```bash
# Capture skill — broad dedup before create
loopany artifact list --contains "<key phrase>"

# Task duplicates (prefer kind-scoped)
loopany artifact list --kind task --contains "<key phrase>"

# Signal duplicates
loopany artifact list --kind signal --contains "<symptom or path>"
```

| Match found | Action |
|-------------|--------|
| Same topic, open `task` in `todo`/`running` | Append evidence or `loopany refs add … --relation follows-up` |
| Same signal symptom | `loopany artifact append <sig-id> --section Recurrences` |
| Near-duplicate `person` | Check aliases via `--kind person --contains "<name>"` |
| No match | `loopany artifact create` per kind playbook |

E2E tests verify body match (`retention`), combined filters (`--kind task --status todo --contains retention`), title-only frontmatter (`orbit`), and `string[]` aliases (`stargaz` → `alice-chen`).

## Subagent dispatch pattern

Long sessions should **not** capture inline—the main agent loses focus and writes weaker artifacts.

```mermaid
sequenceDiagram
  participant Main as Main session
  participant Gate as Quality gate
  participant Sub as Subagent (optional)
  participant CLI as loopany CLI
  participant Core as loopany-core playbooks

  Main->>Gate: Work boundary reached
  Gate->>Gate: Observable? Already captured? Outcome test?
  alt Skip
    Gate-->>Main: No artifact
  else Capture
    Main->>Main: Compose 3–5 sentence context
    Main->>Sub: Record via loopany; read loopany-core for kind
    Sub->>Core: Read kind playbook
    Sub->>CLI: artifact create / append / status
    CLI-->>Sub: id, path
    Sub-->>Main: artifact ID
    Main->>Main: Continue primary task
  end
```

<Steps>
<Step title="Filter in the main session">
Run the quality gate and `--contains` dedup. Decide kind from the event table.
</Step>
<Step title="Compose context">
Write 3–5 sentences: what happened, why it matters, numbers, and any artifact IDs in scope.
</Step>
<Step title="Dispatch">
Prompt: “Record this via loopany. Read `loopany-core` to pick the right kind. Return the artifact ID.”
</Step>
<Step title="Subagent writes">
Subagent runs CLI commands from the kind playbook (create, append `Outcome`, `status`, `refs add`).
</Step>
<Step title="Resume">
Main session stores the returned ID; no context switch for markdown authoring.
</Step>
</Steps>

<Tip>
If the host has no subagent primitive, capture inline but keep commands minimal—one create or one append, not a long authoring detour.
</Tip>

## Typical CLI sequences

### Shipped work → `task`

```bash
loopany artifact list --kind task --contains "rate limiting"

loopany artifact create --kind task \
  --title "Ship API rate limiting (token bucket, Redis)" \
  --status done \
  --content "## Outcome
Added 100 req/min per user; staging 429 errors down ~80%."

# Or two-step if body grows:
loopany artifact create --kind task --title "..." --status running --content "## Plan ..."
loopany artifact append <id> --section Outcome --content "..."
loopany artifact status <id> done --reason "Merged PR #42"
```

Terminal `task` statuses (`done`, `failed`) require a `## Outcome` section in the kind playbook; the CLI enforces status **transitions**, not body shape—agents must append Outcome before flipping status.

### Deferred problem → `signal`

```bash
loopany artifact list --kind signal --contains "PayloadTooLargeError"

loopany artifact create --kind signal \
  --title "upload_image base64-encodes video → >5MB → PayloadTooLargeError" \
  --content "Observed in staging. **Risk:** large uploads fail."
```

Signals need a concrete observable title (≤ 160 chars). Close with `addressed` + graph edge, or `dismissed` + reason.

### Decision → `note`

```bash
loopany artifact create --kind note \
  --slug "redis-over-memcached-sessions" \
  --title "decided: Redis over Memcached for sessions because TTL is built-in" \
  --content "Evaluated both; Redis ops already in stack."
```

Pass `--slug` when the artifact will be cited in `[[wiki-links]]`.

### Signal resolved by new task

```bash
loopany artifact create --kind task --title "Fix upload size path" --status todo
# … work …
loopany artifact append <tsk-id> --section Outcome --content "..."
loopany artifact status <tsk-id> done --reason "Deployed fix"
loopany artifact status <sig-id> addressed --addressed-by <tsk-id>
```

`artifact status … addressed --addressed-by <id>` emits `<addresser> addresses <signal>` in `references.jsonl` (`src/commands/artifact-status.ts`).

## Capture → core → reflect chaining

| Chain | When |
|-------|------|
| Capture → Core | Every capture: kind from capture, schema/status from core playbooks |
| Capture → Reflect | Resolver suggests reflect after **≥ 3 captures in one session** |
| Reflect threshold | Reflect skill runs after **≥ 3 tasks** reach `done` in a short window—not after every single capture |

Beliefs and skill edits never originate in capture alone; route to `loopany-reflect` when evidence crosses the learning threshold.

## Anti-patterns

| Anti-pattern | Why it hurts |
|--------------|--------------|
| Capture on every message | Noise; breaks end-of-task discipline |
| Capture mid-work | No Outcome; premature `task` |
| Skip quality gate | Pollutes reflect and search |
| Inline capture in long sessions | Weak artifacts; use subagent dispatch |
| Fork duplicate signals/tasks | Use `--contains` then append |
| Create `learning` from one task | Wait for patterns; use reflect |

## Verification

| Check | Command / artifact |
|-------|-------------------|
| List dedup | `bun test` → `loopany artifact list` `--contains` cases in `test/cli.e2e.test.ts` |
| Quality gate | `./test/skill-regression.sh 4` (trivial work → no new files) |
| PR → task routing | `./test/skill-regression.sh 5` |
| Workspace health | `loopany doctor` after bulk capture |

## Related pages

<CardGroup>
<Card title="Skills library" href="/skills-library">
Resolver, capture, core, reflect, and review packs; routing table and harness-neutral injection.
</Card>
<Card title="Artifact commands" href="/artifact-commands">
`create`, `append`, `status`, `--addressed-by`, and Outcome conventions for terminal tasks.
</Card>
<Card title="Kinds and validation" href="/kinds-and-validation">
`task`, `signal`, and `note` schemas, status machines, and indexed fields used by `list`.
</Card>
<Card title="Reflect workflow" href="/reflect-workflow">
When capture should hand off to learnings and skill-proposals instead of writing them inline.
</Card>
<Card title="Artifact lifecycle example" href="/artifact-lifecycle-example">
End-to-end signal → task → brief flow aligned with e2e scenarios.
</Card>
</CardGroup>
