init: --no-history, for checkouts that never read the past - #94
Conversation
`kai init` replays up to 50 commits as snapshots, and on any real repo that import is nearly all of its wall clock: measured on kai-server at ba7e4c2, 83.7s with the import and 4.1s without — the semantic graph itself is 2.7s of that. The review pod pays it every run and reads none of it. The blast walk uses the freshly-captured single-snapshot graph, and base...head comes from git; the imported snapshots exist for `kai log`, blame and bisect, which nothing in a container that is deleted at the end of one review will ever run. Default behavior is unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
jschatz1 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Kai review
Kai Summary
Read through this one. One thing worth your eyes before it merges. 👇
Review: kai init --no-history
Scope: kai-engine, commit 3e49fd6. I read the production change in cmd/kai/main.go (the init flow, runGitImport, and the already-initialized short-circuit), the new test file, and the existing init_test.go for comparison. Nothing outside this repo is implicated.
What it does: Adds a --no-history flag (wired to the initNoHistory global) that, when set, skips the runGitImport call inside runInit. Default behavior is untouched — the import still runs whenever the flag is absent. Two tests cover both branches by counting KindSnapshot nodes after init.
Overall take: This is a clean, narrowly-scoped change with a genuine fix-test. The guard is correctly placed inside the isGitRepo block, the default path is byte-for-byte preserved (the old code is just nested one level deeper under if !initNoHistory), and the no-history test would actually fail on the pre-change code. I have no defects to report.
A few things I specifically verified:
- The test is not a no-op.
TestInitNoHistorySkipsTheImportsetsinitNoHistory = trueand asserts exactly one snapshot. On the pre-change code,initNoHistoryis never read, sorunGitImportwould run unconditionally for the 3-commit repo and produce 3 history snapshots plus the working-tree capture, failing thegot != 1assertion. With the fix, only the Step-4runCapturesnapshot exists, sogot == 1passes. This is a real regression guard, not a mechanism-asserts-config shape. - The default test guards the right invariant.
TestInitImportsHistoryByDefaultasserts\> 1snapshots, which requires the import to have actually run — so a future regression that accidentally gates the import too broadly (e.g., inverting the flag) is caught here too. - Global mutation is safe under the test runner.
runInitInReposaves/restores four package globals viat.Cleanup. These tests don't callt.Parallel(), so they run sequentially within the package; no data race on the globals.snapshotCountreadskaiDirwhile it's still.kai(cleanup is LIFO, runs after the count), and uses an absolutedirjoin, so it's correct regardless of cwd. - No downstream breakage from skipping the import.
runGitImport's side effects beyond snapshot creation are writinggraph_refspins and thekaiDir/messagefile; with--no-historythose simply aren't produced, which is consistent with a one-shot checkout that never runskai log/blame/bisect. The capture that follows is independent and still runs, so the head graph the review actually reads is present. - The pre-existing
git rev-list/runGitImportshell-outs have no deadline. That's unchanged by this diff — the change only adds a gate in front of them — so it's not a new defect, though a timeout on those subprocesses would be a worthwhile follow-up for the non-no-history path.
One non-defect worth flagging as a decision: --no-history is a new user-facing flag that, when passed, silently removes the data backing kai log, blame, and bisect for that workspace. It's opt-in, default-preserving, and clearly documented in the flag help text, so it's low-stakes. The decision a human owns is how broadly it gets wired into automation templates — a CI config that defaults every kai init to --no-history would quietly strip history from every workspace that uses it. The flag itself is fine; the policy of where it's applied is the thing to keep an eye on.
Merge readiness: This is ready to merge — no defects, and the only decision (where --no-history gets baked into automation) lives outside this diff.
Important files changed
| File | Change |
|---|---|
cmd/kai/init_no_history_test.go |
modified · +99 −0 |
cmd/kai/main.go |
modified · +20 −5 |
Decisions
Correct as written, but somebody should say yes to these:
--no-historyis a new opt-in flag that stripskai log/blame/bisect data from a workspace; the flag is fine, but wherever it gets defaulted into automation templates is a policy decision about how broadly history is suppressed, affecting anyone whose init runs through that template.
+119 −5 · 2 files · reaches 0 · the full analysis
💬 Reply to any of my comments and I'll answer, or say @kaicontext anywhere on this PR — a question, or "take another look at the retry logic".
Chasing why a PR review takes ~16 minutes. On kai-server#195 the run was 979s, and 875s of it was one line:
kai initin the review pod.Almost none of that is the semantic graph.
kai initreplays up to 50 commits as snapshots (runGitImport, capped atimportMaxCommits) before it captures the working tree.Measured on a fresh clone of kai-server at
ba7e4c2withKAI_CAPTURE_TIMING=1:kai init(git history + graph)kai initwith no.gitpresent (graph only)So ~95% of init is history the caller may never touch. That's a fine trade for a person — it's what makes
kai log, blame and bisect worth having — and a pure tax on a container that is deleted at the end of one review: the reviewer's blast walk uses the freshly-captured single-snapshot graph (BlastFor(..., headHex "")), andbase...headcomes from git.--no-historyskips the import. Default behavior is unchanged.Two tests:
--no-historyleaves exactly one snapshot (the working-tree capture, which the review does read), and the default still imports more than one.The consumer is kaicontext/kai-server#198, which probes for the flag rather than hardcoding it — the pinned kai-ci image predates it, so nothing changes until the pin moves to an image built from this.
🤖 Generated with Claude Code