Skip to content

Releases: ypollak2/chronicle

v1.0.4

15 Apr 09:39

Choose a tag to compare

Changelog

All notable changes to Chronicle are documented here.
Format follows Keep a Changelog.
Versioning follows Semantic Versioning.


[1.0.4] — 2026-04-15

Added

Claude Code integration — eliminate per-session context loss

  • chronicle setup --tool=claude-code now registers Chronicle as an MCP server and adds SessionStart hook
  • .claude/mcp.json created with chronicle mcp server definition
  • .claude/settings.json created with chronicle inject --format=markdown SessionStart hook
  • Global hook also added to ~/.claude/settings.json — auto-injects .lore/ decisions in every project
  • Ensures all 35+ documented architectural decisions available at session start, no knowledge loss between Claude Code invocations

Fixed

Duplicate hook cleanup

  • Removed duplicate system Python hooks (python3 /path/to/hook.py) in favor of venv versions
  • Fixes "2 dashboards" issue where llm-router hooks ran twice per session
  • Impact: cleaner hook execution, eliminates redundant model invocations

[1.0.3] — 2026-04-12

Fixed

Claude Code provider — stdin piping bug

  • Previous invocation claude -p - passed the literal string - as the message instead of reading from stdin
  • Fixed to claude --print --output-format text --allowedTools "" with prompt piped via stdin
  • --allowedTools "" prevents the model from using tools during extraction (faster, deterministic)
  • Also accepts --llm claude as an alias for --llm claude-code

Codex provider — incorrect subcommand

  • Previous invocation codex exec --full-auto - used a non-existent subcommand
  • Fixed to codex --approval-mode full-auto --quiet with prompt via stdin
  • Added JSON extraction fallback: strips any status lines Codex prepends before the JSON block

detectProvider() improvements

  • Detects CLAUDE_CODE_ENTRYPOINT / CLAUDE_CODE_SESSION_ID env vars to prefer claude-code when running inside a Claude Code session
  • Subscription CLIs (claude, codex) now rank before API keys — free providers always win
  • Ollama liveness check added to auto-detection (probes localhost:11434 instead of assuming availability)

Changed

README rewritten for clarity

  • New headline: "Your AI coding assistant keeps forgetting everything. Chronicle fixes that."
  • Problem/solution framing at the top — table showing what gets lost each session
  • LLM provider table updated: subscription CLIs shown first with "Free — uses your existing plan"

[1.0.2] — 2026-04-12

Added

Auto-install git hooks on first use

  • When any chronicle command runs in a git repo that has .lore/ but no Chronicle hooks, hooks are silently installed automatically — no chronicle hooks install needed
  • Check is a fast file-stat (no LLM, no output to the user)
  • Skipped for internal commands (capture, enrich-commit, merge-driver, mcp, quickstart, hooks)

pre-push hook — local .lore/ auto-update

  • New git hook that runs chronicle process synchronously before each git push
  • If .lore/ changed, commits the updates with [skip ci] so the remote always receives a fresh store
  • Uses existing local LLM credentials — no GitHub Actions secret or separate API key needed
  • chronicle hooks remove also removes the pre-push hook

chronicle.yml simplified

  • CI workflow no longer needs an LLM API key or GitHub secret
  • Reduced to a lightweight chronicle verify --max-lag 10 freshness gate
  • All .lore/ updates now happen locally via the pre-push hook

Docs updated to v1.0.x

  • README: version badge → v1.0.1, full commands table with all 26 commands across 5 groups
  • CHANGELOG: v1.0.0 and v1.0.1 entries added
  • ARCHITECTURE: correct store structure, package tree, release process, decision lifecycle, eval harness sections; shipped tool adapters (removed stale "Phase 4" labels)

[1.0.1] — 2026-04-12

Fixed

CI build — missing source files (add.ts, ingest.ts)

  • add.ts and ingest.ts were referenced by cli.ts but missing from the dist bundle, causing CJS Build failed: Could not resolve './commands/add.js' in the v1.0.0 release workflow
  • Added the missing files so the tsup bundle compiles clean

Release workflow — remove npm publish

  • Removed Publish to npm step and registry-url from setup-node; the npm registry requires a paid org account for publish
  • Chronicle now publishes exclusively to PyPI + GitHub Release; no npm publish

Eval suite and CI fixes committed to repo

  • .lore/.eval.json 20-case RAG eval suite added to repo
  • CI matrix updated: removed --extra agno from uv sync, added agno integration test to ignore list (fixes Python 3.12/3.13 CI hang)

[1.0.0] — 2026-04-12

Production-ready milestone. Chronicle can now maintain itself — the .lore/ store is bootstrapped, the GitHub Actions workflow processes every commit automatically, and the RAG quality gate (eval harness) certifies the store works.

Added

chronicle quickstart — interactive setup wizard

  • Guides a new user from zero to a working .lore/ in ~5 minutes
  • Steps: git repo check → chronicle initchronicle migratechronicle hooks installchronicle setup → next-steps summary
  • --yes flag for unattended/CI mode

chronicle migrate — schema migration command

  • Upgrades .lore/ stores from any prior schema version to current (v1→v5)
  • Idempotent — safe to run multiple times
  • Migrations covered: index.md creation (v2), .extraction-cache.json rename (v3), low-confidence.md creation (v4), evolution era deduplication (v5)

chronicle decision — decision lifecycle management

  • chronicle decision list — display all decisions with current lifecycle status tags
  • chronicle decision deprecate "<title>" — mark a decision as deprecated (adds <!-- status:deprecated --> tag)
  • chronicle decision supersede "<title>" --by "<new>" — mark as superseded with forward reference
  • chronicle decision promote "<title>" — lift a low-confidence decision into the main decisions.md

chronicle verify fix — trivial commit exclusion

  • verify now uses getCommits() scanner (same filters as init) so chore, docs, and lockfile commits are not counted as "unprocessed" — prevents false-positive staleness alerts in CI

Changed

  • chronicle eval --init bootstraps eval cases from existing decisions and rejections (was previously empty)
  • chronicle inject filters deprecated/superseded decisions from the output by default (lifecycle-aware injection)
  • Internal: findLoreRoot test isolation via temp-dir rename pattern (CI reliability)

Tests

  • Total: 223+ tests passing across 10 suites
  • Self-dogfood: chronicle eval on Chronicle's own .lore/ — all 4 KPIs pass (100% recall, 100% rejection hit, MRR=1.000, 0% false confidence)

[0.13.0] — 2026-04-12

Added

Pipeline integration tests (#42)

  • process --dry-run tests: verifies commit counting against a real git repo with MIN_DIFF_LINES-compliant commits
  • inject → doctor → verify chain: full downstream pipeline with pre-built .lore/ fixture, no LLM calls needed
  • chronicle search tests: keyword fallback with --text flag, --json, exit code coverage

chronicle search defaults to hybrid semantic mode (#47)

  • Hybrid search (α=0.7 semantic + 0.3 keyword) is now the default when @huggingface/transformers is installed
  • Silently falls back to keyword search when transformers are not available (semanticSearch returns null)
  • New --text flag forces keyword-only mode
  • --semantic flag preserved for pure vector similarity mode

chronicle doctor — 3 new integrity checks (#43)

  • Check 7: orphaned ADR detection — warns when .lore/decisions/ files are not linked from decisions.md
  • Check 8: evolution integrity — detects the corruption pattern where all eras show identical decision counts
  • Check 9: process.log bounds — warns when log exceeds 500 lines

chronicle process — bounded log (#46)

  • process.log is auto-truncated to 500 lines after each run (keeps tail, discards oldest entries)
  • truncateLog() utility at end of process.ts

chronicle init generates index.md (#41)

  • Reads package.json (walks up 2 levels) for name, description, version
  • Generates structured index.md with Key Constraints and Architecture template sections
  • chronicle inject warns on stderr when index.md is missing

Fixed

evolution.md era deduplication (#40)

  • getDecisionsInRange() used inclusive lower bound — same-date decisions flooded all eras sharing that date
  • Fix: genesis era keeps date >= from; all later eras use date > from (exclusive)
  • Row filter changed from !l.includes('Decision') (broke when titles contained "Decision") to checking first table cell specifically

Tests

  • New pipeline integration tests in cli-smoke.test.ts — 14 new tests across 3 describe blocks
  • Evolution regression: "does not repeat same-date decisions across multiple same-day eras"
  • Doctor integrity checks: 6 new tests (orphaned ADRs, evolution corruption, process.log bounds)
  • Total: 223 tests passing

[0.12.0] — 2026-04-12

Added

chronicle status command

  • Single-line health summary: ◆ chronicle │ N decisions · N rejected · N ADRs · N sessions │ ✓ N unprocessed
  • Shows · N low-confidence and · ⚠ N extraction errors when non-zero
  • --json flag for machine-readable output (CI, scripting, status bars)

Decision DAG — Mermaid renderer (chronicle relate --diagram)

  • buildMermaidDAG(graph) renders the full decision relation graph as a flowchart TD Mermaid block
  • Labeled edges: depends-on (solid), supersedes (dashed), related-to (dotted)
  • Sanitizes double-quotes in decision titles; handles all edge types and isolated nodes

Confidence threshold filtering (chronicle process --min-confidence)

  • --min-confidence <n> (default 0.5)...
Read more

v1.0.3

12 Apr 19:12

Choose a tag to compare

Changelog

All notable changes to Chronicle are documented here.
Format follows Keep a Changelog.
Versioning follows Semantic Versioning.


[1.0.3] — 2026-04-12

Fixed

Claude Code provider — stdin piping bug

  • Previous invocation claude -p - passed the literal string - as the message instead of reading from stdin
  • Fixed to claude --print --output-format text --allowedTools "" with prompt piped via stdin
  • --allowedTools "" prevents the model from using tools during extraction (faster, deterministic)
  • Also accepts --llm claude as an alias for --llm claude-code

Codex provider — incorrect subcommand

  • Previous invocation codex exec --full-auto - used a non-existent subcommand
  • Fixed to codex --approval-mode full-auto --quiet with prompt via stdin
  • Added JSON extraction fallback: strips any status lines Codex prepends before the JSON block

detectProvider() improvements

  • Detects CLAUDE_CODE_ENTRYPOINT / CLAUDE_CODE_SESSION_ID env vars to prefer claude-code when running inside a Claude Code session
  • Subscription CLIs (claude, codex) now rank before API keys — free providers always win
  • Ollama liveness check added to auto-detection (probes localhost:11434 instead of assuming availability)

Changed

README rewritten for clarity

  • New headline: "Your AI coding assistant keeps forgetting everything. Chronicle fixes that."
  • Problem/solution framing at the top — table showing what gets lost each session
  • LLM provider table updated: subscription CLIs shown first with "Free — uses your existing plan"

[1.0.2] — 2026-04-12

Added

Auto-install git hooks on first use

  • When any chronicle command runs in a git repo that has .lore/ but no Chronicle hooks, hooks are silently installed automatically — no chronicle hooks install needed
  • Check is a fast file-stat (no LLM, no output to the user)
  • Skipped for internal commands (capture, enrich-commit, merge-driver, mcp, quickstart, hooks)

pre-push hook — local .lore/ auto-update

  • New git hook that runs chronicle process synchronously before each git push
  • If .lore/ changed, commits the updates with [skip ci] so the remote always receives a fresh store
  • Uses existing local LLM credentials — no GitHub Actions secret or separate API key needed
  • chronicle hooks remove also removes the pre-push hook

chronicle.yml simplified

  • CI workflow no longer needs an LLM API key or GitHub secret
  • Reduced to a lightweight chronicle verify --max-lag 10 freshness gate
  • All .lore/ updates now happen locally via the pre-push hook

Docs updated to v1.0.x

  • README: version badge → v1.0.1, full commands table with all 26 commands across 5 groups
  • CHANGELOG: v1.0.0 and v1.0.1 entries added
  • ARCHITECTURE: correct store structure, package tree, release process, decision lifecycle, eval harness sections; shipped tool adapters (removed stale "Phase 4" labels)

[1.0.1] — 2026-04-12

Fixed

CI build — missing source files (add.ts, ingest.ts)

  • add.ts and ingest.ts were referenced by cli.ts but missing from the dist bundle, causing CJS Build failed: Could not resolve './commands/add.js' in the v1.0.0 release workflow
  • Added the missing files so the tsup bundle compiles clean

Release workflow — remove npm publish

  • Removed Publish to npm step and registry-url from setup-node; the npm registry requires a paid org account for publish
  • Chronicle now publishes exclusively to PyPI + GitHub Release; no npm publish

Eval suite and CI fixes committed to repo

  • .lore/.eval.json 20-case RAG eval suite added to repo
  • CI matrix updated: removed --extra agno from uv sync, added agno integration test to ignore list (fixes Python 3.12/3.13 CI hang)

[1.0.0] — 2026-04-12

Production-ready milestone. Chronicle can now maintain itself — the .lore/ store is bootstrapped, the GitHub Actions workflow processes every commit automatically, and the RAG quality gate (eval harness) certifies the store works.

Added

chronicle quickstart — interactive setup wizard

  • Guides a new user from zero to a working .lore/ in ~5 minutes
  • Steps: git repo check → chronicle initchronicle migratechronicle hooks installchronicle setup → next-steps summary
  • --yes flag for unattended/CI mode

chronicle migrate — schema migration command

  • Upgrades .lore/ stores from any prior schema version to current (v1→v5)
  • Idempotent — safe to run multiple times
  • Migrations covered: index.md creation (v2), .extraction-cache.json rename (v3), low-confidence.md creation (v4), evolution era deduplication (v5)

chronicle decision — decision lifecycle management

  • chronicle decision list — display all decisions with current lifecycle status tags
  • chronicle decision deprecate "<title>" — mark a decision as deprecated (adds <!-- status:deprecated --> tag)
  • chronicle decision supersede "<title>" --by "<new>" — mark as superseded with forward reference
  • chronicle decision promote "<title>" — lift a low-confidence decision into the main decisions.md

chronicle verify fix — trivial commit exclusion

  • verify now uses getCommits() scanner (same filters as init) so chore, docs, and lockfile commits are not counted as "unprocessed" — prevents false-positive staleness alerts in CI

Changed

  • chronicle eval --init bootstraps eval cases from existing decisions and rejections (was previously empty)
  • chronicle inject filters deprecated/superseded decisions from the output by default (lifecycle-aware injection)
  • Internal: findLoreRoot test isolation via temp-dir rename pattern (CI reliability)

Tests

  • Total: 223+ tests passing across 10 suites
  • Self-dogfood: chronicle eval on Chronicle's own .lore/ — all 4 KPIs pass (100% recall, 100% rejection hit, MRR=1.000, 0% false confidence)

[0.13.0] — 2026-04-12

Added

Pipeline integration tests (#42)

  • process --dry-run tests: verifies commit counting against a real git repo with MIN_DIFF_LINES-compliant commits
  • inject → doctor → verify chain: full downstream pipeline with pre-built .lore/ fixture, no LLM calls needed
  • chronicle search tests: keyword fallback with --text flag, --json, exit code coverage

chronicle search defaults to hybrid semantic mode (#47)

  • Hybrid search (α=0.7 semantic + 0.3 keyword) is now the default when @huggingface/transformers is installed
  • Silently falls back to keyword search when transformers are not available (semanticSearch returns null)
  • New --text flag forces keyword-only mode
  • --semantic flag preserved for pure vector similarity mode

chronicle doctor — 3 new integrity checks (#43)

  • Check 7: orphaned ADR detection — warns when .lore/decisions/ files are not linked from decisions.md
  • Check 8: evolution integrity — detects the corruption pattern where all eras show identical decision counts
  • Check 9: process.log bounds — warns when log exceeds 500 lines

chronicle process — bounded log (#46)

  • process.log is auto-truncated to 500 lines after each run (keeps tail, discards oldest entries)
  • truncateLog() utility at end of process.ts

chronicle init generates index.md (#41)

  • Reads package.json (walks up 2 levels) for name, description, version
  • Generates structured index.md with Key Constraints and Architecture template sections
  • chronicle inject warns on stderr when index.md is missing

Fixed

evolution.md era deduplication (#40)

  • getDecisionsInRange() used inclusive lower bound — same-date decisions flooded all eras sharing that date
  • Fix: genesis era keeps date >= from; all later eras use date > from (exclusive)
  • Row filter changed from !l.includes('Decision') (broke when titles contained "Decision") to checking first table cell specifically

Tests

  • New pipeline integration tests in cli-smoke.test.ts — 14 new tests across 3 describe blocks
  • Evolution regression: "does not repeat same-date decisions across multiple same-day eras"
  • Doctor integrity checks: 6 new tests (orphaned ADRs, evolution corruption, process.log bounds)
  • Total: 223 tests passing

[0.12.0] — 2026-04-12

Added

chronicle status command

  • Single-line health summary: ◆ chronicle │ N decisions · N rejected · N ADRs · N sessions │ ✓ N unprocessed
  • Shows · N low-confidence and · ⚠ N extraction errors when non-zero
  • --json flag for machine-readable output (CI, scripting, status bars)

Decision DAG — Mermaid renderer (chronicle relate --diagram)

  • buildMermaidDAG(graph) renders the full decision relation graph as a flowchart TD Mermaid block
  • Labeled edges: depends-on (solid), supersedes (dashed), related-to (dotted)
  • Sanitizes double-quotes in decision titles; handles all edge types and isolated nodes

Confidence threshold filtering (chronicle process --min-confidence)

  • --min-confidence <n> (default 0.5) — decisions below threshold are quarantined to .lore/low-confidence.md rather than discarded or silently accepted
  • "Preserve but quarantine" pattern: low-confidence results remain reviewable
  • .lore/low-confidence.md added to store structure (STORE_FILES map in @chronicle/core)
  • chronicle status surfaces low-confidence count

Extraction error tracking

  • callWithRetry accepts an optional ctx: { errors: number } ref threaded through concurrent batches
  • On exhaustion (3 failed attempts), ctx.errors is incremented — distinguishes "no decisions found" from "LLM returned malformed JSON"
  • chronicle process passes extractionCtx and logs errors:N to .lore/process.log
  • chronicle status reads the last log entry and surfaces extraction errors

GitHub Actions job summary

  • chronicle.yml writes a markdown table to $GITHUB_STEP_SUMMARY after each `chro...
Read more

v1.0.2

12 Apr 19:03

Choose a tag to compare

Changelog

All notable changes to Chronicle are documented here.
Format follows Keep a Changelog.
Versioning follows Semantic Versioning.


[1.0.2] — 2026-04-12

Added

Auto-install git hooks on first use

  • When any chronicle command runs in a git repo that has .lore/ but no Chronicle hooks, hooks are silently installed automatically — no chronicle hooks install needed
  • Check is a fast file-stat (no LLM, no output to the user)
  • Skipped for internal commands (capture, enrich-commit, merge-driver, mcp, quickstart, hooks)

pre-push hook — local .lore/ auto-update

  • New git hook that runs chronicle process synchronously before each git push
  • If .lore/ changed, commits the updates with [skip ci] so the remote always receives a fresh store
  • Uses existing local LLM credentials — no GitHub Actions secret or separate API key needed
  • chronicle hooks remove also removes the pre-push hook

chronicle.yml simplified

  • CI workflow no longer needs an LLM API key or GitHub secret
  • Reduced to a lightweight chronicle verify --max-lag 10 freshness gate
  • All .lore/ updates now happen locally via the pre-push hook

Docs updated to v1.0.x

  • README: version badge → v1.0.1, full commands table with all 26 commands across 5 groups
  • CHANGELOG: v1.0.0 and v1.0.1 entries added
  • ARCHITECTURE: correct store structure, package tree, release process, decision lifecycle, eval harness sections; shipped tool adapters (removed stale "Phase 4" labels)

[1.0.1] — 2026-04-12

Fixed

CI build — missing source files (add.ts, ingest.ts)

  • add.ts and ingest.ts were referenced by cli.ts but missing from the dist bundle, causing CJS Build failed: Could not resolve './commands/add.js' in the v1.0.0 release workflow
  • Added the missing files so the tsup bundle compiles clean

Release workflow — remove npm publish

  • Removed Publish to npm step and registry-url from setup-node; the npm registry requires a paid org account for publish
  • Chronicle now publishes exclusively to PyPI + GitHub Release; no npm publish

Eval suite and CI fixes committed to repo

  • .lore/.eval.json 20-case RAG eval suite added to repo
  • CI matrix updated: removed --extra agno from uv sync, added agno integration test to ignore list (fixes Python 3.12/3.13 CI hang)

[1.0.0] — 2026-04-12

Production-ready milestone. Chronicle can now maintain itself — the .lore/ store is bootstrapped, the GitHub Actions workflow processes every commit automatically, and the RAG quality gate (eval harness) certifies the store works.

Added

chronicle quickstart — interactive setup wizard

  • Guides a new user from zero to a working .lore/ in ~5 minutes
  • Steps: git repo check → chronicle initchronicle migratechronicle hooks installchronicle setup → next-steps summary
  • --yes flag for unattended/CI mode

chronicle migrate — schema migration command

  • Upgrades .lore/ stores from any prior schema version to current (v1→v5)
  • Idempotent — safe to run multiple times
  • Migrations covered: index.md creation (v2), .extraction-cache.json rename (v3), low-confidence.md creation (v4), evolution era deduplication (v5)

chronicle decision — decision lifecycle management

  • chronicle decision list — display all decisions with current lifecycle status tags
  • chronicle decision deprecate "<title>" — mark a decision as deprecated (adds <!-- status:deprecated --> tag)
  • chronicle decision supersede "<title>" --by "<new>" — mark as superseded with forward reference
  • chronicle decision promote "<title>" — lift a low-confidence decision into the main decisions.md

chronicle verify fix — trivial commit exclusion

  • verify now uses getCommits() scanner (same filters as init) so chore, docs, and lockfile commits are not counted as "unprocessed" — prevents false-positive staleness alerts in CI

Changed

  • chronicle eval --init bootstraps eval cases from existing decisions and rejections (was previously empty)
  • chronicle inject filters deprecated/superseded decisions from the output by default (lifecycle-aware injection)
  • Internal: findLoreRoot test isolation via temp-dir rename pattern (CI reliability)

Tests

  • Total: 223+ tests passing across 10 suites
  • Self-dogfood: chronicle eval on Chronicle's own .lore/ — all 4 KPIs pass (100% recall, 100% rejection hit, MRR=1.000, 0% false confidence)

[0.13.0] — 2026-04-12

Added

Pipeline integration tests (#42)

  • process --dry-run tests: verifies commit counting against a real git repo with MIN_DIFF_LINES-compliant commits
  • inject → doctor → verify chain: full downstream pipeline with pre-built .lore/ fixture, no LLM calls needed
  • chronicle search tests: keyword fallback with --text flag, --json, exit code coverage

chronicle search defaults to hybrid semantic mode (#47)

  • Hybrid search (α=0.7 semantic + 0.3 keyword) is now the default when @huggingface/transformers is installed
  • Silently falls back to keyword search when transformers are not available (semanticSearch returns null)
  • New --text flag forces keyword-only mode
  • --semantic flag preserved for pure vector similarity mode

chronicle doctor — 3 new integrity checks (#43)

  • Check 7: orphaned ADR detection — warns when .lore/decisions/ files are not linked from decisions.md
  • Check 8: evolution integrity — detects the corruption pattern where all eras show identical decision counts
  • Check 9: process.log bounds — warns when log exceeds 500 lines

chronicle process — bounded log (#46)

  • process.log is auto-truncated to 500 lines after each run (keeps tail, discards oldest entries)
  • truncateLog() utility at end of process.ts

chronicle init generates index.md (#41)

  • Reads package.json (walks up 2 levels) for name, description, version
  • Generates structured index.md with Key Constraints and Architecture template sections
  • chronicle inject warns on stderr when index.md is missing

Fixed

evolution.md era deduplication (#40)

  • getDecisionsInRange() used inclusive lower bound — same-date decisions flooded all eras sharing that date
  • Fix: genesis era keeps date >= from; all later eras use date > from (exclusive)
  • Row filter changed from !l.includes('Decision') (broke when titles contained "Decision") to checking first table cell specifically

Tests

  • New pipeline integration tests in cli-smoke.test.ts — 14 new tests across 3 describe blocks
  • Evolution regression: "does not repeat same-date decisions across multiple same-day eras"
  • Doctor integrity checks: 6 new tests (orphaned ADRs, evolution corruption, process.log bounds)
  • Total: 223 tests passing

[0.12.0] — 2026-04-12

Added

chronicle status command

  • Single-line health summary: ◆ chronicle │ N decisions · N rejected · N ADRs · N sessions │ ✓ N unprocessed
  • Shows · N low-confidence and · ⚠ N extraction errors when non-zero
  • --json flag for machine-readable output (CI, scripting, status bars)

Decision DAG — Mermaid renderer (chronicle relate --diagram)

  • buildMermaidDAG(graph) renders the full decision relation graph as a flowchart TD Mermaid block
  • Labeled edges: depends-on (solid), supersedes (dashed), related-to (dotted)
  • Sanitizes double-quotes in decision titles; handles all edge types and isolated nodes

Confidence threshold filtering (chronicle process --min-confidence)

  • --min-confidence <n> (default 0.5) — decisions below threshold are quarantined to .lore/low-confidence.md rather than discarded or silently accepted
  • "Preserve but quarantine" pattern: low-confidence results remain reviewable
  • .lore/low-confidence.md added to store structure (STORE_FILES map in @chronicle/core)
  • chronicle status surfaces low-confidence count

Extraction error tracking

  • callWithRetry accepts an optional ctx: { errors: number } ref threaded through concurrent batches
  • On exhaustion (3 failed attempts), ctx.errors is incremented — distinguishes "no decisions found" from "LLM returned malformed JSON"
  • chronicle process passes extractionCtx and logs errors:N to .lore/process.log
  • chronicle status reads the last log entry and surfaces extraction errors

GitHub Actions job summary

  • chronicle.yml writes a markdown table to $GITHUB_STEP_SUMMARY after each chronicle process run
  • Table shows: decisions, rejections, ADRs, sessions, unprocessed commits, low-confidence, extraction errors

Changed

  • evolution eras now sort decisions by risk level (high → medium → low) before rendering
  • renderEvolutionMarkdown hides the "Most changed files" section when decisions exist — file churn is noise when decisions tell the story
  • getDecisionsInRange now correctly filters by date range; handles both legacy format (title in col[0]) and current format (date in col[0])
  • chronicle inject uses the two most-recent evolution eras (previously used the oldest era)

Fixed

  • Removed 'two-pass' from ExtractionStrategy type — it was typed as valid but threw "not implemented" at runtime
  • chronicle status crash: 'low-confidence' was missing from STORE_FILES map, causing lorePath(root, undefined) at runtime

Tests

  • New semantic-search.test.ts — 7 tests covering null embed fallback, empty corpus, hybrid mode, buildEmbeddingIndex
  • New cli-smoke.test.ts freshness block — 3 tests: unprocessed detection, cache-hit zero, exit-1 on lag
  • callWithRetry ctx tests — 6 new tests: success, empty [], retry-then-succeed, exhaustion increments ctx, [] does not increment ctx, accumulation across batches
  • evolution.test.ts — 4 new tests: risk ordering, keyFiles suppression when decisions exist, keyFiles shown when no decisions, date-range filtering
  • Total: 202 tests p...
Read more

v1.0.1

12 Apr 14:34

Choose a tag to compare

Changelog

All notable changes to Chronicle are documented here.
Format follows Keep a Changelog.
Versioning follows Semantic Versioning.


[0.13.0] — 2026-04-12

Added

Pipeline integration tests (#42)

  • process --dry-run tests: verifies commit counting against a real git repo with MIN_DIFF_LINES-compliant commits
  • inject → doctor → verify chain: full downstream pipeline with pre-built .lore/ fixture, no LLM calls needed
  • chronicle search tests: keyword fallback with --text flag, --json, exit code coverage

chronicle search defaults to hybrid semantic mode (#47)

  • Hybrid search (α=0.7 semantic + 0.3 keyword) is now the default when @huggingface/transformers is installed
  • Silently falls back to keyword search when transformers are not available (semanticSearch returns null)
  • New --text flag forces keyword-only mode
  • --semantic flag preserved for pure vector similarity mode

chronicle doctor — 3 new integrity checks (#43)

  • Check 7: orphaned ADR detection — warns when .lore/decisions/ files are not linked from decisions.md
  • Check 8: evolution integrity — detects the corruption pattern where all eras show identical decision counts
  • Check 9: process.log bounds — warns when log exceeds 500 lines

chronicle process — bounded log (#46)

  • process.log is auto-truncated to 500 lines after each run (keeps tail, discards oldest entries)
  • truncateLog() utility at end of process.ts

chronicle init generates index.md (#41)

  • Reads package.json (walks up 2 levels) for name, description, version
  • Generates structured index.md with Key Constraints and Architecture template sections
  • chronicle inject warns on stderr when index.md is missing

Fixed

evolution.md era deduplication (#40)

  • getDecisionsInRange() used inclusive lower bound — same-date decisions flooded all eras sharing that date
  • Fix: genesis era keeps date >= from; all later eras use date > from (exclusive)
  • Row filter changed from !l.includes('Decision') (broke when titles contained "Decision") to checking first table cell specifically

Tests

  • New pipeline integration tests in cli-smoke.test.ts — 14 new tests across 3 describe blocks
  • Evolution regression: "does not repeat same-date decisions across multiple same-day eras"
  • Doctor integrity checks: 6 new tests (orphaned ADRs, evolution corruption, process.log bounds)
  • Total: 223 tests passing

[0.12.0] — 2026-04-12

Added

chronicle status command

  • Single-line health summary: ◆ chronicle │ N decisions · N rejected · N ADRs · N sessions │ ✓ N unprocessed
  • Shows · N low-confidence and · ⚠ N extraction errors when non-zero
  • --json flag for machine-readable output (CI, scripting, status bars)

Decision DAG — Mermaid renderer (chronicle relate --diagram)

  • buildMermaidDAG(graph) renders the full decision relation graph as a flowchart TD Mermaid block
  • Labeled edges: depends-on (solid), supersedes (dashed), related-to (dotted)
  • Sanitizes double-quotes in decision titles; handles all edge types and isolated nodes

Confidence threshold filtering (chronicle process --min-confidence)

  • --min-confidence <n> (default 0.5) — decisions below threshold are quarantined to .lore/low-confidence.md rather than discarded or silently accepted
  • "Preserve but quarantine" pattern: low-confidence results remain reviewable
  • .lore/low-confidence.md added to store structure (STORE_FILES map in @chronicle/core)
  • chronicle status surfaces low-confidence count

Extraction error tracking

  • callWithRetry accepts an optional ctx: { errors: number } ref threaded through concurrent batches
  • On exhaustion (3 failed attempts), ctx.errors is incremented — distinguishes "no decisions found" from "LLM returned malformed JSON"
  • chronicle process passes extractionCtx and logs errors:N to .lore/process.log
  • chronicle status reads the last log entry and surfaces extraction errors

GitHub Actions job summary

  • chronicle.yml writes a markdown table to $GITHUB_STEP_SUMMARY after each chronicle process run
  • Table shows: decisions, rejections, ADRs, sessions, unprocessed commits, low-confidence, extraction errors

Changed

  • evolution eras now sort decisions by risk level (high → medium → low) before rendering
  • renderEvolutionMarkdown hides the "Most changed files" section when decisions exist — file churn is noise when decisions tell the story
  • getDecisionsInRange now correctly filters by date range; handles both legacy format (title in col[0]) and current format (date in col[0])
  • chronicle inject uses the two most-recent evolution eras (previously used the oldest era)

Fixed

  • Removed 'two-pass' from ExtractionStrategy type — it was typed as valid but threw "not implemented" at runtime
  • chronicle status crash: 'low-confidence' was missing from STORE_FILES map, causing lorePath(root, undefined) at runtime

Tests

  • New semantic-search.test.ts — 7 tests covering null embed fallback, empty corpus, hybrid mode, buildEmbeddingIndex
  • New cli-smoke.test.ts freshness block — 3 tests: unprocessed detection, cache-hit zero, exit-1 on lag
  • callWithRetry ctx tests — 6 new tests: success, empty [], retry-then-succeed, exhaustion increments ctx, [] does not increment ctx, accumulation across batches
  • evolution.test.ts — 4 new tests: risk ordering, keyFiles suppression when decisions exist, keyFiles shown when no decisions, date-range filtering
  • Total: 202 tests passing

[0.9.0] — 2026-04-11

Added

Decision relationship DAG (chronicle relate) (I1)

  • chronicle relate "<title>" --depends-on "<title>" — record that a decision builds on another
  • chronicle relate "<title>" --supersedes "<title>" — mark an old decision as replaced
  • chronicle relate "<title>" --related-to "<title>" — soft cross-reference between decisions
  • chronicle relate --list — print the full relation graph across all decisions
  • Relations stored as <!-- relations:{...} --> inline HTML comments in decisions.md rows (backward-compatible with existing stores)
  • applyRelationToContent, buildRelationGraph, getRelatedRows, parseRelations, serializeRelations, addRelationToRow, removeRelationFromRow, extractTitleFromRow exported from @chronicle/core

Business/product context layer (chronicle context) (I2)

  • chronicle context add --goal|--constraint|--team|--stack|--non-goal <text> — add a fact to .lore/context.md
  • chronicle context remove ... — remove a context fact
  • chronicle context show — print current project context
  • chronicle context edit — open context.md in $EDITOR
  • chronicle inject now prepends the project context block at the top of every output
  • readContext, writeContext, addContextFact, removeContextFact, formatContextForInject exported from @chronicle/core

Ownership tracking (chronicle who) (I3)

  • chronicle who <file> — show owner(s) and all recorded decisions + risks for a file
  • Reads CODEOWNERS automatically (checks CODEOWNERS, .github/CODEOWNERS, .gitlab/CODEOWNERS)
  • Falls back to .lore/ownership.md (format: - \pattern`: @owner`)
  • chronicle capture now stamps <!-- author:email --> on each captured decision row
  • chronicle inject --files now includes a ## File Ownership section when ownership is defined
  • loadOwnership, getOwnersForFile, parseAuthorFromRow, setAuthorOnRow, buildOwnershipSection, writeLoreOwnership exported from @chronicle/core

CI / Server-side automation

  • chronicle verify — CI gate: exits 1 when .lore/ lags by more than --max-lag commits (default 5); --json for machine-readable output
  • chronicle process — batch processor for GitHub Actions: processes all uncached commits in one pass, writes .lore/process.log, exits 1 on LLM errors
  • .github/workflows/chronicle.yml — official GitHub Actions workflow that triggers on push to main, runs chronicle process, and commits updated .lore/ back with [skip ci] — closes the "repo maintains itself" loop

Comprehensive test suite (149 tests across 9 suites)

  • extraction-parsing.test.ts — 21 tests covering malformed JSON, HTML-wrapped responses, null fields, truncated output, code block variations, and prompt completeness
  • ranker.test.ts — 26 tests for parseDecisionsTable, scoreRow (file match, age decay, risk/confidence bonus), rankDecisions (sort order, semantic blend, topN), estimateTokens, trimToTokenBudget
  • rag-quality.test.ts — 28 behavioral tests: "does the store contain the right knowledge?" — decisions completeness, rejections format, risks content, evolution eras, deep ADR structure, inject output ranking, staleness, token budget, relations DAG, business context
  • pipeline.test.ts — 10 end-to-end integration tests using real git repos (temp fixture) + mock LLM: feature commit → decisions.md, security → high-risk, rejection → rejected.md, noise filtering, store write correctness, deep ADR creation, cache prevents re-processing
  • fixtures.ts — shared fixture factory: buildProjectRepo() (7-commit git repo covering all change types), buildPopulatedLore() (pre-populated .lore/ for inject tests), buildMockLLM() (keyword-aware mock returning realistic ExtractionResults)

Fixed

  • parseExtractionResponse now filters non-object elements from arrays (LLM hallucination of [1, 2, 3] no longer passes through as decisions)
  • scoreRow recentFiles matching now uses prefix matching: a row affecting src/auth/ correctly matches a recent file src/auth/jwt.ts
  • Extraction cache now marks noise commits (zero results) as processed, preventing re-querying on the second pass
  • buildExtractionPrompt now includes the commit hash in the prompt so the LLM can return it in each result object (enabling accurate cache k...
Read more

v0.13.0 — Correctness & Pipeline Quality

12 Apr 10:10

Choose a tag to compare

What's new

Correctness fixes

  • Evolution era deduplicationgetDecisionsInRange() used inclusive lower bound, causing same-date decisions to appear in every era. Fixed: genesis era uses date >= from, later eras use date > from (exclusive). Run chronicle evolution --regen to regenerate.
  • chronicle init now generates index.md — reads package.json for project name/description/version; generates structured template with Key Constraints and Architecture sections. chronicle inject warns when missing.

New checks in chronicle doctor

  • Orphaned ADR detection — warns when .lore/decisions/ files are not linked from decisions.md
  • Evolution integrity — detects corruption when all eras show identical decision counts
  • process.log bounds — warns when log exceeds 500 lines

chronicle search now uses hybrid mode by default

  • Hybrid semantic + keyword search (α=0.7) runs when @huggingface/transformers is installed
  • Silently falls back to keyword search otherwise
  • New --text flag forces keyword-only mode

Bounded process.log

  • Auto-truncated to 500 lines after each chronicle process run

Tests

223 passing (up from 209)

Breaking changes

Existing evolution.md files built with v0.12 may show duplicate decisions across eras. Run chronicle evolution --regen to fix.

v0.12.0 — Status Command, Decision DAG & Extraction Quality

11 Apr 23:24

Choose a tag to compare

What's New

chronicle status command

Single-line health summary: decisions, ADRs, sessions, unprocessed commit count, low-confidence quarantine, and extraction errors. Supports --json for CI/scripting.

◆ chronicle │ 30 decisions · 6 rejected · 3 ADRs · 0 sessions │ ✓ 0 unprocessed

Decision DAG — Mermaid diagram renderer

chronicle relate --diagram renders your decision relation graph as a Mermaid flowchart TD block, showing depends-on, supersedes, and related-to edges with labeled arrows.

Extraction quality improvements

  • Few-shot examples in the extraction prompt (decision, rejection, noise) anchor model calibration
  • JSON retry with exponential backoff — up to 3 attempts (1s/2s) on malformed JSON; clean [] accepted immediately
  • Diff truncation — diffs >3000 chars are trimmed and flagged with a NOTE header so the LLM knows context is partial
  • Confidence threshold (--min-confidence, default 0.5) — results below threshold go to .lore/low-confidence.md rather than being silently discarded
  • inject context fix — now uses the two most-recent evolution eras instead of the oldest, so AI context reflects current state

CI observability

chronicle process in GitHub Actions now writes a markdown table to $GITHUB_STEP_SUMMARY showing decisions added, ADRs, unprocessed commits, and extraction errors.

Bug fixes

  • Remove 'two-pass' from ExtractionStrategy (was typed valid but threw at runtime)
  • evolution date-range filtering now works correctly
  • Evolution eras sort decisions by risk (high → medium → low)
  • keyFiles section hidden when decisions exist (file churn is noise when decisions tell the story)

Install

pip install --upgrade chronicle-dev

Full Changelog

https://github.com/yalipollak/chronicle/compare/v0.9.1...v0.12.0

v0.9.1

11 Apr 22:47

Choose a tag to compare

Changelog

All notable changes to Chronicle are documented here.
Format follows Keep a Changelog.
Versioning follows Semantic Versioning.


[0.9.0] — 2026-04-11

Added

Decision relationship DAG (chronicle relate) (I1)

  • chronicle relate "<title>" --depends-on "<title>" — record that a decision builds on another
  • chronicle relate "<title>" --supersedes "<title>" — mark an old decision as replaced
  • chronicle relate "<title>" --related-to "<title>" — soft cross-reference between decisions
  • chronicle relate --list — print the full relation graph across all decisions
  • Relations stored as <!-- relations:{...} --> inline HTML comments in decisions.md rows (backward-compatible with existing stores)
  • applyRelationToContent, buildRelationGraph, getRelatedRows, parseRelations, serializeRelations, addRelationToRow, removeRelationFromRow, extractTitleFromRow exported from @chronicle/core

Business/product context layer (chronicle context) (I2)

  • chronicle context add --goal|--constraint|--team|--stack|--non-goal <text> — add a fact to .lore/context.md
  • chronicle context remove ... — remove a context fact
  • chronicle context show — print current project context
  • chronicle context edit — open context.md in $EDITOR
  • chronicle inject now prepends the project context block at the top of every output
  • readContext, writeContext, addContextFact, removeContextFact, formatContextForInject exported from @chronicle/core

Ownership tracking (chronicle who) (I3)

  • chronicle who <file> — show owner(s) and all recorded decisions + risks for a file
  • Reads CODEOWNERS automatically (checks CODEOWNERS, .github/CODEOWNERS, .gitlab/CODEOWNERS)
  • Falls back to .lore/ownership.md (format: - \pattern`: @owner`)
  • chronicle capture now stamps <!-- author:email --> on each captured decision row
  • chronicle inject --files now includes a ## File Ownership section when ownership is defined
  • loadOwnership, getOwnersForFile, parseAuthorFromRow, setAuthorOnRow, buildOwnershipSection, writeLoreOwnership exported from @chronicle/core

CI / Server-side automation

  • chronicle verify — CI gate: exits 1 when .lore/ lags by more than --max-lag commits (default 5); --json for machine-readable output
  • chronicle process — batch processor for GitHub Actions: processes all uncached commits in one pass, writes .lore/process.log, exits 1 on LLM errors
  • .github/workflows/chronicle.yml — official GitHub Actions workflow that triggers on push to main, runs chronicle process, and commits updated .lore/ back with [skip ci] — closes the "repo maintains itself" loop

Comprehensive test suite (149 tests across 9 suites)

  • extraction-parsing.test.ts — 21 tests covering malformed JSON, HTML-wrapped responses, null fields, truncated output, code block variations, and prompt completeness
  • ranker.test.ts — 26 tests for parseDecisionsTable, scoreRow (file match, age decay, risk/confidence bonus), rankDecisions (sort order, semantic blend, topN), estimateTokens, trimToTokenBudget
  • rag-quality.test.ts — 28 behavioral tests: "does the store contain the right knowledge?" — decisions completeness, rejections format, risks content, evolution eras, deep ADR structure, inject output ranking, staleness, token budget, relations DAG, business context
  • pipeline.test.ts — 10 end-to-end integration tests using real git repos (temp fixture) + mock LLM: feature commit → decisions.md, security → high-risk, rejection → rejected.md, noise filtering, store write correctness, deep ADR creation, cache prevents re-processing
  • fixtures.ts — shared fixture factory: buildProjectRepo() (7-commit git repo covering all change types), buildPopulatedLore() (pre-populated .lore/ for inject tests), buildMockLLM() (keyword-aware mock returning realistic ExtractionResults)

Fixed

  • parseExtractionResponse now filters non-object elements from arrays (LLM hallucination of [1, 2, 3] no longer passes through as decisions)
  • scoreRow recentFiles matching now uses prefix matching: a row affecting src/auth/ correctly matches a recent file src/auth/jwt.ts
  • Extraction cache now marks noise commits (zero results) as processed, preventing re-querying on the second pass
  • buildExtractionPrompt now includes the commit hash in the prompt so the LLM can return it in each result object (enabling accurate cache keying)
  • Evolution test updated: buildEvolution correctly synthesizes a single v0.1 (initial) era for repos with no git tags (time-based era synthesis was added in v0.3.0 but the test expectation was not updated)

[0.8.0] — 2026-04-11

Added

Multi-source knowledge ingestion

chronicle add — register additional knowledge sources:

  • --repo <path|url> — secondary git repo (clones remotes to ~/.chronicle/repos/); decisions extracted immediately
  • --dir <path> — local directory (.md, .ts, .py, .go, etc.)
  • --url <url> — web page (HTML stripped to text)
  • --pdf <path> — PDF file (text PDFs; requires optional pdf-parse)
  • --list / --remove <id> — manage registered sources
  • Source registry persisted at .lore/sources.json

chronicle ingest — index dir/url/pdf sources into .lore/chunks/{sourceId}/:

  • Chunks text at ~500-token boundaries (paragraph-aware)
  • Skips already-ingested sources unless --force
  • --id <id> to re-ingest a single source

Unified search (M4)

  • chronicle search now also scans .lore/chunks/ in keyword mode
  • Semantic/hybrid modes already work across all embedded content

Git merge driver for decisions.md (M5)

  • chronicle hooks install now registers merge.chronicle-decisions in .git/config
  • Adds .lore/decisions*.md merge=chronicle-decisions to .gitattributes
  • chronicle merge-driver <base> <ours> <theirs> (internal, called by git):
    • Union-merges table rows from both branches
    • Deduplicates by title (keeps newest date)
    • Exits 0 → conflict-free merge; exits 1 → unresolvable

Source abstraction layer (@chronicle/core)

  • SourceConfig, SourceType, SourceRegistry types
  • loadSourceRegistry, saveSourceRegistry, addSource, removeSource, listSources, getSource, markIngested, deriveSourceId
  • chunkText, ingestDir, ingestUrl, ingestPdf from ingestor.ts

[0.7.0] — 2026-04-11

Added

Local embedding engine (@chronicle/core)

  • embed(text) / embedBatch(texts) — MiniLM-L6-v2 via @huggingface/transformers (22MB, fully offline)
  • cosineSimilarity(a, b) — dot product on normalized vectors
  • loadEmbeddingCache / saveEmbeddingCache — SHA-256 content-keyed JSON cache at .lore/embeddings.json
  • getEmbeddings(texts, cache) — batch embedding with cache deduplication (only new content is embedded)
  • @huggingface/transformers is an optionalDependency — Chronicle works without it, embedding features degrade gracefully to heuristic mode

Semantic search (chronicle search)

  • --semantic — pure vector similarity search using MiniLM embeddings
  • --hybrid — linear blend: 0.7 × semantic + 0.3 × keyword score
  • Visual score bar output (█░░░ style) with source attribution
  • Graceful fallback to keyword search with install hint if transformers not available

Semantic inject ranking (chronicle inject)

  • --query <text> — natural language query that re-ranks decision rows by semantic similarity
  • Phase 2 ranker: 0.6 × semantic + 0.4 × heuristic blend when --query provided
  • buildSemanticScores(rows, query) exported from @chronicle/core

Incremental vector index (post-commit hook)

  • buildEmbeddingIndex(root) — indexes all decisions, rejects, risks; skips cached content
  • Called automatically by chronicle capture after each commit (only new decisions are embedded)

RAG quality harness (chronicle eval)

  • chronicle eval — runs 4 KPI checks: Decision Recall, Rejection Hit Rate, Semantic MRR@5, False Confidence Rate
  • chronicle eval --init — bootstraps .lore/.eval.json from existing decisions (ready to run immediately)
  • --json for machine-readable output; --verbose for per-case details
  • Exits 1 if any KPI is below target (suitable for CI)
  • KPI targets: Recall ≥ 80%, Rejection Hit ≥ 90%, MRR@5 ≥ 0.70, False Confidence ≤ 10%

Changed

  • rankDecisions() now accepts semanticScores?: Map<string, number> for hybrid scoring

[0.6.0] — 2026-04-11

Added

Relevance-ranked inject (chronicle inject)

  • --top <n> — return only the N most relevant decisions (ranked by heuristic score)
  • --tokens <n> — auto-trim output to fit within N tokens (~4 chars/token)
  • --min-confidence <n> — omit decisions below a confidence threshold (0.0–1.0)
  • rankDecisions() in @chronicle/core — heuristic scoring: file match ×3, recent file ×1, risk bonus (high=+2, medium=+1), age decay, confidence bonus
  • trimToTokenBudget() — greedy section trimmer with partial truncation fallback

Confidence scores on decisions

  • LLM extraction now returns a confidence field (0.0–1.0) per decision
  • Stored as <!-- confidence:0.72 --> inline HTML comments in decisions.md rows
  • Backward-compatible: existing stores default to confidence=1.0

Staleness detection (chronicle inject --no-stale)

  • Automatically flags decisions whose affected files have been significantly modified since the decision was recorded
  • One-shot git log --name-only scan builds a FileModMap — no per-decision git calls
  • Stale decisions annotated with <!-- stale --> and surfaced as a ⚠️ Potentially Stale Decisions warning block in inject output
  • Disable with --no-stale for faster runs without git access

Session history index (chronicle session save)

  • Every session save now rebuilds .lore/sessions/_index.md — a compact markdown table of all sessions
  • chronicle inject includes...
Read more

v0.5.4

10 Apr 16:33

Choose a tag to compare

Changelog

All notable changes to Chronicle are documented here.
Format follows Keep a Changelog.
Versioning follows Semantic Versioning.


[0.5.0] — 2026-04-10

Added

New Commands

  • chronicle doctor — validates .lore/ health: checks for missing files, broken ADR links, cache integrity, and git hook installation
  • chronicle search <query> — full-text search across all .lore/ markdown files with highlighted matches and file:line context; --json flag for machine output
  • chronicle serve [--port] — zero-dependency local web viewer (dark theme, sidebar nav, live search); opens in browser automatically
  • chronicle session save|list|show — save and browse session notes in .lore/sessions/; supports piped input for auto-summaries

Parallel Extraction

  • extractFromCommits() now runs LLM batches concurrently (default concurrency=4 for API providers, 1 for Ollama)
  • --concurrency <n> flag on init and deepen for manual override
  • Benchmark: 4 batches in parallel → ~4× speedup vs sequential for Anthropic/Gemini/OpenAI

Progressive History (--limit)

  • chronicle init --limit <n> — cap initial scan to N most recent commits
  • chronicle deepen --limit <n> — process additional batches incrementally
  • Enables fast first-run (20 commits → ~5s with API) then deepening as needed

LLM Provider Updates

  • Gemini updated to gemini-2.5-flash with thinkingBudget: 0 (thinking mode disabled for structured extraction — 8× faster)
  • All providers now defensively handle partial LLM responses (missing title, affects, risk fields no longer crash)

Null-safety fixes

  • buildStore, formatDeepADR, formatDecisionEntry, formatRejectionEntry all handle LLM responses missing optional fields
  • Cache fallback: results matched to commits by hash field, with positional fallback

Fixed

  • deepen now accepts --llm, --limit, --concurrency (was hardcoded to anthropic, no limit)
  • git log delimiter changed from | to \x1f (ASCII unit separator) — fixes parsing for repos with | in commit subjects

[0.4.0] — 2026-04-10

Added

Semantic Clustering Extraction (strategy: 'clustered')

  • extractFilesFromDiff() — parses diff --git a/X b/X headers to extract the file set touched by a commit
  • clusterCommitsByFileOverlap() — groups commits into cohesive clusters where all members share at least one touched file
  • Isolated commits (no file overlap with neighbours) are batched together up to 4 per group to avoid excessive LLM calls
  • Clusters respect MAX_CLUSTER_SIZE=8 and MAX_CLUSTER_CHARS=8000 to stay within LLM context limits
  • strategyClustered() — runs one LLM call per semantic cluster instead of per fixed-size batch
  • Pass { strategy: 'clustered' } to extractFromCommits() to use the new strategy

Why it matters: The v1 simple strategy could batch "add JWT auth" with unrelated CSS tweaks. The clustered strategy ensures the LLM sees a coherent feature narrative — all commits that touched auth/ together — yielding richer rationale extraction.

Tests

  • 8 new clustering tests: file parsing, overlap detection, singleton merging, MAX_CLUSTER_SIZE cap, LLM call count
  • Total: 64 tests passing (58 TS + 6 Python)

[0.3.0] — 2025-04-10

Added

Evolution Records (chronicle evolution)

  • buildEvolution() — groups git history into eras (one per release tag + current untagged work)
  • Each era contains: decisions made, rejections logged, most-changed files, date range
  • renderEvolutionMarkdown() — renders eras to human+AI-readable .lore/evolution.md
  • mergeWithExisting() — preserves manually-written > summary fields when regenerating
  • chronicle evolution --regen — force-rebuild; --view — print to stdout
  • Auto-generates evolution.md at the end of chronicle init
  • Evolution included in chronicle inject output (first era, compact)

Terminal Status Indicator

  • Before every write command: ◆ chronicle │ N decisions · N rejected · N ADRs · last capture: Xm ago
  • After every write command: ◆ chronicle wrote +N decisions, +N rejections (only if something changed)
  • Written to stderr — doesn't pollute chronicle inject stdout pipe
  • Active for: init, deepen, setup, diagram, evolution, capture

Tests

  • 12 evolution tests: tag detection, era chaining, HEAD detection, rendering, merge behavior
  • Total: 62 tests passing (56 TS + 6 Python)

[0.2.0] — 2025-04-10

Added

Tool adapters (chronicle setup --tool=<name>)

  • claude-code / openclaw — MCP server config (.claude/mcp.json) + SessionStart/Stop hooks (.claude/settings.json); merges with existing config
  • cursor — generates .cursorrules with current .lore/ context
  • aider — writes .aider.conf.yml with --read entries for .lore/ files; idempotent
  • gemini-cli — generates GEMINI.md with compressed context
  • copilot — generates .github/copilot-instructions.md
  • codex — appends Chronicle context to AGENTS.md
  • opencode — writes .opencode.json with contextFiles entries
  • trae / factory — universal pipe instructions (chronicle inject | <tool>)
  • chronicle setup with no args lists all available integrations
  • chronicle setup --all installs every adapter at once

ASCII Diagrams (chronicle diagram)

  • All diagrams are plain .txt files — render anywhere (terminal, GitHub, AI context windows)
  • architecture.txt — module tree grouped by directory, relationships from decision log
  • dependencies.txt — import graph from source files; highlights high-blast-radius files (≥3 dependents)
  • evolution.txt — timeline from git tags + dated decision entries, grouped by year

Tests

  • 11 adapter tests covering install, idempotency, merge behavior, pipe tools
  • Total: 50 tests passing (44 TS + 6 Python)

Changed

  • Diagram files use .txt extension instead of .mmd — ASCII format, no renderer needed

Unreleased

Planned

  • Phase 8 (v3): Two-pass extraction (cheap LLM filter → quality model for complex decisions)

0.1.0 — 2025-04-10

Initial release of Chronicle — AI-native development memory.

Added

Core (@chronicle/core)

  • store.ts — file-based markdown store with findLoreRoot (walks up like git), readStore, writeStore, appendToStore, writeDeepDecision, initStore
  • scanner.ts — git history scanner with noise filtering (chore/style/docs/test prefixes), diff size threshold (≥20 changed lines), diff capping (4000 chars), tag detection
  • extractor.ts — LLM extraction engine with pluggable strategy pattern; v1 simple strategy (batches of 6, ≤5000 chars); clustered and two-pass slots reserved for v2/v3
  • cache.ts — SHA-keyed JSON file cache; prevents reprocessing commits across runs
  • ExtractionCache interface for swappable cache backends (in-memory, file, future SQLite)

CLI (chronicle-dev)

  • chronicle init [--depth] — bootstraps .lore/ from git history; progressive scan defaults to 6 months
  • chronicle inject [--files] [--full] [--format] — outputs compressed context to stdout; scopes to relevant files; supports markdown, xml, plain formats
  • chronicle deepen [--depth] — extends scan further back without reprocessing cached commits
  • chronicle hooks install/remove — installs post-commit (async decision capture) and prepare-commit-msg (risk annotation) git hooks
  • Internal chronicle capture and chronicle enrich-commit commands (invoked by hooks)

MCP Server (@chronicle/mcp)

  • chronicle_get_context — injects compressed project context; scopes to files if specified
  • chronicle_log_decision — AI logs architectural choices mid-session
  • chronicle_log_rejection — AI logs abandoned approaches (crown jewel: prevents future repetition)
  • chronicle_get_risks — returns blast-radius info before touching a file
  • chronicle_save_session — summarizes session to .lore/sessions/YYYY-MM-DD.md

Python wrapper (chronicle-dev on PyPI)

  • Thin subprocess wrapper; delegates all logic to Node CLI
  • Detects Node ≥ 20; falls back to npx chronicle-dev if not globally installed
  • Entry point: chronicle command identical to npm version

Project

  • .lore/ store structure: index.md, decisions.md, decisions/, rejected.md, risks.md, evolution.md, diagrams/, sessions/
  • Hub-and-spoke ADR model: shallow decisions inline, complex decisions in decisions/<slug>.md
  • ARCHITECTURE.md — full system design documentation
  • GitHub Actions CI (test on every push/PR) and Release (publish npm + PyPI on tag)
  • Vitest test suite for core package (store, extractor, scanner)
  • pytest suite for Python wrapper

Architecture decisions

  • Markdown-only store: no vector DB, no embeddings — plain files readable by any LLM
  • Commit SHA cache ensures bootstrap is idempotent and cost-efficient
  • Strategy pattern in extractor: v1 ships today, v2/v3 are drop-in replacements
  • Python package delegates to Node — single source of truth, no duplication

v0.5.2

10 Apr 16:09

Choose a tag to compare

Changelog

All notable changes to Chronicle are documented here.
Format follows Keep a Changelog.
Versioning follows Semantic Versioning.


[0.5.0] — 2026-04-10

Added

New Commands

  • chronicle doctor — validates .lore/ health: checks for missing files, broken ADR links, cache integrity, and git hook installation
  • chronicle search <query> — full-text search across all .lore/ markdown files with highlighted matches and file:line context; --json flag for machine output
  • chronicle serve [--port] — zero-dependency local web viewer (dark theme, sidebar nav, live search); opens in browser automatically
  • chronicle session save|list|show — save and browse session notes in .lore/sessions/; supports piped input for auto-summaries

Parallel Extraction

  • extractFromCommits() now runs LLM batches concurrently (default concurrency=4 for API providers, 1 for Ollama)
  • --concurrency <n> flag on init and deepen for manual override
  • Benchmark: 4 batches in parallel → ~4× speedup vs sequential for Anthropic/Gemini/OpenAI

Progressive History (--limit)

  • chronicle init --limit <n> — cap initial scan to N most recent commits
  • chronicle deepen --limit <n> — process additional batches incrementally
  • Enables fast first-run (20 commits → ~5s with API) then deepening as needed

LLM Provider Updates

  • Gemini updated to gemini-2.5-flash with thinkingBudget: 0 (thinking mode disabled for structured extraction — 8× faster)
  • All providers now defensively handle partial LLM responses (missing title, affects, risk fields no longer crash)

Null-safety fixes

  • buildStore, formatDeepADR, formatDecisionEntry, formatRejectionEntry all handle LLM responses missing optional fields
  • Cache fallback: results matched to commits by hash field, with positional fallback

Fixed

  • deepen now accepts --llm, --limit, --concurrency (was hardcoded to anthropic, no limit)
  • git log delimiter changed from | to \x1f (ASCII unit separator) — fixes parsing for repos with | in commit subjects

[0.4.0] — 2026-04-10

Added

Semantic Clustering Extraction (strategy: 'clustered')

  • extractFilesFromDiff() — parses diff --git a/X b/X headers to extract the file set touched by a commit
  • clusterCommitsByFileOverlap() — groups commits into cohesive clusters where all members share at least one touched file
  • Isolated commits (no file overlap with neighbours) are batched together up to 4 per group to avoid excessive LLM calls
  • Clusters respect MAX_CLUSTER_SIZE=8 and MAX_CLUSTER_CHARS=8000 to stay within LLM context limits
  • strategyClustered() — runs one LLM call per semantic cluster instead of per fixed-size batch
  • Pass { strategy: 'clustered' } to extractFromCommits() to use the new strategy

Why it matters: The v1 simple strategy could batch "add JWT auth" with unrelated CSS tweaks. The clustered strategy ensures the LLM sees a coherent feature narrative — all commits that touched auth/ together — yielding richer rationale extraction.

Tests

  • 8 new clustering tests: file parsing, overlap detection, singleton merging, MAX_CLUSTER_SIZE cap, LLM call count
  • Total: 64 tests passing (58 TS + 6 Python)

[0.3.0] — 2025-04-10

Added

Evolution Records (chronicle evolution)

  • buildEvolution() — groups git history into eras (one per release tag + current untagged work)
  • Each era contains: decisions made, rejections logged, most-changed files, date range
  • renderEvolutionMarkdown() — renders eras to human+AI-readable .lore/evolution.md
  • mergeWithExisting() — preserves manually-written > summary fields when regenerating
  • chronicle evolution --regen — force-rebuild; --view — print to stdout
  • Auto-generates evolution.md at the end of chronicle init
  • Evolution included in chronicle inject output (first era, compact)

Terminal Status Indicator

  • Before every write command: ◆ chronicle │ N decisions · N rejected · N ADRs · last capture: Xm ago
  • After every write command: ◆ chronicle wrote +N decisions, +N rejections (only if something changed)
  • Written to stderr — doesn't pollute chronicle inject stdout pipe
  • Active for: init, deepen, setup, diagram, evolution, capture

Tests

  • 12 evolution tests: tag detection, era chaining, HEAD detection, rendering, merge behavior
  • Total: 62 tests passing (56 TS + 6 Python)

[0.2.0] — 2025-04-10

Added

Tool adapters (chronicle setup --tool=<name>)

  • claude-code / openclaw — MCP server config (.claude/mcp.json) + SessionStart/Stop hooks (.claude/settings.json); merges with existing config
  • cursor — generates .cursorrules with current .lore/ context
  • aider — writes .aider.conf.yml with --read entries for .lore/ files; idempotent
  • gemini-cli — generates GEMINI.md with compressed context
  • copilot — generates .github/copilot-instructions.md
  • codex — appends Chronicle context to AGENTS.md
  • opencode — writes .opencode.json with contextFiles entries
  • trae / factory — universal pipe instructions (chronicle inject | <tool>)
  • chronicle setup with no args lists all available integrations
  • chronicle setup --all installs every adapter at once

ASCII Diagrams (chronicle diagram)

  • All diagrams are plain .txt files — render anywhere (terminal, GitHub, AI context windows)
  • architecture.txt — module tree grouped by directory, relationships from decision log
  • dependencies.txt — import graph from source files; highlights high-blast-radius files (≥3 dependents)
  • evolution.txt — timeline from git tags + dated decision entries, grouped by year

Tests

  • 11 adapter tests covering install, idempotency, merge behavior, pipe tools
  • Total: 50 tests passing (44 TS + 6 Python)

Changed

  • Diagram files use .txt extension instead of .mmd — ASCII format, no renderer needed

Unreleased

Planned

  • Phase 8 (v3): Two-pass extraction (cheap LLM filter → quality model for complex decisions)

0.1.0 — 2025-04-10

Initial release of Chronicle — AI-native development memory.

Added

Core (@chronicle/core)

  • store.ts — file-based markdown store with findLoreRoot (walks up like git), readStore, writeStore, appendToStore, writeDeepDecision, initStore
  • scanner.ts — git history scanner with noise filtering (chore/style/docs/test prefixes), diff size threshold (≥20 changed lines), diff capping (4000 chars), tag detection
  • extractor.ts — LLM extraction engine with pluggable strategy pattern; v1 simple strategy (batches of 6, ≤5000 chars); clustered and two-pass slots reserved for v2/v3
  • cache.ts — SHA-keyed JSON file cache; prevents reprocessing commits across runs
  • ExtractionCache interface for swappable cache backends (in-memory, file, future SQLite)

CLI (chronicle-dev)

  • chronicle init [--depth] — bootstraps .lore/ from git history; progressive scan defaults to 6 months
  • chronicle inject [--files] [--full] [--format] — outputs compressed context to stdout; scopes to relevant files; supports markdown, xml, plain formats
  • chronicle deepen [--depth] — extends scan further back without reprocessing cached commits
  • chronicle hooks install/remove — installs post-commit (async decision capture) and prepare-commit-msg (risk annotation) git hooks
  • Internal chronicle capture and chronicle enrich-commit commands (invoked by hooks)

MCP Server (@chronicle/mcp)

  • chronicle_get_context — injects compressed project context; scopes to files if specified
  • chronicle_log_decision — AI logs architectural choices mid-session
  • chronicle_log_rejection — AI logs abandoned approaches (crown jewel: prevents future repetition)
  • chronicle_get_risks — returns blast-radius info before touching a file
  • chronicle_save_session — summarizes session to .lore/sessions/YYYY-MM-DD.md

Python wrapper (chronicle-dev on PyPI)

  • Thin subprocess wrapper; delegates all logic to Node CLI
  • Detects Node ≥ 20; falls back to npx chronicle-dev if not globally installed
  • Entry point: chronicle command identical to npm version

Project

  • .lore/ store structure: index.md, decisions.md, decisions/, rejected.md, risks.md, evolution.md, diagrams/, sessions/
  • Hub-and-spoke ADR model: shallow decisions inline, complex decisions in decisions/<slug>.md
  • ARCHITECTURE.md — full system design documentation
  • GitHub Actions CI (test on every push/PR) and Release (publish npm + PyPI on tag)
  • Vitest test suite for core package (store, extractor, scanner)
  • pytest suite for Python wrapper

Architecture decisions

  • Markdown-only store: no vector DB, no embeddings — plain files readable by any LLM
  • Commit SHA cache ensures bootstrap is idempotent and cost-efficient
  • Strategy pattern in extractor: v1 ships today, v2/v3 are drop-in replacements
  • Python package delegates to Node — single source of truth, no duplication

v0.5.1

10 Apr 15:52

Choose a tag to compare

Changelog

All notable changes to Chronicle are documented here.
Format follows Keep a Changelog.
Versioning follows Semantic Versioning.


[0.5.0] — 2026-04-10

Added

New Commands

  • chronicle doctor — validates .lore/ health: checks for missing files, broken ADR links, cache integrity, and git hook installation
  • chronicle search <query> — full-text search across all .lore/ markdown files with highlighted matches and file:line context; --json flag for machine output
  • chronicle serve [--port] — zero-dependency local web viewer (dark theme, sidebar nav, live search); opens in browser automatically
  • chronicle session save|list|show — save and browse session notes in .lore/sessions/; supports piped input for auto-summaries

Parallel Extraction

  • extractFromCommits() now runs LLM batches concurrently (default concurrency=4 for API providers, 1 for Ollama)
  • --concurrency <n> flag on init and deepen for manual override
  • Benchmark: 4 batches in parallel → ~4× speedup vs sequential for Anthropic/Gemini/OpenAI

Progressive History (--limit)

  • chronicle init --limit <n> — cap initial scan to N most recent commits
  • chronicle deepen --limit <n> — process additional batches incrementally
  • Enables fast first-run (20 commits → ~5s with API) then deepening as needed

LLM Provider Updates

  • Gemini updated to gemini-2.5-flash with thinkingBudget: 0 (thinking mode disabled for structured extraction — 8× faster)
  • All providers now defensively handle partial LLM responses (missing title, affects, risk fields no longer crash)

Null-safety fixes

  • buildStore, formatDeepADR, formatDecisionEntry, formatRejectionEntry all handle LLM responses missing optional fields
  • Cache fallback: results matched to commits by hash field, with positional fallback

Fixed

  • deepen now accepts --llm, --limit, --concurrency (was hardcoded to anthropic, no limit)
  • git log delimiter changed from | to \x1f (ASCII unit separator) — fixes parsing for repos with | in commit subjects

[0.4.0] — 2026-04-10

Added

Semantic Clustering Extraction (strategy: 'clustered')

  • extractFilesFromDiff() — parses diff --git a/X b/X headers to extract the file set touched by a commit
  • clusterCommitsByFileOverlap() — groups commits into cohesive clusters where all members share at least one touched file
  • Isolated commits (no file overlap with neighbours) are batched together up to 4 per group to avoid excessive LLM calls
  • Clusters respect MAX_CLUSTER_SIZE=8 and MAX_CLUSTER_CHARS=8000 to stay within LLM context limits
  • strategyClustered() — runs one LLM call per semantic cluster instead of per fixed-size batch
  • Pass { strategy: 'clustered' } to extractFromCommits() to use the new strategy

Why it matters: The v1 simple strategy could batch "add JWT auth" with unrelated CSS tweaks. The clustered strategy ensures the LLM sees a coherent feature narrative — all commits that touched auth/ together — yielding richer rationale extraction.

Tests

  • 8 new clustering tests: file parsing, overlap detection, singleton merging, MAX_CLUSTER_SIZE cap, LLM call count
  • Total: 64 tests passing (58 TS + 6 Python)

[0.3.0] — 2025-04-10

Added

Evolution Records (chronicle evolution)

  • buildEvolution() — groups git history into eras (one per release tag + current untagged work)
  • Each era contains: decisions made, rejections logged, most-changed files, date range
  • renderEvolutionMarkdown() — renders eras to human+AI-readable .lore/evolution.md
  • mergeWithExisting() — preserves manually-written > summary fields when regenerating
  • chronicle evolution --regen — force-rebuild; --view — print to stdout
  • Auto-generates evolution.md at the end of chronicle init
  • Evolution included in chronicle inject output (first era, compact)

Terminal Status Indicator

  • Before every write command: ◆ chronicle │ N decisions · N rejected · N ADRs · last capture: Xm ago
  • After every write command: ◆ chronicle wrote +N decisions, +N rejections (only if something changed)
  • Written to stderr — doesn't pollute chronicle inject stdout pipe
  • Active for: init, deepen, setup, diagram, evolution, capture

Tests

  • 12 evolution tests: tag detection, era chaining, HEAD detection, rendering, merge behavior
  • Total: 62 tests passing (56 TS + 6 Python)

[0.2.0] — 2025-04-10

Added

Tool adapters (chronicle setup --tool=<name>)

  • claude-code / openclaw — MCP server config (.claude/mcp.json) + SessionStart/Stop hooks (.claude/settings.json); merges with existing config
  • cursor — generates .cursorrules with current .lore/ context
  • aider — writes .aider.conf.yml with --read entries for .lore/ files; idempotent
  • gemini-cli — generates GEMINI.md with compressed context
  • copilot — generates .github/copilot-instructions.md
  • codex — appends Chronicle context to AGENTS.md
  • opencode — writes .opencode.json with contextFiles entries
  • trae / factory — universal pipe instructions (chronicle inject | <tool>)
  • chronicle setup with no args lists all available integrations
  • chronicle setup --all installs every adapter at once

ASCII Diagrams (chronicle diagram)

  • All diagrams are plain .txt files — render anywhere (terminal, GitHub, AI context windows)
  • architecture.txt — module tree grouped by directory, relationships from decision log
  • dependencies.txt — import graph from source files; highlights high-blast-radius files (≥3 dependents)
  • evolution.txt — timeline from git tags + dated decision entries, grouped by year

Tests

  • 11 adapter tests covering install, idempotency, merge behavior, pipe tools
  • Total: 50 tests passing (44 TS + 6 Python)

Changed

  • Diagram files use .txt extension instead of .mmd — ASCII format, no renderer needed

Unreleased

Planned

  • Phase 8 (v3): Two-pass extraction (cheap LLM filter → quality model for complex decisions)

0.1.0 — 2025-04-10

Initial release of Chronicle — AI-native development memory.

Added

Core (@chronicle/core)

  • store.ts — file-based markdown store with findLoreRoot (walks up like git), readStore, writeStore, appendToStore, writeDeepDecision, initStore
  • scanner.ts — git history scanner with noise filtering (chore/style/docs/test prefixes), diff size threshold (≥20 changed lines), diff capping (4000 chars), tag detection
  • extractor.ts — LLM extraction engine with pluggable strategy pattern; v1 simple strategy (batches of 6, ≤5000 chars); clustered and two-pass slots reserved for v2/v3
  • cache.ts — SHA-keyed JSON file cache; prevents reprocessing commits across runs
  • ExtractionCache interface for swappable cache backends (in-memory, file, future SQLite)

CLI (chronicle-dev)

  • chronicle init [--depth] — bootstraps .lore/ from git history; progressive scan defaults to 6 months
  • chronicle inject [--files] [--full] [--format] — outputs compressed context to stdout; scopes to relevant files; supports markdown, xml, plain formats
  • chronicle deepen [--depth] — extends scan further back without reprocessing cached commits
  • chronicle hooks install/remove — installs post-commit (async decision capture) and prepare-commit-msg (risk annotation) git hooks
  • Internal chronicle capture and chronicle enrich-commit commands (invoked by hooks)

MCP Server (@chronicle/mcp)

  • chronicle_get_context — injects compressed project context; scopes to files if specified
  • chronicle_log_decision — AI logs architectural choices mid-session
  • chronicle_log_rejection — AI logs abandoned approaches (crown jewel: prevents future repetition)
  • chronicle_get_risks — returns blast-radius info before touching a file
  • chronicle_save_session — summarizes session to .lore/sessions/YYYY-MM-DD.md

Python wrapper (chronicle-dev on PyPI)

  • Thin subprocess wrapper; delegates all logic to Node CLI
  • Detects Node ≥ 20; falls back to npx chronicle-dev if not globally installed
  • Entry point: chronicle command identical to npm version

Project

  • .lore/ store structure: index.md, decisions.md, decisions/, rejected.md, risks.md, evolution.md, diagrams/, sessions/
  • Hub-and-spoke ADR model: shallow decisions inline, complex decisions in decisions/<slug>.md
  • ARCHITECTURE.md — full system design documentation
  • GitHub Actions CI (test on every push/PR) and Release (publish npm + PyPI on tag)
  • Vitest test suite for core package (store, extractor, scanner)
  • pytest suite for Python wrapper

Architecture decisions

  • Markdown-only store: no vector DB, no embeddings — plain files readable by any LLM
  • Commit SHA cache ensures bootstrap is idempotent and cost-efficient
  • Strategy pattern in extractor: v1 ships today, v2/v3 are drop-in replacements
  • Python package delegates to Node — single source of truth, no duplication