Brain Ingest (paste → know)
User does one thing: paste a link, path, script, or blob.
Agent runs the full loop, writes/updates a dossier, and returns what we know + a 3-line so what.
paste → route → extract → CAPTURE (always)
→ distill claims
→ COMMIT (gates; fail → stay inbox)
→ DOSSIER write/update (trusted only)
→ report + so what
Default mode: auto (no extra questions unless blocked).
Cap: 12 commit attempts per paste (rest stay inbox as candidates).
Portability
This bundle ships with references/ (dossier + report templates, extractor notes) — keep
that folder next to SKILL.md.
- Hermes: full pipeline.
requires_skillsabove must be installed; usesweb_extractandfact_storewhen available. - Other agents (Claude Code, Codex, …): standalone mode. No prerequisite skills needed.
Use any web-fetch/read tool for extraction, keep the same vault layout on disk
(
inbox/,knowledge/dossiers/), and replacefact_storecommits with dossier bullets only. Everything else — routing, source packs, claim gating, dossier merge, the report shape — works as written.
When to use
- Message is mostly a URL,
github.com/..., YouTube link, local path, or “learn this:” + paste - User says point the brain at X / ingest / absorb / remember this page
- After simple-second-brain exists (bootstrap vault if needed)
Do not use
- Pure chat questions with no source material
- Private credentials,
.env, keys (refuse commit; warn) - Huge monorepo without a path scope (ask once for subpath or fail closed to capture-only)
Modes
| Mode | Behavior |
|---|---|
auto (default) |
Capture all; auto-commit only high evidence claims |
capture-only |
Stop after inbox source pack |
draft |
Write commit candidates in inbox; do not fact_store/knowledge commit |
If user says “just save” → capture-only. If “don’t commit yet” → draft.
Process (pipeline)
0. Bootstrap
Ensure simple-second-brain vault exists, including dossiers:
ROOT="${HERMES_BRAIN:-$HOME/.hermes/hermes-brain}"
mkdir -p "$ROOT"/{inbox/_done,knowledge/dossiers,knowledge/areas,ideas,goals,daily,templates}
1. Route the paste
Detect one primary kind (first match wins):
| Kind | Signals | Extractor |
|---|---|---|
youtube |
youtube.com, youtu.be | transcript/title via youtube skill or web_extract / yt-dlp if available |
github |
github.com/... | README + tree summary; optional clone shallow if needed |
web |
http(s) URL | web_extract or browser |
pdf |
.pdf URL or path | pdf tools / extract text |
local_code |
existing path, or git@ |
read key files; don't dump whole tree |
raw_text |
multi-line paste, script, markdown | use as-is |
unknown |
capture raw + note kind unknown |
Write routing decision into the source pack frontmatter: kind:.
2. Extract (reality surface)
Always produce a source pack file under inbox:
inbox/YYYY-MM-DD-HHMM-ingest-<slug>.md
Must include:
---
status: inbox
captured: <ISO>
source: ingest
kind: youtube|web|github|...
origin: <url-or-path-or-paste>
mode: auto|capture-only|draft
---
# Ingest: <title>
## Origin
- <url or path>
## Extract summary
<what was fetched — tools used>
## Raw / excerpts
<blockquote or fenced excerpts with pointers>
## Claim candidates
1. ...
2. ...
Evidence rule: every later COMMIT must cite this file path and/or the origin URL.
If extract fails: still capture the paste + error; stop (no fake claims).
Done when: source pack path exists on disk.
3. Distill claims
From the extract, list atomic claim candidates (default max 12):
- One fact each, ≤20 words preferred
- Tag confidence:
high|medium|low high= directly stated in source with quote/spanmedium= clear paraphrase of one passagelow= inference → never auto-commit
Drop marketing fluff, undated superlatives, secrets.
4. Capture is already done
Source pack = capture. Optionally also append one line to daily/YYYY-MM-DD.md under ## Ingests.
5. Commit (auto mode only)
For each high claim (and medium only if user said “be aggressive”):
- Run
verified-brain-commit-ritualgates: evidence / scope / conflict - Evidence must point at origin + source pack path (+ quote)
- COMMIT → prefer
fact_storefor one-liners; always fold trusted bullets into the dossier in step 6 (do not scatter only into randomknowledge/ingest/files unless the dossier points at them) - INBOX on any fail — append to source pack under
## Held (gates failed)
Never commit low. Never commit secrets.
6. Dossier + what we know + so what (mandatory in auto and draft)
Slug: stable topic key from title/repo/video id (kebab-case, ≤60 chars).
Path: $ROOT/knowledge/dossiers/<slug>.md
6a. Write or update the dossier
- If file missing: create from
references/dossier-template.md - If file exists: merge — append new committed bullets under
## What we know(dedupe near-identical lines); add origin under## Sourcesif new; leave prior trusted bullets intact - Body rules:
## What we know= trusted only (this ingest’s commits + prior trusted on this topic from fact_store/knowledge)- Optional
## Untrusted / held= clearly labeled; never mixed into What we know - Each trusted bullet ends with a handle:
(src: origin)and/orfact_store#idand/or source_pack path - Frontmatter:
status: committed,updated: <ISO>,origins: […url…],slug:
capture-onlymode: skip dossier update (source pack only)
Done when: test -f dossier path and What we know has only trusted lines.
6b. Chat report
Return to user in this shape:
INGEST complete
origin: …
kind: …
source_pack: <abs path>
dossier: <abs path>
COMMITTED (trusted):
- claim … [fact_id or dossier]
HELD in inbox (untrusted):
- claim … (failed: evidence|scope|conflict|low-confidence)
WHAT WE KNOW NOW:
- <mirror dossier ## What we know — trusted only>
SO WHAT:
1. <action or decision implication>
2. <action or “none”>
3. <action or “none”>
Open questions:
- <gaps the source didn't answer>
Rules:
- Do not list held items under WHAT WE KNOW NOW
- SO WHAT is exactly 3 lines, numbered; derived only from trusted bullets (or “none — monitoring only”)
- Prefer concrete next steps (read X, try Y, watch Z) over vibes
Details: references/what-we-know-template.md, references/dossier-template.md.
Extractor cheatsheet
| Kind | Prefer |
|---|---|
| web | web_extract([url]) |
| youtube | youtube-content skill / transcript fetch; else page extract |
| github | raw README URL + web_extract; or shallow clone to /tmp and read |
| local_code | find/read_file on entrypoints + README only first |
| raw_text | save paste verbatim in source pack |
Details: references/extractors.md.
Bounded automation (non-negotiable)
- Idempotent-ish: same origin same day → update same slug or add
-2suffix; don't spam duplicates without checkingrg originin inbox/knowledge - Observable: always print source_pack path
- Fail closed: weak claims stay inbox
- Cap work: 12 commits; large codebases need a subpath
- No external publish
Verification checklist
- Source pack on disk with origin + kind
- Every COMMIT has gate report + evidence path
- Dossier path exists under
knowledge/dossiers/(auto/draft) - Dossier
## What we knowcontains only trusted items - Chat report includes
dossier:abs path + exactly 3 SO WHAT lines - User only pasted; agent didn't require a form unless blocked
NEVER
- Commit a
low-confidence claim, in any mode - Commit secrets (
.env, keys, credentials) — refuse and warn - Mix held/untrusted bullets into a dossier's
## What we know - Invent spoken claims for a YouTube video whose transcript failed to fetch
- Report WHAT WE KNOW in chat without the dossier file existing on disk
- Publish or send anything externally — this skill is local-only
Pitfalls
- Committing model summary without quotes from extract
- Treating whole article as one claim
- YouTube without transcript → capture titles only, don't invent spoken claims
- Ingesting secrets from a pasted
.env - Dumping WHAT WE KNOW only in chat without writing the dossier
- Mixing held/untrusted bullets into dossier
## What we know - SO WHAT longer than 3 lines or based on untrusted claims