optimize: consolidate agent-optimization module + reversible-compression retrieve (CCR) - #204
Conversation
Renamed crates: caveman->flare-output, ponytail->flare-code.
Created src/flare/ module (output/code/context/runtime layers).
New CLI: agentflare flare {output,code,context,status}.
Legacy aliases: agentflare {caveman,ponytail} kept.
Rebranded embedded .md rule files in flare-code crate.
Updated config.rs detect.rs platform.rs state.rs switcher.rs.
…module in Consolidation module + CLI renamed flare -> optimize (flare stays the brand namespace: mcp__flare, flare-* crates). src/flare -> src/optimize, src/cli/flare.rs -> src/cli/optimize.rs, FlareArgs -> OptimizeArgs. The existing session-hygiene/routing module (src/optimize.rs) folds in as src/optimize/runtime.rs via a glob re-export, so crate::optimize::* call sites are unchanged. CLI: optimize primary; flare and opt as aliases. Brand crates and init.rs hook strings untouched.
…d index; TTL-on-list; sorted MCP list
The consolidation locked `optimize` as the module/command name (flare is the
namespace). AGENTS.md still documented `agentflare flare {output,code,context}`;
update the table + prose to `optimize` and list `agentflare flare` alongside
caveman/ponytail as a backward-compatible alias.
📝 WalkthroughWalkthroughThe PR consolidates output, code, context, retrieval, and runtime capabilities under ChangesOptimize module consolidation
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant CLI
participant Compressor
participant Registry
participant MCP
CLI->>Compressor: compress input
Compressor-->>CLI: report and original path
CLI->>Registry: register backup and create marker
Registry-->>CLI: retrieval id
MCP->>Registry: retrieve id
Registry-->>MCP: original content
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 11
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/cli/caveman.rs (1)
58-66: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winLegacy
caveman compresspath doesn't register the CCR entry, unlike the newoptimize output compress.
src/cli/optimize.rs'sOutputAction::runcallsrecord_and_marker(...)on success to register the original with the retrieve registry and print an expand marker; this duplicate success-path logic inCavemanArgs::runomits that call entirely. Content isn't lost (the backup/original still exists on disk), but users of the deprecatedcaveman/hiddenflarealias get no short-id or hint thatagentflare optimize retrieve <id>can recover it, breaking the documented recovery workflow for anyone still on the legacy entry point. Based on learnings, recovery of output-layer compressed content is expected viaagentflare optimize retrieve <id>.♻️ Proposed fix (also reduces duplication)
match result { Ok(report) => { let pct = 100 - (100 * report.compressed_bytes / report.original_bytes.max(1)); println!( "{}→{}B ▼{pct}%", report.original_bytes, report.compressed_bytes ); + println!( + "{}", + crate::cli::optimize::record_and_marker( + report.original_path.clone(), + report.original_bytes as u64, + report.compressed_bytes as u64, + crate::optimize::retrieve::now_unix(), + ) + ); }(requires making
record_and_markerinsrc/cli/optimize.rsat leastpub(crate))🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/cli/caveman.rs` around lines 58 - 66, Update the successful compression branch in CavemanArgs::run to invoke the existing record_and_marker helper, matching OutputAction::run in optimize.rs. Expose record_and_marker as pub(crate) if necessary, and pass the legacy compression result’s original/output context so the CCR entry and expand marker are registered before or alongside the existing summary output.Source: Learnings
crates/flare-code/src/platform.rs (1)
68-74: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick winStale assertion will fail: test still expects
"PONYTAIL:FULL".
format_hook_outputnow emitssystemMessage: "FLARE CODE:FULL"(line 39), but this test still asserts"PONYTAIL:FULL"— it will fail on the nextcargo testrun.🐛 Proposed fix
- assert_eq!(parsed["systemMessage"], "PONYTAIL:FULL"); + assert_eq!(parsed["systemMessage"], "FLARE CODE:FULL");🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/flare-code/src/platform.rs` around lines 68 - 74, Update the expected systemMessage assertion in codex_session_start_includes_system_message to match the current "FLARE CODE:FULL" output produced by format_hook_output, while preserving the existing additionalContext and hookSpecificOutput assertions.
🧹 Nitpick comments (2)
crates/flare-output/src/llm.rs (1)
29-29: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueHardcoded default model may go stale.
claude-sonnet-4-5is still a valid alias, but Anthropic ships new model generations frequently (e.g. Sonnet 4.6, Sonnet 5 already exist). Since this is only a fallback whenCAVEMAN_MODELisn't set, impact is limited, but consider documenting the override env var prominently or bumping the default periodically.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/flare-output/src/llm.rs` at line 29, Update the fallback model handling in the model initialization to avoid an undocumented stale hardcoded default: prominently document the CAVEMAN_MODEL override near this configuration, and select the currently supported default model according to the project’s model policy. Preserve the environment-variable override behavior.src/optimize/retrieve.rs (1)
261-278: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value
retrieve()doesn't enforce TTL likeactive_state()does.
active_state()explicitly re-checks TTL "on read, not just at registration" (comment at line 193-195), butretrieve(id)just does a rawload_state()lookup — an id can remain retrievable pastTTL_SECSuntil some otherregister()/listcall happens to trigger a prune. Low impact (id holders are implicitly trusted local callers), but worth aligning for consistency with the stated TTL design intent.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/optimize/retrieve.rs` around lines 261 - 278, Update retrieve() to enforce TTL on read, matching active_state() by loading the state through the existing TTL-aware path or rechecking expiration before resolving the entry. Ensure expired IDs are treated as unavailable while preserving current retrieval behavior for active entries and existing error handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@AGENTS.md`:
- Around line 21-22: Update the legacy command documentation in AGENTS.md to
include the visible agentflare opt shorthand and identify agentflare flare as a
hidden legacy alias, while retaining caveman and ponytail as backward-compatible
aliases.
In `@crates/flare-code/src/skill-debt.md`:
- Line 20: Update the documented grep scan command in skill-debt.md to exclude
node_modules, .git, and build-output directories using appropriate --exclude-dir
flags, while preserving the existing flare-code pattern and recursive scan
behavior.
In `@crates/flare-code/src/skill-no-hallucination.md`:
- Around line 1-35: Complete the legacy-name migration across all embedded skill
cards: in crates/flare-code/src/skill-no-hallucination.md (lines 1-35), rename
metadata, headings, triggers, and revert text from ponytail to flare-code; apply
the same identity, comparison, trigger, invocation, and revert updates in
crates/flare-code/src/skill-playbook.md (lines 1-41) and
crates/flare-code/src/skill-review.md (lines 1-91); in
crates/flare-code/src/skill.md (lines 137-138), replace the stale Caveman
companion reference with flare-output terminology.
In `@crates/flare-code/src/skill.md`:
- Around line 29-30: Update the command reference in the skill documentation
from `/flare code` to the documented hyphenated `/flare-code` form, while
preserving the existing mode options and default behavior.
In `@crates/flare-output/src/sensitive.rs`:
- Around line 26-35: Update the sensitive-name matching logic using
SENSITIVE_NAME_TOKENS so tokens are recognized only at word boundaries rather
than through raw substring containment. Preserve matches for genuinely sensitive
names while allowing filenames such as secretary.md, tokenizer.py,
tokenomics.md, and detokenize.md to pass the compress() gate in the surrounding
sensitive-check flow.
In `@crates/flare-output/src/validate.rs`:
- Around line 17-22: Update extract_headings to remove fenced code blocks before
applying HEADING_REGEX, matching the preprocessing used by extract_inline_codes.
Preserve the existing heading capture and trimming behavior while ensuring
`#-prefixed` lines inside fenced blocks are not returned as headings.
In `@opencode.json`:
- Around line 9-10: Remove the obsolete rust-analyzer.inlayHints.enable setting
from the configuration, leaving rust-analyzer diagnostics and any per-hint-group
controls unchanged.
In `@src/cli/optimize.rs`:
- Around line 77-78: Use saturating subtraction when calculating the compression
percentage so values above 100 do not panic. Update the percentage calculation
associated with report.compressed_bytes in src/cli/optimize.rs lines 77-78 and
the corresponding calculation in src/cli/caveman.rs lines 60-61, using
100usize.saturating_sub(...) or a shared helper to keep both paths aligned.
In `@src/mcp_server.rs`:
- Around line 2195-2202: Update the "list" handler to serialize a summary
representation of each CompressionEntry rather than the full entries, excluding
the kind field and its backup_path/blob_path data. Preserve the existing state
retrieval and created_ts descending sort, and use the summary only for the final
serde_json::to_string response.
- Around line 2186-2194: Update optimize’s retrieve branch to map
RetrieveError::NotFound from retrieve::retrieve to ErrorData::invalid_params
while preserving internal_error for other failures. In the optimize list branch,
stop serializing CompressionEntry directly and construct a response
representation that omits or redacts backup_path and blob_path before returning
data over MCP.
In `@src/optimize/runtime.rs`:
- Around line 70-87: Update has_word_boundary_match to validate both sides of
each keyword match: retain the existing preceding-character check and require
the character immediately after the keyword to be non-alphabetic or the end of
text. Preserve the current scanning behavior and ensure keywords with trailing
spaces continue to work correctly.
---
Outside diff comments:
In `@crates/flare-code/src/platform.rs`:
- Around line 68-74: Update the expected systemMessage assertion in
codex_session_start_includes_system_message to match the current "FLARE
CODE:FULL" output produced by format_hook_output, while preserving the existing
additionalContext and hookSpecificOutput assertions.
In `@src/cli/caveman.rs`:
- Around line 58-66: Update the successful compression branch in
CavemanArgs::run to invoke the existing record_and_marker helper, matching
OutputAction::run in optimize.rs. Expose record_and_marker as pub(crate) if
necessary, and pass the legacy compression result’s original/output context so
the CCR entry and expand marker are registered before or alongside the existing
summary output.
---
Nitpick comments:
In `@crates/flare-output/src/llm.rs`:
- Line 29: Update the fallback model handling in the model initialization to
avoid an undocumented stale hardcoded default: prominently document the
CAVEMAN_MODEL override near this configuration, and select the currently
supported default model according to the project’s model policy. Preserve the
environment-variable override behavior.
In `@src/optimize/retrieve.rs`:
- Around line 261-278: Update retrieve() to enforce TTL on read, matching
active_state() by loading the state through the existing TTL-aware path or
rechecking expiration before resolving the entry. Ensure expired IDs are treated
as unavailable while preserving current retrieval behavior for active entries
and existing error handling.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 7bc8fb9f-7792-4e68-ab93-ba48aa745eb0
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (45)
AGENTS.mdCargo.tomlcrates/flare-code/CHANGELOG.mdcrates/flare-code/Cargo.tomlcrates/flare-code/src/config.rscrates/flare-code/src/detect.rscrates/flare-code/src/instructions.rscrates/flare-code/src/lib.rscrates/flare-code/src/platform.rscrates/flare-code/src/skill-audit.mdcrates/flare-code/src/skill-debt.mdcrates/flare-code/src/skill-gain.mdcrates/flare-code/src/skill-help.mdcrates/flare-code/src/skill-no-hallucination.mdcrates/flare-code/src/skill-playbook.mdcrates/flare-code/src/skill-review.mdcrates/flare-code/src/skill.mdcrates/flare-code/src/state.rscrates/flare-code/src/sub_skills.rscrates/flare-code/src/switcher.rscrates/flare-output/CHANGELOG.mdcrates/flare-output/Cargo.tomlcrates/flare-output/src/compress.rscrates/flare-output/src/error.rscrates/flare-output/src/frontmatter.rscrates/flare-output/src/lib.rscrates/flare-output/src/llm.rscrates/flare-output/src/prompt.rscrates/flare-output/src/sensitive.rscrates/flare-output/src/validate.rscrates/ponytail/src/skill-help.mdopencode.jsonsrc/cli/caveman.rssrc/cli/mod.rssrc/cli/optimize.rssrc/cli/ponytail.rssrc/compact.rssrc/mcp_prompts.rssrc/mcp_server.rssrc/optimize/code.rssrc/optimize/context.rssrc/optimize/mod.rssrc/optimize/output.rssrc/optimize/retrieve.rssrc/optimize/runtime.rs
💤 Files with no reviewable changes (1)
- crates/ponytail/src/skill-help.md
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 11
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/cli/caveman.rs (1)
58-66: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winLegacy
caveman compresspath doesn't register the CCR entry, unlike the newoptimize output compress.
src/cli/optimize.rs'sOutputAction::runcallsrecord_and_marker(...)on success to register the original with the retrieve registry and print an expand marker; this duplicate success-path logic inCavemanArgs::runomits that call entirely. Content isn't lost (the backup/original still exists on disk), but users of the deprecatedcaveman/hiddenflarealias get no short-id or hint thatagentflare optimize retrieve <id>can recover it, breaking the documented recovery workflow for anyone still on the legacy entry point. Based on learnings, recovery of output-layer compressed content is expected viaagentflare optimize retrieve <id>.♻️ Proposed fix (also reduces duplication)
match result { Ok(report) => { let pct = 100 - (100 * report.compressed_bytes / report.original_bytes.max(1)); println!( "{}→{}B ▼{pct}%", report.original_bytes, report.compressed_bytes ); + println!( + "{}", + crate::cli::optimize::record_and_marker( + report.original_path.clone(), + report.original_bytes as u64, + report.compressed_bytes as u64, + crate::optimize::retrieve::now_unix(), + ) + ); }(requires making
record_and_markerinsrc/cli/optimize.rsat leastpub(crate))🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/cli/caveman.rs` around lines 58 - 66, Update the successful compression branch in CavemanArgs::run to invoke the existing record_and_marker helper, matching OutputAction::run in optimize.rs. Expose record_and_marker as pub(crate) if necessary, and pass the legacy compression result’s original/output context so the CCR entry and expand marker are registered before or alongside the existing summary output.Source: Learnings
crates/flare-code/src/platform.rs (1)
68-74: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick winStale assertion will fail: test still expects
"PONYTAIL:FULL".
format_hook_outputnow emitssystemMessage: "FLARE CODE:FULL"(line 39), but this test still asserts"PONYTAIL:FULL"— it will fail on the nextcargo testrun.🐛 Proposed fix
- assert_eq!(parsed["systemMessage"], "PONYTAIL:FULL"); + assert_eq!(parsed["systemMessage"], "FLARE CODE:FULL");🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/flare-code/src/platform.rs` around lines 68 - 74, Update the expected systemMessage assertion in codex_session_start_includes_system_message to match the current "FLARE CODE:FULL" output produced by format_hook_output, while preserving the existing additionalContext and hookSpecificOutput assertions.
🧹 Nitpick comments (2)
crates/flare-output/src/llm.rs (1)
29-29: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueHardcoded default model may go stale.
claude-sonnet-4-5is still a valid alias, but Anthropic ships new model generations frequently (e.g. Sonnet 4.6, Sonnet 5 already exist). Since this is only a fallback whenCAVEMAN_MODELisn't set, impact is limited, but consider documenting the override env var prominently or bumping the default periodically.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/flare-output/src/llm.rs` at line 29, Update the fallback model handling in the model initialization to avoid an undocumented stale hardcoded default: prominently document the CAVEMAN_MODEL override near this configuration, and select the currently supported default model according to the project’s model policy. Preserve the environment-variable override behavior.src/optimize/retrieve.rs (1)
261-278: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value
retrieve()doesn't enforce TTL likeactive_state()does.
active_state()explicitly re-checks TTL "on read, not just at registration" (comment at line 193-195), butretrieve(id)just does a rawload_state()lookup — an id can remain retrievable pastTTL_SECSuntil some otherregister()/listcall happens to trigger a prune. Low impact (id holders are implicitly trusted local callers), but worth aligning for consistency with the stated TTL design intent.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/optimize/retrieve.rs` around lines 261 - 278, Update retrieve() to enforce TTL on read, matching active_state() by loading the state through the existing TTL-aware path or rechecking expiration before resolving the entry. Ensure expired IDs are treated as unavailable while preserving current retrieval behavior for active entries and existing error handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@AGENTS.md`:
- Around line 21-22: Update the legacy command documentation in AGENTS.md to
include the visible agentflare opt shorthand and identify agentflare flare as a
hidden legacy alias, while retaining caveman and ponytail as backward-compatible
aliases.
In `@crates/flare-code/src/skill-debt.md`:
- Line 20: Update the documented grep scan command in skill-debt.md to exclude
node_modules, .git, and build-output directories using appropriate --exclude-dir
flags, while preserving the existing flare-code pattern and recursive scan
behavior.
In `@crates/flare-code/src/skill-no-hallucination.md`:
- Around line 1-35: Complete the legacy-name migration across all embedded skill
cards: in crates/flare-code/src/skill-no-hallucination.md (lines 1-35), rename
metadata, headings, triggers, and revert text from ponytail to flare-code; apply
the same identity, comparison, trigger, invocation, and revert updates in
crates/flare-code/src/skill-playbook.md (lines 1-41) and
crates/flare-code/src/skill-review.md (lines 1-91); in
crates/flare-code/src/skill.md (lines 137-138), replace the stale Caveman
companion reference with flare-output terminology.
In `@crates/flare-code/src/skill.md`:
- Around line 29-30: Update the command reference in the skill documentation
from `/flare code` to the documented hyphenated `/flare-code` form, while
preserving the existing mode options and default behavior.
In `@crates/flare-output/src/sensitive.rs`:
- Around line 26-35: Update the sensitive-name matching logic using
SENSITIVE_NAME_TOKENS so tokens are recognized only at word boundaries rather
than through raw substring containment. Preserve matches for genuinely sensitive
names while allowing filenames such as secretary.md, tokenizer.py,
tokenomics.md, and detokenize.md to pass the compress() gate in the surrounding
sensitive-check flow.
In `@crates/flare-output/src/validate.rs`:
- Around line 17-22: Update extract_headings to remove fenced code blocks before
applying HEADING_REGEX, matching the preprocessing used by extract_inline_codes.
Preserve the existing heading capture and trimming behavior while ensuring
`#-prefixed` lines inside fenced blocks are not returned as headings.
In `@opencode.json`:
- Around line 9-10: Remove the obsolete rust-analyzer.inlayHints.enable setting
from the configuration, leaving rust-analyzer diagnostics and any per-hint-group
controls unchanged.
In `@src/cli/optimize.rs`:
- Around line 77-78: Use saturating subtraction when calculating the compression
percentage so values above 100 do not panic. Update the percentage calculation
associated with report.compressed_bytes in src/cli/optimize.rs lines 77-78 and
the corresponding calculation in src/cli/caveman.rs lines 60-61, using
100usize.saturating_sub(...) or a shared helper to keep both paths aligned.
In `@src/mcp_server.rs`:
- Around line 2195-2202: Update the "list" handler to serialize a summary
representation of each CompressionEntry rather than the full entries, excluding
the kind field and its backup_path/blob_path data. Preserve the existing state
retrieval and created_ts descending sort, and use the summary only for the final
serde_json::to_string response.
- Around line 2186-2194: Update optimize’s retrieve branch to map
RetrieveError::NotFound from retrieve::retrieve to ErrorData::invalid_params
while preserving internal_error for other failures. In the optimize list branch,
stop serializing CompressionEntry directly and construct a response
representation that omits or redacts backup_path and blob_path before returning
data over MCP.
In `@src/optimize/runtime.rs`:
- Around line 70-87: Update has_word_boundary_match to validate both sides of
each keyword match: retain the existing preceding-character check and require
the character immediately after the keyword to be non-alphabetic or the end of
text. Preserve the current scanning behavior and ensure keywords with trailing
spaces continue to work correctly.
---
Outside diff comments:
In `@crates/flare-code/src/platform.rs`:
- Around line 68-74: Update the expected systemMessage assertion in
codex_session_start_includes_system_message to match the current "FLARE
CODE:FULL" output produced by format_hook_output, while preserving the existing
additionalContext and hookSpecificOutput assertions.
In `@src/cli/caveman.rs`:
- Around line 58-66: Update the successful compression branch in
CavemanArgs::run to invoke the existing record_and_marker helper, matching
OutputAction::run in optimize.rs. Expose record_and_marker as pub(crate) if
necessary, and pass the legacy compression result’s original/output context so
the CCR entry and expand marker are registered before or alongside the existing
summary output.
---
Nitpick comments:
In `@crates/flare-output/src/llm.rs`:
- Line 29: Update the fallback model handling in the model initialization to
avoid an undocumented stale hardcoded default: prominently document the
CAVEMAN_MODEL override near this configuration, and select the currently
supported default model according to the project’s model policy. Preserve the
environment-variable override behavior.
In `@src/optimize/retrieve.rs`:
- Around line 261-278: Update retrieve() to enforce TTL on read, matching
active_state() by loading the state through the existing TTL-aware path or
rechecking expiration before resolving the entry. Ensure expired IDs are treated
as unavailable while preserving current retrieval behavior for active entries
and existing error handling.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 7bc8fb9f-7792-4e68-ab93-ba48aa745eb0
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (45)
AGENTS.mdCargo.tomlcrates/flare-code/CHANGELOG.mdcrates/flare-code/Cargo.tomlcrates/flare-code/src/config.rscrates/flare-code/src/detect.rscrates/flare-code/src/instructions.rscrates/flare-code/src/lib.rscrates/flare-code/src/platform.rscrates/flare-code/src/skill-audit.mdcrates/flare-code/src/skill-debt.mdcrates/flare-code/src/skill-gain.mdcrates/flare-code/src/skill-help.mdcrates/flare-code/src/skill-no-hallucination.mdcrates/flare-code/src/skill-playbook.mdcrates/flare-code/src/skill-review.mdcrates/flare-code/src/skill.mdcrates/flare-code/src/state.rscrates/flare-code/src/sub_skills.rscrates/flare-code/src/switcher.rscrates/flare-output/CHANGELOG.mdcrates/flare-output/Cargo.tomlcrates/flare-output/src/compress.rscrates/flare-output/src/error.rscrates/flare-output/src/frontmatter.rscrates/flare-output/src/lib.rscrates/flare-output/src/llm.rscrates/flare-output/src/prompt.rscrates/flare-output/src/sensitive.rscrates/flare-output/src/validate.rscrates/ponytail/src/skill-help.mdopencode.jsonsrc/cli/caveman.rssrc/cli/mod.rssrc/cli/optimize.rssrc/cli/ponytail.rssrc/compact.rssrc/mcp_prompts.rssrc/mcp_server.rssrc/optimize/code.rssrc/optimize/context.rssrc/optimize/mod.rssrc/optimize/output.rssrc/optimize/retrieve.rssrc/optimize/runtime.rs
💤 Files with no reviewable changes (1)
- crates/ponytail/src/skill-help.md
🛑 Comments failed to post (11)
AGENTS.md (1)
21-22: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Document the visible
optalias.The CLI migration retains
agentflare optas the visible shorthand, but these lines list onlyflare,caveman, andponytail. Addagentflare opt, and distinguishflareas the hidden legacy alias so the documented command surface matches the PR objective.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@AGENTS.md` around lines 21 - 22, Update the legacy command documentation in AGENTS.md to include the visible agentflare opt shorthand and identify agentflare flare as a hidden legacy alias, while retaining caveman and ponytail as backward-compatible aliases.crates/flare-code/src/skill-debt.md (1)
20-20: 🚀 Performance & Scalability | 🟡 Minor | ⚡ Quick win
Make the documented scan actually skip excluded directories.
The preceding instruction promises to skip
node_modules,.git, and build output, but this command has no--exclude-dirflags. It will recurse into those trees, causing noisy results and unnecessary scanning.Proposed fix
-`grep -rnE '(#|//) ?flare-code:' .` +`grep -rnE --exclude-dir=node_modules --exclude-dir=.git --exclude-dir=build --exclude-dir=target '(#|//) ?flare-code:' .`📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.`grep -rnE --exclude-dir=node_modules --exclude-dir=.git --exclude-dir=build --exclude-dir=target '(#|//) ?flare-code:' .` (add other comment prefixes if your stack uses them)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/flare-code/src/skill-debt.md` at line 20, Update the documented grep scan command in skill-debt.md to exclude node_modules, .git, and build-output directories using appropriate --exclude-dir flags, while preserving the existing flare-code pattern and recursive scan behavior.crates/flare-code/src/skill-no-hallucination.md (1)
1-35: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Complete the legacy-name migration in the embedded skill cards.
These cards still expose
ponytail-*identities and triggers, whileskill-help.mddocumentsflare-code-*. Becausesub_skills.rsembeds these files verbatim, users can receive stale invocation and revert instructions at runtime.
crates/flare-code/src/skill-no-hallucination.md#L1-L35: rename metadata, headings, triggers, and revert text toflare-code.crates/flare-code/src/skill-playbook.md#L1-L41: replace ponytail identity, comparisons, triggers, and revert instructions with flare-code terminology.crates/flare-code/src/skill-review.md#L1-L91: rename the review skill and all invocation/revert references consistently.crates/flare-code/src/skill.md#L137-L138: replace the staleCavemancompanion reference with the renamedflare-outputterminology.📍 Affects 4 files
crates/flare-code/src/skill-no-hallucination.md#L1-L35(this comment)crates/flare-code/src/skill-playbook.md#L1-L41crates/flare-code/src/skill-review.md#L1-L91crates/flare-code/src/skill.md#L137-L138🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/flare-code/src/skill-no-hallucination.md` around lines 1 - 35, Complete the legacy-name migration across all embedded skill cards: in crates/flare-code/src/skill-no-hallucination.md (lines 1-35), rename metadata, headings, triggers, and revert text from ponytail to flare-code; apply the same identity, comparison, trigger, invocation, and revert updates in crates/flare-code/src/skill-playbook.md (lines 1-41) and crates/flare-code/src/skill-review.md (lines 1-91); in crates/flare-code/src/skill.md (lines 137-138), replace the stale Caveman companion reference with flare-output terminology.Source: Learnings
crates/flare-code/src/skill.md (1)
29-30: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Use the documented hyphenated command form.
Line 30 says
/flare code, while the canonical command documented inskill-help.mdis/flare-code; users copying this form may fail to switch modes.Proposed fix
- Switch: `/flare code lite|full|ultra`. + Switch: `/flare-code lite|full|ultra`.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.unsure. Off only: "stop flare code" / "normal mode". Default: **full**. Switch: `/flare-code lite|full|ultra`.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/flare-code/src/skill.md` around lines 29 - 30, Update the command reference in the skill documentation from `/flare code` to the documented hyphenated `/flare-code` form, while preserving the existing mode options and default behavior.crates/flare-output/src/sensitive.rs (1)
26-35: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Substring token matching causes false-positive "sensitive" blocks.
SENSITIVE_NAME_TOKENS.iter().any(|tok| normalized.contains(tok))does raw substring containment, so common non-sensitive filenames get incorrectly refused:secretary.md(containssecret),tokenizer.py/tokenomics.md/detokenize.md(containtoken). Since this directly gatescompress()incrates/flare-output/src/compress.rs(line 44-46), it blocks legitimate compressions on such docs.🛡️ Proposed fix: match tokens at word boundaries instead of raw substrings
- let normalized: String = name - .to_lowercase() - .chars() - .filter(|c| !"_- .".contains(*c)) - .collect(); - SENSITIVE_NAME_TOKENS - .iter() - .any(|tok| normalized.contains(tok)) + // Split on separators instead of stripping them, so tokens must match a + // whole "word" in the name rather than an arbitrary substring (avoids + // "secretary" matching "secret", "tokenizer" matching "token", etc.). + let lower = name.to_lowercase(); + lower + .split(|c: char| "_- .".contains(c)) + .any(|word| SENSITIVE_NAME_TOKENS.contains(&word))Also applies to: 52-60
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/flare-output/src/sensitive.rs` around lines 26 - 35, Update the sensitive-name matching logic using SENSITIVE_NAME_TOKENS so tokens are recognized only at word boundaries rather than through raw substring containment. Preserve matches for genuinely sensitive names while allowing filenames such as secretary.md, tokenizer.py, tokenomics.md, and detokenize.md to pass the compress() gate in the surrounding sensitive-check flow.crates/flare-output/src/validate.rs (1)
17-22: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
extract_headingsdoesn't exclude fenced code blocks, unlikeextract_inline_codes.A
#-prefixed line inside a fenced code block (a shell/Python/YAML comment) is picked up byHEADING_REGEXas a markdown heading, sinceextract_headingsruns on the raw text.extract_inline_codes(lines 72-83) already strips fenced blocks first for exactly this reason — headings should do the same for consistency and to avoid confusing "Headings not preserved" error text when code containing#comments is involved.♻️ Proposed fix: strip fenced blocks before extracting headings
fn extract_headings(text: &str) -> Vec<(String, String)> { - HEADING_REGEX - .captures_iter(text) + let mut without_fences = text.to_string(); + for block in extract_code_blocks(text) { + without_fences = without_fences.replacen(&block, "", 1); + } + HEADING_REGEX + .captures_iter(&without_fences) .map(|c| (c[1].to_string(), c[2].trim().to_string())) .collect() }Also applies to: 72-83
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/flare-output/src/validate.rs` around lines 17 - 22, Update extract_headings to remove fenced code blocks before applying HEADING_REGEX, matching the preprocessing used by extract_inline_codes. Preserve the existing heading capture and trimming behavior while ensuring `#-prefixed` lines inside fenced blocks are not returned as headings.opencode.json (1)
9-10: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -eu python -m json.tool opencode.json >/dev/null if rg -n '"rust-analyzer\.inlayHints\.enable"' opencode.json; then echo "obsolete rust-analyzer setting remains" >&2 exit 1 fiRepository: getappz/agentflare
Length of output: 246
Remove the obsolete
rust-analyzer.inlayHints.enablesetting. rust-analyzer now uses per-hint-group controls, so this key is ignored and the intended inlay-hints policy won't apply.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@opencode.json` around lines 9 - 10, Remove the obsolete rust-analyzer.inlayHints.enable setting from the configuration, leaving rust-analyzer diagnostics and any per-hint-group controls unchanged.src/cli/optimize.rs (1)
77-78: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail printf '\n== target lines ==\n' sed -n '1,140p' src/cli/optimize.rs printf '\n== caveman ==\n' sed -n '1,140p' src/cli/caveman.rs printf '\n== find compress impl and report struct ==\n' rg -n "struct Report|fn compress|compressed_bytes|original_bytes|saturating_sub|100 - \(100 \* report\.compressed_bytes" -S .Repository: getappz/agentflare
Length of output: 9893
🏁 Script executed:
#!/bin/bash set -euo pipefail sed -n '1,260p' crates/flare-output/src/compress.rs printf '\n== tests around report bytes ==\n' sed -n '260,360p' crates/flare-output/src/compress.rsRepository: getappz/agentflare
Length of output: 13185
🏁 Script executed:
python3 - <<'PY' def pct(o, c): return 100 - (100 * c // max(o, 1)) cases = [ (100, 100), (100, 101), (1000, 1000), (1000, 1001), (1000, 1010), (99, 100), (10, 11), ] for o, c in cases: q = 100 * c // max(o, 1) print(f"original={o:4} compressed={c:4} term={q:3} pct={pct(o,c)}") PYRepository: getappz/agentflare
Length of output: 476
Use saturating subtraction for the compression percentage
src/cli/optimize.rs:77andsrc/cli/caveman.rs:60can panic when the final file size pushes the integer percentage above 100; switch to100usize.saturating_sub(...)or a shared helper so both paths stay aligned.📍 Affects 2 files
src/cli/optimize.rs#L77-L78(this comment)src/cli/caveman.rs#L60-L61🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/cli/optimize.rs` around lines 77 - 78, Use saturating subtraction when calculating the compression percentage so values above 100 do not panic. Update the percentage calculation associated with report.compressed_bytes in src/cli/optimize.rs lines 77-78 and the corresponding calculation in src/cli/caveman.rs lines 60-61, using 100usize.saturating_sub(...) or a shared helper to keep both paths aligned.src/mcp_server.rs (2)
2186-2194: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash ast-grep run --pattern 'enum RetrieveError { $$$ }' --lang rust src/optimize/retrieve.rs rg -n "enum RetrieveError" -A 8 src/optimize/retrieve.rsRepository: getappz/agentflare
Length of output: 409
🏁 Script executed:
#!/bin/bash set -euo pipefail # Show the optimize handler and surrounding code in src/mcp_server.rs nl -ba src/mcp_server.rs | sed -n '2160,2235p' printf '\n--- CompressionEntry / EntryKind definitions ---\n' rg -n "struct CompressionEntry|enum EntryKind|backup_path|blob_path" -A 8 -B 4 src/mcp_server.rs src/optimize -g '*.rs'Repository: getappz/agentflare
Length of output: 196
🏁 Script executed:
#!/bin/bash set -euo pipefail nl -ba src/mcp_server.rs | sed -n '2178,2225p' printf '\n--- nearby optimize-related type definitions ---\n' rg -n "struct CompressionEntry|enum EntryKind|backup_path|blob_path|Serialize" -A 10 -B 4 src/mcp_server.rs src -g '*.rs'Repository: getappz/agentflare
Length of output: 196
🏁 Script executed:
#!/bin/bash set -euo pipefail printf '%s\n' '--- retrieve implementation ---' rg -n "pub fn retrieve|fn retrieve" -A 40 -B 6 src/optimize/retrieve.rs printf '\n%s\n' '--- CompressionEntry / EntryKind definitions and serialization derives ---' rg -n "struct CompressionEntry|enum EntryKind|derive\\(" -A 12 -B 4 src/mcp_server.rs src/optimize -g '*.rs'Repository: getappz/agentflare
Length of output: 27994
🏁 Script executed:
#!/bin/bash set -euo pipefail printf '%s\n' '--- optimize() handler in src/mcp_server.rs ---' sed -n '2180,2215p' src/mcp_server.rs printf '\n%s\n' '--- optimize-related response types / serde derives ---' rg -n "CompressionEntry|EntryKind|retrieve::retrieve|to_string_pretty|serde_json::to_value|list" -A 8 -B 4 src/mcp_server.rs src/optimize -g '*.rs'Repository: getappz/agentflare
Length of output: 50375
Map missing compression ids to
invalid_params, and redact paths fromoptimize(list)
retrievealready returnsRetrieveError::NotFound(_)for unknown ids, so surface that asinvalid_paramsinstead ofinternal_error.listserializesCompressionEntrydirectly, which includesEntryKind::FileBackup { backup_path }andEntryKind::Inline { blob_path }; that leaks local paths over the MCP boundary.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mcp_server.rs` around lines 2186 - 2194, Update optimize’s retrieve branch to map RetrieveError::NotFound from retrieve::retrieve to ErrorData::invalid_params while preserving internal_error for other failures. In the optimize list branch, stop serializing CompressionEntry directly and construct a response representation that omits or redacts backup_path and blob_path before returning data over MCP.
2195-2202: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash rg -n "struct CompressionEntry" -A 12 src/optimize/retrieve.rs rg -n "enum EntryKind" -A 8 src/optimize/retrieve.rsRepository: getappz/agentflare
Length of output: 756
🏁 Script executed:
#!/bin/bash set -euo pipefail # Map the relevant types and their constructors/usages. ast-grep outline src/optimize/retrieve.rs --view expanded echo '--- usages of EntryKind variants ---' rg -n "EntryKind::(FileBackup|Inline|LeanCtxRead)|backup_path|blob_path|CompressionEntry \{" src/optimize -A 3 -B 3 echo '--- check serialization derive on the types ---' sed -n '1,80p' src/optimize/retrieve.rsRepository: getappz/agentflare
Length of output: 17091
Redact
kindfromlistoutputCompressionEntryserializesEntryKind::{FileBackup, Inline}verbatim, so this endpoint leaksbackup_path/blob_pathto MCP clients. Return a summary here instead of the full entry.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mcp_server.rs` around lines 2195 - 2202, Update the "list" handler to serialize a summary representation of each CompressionEntry rather than the full entries, excluding the kind field and its backup_path/blob_path data. Preserve the existing state retrieval and created_ts descending sort, and use the summary only for the final serde_json::to_string response.src/optimize/runtime.rs (1)
70-87: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Word-boundary check is one-sided — only the preceding character is checked, not the following one.
Keywords without a built-in trailing separator ("where is", "where's", "search for") can false-positive when immediately followed by more letters, e.g.
"search formation"contains the literal substring"search for"preceded by a space, so this currently reports a match even though the real word is "formation"."find "/"locate "are accidentally safe only because they embed a trailing space.🐛 Proposed fix: add a symmetric trailing-boundary check
fn has_word_boundary_match(text: &str, keyword: &str) -> bool { let bytes = text.as_bytes(); let mut start = 0; while let Some(pos) = text[start..].find(keyword) { let abs_pos = start + pos; + let end_pos = abs_pos + keyword.len(); let preceded_ok = abs_pos == 0 || !bytes[abs_pos - 1].is_ascii_alphabetic(); - if preceded_ok { + let followed_ok = end_pos >= bytes.len() || !bytes[end_pos].is_ascii_alphabetic(); + if preceded_ok && followed_ok { return true; } start = abs_pos + keyword.len().max(1); if start > text.len() { break; } } false }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.const LOCATE_KEYWORDS: &[&str] = &["find ", "where is", "where's", "search for", "locate "]; fn has_word_boundary_match(text: &str, keyword: &str) -> bool { let bytes = text.as_bytes(); let mut start = 0; while let Some(pos) = text[start..].find(keyword) { let abs_pos = start + pos; let end_pos = abs_pos + keyword.len(); let preceded_ok = abs_pos == 0 || !bytes[abs_pos - 1].is_ascii_alphabetic(); let followed_ok = end_pos >= bytes.len() || !bytes[end_pos].is_ascii_alphabetic(); if preceded_ok && followed_ok { return true; } start = abs_pos + keyword.len().max(1); if start > text.len() { break; } } false }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/optimize/runtime.rs` around lines 70 - 87, Update has_word_boundary_match to validate both sides of each keyword match: retain the existing preceding-character check and require the character immediately after the keyword to be non-alphabetic or the end of text. Preserve the current scanning behavior and ensure keywords with trailing spaces continue to work correctly.
…test CI runs clippy -D warnings and cargo test --workspace, which the consolidation tripped: - cli/optimize.rs: drop needless &transcript borrow (needless_borrows_for_generic_args) - cli/optimize.rs: sessions.values() instead of iter().map(|(_, r)|) (iter_kv_map) - flare-code/platform.rs: test still expected the pre-rebrand PONYTAIL:FULL codex system message; production now emits FLARE CODE:FULL
…legacy CCR) - cli: use 100usize.saturating_sub for compression %, avoiding an unsigned underflow panic when the compressed file ends up larger than the original (optimize output + legacy caveman paths) - mcp optimize list: return a summary (id/kind-label/sizes/ts) instead of the full CompressionEntry, so backup_path/blob_path are no longer leaked to clients (new retrieve::kind_label helper) - legacy caveman compress: register the CCR original + print the expand marker, matching optimize output compress (record_and_marker made pub(crate)) Rebrand of embedded skill cards + CAVEMAN_MODEL env var deferred to a follow-up (live invocation-name compat) — tracked separately.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/mcp_server.rs (2)
2188-2193: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winReturn invalid parameters for unknown or blank retrieval IDs.
Line 2189 only checks presence, and Line 2192 maps
RetrieveError::NotFoundtointernal_error. A stale, empty, or mistyped ID is caller input and should not be reported as a server failure.Proposed fix
- let id = req.id.ok_or_else(|| { - ErrorData::invalid_params("id is required for retrieve", None) - })?; - crate::optimize::retrieve::retrieve(&id) - .map_err(|e| ErrorData::internal_error(e.to_string(), None)) + let id = req + .id + .filter(|id| !id.trim().is_empty()) + .ok_or_else(|| { + ErrorData::invalid_params("id is required for retrieve", None) + })?; + match crate::optimize::retrieve::retrieve(&id) { + Ok(content) => Ok(content), + Err(crate::optimize::retrieve::RetrieveError::NotFound(_)) => { + Err(ErrorData::invalid_params("unknown retrieve id", None)) + } + Err(e) => Err(ErrorData::internal_error(e.to_string(), None)), + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mcp_server.rs` around lines 2188 - 2193, Update the "retrieve" request handling to reject blank or unknown IDs as invalid parameters: validate the supplied id after the existing presence check, and map retrieve failures indicating a missing record to ErrorData::invalid_params instead of internal_error. Preserve internal_error mapping for genuine server-side retrieval failures.
2192-2193: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winApply the TTL check to retrieval too.
retrieve()reads the raw registry, so an expired CCR entry can still be fetched by ID after it disappears fromlist. Route retrieval through the pruned active state or reject expired entries before loading the content.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mcp_server.rs` around lines 2192 - 2193, Update the retrieval handler around crate::optimize::retrieve::retrieve to enforce CCR TTL expiration before loading content. Route the lookup through the same pruned active registry state used by listing, or validate the entry’s expiration and reject it when expired, while preserving the existing internal-error mapping for valid retrieval failures.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@src/mcp_server.rs`:
- Around line 2188-2193: Update the "retrieve" request handling to reject blank
or unknown IDs as invalid parameters: validate the supplied id after the
existing presence check, and map retrieve failures indicating a missing record
to ErrorData::invalid_params instead of internal_error. Preserve internal_error
mapping for genuine server-side retrieval failures.
- Around line 2192-2193: Update the retrieval handler around
crate::optimize::retrieve::retrieve to enforce CCR TTL expiration before loading
content. Route the lookup through the same pruned active registry state used by
listing, or validate the entry’s expiration and reject it when expired, while
preserving the existing internal-error mapping for valid retrieval failures.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 4521df86-6264-4fd3-b85c-fb85f7373069
📒 Files selected for processing (4)
src/cli/caveman.rssrc/cli/optimize.rssrc/mcp_server.rssrc/optimize/retrieve.rs
🚧 Files skipped from review as they are similar to previous changes (3)
- src/cli/caveman.rs
- src/optimize/retrieve.rs
- src/cli/optimize.rs
Consolidates the scattered agent-optimization features (caveman / ponytail / compact) into a single
optimizemodule, and makes output-layer compression reversible via aretrievetool (CCR pattern). Tracker items: flare #93 (parent, consolidation) and #94 (retrieve/CCR).Decoupled from the site landing-page work (PR #203) — this branch was rebased
--onto masterso it carries only the consolidation commits, nosite/changes.What's in it
Consolidation (#93)
src/flare/→src/optimize/(module + CLIagentflare optimize {output,code,context,…},optvisible alias,flarehidden alias); addsmcp__flare__optimize.caveman→flare-output,ponytail→flare-code.contextlayer merged fromcompact.rs(in-memory FTS5/BM25 transcript scorer).AGENTS.mdmigrated to theoptimizecommand surface (legacyflare/caveman/ponytaildocumented as backward-compatible aliases).Reversible compression / retrieve (#94, CCR)
optimize/retrieve.rs: registers each compression's original under a short id; file-backed originals are snapshotted into an owned blob store so they survive source mutation/deletion. Atomic (temp + rename) index writes under a best-effort advisory lock; TTL + max-entry pruning that also deletes owned blobs.flare-outputcompress()now reportsoriginal_path; the output CLI registers it and prints an expand-marker.optimize action=retrieve|list(list is TTL-pruned + sorted newest-first).agentflare optimize retrieve <id>/--list.Verification (local)
cargo fmt --all --check— cleancargo clippy --all-targets— clean (2 pre-existing style warnings only)cargo test— 491 passed, 0 failedNot included (tracked separately)
input/memoryoptimize layers → flare ci: temporarily disable release-plz crates.io publish #101 / feat: expose ponytail as MCP prompts, add missing CLI subcommands #102compact.rs, wirecontext/sessionsas lean-ctx delegations → flare feat(ponytail): SubagentStart agent_type regex matcher #91ponytail/flare→optimizesettings migration → flare feat: skill registry MCP — skill_search + skill_load #92Summary by CodeRabbit
optimizecommand for Flare Code minimalism, output compression, context transcript scoring, runtime/session assistance, status, and retrieval-by-id.