A real, fully-offline
learnrun over a made-up corpus (examples/demo-corpus.txt). Recorded from the real run bydocs/record-demo.py(asciicast +agg); the idle synthesis wait is time-compressed. A VHS recipe is indocs/demo.tape.
Skill3 is a lightweight Java CLI that relearns a technical skill for an AI
agent. It discovers documentation sources, scores them for authority and
freshness (anchored to a target model's knowledge cutoff), synthesizes them
with a local LLM into an Agent Skills SKILL.md, and vets the result with
NVIDIA's SkillSpector.
The point: a model only knows what existed before its training cutoff. Skill3 gathers what changed after that cutoff and bakes it into a skill the agent can load — so it stops emitting deprecated patterns.
- General — no skill is hardcoded; the model plans the searches and freshness is driven by a cutoff date, so it works for any topic (technical or not).
- Delta, not primer — a generated skill covers only what changed after the cutoff and tells the model to rely on existing knowledge for the rest.
- Local-first — by default synthesis runs on a local LLM (Ollama), so the only external service is discovery (Brave Search). A hosted provider (any OpenAI-compatible gateway, or Claude via the native SDK) is opt-in.
- Cutoff-anchored — the discovery window is bounded by the target model's cutoff (below) and today (above), so results are the slice the model doesn't already know.
- Quality-gated — the build runs Error Prone, PMD, SpotBugs and ArchUnit, and ships compile-time AI guardrails via VibeTags.
See docs/SPEC.md for the full specification, docs/ARCHITECTURE.md for the design, and docs/PLAN.md for the roadmap.
A large language model is trained on a snapshot of the world that ends on a fixed date: its knowledge cutoff. Everything before that date the model may know; everything after it the model has simply never seen. Claude Opus 4.8, for example, has a cutoff of January 2026 — ask it about anything from February 2026 onward and it will either say it doesn't know, or (worse) confidently answer using stale, pre-cutoff information.
The cutoff is not a bug to be patched; it's a hard property of how the model was trained. You can't retrain the model, but you can hand it the missing slice of the world at runtime. That is the entire premise of Skill3:
Take a topic and a model's cutoff date, gather only what changed after that date, and compile it into a
SKILL.mdthe agent loads — so it answers from current reality instead of stale memory.
Concretely, the cutoff date drives a date-bounded web search: discovery starts at the
cutoff and ends today (2026-01-01to<today>), so the pipeline spends its effort on
material the model could not possibly already know, rather than re-summarising what it
learned in training. Everything else — authority scoring, freshness ranking, local
synthesis, vetting — exists to turn that fresh slice into something an agent can trust.
This works for any topic, not just code (see the examples — a software protocol and current events). The cutoff is the dial; the skill is the output.
The cleanest illustration of the problem Skill3 solves is the Model Context Protocol.
MCP revisions are date-versioned (2024-11-05 → 2025-03-26 → 2025-06-18), and the
changes between them are not backward-compatible: a new HTTP transport, a required
MCP-Protocol-Version header, removed JSON-RPC batching, new primitives like elicitation.
A model trained before mid-2025 confidently emits the old protocol — wrong transport, missing header, assumptions that silently break real integrations. That's exactly the post-cutoff drift Skill3 targets: anchor discovery at the model's cutoff, pull what changed since, and bake it into a skill the agent loads.
See the generated example: examples/SKILL-mcp.md — an MCP skill
centred on protocol versioning and revision negotiation.
Skill3 is a linear pipeline (LearnPipeline). The synthesis model (local Ollama by
default, or a hosted provider) is used at four points — to plan the searches, to
synthesize the skill, optionally to verify it, and to revise it during
vetting. Brave does discovery and SkillSpector does safety vetting.
┌──────── Phase 0: Plan (model) ─────────┐
topic + cutoff ► QueryPlanner → N post-cutoff queries │ topic-agnostic; no per-topic logic
└──────────────────┬─────────────────────┘
▼
┌──────────── Phase 1: Discovery & Retrieval ─────────────┐
per query ─► Brave Search ─► fetch pages (parallel) ─► extract dates ─► score authority
└───────────────────────────────────────────┬───────────┘
▼
┌──────────────── Phase 2: Ranking ──────────────┐
│ consensus (prune lonely code blocks) │ ranked ContextBundle
│ freshness: cutoff ≤ published ≤ today │ (future-dated dropped)
│ authoritative hosts ranked first │
└──────────────────────────────┬─────────────────┘
▼
┌──────── Phase 3: Synthesis (model) ────────┐
│ model drafts a post-cutoff DELTA │ ← post-processor, not the model,
│ deterministic post-processor guarantees │ guarantees the frontmatter
│ spec-compliant frontmatter + footer │
└──────────────────────┬─────────────────────┘
▼
┌──── Phase 3b: Verify (model, --verify) ────┐
│ re-ground each claim against the sources; │ optional accuracy gate
│ demote future-dated releases to "planned" │
└──────────────────────┬─────────────────────┘
▼
┌──────── Phase 4: Vetting (SkillSpector) ────┐
│ static scan → findings │
│ self-correction loop revises (bounded) │
└──────────────────────┬─────────────────────┘
▼
skills/<topic>/SKILL.md (+ index.html preview)
| Stage | Component | Where | Notes |
|---|---|---|---|
| Plan | QueryPlanner (the synthesis model) |
model | Topic-agnostic: the model expands the topic into up to 6 post-cutoff facet queries (it already knows the topic, so it knows what might have changed). No hardcoded per-topic logic. |
| Discover | Brave Search API → web scraper fallback, or --input-file (FileCorpus) |
Network / offline | Runs every planned query (freshness-windowed); needs an API key. Or skip the network entirely and supply a user-curated corpus file — see Offline discovery. |
| Fetch | RetrievalService over virtual threads |
Network | Merges/de-dupes URLs across queries, then fetches concurrently (one virtual thread per URL); results merged on the caller thread. |
| Date / authority | DateExtractor, AuthorityScorer |
Local | Published-date extraction + per-host trust; --authoritative hosts rank first. |
| Rank | IngestionPipeline (ConsensusValidator, FreshnessFilter) |
Local | Code kept only with cross-source agreement; freshness anchored to the cutoff and bounded above by today (future-dated sources dropped). |
| Synthesize | synthesis model + SkillMdPostProcessor |
model + local | Model drafts a post-cutoff delta; the post-processor — not the model — guarantees valid frontmatter and stamps the footer. |
| Verify (opt-in) | Verifier (--verify) |
model | Re-grounds every claim against the sources; removes unsupported claims, demotes future-dated releases. Worthwhile only with a capable model. |
| Vet | SkillSpectorRunner + SelfCorrectionLoop |
Local | Static safety scan; re-drafts on findings (bounded iterations). "Clean" means safe, not necessarily accurate — hence Verify. |
With the default local provider, only Discover leaves the machine — planning,
synthesis, verification, and vetting are all local. Choosing --llm-provider openai
or anthropic moves the model calls to a hosted endpoint.
| Guide | What is in it |
|---|---|
| Install | Requirements, build, SkillSpector setup, Brave key |
| Usage | Every learn flag, --input-file, model choice, the cutoff window |
| Architecture | How it is structured and why — with generated diagrams |
| Specification | Full behavioural spec |
| Development | Build gates, releases, AI guardrails |
| Example output | A complete run, start to finish |
| Roadmap | What is planned next |
skill3 is built and maintained by a single developer in his spare time. If it saves you time, a small donation helps keep the project alive:
- Donate via PayPal — every contribution, however small, is appreciated.
- Don't have PayPal yet? Sign up with this invite link — free for you, and PayPal gives the project a referral bonus.
Apache-2.0 — see LICENSE.
