scaccogatto/okf-skills/backfill
Claude Code and agent skill by scaccogatto/okf-skills
- community
Checking that the SKILL.md file is still in the repository.
Reconstruct an OKF bundle by event-sourcing a repository's history (git log and Claude session transcripts). Use when creating an `.okf/` bundle for an existing repository that predates this skill, or when resuming an interrupted backfill session. Triggers on: "reconstruct the OKF bundle", "backfill the knowledge bundle", "event-source the history".
Install
npx vskill@latest install scaccogatto/okf-skills/backfillSKILL.md
Reconstruct an OKF bundle from history
This skill replays a repository's decision-making history (git commits and Claude session transcripts) to rebuild its OKF knowledge bundle as if the okf skill's Stop hook had been active from the start.
The extraction layer is deterministic (same repo → byte-identical events); the replay layer is an LLM loop, replayable and auditable but not byte-identical (timestamps, summaries change per run). See the event schema (§1) and skip rules (§3).
1. Event schema
Git commits and session turns become events (JSONL, one per line, sorted by timestamp then source):
- Git events come from
git log --first-parent --numstat. - Session events pair each user message with the last assistant text
block of that turn (the wrap-up), extracted from ~/.claude/projects/<repo-slug>/*.jsonl and worktree subdirs.
- Timestamps are normalized to UTC ISO 8601 strings ending in
Z. - Skip field (optional, added by extraction): marks low-signal events —
see §3, never overridden by replay.
2. Protocol: Preflight → Extract → Bootstrap → Replay (Map+Reduce) → Finalize
Preflight: check if bundle can be rebuilt
If .backfill-state.json exists, resume from the cursor; otherwise, fresh bootstrap.
Extract: generate event stream
Write events.jsonl to the scratchpad (never committed). Report:
- Total events extracted, per-source counts, and per-rule skip counts.
Bootstrap: initialize bundle (fresh only)
Create .okf/ with:
Cursor (.okf/.backfill-state.json):
Replay: two-phase map/reduce protocol
The replay is now structured in two phases to enforce semantic depth and anti-degeneration rules:
Phase 1: Map (parallel analysis, per-event)
Launch okf:event-analyzer agents for the live events (those without skip field), in waves of 4 to 10 (see the cost note in §5), via Claude Code's Workflow agentType parameter. Each analyzer receives its event ids, the events.jsonl path, the repo path, the output directory and the emitter path, and:
- Fetches its own event JSON with
jq(the orchestrator dispatches ids, never content) - Reads git evidence only through the capped diff emitter (§6); session events need no other call
- Writes
analyses/<event-id>.md(event id with:sanitized to-) to scratchpad, with a
truncated flag copied from the emitter's last line
- Replies with one line of counts per event; the analysis never travels back in the reply
- Never touches
.okf/ - Is resumable: skip events already in
analyses/
Dispatch rule (deterministic, from events.jsonl, no content read): a live event is small when it is a session turn or a commit whose numstat totals at most 60 changed lines. Small events are grouped chronologically, eight per analyzer call; large commits go one per call. Measured on this repository (benchmark/map-tier/RESULTS.md): 57 calls instead of 147, a third off the map phase at the same tier, no loss on any per-event metric and no cross-event contamination.
Host-agnostic fallback (if no Workflow support): spawn generic subagents with the same system prompt as agents/event-analyzer.md, one per event, collecting analyses to scratchpad.
Phase 2: Reduce (sequential folding, one agent)
Run a single okf:bundle-weaver agent that:
- Reads all analyses in chronological order
- Folds them into
.okf/, updating or creating concepts - Enforces anti-degeneration rules (§4)
- Adds a dated
log.mdbullet for each lifecycle event only (a concept created, deprecated or
superseded); the "why" of a routine update goes into the concept body
- Manages cursor (
.okf/.backfill-state.json) for resume capability - Is the only actor that writes
.okf/ - Replies with one line of counts (folded, created, updated, bullets, conflicts, superseded,
truncated inputs); the bundle never travels back in the reply
Resume behavior: both phases support resumption. Phase 1 skips already-analyzed event ids; Phase 2 restarts from last_id in the cursor.
Domain priming (advisory)
Before starting the map phase, read the repository's README and directory structure to sketch a candidate taxonomy of concepts (skills, integrations, decisions, etc.). This priming is advisory only — it helps the analyzer emit better candidate names. The guarantee that no events are lost comes from the deterministic coverage check in Finalize (§5), not from priming; analyses without candidate names still flow to the weaver.
Context hygiene (orchestrator)
The orchestrator handles ids and counts, never content. Events, analyses and diffs are read by the agents; the orchestrator reads:
Never cat events.jsonl or open an analysis from the orchestrator: whatever enters its context is billed at the frontier rate on every following turn, and the routing exists to prevent that.
Finalize: validate and clean up
- Write `index.md` per directory by hand (do NOT run
okf_init.py— it
would scaffold placeholder files): one # Section per directory, one bullet per concept, * [Title](file.md) - description taken from each concept's frontmatter (SPEC §8). The root index.md keeps its okf_version: "0.2" frontmatter and links every subdirectory.
- Add final log entry (today's date, appended to existing dated section if present):
``` ## 2026-09-01
- Backfill: reconstructed from N events by okf-backfill/0.9.5
```
- Delete cursor:
``bash rm -f .okf/.backfill-state.json ``
- Run self-checks for anti-degeneration rules:
```bash # No concept filenames derived from change type ! find .okf -name "*.md" | grep -E "merge-pull-request|(^|/)(feat|fix|chore|docs)[:-]"
# No non-kebab-case characters in filenames ! find .okf -name "*.md" | grep -E "[^a-z0-9/.-]"
# No identical consecutive log bullets awk 'p==$0 && /^- / {exit 1} {p=$0}' .okf/log.md
# Every concept declares its lifecycle (absent status reads as stable, SPEC §5.4) [ -z "$(grep -rL '^status:' --include='*.md' .okf | grep -v '/index.md$\|/log.md$')" ] ``` These are lexical guards; they do not catch a bundle that asserts a superseded state. That check is semantic and belongs to the weaver, at fold time, when it has both the analysis and the earlier concepts on disk (§4 rule 5).
- Run coverage check to guarantee every event is mapped:
``bash uv run "${CLAUDE_SKILL_DIR}/scripts/okf_backfill_events.py" \ --check-coverage events.jsonl .okf ` Exit code 0 means all live events (non-skipped) appear in the bundle's sources` or log. Exit code 1 with a list of unmapped ids means the weaver skipped some events; fix and re-run.
- Validate bundle schema:
``bash uv run "${CLAUDE_SKILL_DIR}/../validate/scripts/okf_validate.py" .okf --strict `` Fix every error before finishing.
- Report the resulting bundle:
- Concept count per directory
- Log entry samples (first and last)
- Coverage check result (all events mapped)
- Validation result (pass/fail, warnings)
- Superseded resolutions (the weaver's
supersededcount) and deprecated concepts:
grep -rl '^status: deprecated' --include='*.md' .okf | wc -l
- Agents spawned per phase (analyzers, weaver invocations) and, when the host reports it,
tokens per phase
- Truncated analyses:
grep -l '^truncated: true' analyses/*.md | wc -l, next to the
deterministic estimate of git events whose full diff exceeds the default cap: jq -r 'select(.skip==null and .source=="git") | [.files[]|.add+.del] | add' events.jsonl | awk '$1>300' | wc -l
3. Skip rules
Events matching a rule below are marked skip: <rule-id> and skipped during replay (cursor advances, no log entry):
| Rule | Condition | Rationale | |
|---|---|---|---|
paths-only-generated | Git commit touches ONLY lockfiles or generated code (vendor/, node_modules/, dist/, .min., *.lock, etc.) | Noise: build byproducts, no knowledge content | |
merge-no-files | Git merge commit with no file changes (first-parent only) | Housekeeping | |
session-command-noise | Session user message is a slash command or <20 chars and has no useful outcome | Ephemeral UI/chatter |
Extend the first rule with --skip-globs "extra/**" for repo-specific patterns.
4. Anti-degeneration rules
The analyzer and weaver enforce these rules to prevent the bundle from devolving into a mechanical listing of commits or a taxonomy-by-accident:
- Concept names describe domain entities, not changes. Forbidden:
- Filenames derived from git subject:
merge-pull-request-#2-....md,feat:-add-docs-skill.md,fix:-handle-edge-case.md - Bare action words:
update.md,fix.md,add-feature.md - Non-kebab-case: spaces, underscores, capitals, special characters (allowed:
[a-z0-9-]only)
Example: a commit with subject "feat: add presales pipeline" touches a domain concept. The concept is named presales-pipeline.md (the entity), not feat:-add-presales-pipeline.md (the change). The change history lives in frontmatter sources and the body's ## History; log.md holds only lifecycle events.
- Prefer update over create. Every event is analyzed for which concepts it touches; if
a concept already exists and the analysis fits, update its sources and body. Only create a new concept if the analysis reveals a distinct domain entity not yet captured.
- Log bullets are lifecycle events, and explain intent. Only a concept created,
deprecated or superseded gets a bullet; a routine update does not. A bullet answers "why?" from the commit body or session outcome, never just re-reads the subject:
- Bad:
- Added presales-pipeline.md feature - Good:
- **Creation**: [Presales pipeline](...), formalized to clarify handoff points
- No identical consecutive bullets. A run of same-concept bullets means updates leaked
into the log: ```
- Feature X update
- Feature X update
- Feature X update
`` Instead: no bullet at all; the updates live in the concept's body and sources`.
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/backfill/SKILL.md
Popularity
- Repository stars
- 386
- Repository forks
- 35
- 7-day trend score
- 30
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/scaccogatto/okf-skills/backfill)