Skip to content

fix: remediate full-review findings - #70

Merged
jmagar merged 5 commits into
mainfrom
codex/cortex-review-24-fixes
Jun 8, 2026
Merged

fix: remediate full-review findings#70
jmagar merged 5 commits into
mainfrom
codex/cortex-review-24-fixes

Conversation

@jmagar

@jmagar jmagar commented Jun 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

Closes #69.

This PR completes the comprehensive remediation pass for all 24 findings from the full-review issue. It includes runtime/code fixes, regression coverage, CI/policy gates, docs rebrand/security/release updates, and agent-memory source-of-truth repair.

Issue #69 Checklist

  • 1. Reduced inventory graph projection write-lock scope by building a projection plan outside the global DB write lock and applying only the minimal DB mutation phase under lock; added a regression proving unrelated writes are not blocked during expensive projection preparation.
  • 2. Added a shared SSH context with bounded concurrency and retry/backoff behavior across remote inventory and Docker event collection, with concurrency/backoff coverage.
  • 3. Changed inventory SSH host key policy to strict checking by default with explicit CORTEX_INVENTORY_SSH_TRUST_ON_FIRST_USE=true bootstrap opt-in and known-hosts support.
  • 4. Hardened remote deploy SSH host handling by rejecting option-like hosts and using the shared SSH argument builder with -- before the host.
  • 5. Rebranded current docs/config/schema examples from stale public syslog identity to cortex tool names, scopes, plugin paths, install examples, and schema metadata where appropriate.
  • 6. Restored CLAUDE.md as the source of truth and converted sibling AGENTS.md files to symlinks after merging deltas.
  • 7. Moved MCP argument validation to typed request structs for the affected actions and added unknown-field and numeric-type rejection coverage.
  • 8. Added action handler metadata to the MCP action registry and dispatch through that registry mapping.
  • 9. Routed deploy SSH through the shared hardened SSH policy rather than its own unchecked host path.
  • 10. Unified touched query variants and pushed limits into SQL bindings for error summary/search/tail paths.
  • 11. Split patterns into DB row fetch plus CPU clustering outside the DB closure.
  • 12. Returned normalized inventory from refresh in memory and projected that snapshot instead of rereading the cache from disk.
  • 13. Documented RSA advisory ownership/review cadence, added MIT package metadata, and cleaned cargo-deny warning noise so cargo deny check is clean.
  • 14. Consolidated release/version policy, kept canonical version-bearing files in sync, and added a plugin-manifest guard for intentionally unversioned manifests.
  • 15. Updated CI clippy to cargo clippy --all-targets -- -D warnings.
  • 16. Added docs authority guidance separating current docs from archival/historical material.
  • 17. Removed the redundant graph count query in inventory projection.
  • 18. Extracted inventory collector timeout/reporting helper behavior and reduced collector boilerplate.
  • 19. Changed MCP payload diagnostics to invalid {action} arguments.
  • 20. Replaced touched SQL limit interpolation with bound parameters / typed helper use.
  • 21. Documented OAuth non-Unix fail-closed behavior.
  • 22. Added a release checklist separating hermetic CI gates from live fleet/smoke gates.
  • 23. Added an operator-facing security model covering MCP/OAuth/SSH/advisories/redaction trust assumptions.
  • 24. Documented rmcp = "1.6.0" as the supported lower bound while the lockfile may resolve newer compatible 1.x releases.

Verification

  • cargo fmt -- --check passed.
  • cargo test passed: lib 1074 passed, 0 failed, 1 ignored; main 328 passed, 0 failed, 1 ignored; integration/doc tests passed.
  • cargo clippy --all-targets -- -D warnings passed.
  • cargo deny check passed: advisories ok, bans ok, licenses ok, sources ok.
  • bash scripts/check-version-sync.sh --require-changelog passed at v1.14.2.
  • bash scripts/check-agent-memory-symlinks.sh passed.
  • bash scripts/check-plugin-manifest-versions.sh passed.
  • bash scripts/check-public-identity.sh passed.
  • git diff --check passed.
  • Pre-commit hooks passed: env guard, diff check, format, yaml, lint.
  • Pre-push hook passed: full test run.

Notes

No subpoints were intentionally deferred. Live fleet smoke gates are documented in docs/RELEASE.md and remain operator-intent gates, not hermetic CI gates.


Summary by cubic

Completes remediation of all 24 full‑review findings. Tightens request/schema validation, adds graph lookup by id with stricter target rules, and hardens SSH inventory/remote Docker/deploy flows with safer defaults and new telemetry.

  • Bug Fixes
    • Validation: deny_unknown_fields across HTTP/MCP models; MCP tool schema sets additionalProperties: false with numeric mins; standardized “invalid {action} arguments”; enforced array shape for abuse.terms.
    • Graph/DB: added entity_id lookup; reject mixed/partial targets; around fixed to depth=1; inventory projection planned outside the write lock and removed redundant counts; bound SQL LIMIT parameters; split pattern row fetch from CPU clustering.
    • SSH/deploy: unified on SshContext with strict host key checking, safe arg building (reject option-like hosts, insert --), bounded concurrency, and retry/backoff; remote Docker event streams use safer defaults; added counters and last-error snapshots.
    • CI/docs: new CI guards for plugin manifest version policy (manifests unversioned), agent‑memory symlinks, and public identity strings; rebrand docs to “cortex”; set license = "MIT"; documented rmcp = "1.6.0" lower bound; bumped release metadata to 1.14.2.

Written for commit 80f977d. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Safer SSH orchestration and remote-deploy UX with host-safety checks, configurable SSH behavior, and improved event-stream handling.
    • Stricter API validation: many endpoints now reject unknown request fields.
    • Pattern analysis uses bounded scan limits and improved clustering.
  • Bug Fixes

    • Inventory projection updated to avoid holding write locks during preparation.
    • Hardening of SSH-backed inventory and deploy flows; deploy rejects unsafe hosts early.
  • CI

    • CI now runs additional repo policy checks (plugin manifest/version rules, agent-memory symlink validation, public-identity scans) and lints all targets.
  • Chores

    • Release bumped to 1.14.2 and documentation/tooling renamed/rebased around “cortex.”

@coderabbitai

coderabbitai Bot commented Jun 7, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8c3034ec-7914-4b1d-a839-4fd53b36798b

📥 Commits

Reviewing files that changed from the base of the PR and between 8c25f0b and 80f977d.

📒 Files selected for processing (17)
  • deny.toml
  • docs/GUARDRAILS.md
  • docs/mcp/DEPLOY.md
  • docs/plugin/HOOKS.md
  • scripts/check-plugin-manifest-versions.sh
  • scripts/check-public-identity.sh
  • src/app/services/analytics.rs
  • src/db/graph_inventory.rs
  • src/db/graph_inventory_tests.rs
  • src/deploy.rs
  • src/deploy_tests.rs
  • src/inventory/orchestrator.rs
  • src/inventory/orchestrator_tests.rs
  • src/mcp/actions.rs
  • src/mcp/tools.rs
  • src/mcp/tools_tests.rs
  • src/runtime/inventory_refresh.rs

📝 Walkthrough

Walkthrough

This PR adds CI/release checks and scripts, rebrands docs to cortex, implements SshOptions/SshContext and wires it into inventory collectors and deploy, refactors inventory projection into plan/apply, binds SQL LIMITs and splits patterns fetch/clustering, centralizes MCP typed request parsing and schema tightening, tightens request-model deserialization, extends runtime observability, and updates/adds tests.

Changes

Release & CI

Layer / File(s) Summary
CI workflow and release scripts
.github/workflows/ci.yml, scripts/check-plugin-manifest-versions.sh, scripts/check-agent-memory-symlinks.sh, scripts/check-public-identity.sh
Adds script checks to version-sync job and runs clippy with --all-targets -- -D warnings; adds plugin manifest, agent-memory symlink, and public-identity guards.
Version metadata
Cargo.toml, server.json, mcpb/manifest.json, CHANGELOG.md
Bumps crate and package versions to 1.14.2, adds license and changelog entry.

Documentation & Policy

Layer / File(s) Summary
Docs rebrand and authority
CLAUDE.md, docs/README.md, docs/RELEASE.md, docs/SECURITY.md, docs/RUST.md
Rewrites CLAUDE operational guide, adds RELEASE and SECURITY docs, clarifies rmcp intent and authoritative docs index.
MCP/plugin docs and paths
docs/mcp/*, docs/plugin/*, README.md, config/mcporter.json
Replaces syslog→cortex naming across MCP/plugin docs and examples; updates plugin manifest handling and marketplace examples.

Models & CLI

Layer / File(s) Summary
Request model strictness
src/app/models/*.rs, src/app/models/stats.rs, src/app/models/graph.rs
Adds #[serde(deny_unknown_fields)] to many request structs, adds alias "limit" for PatternsRequest.scan_limit, and adds optional entity_id to GraphEntityLookupRequest.
CLI/test alignment
src/cli/*, src/app/service_tests.rs
Aligns CLI request construction and tests to include entity_id: None and to assert stricter validation behavior.

SSH & Deploy

Layer / File(s) Summary
SSH abstraction and tests
src/inventory/ssh.rs, src/inventory/ssh_tests.rs
Introduces SshOptions, SshContext, HostResolution, public is_safe_ssh_host, concurrency limiter, retries/backoff, and expanded tests for args, jitter, cancellation, and concurrency.
Deploy runner
src/deploy.rs, src/deploy_tests.rs
Uses SshContext-generated ssh args, rejects unsafe/option-like hosts before running remote phases; adds FakeRemoteRunner and deploy tests.

Inventory & Orchestration

Layer / File(s) Summary
Orchestrator & collectors
src/inventory/orchestrator.rs, src/inventory/raw_configs.rs, src/inventory/remote_configs.rs, src/inventory/remote_device.rs, src/inventory/remote_docker.rs
Introduces InventoryRefreshOutcome, centralizes collector timing with collector_task, constructs and passes a shared SshContext to SSH-backed collectors, and changes raw_configs to accept CollectOptions including ssh_context.
Runtime integration
src/runtime/inventory_refresh.rs, src/runtime/inventory_refresh_tests.rs
Inventory refresh uses refresh_inventory_with_inventory and Docker event streaming uses shared SshContext with sampled subprocess output and observability hooks.

Graph Projection

Layer / File(s) Summary
Planner/apply split
src/db/graph_inventory.rs, src/db/graph_inventory_tests.rs, src/db/graph_inventory/sql.rs
project_inventory builds InventoryProjectionPlan in memory; apply_projection_plan performs DB transaction upserts for entities/aliases/relationships; removes old SQL upsert helpers and adds planner data model and regression tests ensuring projection prep doesn't block unrelated writes.

DB Queries & Patterns

Layer / File(s) Summary
LIMIT binding and query helpers
src/db/queries.rs, src/db/queries_tests.rs
Adds push_bound_limit and binds LIMIT parameters across FTS and non-FTS paths; refactors tail and get_error_summary SQL builders and tests.
Pattern fetch + clustering
src/db/analytics.rs, src/app/services/analytics.rs, src/db/analytics_tests.rs, src/db.rs
Splits patterns into fetch_pattern_rows (DB scan with truncation detection) and cluster_pattern_rows (CPU aggregation); service updated to call fetch then cluster; re-exports adjusted and tests updated.

MCP & Schemas

Layer / File(s) Summary
Typed action parsing and dispatch
src/mcp/tools.rs, src/mcp/tools_tests.rs, src/mcp/actions.rs
Adds ActionHandler/handler_for and moves many tool handlers to typed serde deserialization via action_payload(args, action), standardizing invalid-argument messages and extending tests for unknown-field rejection.
Schema tightening
src/mcp/schemas.rs, src/mcp/schemas_tests.rs
Sets additionalProperties=false, tightens numeric bounds (evidence_id, depth), bounds scan_limit to PATTERN_SCAN_LIMIT_MAX, and refactors graph action schema to enforce allowed lookup modes and depth constraints with tests validating parity.

Observability & Runtime

Layer / File(s) Summary
Remote Docker event failures
src/observability.rs, src/runtime/inventory_refresh.rs
Adds remote_docker_event_stream_failures and last-error snapshot fields; inventory refresh records stream failures and tests updated to assert snapshot fields.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

  • #69: Implements many objectives (inventory projection lock-scope, SSH concurrency/backoff, MCP typed validation, CI clippy all-targets). The PR addresses those listed goals.
  • Address comprehensive full-review findings aurora#19: Related to agent-memory symlink convention; PR adds check script and doc changes restoring CLAUDE.md/AGENTS.md symlink behavior.

Possibly related PRs

  • jmagar/cortex#68: Related inventory/orchestrator and graph projection work this PR refactors.
  • jmagar/cortex#67: Related inventory-refresh refactor and homelab inventory map changes.
  • jmagar/cortex#65: Related CLI/AI output UX changes reused by this PR.

"A rabbit binks through code and docs so bright,
CI guards the gates and SSH holds tight,
Cortex names bloom where syslog once stood,
Patterns cluster and MCP speaks good,
Release hops onward into the night." 🐇✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/cortex-review-24-fixes

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
docs/mcp/DEPLOY.md (1)

173-173: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update stale syslog-named SWAG config reference.

Line 173 still points to docs/syslog.subdomain.conf, which appears inconsistent with the cortex rebrand and can mislead operators looking for current deployment docs.

🤖 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 `@docs/mcp/DEPLOY.md` at line 173, Update the stale reference in DEPLOY.md that
points to docs/syslog.subdomain.conf and the example URL
https://cortex.tootie.tv/mcp: locate the string "docs/syslog.subdomain.conf" and
replace it with the current SWAG/nginx config filename used by the project
(e.g., the repo's current SWAG config file), and update or remove the
"https://cortex.tootie.tv/mcp" example to the correct, non-rebranded domain or a
neutral placeholder; ensure the text around the reference still directs
operators to the working nginx/SWAG config (adjust the filename in the same
sentence where docs/syslog.subdomain.conf appears).
src/inventory/orchestrator.rs (1)

171-182: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Per-collector timeouts are never classified as skipped.

collector_task() emits the timeout marker as "timeout", but run_collector() only recognizes "collection_timeout". Any collector that hits its individual deadline will therefore fall through to "partial" instead of "skipped".

Proposed fix
-type NamedOutput = (&'static str, String, String, u128, CollectorOutput);
+type NamedOutput = (&'static str, String, String, u128, bool, CollectorOutput);

-                    (
-                        name,
-                        now.clone(),
-                        now,
-                        config.collection_deadline.as_millis(),
-                        output,
-                    )
+                    (
+                        name,
+                        now.clone(),
+                        now,
+                        config.collection_deadline.as_millis(),
+                        true,
+                        output,
+                    )

-        let out = match tokio::time::timeout(deadline, future).await {
-            Ok(output) => output,
-            Err(_) => timeout_output(name, deadline),
-        };
+        let (timed_out, out) = match tokio::time::timeout(deadline, future).await {
+            Ok(output) => (false, output),
+            Err(_) => (true, timeout_output(name, deadline)),
+        };
         (
             name,
             started,
             Utc::now().to_rfc3339(),
             t.elapsed().as_millis(),
+            timed_out,
             out,
         )

-    let (name, started_at, finished_at, elapsed_ms, output) = result;
+    let (name, started_at, finished_at, elapsed_ms, timed_out, output) = result;
     warnings.extend(output.warnings.iter().cloned());
-    let status = if output
-        .errors
-        .iter()
-        .any(|e| e.phase == "collection_timeout")
-    {
+    let status = if timed_out {
         "skipped"
     } else if output.errors.iter().any(|e| e.severity == "error") {
         "failed"

Also applies to: 271-274, 300-306

🤖 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/inventory/orchestrator.rs` around lines 171 - 182, The per-collector
timeout marker mismatch causes timed collectors to be classified as "partial"
because collector_task emits "timeout" while run_collector expects
"collection_timeout"; update run_collector (the code paths that inspect
CollectorOutput warnings/markers) to treat either "timeout" or
"collection_timeout" as the timeout/skipped case (or normalize incoming warnings
by mapping "timeout" -> "collection_timeout") so that COLLECTOR_NAMES iteration
and CollectorOutput::warn("collection_timeout", ...) semantics correctly
classify those collectors as skipped; apply the same change in the other similar
branches that inspect collector warnings (the other occurrences noted around
where run_collector handles per-collector results).
🤖 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 `@deny.toml`:
- Around line 55-58: The policy currently sets the cargo-deny wildcards policy
to "allow" via the wildcards setting; change this to "warn" so wildcard
dependency requirements are detected and surfaced (i.e., update the wildcards =
"allow" entry to wildcards = "warn"), keeping the git dep pin behavior intact
while restoring warning-level detection for broad/wildcard specs.

In `@docs/plugin/HOOKS.md`:
- Line 24: Update the inconsistent file path references in HOOKS.md so they
match: decide whether the hooks file lives at "plugins/cortex/hooks/hooks.json"
or "plugins/hooks/hooks.json", then change the other occurrence to the chosen
path (update the sentence "Hooks are registered in
`plugins/cortex/hooks/hooks.json`" or the "File location" tree entries
referencing `plugins/hooks/hooks.json`) so both references are identical and
correct.

In `@docs/plugin/SKILLS.md`:
- Line 41: Update the "Directory structure" section in the SKILLS.md
documentation (around lines 17-18) to align with the new path structure. Replace
references to `plugins/skills/syslog/` with the new `plugins/cortex/skills/`
path pattern to maintain consistency with the updated examples shown elsewhere
in the document at lines 41, 52, and 59. Ensure all directory examples in the
structure block reflect the current plugin directory organization.

In `@scripts/check-plugin-manifest-versions.sh`:
- Around line 25-36: Invert the Python exit logic inside the heredoc so the
script returns non-zero when a top-level "version" key is present (and zero
otherwise); specifically change the current sys.exit(0 if "version" in payload
else 1) to sys.exit(1 if "version" in payload else 0) inside the Python block of
the check-plugin-manifest-versions.sh heredoc so the shell if ... then condition
becomes direct (if python fails then print the FAIL message and set status=1).

In `@src/app/services/analytics.rs`:
- Around line 123-137: The clustering work is happening after awaiting
self.run_db which can block executor threads; move the db::cluster_pattern_rows
call and construction of PatternsResponse into the closure passed to run_db so
clustering runs on the DB worker thread. Specifically, inside the closure given
to run_db("patterns_fetch", ...) perform db::fetch_pattern_rows then call
db::cluster_pattern_rows(rows, top_n) and return the PatternsResponse (or the
tuple needed) from the closure so the await receives the already-clustered
result instead of running cluster_pattern_rows after the await.

In `@src/db/graph_inventory.rs`:
- Around line 596-603: The current token filtering in the prefix extraction uses
starts_with("http") which incorrectly excludes tokens like "http-api"; change
the predicate in the closure used after upstream.split(...) so it only rejects
exact URL scheme tokens ("http" or "https") instead of anything starting with
"http" — e.g. replace part.starts_with("http") with a check like part == "http"
|| part == "https". This affects the block that computes prefix and calls
canonical_or_raw and match_service_name_key (variables/functions: upstream,
prefix, canonical_or_raw, match_service_name_key, normalized, source, services).

In `@src/deploy.rs`:
- Around line 643-666: Move the inline unit tests
(remote_deploy_rejects_option_like_hosts_before_running_ssh and
remote_deploy_accepts_safe_hosts) out of the deploy module into a sidecar test
file named deploy_tests.rs and keep only the test-module hook in the source;
update references so the tests still use FakeRemoteRunner and
run_remote_deploy_with_runner from the deploy module, and replace the inline
tests block with the single hook: #[cfg(test)] #[path = "deploy_tests.rs"] mod
tests; ensuring the new deploy_tests.rs contains the original test functions and
any necessary use/imports.

In `@src/runtime/inventory_refresh.rs`:
- Around line 206-209: spawn_remote_docker_event_tasks /
run_remote_docker_events_once currently acquire_owned() a semaphore permit and
hold it for the entire lifetime of the remote `docker events` process, which
starves other hosts; change the logic so the semaphore is only held while
initiating the SSH/command (e.g., acquire_owned() in
run_remote_docker_events_once just long enough to open the SSH session and spawn
the remote `docker events` reader) and then drop the owned permit before
awaiting the long-lived stream; specifically modify
run_remote_docker_events_once and the task started by
spawn_remote_docker_event_tasks to release the permit (drop the
OwnedSemaphorePermit) immediately after the child/process is started (or use
try_acquire with timeout if startup may block), so SshContext/SSH setup uses the
permit briefly but the long-lived event loop does not hold it.

---

Outside diff comments:
In `@docs/mcp/DEPLOY.md`:
- Line 173: Update the stale reference in DEPLOY.md that points to
docs/syslog.subdomain.conf and the example URL https://cortex.tootie.tv/mcp:
locate the string "docs/syslog.subdomain.conf" and replace it with the current
SWAG/nginx config filename used by the project (e.g., the repo's current SWAG
config file), and update or remove the "https://cortex.tootie.tv/mcp" example to
the correct, non-rebranded domain or a neutral placeholder; ensure the text
around the reference still directs operators to the working nginx/SWAG config
(adjust the filename in the same sentence where docs/syslog.subdomain.conf
appears).

In `@src/inventory/orchestrator.rs`:
- Around line 171-182: The per-collector timeout marker mismatch causes timed
collectors to be classified as "partial" because collector_task emits "timeout"
while run_collector expects "collection_timeout"; update run_collector (the code
paths that inspect CollectorOutput warnings/markers) to treat either "timeout"
or "collection_timeout" as the timeout/skipped case (or normalize incoming
warnings by mapping "timeout" -> "collection_timeout") so that COLLECTOR_NAMES
iteration and CollectorOutput::warn("collection_timeout", ...) semantics
correctly classify those collectors as skipped; apply the same change in the
other similar branches that inspect collector warnings (the other occurrences
noted around where run_collector handles per-collector results).
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6e0f21cd-e4d0-4301-8df4-aea2e8dca3e0

📥 Commits

Reviewing files that changed from the base of the PR and between bd11af1 and 7de4571.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock and included by **/*
📒 Files selected for processing (74)
  • .github/workflows/ci.yml
  • AGENTS.md
  • AGENTS.md
  • CHANGELOG.md
  • CLAUDE.md
  • Cargo.toml
  • README.md
  • config/mcporter.json
  • deny.toml
  • docs/CLI.md
  • docs/CONFIG.md
  • docs/INVENTORY.md
  • docs/OAUTH.md
  • docs/README.md
  • docs/RELEASE.md
  • docs/RUST.md
  • docs/SECURITY.md
  • docs/contracts/mcp-actions-current.md
  • docs/mcp/CONNECT.md
  • docs/mcp/DEPLOY.md
  • docs/mcp/DEV.md
  • docs/mcp/ELICITATION.md
  • docs/mcp/MCPORTER.md
  • docs/mcp/PATTERNS.md
  • docs/mcp/PUBLISH.md
  • docs/mcp/SCHEMA.md
  • docs/mcp/TESTS.md
  • docs/mcp/TOOLS.md
  • docs/mcp/TRANSPORT.md
  • docs/mcp/WEBMCP.md
  • docs/plugin/AGENTS.md
  • docs/plugin/AGENTS.md
  • docs/plugin/CLAUDE.md
  • docs/plugin/HOOKS.md
  • docs/plugin/MARKETPLACES.md
  • docs/plugin/PLUGINS.md
  • docs/plugin/SKILLS.md
  • docs/repo/SCRIPTS.md
  • docs/runbooks/deploy.md
  • mcpb/manifest.json
  • scripts/check-agent-memory-symlinks.sh
  • scripts/check-plugin-manifest-versions.sh
  • scripts/check-public-identity.sh
  • server.json
  • src/app/models/ai_incidents.rs
  • src/app/models/ai_sessions.rs
  • src/app/models/context.rs
  • src/app/models/ops.rs
  • src/app/models/stats.rs
  • src/app/services/analytics.rs
  • src/db.rs
  • src/db/analytics.rs
  • src/db/graph_inventory.rs
  • src/db/graph_inventory/sql.rs
  • src/db/graph_inventory_tests.rs
  • src/db/queries.rs
  • src/db/queries_tests.rs
  • src/deploy.rs
  • src/inventory.rs
  • src/inventory/orchestrator.rs
  • src/inventory/orchestrator_tests.rs
  • src/inventory/raw_configs.rs
  • src/inventory/remote_configs.rs
  • src/inventory/remote_device.rs
  • src/inventory/remote_docker.rs
  • src/inventory/ssh.rs
  • src/inventory/ssh_tests.rs
  • src/mcp/actions.rs
  • src/mcp/rmcp_server.rs
  • src/mcp/rmcp_server_tests.rs
  • src/mcp/tools.rs
  • src/mcp/tools_tests.rs
  • src/runtime/inventory_refresh.rs
  • src/runtime/inventory_refresh_tests.rs

Comment thread deny.toml Outdated
Comment thread docs/plugin/HOOKS.md
Comment thread docs/plugin/SKILLS.md
Comment thread scripts/check-plugin-manifest-versions.sh Outdated
Comment thread src/app/services/analytics.rs Outdated
Comment thread src/db/graph_inventory.rs
Comment thread src/deploy.rs Outdated
Comment thread src/runtime/inventory_refresh.rs Outdated
@jmagar

jmagar commented Jun 7, 2026

Copy link
Copy Markdown
Collaborator Author

Review Toolkit follow-up pushed to codex/cortex-review-24-fixes.

Commits:

  • 5fb969d51f8bb708cfe6b53dff0adf7db6d1b64a — main Review Toolkit fixes
  • 8c25f0be77d9053231d0e23ba7a409292ad3bb0f — portable public-identity check fallback for CI runners without rg

Findings addressed:

  1. Remote Docker event stream failures now capture bounded stdout/stderr/status, warn on first failure plus rate-limited repeats, and expose degradation through runtime observability.
  2. SSH host discovery now returns warnings for rejected unsafe hosts and unreadable ssh config, and collectors surface partial/degraded output when explicit hosts are all rejected.
  3. Public identity scan now derives current tracked files, covers current docs/manifests/scripts/plugin config, excludes archival paths explicitly, treats search errors as fatal, and falls back to grep when rg is unavailable.
  4. Plugin manifest version check now separates JSON parse validation from version-policy validation; invalid JSON fails.
  5. Stale docs/SETUP.md JSON-RPC tool name changed from syslog to cortex, and identity checks catch that current-doc pattern.
  6. Deploy/inventory SSH docs and changelog wording now distinguish shared inventory/event-stream safeguards from deploy-specific host validation and argv policy.
  7. Plugin hook docs now use ${CLAUDE_PLUGIN_ROOT}/bin/cortex setup plugin-hook, with scripts/plugin-setup.sh described only as the thin/manual legacy adapter.
  8. Stale skill paths updated to plugins/cortex/skills/<skill>/.
  9. docs/CHECKLIST.md was updated to current release/version policy instead of remaining stale while classified as authoritative.
  10. Operator deployment links now point to docs/RELEASE.md instead of archival runbook guidance.
  11. docs/RELEASE.md now includes bash scripts/check-public-identity.sh and git diff --check in hermetic gates.
  12. Removed the redundant ActionHandler/handler_for dispatch list while keeping ACTION_SPECS metadata and drift tests.
  13. Extracted shared MCP action sample helpers and reused them for schema dispatch and unknown-field tests.
  14. Removed legacy SSH run wrappers; production collectors use SshContext::run, while the only raw argv path is documented on SshContext for long-lived streaming/deploy processes.
  15. Removed the test-only patterns(...) compatibility wrapper; tests call fetch_pattern_rows and cluster_pattern_rows directly.
  16. Removed stale action metadata dead-code/comment wrappers and duplicate rmcp server wrapper docs.
  17. Graph target resolution now enforces exactly one lookup strategy (entity_id, canonical key, or alias) with invalid mixes rejected as InvalidInput.
  18. graph around now rejects unsupported depth, including depth=0, instead of reporting misleading metadata.
  19. MCP schema/tests now constrain graph targets, graph depth, typed unknown fields, and pattern scan limit to match runtime behavior.
  20. patterns.scan_limit uses shared PATTERN_SCAN_LIMIT_MAX = 10000 across runtime, schema, docs, and tests.
  21. SshOptions fields are private with checked builders for timeout/concurrency/retry values; zero timeout cannot be emitted.
  22. SSH retry backoff now includes bounded host-keyed jitter with tests.
  23. Added cancellation coverage for SSH limiter waits and remote Docker event task cancellation.
  24. Unknown-field coverage now spans all typed action_payload actions plus graph modes entity, around, explain, and evidence.
  25. Added SQL limit binding coverage for tail_logs, get_error_summary, and fetch_pattern_rows.

Local verification on final head:

  • cargo fmt -- --check
  • cargo test
  • cargo clippy --all-targets -- -D warnings
  • cargo deny check
  • bash scripts/check-version-sync.sh --require-changelog
  • bash scripts/check-agent-memory-symlinks.sh
  • bash scripts/check-plugin-manifest-versions.sh
  • bash scripts/check-public-identity.sh
  • PATH=/usr/bin:/bin bash scripts/check-public-identity.sh
  • git diff --check origin/main...HEAD

PR status after push:

  • Head: 8c25f0be77d9053231d0e23ba7a409292ad3bb0f
  • GitHub check runs: Version Sync, Formatting, Clippy, Tests, cargo-deny, Secret Scan, Codex Plugin scan, Pre-publish CI gate, build-and-push, and MCP Integration Tests all ✅
  • External CodeRabbit status was still pending on last poll.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
CHANGELOG.md (1)

10-10: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update release compare links to include 1.14.2.

Line 10 adds 1.14.2, but the footer still points [Unreleased] to v1.14.0...HEAD and is missing 1.14.2 / 1.14.1 link definitions, so release navigation is stale.

♻️ Suggested update
-[Unreleased]: https://github.com/jmagar/cortex/compare/v1.14.0...HEAD
+[Unreleased]: https://github.com/jmagar/cortex/compare/v1.14.2...HEAD
+[1.14.2]: https://github.com/jmagar/cortex/compare/v1.14.1...v1.14.2
+[1.14.1]: https://github.com/jmagar/cortex/compare/v1.14.0...v1.14.1
 [1.14.0]: https://github.com/jmagar/cortex/compare/v1.13.3...v1.14.0
🤖 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 `@CHANGELOG.md` at line 10, The footer link definitions are stale after adding
the header "## [1.14.2] - 2026-06-07": update the release compare links so
[Unreleased] points to v1.14.2...HEAD (not v1.14.0...HEAD) and add link
definitions for [1.14.2] and [1.14.1] with the correct GitHub compare ranges
(e.g. v1.14.1...v1.14.2 and v1.14.0...v1.14.1 or your repo's equivalent tags),
ensuring the labels in the footer match the header "[1.14.2] - 2026-06-07" and
previous release names.
docs/plugin/CONFIG.md (1)

34-34: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Clarify the duplicated CORTEX_* / CORTEX_* reference.

The phrase "exports current Claude Code userConfig values as CORTEX_* / CORTEX_* environment variables" contains unclear duplication. Line 41 refers only to "CORTEX_* overrides" without the slash-separated repetition. If both fragments refer to the same variable pattern, remove the duplication; if they represent distinct sets, clarify the distinction.

🤖 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 `@docs/plugin/CONFIG.md` at line 34, The sentence that says "exports current
Claude Code `userConfig` values as `CORTEX_*` / `CORTEX_*` environment
variables" is ambiguous due to the duplicated `CORTEX_*` reference; update the
docs text so it clearly states whether a single pattern (`CORTEX_*`) is used or
two distinct patterns are meant. Locate the phrase referencing `userConfig` and
`CORTEX_*` in CONFIG.md and either remove the duplicate slash form to read
"exports current Claude Code `userConfig` values as `CORTEX_*` environment
variables" or replace one side of the slash with the correct distinct pattern
(and ensure consistency with the later "CORTEX_* overrides" mention). Ensure the
final wording matches the actual variable pattern used by the codebase.
docs/plugin/HOOKS.md (1)

34-34: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Clarify the duplicated CORTEX_* / CORTEX_* reference.

The phrase "exports current Claude Code userConfig values as CORTEX_* / CORTEX_* environment variables" contains the same unclear duplication found in CONFIG.md. Consider removing the repetition or clarifying if the slash represents two distinct variable sets.

🤖 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 `@docs/plugin/HOOKS.md` at line 34, The sentence in HOOKS.md that reads
"exports current Claude Code `userConfig` values as `CORTEX_*` / `CORTEX_*`
environment variables" duplicates the same token and is unclear; edit that line
to either remove the repeated `CORTEX_*` so it reads "as `CORTEX_*` environment
variables" or explicitly clarify what the slash means (e.g., "`CORTEX_*`
(build-time) / `CORTEX_*` (runtime)" or list the two distinct variable
prefixes), updating the phrase that references `userConfig` to match the chosen
wording so the intent is unambiguous.
src/mcp/tools_tests.rs (1)

594-611: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Consider tightening the assertion to verify action name in error.

The test verifies that type mismatches produce errors containing "invalid " and either "invalid type" or "invalid value", but doesn't verify that the action name appears in the error message. Since action_payload at line 431 in tools.rs produces errors in the format "invalid {action} arguments: {err}", you could strengthen this assertion to also check for the action name.

♻️ Optional: stricter assertion
+        let action = args["action"].as_str().unwrap();
         let err = execute_tool(&h.state, "cortex", args, None)
             .await
             .unwrap_err();
         assert!(
-            err.to_string().contains("invalid ")
+            err.to_string().contains(&format!("invalid {action} arguments"))
                 && (err.to_string().contains("invalid type")
                     || err.to_string().contains("invalid value"))
         );
🤖 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/tools_tests.rs` around lines 594 - 611, The test
numeric_args_reject_wrong_type_values should also assert that the error message
includes the tool action name emitted by action_payload; update the loop so
after calling execute_tool and obtaining err you extract the action string from
args (e.g. args["action"]) and assert err.to_string() contains format!("invalid
{} arguments", action) in addition to the existing invalid/type checks, ensuring
the error includes the specific action name produced by action_payload.
♻️ Duplicate comments (2)
src/runtime/inventory_refresh.rs (1)

293-346: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Long-lived event streams still exhaust the SSH semaphore.

The permit acquired at Line 293 is held until the function returns (Line 346), which doesn't happen until the docker events stream exits (Line 333). For stable fleets, long-running event streams hold permits indefinitely, exhausting the max_concurrent limit and silently blocking additional hosts from starting their event streams.

🔧 Recommended fix

Drop the permit immediately after spawning the SSH child, before entering the line-reading loop:

 async fn run_remote_docker_events_once(
     host: &str,
     ssh_context: &crate::inventory::ssh::SshContext,
     trigger: mpsc::Sender<()>,
     token: CancellationToken,
 ) -> anyhow::Result<()> {
-    let Some(_permit) = ssh_context.acquire_owned_cancellable(&token).await? else {
+    let Some(permit) = ssh_context.acquire_owned_cancellable(&token).await? else {
         return Ok(());
     };
     let args = remote_docker_events_ssh_args(ssh_context, host)?;
     let mut child = Command::new("ssh")
         .args(args)
         .stdin(Stdio::null())
         .stdout(Stdio::piped())
         .stderr(Stdio::piped())
         .kill_on_drop(true)
         .spawn()?;
+    drop(permit);  // Release concurrency slot now that SSH is started
     let stdout = child
🤖 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/runtime/inventory_refresh.rs` around lines 293 - 346, The SSH permit
acquired via ssh_context.acquire_owned_cancellable (bound to _permit) is held
for the whole function and blocks other hosts; after spawning the SSH child
(Command::new("ssh")...spawn()) and starting the stderr_task, explicitly drop
the permit (drop(_permit) or move acquisition into a smaller scope) so the
semaphore is released before entering the line-reading loop, while keeping the
rest of the logic (lines loop, token.cancelled handling, child.kill, stderr_task
abort) unchanged.
src/deploy.rs (1)

474-669: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Move all inline deploy tests to a sidecar deploy_tests.rs module.

The inline test module (lines 474-669) violates the repository coding guideline requiring unit tests to live in sidecar *_tests.rs files with only a #[cfg(test)] #[path = "deploy_tests.rs"] mod tests; hook remaining in the source file. This pattern is established in other modules (ssh.rs, remote_configs.rs, remote_device.rs, remote_docker.rs). All test functions—including the newly added remote_deploy_rejects_option_like_hosts_before_running_ssh and remote_deploy_accepts_safe_hosts—should be moved to deploy_tests.rs with use super::*; to access the module under test.

As per coding guidelines, **/*_tests.rs: Unit tests live in sidecar files beside their source modules with source files containing only #[cfg(test)] #[path = "..._tests.rs"] mod tests; hook.

🤖 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/deploy.rs` around lines 474 - 669, Move the entire #[cfg(test)] mod tests
block out of src/deploy.rs into a new sidecar file named deploy_tests.rs and
leave only a hook in deploy.rs: #[cfg(test)] #[path = "deploy_tests.rs"] mod
tests;; in the new deploy_tests.rs keep use super::*; and preserve all test
items (FakeRemoteRunner, its impl RemoteRunner, and tests like
remote_dry_run_only_checks_ssh_and_docker,
remote_repair_writes_assets_before_compose_up,
remote_env_uses_remote_uid_and_gid,
remote_deploy_skips_mutations_after_identity_failure,
remote_deploy_reports_identity_spawn_error_as_phase_failure,
remote_deploy_does_not_source_env_as_shell,
remote_deploy_rejects_option_like_hosts_before_running_ssh,
remote_deploy_accepts_safe_hosts) unchanged so they continue to reference
run_remote_deploy_with_runner and other symbols from the parent module.

Source: Coding guidelines

🤖 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 `@docs/plugin/HOOKS.md`:
- Around line 64-66: The docs show a literal command `plugins/cortex/bin/cortex
setup plugin-hook` that can mismatch the hook definition using
`${CLAUDE_PLUGIN_ROOT}/bin/cortex setup plugin-hook`; update the example to use
the environment variable consistently (i.e. `${CLAUDE_PLUGIN_ROOT}/bin/cortex
setup plugin-hook`) or add a short note instructing users to export
`CLAUDE_PLUGIN_ROOT` to the correct path before running the manual command;
reference the symbols CLAUDE_PLUGIN_ROOT and the setup command to make the
change clear.

---

Outside diff comments:
In `@CHANGELOG.md`:
- Line 10: The footer link definitions are stale after adding the header "##
[1.14.2] - 2026-06-07": update the release compare links so [Unreleased] points
to v1.14.2...HEAD (not v1.14.0...HEAD) and add link definitions for [1.14.2] and
[1.14.1] with the correct GitHub compare ranges (e.g. v1.14.1...v1.14.2 and
v1.14.0...v1.14.1 or your repo's equivalent tags), ensuring the labels in the
footer match the header "[1.14.2] - 2026-06-07" and previous release names.

In `@docs/plugin/CONFIG.md`:
- Line 34: The sentence that says "exports current Claude Code `userConfig`
values as `CORTEX_*` / `CORTEX_*` environment variables" is ambiguous due to the
duplicated `CORTEX_*` reference; update the docs text so it clearly states
whether a single pattern (`CORTEX_*`) is used or two distinct patterns are
meant. Locate the phrase referencing `userConfig` and `CORTEX_*` in CONFIG.md
and either remove the duplicate slash form to read "exports current Claude Code
`userConfig` values as `CORTEX_*` environment variables" or replace one side of
the slash with the correct distinct pattern (and ensure consistency with the
later "CORTEX_* overrides" mention). Ensure the final wording matches the actual
variable pattern used by the codebase.

In `@docs/plugin/HOOKS.md`:
- Line 34: The sentence in HOOKS.md that reads "exports current Claude Code
`userConfig` values as `CORTEX_*` / `CORTEX_*` environment variables" duplicates
the same token and is unclear; edit that line to either remove the repeated
`CORTEX_*` so it reads "as `CORTEX_*` environment variables" or explicitly
clarify what the slash means (e.g., "`CORTEX_*` (build-time) / `CORTEX_*`
(runtime)" or list the two distinct variable prefixes), updating the phrase that
references `userConfig` to match the chosen wording so the intent is
unambiguous.

In `@src/mcp/tools_tests.rs`:
- Around line 594-611: The test numeric_args_reject_wrong_type_values should
also assert that the error message includes the tool action name emitted by
action_payload; update the loop so after calling execute_tool and obtaining err
you extract the action string from args (e.g. args["action"]) and assert
err.to_string() contains format!("invalid {} arguments", action) in addition to
the existing invalid/type checks, ensuring the error includes the specific
action name produced by action_payload.

---

Duplicate comments:
In `@src/deploy.rs`:
- Around line 474-669: Move the entire #[cfg(test)] mod tests block out of
src/deploy.rs into a new sidecar file named deploy_tests.rs and leave only a
hook in deploy.rs: #[cfg(test)] #[path = "deploy_tests.rs"] mod tests;; in the
new deploy_tests.rs keep use super::*; and preserve all test items
(FakeRemoteRunner, its impl RemoteRunner, and tests like
remote_dry_run_only_checks_ssh_and_docker,
remote_repair_writes_assets_before_compose_up,
remote_env_uses_remote_uid_and_gid,
remote_deploy_skips_mutations_after_identity_failure,
remote_deploy_reports_identity_spawn_error_as_phase_failure,
remote_deploy_does_not_source_env_as_shell,
remote_deploy_rejects_option_like_hosts_before_running_ssh,
remote_deploy_accepts_safe_hosts) unchanged so they continue to reference
run_remote_deploy_with_runner and other symbols from the parent module.

In `@src/runtime/inventory_refresh.rs`:
- Around line 293-346: The SSH permit acquired via
ssh_context.acquire_owned_cancellable (bound to _permit) is held for the whole
function and blocks other hosts; after spawning the SSH child
(Command::new("ssh")...spawn()) and starting the stderr_task, explicitly drop
the permit (drop(_permit) or move acquisition into a smaller scope) so the
semaphore is released before entering the line-reading loop, while keeping the
rest of the logic (lines loop, token.cancelled handling, child.kill, stderr_task
abort) unchanged.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 30446e3a-da7c-43ff-be3c-0c115309e168

📥 Commits

Reviewing files that changed from the base of the PR and between 7de4571 and 8c25f0b.

📒 Files selected for processing (50)
  • CHANGELOG.md
  • CLAUDE.md
  • README.md
  • docs/CHECKLIST.md
  • docs/CONFIG.md
  • docs/INVENTORY.md
  • docs/README.md
  • docs/RELEASE.md
  • docs/SECURITY.md
  • docs/SETUP.md
  • docs/mcp/SCHEMA.md
  • docs/plugin/CLAUDE.md
  • docs/plugin/CONFIG.md
  • docs/plugin/HOOKS.md
  • docs/plugin/SKILLS.md
  • docs/repo/SCRIPTS.md
  • plugins/cortex/skills/cortex-redeploy/SKILL.md
  • scripts/check-plugin-manifest-versions.sh
  • scripts/check-public-identity.sh
  • scripts/smoke-test.sh
  • scripts/validate-marketplace.sh
  • src/app/models/graph.rs
  • src/app/service_tests.rs
  • src/app/services/analytics.rs
  • src/app/services/graph.rs
  • src/app/services/graph_limits.rs
  • src/cli/dispatch_surface_gap.rs
  • src/cli/dispatch_tests.rs
  • src/db.rs
  • src/db/analytics.rs
  • src/db/analytics_tests.rs
  • src/db/queries.rs
  • src/db/queries_tests.rs
  • src/deploy.rs
  • src/inventory/remote_configs.rs
  • src/inventory/remote_device.rs
  • src/inventory/remote_docker.rs
  • src/inventory/ssh.rs
  • src/inventory/ssh_tests.rs
  • src/mcp/actions.rs
  • src/mcp/rmcp_server.rs
  • src/mcp/schemas.rs
  • src/mcp/schemas_tests.rs
  • src/mcp/tools.rs
  • src/mcp/tools_tests.rs
  • src/observability.rs
  • src/runtime.rs
  • src/runtime/inventory_refresh.rs
  • src/runtime/inventory_refresh_tests.rs
  • tests/test_live.sh
💤 Files with no reviewable changes (1)
  • src/mcp/rmcp_server.rs

Comment thread docs/plugin/HOOKS.md
@jmagar

jmagar commented Jun 7, 2026

Copy link
Copy Markdown
Collaborator Author

Final lavra-review fixes pushed in 74ed4397aacba5dcc164d89ee773ffb6d1eb301f.

Addressed findings:

  • P2 collector timeout status: per-collector deadline timeouts now emit collection_timeout, so run_collector classifies them as skipped. Added regression collector_deadline_timeout_is_reported_as_skipped.
  • P2 MCP dispatch drift: ActionSpec now owns an ActionHandler, handler_for(action) resolves dispatch through the registry, and tool_cortex dispatches via that handler. Added registry coverage assertion for every ACTION_SPECS row.
  • P3 stale SWAG docs/check: deploy/guardrail docs now point at /config/nginx/proxy-confs/cortex.subdomain.conf; check-public-identity.sh now scans for docs/syslog.subdomain.conf and syslog.subdomain.conf drift.
  • P3 reverse-proxy upstream matching: upstream token filtering now rejects only exact http/https scheme tokens, preserving service names like http-api. Added a graph projection regression for http://http-api:8080 routing.

Local verification passed:

  • cargo fmt -- --check
  • cargo test
  • cargo clippy --all-targets -- -D warnings
  • cargo deny check
  • bash scripts/check-version-sync.sh --require-changelog
  • bash scripts/check-agent-memory-symlinks.sh
  • bash scripts/check-plugin-manifest-versions.sh
  • bash scripts/check-public-identity.sh
  • git diff --check origin/main...HEAD

Push verification:

  • git pull --rebase reported the branch was up to date.
  • bd dolt push completed.
  • git push origin codex/cortex-review-24-fixes completed; pre-push test hook passed.
  • gh pr view 70 --repo jmagar/cortex --json statusCheckRollup,headRefOid,url reported head 74ed4397aacba5dcc164d89ee773ffb6d1eb301f. At that check, newly-triggered GitHub checks were still in progress/pending, while GitGuardian and the Codex plugin scan were already successful.

Resolves review thread PRRT_kwDORy0Fc86HsTI8

Resolves review thread PRRT_kwDORy0Fc86HsjPT

Resolves review thread PRRT_kwDORy0Fc86HsTI_

Resolves review thread PRRT_kwDORy0Fc86HsTJB

Resolves review thread PRRT_kwDORy0Fc86HsTJE

Resolves review thread PRRT_kwDORy0Fc86HsTJF
@jmagar
jmagar merged commit adc85a7 into main Jun 8, 2026
13 checks passed
@jmagar
jmagar deleted the codex/cortex-review-24-fixes branch June 8, 2026 00:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Comprehensive full review findings: 24 issues from fresh repo-wide pass

1 participant