This document captures the research behind ACF's context compaction (phase 7) and caveman mode (phase 8), including the sources studied, the techniques adapted, and the design decisions made.
ACF's compaction system is inspired by Kimi CLI's open-source compaction system, developed by MoonshotAI. The following sources were studied:
- Repository: MoonshotAI/kimi-cli
- File:
src/kimi_cli/soul/compaction.py - Key contribution: the
Compactionprotocol,SimpleCompactionimplementation, andshould_auto_compacttrigger logic
- File:
src/kimi_cli/prompts/compact.md - Key contribution: compression priorities (Current Task State, Errors &
Solutions, Code Evolution, System Context, Design Decisions, TODO Items) and
XML-tagged output structure (
<current_focus>,<environment>,<completed_tasks>,<active_issues>,<code_state>,<important_context>)
- Commit: 86e0c92
- Key contribution: rewriting the compaction summary as the agent's own continuing notes (first-person), not a third-party report. Preserves exact commands, paths, and outcomes; states the precise next action; flags claimed-but-unverified work.
- Commit: 329846c
- Key contribution: keeping the oldest 2k tokens and the most recent 18k tokens of user messages, with an elision marker between them. The original task statement no longer vanishes in long sessions.
- PR: feat(compaction): support custom /compact instructions
- Key contribution:
/compact keep db discussions— the user can tell the model what to prioritize when compressing. ACF adapts this as"compact context — keep the stack-audit findings".
- URL: https://moonshotai.github.io/kimi-code/en/guides/sessions.html
- Key contribution: user-facing documentation of auto-compaction and manual
/compactcommand
- URL: https://deepwiki.com/MoonshotAI/kimi-cli/7.3-context-compaction
- Key contribution: architectural overview of the compaction system, including
the
Compactionprotocol,SimpleCompactionstrategy, and token estimation heuristics
Kimi's approach: SimpleCompaction splits messages into to_compact
(older, summarized) and to_preserve (recent, verbatim). Default
max_preserved_messages = 2. Kimi Code's PR #1313 extends this to a
three-region split: head (oldest, verbatim), tail (most recent, verbatim),
and middle (compacted), with an elision marker between head and tail.
ACF's adaptation: ACF uses a three-region split with SDLC-specific bounds:
- Head (max 500 tokens): the original user request — the first message of the session — is preserved verbatim. This ensures the original task statement never vanishes in long sessions.
- Tail (max 1000 tokens): the most recent phase output (e.g., the last stack-audit findings or the current issue draft) is preserved verbatim.
- Middle: everything between head and tail is compacted using priority-based compression.
- Elision marker:
[... ~N tokens compacted ...]is inserted between the head and tail sections.
If the head or tail exceeds its token budget, it is truncated with a
[... truncated ...] marker. If the entire session fits within head + tail
budgets, no compaction is needed.
Kimi's approach: the compact.md prompt defines compression priorities in
order: Current Task State, Errors & Solutions, Code Evolution, System Context,
Design Decisions, TODO Items. Rules: MUST KEEP errors/working solutions,
MERGE similar discussions, REMOVE redundant explanations, CONDENSE long code
blocks.
ACF's adaptation: ACF applies the same priorities to the SDLC context:
- Current issue/PR draft — preserve verbatim
- Stack-audit findings — preserve orphan PRs, close gaps, escaped issues
- Test commands and CI checks — preserve exact command strings
- Architecture facts — compress to one-line summaries
- Conventions — compress to label names only
- Completed phases — compress to one-line outcomes
Kimi's approach: the compaction output uses XML-like tags:
<current_focus>, <environment>, <completed_tasks>, <active_issues>,
<code_state>, <important_context>.
ACF's adaptation: ACF uses SDLC-specific tags:
<current_focus>, <stack>, <tests>, <ci>, <architecture>,
<conventions>, <completed_phases>.
Kimi's approach (from PR #1214): the compaction summary is written as the agent's own continuing notes. It preserves exact commands, paths, and outcomes; states the precise next action; flags claimed-but-unverified work rather than trusting it. The summary prefix uses a skeptical "your own working notes" framing.
ACF's adaptation: after compaction, the progress file reads as the agent's own working notes, structured as head + elision + tail + compacted summary:
## Compacted Handoff
### Original Request (preserved)
[user's original request, verbatim — max 500 tokens]
[... ~N tokens compacted ...]
### Current State (preserved)
[most recent phase output, verbatim — max 1000 tokens]
### Compacted Summary
I was working on [issue/PR title]. The context snapshot is compacted.
What I know:
- Stack has [N] orphan PRs, [M] stale issues
- Test command: [exact command] — [N] tests pass
- CI check: [check name] must pass
What I need to do next:
- [precise next action]
What I have NOT verified yet:
- [anything claimed but not confirmed]Kimi's approach: should_auto_compact triggers when either:
token_count >= max_context_size * trigger_ratio(default 0.85)token_count + reserved_context_size >= max_context_size
ACF's adaptation: same logic, but with ACF-specific defaults:
max_context_size: 8000 tokens (ACF context is already compressed)trigger_ratio: 0.75 (compact earlier than Kimi's 0.85)reserved_context_size: 2000 tokens (space for the next phase's output)
Kimi's approach: /compact keep db discussions — the user provides a hint
that is appended to the compaction prompt, telling the model what to prioritize.
ACF's adaptation: "compact context — keep the stack-audit findings" —
the custom instruction is appended to the compaction prompt in the same way.
Kimi's approach: estimate_text_tokens() calculates total_chars // 4
(approx. 4 chars per token for English).
ACF's adaptation: same heuristic for English content. For Spanish content,
use chars // 3.5 (Spanish has more characters per token due to accents and
longer words).
Caveman mode (phase 8) is NOT from Kimi. It is original to ACF, taking Kimi's compression rules to their logical extreme.
Kimi's compaction targets ~800 tokens (from ~2000). But some models have very small context windows (<8K tokens), and some users run on budget-constrained APIs where every token costs money. Caveman mode targets <500 tokens, with a "bare caveman" last resort at ~100 tokens.
- No prose — every word must earn its place
- Paths, not descriptions —
AGENTS.mdnot "the agent directives file" - Counts, not lists —
26 servicesnot 26 service names - Labels, not sentences —
priority:P1not "this is high priority" - Commands, not explanations —
lune run scripts/test_core.luaunot "run the core test suite" - Symbols over words —
→,|,#N
- Architecture context — only a one-line stack summary
- Convention details — only label names, no rules
- Library opportunities — reduced to a count
- Stale issue titles — reduced to issue numbers
- Template structure — not included at all
If any of these are critical, use compaction (phase 7) instead.
When even the caveman snapshot is too large:
NOW:<issue/PR 1line>
NEXT:<action 1line>
TEST:<cmd> → <N>pass
CI:<check>@<wf>
~100 tokens. Loses all stack context but preserves the ability to craft an issue or PR with the right test command and CI check.
Full snapshot (~2000 tokens)
│
▼ [trigger_ratio exceeded]
Compacted snapshot (~800 tokens, phase 7)
│
▼ [still too large or caveman requested]
Caveman snapshot (<500 tokens, phase 8)
│
▼ [still too large]
Bare caveman (~100 tokens)
Kimi CLI's compaction system is open-source, well-documented, and battle-tested in production. Adapting it gives ACF a solid foundation without reinventing the wheel. The four key techniques (head+tail preservation, priority-based compression, XML-tagged output, first-person handoff) are directly applicable to the SDLC context that ACF manages.
Compaction is lossy but structured — it preserves the shape of the data in XML tags. Caveman is lossy and unstructured — it reduces everything to bare marks. They serve different needs:
- Compaction: "I have too much context but I still need structure"
- Caveman: "I have almost no context budget, give me the bare minimum"
Making caveman a separate phase (not just "more aggressive compaction") keeps the two modes cleanly separated and lets the user choose explicitly.
ACF's context is already compressed (paths, labels, counts). The full snapshot starts at ~2000 tokens, not ~200K tokens like a raw conversation. Compacting at 0.85 would leave very little headroom for the next phase. 0.75 gives more buffer.
Compaction is lossy by design. Keeping the original would double the token cost. If the full snapshot is needed, re-run context-load (it's cheap — just reading MDs and building a path index).
- Head+tail preservation (adapted from Kimi Code PR #1313): the original
user request (head, max 500 tokens) and the most recent phase output (tail,
max 1000 tokens) are preserved verbatim, with an elision marker
(
[... ~N tokens compacted ...]) between them. The middle is compacted using priority-based compression. Seeskills/07-compaction/SKILL.md§"Head+Tail Preservation".
- Compaction metrics: track token savings per phase, per project
- Caveman auto-detection: detect the model's context window size and auto-select between full, compacted, and caveman modes
- Cross-project compaction: compact context across multiple projects in a monorepo or org