ID:WORK-135Status:donePriority:mediumComplexity:simpleSource:SPEC-038
Batch extraction and history caching
Implement efficient batch extraction of history for all plan entities and integrate with the existing .plan-cache.json caching mechanism. Handle shallow clone edge cases.
Acceptance Criteria
- Batch extraction: single
git logcall to get all commits affecting the plan directory with file lists - Batch extraction groups commits by file path and runs per-entity extraction only where needed
- Single-commit files emit a
createdevent without running full extraction HistoryCacheEntryadded to cache structure withlatestCommithash andeventsarray- Cache invalidation is exact: skip files whose latest commit hash matches the cache
- Shallow clone detection warns and marks timeline as potentially incomplete
- Batch extraction returns a unified timeline sorted by date
- Tests for cache hit/miss logic
- Tests for shallow clone handling
Dependencies
- Event model types and per-entity git history extraction — Event model and per-entity extraction
Approach
Extend the existing scanPlanFiles() cache structure in runes/plan/src/scanner.ts (or a sibling module) to include history entries keyed by latest commit hash. The batch extraction function runs git log --format="%H %aI %aN %s" --name-only -- <plan-dir> once to get all commits with affected files, then delegates to per-entity extraction for files with multiple commits.
Follow the shallow clone detection pattern from packages/content/src/timestamps.ts (git rev-parse --is-shallow-repository).
References
- Git-Native Entity History — Git-Native Entity History (Data Extraction + Caching sections)
Resolution
Completed: 2026-04-13
Branch: claude/spec-038-breakdown-pChav
What was done
runes/plan/src/history.ts— Core event model types (HistoryEvent, AttributeChange, CriteriaChange) + per-entity extraction algorithm (git log --follow, git show, parse/diff) + batch extraction + cachingrunes/plan/src/commands/history.ts— CLIplan historycommand with single-entity and global modes, all filters (--since, --type, --author, --status, --all, --limit, --format json)runes/plan/src/cli-plugin.ts— Registered history command in CLI pluginrunes/plan/src/tags/plan-history.ts— Self-closing plan-history tag definition with sentinel patternrunes/plan/src/pipeline.ts— Extended PlanAggregatedData with history + repositoryUrl fields, added aggregate hook extraction, added postProcess resolver for per-entity timeline and global commit-grouped feedrunes/plan/src/commands/render-pipeline.ts— Pass plan directory to pipeline via setPlanDirrunes/plan/src/config.ts— Added PlanHistory rune configrunes/plan/src/index.ts— Exported plan-history rune in RunePackagerunes/plan/styles/default.css— Timeline CSS with vertical line, circle markers, diff coloring, responsive layoutrunes/plan/test/history.test.ts— 31 tests covering parsing, diffing, and integration with real git repos
Notes
- All 6 work items were implemented together as they form a cohesive feature
- Pre-existing build issues in the plan package (missing @types/node, unresolved @refrakt-md/runes) prevent full tsc build, but all new code compiles and tests pass via vitest
- History cache uses a separate .plan-history-cache.json file (not merged into .plan-cache.json) to keep concerns separate
Relationships
Dependency of
History
- 607bcd1statusready→done
- ☑ Batch extraction: single `git log` call to get all commits affecting the plan directory with file lists
- ☑ Batch extraction groups commits by file path and runs per-entity extraction only where needed
- ☑ Single-commit files emit a `created` event without running full extraction
- +6 more criteria
- a59fd62Created (ready, medium, simple, SPEC-038, plan, cli, git, history, cache)