Inbox Skill
Universal capture and classification for unstructured content. Accepts voice memos, quick notes, raw text, forwarded emails -- classifies and routes to the appropriate downstream skill.
Vault Location
vault/_inbox/
_inbox.yaml # Derived index (rebuilt from frontmatter)
YYMMDD-HHMMSS[-slug].md # Active items (frontmatter is canonical)
.audio/ # Raw audio captured by Trillian, paired by basename
YYMMDD-HHMMSS[-slug].m4a
.files/ # File drops: input files with a vault destiny (CR-024)
YYMMDD-HHMMSS[-slug].<ext>
.archive/ # Processed items (moved here after downstream skill runs)
.audio/ # Audio archived alongside transcript
.files/ # Source files that don't accompany their output
Schema: see docs/schemas/inbox.md for
the canonical <id>.md frontmatter shape, .audio/ convention, and
lifecycle states. The schema is the source of truth; this SKILL.md
documents skill behaviour. Other tools (Trillian, Deep Thought, Marvin,
external skills) write directly to _inbox/ against the schema; /inbox
is one of several producers.
Subcommands
/inbox [content] -- Default: Capture + Classify
Accept raw content (pasted text, file path, or inline text), classify it, store in _inbox/, and suggest the downstream skill.
Processing flow:
Parse input -- detect content type:
- Multiple speakers, timestamps, speaker labels ->
voice_memo
- "From:", "Subject:", email headers ->
email
- File path provided -> read the file, detect type from content
- Binary or non-markdown file path (PDF, CSV/xlsx, image, media, archive) ->
file_drop (CR-024): move/copy the file into _inbox/.files/<id>.<ext> and create the paired stub with source.file_path and a type-based classification guess (PDF/document → summarize into a folder; CSV/xlsx → project data; image/media → attachment). Files >~25 MB: flag the size and offer process-in-place + reference-stub archiving instead of moving the blob. Full convention in docs/schemas/inbox.md "File drops".
- Short text, no structure ->
quick_note
- Everything else ->
raw_text
Auto-classify -- determine which downstream skill should process this:
| Signal |
Classification |
Target Skill |
| Speaker labels, timestamps, dialogue format |
transcript |
/transcript |
| Org team member names (from ops-config), meeting context |
ops |
/ops |
| "TODO", "remind me", imperative sentences, action items |
task |
/tasks add |
| Short observation, no action context |
note |
None (already saved) |
| Idea, brainstorm, "what if" |
idea |
None (already saved) |
Assign confidence: high (clear signals), medium (some signals), low (ambiguous).
Determine routing -- consult CLAUDE.md MEETING ROUTING for folder suggestions:
- Match participant names using the name resolution algorithm:
- Check
_contacts/*/_meta.yaml for display_name or aliases match
- Check org config
team[] for internal team members
- Matching is case-insensitive with Swedish character folding
- Identify org context from ops-config team lists
- Suggest target folder (e.g.,
_contacts/david-ekberg/, acme/meetings/management/)
- See Contact Metadata Schema for name resolution details
Confirm with user -- present classification + routing summary:
Classification: transcript (high confidence)
Target skill: /transcript
Target folder: _contacts/david-ekberg/
OK to proceed? (or override)
Wait for user confirmation or override. Keep it brief -- one question, then go.
Store in _inbox/:
- Write content to
_inbox/YYMMDD-HHMMSS[-slug].md with frontmatter per docs/schemas/inbox.md
- Set
id, created, classification, confidence, status: pending, and routing fields in frontmatter
- Rebuild
_inbox.yaml index from the new frontmatter
- If the input was paired audio, set
source.audio_path and ensure the audio is at _inbox/.audio/<id>.m4a
Execute the downstream skill automatically:
transcript -> Run /transcript with the content, passing the target folder
ops -> Run /ops with the content, passing the org config
task -> Run /tasks add [extracted description]
note/idea -> Already saved, no downstream skill needed
- Do NOT just print instructions -- actually invoke the skill and let it run
- The downstream skill handles all its own processing (summary, changelog, task import, insights, history)
Archive the inbox item after the downstream skill completes:
- Set frontmatter
status: processed, processed_at to now (ISO 8601), processed_by to the downstream skill name, output_file to its output path
- Move the .md file to
_inbox/.archive/<id>.md and set archived_to
- If paired audio exists, also move
_inbox/.audio/<id>.m4a to _inbox/.archive/.audio/<id>.m4a
- Rebuild
_inbox.yaml to reflect the new state
/inbox status -- Show Inbox State
Display counts by status (per schema):
Inbox Status:
pending: 3 items
processing: 1 item
processed: 5 items (will archive on next process run)
skipped: 1 item
archived: 12 items (in .archive/)
---
Active: 4 items (pending + processing + skipped)
Orphan audio: 1 file (audio in .audio/ with no matching .md yet)
Also show classification breakdown of active items, flag any orphan
audio waiting in .audio/ for a matching transcript, and flag orphan
file drops in .files/ with no paired stub (offer to register them,
CR-024).
/inbox process [id|all] -- Process Stored Items
Process one item by ID, or all unprocessed items (status new or classified) with all.
Single item (/inbox process <id>):
- Read the item's frontmatter and body from
_inbox/<id>.md
- If
classification is missing or confidence: low, run classification (Step 2 from default flow); update frontmatter
- Show classification and target, ask user to confirm or override
- Set frontmatter
status: processing
- Execute the downstream skill -- actually run
/transcript, /ops, or /tasks add as appropriate
- After the downstream skill completes, update frontmatter:
status: processed, processed_at, processed_by, output_file
- Move
<id>.md to _inbox/.archive/<id>.md (and paired audio to .archive/.audio/<id>.m4a if present); set archived_to
- File drops (CR-024): the source file in
.files/ moves WITH the output -- to the target folder's .attachments/ when it should accompany the content (ask if unclear), else to _inbox/.archive/.files/<id>.<ext>. Record the final path in the stub before archiving it.
- Rebuild
_inbox.yaml from current frontmatter
All items (/inbox process all):
- Glob
_inbox/*.md, read each frontmatter, filter to status: pending or processing. Skip working documents (registered type: working_doc / tag do-not-process per the schema CR-022 section) -- they are surfaces, not captures
- If no items to process, report "Inbox is empty" and stop
- Read and classify all items, then present a single confirmation table:
| ID | Title | Classification | Target | Folder |
|--------------------------|----------------|----------------|-------------|---------------------|
| 250428-091803-bob | samtal med bob | transcript | /transcript | _contacts/bob/ |
| 250428-103044-sara | samtal med sara| transcript | /transcript | _contacts/sara/ |
Ask: "Process all? (or list IDs to skip/override)"
- Execute each item sequentially -- for each confirmed item:
a. Set frontmatter
status: processing
b. Run the downstream skill with the body content and target folder
c. Let the skill complete its full processing (summary, changelog, tasks, insights)
d. Update frontmatter: status: processed, processed_at, processed_by, output_file, archived_to
e. Move <id>.md to .archive/; move paired audio (if any) to .archive/.audio/
f. Brief status line: "Item 250428-091803-bob done -- processed as transcript -> _contacts/bob/"
- Rebuild
_inbox.yaml once at the end
- Print final summary: "Processed N items, M archived, K orphan audio still pending"
Key principle: /inbox process is an automation pipeline, not a suggestion engine. It actually runs the downstream skills. Human-in-the-loop is limited to:
- Confirming the classification table before execution begins
- Any validation questions the downstream skill itself needs (e.g.,
/transcript may ask about participants, /ops may ask about org config) -- pass these through to the user as they come up
/inbox triage [refresh|status] -- Triage working-surface upkeep (CR-022)
Operates on the vault's registered triage doc (see the
schema CR-022 section: an _inbox/ working
document with type: working_doc, status: keep, tag do-not-process).
If no triage doc is registered, say so and stop -- this subcommand never
creates one uninvited (offer to register an existing file if the user asks).
Design principle (blocking): mechanical upkeep only. Never reorder,
reword, re-bucket, or classify items. Sorting INKORG is the human's
thinking step, not the skill's.
refresh (default):
- Week anchor: update the
Veckoankare: line's date and week number to
today. Preserve the standing-context text after them verbatim -- only the
date/week tokens change. If bucket headings carry week numbers
(e.g. DENNA VECKA (v.26)), update those tokens too.
- Archive done items: move every
[x] bullet (with its sub-bullets) to
_inbox/.archive/YYMMDD-triage-klart.md -- create with a # KLART-arkiv
header if missing, append under a ## YYMMDD heading, keep the bullet
text verbatim plus a (arkiverad YYMMDD) suffix.
- Report INKORG age: list INKORG items that have sat unsorted >7 days
(report only -- sorting is the human's job).
- Flag plaintext credentials: scan for password/API-key-looking lines
(per the schema's no-secrets rule) and report them with the
recommendation to replace with a password-manager reference. Never
auto-remove. Skip lines ending in
<!-- secret-ok --> — that marker
is the owner's recorded decision to keep the credential inline; offer to
stamp it when the user says a flagged line should stay.
- Report: one summary line per action class (anchor updated, N items
archived, M INKORG items aging, K credential flags). Show the diff of
what moved.
status: read-only -- items per section, INKORG count + oldest item
age, [x] items awaiting archive, week-anchor date vs today, link to the
KLART archive.
Optional external mirror (CR-017). A vault MAY point the triage doc at an
external actions surface (e.g. a task app) for a focused today/tomorrow view.
This is a local, per-vault integration -- its script, credentials, and
target IDs live outside this repo (a local script dir + a gitignored secret;
a config pointer under the vault's own config layer). Two directions, both
human-gated, mirroring the mechanical-upkeep principle above:
- push -- mirror the current actionable today/tomorrow items outward,
after showing a preview. One-way, additive, deduped against what's already
there. It never invents dates: an item ships only if the line itself marks
it today/tomorrow.
- reconcile -- read the external surface back and, for items completed
there, propose marking the matching triage line
[x]; the human
approves before anything is written. Never an automatic merge -- the triage
doc stays the system of record, consistent with "sorting is the human's
step, not the skill's."
This skill documents the contract (gated push + gated reconcile, secret-free,
triage-path read from the registered file:); it ships no provider code.
/inbox help -- Usage Guide
Print this usage guide:
/inbox [content] Capture, classify, and route content
/inbox status Show inbox counts by status
/inbox process [id|all] Process one or all stored items
/inbox triage [refresh|status] Triage working-surface upkeep (CR-022)
/inbox help This help text
Content types detected: voice_memo, email, quick_note, raw_text, clipboard
Classifications: transcript, ops, task, note, idea
Items are stored in vault/_inbox/ and tracked in _inbox.yaml.
After processing with the downstream skill, items are archived.
_inbox.yaml -- derived index
_inbox.yaml is a derived index, rebuilt from the frontmatter of every
_inbox/*.md. It exists for fast batch listing (Marvin, /inbox status)
without parsing every markdown file.
The canonical metadata for any single item lives in that item's
frontmatter, not here. If frontmatter and index disagree, frontmatter wins.
/inbox rebuilds the index on every status or process invocation.
External tools writing items directly into _inbox/<id>.md MAY also append
to the index, but they are not required to -- the next /inbox call picks
up new files from frontmatter automatically.
See docs/schemas/inbox.md for the index
schema (version: 2, post-CR-012). v1 files are detected and rewritten
lazily on first run.
Content File Format
Markdown with YAML frontmatter (canonical metadata) and a body. See
docs/schemas/inbox.md for the full
frontmatter spec.
Filename: YYMMDD-HHMMSS[-slug].md where:
YYMMDD-HHMMSS is creation timestamp (vault-local)
slug is optional, kebab-case, derived from a short title
Minimal valid frontmatter:
---
id: 250428-091803
created: 2026-04-28T09:18:03+02:00
status: pending
---
/inbox populates additional fields (classification, target_skill,
target_folder, confidence) when the item is classified.
Integration
- Reads ops-config for team member recognition and org routing
- Reads CLAUDE.md MEETING ROUTING for folder suggestions
- Reads
_contacts/ folder structure for participant matching
- Executes downstream skills (
/transcript, /ops, /tasks) -- not just suggestions
- Marvin (formerly core-skills-visualisation) provides a web UI for the same data (create, view, classify, archive)
- Trillian (vault-pulse) writes raw audio to
_inbox/.audio/ and frontmatter-only stub markdown to _inbox/<id>.md; the matching transcript arrives later from Deep Thought
- Deep Thought writes transcript markdown back to
_inbox/<id>.md with source.external_id set to the DT job id
Archive Policy
Follows the core-skills archive pattern: never delete, always archive.
- Processed markdown moves to
_inbox/.archive/<id>.md
- Paired audio (if any) moves to
_inbox/.archive/.audio/<id>.m4a
- The pairing-by-basename rule is preserved across the move
_inbox.yaml retains the item entry with status: processed and archived_to set
- Archive is browsable but not shown in active views
- Retention for archived audio is user-configurable (default: keep indefinitely; future
/inbox prune --older-than Nd will reclaim space)
Rules
- Confirm classification with user before executing -- one brief confirmation, then go
- Execute downstream skills automatically after confirmation -- do not just print instructions
- Minimize questions -- classify, confirm, execute, archive. No back-and-forth.
- Frontmatter is canonical;
_inbox.yaml is a derived index. If they disagree, frontmatter wins.
- Use the
YYMMDD-HHMMSS[-slug] identifier format (per schema)
- One content file per inbox item; pair with
.audio/<id>.m4a if audio captured
- Items created via Marvin web UI, Trillian, or Deep Thought follow the same schema
- After downstream skill completes, archive the inbox item automatically (and its paired audio)
1---2name: inbox3description: Inbox Skill4---56# Inbox Skill78Universal capture and classification for unstructured content. Accepts voice memos, quick notes, raw text, forwarded emails -- classifies and routes to the appropriate downstream skill.910## Vault Location1112```13vault/_inbox/14 _inbox.yaml # Derived index (rebuilt from frontmatter)15 YYMMDD-HHMMSS[-slug].md # Active items (frontmatter is canonical)16 .audio/ # Raw audio captured by Trillian, paired by basename17 YYMMDD-HHMMSS[-slug].m4a18 .files/ # File drops: input files with a vault destiny (CR-024)19 YYMMDD-HHMMSS[-slug].<ext>20 .archive/ # Processed items (moved here after downstream skill runs)21 .audio/ # Audio archived alongside transcript22 .files/ # Source files that don't accompany their output23```2425**Schema**: see [`docs/schemas/inbox.md`](../../docs/schemas/inbox.md) for26the canonical `<id>.md` frontmatter shape, `.audio/` convention, and27lifecycle states. The schema is the source of truth; this SKILL.md28documents skill behaviour. Other tools (Trillian, Deep Thought, Marvin,29external skills) write directly to `_inbox/` against the schema; `/inbox`30is one of several producers.3132## Subcommands3334### `/inbox [content]` -- Default: Capture + Classify3536Accept raw content (pasted text, file path, or inline text), classify it, store in `_inbox/`, and suggest the downstream skill.3738**Processing flow:**39401. **Parse input** -- detect content type:41 - Multiple speakers, timestamps, speaker labels -> `voice_memo`42 - "From:", "Subject:", email headers -> `email`43 - File path provided -> read the file, detect type from content44 - **Binary or non-markdown file path** (PDF, CSV/xlsx, image, media, archive) -> `file_drop` (CR-024): move/copy the file into `_inbox/.files/<id>.<ext>` and create the paired stub with `source.file_path` and a type-based classification guess (PDF/document → summarize into a folder; CSV/xlsx → project data; image/media → attachment). Files >~25 MB: flag the size and offer process-in-place + reference-stub archiving instead of moving the blob. Full convention in [`docs/schemas/inbox.md`](../../docs/schemas/inbox.md) "File drops".45 - Short text, no structure -> `quick_note`46 - Everything else -> `raw_text`47482. **Auto-classify** -- determine which downstream skill should process this:4950 | Signal | Classification | Target Skill |51 |--------|---------------|-------------|52 | Speaker labels, timestamps, dialogue format | `transcript` | `/transcript` |53 | Org team member names (from ops-config), meeting context | `ops` | `/ops` |54 | "TODO", "remind me", imperative sentences, action items | `task` | `/tasks add` |55 | Short observation, no action context | `note` | None (already saved) |56 | Idea, brainstorm, "what if" | `idea` | None (already saved) |5758 Assign confidence: `high` (clear signals), `medium` (some signals), `low` (ambiguous).59603. **Determine routing** -- consult CLAUDE.md MEETING ROUTING for folder suggestions:61 - Match participant names using the name resolution algorithm:62 - Check `_contacts/*/_meta.yaml` for `display_name` or `aliases` match63 - Check org config `team[]` for internal team members64 - Matching is case-insensitive with Swedish character folding65 - Identify org context from ops-config team lists66 - Suggest target folder (e.g., `_contacts/david-ekberg/`, `acme/meetings/management/`)67 - See [Contact Metadata Schema](../ops-config/contact-meta-schema.md) for name resolution details68694. **Confirm with user** -- present classification + routing summary:70 ```71 Classification: transcript (high confidence)72 Target skill: /transcript73 Target folder: _contacts/david-ekberg/7475 OK to proceed? (or override)76 ```77 Wait for user confirmation or override. Keep it brief -- one question, then go.78795. **Store in `_inbox/`**:80 - Write content to `_inbox/YYMMDD-HHMMSS[-slug].md` with frontmatter per [`docs/schemas/inbox.md`](../../docs/schemas/inbox.md)81 - Set `id`, `created`, `classification`, `confidence`, `status: pending`, and routing fields in frontmatter82 - Rebuild `_inbox.yaml` index from the new frontmatter83 - If the input was paired audio, set `source.audio_path` and ensure the audio is at `_inbox/.audio/<id>.m4a`84856. **Execute the downstream skill automatically:**86 - `transcript` -> Run `/transcript` with the content, passing the target folder87 - `ops` -> Run `/ops` with the content, passing the org config88 - `task` -> Run `/tasks add [extracted description]`89 - `note`/`idea` -> Already saved, no downstream skill needed90 - **Do NOT just print instructions** -- actually invoke the skill and let it run91 - The downstream skill handles all its own processing (summary, changelog, task import, insights, history)92937. **Archive the inbox item** after the downstream skill completes:94 - Set frontmatter `status: processed`, `processed_at` to now (ISO 8601), `processed_by` to the downstream skill name, `output_file` to its output path95 - Move the .md file to `_inbox/.archive/<id>.md` and set `archived_to`96 - If paired audio exists, also move `_inbox/.audio/<id>.m4a` to `_inbox/.archive/.audio/<id>.m4a`97 - Rebuild `_inbox.yaml` to reflect the new state9899### `/inbox status` -- Show Inbox State100101Display counts by status (per [schema](../../docs/schemas/inbox.md)):102```103Inbox Status:104 pending: 3 items105 processing: 1 item106 processed: 5 items (will archive on next process run)107 skipped: 1 item108 archived: 12 items (in .archive/)109 ---110 Active: 4 items (pending + processing + skipped)111 Orphan audio: 1 file (audio in .audio/ with no matching .md yet)112```113114Also show classification breakdown of active items, flag any orphan115audio waiting in `.audio/` for a matching transcript, and flag orphan116**file drops** in `.files/` with no paired stub (offer to register them,117CR-024).118119### `/inbox process [id|all]` -- Process Stored Items120121Process one item by ID, or all unprocessed items (status `new` or `classified`) with `all`.122123**Single item (`/inbox process <id>`):**1241251. Read the item's frontmatter and body from `_inbox/<id>.md`1262. If `classification` is missing or `confidence: low`, run classification (Step 2 from default flow); update frontmatter1273. Show classification and target, ask user to confirm or override1284. Set frontmatter `status: processing`1295. **Execute the downstream skill** -- actually run `/transcript`, `/ops`, or `/tasks add` as appropriate1306. After the downstream skill completes, update frontmatter:131 - `status: processed`, `processed_at`, `processed_by`, `output_file`1327. Move `<id>.md` to `_inbox/.archive/<id>.md` (and paired audio to `.archive/.audio/<id>.m4a` if present); set `archived_to`133 - **File drops (CR-024):** the source file in `.files/` moves WITH the output -- to the target folder's `.attachments/` when it should accompany the content (ask if unclear), else to `_inbox/.archive/.files/<id>.<ext>`. Record the final path in the stub before archiving it.1348. Rebuild `_inbox.yaml` from current frontmatter135136**All items (`/inbox process all`):**1371381. Glob `_inbox/*.md`, read each frontmatter, filter to `status: pending` or `processing`. **Skip working documents** (registered `type: working_doc` / tag `do-not-process` per the [schema](../../docs/schemas/inbox.md) CR-022 section) -- they are surfaces, not captures1392. If no items to process, report "Inbox is empty" and stop1403. Read and classify all items, then present a single confirmation table:141 ```142 | ID | Title | Classification | Target | Folder |143 |--------------------------|----------------|----------------|-------------|---------------------|144 | 250428-091803-bob | samtal med bob | transcript | /transcript | _contacts/bob/ |145 | 250428-103044-sara | samtal med sara| transcript | /transcript | _contacts/sara/ |146 ```147 Ask: "Process all? (or list IDs to skip/override)"1484. **Execute each item sequentially** -- for each confirmed item:149 a. Set frontmatter `status: processing`150 b. Run the downstream skill with the body content and target folder151 c. Let the skill complete its full processing (summary, changelog, tasks, insights)152 d. Update frontmatter: `status: processed`, `processed_at`, `processed_by`, `output_file`, `archived_to`153 e. Move `<id>.md` to `.archive/`; move paired audio (if any) to `.archive/.audio/`154 f. Brief status line: "Item 250428-091803-bob done -- processed as transcript -> _contacts/bob/"1555. Rebuild `_inbox.yaml` once at the end1566. Print final summary: "Processed N items, M archived, K orphan audio still pending"157158**Key principle:** `/inbox process` is an automation pipeline, not a suggestion engine. It actually runs the downstream skills. Human-in-the-loop is limited to:159- Confirming the classification table before execution begins160- Any validation questions the downstream skill itself needs (e.g., `/transcript` may ask about participants, `/ops` may ask about org config) -- pass these through to the user as they come up161162### `/inbox triage [refresh|status]` -- Triage working-surface upkeep (CR-022)163164Operates on the vault's registered **triage doc** (see the165[schema](../../docs/schemas/inbox.md) CR-022 section: an `_inbox/` working166document with `type: working_doc`, `status: keep`, tag `do-not-process`).167If no triage doc is registered, say so and stop -- this subcommand never168creates one uninvited (offer to register an existing file if the user asks).169170**Design principle (blocking): mechanical upkeep only.** Never reorder,171reword, re-bucket, or classify items. Sorting INKORG is the human's172thinking step, not the skill's.173174**`refresh`** (default):1751761. **Week anchor:** update the `Veckoankare:` line's date and week number to177 today. Preserve the standing-context text after them verbatim -- only the178 date/week tokens change. If bucket headings carry week numbers179 (e.g. `DENNA VECKA (v.26)`), update those tokens too.1802. **Archive done items:** move every `[x]` bullet (with its sub-bullets) to181 `_inbox/.archive/YYMMDD-triage-klart.md` -- create with a `# KLART-arkiv`182 header if missing, append under a `## YYMMDD` heading, keep the bullet183 text verbatim plus a `(arkiverad YYMMDD)` suffix.1843. **Report INKORG age:** list INKORG items that have sat unsorted >7 days185 (report only -- sorting is the human's job).1864. **Flag plaintext credentials:** scan for password/API-key-looking lines187 (per the schema's no-secrets rule) and report them with the188 recommendation to replace with a password-manager reference. Never189 auto-remove. **Skip lines ending in `<!-- secret-ok -->`** — that marker190 is the owner's recorded decision to keep the credential inline; offer to191 stamp it when the user says a flagged line should stay.1925. **Report:** one summary line per action class (anchor updated, N items193 archived, M INKORG items aging, K credential flags). Show the diff of194 what moved.195196**`status`:** read-only -- items per section, INKORG count + oldest item197age, `[x]` items awaiting archive, week-anchor date vs today, link to the198KLART archive.199200**Optional external mirror (CR-017).** A vault MAY point the triage doc at an201external actions surface (e.g. a task app) for a focused *today/tomorrow* view.202This is a **local, per-vault integration** -- its script, credentials, and203target IDs live outside this repo (a local script dir + a gitignored secret;204a config pointer under the vault's own config layer). Two directions, both205**human-gated**, mirroring the mechanical-upkeep principle above:206207- **push** -- mirror the current actionable *today/tomorrow* items outward,208 after showing a preview. One-way, additive, deduped against what's already209 there. It never invents dates: an item ships only if the line itself marks210 it today/tomorrow.211- **reconcile** -- read the external surface back and, for items completed212 there, **propose** marking the matching triage line `[x]`; the human213 approves before anything is written. Never an automatic merge -- the triage214 doc stays the system of record, consistent with "sorting is the human's215 step, not the skill's."216217This skill documents the *contract* (gated push + gated reconcile, secret-free,218triage-path read from the registered `file:`); it ships **no** provider code.219220### `/inbox help` -- Usage Guide221222Print this usage guide:223224```225/inbox [content] Capture, classify, and route content226/inbox status Show inbox counts by status227/inbox process [id|all] Process one or all stored items228/inbox triage [refresh|status] Triage working-surface upkeep (CR-022)229/inbox help This help text230231Content types detected: voice_memo, email, quick_note, raw_text, clipboard232Classifications: transcript, ops, task, note, idea233234Items are stored in vault/_inbox/ and tracked in _inbox.yaml.235After processing with the downstream skill, items are archived.236```237238## `_inbox.yaml` -- derived index239240`_inbox.yaml` is a derived index, rebuilt from the frontmatter of every241`_inbox/*.md`. It exists for fast batch listing (Marvin, `/inbox status`)242without parsing every markdown file.243244The canonical metadata for any single item lives in that item's245frontmatter, not here. If frontmatter and index disagree, frontmatter wins.246247`/inbox` rebuilds the index on every `status` or `process` invocation.248External tools writing items directly into `_inbox/<id>.md` MAY also append249to the index, but they are not required to -- the next `/inbox` call picks250up new files from frontmatter automatically.251252See [`docs/schemas/inbox.md`](../../docs/schemas/inbox.md) for the index253schema (`version: 2`, post-CR-012). v1 files are detected and rewritten254lazily on first run.255256## Content File Format257258Markdown with **YAML frontmatter** (canonical metadata) and a body. See259[`docs/schemas/inbox.md`](../../docs/schemas/inbox.md) for the full260frontmatter spec.261262Filename: `YYMMDD-HHMMSS[-slug].md` where:263- `YYMMDD-HHMMSS` is creation timestamp (vault-local)264- `slug` is optional, kebab-case, derived from a short title265266Minimal valid frontmatter:267268```yaml269---270id: 250428-091803271created: 2026-04-28T09:18:03+02:00272status: pending273---274```275276`/inbox` populates additional fields (classification, target_skill,277target_folder, confidence) when the item is classified.278279## Integration280281- **Reads** ops-config for team member recognition and org routing282- **Reads** CLAUDE.md MEETING ROUTING for folder suggestions283- **Reads** `_contacts/` folder structure for participant matching284- **Executes** downstream skills (`/transcript`, `/ops`, `/tasks`) -- not just suggestions285- **Marvin** (formerly core-skills-visualisation) provides a web UI for the same data (create, view, classify, archive)286- **Trillian** (vault-pulse) writes raw audio to `_inbox/.audio/` and frontmatter-only stub markdown to `_inbox/<id>.md`; the matching transcript arrives later from Deep Thought287- **Deep Thought** writes transcript markdown back to `_inbox/<id>.md` with `source.external_id` set to the DT job id288289## Archive Policy290291Follows the core-skills archive pattern: never delete, always archive.292- Processed markdown moves to `_inbox/.archive/<id>.md`293- Paired audio (if any) moves to `_inbox/.archive/.audio/<id>.m4a`294- The pairing-by-basename rule is preserved across the move295- `_inbox.yaml` retains the item entry with `status: processed` and `archived_to` set296- Archive is browsable but not shown in active views297- Retention for archived audio is user-configurable (default: keep indefinitely; future `/inbox prune --older-than Nd` will reclaim space)298299## Rules300301- Confirm classification with user before executing -- one brief confirmation, then go302- **Execute downstream skills automatically** after confirmation -- do not just print instructions303- Minimize questions -- classify, confirm, execute, archive. No back-and-forth.304- **Frontmatter is canonical**; `_inbox.yaml` is a derived index. If they disagree, frontmatter wins.305- Use the `YYMMDD-HHMMSS[-slug]` identifier format (per [schema](../../docs/schemas/inbox.md))306- One content file per inbox item; pair with `.audio/<id>.m4a` if audio captured307- Items created via Marvin web UI, Trillian, or Deep Thought follow the same schema308- After downstream skill completes, archive the inbox item automatically (and its paired audio)