fix(daemon): validate exported OKF documents structurally - #415
fix(daemon): validate exported OKF documents structurally#415KooshaPari wants to merge 11 commits into
Conversation
🤖 CodeAnt AI — Review Status
|
Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
|
Warning Review limit reached
Next review available in: 43 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughSummaryThis PR updates daemon validation to parse on-disk bundles as The PR adds inline icons to viewer tabs and exposes the OKF validation API. It also adds a pull-request CI self-check for evaluation reproducibility and updates the evaluation manifest hash. Must Fix
Should Fix
Consider
Approve / Request ChangesApprove if formatting, clippy, workspace tests, and public API requirements pass. Otherwise, request changes. WalkthroughThe change adds structural OKF validation, collision-safe bundle filenames, inline SVG viewer tab icons, pull-request reproducibility checks, a Cargo.lock hash update, and a canonical session handoff document. ChangesOKF validation
Viewer updates
Reproducibility checks
Session handoff
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant ValidateCommand as validate command
participant Filesystem
participant OkfDocument
participant Validator as validate_okf_document
ValidateCommand->>Filesystem: locate sanitized bundle path
Filesystem-->>ValidateCommand: return bundle JSON
ValidateCommand->>OkfDocument: deserialize JSON
ValidateCommand->>Validator: validate document
Validator-->>ValidateCommand: return structured errors
ValidateCommand-->>ValidateCommand: emit validation JSON and exit status
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 2⚔️ Resolve merge conflicts 💡
🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
✨ Simplify code
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 |
| /// Inline SVG icons for each tab. | ||
| const ICON_SVG_BUNDLES: &str = include_str!("../../../assets/icons/line/bundles.svg"); | ||
| const ICON_SVG_HISTORY: &str = include_str!("../../../assets/icons/line/history.svg"); | ||
| const ICON_SVG_MEMORY: &str = include_str!("../../../assets/icons/line/memory.svg"); | ||
| const ICON_SVG_UNFINISHED: &str = include_str!("../../../assets/icons/line/unfinished.svg"); | ||
| const ICON_SVG_TIMELINE: &str = include_str!("../../../assets/icons/line/timeline.svg"); | ||
| const ICON_SVG_LIVE: &str = include_str!("../../../assets/icons/line/live.svg"); | ||
| const ICON_SVG_SEARCH: &str = include_str!("../../../assets/icons/line/search.svg"); | ||
| const ICON_SVG_REPLAY: &str = include_str!("../../../assets/icons/line/replay.svg"); |
There was a problem hiding this comment.
Suggestion: The new documentation and constants were inserted between #[allow(non_snake_case)] and pub fn App(), so the allow attribute now applies to the icon constant rather than the App function. With the repository's denied Clippy lints, the intentionally PascalCase App function can trigger the non_snake_case lint; move the allow attribute directly above the function. [inconsistent naming]
Severity Level: Major ⚠️
- ❌ Strict viewer builds can fail on the `App` naming lint.
- ⚠️ Normal builds may emit an avoidable non-snake-case warning.(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** crates/sl-viewer/src/app.rs
**Line:** 207:215
**Comment:**
*Inconsistent Naming: The new documentation and constants were inserted between `#[allow(non_snake_case)]` and `pub fn App()`, so the allow attribute now applies to the icon constant rather than the `App` function. With the repository's denied Clippy lints, the intentionally PascalCase `App` function can trigger the `non_snake_case` lint; move the allow attribute directly above the function.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| <<<<<<< Updated upstream | ||
| use crate::mock_data::sample_sessions; | ||
| ======= | ||
| >>>>>>> Stashed changes |
There was a problem hiding this comment.
Suggestion: Unresolved merge-conflict markers were committed into this Rust source file. They leave the viewer crate in an unmerged state and prevent it from compiling; remove the markers and retain the intended sample_sessions import. [possible bug]
Severity Level: Critical 🚨
- ❌ Viewer crate compilation fails immediately.
- ❌ Viewer tests and desktop/web builds are blocked.(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** crates/sl-viewer/src/corpus_loader.rs
**Line:** 12:15
**Comment:**
*Possible Bug: Unresolved merge-conflict markers were committed into this Rust source file. They leave the viewer crate in an unmerged state and prevent it from compiling; remove the markers and retain the intended `sample_sessions` import.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix|
|
||
| let mut entity_ids = std::collections::HashSet::with_capacity(document.entities.len()); | ||
| for (index, entity) in document.entities.iter().enumerate() { | ||
| if !entity_ids.insert(entity.id.as_str()) { |
There was a problem hiding this comment.
Suggestion: The ID set only detects duplicates; it does not reject an empty entity ID. Consequently, a document containing one entity with id: "" passes this validation and relations can legally reference that unusable identifier. Reject empty IDs before inserting them into the uniqueness set. [incomplete implementation]
Severity Level: Major ⚠️
- ⚠️ On-disk OKF validation accepts unusable empty entity IDs.
- ⚠️ Downstream graph consumers may not distinguish an empty node identifier.(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src/ports/okf.rs
**Line:** 197:197
**Comment:**
*Incomplete Implementation: The ID set only detects duplicates; it does not reject an empty entity ID. Consequently, a document containing one entity with `id: ""` passes this validation and relations can legally reference that unusable identifier. Reject empty IDs before inserting them into the uniqueness set.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fixThere was a problem hiding this comment.
Actionable comments posted: 9
🤖 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 `@crates/sl-daemon/src/main.rs`:
- Around line 1359-1379: The existing test only covers successful validation;
add unit tests beside validate_okf_document in src/ports/okf.rs for
unsupported_version, source_id_mismatch, duplicate_entity_id,
dangling_relation_source, and dangling_relation_target. Each test must assert
the validator emits the expected error code and field, while retaining
validate_on_disk_okf_accepts_daemon_generated_document in main.rs for
ETL-to-validation integration coverage.
- Around line 1164-1171: Update the exit decision in run_validate to use
errors.is_empty() directly instead of reading result["valid"] through
serde_json::Value and unwrap_or(false). Preserve the current behavior by exiting
with cli::EXIT_NOT_OK whenever errors is non-empty, while leaving the JSON
output unchanged.
- Line 1178: Apply the same sanitization used by etl::transform_file when
constructing the read path in validate_on_disk_okf: make sanitize accessible as
pub(crate) and join the data directory with sanitize(&bundle_id) before
appending the .okf.json suffix. Preserve the existing filename format while
ensuring read/write round trips support session IDs containing path separators.
In `@crates/sl-viewer/src/app.rs`:
- Around line 217-230: Update icon_svg to map exhaustively from the Tab type
rather than accepting arbitrary string names with a Bundles fallback. Ensure
every Tab variant maps to its corresponding icon constant so newly added or
misspelled variants are caught at compile time.
- Around line 906-909: Update the icon wrapper span in the tab rendering near
tab.label() to include the tab-icon class, and define or reuse the corresponding
.tab-icon styling with a small margin-inline-end so the SVG and label are
visibly separated.
- Around line 906-909: Add aria-hidden="true" to the span wrapper containing
icon_svg(tab.icon()) in the tab rendering, while leaving tab.label() as the
button’s accessible name.
In `@crates/sl-viewer/src/corpus_loader.rs`:
- Around line 12-15: Resolve the merge conflict in corpus_loader.rs by removing
all conflict markers and retaining the use crate::mock_data::sample_sessions;
import required by load_sessions.
In `@HANDOFF-session-2026-08-05.md`:
- Around line 129-130: Update the handoff entry describing
crates/sl-viewer/src/corpus_loader.rs to state that unresolved conflict markers
remain and that the file still references the affected web_exports symbol.
Remove the claim that the markers were resolved, and identify this as a
remaining blocker for reliable workspace checks.
- Around line 1-2: Fix the Markdown spacing in HANDOFF-session-2026-08-05.md by
adding blank lines before and after every affected heading and around the table
near lines 118–125, including all listed ranges. Preserve the existing content
and table structure, and ensure the file passes markdownlint-cli2 MD022 and
MD058.
🪄 Autofix
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: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 95876ea3-1a75-40c9-9dcd-3c7ee1cd1273
📒 Files selected for processing (6)
HANDOFF-session-2026-08-05.mdcrates/sl-daemon/src/main.rscrates/sl-viewer/src/app.rscrates/sl-viewer/src/corpus_loader.rssrc/lib.rssrc/ports/okf.rs
📜 Review details
⏰ Context from checks skipped due to timeout. (3)
- GitHub Check: Summary
- GitHub Check: prepare
- GitHub Check: browser e2e · axe · responsive · visual
⚠️ CI failures not shown inline (2)
GitHub Check: Summary: The current Mergify configuration is invalid
Conclusion: failure
* Invalid condition 'author=dependabot[bot] | renovate[bot]' @ root → pull_request_rules → item 1 → conditions → item 0 → author=dependabot[bot] | renovate[bot]
```
Invalid GitHub login
```
* Invalid condition 'author=trunk-io[bot] | mergify[bot] | github-actions[bot]' @ root → pull_request_rules → item 2 → conditions → item 0 → author=trunk-io[bot] | mergify[bot] | github-actions[bot]
```
Invalid GitHub login
```
* Invalid condition 'age>=30d' @ root → pull_request_rules → item 8 → conditions → item 2 → age>=30d
```
Invalid attribute
```
* Extra inputs are not permitted @ root → pull_request_rules → item 0 → actions → post_merge
* Extra inputs are not permitted @ root → pull_request_rules → item 1 → actions → post_merge
* Extra inputs are not permitted @ root → pull_request_rules → item 3 → actions → request_reviews → github_accounts
GitHub Check: Mergify Merge Queue: The current Mergify configuration is invalid
Conclusion: failure
* Invalid condition 'author=dependabot[bot] | renovate[bot]' @ root → pull_request_rules → item 1 → conditions → item 0 → author=dependabot[bot] | renovate[bot]
```
Invalid GitHub login
```
* Invalid condition 'author=trunk-io[bot] | mergify[bot] | github-actions[bot]' @ root → pull_request_rules → item 2 → conditions → item 0 → author=trunk-io[bot] | mergify[bot] | github-actions[bot]
```
Invalid GitHub login
```
* Invalid condition 'age>=30d' @ root → pull_request_rules → item 8 → conditions → item 2 → age>=30d
```
Invalid attribute
```
* Extra inputs are not permitted @ root → pull_request_rules → item 0 → actions → post_merge
* Extra inputs are not permitted @ root → pull_request_rules → item 1 → actions → post_merge
* Extra inputs are not permitted @ root → pull_request_rules → item 3 → actions → request_reviews → github_accounts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{rs,toml}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{rs,toml}: Use the Rust toolchain pinned inrust-toolchain.toml; the workspace MSRV is Rust 1.85.
Validate Rust workspace changes with the prescribed locked build, all-features test suite, Clippy, and rustfmt checks where applicable.
Files:
src/ports/okf.rscrates/sl-daemon/src/main.rscrates/sl-viewer/src/app.rscrates/sl-viewer/src/corpus_loader.rssrc/lib.rs
**/*.rs
📄 CodeRabbit inference engine (AGENTS.md)
Fix Clippy warnings; do not add
#[allow]unless it includes a tracking-issue comment.
Files:
src/ports/okf.rscrates/sl-daemon/src/main.rscrates/sl-viewer/src/app.rscrates/sl-viewer/src/corpus_loader.rssrc/lib.rs
crates/sl-daemon/**/*.{rs,toml}
📄 CodeRabbit inference engine (AGENTS.md)
Use
cargo test --manifest-path crates/sl-daemon/Cargo.tomlas the fast inner-loop test command forsl-daemonchanges.
Files:
crates/sl-daemon/src/main.rs
crates/sl-viewer/**/*.{rs,toml}
📄 CodeRabbit inference engine (AGENTS.md)
crates/sl-viewer/**/*.{rs,toml}: Thesl-viewercrate uses Dioxus 0.6; use the Dioxus CLI/toolchain for desktop development and bundling.
Usecargo check -p sl-vieweras the fast inner-loop check for viewer changes.
Files:
crates/sl-viewer/src/app.rscrates/sl-viewer/src/corpus_loader.rs
crates/sl-viewer/**/*
📄 CodeRabbit inference engine (AGENTS.md)
When packaging the macOS viewer, account for the documented Electrobun/Dioxus code-signing requirements.
Files:
crates/sl-viewer/src/app.rscrates/sl-viewer/src/corpus_loader.rs
*
📄 CodeRabbit inference engine (AGENTS.md)
*: Perform feature work in a git worktree under.claude/worktrees/, created fromorigin/mainon a branch named<type>/<topic>, rather than working directly onmain.
Do not make direct commits to protectedmain; use a pull request.
Do not usegit reset --hard,git stash, orgit cleanin worktrees.
Do not use--no-verifyor bypass hooks without operator approval.
Do not work on a branch or worktree another actor is using.
Files:
HANDOFF-session-2026-08-05.md
🪛 LanguageTool
HANDOFF-session-2026-08-05.md
[style] ~137-~137: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...&str) -> &'static strlookup helper. - Addeddangerous_inner_html: "{icon_svg(tab.i...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~182-~182: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...b-pages / per-page additional panels. - No "feed data" affordance — user cannot po...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🪛 markdownlint-cli2 (0.23.2)
HANDOFF-session-2026-08-05.md
[warning] 1-1: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 85-85: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 91-91: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 95-95: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 99-99: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 109-109: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 117-117: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 118-118: Tables should be surrounded by blank lines
(MD058, blanks-around-tables)
[warning] 128-128: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 133-133: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 140-140: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 160-160: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 164-164: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 170-170: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 173-173: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 178-178: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 184-184: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 189-189: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 192-192: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
🔇 Additional comments (7)
src/ports/okf.rs (3)
126-139: LGTM!
195-223: LGTM!
176-182: 🩺 Stability & AvailabilityNo change needed.
Exports are anchored at
OkfDocument::new(okf: "1.0".into()), and the docs treatokf == "1.0"as the canonical OKF contract for this pipeline.src/lib.rs (1)
65-68: LGTM!crates/sl-daemon/src/main.rs (1)
296-300: 🎯 Functional CorrectnessThe documented exit codes match the CLI constants.
crates/sl-viewer/src/app.rs (2)
97-110: LGTM!
906-909: 📐 Maintainability & Code QualityAlign the Dioxus dependency with the repository guidance and recheck the feature under the pinned Rust toolchain.
crates/sl-viewer/Cargo.tomldeclaresdioxus = "0.7", while the repository guidance states sl-viewer use Dioxus 0.6. The full lockfile build cannot complete in this environment due to missingpkg-configforglib-sys, so the Rust check should be rerun with the pinned toolchain to rule out a local dependency/installation failure.
| /// Lookup table for tab icon SVGs. | ||
| fn icon_svg(tab_icon: &str) -> &'static str { | ||
| match tab_icon { | ||
| "bundles" => ICON_SVG_BUNDLES, | ||
| "history" => ICON_SVG_HISTORY, | ||
| "memory" => ICON_SVG_MEMORY, | ||
| "unfinished" => ICON_SVG_UNFINISHED, | ||
| "timeline" => ICON_SVG_TIMELINE, | ||
| "live" => ICON_SVG_LIVE, | ||
| "search" => ICON_SVG_SEARCH, | ||
| "replay" => ICON_SVG_REPLAY, | ||
| _ => ICON_SVG_BUNDLES, | ||
| } | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win
Avoid silently using the Bundles icon for unknown names.
If a new or misspelled icon name is missing from this lookup, the UI displays the Bundles icon without an error. Match directly on Tab, or use one exhaustive mapping, so missing cases fail during compilation.
🤖 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/sl-viewer/src/app.rs` around lines 217 - 230, Update icon_svg to map
exhaustively from the Tab type rather than accepting arbitrary string names with
a Bundles fallback. Ensure every Tab variant maps to its corresponding icon
constant so newly added or misspelled variants are caught at compile time.
| span { | ||
| dangerous_inner_html: "{icon_svg(tab.icon())}" | ||
| } | ||
| "{tab.label()}" |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Add explicit spacing between the icon and label.
The SVG wrapper has no class or margin. The following text node starts immediately after it. The icon and label can render without visible separation.
Proposed fix
span {
+ class: "tab-icon",
dangerous_inner_html: "{icon_svg(tab.icon())}"
}Add a small margin-inline-end to .tab-icon.
🤖 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/sl-viewer/src/app.rs` around lines 906 - 909, Update the icon wrapper
span in the tab rendering near tab.label() to include the tab-icon class, and
define or reuse the corresponding .tab-icon styling with a small
margin-inline-end so the SVG and label are visibly separated.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Mark the decorative SVG as hidden from assistive technology.
The button already exposes tab.label() as its accessible name. Add aria-hidden="true" to the wrapper so screen readers ignore the decorative SVG.
Proposed fix
span {
+ "aria-hidden": "true",
dangerous_inner_html: "{icon_svg(tab.icon())}"
}📝 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.
| span { | |
| dangerous_inner_html: "{icon_svg(tab.icon())}" | |
| } | |
| "{tab.label()}" | |
| span { | |
| "aria-hidden": "true", | |
| dangerous_inner_html: "{icon_svg(tab.icon())}" | |
| } | |
| "{tab.label()}" |
🤖 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/sl-viewer/src/app.rs` around lines 906 - 909, Add aria-hidden="true"
to the span wrapper containing icon_svg(tab.icon()) in the tab rendering, while
leaving tab.label() as the button’s accessible name.
| # Session Handoff — SessionLedger / Grapheon / asset-engine | ||
| **Captured:** 2026-08-05 (final state of the Forge session the user is closing due to length + hallucination drift). |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Fix the reported Markdown lint violations.
markdownlint-cli2 reports MD022 for headings without surrounding blank lines and MD058 for the table near Lines 118-125. Add the required blank lines so the handoff passes the configured Markdown checks.
Also applies to: 85-86, 91-92, 95-96, 99-100, 109-110, 117-125, 128-129, 133-134, 140-141, 160-161, 164-165, 170-171, 173-174, 178-179, 184-185, 189-190, 192-193
🧰 Tools
🪛 markdownlint-cli2 (0.23.2)
[warning] 1-1: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
🤖 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 `@HANDOFF-session-2026-08-05.md` around lines 1 - 2, Fix the Markdown spacing
in HANDOFF-session-2026-08-05.md by adding blank lines before and after every
affected heading and around the table near lines 118–125, including all listed
ranges. Preserve the existing content and table structure, and ensure the file
passes markdownlint-cli2 MD022 and MD058.
Source: Linters/SAST tools
| - Prior merge deleted `crates/sl-viewer/src/web_exports.rs` but left `mod web_exports;` declaration gone and `use web_exports::*;` remaining in `corpus_loader.rs` (test code) and call sites in production code → `cargo build` broke. | ||
| - Fix: recreated `web_exports.rs` with `WebExportProvider::{ChatGpt, Claude, Gemini}`, `web_export_roots_with_env()`, `load_web_export_corpus()`. Re-added `pub mod web_exports;` to `lib.rs`. Fixed `.cloned().collect()` on `Option<&str>` in SVG parts extraction. Resolved `<<<<<<<` conflict markers in `corpus_loader.rs`. |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Record the unresolved corpus_loader.rs state accurately.
Line 130 says that the conflict markers were resolved. The current PR context states that crates/sl-viewer/src/corpus_loader.rs still contains unresolved conflict markers and references the affected imported symbol. Update this handoff to record the remaining blocker. Otherwise, the next session may skip a source state that still prevents reliable workspace checks.
🤖 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 `@HANDOFF-session-2026-08-05.md` around lines 129 - 130, Update the handoff
entry describing crates/sl-viewer/src/corpus_loader.rs to state that unresolved
conflict markers remain and that the file still references the affected
web_exports symbol. Remove the claim that the markers were resolved, and
identify this as a remaining blocker for reliable workspace checks.
Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
| "valid": errors.is_empty(), | ||
| "errors": errors, | ||
| }); | ||
| println!("{result}"); |
There was a problem hiding this comment.
WARNING: JSON output format changed from pretty-printed to compact
The old code used serde_json::to_string_pretty(&result), while the new code uses println!("{result}") which produces compact JSON via Display. This is a behavioral change in the validate command's stdout that could break downstream consumers expecting pretty-printed output.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| } | ||
|
|
||
| let mut entity_ids = std::collections::HashSet::with_capacity(document.entities.len()); | ||
| for (index, entity) in document.entities.iter().enumerate() { |
There was a problem hiding this comment.
WARNING: Empty entity IDs are not validated
This loop only detects duplicate IDs via HashSet::insert. An entity with id: "" passes validation and is not flagged. Empty IDs are structurally invalid and can cause downstream issues when relations attempt to reference them.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (1 file)
Previous Review Summaries (4 snapshots, latest commit 3d6e099)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 3d6e099)Status: No Issues Found | Recommendation: Merge Files Reviewed (1 file)
Previous review (commit c9fa5fd)Status: No Issues Found | Recommendation: Merge Files Reviewed (1 file)
Previous review (commit fd93386)Status: 7 Issues Found | Recommendation: Request Changes Overview
Issue Details (click to expand)CRITICAL
WARNING
SUGGESTION
Files Reviewed (7 files)
Fix these issues in Kilo Cloud Previous review (commit b00c2d1)Status: 7 Issues Found | Recommendation: Request Changes Overview
Issue Details (click to expand)CRITICAL
WARNING
SUGGESTION
Files Reviewed (7 files)
Reviewed by step-3.7-flash · Input: 64.6K · Output: 12.4K · Cached: 180K |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@crates/sl-daemon/src/etl.rs`:
- Around line 150-151: Replace the lossy sanitize function in
crates/sl-daemon/src/etl.rs:150-151 with an injective encoding that remains a
single path component, and preserve or migrate existing filenames if supported.
Update the lookup at crates/sl-daemon/src/main.rs:1179-1179 to use the same
mapping. Add an ETL-to-validation regression test covering bundle IDs a/b and
a_b, asserting distinct output paths and preserved source IDs.
🪄 Autofix
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: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 1832e228-b606-4a07-a8e9-a57712826914
📒 Files selected for processing (3)
crates/sl-daemon/src/etl.rscrates/sl-daemon/src/main.rssrc/ports/okf.rs
📜 Review details
⏰ Context from checks skipped due to timeout. (3)
- GitHub Check: semgrep-cloud-platform/scan
- GitHub Check: prepare
- GitHub Check: Summary
⚠️ CI failures not shown inline (2)
GitHub Check: Summary: The current Mergify configuration is invalid
Conclusion: failure
* Invalid condition 'author=dependabot[bot] | renovate[bot]' @ root → pull_request_rules → item 1 → conditions → item 0 → author=dependabot[bot] | renovate[bot]
```
Invalid GitHub login
```
* Invalid condition 'author=trunk-io[bot] | mergify[bot] | github-actions[bot]' @ root → pull_request_rules → item 2 → conditions → item 0 → author=trunk-io[bot] | mergify[bot] | github-actions[bot]
```
Invalid GitHub login
```
* Invalid condition 'age>=30d' @ root → pull_request_rules → item 8 → conditions → item 2 → age>=30d
```
Invalid attribute
```
* Extra inputs are not permitted @ root → pull_request_rules → item 0 → actions → post_merge
* Extra inputs are not permitted @ root → pull_request_rules → item 1 → actions → post_merge
* Extra inputs are not permitted @ root → pull_request_rules → item 3 → actions → request_reviews → github_accounts
GitHub Check: Mergify Merge Queue: The current Mergify configuration is invalid
Conclusion: failure
* Invalid condition 'author=dependabot[bot] | renovate[bot]' @ root → pull_request_rules → item 1 → conditions → item 0 → author=dependabot[bot] | renovate[bot]
```
Invalid GitHub login
```
* Invalid condition 'author=trunk-io[bot] | mergify[bot] | github-actions[bot]' @ root → pull_request_rules → item 2 → conditions → item 0 → author=trunk-io[bot] | mergify[bot] | github-actions[bot]
```
Invalid GitHub login
```
* Invalid condition 'age>=30d' @ root → pull_request_rules → item 8 → conditions → item 2 → age>=30d
```
Invalid attribute
```
* Extra inputs are not permitted @ root → pull_request_rules → item 0 → actions → post_merge
* Extra inputs are not permitted @ root → pull_request_rules → item 1 → actions → post_merge
* Extra inputs are not permitted @ root → pull_request_rules → item 3 → actions → request_reviews → github_accounts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{rs,toml}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{rs,toml}: Use the Rust toolchain pinned inrust-toolchain.toml; the workspace MSRV is Rust 1.85.
Validate Rust workspace changes with the prescribed locked build, all-features test suite, Clippy, and rustfmt checks where applicable.
Files:
src/ports/okf.rscrates/sl-daemon/src/etl.rscrates/sl-daemon/src/main.rs
**/*.rs
📄 CodeRabbit inference engine (AGENTS.md)
Fix Clippy warnings; do not add
#[allow]unless it includes a tracking-issue comment.
Files:
src/ports/okf.rscrates/sl-daemon/src/etl.rscrates/sl-daemon/src/main.rs
crates/sl-daemon/**/*.{rs,toml}
📄 CodeRabbit inference engine (AGENTS.md)
Use
cargo test --manifest-path crates/sl-daemon/Cargo.tomlas the fast inner-loop test command forsl-daemonchanges.
Files:
crates/sl-daemon/src/etl.rscrates/sl-daemon/src/main.rs
🔇 Additional comments (2)
src/ports/okf.rs (1)
197-203: LGTM!Also applies to: 263-346
crates/sl-daemon/src/main.rs (1)
1360-1379: LGTM!
| pub(crate) fn sanitize(id: &str) -> String { | ||
| id.chars().map(|c| if matches!(c, '/' | '\\' | ':') { '_' } else { c }).collect() |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
Use a collision-free filename encoding for bundle IDs.
sanitize("a/b") and sanitize("a_b") both produce a_b. ETL can overwrite the first document with the second document. Validation can then load and validate the wrong document.
crates/sl-daemon/src/etl.rs#L150-L151: replace the lossy mapping with an injective, single-path-component encoding. Preserve or migrate existing output filenames if they are supported.crates/sl-daemon/src/main.rs#L1179-L1179: use the same collision-free mapping for lookup.- Add an ETL-to-validation regression test for
a/banda_bthat asserts distinct output paths and source IDs.
📍 Affects 2 files
crates/sl-daemon/src/etl.rs#L150-L151(this comment)crates/sl-daemon/src/main.rs#L1179-L1179
🤖 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/sl-daemon/src/etl.rs` around lines 150 - 151, Replace the lossy
sanitize function in crates/sl-daemon/src/etl.rs:150-151 with an injective
encoding that remains a single path component, and preserve or migrate existing
filenames if supported. Update the lookup at
crates/sl-daemon/src/main.rs:1179-1179 to use the same mapping. Add an
ETL-to-validation regression test covering bundle IDs a/b and a_b, asserting
distinct output paths and preserved source IDs.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 @.github/workflows/ci.yml:
- Line 221: Update the actions/checkout step to reference the approved full
commit SHA instead of the mutable v7 tag, and set persist-credentials to false
for this checkout action.
🪄 Autofix
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: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: c99a6624-ee45-4db8-aa12-b8c38a86701b
📒 Files selected for processing (2)
.github/workflows/ci.ymldocs/ops/eval-manifest.json
📜 Review details
⏰ Context from checks skipped due to timeout. (4)
- GitHub Check: semgrep-cloud-platform/scan
- GitHub Check: prepare
- GitHub Check: browser e2e · axe · responsive · visual
- GitHub Check: Summary
⚠️ CI failures not shown inline (2)
GitHub Check: Summary: The current Mergify configuration is invalid
Conclusion: failure
* Invalid condition 'author=dependabot[bot] | renovate[bot]' @ root → pull_request_rules → item 1 → conditions → item 0 → author=dependabot[bot] | renovate[bot]
```
Invalid GitHub login
```
* Invalid condition 'author=trunk-io[bot] | mergify[bot] | github-actions[bot]' @ root → pull_request_rules → item 2 → conditions → item 0 → author=trunk-io[bot] | mergify[bot] | github-actions[bot]
```
Invalid GitHub login
```
* Invalid condition 'age>=30d' @ root → pull_request_rules → item 8 → conditions → item 2 → age>=30d
```
Invalid attribute
```
* Extra inputs are not permitted @ root → pull_request_rules → item 0 → actions → post_merge
* Extra inputs are not permitted @ root → pull_request_rules → item 1 → actions → post_merge
* Extra inputs are not permitted @ root → pull_request_rules → item 3 → actions → request_reviews → github_accounts
GitHub Check: Mergify Merge Queue: The current Mergify configuration is invalid
Conclusion: failure
* Invalid condition 'author=dependabot[bot] | renovate[bot]' @ root → pull_request_rules → item 1 → conditions → item 0 → author=dependabot[bot] | renovate[bot]
```
Invalid GitHub login
```
* Invalid condition 'author=trunk-io[bot] | mergify[bot] | github-actions[bot]' @ root → pull_request_rules → item 2 → conditions → item 0 → author=trunk-io[bot] | mergify[bot] | github-actions[bot]
```
Invalid GitHub login
```
* Invalid condition 'age>=30d' @ root → pull_request_rules → item 8 → conditions → item 2 → age>=30d
```
Invalid attribute
```
* Extra inputs are not permitted @ root → pull_request_rules → item 0 → actions → post_merge
* Extra inputs are not permitted @ root → pull_request_rules → item 1 → actions → post_merge
* Extra inputs are not permitted @ root → pull_request_rules → item 3 → actions → request_reviews → github_accounts
🧰 Additional context used
🪛 zizmor (1.29.0)
.github/workflows/ci.yml
[warning] 221-221: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 221-221: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🔇 Additional comments (2)
.github/workflows/ci.yml (1)
213-220: LGTM!Also applies to: 222-225
docs/ops/eval-manifest.json (1)
47-47: 🗄️ Data Integrity & Integrationcargo_lock_sha256 matches
Cargo.lock.
| if: github.event_name == 'pull_request' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v7 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== workflow excerpt =="
if [ -f .github/workflows/ci.yml ]; then
nl -ba .github/workflows/ci.yml | sed -n '200,240p'
else
echo "missing .github/workflows/ci.yml"
fi
echo
echo "== checkout occurrences =="
rg -n "actions/checkout|persist-credentials|permissions:|pull|GITHUB_TOKEN|pull_request" .github/workflows/ci.yml || true
echo
echo "== repository approved actions? =="
if [ -d .github/actions ]; then
rg -n "actions/checkout|full commit|commit SHA|actions/checkout@" .github || true
else
echo "no .github/actions directory"
fiRepository: KooshaPari/SessionLedger
Length of output: 225
🌐 Web query:
actions/checkout persist-credentials true by default README
💡 Result:
The persist-credentials input for the GitHub actions/checkout action is set to true by default [1][2]. This setting configures the action to persist the authentication token or SSH key in the local git configuration of the checked-out repository [1][3]. This allows your workflow scripts to run authenticated git commands (e.g., git push) without needing to manually configure credentials [1][4]. Important security and operational details regarding this default behavior include: - Purpose: By persisting the token in the local git config, the action enables seamless, authenticated git operations within your workflow steps [1][5]. - Opt-out: You can disable this behavior by explicitly setting persist-credentials: false in your workflow YAML file if you prefer not to have credentials stored in the local git config [1][4]. - Security Enhancement: In newer versions of the action, the credentials are stored in a separate file under the $RUNNER_TEMP directory, rather than being written directly into the standard.git/config file [1][5]. This is designed to improve security by isolating the credential file [1][5]. - Automatic Cleanup: Regardless of the persistence, the credentials are removed during the post-job cleanup phase of the action [1][5]. While there has been community discussion and debate regarding whether this should be true by default due to security concerns [6], it remains the established default configuration in the official actions/checkout action [1][2].
Citations:
- 1: https://github.com/actions/checkout
- 2: https://raw.githubusercontent.com/actions/checkout/v6/action.yml
- 3: https://github.com/actions/checkout/tree/v6.0.0
- 4: https://github.com/actions/checkout/tree/v6.0.2?tab=readme-ov-file
- 5: https://github.com/actions/checkout/?tab=readme-ov-file
- 6: [security] Escalate concerning default
persist-credentials=trueplease actions/checkout#2312
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== workflow excerpt =="
if [ -f .github/workflows/ci.yml ]; then
awk 'NR>=200 && NR<=240 { printf "%4d\t%s\n", NR, $0 }' .github/workflows/ci.yml
else
echo "missing .github/workflows/ci.yml"
fi
echo
echo "== checkout occurrences =="
grep -n "actions/checkout\|persist-credentials\|permissions:\|pull\|GITHUB_TOKEN\|pull_request" .github/workflows/ci.yml || true
echo
echo "== repository approved actions? =="
if [ -d .github/actions ]; then
grep -R "actions/checkout\|commit SHA\|actions/checkout@" .github || true
else
echo "no .github/actions directory"
fiRepository: KooshaPari/SessionLedger
Length of output: 2744
🌐 Web query:
actionlint GITHUB_TOKEN pull_request workflow syntax warning persist-credentials false actions/checkout default true
💡 Result:
The actionlint tool includes a specific security check that flags the use of actions/checkout without explicitly setting persist-credentials: false [1]. This check is designed to mitigate security risks associated with the default behavior of actions/checkout [2][3]. By default, actions/checkout persists the GITHUB_TOKEN (or other authentication credentials) in the local git configuration of the runner [4][5]. While this allows subsequent steps in the same job to execute authenticated git commands, it also means that any subsequent step—including those executing untrusted code—can access these credentials [6][3]. Setting persist-credentials: false explicitly opts out of this behavior, ensuring the token is not stored in the git configuration [4]. Actionlint identifies this as a potential vulnerability because leaving the default enabled (true) increases the attack surface if a workflow job is compromised [2][7]. Even though the GITHUB_TOKEN is available to the entire job regardless of this setting, minimizing its exposure by not writing it to disk is considered a security best practice [8][6].
Citations:
- 1: rhysd/actionlint@c3393ef
- 2: https://tenki.cloud/blog/lint-github-actions-workflows-actionlint
- 3: https://github.com/suzuki-shunsuke/ghalint/blob/main/docs/policies/013.md
- 4: https://github.com/actions/checkout
- 5: https://github.com/actions/checkout/tree/v6.0.2?tab=readme-ov-file
- 6: Remove
persist-credentialsor change the default tofalseactions/checkout#485 - 7: https://sisaku-security.github.io/lint/docs/goat/case06-artipacked/
- 8: Change the default value of persist-credentials to false actions/checkout#1687
Pin actions/checkout to a full SHA and set persist-credentials: false.
actions/checkout@v7 is a mutable tag, and this job runs PR-controlled PowerShell with access to the workflow token. Persisting credentials would let unchecked checkout output write a git credential alias to the local runner. Pin the approved commit and disable persistence.
Proposed hardening
- - uses: actions/checkout@v7
+ - uses: actions/checkout@<approved-40-character-commit-sha> # v7
+ with:
+ persist-credentials: false🧰 Tools
🪛 zizmor (1.29.0)
[warning] 221-221: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 221-221: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 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 @.github/workflows/ci.yml at line 221, Update the actions/checkout step to
reference the approved full commit SHA instead of the mutable v7 tag, and set
persist-credentials to false for this checkout action.
Source: Linters/SAST tools
|
Closing as superseded. Cannot auto-rebase due to merge conflicts. Branch preserved locally for reference. |
User description
Summary
Evidence
cargo test validate_on_disk_okf_accepts_daemon_generated_document(1 passed)serve --once --http-bind off-> 1 OKF documentvalidate roundtrip-session --data-dir ...->{"errors":[],"valid":true}Known unrelated workspace issue: full
cargo fmt --all -- --checkis blocked by pre-existing conflict markers incrates/sl-viewer/src/corpus_loader.rs.CodeAnt-AI Description
Validate exported OKF graphs correctly and add icons to viewer tabs
What Changed
Impact
✅ Reliable OKF export validation✅ Clearer structural validation errors✅ Faster tab recognition in the viewer💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.