feat(skills): author the Continuous Research skills, and make its roles honest
The boot log has said `continuous_research — 4 role skills bound, 8 unresolved`
on every start. Those eight roles ran without the instructions their template
promised them, silently: `skills_loader` reports the miss and carries on.
Worse than the missing files was what the prompts described. v1 told the
harvester to sweep "RSS feeds, GitHub trending, HN front page, YouTube /
podcast RSS" — none of which exist. `harvest.rs` searches arXiv and nothing
else. A role prompt describing a machine that was never built is the failure
this codebase keeps paying for, so v2 describes the machine that exists.
Roles now match the pipeline: paper_reader (the harvest already ran; read the
manifest and the papers), signal_ranker (unchanged in spirit), script_writer
(the podcast half, which had no role at all).
Seven skills authored under skills/research/, kebab-case to match the loader —
team_template_loader.rs:177-181 documents the snake_case/kebab-case trap that
already unbinds skills elsewhere:
arxiv-daily what the harvest guarantees, so an agent does
NOT re-search arXiv and corrupt the seen-set
paper-to-project-relevance name a file or roadmap item, or say "no bearing"
duplicate-detection the seen-set catches identity; this catches the
same work under a different id
signal-to-noise-ranking novelty/relevance/depth, and the two biases to
resist (recency up, inconvenience down)
executive-summary-writing what it is / why it matters / what to do — decide,
do not hedge
obsidian-vault-conventions the vault is a human's live workspace; never
main, never reorganise, hash the body not the file
podcast-dialogue-writing write for someone on a treadmill; the 10-70 char
highlight bound is the API's, not a style rule
`web_fetch` dropped from mcp_bundles: runtime_provision.rs binds every mission
claw to `["clawmates_door"]` and never reads that field, so declaring it
instructed roles to use a tool that never arrived. The prompts say `curl` via
Bash, which is what they actually have.
Boot now reports `continuous_research — 11 role skills bound`, with no
unresolved clause. 344 tests pass.
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
e20b321055
commit
a2d7e3ea92
@@ -0,0 +1,48 @@
|
|||||||
|
---
|
||||||
|
name: arxiv-daily
|
||||||
|
description: What the arXiv harvest already guarantees, and what an agent must therefore not redo.
|
||||||
|
when_to_use: You are working with a harvest manifest in a Continuous Research mission.
|
||||||
|
tags: [research, sources]
|
||||||
|
---
|
||||||
|
|
||||||
|
# The harvest is already done when you start
|
||||||
|
|
||||||
|
Searching arXiv is not your job. Before your phase launches, the server has
|
||||||
|
already run the harvest: searched each topic, checked the seen-set, downloaded
|
||||||
|
each new PDF, verified it, shelved it in blob storage and written a vault note.
|
||||||
|
It takes seconds and it is deterministic.
|
||||||
|
|
||||||
|
Your input is the result:
|
||||||
|
|
||||||
|
```
|
||||||
|
ContinuousResearch/<date>/harvest.jsonl
|
||||||
|
{ source, url, title, snippet, first_seen, topic_tags }
|
||||||
|
```
|
||||||
|
|
||||||
|
One line per paper that is **new since the last run**. Papers already covered
|
||||||
|
are not in it — by design, not omission.
|
||||||
|
|
||||||
|
## What that guarantees
|
||||||
|
|
||||||
|
- **No repeats across runs.** `corpus_items` is keyed `arxiv:<id>` with the
|
||||||
|
version suffix stripped, so `2401.12345v3` cannot reappear as new because
|
||||||
|
`v1` was seen. This is the entire reason a recurring mission is worth having.
|
||||||
|
- **Every shelved paper has a real PDF.** Fetched bytes are rejected unless they
|
||||||
|
start with `%PDF` — arXiv serves an HTML holding page while a paper renders,
|
||||||
|
and shelving that would leave an unreadable file behind a checkmark.
|
||||||
|
- **A failed download stays unseen.** The checkmark is written last, after the
|
||||||
|
PDF and the note are both on disk, so a paper that failed halfway is retried
|
||||||
|
next run rather than being lost behind a mark that says it was handled.
|
||||||
|
|
||||||
|
## What that means for you
|
||||||
|
|
||||||
|
- **Do not search arXiv yourself.** Anything you find outside the manifest is
|
||||||
|
either already covered or was deliberately not selected, and shelving it
|
||||||
|
outside the pipeline leaves the seen-set wrong.
|
||||||
|
- **Do not treat an empty manifest as a failure.** A quiet day is a real
|
||||||
|
outcome. Say "nothing new today" and stop — do not go looking for something to
|
||||||
|
talk about.
|
||||||
|
- **Do read the paper.** The manifest's `snippet` is a trimmed abstract, and the
|
||||||
|
abstract is the authors' pitch. `curl` the arXiv abstract page for the rest.
|
||||||
|
What a paper claims and what its evaluation shows differ often enough that
|
||||||
|
catching the gap is most of the value you add.
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
---
|
||||||
|
name: duplicate-detection
|
||||||
|
description: Recognising that two harvested items are the same work, and why the seen-set is not enough on its own.
|
||||||
|
when_to_use: You are processing a harvest manifest and must avoid covering the same work twice.
|
||||||
|
tags: [research, judgement]
|
||||||
|
---
|
||||||
|
|
||||||
|
# The same work wearing different clothes
|
||||||
|
|
||||||
|
The harvest already dedupes by identity: `corpus_items` keys papers by
|
||||||
|
`arxiv:NNNN.NNNNN` with the version suffix stripped, so `2401.12345v3` and
|
||||||
|
`2401.12345v1` are one paper and a paper already shelved never reappears. That
|
||||||
|
is exact-identity dedup, and it is done for you.
|
||||||
|
|
||||||
|
What it cannot catch is the same *work* arriving under a different identity.
|
||||||
|
|
||||||
|
## The cases the seen-set misses
|
||||||
|
|
||||||
|
- **A paper and its blog post.** Different URLs, same result. Cover the paper;
|
||||||
|
mention the post only if it adds an author's clarification.
|
||||||
|
- **Preprint then conference version.** Different arXiv id, often a different
|
||||||
|
title, sometimes months apart. If the contribution is the same, it is one
|
||||||
|
item — and the interesting fact is what changed in review.
|
||||||
|
- **The same group's incremental follow-up.** "X for Video" three months after
|
||||||
|
"X". Genuinely new, but the listener needs the earlier one as context, so
|
||||||
|
cover them together rather than as two unrelated items.
|
||||||
|
- **Two groups, one idea, same season.** Not duplicates. Say so explicitly —
|
||||||
|
independent convergence is itself a signal that the idea is real.
|
||||||
|
|
||||||
|
## How to decide
|
||||||
|
|
||||||
|
Compare on **contribution**, not on title or authors:
|
||||||
|
|
||||||
|
1. What does it claim that nobody claimed before?
|
||||||
|
2. What experiment supports that specific claim?
|
||||||
|
|
||||||
|
If two items give the same answer to both, they are one item. If they differ on
|
||||||
|
either, they are two — even from the same lab, even with near-identical titles.
|
||||||
|
|
||||||
|
## When you merge, say so
|
||||||
|
|
||||||
|
Never silently drop the second one. A merged entry states it:
|
||||||
|
|
||||||
|
> Also appeared as a NeurIPS submission with an extra ablation; same core
|
||||||
|
> result, so covered once here.
|
||||||
|
|
||||||
|
Silent dedup is indistinguishable from a harvest that missed something, and the
|
||||||
|
whole point of a standing sweep is knowing which of the two happened.
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
---
|
||||||
|
name: executive-summary-writing
|
||||||
|
description: Writing the three-part item entry — what it is, why it matters to us, what to do — so a digest is readable in two minutes.
|
||||||
|
when_to_use: You are writing digest or analysis entries for harvested research items.
|
||||||
|
tags: [research, writing]
|
||||||
|
---
|
||||||
|
|
||||||
|
# The three-part entry
|
||||||
|
|
||||||
|
Every item gets exactly three parts. The shape is the discipline: it makes the
|
||||||
|
omissions visible.
|
||||||
|
|
||||||
|
**What it is** — one sentence, what they actually did. Not what it enables, not
|
||||||
|
why it is exciting. If you cannot state the contribution in one sentence you
|
||||||
|
have not finished reading.
|
||||||
|
|
||||||
|
**Why it matters to us** — the named project, file or open question it touches.
|
||||||
|
If nothing applies, the item does not belong in the digest. That rule is what
|
||||||
|
keeps a digest from becoming a feed.
|
||||||
|
|
||||||
|
**What to do about it** — one decision, from a closed set:
|
||||||
|
|
||||||
|
```
|
||||||
|
read fully worth an hour of someone's time
|
||||||
|
add to backlog a concrete change we should make
|
||||||
|
ignore seen, judged, not for us
|
||||||
|
escalate changes a plan we are currently executing
|
||||||
|
```
|
||||||
|
|
||||||
|
## Decide; do not hedge
|
||||||
|
|
||||||
|
"Consider evaluating whether this might inform our approach" is four words of
|
||||||
|
decision wrapped in ten of insulation. Write `ignore` or write `add to backlog`.
|
||||||
|
Being wrong in a specific direction is recoverable; being vague is not, because
|
||||||
|
nobody can tell later whether the call was right.
|
||||||
|
|
||||||
|
## Two minutes, total
|
||||||
|
|
||||||
|
Not two minutes per item — two minutes for the digest. Five items at three
|
||||||
|
sentences each is roughly the budget. If an item needs more, it is not a digest
|
||||||
|
entry, it is a reading note: link to it and keep the entry short.
|
||||||
|
|
||||||
|
## Frontmatter carries the ratio
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
date: 2026-08-17
|
||||||
|
harvested: 23
|
||||||
|
surfaced: 4
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
Harvested-versus-surfaced tracked over time is how you notice selectivity drift.
|
||||||
|
A run that surfaces everything has stopped filtering; a run that surfaces
|
||||||
|
nothing for a week is either a quiet field or a broken harvest, and the counts
|
||||||
|
are what tell you which.
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
---
|
||||||
|
name: obsidian-vault-conventions
|
||||||
|
description: Writing into a live Obsidian vault a human also edits — frontmatter, links, paths, and what never to touch.
|
||||||
|
when_to_use: You are committing notes, digests or scripts into the valhalla-vault repository.
|
||||||
|
tags: [research, conventions]
|
||||||
|
---
|
||||||
|
|
||||||
|
# The vault is somebody's live workspace
|
||||||
|
|
||||||
|
`valhalla-vault` is a real Obsidian vault a human edits and syncs continuously.
|
||||||
|
It is not scratch space. Two consequences drive everything below.
|
||||||
|
|
||||||
|
## Never commit to `main`
|
||||||
|
|
||||||
|
Mission work lands on the run's own branch. `library.rs` does this deliberately
|
||||||
|
and only auto-merges when the change is provably additive — every file in
|
||||||
|
`git diff --name-status base...branch` is an `A`. A rename or a delete is not
|
||||||
|
additive and stops the merge.
|
||||||
|
|
||||||
|
That rule protects the human: an auto-merge can add a note beside their work,
|
||||||
|
never rewrite it.
|
||||||
|
|
||||||
|
## Stay in your folders
|
||||||
|
|
||||||
|
```
|
||||||
|
60 Papers/arxiv-<id>.md one note per paper, written by the harvest
|
||||||
|
ContinuousResearch/<date>/... one folder per run — yours
|
||||||
|
```
|
||||||
|
|
||||||
|
Do not reorganise, rename or "tidy" anything outside those. What looks like a
|
||||||
|
stray file is usually load-bearing in someone's graph.
|
||||||
|
|
||||||
|
## Frontmatter is the index
|
||||||
|
|
||||||
|
Obsidian queries it, so it must be parseable YAML and keys must stay stable:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
date: 2026-08-17
|
||||||
|
type: research-digest
|
||||||
|
harvested: 23
|
||||||
|
surfaced: 4
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
**Hash the body, not the file.** Sync rewrites `updated:` and `size_kb:` on
|
||||||
|
notes it touches; hashing the whole file reports phantom edits on notes nobody
|
||||||
|
changed and makes "unchanged" meaningless.
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
`[[wikilinks]]` are the vault's native form — use them for internal references,
|
||||||
|
plain markdown links for external URLs. A link to a note that does not exist yet
|
||||||
|
is fine and idiomatic: it marks something worth writing.
|
||||||
|
|
||||||
|
## `source:` is not identity
|
||||||
|
|
||||||
|
The vault uses `source:` for local provenance — often a path like
|
||||||
|
`/Users/…/Downloads/paper.pdf`. It is not a citable identifier and must never be
|
||||||
|
used as a dedup key. Identity is `arxiv:<id>`, version suffix stripped.
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
---
|
||||||
|
name: paper-to-project-relevance
|
||||||
|
description: How to judge whether a paper actually bears on one of the operator's projects, and how to say so concretely instead of vaguely.
|
||||||
|
when_to_use: You are reading harvested papers in a Continuous Research mission and must decide which ones matter and why.
|
||||||
|
tags: [research, judgement]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Does this paper bear on our work?
|
||||||
|
|
||||||
|
The value of a research digest is not that it lists papers. It is that it tells
|
||||||
|
you which of *your* problems just got easier. A summary that could have been
|
||||||
|
written without knowing anything about the operator's projects has failed, no
|
||||||
|
matter how accurate it is.
|
||||||
|
|
||||||
|
## The test
|
||||||
|
|
||||||
|
For each paper, answer in this order. Stop at the first "no".
|
||||||
|
|
||||||
|
1. **Is the claim real?** What did they actually measure, on what, against what
|
||||||
|
baseline? A 40% speedup on a benchmark nobody runs is not a 40% speedup.
|
||||||
|
2. **Does it touch a problem we have?** Not a problem in the same *field* — a
|
||||||
|
problem in the project brief. "Vector search" is a field. "Our HNSW insert
|
||||||
|
loop is serial and the ROADMAP flags it as needing a correctness pass" is a
|
||||||
|
problem.
|
||||||
|
3. **Would we do anything differently?** If the honest answer is "no, but it's
|
||||||
|
interesting", say exactly that. It is a legitimate outcome and it costs the
|
||||||
|
listener five seconds instead of two minutes.
|
||||||
|
|
||||||
|
## Say the specific thing
|
||||||
|
|
||||||
|
Weak, and useless to act on:
|
||||||
|
|
||||||
|
> This work on graph pruning could be relevant to vector search performance.
|
||||||
|
|
||||||
|
Strong, because it names the target and the change:
|
||||||
|
|
||||||
|
> They prune by neighbour-degree rather than distance, which is the same
|
||||||
|
> decision `clawhdf5-ann/src/hnsw.rs` makes in `prune_connections`. Ours is
|
||||||
|
> already rayon-parallel per node, so this is a swap of the scoring function,
|
||||||
|
> not a restructure — maybe 30 lines. Worth trying because our ROADMAP lists
|
||||||
|
> recall regression at high M as an open question, and that is exactly what
|
||||||
|
> their Table 3 measures.
|
||||||
|
|
||||||
|
Name a file, a function, a roadmap item, or an open question. If you cannot name
|
||||||
|
one, you have not established relevance — you have established topic overlap.
|
||||||
|
|
||||||
|
## Honest negatives are the point
|
||||||
|
|
||||||
|
Most papers will not bear on the work. Recording that plainly is what makes the
|
||||||
|
positives trustworthy. One line is enough:
|
||||||
|
|
||||||
|
> No bearing — single-GPU training throughput, we do no training.
|
||||||
|
|
||||||
|
A run where everything is relevant is a run that stopped judging.
|
||||||
|
|
||||||
|
## What NOT to do
|
||||||
|
|
||||||
|
- **Do not infer relevance from keyword overlap.** Sharing the word "agent"
|
||||||
|
with our codebase is not a connection.
|
||||||
|
- **Do not soften a negative into a maybe.** "Could potentially inform future
|
||||||
|
work" is how a digest becomes unreadable.
|
||||||
|
- **Do not review from the title or the abstract's claims.** The note carries
|
||||||
|
the abstract; the paper is one `curl` away. What a paper *says* it does and
|
||||||
|
what its evaluation *shows* are routinely different, and catching that gap is
|
||||||
|
most of the value you add.
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
---
|
||||||
|
name: podcast-dialogue-writing
|
||||||
|
description: How to turn a paper analysis into a two-host script someone can follow while running, and the hard limits the audio API imposes.
|
||||||
|
when_to_use: You are writing the script phase of a Continuous Research mission, turning analysis.md into script.md and episode.json.
|
||||||
|
tags: [research, writing]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Writing for someone on a treadmill
|
||||||
|
|
||||||
|
The listener is not at a desk. They cannot scroll back, they cannot see a table,
|
||||||
|
and they are half-listening. Everything follows from that.
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
|
||||||
|
Lead with the conclusion, then support it. A paper-by-paper walk is the wrong
|
||||||
|
shape: the listener does not know which papers matter until you tell them, and
|
||||||
|
by then the first one is gone.
|
||||||
|
|
||||||
|
```
|
||||||
|
COLD OPEN one sentence: the single thing that changed today
|
||||||
|
THE MAIN the paper that actually matters, 3-4 minutes
|
||||||
|
THE REST two or three, a minute each
|
||||||
|
NOTHING what you looked at and dismissed, 20 seconds
|
||||||
|
```
|
||||||
|
|
||||||
|
"Nothing" is not filler. Knowing that eleven papers were read and eight did not
|
||||||
|
matter is what makes the three that did credible.
|
||||||
|
|
||||||
|
## Two hosts, with a reason to be two
|
||||||
|
|
||||||
|
HOST carries the thread and asks what the listener would ask. GUEST has read the
|
||||||
|
paper and answers. The reason for a second voice is that disagreement and
|
||||||
|
"wait, why?" are easier to follow than monologue — not that alternating names
|
||||||
|
looks like a script.
|
||||||
|
|
||||||
|
Bad, because these are one voice cut in half:
|
||||||
|
|
||||||
|
> HOST: The paper introduces a new pruning method.
|
||||||
|
> GUEST: Yes, and it improves recall by 12%.
|
||||||
|
|
||||||
|
Good, because the second voice is doing work:
|
||||||
|
|
||||||
|
> HOST: Twelve percent recall — is that on a benchmark we'd care about?
|
||||||
|
> GUEST: That's the catch. It's on SIFT1M, which is a million 128-dim vectors.
|
||||||
|
> Our embeddings are 1536-dim and we're at about 40,000. So the shape of
|
||||||
|
> their win might not survive at our dimensionality.
|
||||||
|
|
||||||
|
## Say numbers the ear can hold
|
||||||
|
|
||||||
|
"Roughly a third faster" beats "34.7% faster". "About a million vectors" beats
|
||||||
|
"1,000,000". Read every line aloud in your head; if you stumble, the TTS will
|
||||||
|
too.
|
||||||
|
|
||||||
|
Never write anything the listener cannot hold: no URLs, no arXiv ids, no table
|
||||||
|
references, no "as shown in Figure 4". If they need the citation it is in the
|
||||||
|
vault note.
|
||||||
|
|
||||||
|
## Hard limits, not style preferences
|
||||||
|
|
||||||
|
`episode.json` is consumed by the audio API, and these bounds are enforced by it:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "title": "<one line, under 80 characters>",
|
||||||
|
"highlights": ["<each 10-70 characters>", "..."] }
|
||||||
|
```
|
||||||
|
|
||||||
|
- **At most 5 highlights**, each **10–70 characters**. Outside that range the
|
||||||
|
request is rejected, not truncated.
|
||||||
|
- Target **seven minutes of speech, roughly 1,000 words**. Audio quality
|
||||||
|
degrades on long single generations, so a sprawling script produces a worse
|
||||||
|
episode, not just a longer one.
|
||||||
|
|
||||||
|
## Cut rather than pad
|
||||||
|
|
||||||
|
If only one paper mattered, write a four-minute episode about one paper. An
|
||||||
|
episode padded to length with work that did not matter trains the listener to
|
||||||
|
skip, and once they skip, the whole pipeline is worthless.
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
---
|
||||||
|
name: signal-to-noise-ranking
|
||||||
|
description: Scoring harvested items on novelty, relevance and depth so a digest surfaces the few that matter.
|
||||||
|
when_to_use: You are ranking harvested research items before deciding which reach the digest or the podcast.
|
||||||
|
tags: [research, judgement]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Ranking signal against noise
|
||||||
|
|
||||||
|
Score each item on three axes, 0–3. Sum them. The sum decides where it goes, and
|
||||||
|
the axes exist so that a high score has to be earned in more than one way.
|
||||||
|
|
||||||
|
## The axes
|
||||||
|
|
||||||
|
**Novelty (0–3)** — how different is this from what we have already seen on this
|
||||||
|
topic in the last 30 days? A fourth paper making the same claim is a 0 even if
|
||||||
|
the claim is important. Recency is not novelty: something published today that
|
||||||
|
restates last month's result is still a 0.
|
||||||
|
|
||||||
|
**Relevance (0–3)** — how directly does it connect to a named project or open
|
||||||
|
question? Not the field — the project. See `paper-to-project-relevance`. If you
|
||||||
|
cannot name the thing it touches, this is at most a 1.
|
||||||
|
|
||||||
|
**Depth (0–3)** — is this a primary source with an evaluation, or the fifth blog
|
||||||
|
post about someone else's paper? A primary source with a weak evaluation can
|
||||||
|
still beat a good summary of it, because you can check the former.
|
||||||
|
|
||||||
|
## Thresholds
|
||||||
|
|
||||||
|
```
|
||||||
|
>= 6 goes in the digest / the episode
|
||||||
|
>= 4 goes to watchlist.md — worth knowing, not worth airtime
|
||||||
|
< 4 dropped from the digest, KEPT in the raw manifest
|
||||||
|
```
|
||||||
|
|
||||||
|
Dropped is not deleted. The manifest is the audit trail: "we saw it and passed"
|
||||||
|
is a different and more useful record than silence, and it is what lets you
|
||||||
|
notice later that the ranking was wrong.
|
||||||
|
|
||||||
|
## Two failure modes to resist
|
||||||
|
|
||||||
|
- **Up-ranking the recent.** Time is not a quality signal. A preprint from this
|
||||||
|
morning gets no credit for being from this morning.
|
||||||
|
- **Down-ranking the inconvenient.** A paper that contradicts the approach we
|
||||||
|
are currently taking is *high* signal, not low. The temptation to score it
|
||||||
|
down is exactly why it needs airtime.
|
||||||
|
|
||||||
|
## Escape hatch
|
||||||
|
|
||||||
|
Anything the operator has explicitly flagged bypasses scoring entirely. A human
|
||||||
|
saying "look at this" outranks the rubric; the rubric exists for the other
|
||||||
|
several hundred items.
|
||||||
@@ -1,44 +1,66 @@
|
|||||||
key = "continuous_research"
|
key = "continuous_research"
|
||||||
name = "Continuous Research"
|
name = "Continuous Research"
|
||||||
description = "Standing scan across all monitored data sources + media types — news, blogs, papers, code releases, talks — for the latest signal on tracked topics. Runs on schedule; produces a rolling daily digest."
|
description = "Reads each day's newly harvested arXiv papers against the operator's active projects and writes a two-host podcast script."
|
||||||
stack = ["research", "monitoring", "digest", "obsidian", "rss", "podcasts"]
|
stack = ["research", "papers", "digest", "obsidian", "podcast"]
|
||||||
category = "research"
|
category = "research"
|
||||||
default_topology = "pipeline"
|
default_topology = "pipeline"
|
||||||
risk_profile = "research_readonly"
|
risk_profile = "research_readonly"
|
||||||
mcp_bundles = ["clawmates_door", "clawmates_skills", "web_fetch"]
|
# `web_fetch` was declared here and is INERT: runtime_provision.rs binds every
|
||||||
version = 1
|
# mission claw to `mcp_bundles = ["clawmates_door"]` and never reads this field.
|
||||||
|
# Agents reach a paper with `curl` through Bash instead, which the prompts say.
|
||||||
|
# Listing a bundle that does not arrive is how a role ends up instructed to use
|
||||||
|
# a tool it does not have.
|
||||||
|
mcp_bundles = ["clawmates_door", "clawmates_skills"]
|
||||||
|
version = 2
|
||||||
|
|
||||||
|
# v2 aligns the roles with the pipeline that actually exists.
|
||||||
|
#
|
||||||
|
# v1 told the harvester to sweep "RSS feeds, GitHub trending, HN front page,
|
||||||
|
# YouTube / podcast RSS". None of those are implemented — `harvest.rs` searches
|
||||||
|
# arXiv and nothing else — and 8 of its 12 skills did not exist, so those roles
|
||||||
|
# ran with neither the sources nor the instructions they were promised. A role
|
||||||
|
# prompt describing a machine that was never built is the failure this codebase
|
||||||
|
# keeps paying for, so the prompts below describe the machine that exists.
|
||||||
|
|
||||||
[[roles]]
|
[[roles]]
|
||||||
slot = "signal_harvester"
|
slot = "paper_reader"
|
||||||
order_idx = 0
|
order_idx = 0
|
||||||
skills = ["rss-fetch", "arxiv-daily", "github-trending", "web-search-triage", "decompose-int-items"]
|
skills = ["arxiv-daily", "paper-to-project-relevance", "duplicate-detection"]
|
||||||
system_prompt = """
|
system_prompt = """
|
||||||
You are the SIGNAL HARVESTER of a Continuous Research team.
|
You are the PAPER READER of a Continuous Research team.
|
||||||
|
|
||||||
Every run: sweep the operator's tracked topics across every configured
|
The harvest has already run before you start. Your input is
|
||||||
source — arXiv daily new-listings, RSS feeds (blogs / news / vendor
|
`ContinuousResearch/<date>/harvest.jsonl` — one line per paper that is NEW since
|
||||||
release notes), GitHub trending in tracked languages, HN front page
|
the last run, already downloaded and catalogued. Do not search arXiv yourself:
|
||||||
filtered by keyword, YouTube / podcast RSS for tracked speakers.
|
anything outside that manifest is either already covered or was deliberately not
|
||||||
|
selected, and shelving it outside the pipeline corrupts the seen-set.
|
||||||
|
|
||||||
Capture into `ContinuousResearch/<date>/harvest.jsonl`:
|
For each paper, read past the abstract (`curl` the arXiv abstract page) and
|
||||||
`{ source, url, title, snippet, first_seen, topic_tags }`. Dedup
|
write an entry in `ContinuousResearch/<date>/analysis.md`:
|
||||||
against yesterday's harvest by url + normalized title. Never guess
|
|
||||||
tags; use only tags from the operator's tracked list.
|
- what it actually did — the experiment, not the pitch
|
||||||
|
- whether the evidence supports the claim
|
||||||
|
- which of the operator's projects it bears on, naming a file, module or
|
||||||
|
roadmap item — or one line saying it bears on none
|
||||||
|
|
||||||
|
An empty manifest is a real outcome: say "nothing new today" and stop. A paper
|
||||||
|
with no bearing is also a real outcome, and recording it plainly is what makes
|
||||||
|
the ones that do bear credible.
|
||||||
"""
|
"""
|
||||||
brain_seed = """
|
brain_seed = """
|
||||||
# Signal harvester memory seed
|
# Paper reader memory seed
|
||||||
|
|
||||||
## Sources
|
|
||||||
- arXiv daily new listings for each subject class in the tracked topics
|
|
||||||
- RSS feeds (curated list; do not add without operator approval)
|
|
||||||
- GitHub trending (filter by tracked language + tracked topic)
|
|
||||||
- HN + Lobsters + subreddit filters
|
|
||||||
- YouTube / Podcast RSS
|
|
||||||
|
|
||||||
## Redlines
|
## Redlines
|
||||||
- Never fabricate `first_seen`. Use the source's own timestamp.
|
- Never review a paper from its title or its abstract's claims alone. What a
|
||||||
- Do not inflate topic tags to broaden reach — precision is the whole
|
paper says it does and what its evaluation shows differ often enough that
|
||||||
point of a standing sweep.
|
catching the gap is most of the value.
|
||||||
|
- Never manufacture relevance. Topic overlap is not relevance; naming the file
|
||||||
|
or open question it touches is.
|
||||||
|
- Never go looking for extra papers to fill a quiet day.
|
||||||
|
|
||||||
|
## Identity
|
||||||
|
- A paper is `arxiv:<id>` with the version suffix stripped. `2401.12345v3` and
|
||||||
|
`2401.12345v1` are one paper.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
[[roles]]
|
[[roles]]
|
||||||
@@ -48,61 +70,61 @@ skills = ["signal-to-noise-ranking", "duplicate-detection", "workspace-repo-comm
|
|||||||
system_prompt = """
|
system_prompt = """
|
||||||
You are the SIGNAL RANKER of a Continuous Research team.
|
You are the SIGNAL RANKER of a Continuous Research team.
|
||||||
|
|
||||||
Score each harvested item on 3 axes (0..3):
|
Score each analysed paper 0..3 on Novelty, Relevance and Depth, and sum:
|
||||||
|
|
||||||
- Novelty: how different is this from what we've seen in the last 30
|
>= 6 goes in the episode
|
||||||
days on the same topic?
|
>= 4 goes to `ContinuousResearch/<date>/watchlist.md`
|
||||||
- Relevance: how directly does it connect to an active project or an
|
< 4 dropped from the episode, KEPT in the manifest for audit
|
||||||
open question in the vault?
|
|
||||||
- Depth: is this a primary source, or the 5th blog rehash of a paper?
|
|
||||||
|
|
||||||
Sum the axes; anything ≥ 6 goes to the daily digest, ≥ 4 goes to
|
Dropped is not deleted. "We saw it and passed" is a more useful record than
|
||||||
`ContinuousResearch/<date>/watchlist.md`, below is silently dropped
|
silence, and it is what lets someone notice later that the ranking was wrong.
|
||||||
(but kept in the raw jsonl for auditability).
|
|
||||||
"""
|
"""
|
||||||
brain_seed = """
|
brain_seed = """
|
||||||
# Signal ranker memory seed
|
# Signal ranker memory seed
|
||||||
|
|
||||||
## Redlines
|
## Redlines
|
||||||
- Do not up-rank items just because they're recent. Time is not a
|
- Recency is not quality. A preprint from this morning earns nothing for being
|
||||||
quality signal.
|
from this morning.
|
||||||
- Do not down-rank items because they contradict our current line of
|
- A paper that contradicts our current approach is HIGH signal. The urge to
|
||||||
work. Contradiction is high-signal.
|
score it down is exactly why it needs airtime.
|
||||||
|
|
||||||
## Escape hatches
|
## Escape hatch
|
||||||
- Anything with `[operator-attention]` tag from the harvester bypasses
|
- Anything the operator flagged explicitly bypasses scoring. A human saying
|
||||||
scoring — the operator explicitly flagged it.
|
"look at this" outranks the rubric.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
[[roles]]
|
[[roles]]
|
||||||
slot = "digest_writer"
|
slot = "script_writer"
|
||||||
order_idx = 2
|
order_idx = 2
|
||||||
skills = ["executive-summary-writing", "obsidian-vault-conventions", "workspace-repo-commit-protocol", "small-focused-commits"]
|
skills = ["podcast-dialogue-writing", "executive-summary-writing", "obsidian-vault-conventions", "workspace-repo-commit-protocol", "small-focused-commits"]
|
||||||
system_prompt = """
|
system_prompt = """
|
||||||
You are the DIGEST WRITER of a Continuous Research team.
|
You are the SCRIPT WRITER of a Continuous Research team.
|
||||||
|
|
||||||
Every run: produce `ContinuousResearch/<date>/digest.md` — the top 5
|
Turn the analysis into `ContinuousResearch/<date>/script.md` — a conversation
|
||||||
highest-scored items with 3-sentence writeups each. Structure:
|
between HOST and GUEST — plus `ContinuousResearch/<date>/episode.json`:
|
||||||
|
|
||||||
- **What it is** (single sentence)
|
{ "title": "<one line, under 80 chars>",
|
||||||
- **Why it matters to us** (link to the affected project or open
|
"highlights": ["<10-70 chars each, at most 5>"] }
|
||||||
question in the vault)
|
|
||||||
- **What to do about it** (one action: read fully / add to backlog /
|
|
||||||
ignore / escalate)
|
|
||||||
|
|
||||||
The digest is what the operator actually reads. If it's not readable in
|
Those bounds are the audio API's and are enforced: a highlight outside them is
|
||||||
2 minutes, it failed.
|
rejected, not trimmed.
|
||||||
|
|
||||||
|
The listener is on a treadmill. Lead with what changed for our projects, not
|
||||||
|
with a list of papers. Target seven minutes, roughly 1,000 words. If only one
|
||||||
|
paper mattered, write four minutes about one paper — an episode padded with work
|
||||||
|
that did not matter teaches the listener to skip.
|
||||||
"""
|
"""
|
||||||
brain_seed = """
|
brain_seed = """
|
||||||
# Digest writer memory seed
|
# Script writer memory seed
|
||||||
|
|
||||||
## Discipline
|
## Discipline
|
||||||
- The "why it matters" sentence always links to an internal vault node.
|
- The second voice must do work — ask what the listener would ask, push back.
|
||||||
If none applies, the item shouldn't be in the digest.
|
Alternating names over one voice cut in half is not a dialogue.
|
||||||
- The "what to do about it" is a decision, not a hedge. Never write
|
- Say the specific thing: "this changes how we prune the HNSW graph in
|
||||||
"consider evaluating" — pick one.
|
clawhdf5" beats "researchers propose a novel method".
|
||||||
|
- Nothing the ear cannot hold: no URLs, no arXiv ids, no figure references.
|
||||||
|
|
||||||
## Format
|
## Format
|
||||||
- Frontmatter carries the run date + total items harvested vs surfaced
|
- Frontmatter carries the run date and harvested-vs-surfaced counts, so
|
||||||
ratio so we track selectivity drift over time.
|
selectivity drift is visible over time.
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user