From signal-loom
Enrich unenriched scraped articles into structured metadata using parallel sub-agents. Use after scraping, or when the user says "enrich", "/enrich", or "add metadata to the new articles".
How this skill is triggered — by the user, by Claude, or both
Slash command
/signal-loom:enrichThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Enriches scraped markdown files that lack an enrichment block, by dispatching parallel `enricher` sub-agents. The skill orchestrates; it performs **no validation or writing itself** — every raw result goes straight to `core.enrichment_writeback`, which owns validation, normalization, the security allow-list, and atomic writes. This keeps the interactive (sub-agent) and headless (API) paths iden...
Enriches scraped markdown files that lack an enrichment block, by dispatching parallel enricher sub-agents. The skill orchestrates; it performs no validation or writing itself — every raw result goes straight to core.enrichment_writeback, which owns validation, normalization, the security allow-list, and atomic writes. This keeps the interactive (sub-agent) and headless (API) paths identical.
Don't compute a config path manually — the core resolver discovers it. Order:
--config <path> if the user supplied one$CLAUDE_PLUGIN_OPTION_CONFIG_PATH (set by Claude Code userConfig)$SIGNAL_LOOM_CONFIG (legacy; deprecated)$CLAUDE_PROJECT_DIR (or cwd) looking for signal-loom.yaml,
.signal-loom.yaml, .signal-loom/config.yaml, or config/signal-loom.yamlIf the resolver finds nothing it errors with a "run init" hint — do NOT try to
write a default config from this skill. Tell the user to run the init skill
or python -m core.init --to . and stop.
Optional CLI override when the user explicitly names a config:
CONFIG_ARG=""
[ -n "${CONFIG:-}" ] && CONFIG_ARG="--config $CONFIG"
Find unenriched files. Read settings to locate content_dir:
uv run --project "${CLAUDE_PLUGIN_ROOT}" python -m core.config --print content_dir $CONFIG_ARG
(If that helper isn't available, default to content/.) List *.md files whose frontmatter lacks enriched: true.
Load the model + vocabulary the enrichers must use, from config: enrichment_model and the controlled topic vocabulary (topics_path). The sub-agents MUST be told the configured enrichment_model (do not hardcode a model) and the allowed primary-topic list — this is what keeps interactive enrichment consistent with the headless path.
Dispatch one enricher sub-agent per file, in parallel. The skill must inject into each sub-agent's prompt (as text — the agent has no tools and cannot read files):
${CLAUDE_PLUGIN_ROOT}/core/enrichment_spec.mdtopics_path)Each sub-agent returns a single ```yaml block. Use the configured enrichment_model for the dispatch.
Hand each raw result to writeback — do not transform it:
Security rule: never interpolate model output into a shell command. Write the sub-agent's raw output to a temp file first, then pass the temp file path to writeback via
--raw-file. This prevents$(…)/backtick command injection from untrusted model responses.
# Write the raw sub-agent output to a temp file (never echo it into a shell)
_tmpfile=$(mktemp)
printf '%s' "<raw output from sub-agent>" > "$_tmpfile"
uv run --project "${CLAUDE_PLUGIN_ROOT}" python -m core.enrichment_writeback apply "<path/to/file.md>" $CONFIG_ARG --raw-file "$_tmpfile"
rm -f "$_tmpfile"
Writeback validates against the schema (dropping any non-allow-listed keys), normalizes entities, and writes atomically. A malformed result is skipped and logged to the re-run queue — never crash the batch.
Report how many files were enriched, how many were skipped, and surface any entries in the re-run queue (failed-enrichments.jsonl).
core.enrichment_writeback is the single source of truth for that.agents/enricher.md); the enrichers have no tools and cannot act on injected instructions.uv run --project "${CLAUDE_PLUGIN_ROOT}" python -m core.index $CONFIG_ARG (or let /pipeline do it).npx claudepluginhub dwroblewski/signal-loom --plugin signal-loomCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.