feat(cortex): add self-awareness docs and config diagnostics#311
feat(cortex): add self-awareness docs and config diagnostics#311
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds a self-awareness module embedding docs and changelog, two runtime tools (spacebot_docs, config_inspect), augments cortex prompt context with manifest and runtime snapshots, updates tool-server wiring to accept RuntimeConfig, and enhances release tooling and CHANGELOG management plus a release-skill doc. (49 words) Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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 |
Co-authored-by: tembo[bot] <208362400+tembo[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
src/tools/config_inspect.rs (1)
96-118: Consider consistent handling for missing vs unknown sections.Lines 101-112 return
Value::Nullforbinary_version,deployment, andmcpwhen the key doesn't exist, but lines 113-116 return an error for unknown sections. This creates an inconsistency: if someone requests"binary_version"and it's missing, they getnull, but if they request an invalid key like"foo", they get an error.If the intent is that
binary_version/deployment/mcpare always present in the snapshot, theunwrap_or(Null)is defensive and fine. However, if a user typos"binary_versoin", they'll get a helpful error, whereas a typo on a valid key that happens to be absent silently returns null.This is minor since the keys being special-cased should always exist in
runtime_snapshot_value.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/tools/config_inspect.rs` around lines 96 - 118, select_section currently returns serde_json::Value::Null for missing special-case keys ("binary_version", "deployment", "mcp") but returns an error for other missing keys; make the behavior consistent by returning an error when any requested key is missing. In select_section, replace the .get(...).cloned().unwrap_or(Null) branches for "binary_version", "deployment", and "mcp" with the same pattern used in the default arm (i.e., .get(...).cloned().ok_or_else(|| unknown_section_error(section_or_key))), so missing special keys produce the unknown_section_error; keep unknown_section_error as the canonical error helper.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.agents/skills/release-bump-changelog/SKILL.md:
- Around line 32-35: Rename the duplicate "3." list item to "4." in the SKILL.md
step labeled "Verify results" so the sequence flows correctly; locate the block
containing the commands (`git show --name-only --stat`, `git tag --list "v*"
--sort=-v:refname | head -n 5`) and update the leading number for that bullet
from 3. to 4. to fix the numbering inconsistency.
In `@CHANGELOG.md`:
- Around line 350-358: Remove the duplicated "What's Changed" and "New
Contributors" blocks for v0.1.5 (the repeated sections under "## What's Changed"
and "## New Contributors" that appear twice) so only one set of those entries
for v0.1.5 remains; locate the duplicate block that repeats the v0.1.5 entries
(the lines duplicating the bullet points for fixes and first-time contributors
and the "Full Changelog" link) and delete the redundant copy, leaving the
original v0.1.5 section intact.
In `@scripts/release-tag.sh`:
- Around line 226-231: The working-tree disallowed-changes check currently
exempts CARGO_TOML_RELATIVE, CARGO_LOCK_RELATIVE and
marketing_copy_allowed_relative but omits the changelog; update the conditional
that populates disallowed_changes (the if that compares "$file" to
"$CARGO_TOML_RELATIVE", "$CARGO_LOCK_RELATIVE", and
"$marketing_copy_allowed_relative") to also skip when "$file" equals
"$CHANGELOG_RELATIVE" so uncommitted CHANGELOG.md changes are treated as
allowed; ensure you reference the same variable names (file,
CARGO_TOML_RELATIVE, CARGO_LOCK_RELATIVE, marketing_copy_allowed_relative,
CHANGELOG_RELATIVE) and append no-op behavior to disallowed_changes when
matched.
---
Nitpick comments:
In `@src/tools/config_inspect.rs`:
- Around line 96-118: select_section currently returns serde_json::Value::Null
for missing special-case keys ("binary_version", "deployment", "mcp") but
returns an error for other missing keys; make the behavior consistent by
returning an error when any requested key is missing. In select_section, replace
the .get(...).cloned().unwrap_or(Null) branches for "binary_version",
"deployment", and "mcp" with the same pattern used in the default arm (i.e.,
.get(...).cloned().ok_or_else(|| unknown_section_error(section_or_key))), so
missing special keys produce the unknown_section_error; keep
unknown_section_error as the canonical error helper.
ℹ️ Review info
Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: fcc69ba1-b151-4e4f-9b9c-6d839129347d
📒 Files selected for processing (21)
.agents/skills/release-bump-changelog/SKILL.mdAGENTS.mdCHANGELOG.mddocs/content/docs/(core)/cortex.mdxdocs/content/docs/(deployment)/roadmap.mdxdocs/content/docs/(features)/tools.mdxprompts/en/branch.md.j2prompts/en/cortex_chat.md.j2prompts/en/tools/config_inspect_description.md.j2prompts/en/tools/spacebot_docs_description.md.j2scripts/release-tag.shsrc/agent/cortex_chat.rssrc/api/agents.rssrc/lib.rssrc/main.rssrc/prompts/engine.rssrc/prompts/text.rssrc/self_awareness.rssrc/tools.rssrc/tools/config_inspect.rssrc/tools/spacebot_docs.rs
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/self_awareness.rs (1)
84-101:⚠️ Potential issue | 🟠 MajorRedact MCP transport fields in runtime snapshots to prevent secret exposure.
Line 90 currently emits raw
args, and Line 99 emits rawurl; both can contain credentials/tokens and may leak through diagnostics and prompts.💡 Proposed fix
McpTransport::Stdio { command, args, env } => { let mut env_keys = env.keys().cloned().collect::<Vec<_>>(); env_keys.sort(); json!({ "kind": "stdio", "command": command, - "args": args, + "args_count": args.len(), "env_keys": env_keys, }) } McpTransport::Http { url, headers } => { let mut header_keys = headers.keys().cloned().collect::<Vec<_>>(); header_keys.sort(); json!({ "kind": "http", - "url": url, + "url_redacted": true, "header_keys": header_keys, }) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/self_awareness.rs` around lines 84 - 101, The snapshot currently emits raw transport fields that may contain secrets: in McpTransport::Stdio do not include the raw args vector (variable args) in the json, and in McpTransport::Http do not include the raw url (variable url); instead replace them with a redacted placeholder (e.g. "<redacted>") or a safe summary (e.g. args_count and url_present boolean) while still preserving command, env_keys and header_keys for diagnostics; update the McpTransport::Stdio and McpTransport::Http match arms to output the redacted/summarized fields rather than the raw args and url.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/self_awareness.rs`:
- Around line 46-56: Remove the duplicated function declaration and stray brace:
keep a single pub fn changelog_highlights() -> String implementation that calls
latest_release_notes(CHANGELOG_DOC, 3).unwrap_or_else(...) and delete the extra
duplicated signature and the extra closing brace so the function block is
properly formed; ensure the final function contains the fallback using
CHANGELOG_DOC.lines().take(200).collect::<Vec<_>>().join("\n") and compiles
cleanly.
---
Duplicate comments:
In `@src/self_awareness.rs`:
- Around line 84-101: The snapshot currently emits raw transport fields that may
contain secrets: in McpTransport::Stdio do not include the raw args vector
(variable args) in the json, and in McpTransport::Http do not include the raw
url (variable url); instead replace them with a redacted placeholder (e.g.
"<redacted>") or a safe summary (e.g. args_count and url_present boolean) while
still preserving command, env_keys and header_keys for diagnostics; update the
McpTransport::Stdio and McpTransport::Http match arms to output the
redacted/summarized fields rather than the raw args and url.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
CHANGELOG.md (1)
61-63: Make the v0.2.0 narrative a subheading, not a release heading.Line 61 currently looks version-heading-like at
##level. Using a subheading (###) keeps release boundaries unambiguous for humans and release tooling.✏️ Suggested change
-## v0.2.0 is the _biggest_ Spacebot release yet. +### Release Story + +v0.2.0 is the _biggest_ Spacebot release yet.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@CHANGELOG.md` around lines 61 - 63, The release line "## v0.2.0 is the _biggest_ Spacebot release yet." should be demoted from an H2 to an H3 to make it a subheading; update the Markdown heading marker from "##" to "###" for that exact line so the v0.2.0 narrative becomes a subheading and keeps release boundary headings unambiguous.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/tools/spacebot_docs.rs`:
- Around line 171-194: The handler currently computes start_line from
args.start_line and calls slice_lines(...) then builds a success
SpacebotDocsOutput which can report inverted or out-of-range ranges if
args.start_line is past EOF; update the logic around args.start_line,
args.max_lines and the return path in the code that constructs
SpacebotDocsOutput/SpacebotDocContent so that you first call
slice_lines(&document.content, start_line, max_lines) to get total_lines, then
if start_line > total_lines either return a structured error result (success:
false with a clear message) or normalize values (set start_line = total_lines,
end_line = total_lines, has_more = false, content = empty) before creating
SpacebotDocsOutput; reference slice_lines, SpacebotDocsOutput,
SpacebotDocContent, args.start_line and args.max_lines when making the change.
---
Nitpick comments:
In `@CHANGELOG.md`:
- Around line 61-63: The release line "## v0.2.0 is the _biggest_ Spacebot
release yet." should be demoted from an H2 to an H3 to make it a subheading;
update the Markdown heading marker from "##" to "###" for that exact line so the
v0.2.0 narrative becomes a subheading and keeps release boundary headings
unambiguous.
ℹ️ Review info
Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 98b79fbf-99a7-44fc-8ac1-1410d208723c
📒 Files selected for processing (7)
.agents/skills/release-bump-changelog/SKILL.mdCHANGELOG.mdscripts/release-tag.shsrc/agent/cortex_chat.rssrc/self_awareness.rssrc/tools/config_inspect.rssrc/tools/spacebot_docs.rs
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/tools/spacebot_docs.rs`:
- Around line 155-170: The read branch currently returns Err on user/LLM
mistakes (missing doc_id via requested_id and missing document from
crate::self_awareness::get_embedded_doc leading to unknown_doc_error) — change
these to return a structured tool response (Ok with a payload like { success:
false, error: "<message>" }) so failures are recoverable by the model rather
than bubbling as Err; do the same for the invalid-action path referenced around
the 208-210 checks (return Ok structured failure for unrecognized actions) and
ensure the caller still receives the same success:true/false schema expected by
the tool contract.
- Around line 135-150: The message uses docs.len() after truncation so when
results were trimmed to 200 it incorrectly reports "200 docs available"; before
truncating (in the function that builds SpacebotDocsOutput) capture the total
count (e.g., let total = docs.len()), then truncate docs to 200 and use total
for the availability message while optionally indicating the shown count (e.g.,
format!("{} docs available (showing {})", total, docs.len())); update the
formatted message building code that references args.query to combine the
total/shown counts and the query filter text accordingly.
ℹ️ Review info
Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 22a2d954-742e-481e-b2cd-78b93a8301d6
📒 Files selected for processing (3)
prompts/en/channel.md.j2prompts/en/tools/branch_description.md.j2src/tools/spacebot_docs.rs
| if docs.len() > 200 { | ||
| docs.truncate(200); | ||
| } | ||
|
|
||
| Ok(SpacebotDocsOutput { | ||
| success: true, | ||
| action, | ||
| message: format!( | ||
| "{} docs available{}", | ||
| docs.len(), | ||
| args.query | ||
| .as_deref() | ||
| .filter(|query| !query.trim().is_empty()) | ||
| .map(|query| format!(" (filtered by '{query}')")) | ||
| .unwrap_or_default() | ||
| ), |
There was a problem hiding this comment.
List message becomes inaccurate after truncation.
When results exceed 200, the output says “200 docs available” even if more exist. This can mislead downstream tool selection.
Suggested fix
"list" => {
- let mut docs = crate::self_awareness::list_embedded_docs(args.query.as_deref());
- if docs.len() > 200 {
+ let mut docs = crate::self_awareness::list_embedded_docs(args.query.as_deref());
+ let total_matches = docs.len();
+ if total_matches > 200 {
docs.truncate(200);
}
@@
- message: format!(
- "{} docs available{}",
- docs.len(),
+ message: format!(
+ "{} docs returned{}{}",
+ docs.len(),
+ if total_matches > docs.len() {
+ format!(" (truncated from {total_matches})")
+ } else {
+ String::new()
+ },
args.query
.as_deref()
.filter(|query| !query.trim().is_empty())
.map(|query| format!(" (filtered by '{query}')"))
.unwrap_or_default()
),🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/tools/spacebot_docs.rs` around lines 135 - 150, The message uses
docs.len() after truncation so when results were trimmed to 200 it incorrectly
reports "200 docs available"; before truncating (in the function that builds
SpacebotDocsOutput) capture the total count (e.g., let total = docs.len()), then
truncate docs to 200 and use total for the availability message while optionally
indicating the shown count (e.g., format!("{} docs available (showing {})",
total, docs.len())); update the formatted message building code that references
args.query to combine the total/shown counts and the query filter text
accordingly.
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/tools/spacebot_docs.rs (1)
135-151:⚠️ Potential issue | 🟡 MinorList response message is inaccurate when results are truncated.
After truncating to 200 (
Line 136-Line 138), the message still reportsdocs.len()as “docs available,” which hides that more matches may exist.Suggested fix
"list" => { let mut docs = crate::self_awareness::list_embedded_docs(args.query.as_deref()); - if docs.len() > 200 { + let total_matches = docs.len(); + if total_matches > 200 { docs.truncate(200); } Ok(SpacebotDocsOutput { success: true, action, message: format!( - "{} docs available{}", + "{} docs returned{}{}", docs.len(), + if total_matches > docs.len() { + format!(" (truncated from {total_matches})") + } else { + String::new() + }, args.query .as_deref() .filter(|query| !query.trim().is_empty()) .map(|query| format!(" (filtered by '{query}')")) .unwrap_or_default() ),🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/tools/spacebot_docs.rs` around lines 135 - 151, The message wrongly reports docs.len() after truncation; capture the full match count before truncating (e.g., let total = docs.len()) right after calling crate::self_awareness::list_embedded_docs, then truncate docs to 200 and build SpacebotDocsOutput.message using both values (e.g., format!("showing {} of {} docs available{}", docs.len(), total, ...)) so the output clearly indicates when results are truncated; update the code around list_embedded_docs, docs truncation, and the SpacebotDocsOutput construction to use these variables.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@src/tools/spacebot_docs.rs`:
- Around line 135-151: The message wrongly reports docs.len() after truncation;
capture the full match count before truncating (e.g., let total = docs.len())
right after calling crate::self_awareness::list_embedded_docs, then truncate
docs to 200 and build SpacebotDocsOutput.message using both values (e.g.,
format!("showing {} of {} docs available{}", docs.len(), total, ...)) so the
output clearly indicates when results are truncated; update the code around
list_embedded_docs, docs truncation, and the SpacebotDocsOutput construction to
use these variables.
ℹ️ Review info
Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: cb7f9670-4f74-4f86-a174-466c04e11c9e
📒 Files selected for processing (1)
src/tools/spacebot_docs.rs
Summary
self_awarenessmodule that embeds Spacebot self-knowledge (AGENTS.md, seededCHANGELOG.md, static repo docs, and alldocs/contentmarkdown) and injects it into cortex chat with a live redacted runtime-config snapshotspacebot_docs(branch + cortex chat) andconfig_inspect(cortex chat) tools, plus prompt/docs updates so agents use source docs and live config for diagnosticsCHANGELOG.mdthroughcargo bump:scripts/release-tag.shnow generates GitHub-native notes and requires a per-release marketing story; add.agents/skills/release-bump-changelogto standardize that flowValidation
./scripts/preflight.sh./scripts/gate-pr.shNote
AI-Generated Summary
This PR equips the cortex process with self-awareness by embedding architectural documentation and exposing live configuration state. New tools allow the cortex and branches to query system architecture (via
spacebot_docs) and inspect runtime config (viaconfig_inspect). The release workflow now generates versioned changelog entries combining marketing narrative with GitHub-native release notes, standardized through a new skill.Written by Tembo for commit 33a6a0c. This will update automatically on new commits.