Skip to content

Security hardening: MarketPulse validation, safer JSON IPC, git-only deps - #8

Merged
rmems merged 16 commits into
mainfrom
security/hardening-marketpulse-ipc
Aug 2, 2026
Merged

Security hardening: MarketPulse validation, safer JSON IPC, git-only deps#8
rmems merged 16 commits into
mainfrom
security/hardening-marketpulse-ipc

Conversation

@rmems

@rmems rmems commented Jul 31, 2026

Copy link
Copy Markdown
Owner

User description

Summary

First hardening PR for residual findings from the pre-push security audit.

Test plan

  • cd execution && cargo test (19 tests pass)
  • julia --project=brain test/runtests.jl (all Capital unit tests pass)
  • Builds without ../Limen-Neural on the dependency path

Closes #1
Closes #2
Closes #3
Closes #6

Leaves open: #4 (ZAP allowlist), #5 (confidence docs), #7 (crate rename).


Summary by cubic

Hardens market/readout validation and isolates JSON IPC with lifetime owner-locks, safer defaults, and stricter endpoint checks. Owns wire types in-tree and pins Limen‑Neural deps by git rev; CI sticks to Rust 1.97.1 and Julia 1.12; Kelly sizing fails closed.

  • New Features

    • Validate MarketPulse/ReadoutPacket: reject NaN/Inf and non‑positive prices; clamp vols to [0, 1]; relevance in [0, 1] and sum ~1 (±0.05) with inclusive bounds; fail closed on overflowed scores; tests updated; spike_helm only advances the tick after a successful decode.
    • Safer JSON IPC: require ipc:// + absolute path with no ..; default to $XDG_RUNTIME_DIR/limen-capital/signals.ipc or /tmp/limen-capital-$UID/signals.ipc; secure dir (0700, owner UID, no symlink); hold exclusive *.owner.lock via flock(LOCK_EX|NB) for the process lifetime; do not unlink lock files on release; open locks with O_CLOEXEC|O_NOFOLLOW (portable O_CREAT); release lock and clean up ZMQ on constructor failures; lazy default endpoint; only unlink stale Unix sockets; never replace a live socket unless REPLACE=1.
    • Kelly sizing: clamp to 0..=1; return 0 on invalid p/b or non‑finite values; tests added.
    • CI: pinned actions; Rust 1.97.1 fmt + clippy -D warnings + tests (all features; skip live dYdX); Julia 1.12 CPU tests; integration gate enforces git URLs with 40‑char rev pins (scoped to [dependencies]).
  • Dependencies

    • Git pins: metabolic-ledger (required) plus optional kinetic-signals/neuromod by fixed rev; drop corpus-ipc; own MarketPulse/ReadoutPacket in execution/src/binary_wire.rs.
    • Julia [sources] pin LiquidCortex and TemporalFocus by url + rev; [compat] julia = "1.12".

Written for commit 8ea80ec. Summary will update on new commits.

Review in cubic


CodeAnt-AI Description

Harden market data validation, isolate JSON IPC, and remove local dependency checkout requirements

What Changed

  • Invalid MarketPulse and ReadoutPacket data is rejected before processing when it contains non-finite values; non-positive prices and unsafe trade calculations fail closed.
  • Market volumes are limited to the valid 0–1 range, while malformed market frames no longer advance the brain’s processing tick.
  • JSON trade signals now use user-scoped IPC paths under $XDG_RUNTIME_DIR or /tmp, with validated LIMEN_JSON_IPC overrides and no automatic replacement of active sockets.
  • Rust wire types are maintained in the application, and Limen-Neural dependencies resolve from pinned git revisions instead of required sibling checkouts.
  • Added coverage for malformed packets, overflow-safe trade mapping, Kelly input handling, IPC path validation, and automated Rust/Julia CI checks.

Impact

✅ Fewer malformed market frames reaching trading logic
✅ Safer multi-user JSON signal IPC
✅ No sibling dependency checkout required

💡 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:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

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:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

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.

rmems added 2 commits July 31, 2026 09:47
- Pin metabolic-ledger (and optional kinetic/neuromod) by git rev; drop path clones
- Own MarketPulse/ReadoutPacket in-tree (corpus-ipc public main lacks binary_wire)
- Reject non-finite/non-positive MarketPulse prices; soft-clamp vols to [0,1]
- Default JSON IPC under XDG_RUNTIME_DIR or /tmp/limen-capital-$USER (LIMEN_JSON_IPC)
- Add docs/SECURITY.md loopback threat model; refresh deps/PRE_PUSH/README

Closes #1 #2 #3 #6
@codeant-ai

codeant-ai Bot commented Jul 31, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Incremental review completed 8f4d8f5 Aug 01, 2026 · 07:19 07:19
✅ Reviewed your PR b2bd310 Jul 31, 2026 · 14:52 14:55

@codeant-ai

codeant-ai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai codeant-ai Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files label Jul 31, 2026
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added validated binary market-data and trade-signal formats.
    • Added configurable, user-scoped JSON IPC endpoints with safer permissions.
    • Added automated Git, secret-scanning, issue-tracking, and continuous-integration workflows.
    • Added Beads issue-management configuration and guidance.
  • Bug Fixes

    • Invalid market data is rejected, with supported volumes safely clamped.
    • Invalid frames no longer stop processing.
    • Risk calculations now fail safely for invalid inputs.
  • Documentation

    • Added security, setup, protocol, and collaboration guidance.
    • Updated dependency and endpoint configuration instructions.

Walkthrough

The change adds in-tree wire contracts, MarketPulse validation, scoped JSON IPC, pinned dependencies, security guidance, CI, and Beads repository automation.

Changes

Runtime and dependency integration

Layer / File(s) Summary
Binary wire contracts and validation
execution/src/binary_wire.rs, brain/market_types.jl, brain/spike_helm.jl, execution/src/kelly.rs, brain/test/*
Adds fixed-size packet encoding, decoding, trade mapping, finite-value checks, price checks, volume clamping, and Kelly input validation.
User-scoped JSON IPC
strategy/signal_broadcaster.jl, execution/src/wire.rs, execution/src/main.rs, docs/wire-protocol-v1.md, wire/README.md
Resolves IPC endpoints from LIMEN_JSON_IPC, runtime directories, or UID-scoped /tmp paths. It validates paths and manages endpoint ownership.
Pinned dependency resolution
execution/Cargo.toml, brain/Project.toml, brain/adapters.jl, brain/reservoir.jl, README.md, docs/deps.md, docs/PRE_PUSH.md, test_integration.sh
Replaces sibling checkouts with pinned Git revisions and package-based loading.
Security operating guidance
docs/SECURITY.md
Documents trust assumptions, CURVE configuration, IPC isolation, residual risks, and reporting procedures.
Runtime cleanup
execution/src/dydx.rs, execution/src/bin/*, execution/src/lib.rs
Adds default constructors, warning-suppression attributes, and small API or formatting updates.

Beads repository workflow

Layer / File(s) Summary
Beads configuration and local state
.beads/*, .gitignore
Adds Beads configuration and ignores local database, runtime, credential, backup, and server artifacts.
Git hook execution
.beads/hooks/*
Runs Git LFS, Aikido, and Beads hooks with timeout and failure handling.
Agent workflow integration
AGENTS.md, CLAUDE.md, .claude/settings.json, .beads/README.md
Adds Beads commands, non-interactive workflow rules, session completion requirements, and Claude hooks.

Continuous integration

Layer / File(s) Summary
Pinned CI checks
.github/workflows/ci.yml
Adds Rust formatting, linting, builds, tests, Julia 1.12 tests, and an integration structure gate.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

  • rmems/xai-dissect#33 — The new workflow also adds automated Rust validation through GitHub Actions.

Poem

A rabbit packs the wire just right,
Safe sockets hide from shared-host night.
Bad floats stop at the gate,
Pinned paths keep builds straight.
Beads record each burrowed step.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning Objectives #1 and #2 are addressed, but #3 lacks clear README linkage and #6 removes the required corpus-ipc dependency instead of pinning it. Link docs/SECURITY.md from README and retain corpus-ipc as a pinned git dependency, or update issue #6 to reflect the changed requirement.
Out of Scope Changes check ⚠️ Warning The PR adds extensive Beads metadata, hooks, agent instructions, Claude settings, and unrelated workflow changes beyond linked issues #1, #2, #3, and #6. Remove unrelated Beads and agent-management files, and separate Kelly, CI, and other independent changes into focused pull requests.
✅ Passed checks (3 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Title check ✅ Passed The title clearly summarizes the PR's primary security, validation, IPC, and dependency changes.
Description check ✅ Passed The description directly explains the validation, IPC security, dependency, documentation, and testing changes.
✨ 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 security/hardening-marketpulse-ipc

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread .beads/hooks/pre-commit Outdated
Comment thread .beads/hooks/pre-commit Outdated

@amazon-q-developer amazon-q-developer 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.

Security Hardening Review

This PR implements important security improvements for MarketPulse validation and IPC path handling. The changes move in the right direction, but several critical security vulnerabilities and validation gaps must be addressed before merge.

Critical Issues Found (7)

Security Vulnerabilities (3):

  1. MarketPulse::decode in binary_wire.rs bypasses validation - defense-in-depth failure
  2. LIMEN_JSON_IPC environment variable lacks path traversal validation (both Rust and Julia)
  3. Missing validation for ReadoutPacket float arrays (NaN/Inf)

Crash Risks (1):
4. Silent failure on IPC directory creation could cause confusing bind errors

Data Integrity (2):
5. Non-price MarketPulse fields not validated for finite values in Julia
6. Validation order inconsistency between Julia and Rust implementations

Required Actions

All identified issues must be resolved before merge:

  • Add validation directly in MarketPulse::decode (not just wrapper)
  • Validate LIMEN_JSON_IPC to prevent path traversal attacks
  • Add finite checks for all MarketPulse signal fields
  • Add finite checks for ReadoutPacket arrays
  • Surface directory creation failures with clear errors
  • Align validation order between Julia and Rust

The core security approach is sound, but these gaps could allow malformed data or malicious paths to compromise system integrity.


You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.


⚠️ This PR contains more than 30 files. Amazon Q is better at reviewing smaller PRs, and may miss issues in larger changesets.

Comment thread execution/src/binary_wire.rs
Comment thread execution/src/wire.rs Outdated
Comment thread execution/src/wire.rs Outdated
Comment thread brain/market_types.jl
Comment thread execution/src/wire.rs Outdated
Comment thread strategy/signal_broadcaster.jl Outdated
Comment thread execution/src/binary_wire.rs
Comment thread .beads/hooks/post-checkout Outdated
Comment thread .beads/hooks/post-checkout Outdated
Comment thread execution/src/binary_wire.rs
Comment thread execution/src/wire.rs Outdated
Comment thread brain/market_types.jl
Comment thread brain/test/runtests.jl
Comment thread strategy/signal_broadcaster.jl Outdated
Comment thread strategy/signal_broadcaster.jl Outdated

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b2bd3104a1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread brain/market_types.jl Outdated
Comment thread README.md
Comment thread .beads/hooks/pre-commit Outdated
Comment thread brain/Project.toml
Comment thread execution/src/binary_wire.rs

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 33 files

Tip: instead of fixing issues one by one fix them all with cubic

Re-trigger cubic

Comment thread .beads/hooks/pre-push Outdated
Comment thread .beads/hooks/pre-commit Outdated
Comment thread execution/src/main.rs Outdated
Comment thread brain/Project.toml
Comment thread execution/Cargo.toml
Comment thread docs/wire-protocol-v1.md
Comment thread .beads/hooks/post-checkout
Comment thread docs/deps.md Outdated
Comment thread execution/src/wire.rs Outdated
Comment thread brain/market_types.jl Outdated

@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: 23

🤖 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 @.beads/config.yaml:
- Around line 11-13: Update the configuration template near the no-db setting to
remove the `no-db` option or explicitly mark it unsupported, ensuring users
cannot configure JSONL-only mode and that the local Dolt database remains the
sole issue source.
- Around line 47-55: Update the secret-key documentation in the Integration
settings comment to require linear.api_key from LINEAR_API_KEY and github.token
from GITHUB_TOKEN only. Remove any wording that permits or describes storing
these secrets in the tracked config file, and explicitly state they must not be
stored there.

In @.beads/hooks/pre-commit:
- Around line 3-5: Update the pre-commit hook’s scanner invocation to resolve
aikido-local-scanner from a documented environment variable or PATH instead of
the hard-coded /home/raulmc/.local/bin path. Preserve the existing fail-fast
validation and error message behavior when the scanner cannot be found, and
continue passing REPO_ROOT to the pre-commit-scan command.

In @.beads/README.md:
- Around line 29-30: Update the “Sync with Dolt remote” workflow in the README
to run `bd dolt pull` before `bd dolt push`, documenting bidirectional
synchronization while preserving the existing publish step.
- Around line 63-64: Replace the mutable main-branch installer command in the
Beads installation instructions with a versioned release download, and add
checksum or signature verification before executing the script. Update the
installation flow in the “Install Beads” section so the remote content is never
piped directly into bash.

In @.gitignore:
- Around line 39-43: Update the Beads/Dolt ignore entries in the root .gitignore
by removing the global *.db pattern and replacing it with a pattern scoped to
the .beads/ directory. Preserve the existing .dolt/ and .beads-credential-key
entries.

In `@AGENTS.md`:
- Around line 32-42: Surround each affected Markdown fenced shell block with
blank lines to satisfy MD031: add spacing before and after the non-interactive
shell block in AGENTS.md lines 32-42, the mandatory Git block in AGENTS.md lines
81-88, and the mandatory Git block in CLAUDE.md lines 36-42; do not alter the
commands or prose.
- Around line 78-86: Update the mandatory session-close workflows in AGENTS.md
lines 78-86 and CLAUDE.md lines 33-41 to include bd dolt pull before issue work
and bd dolt push afterward, using the local Dolt database as the source of
truth. Ensure both workflows verify Dolt synchronization before the final git
pull --rebase and git push sequence.

In `@brain/market_types.jl`:
- Around line 38-44: Update the docstring for validate_market_pulse_fields to
remove the mutation marker and state that it returns a new validated vector.
Keep the existing validation behavior and function signature unchanged.

In `@brain/Project.toml`:
- Around line 21-23: The code uses the [sources] dependency feature which
requires Julia 1.11+, but the current documentation states Julia 1.10+
compatibility. Update the minimum Julia version requirement in two places:
brain/Project.toml at line 27 where the version constraint is specified, and
README.md at line 65 where the documentation states the minimum version. Change
both from Julia 1.10 to Julia 1.11+ to align with the [sources] block introduced
in brain/Project.toml lines 21-23. If Julia 1.10 compatibility must be
maintained instead, remove the [sources] section entirely and use a Julia
1.10-compatible dependency workflow.

In `@brain/test/runtests.jl`:
- Around line 242-256: Restrict the exception handling in the “TemporalFocus
(optional, Pkg git dep)” testset to only the package-not-found/load failure,
such as the relevant ArgumentError or Base.PkgId condition. Keep the
optional-package skip for that specific case, but rethrow all other exceptions
so failures in RegionRouter, ActivityRegion, or update_routing! propagate as
test failures.

In `@CLAUDE.md`:
- Around line 54-70: Replace the unfinished Build & Test, Architecture Overview,
and Conventions & Patterns placeholders in CLAUDE.md with repository-specific
guidance: document the actual Rust and Julia quality-gate commands, relevant
architecture, and project conventions. Ensure the instructions tell agents to
run the documented checks whenever code changes, or remove sections that cannot
be completed.

In `@docs/PRE_PUSH.md`:
- Line 17: Update the local test checklist entry in PRE_PUSH.md to use separate
repository-root subshell commands: run cargo test from execution, then invoke
Julia with the brain project while targeting brain/test/runtests.jl. Replace the
combined command with explicit subshells so both tests are runnable from the
repository root.

In `@docs/SECURITY.md`:
- Around line 55-57: Update the “Reporting” section in SECURITY.md to provide a
concrete private reporting channel, such as a direct GitHub Security Advisory
link or an explicit maintainer contact address. Keep the warning against
disclosing live credentials or private keys in public issues.

In `@docs/wire-protocol-v1.md`:
- Around line 62-63: Update the sibling wire README’s consumer guidance to
identify execution/src/binary_wire.rs as the source of MarketPulse and
ReadoutPacket instead of Limen-Neural corpus-ipc, keeping it consistent with the
ownership statement in the wire protocol documentation.

In `@execution/src/binary_wire.rs`:
- Around line 93-134: Share the duplicated 4-byte float decoding logic by adding
one private read_f32 helper near the packet decoding implementations, then use
it in both MarketPulse::decode and ReadoutPacket::decode for all float fields,
including readout and relevance. Remove the local closure and inline
byte-reading conversions while preserving the existing Result<String> error
behavior.

In `@execution/src/main.rs`:
- Around line 7-16: Document both JSON IPC endpoint fallback branches in
execution/src/main.rs around the usage comments: describe the XDG runtime path
and the /tmp/limen-capital-<uid>/signals.ipc fallback, including the UID
component. Update wire/README.md at the documented endpoint section to state
both defaults and the required directory mode.

In `@execution/src/wire.rs`:
- Around line 27-46: Extend decode_market_pulse to validate finiteness for every
decoded MarketPulse float, including confidence_signal, funding_rate,
liquidation_vol, liquidity_delta, l3_order_imbalance, gpu_temp_c, gpu_power_w,
gpu_util_pct, basys_buffer_load, dydx_oi_delta, and dydx_funding_rate, in
addition to prices and vols. Preserve the existing price positivity checks and
volume clamping, and return an error identifying any non-finite field before
returning the pulse.
- Around line 48-77: Update json_ipc_endpoint and default_tmp_json_ipc_dir to
construct fallback /tmp IPC directories using the current UID rather than $USER.
Before returning an ipc:// endpoint, validate that the directory exists as a
real directory, is not a symlink, and is owned by the current user; treat
create_dir_all or permission-setting failures as errors instead of returning an
endpoint. Ensure the socket is only bound after these ownership and permission
checks succeed.

In `@README.md`:
- Around line 70-74: Update the README integration-test command documentation by
removing the stale “corpus-ipc” fetch claim from the comment on the execution
Cargo test step, while retaining the valid metabolic-ledger dependency reference
and all commands unchanged.

In `@strategy/signal_broadcaster.jl`:
- Around line 37-42: Harden endpoint directory setup across both sites: in
strategy/signal_broadcaster.jl lines 37-42, create or validate an owned,
non-symlink directory with mode 0700 and abort on any failure instead of
continuing; in execution/src/main.rs lines 118-119, handle json_ipc_endpoint()
as fallible before calling connect, with execution/src/wire.rs updated so
endpoint setup errors are returned to the caller.
- Around line 34-35: Replace the USER-based fallback in
strategy/signal_broadcaster.jl:34-35 with the numeric OS UID rule and make the
Rust resolver identical. Update the fallback documentation in
strategy/signal_broadcaster.jl:8-10 and docs/wire-protocol-v1.md:49 to describe
the UID-based path. Revise docs/SECURITY.md:11 to identify the OS UID trust
boundary, docs/SECURITY.md:35-36 to state the safe JSON IPC default and required
permissions, and docs/SECURITY.md:40-46 to reflect reliable user scoping in
multi-user deployments.
- Around line 58-65: Update the SignalBroadcaster constructor’s endpoint
selection to use a conditional expression that calls default_json_ipc_endpoint()
only when endpoint is nothing; preserve explicit endpoint values unchanged
before binding.
🪄 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 Plus

Run ID: 412f6bc4-071b-47df-a55f-a83dbd862f0e

📥 Commits

Reviewing files that changed from the base of the PR and between 5d948d4 and b2bd310.

⛔ Files ignored due to path filters (1)
  • execution/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (32)
  • .beads/.gitignore
  • .beads/README.md
  • .beads/config.yaml
  • .beads/hooks/post-checkout
  • .beads/hooks/post-commit
  • .beads/hooks/post-merge
  • .beads/hooks/pre-commit
  • .beads/hooks/pre-push
  • .beads/hooks/prepare-commit-msg
  • .beads/metadata.json
  • .claude/settings.json
  • .gitignore
  • AGENTS.md
  • CLAUDE.md
  • README.md
  • brain/Project.toml
  • brain/adapters.jl
  • brain/market_types.jl
  • brain/reservoir.jl
  • brain/test/runtests.jl
  • docs/PRE_PUSH.md
  • docs/SECURITY.md
  • docs/deps.md
  • docs/wire-protocol-v1.md
  • execution/Cargo.toml
  • execution/src/bin/market_sim.rs
  • execution/src/binary_wire.rs
  • execution/src/lib.rs
  • execution/src/main.rs
  • execution/src/wire.rs
  • strategy/signal_broadcaster.jl
  • wire/README.md
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: cubic · AI code reviewer
🧰 Additional context used
📓 Path-based instructions (2)
**/*

📄 CodeRabbit inference engine (AGENTS.md)

**/*: Use bd for all task tracking; do not use TodoWrite, TaskCreate, markdown TODO lists, or MEMORY.md files. Run bd prime for workflow context and use bd remember for persistent knowledge.
Treat the local Dolt database under .beads/dolt/ as the source of truth for issues. Use bd dolt push/pull for synchronization; do not treat .beads/issues.jsonl as the wire protocol or run bd import during normal operation.
Use non-interactive flags for shell operations to prevent prompts: cp -f, mv -f, rm -f/rm -rf, scp -o BatchMode=yes, ssh -o BatchMode=yes, apt-get -y, and HOMEBREW_NO_AUTO_UPDATE=1 for Homebrew.
Before completing a work session, file follow-up issues, run quality gates when code changed, update issue statuses, pull with rebase, push successfully, verify status and committed changes, clean up, and provide handoff context.

Files:

  • execution/src/bin/market_sim.rs
  • execution/src/lib.rs
  • brain/Project.toml
  • execution/src/main.rs
  • CLAUDE.md
  • brain/reservoir.jl
  • wire/README.md
  • docs/wire-protocol-v1.md
  • strategy/signal_broadcaster.jl
  • execution/src/wire.rs
  • README.md
  • execution/Cargo.toml
  • AGENTS.md
  • docs/SECURITY.md
  • docs/deps.md
  • brain/adapters.jl
  • execution/src/binary_wire.rs
  • docs/PRE_PUSH.md
  • brain/market_types.jl
  • brain/test/runtests.jl
*.{md,mdx}

📄 CodeRabbit inference engine (CLAUDE.md)

*.{md,mdx}: Use bd for all task tracking; do not use TodoWrite, TaskCreate, or markdown TODO lists.
Run bd prime to obtain the detailed Beads command reference and session-close protocol.
Use bd remember for persistent knowledge; do not use MEMORY.md files.

Files:

  • CLAUDE.md
  • README.md
  • AGENTS.md
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: rmems/Limen-Capital

Timestamp: 2026-07-31T14:54:16.843Z
Learning: Before ending a work session, file issues for remaining work, run quality gates when code changed, update issue statuses, pull with rebase, push successfully, verify the repository is up to date, clean up local state, and provide handoff context.
Learnt from: CR
Repo: rmems/Limen-Capital

Timestamp: 2026-07-31T14:54:16.843Z
Learning: Work is not complete until `git push` succeeds; if pushing fails, resolve the problem and retry.
🪛 markdownlint-cli2 (0.23.1)
CLAUDE.md

[warning] 37-37: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 41-41: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

AGENTS.md

[warning] 33-33: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 82-82: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 86-86: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

🔇 Additional comments (31)
execution/src/binary_wire.rs (1)

1-92: LGTM!

Also applies to: 136-153, 200-217

execution/src/lib.rs (1)

14-14: LGTM!

execution/src/bin/market_sim.rs (1)

7-7: LGTM!

brain/market_types.jl (1)

45-60: LGTM!

Also applies to: 68-75

execution/src/wire.rs (2)

1-26: LGTM!

Also applies to: 79-158


174-179: 🩺 Stability & Availability

No change needed for edition compatibility. execution/Cargo.toml targets Rust edition 2021, where std::env::set_var and std::env::remove_var are not newly unsafe.

brain/test/runtests.jl (1)

32-63: LGTM!

strategy/signal_broadcaster.jl (1)

153-153: LGTM!

docs/SECURITY.md (3)

5-10: LGTM!

Also applies to: 12-25, 30-34, 37-53


1-4: 🔒 Security & Privacy

README link to the security policy is present.


26-29: 🔒 Security & Privacy

No change needed.

The documented CURVE behavior matches the Julia implementation: ZMQ_CURVE=1 can only enable when ZMQ_SERVER_KEY and ZMQ_CLIENT_KEY are missing or invalid; otherwise the socket config and default plain TCP path are unchanged.

.beads/.gitignore (1)

1-71: LGTM!

.beads/metadata.json (1)

1-7: LGTM!

.claude/settings.json (1)

1-26: LGTM!

AGENTS.md (1)

50-70: 📐 Maintainability & Code Quality | ⚡ Quick win

Keep one authoritative Beads instruction block.

The manual block at Lines 3-14 and this generated block repeat bd prime, quick references, and source-of-truth rules. Remove the duplicate Beads content while retaining the separate non-interactive shell guidance.
[ suggest_recommended_refactor]

.beads/hooks/post-checkout (1)

5-27: LGTM!

.beads/hooks/post-commit (1)

1-3: LGTM!

.beads/hooks/post-merge (1)

5-27: LGTM!

.beads/hooks/pre-commit (1)

8-30: LGTM!

.beads/hooks/pre-push (2)

5-27: LGTM!


2-3: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Preserve Git LFS failures before running Beads.

Each hook can return success after git lfs fails because the later Beads block becomes the script status. In particular, pre-push can publish references after required LFS transfer fails.

  • .beads/hooks/pre-push#L2-L3: exit immediately when git lfs pre-push "$@" fails.
  • .beads/hooks/post-checkout#L2-L3: exit immediately when git lfs post-checkout "$@" fails.
  • .beads/hooks/post-merge#L2-L3: exit immediately when git lfs post-merge "$@" fails.
Proposed status handling
 git lfs pre-push "$@"
+_lfs_exit=$?
+[ "$_lfs_exit" -eq 0 ] || exit "$_lfs_exit"
			> Likely an incorrect or invalid review comment.
.beads/hooks/prepare-commit-msg (1)

1-25: LGTM!

brain/adapters.jl (2)

5-15: LGTM!

Also applies to: 19-25


32-36: 🗄️ Data Integrity & Integration

No change needed.

No repository callers read limen_neural, serialize adapter_status(), or destructure the returned named tuple.

brain/reservoir.jl (1)

18-25: LGTM!

README.md (1)

10-23: LGTM!

Also applies to: 182-182

docs/deps.md (2)

7-43: LGTM!

Also applies to: 52-54, 56-76


55-55: 🗄️ Data Integrity & Integration

No docs change needed for the JSON IPC fallback.

All referenced layers use the same fallback path: $XDG_RUNTIME_DIR/limen-capital/signals.ipc when available, otherwise /tmp/limen-capital-$USER/signals.ipc.

			> Likely an incorrect or invalid review comment.
docs/PRE_PUSH.md (1)

15-15: LGTM!

Also applies to: 19-32

execution/Cargo.toml (1)

9-15: 🗄️ Data Integrity & Integration

No action needed. corpus-ipc references are limited to comments, while ipc-zmq and corpus_ipc imports/features are absent from Rust and Cargo files.

brain/Project.toml (1)

21-21: 🎯 Functional Correctness

No duplicate [sources] header is present.

brain/Project.toml has a single [sources] table containing both package sources.

			> Likely an incorrect or invalid review comment.

Comment thread .beads/config.yaml
Comment thread .beads/config.yaml
Comment thread .beads/hooks/pre-commit Outdated
Comment thread .beads/README.md
Comment thread .beads/README.md
Comment thread execution/src/wire.rs Outdated
Comment thread README.md
Comment thread strategy/signal_broadcaster.jl Outdated
Comment thread strategy/signal_broadcaster.jl Outdated
Comment thread strategy/signal_broadcaster.jl Outdated
@rmems rmems self-assigned this Jul 31, 2026
Mirror corinth-canal / Limen-Neural CI style: pinned action SHAs,
concurrency, rustfmt + clippy -D warnings + cargo test in execution/,
and Julia matrix CPU unit tests for brain/ (no GPU).

Also clean clippy/fmt so the new gates pass.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

- Validate all MarketPulse/ReadoutPacket floats inside binary_wire decode
- Soft-clamp vols; reject non-finite signals and non-positive prices
- JSON IPC: require ipc:// absolute paths, UID-scoped /tmp, fail on dir setup
- Beads hooks: PATH-based Aikido, optional LFS, propagate LFS failures
- Docs: binary_wire ownership, SECURITY advisory URL, UID contract
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 7 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

Comment thread execution/src/kelly.rs
Comment thread .github/workflows/ci.yml Outdated
Comment thread .github/workflows/ci.yml Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 37 files

Tip: instead of fixing issues one by one fix them all with cubic

Re-trigger cubic

Comment thread docs/SECURITY.md Outdated
Comment thread execution/src/wire.rs Outdated
Comment thread execution/src/wire.rs Outdated
Comment thread execution/src/binary_wire.rs
Comment thread .beads/hooks/pre-commit
Comment thread strategy/signal_broadcaster.jl
Comment thread strategy/signal_broadcaster.jl Outdated
Comment thread strategy/signal_broadcaster.jl
Comment thread wire/README.md
Comment thread docs/SECURITY.md
@cubic-dev-ai

cubic-dev-ai Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Fixed all 3 security/quality issues:

  1. Kelly NaN handling (execution/src/kelly.rs:58): Added fail-safe check for non-finite Kelly calculation results. Invalid inputs (NaN, infinity) now return 0.0 instead of potentially becoming 100% bankroll positions.

  2. Rust CI feature coverage (.github/workflows/ci.yml:53): Added --all-features flag to Clippy to ensure both kinetic and snn optional features are compile-checked in CI.

  3. Julia CI project validation (.github/workflows/ci.yml:88): Added --project=. flag to activate the brain project, ensuring CI validates Project.toml and pinned git dependencies.

All fixes have been applied to the current PR branch.

Pushed commits to security/hardening-marketpulse-ipc.

cubic-dev-ai Bot and others added 3 commits July 31, 2026 18:47
- Kelly: fail-closed behavior for non-finite inputs (P1)
- Rust CI: compile-check all features including kinetic/snn (P2)
- Julia CI: activate brain project to validate dependencies (P2)
- Run brain CPU tests on Julia 1.12 only (drop 1.10/1.11)
- Pin dtolnay/rust-toolchain to current stable tip (1.97.1+)
- Secure JSON IPC dirs (no symlink, UID ownership, getuid fallback)
- Keep spike_helm loop alive on invalid MarketPulse frames
- Align Julia compat/README/deps/CI on 1.12; rust-version 1.97
- Fail closed when AIKIDO_LOCAL_SCANNER is set but unusable
- Stale ipc socket cleanup; scope .gitignore DBs to .beads/
- Docs: CURVE incomplete E2E, wire readout path, CLAUDE build cmds
- Integration gate uses git pins instead of requiring sibling clones

@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: 5

Caution

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

⚠️ Outside diff range comments (4)
docs/wire-protocol-v1.md (1)

62-63: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Update the readout-mapping reference.

Line 55 still directs readers to corpus_ipc::readout_to_trade. Lines 62-63 state that the in-tree execution/src/binary_wire.rs owns these wire types until corpus-ipc publishes equivalents. Point the mapping reference to execution/src/binary_wire.rs::readout_to_trade or remove the corpus-ipc reference.

🤖 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/wire-protocol-v1.md` around lines 62 - 63, Update the readout-mapping
reference in the documentation to point to
execution/src/binary_wire.rs::readout_to_trade, matching the in-tree ownership
of the wire types; alternatively, remove the outdated
corpus_ipc::readout_to_trade reference while preserving the surrounding
wire-type guidance.
strategy/signal_broadcaster.jl (1)

85-89: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Validate explicit endpoints and resolve the default lazily.

SignalBroadcaster("tcp://127.0.0.1:1") and SignalBroadcaster("ipc://relative") can bind outside Rust’s accepted format, while SignalBroadcaster(default_endpoint) still evaluates default_json_ipc_endpoint() before selecting the explicit endpoint. Use endpoint === nothing ? default_json_ipc_endpoint() : validate_json_ipc_endpoint(endpoint).

🤖 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 `@strategy/signal_broadcaster.jl` around lines 85 - 89, Update the
SignalBroadcaster constructor to resolve the default endpoint lazily: call
default_json_ipc_endpoint() only when endpoint === nothing, and otherwise pass
the explicit endpoint through validate_json_ipc_endpoint(endpoint) before
ZMQ.bind.
docs/SECURITY.md (1)

26-29: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Clarify ZMQ_CLIENT_KEY’s role.

docs/SECURITY.md currently implies that ZMQ_CLIENT_KEY is a client public key, but brain/spike_helm.jl uses it as the server public key passed to ZMQ.set_curve_serverkey before connecting/receiving. Document it as the server public key or rename the env variable to avoid unsafe key configuration.

🤖 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/SECURITY.md` around lines 26 - 29, Update the CURVE environment-variable
guidance in SECURITY.md and the corresponding brain/spike_helm.jl usage so
ZMQ_CLIENT_KEY is consistently documented and configured as the server public
key passed to ZMQ.set_curve_serverkey; alternatively rename the variable
consistently if that is the established configuration direction, ensuring the
documented key roles match the runtime behavior.
.beads/hooks/post-checkout (1)

13-24: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Enforce BEADS_HOOK_TIMEOUT for the non-timeout fallthrough in hook scripts.

Several hooks add BEADS_HOOK_TIMEOUT and run timeout when available, but the else branch still calls bd hooks run without any bound. A Beads command that runs longer can block checkout, merge, commit, push, or message preparation. Add a portable timeout path or fail clearly when the timeout cannot be enforced.

🤖 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 @.beads/hooks/post-checkout around lines 13 - 24, Ensure the timeout
configured by BEADS_HOOK_TIMEOUT is enforced in every hook’s fallback path:
update .beads/hooks/post-checkout lines 13-24, .beads/hooks/post-merge lines
13-24, .beads/hooks/pre-commit lines 24-35, and .beads/hooks/pre-push lines
13-24. Replace each unbounded bd hooks run call with a portable timeout
mechanism, or fail clearly before running when no timeout can be enforced;
preserve the existing timeout exit handling and continuation behavior.
🤖 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/SECURITY.md`:
- Line 11: Update the security documentation for the JSON TradeSignal adapter
and the LIMEN_JSON_IPC override section to clarify that the same-UID isolation
guarantee applies only to default endpoints; alternatively, document and
implement ownership and permission validation for override sockets. Keep the
existing validated absolute-path and no-.. requirements accurate.

In `@execution/src/bin/market_sim.rs`:
- Line 51: Replace the u64::is_multiple_of call in the market simulation loop
with the existing-compatible modulo condition t % 50 == 0, unless the project
explicitly declares Rust 1.87+ support through its Cargo/toolchain
configuration.

In `@execution/src/kelly.rs`:
- Around line 57-61: Update the return documentation for the function containing
kelly_frac to state that the result is constrained to 0.0..=1.0, replacing the
outdated indication that values above 1.0 may be returned. Keep the
implementation and its existing clamp behavior unchanged.
- Around line 57-61: Update KellyCriterion::new and calculate_fraction to reject
invalid inputs before computing or clamping: require a positive payoff ratio b
and a probability within [0.0, 1.0], returning the existing safe zero result for
invalid values. Keep the finite-value validation and add regression tests
covering negative payoff ratios and out-of-range probabilities.

In `@execution/src/wire.rs`:
- Around line 211-219: Refactor json_ipc_endpoint to delegate endpoint selection
to a pure resolution helper that accepts the override value, while retaining
environment-variable access only inside json_ipc_endpoint. Update
json_ipc_respects_env to call the helper with the custom IPC URL instead of
mutating process-global environment state.

---

Outside diff comments:
In @.beads/hooks/post-checkout:
- Around line 13-24: Ensure the timeout configured by BEADS_HOOK_TIMEOUT is
enforced in every hook’s fallback path: update .beads/hooks/post-checkout lines
13-24, .beads/hooks/post-merge lines 13-24, .beads/hooks/pre-commit lines 24-35,
and .beads/hooks/pre-push lines 13-24. Replace each unbounded bd hooks run call
with a portable timeout mechanism, or fail clearly before running when no
timeout can be enforced; preserve the existing timeout exit handling and
continuation behavior.

In `@docs/SECURITY.md`:
- Around line 26-29: Update the CURVE environment-variable guidance in
SECURITY.md and the corresponding brain/spike_helm.jl usage so ZMQ_CLIENT_KEY is
consistently documented and configured as the server public key passed to
ZMQ.set_curve_serverkey; alternatively rename the variable consistently if that
is the established configuration direction, ensuring the documented key roles
match the runtime behavior.

In `@docs/wire-protocol-v1.md`:
- Around line 62-63: Update the readout-mapping reference in the documentation
to point to execution/src/binary_wire.rs::readout_to_trade, matching the in-tree
ownership of the wire types; alternatively, remove the outdated
corpus_ipc::readout_to_trade reference while preserving the surrounding
wire-type guidance.

In `@strategy/signal_broadcaster.jl`:
- Around line 85-89: Update the SignalBroadcaster constructor to resolve the
default endpoint lazily: call default_json_ipc_endpoint() only when endpoint ===
nothing, and otherwise pass the explicit endpoint through
validate_json_ipc_endpoint(endpoint) before ZMQ.bind.
🪄 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 Plus

Run ID: c43e8974-f5b1-4986-afb2-4cc5b4e3624c

📥 Commits

Reviewing files that changed from the base of the PR and between b2bd310 and 78e9fdd.

📒 Files selected for processing (18)
  • .beads/hooks/post-checkout
  • .beads/hooks/post-merge
  • .beads/hooks/pre-commit
  • .beads/hooks/pre-push
  • .github/workflows/ci.yml
  • docs/SECURITY.md
  • docs/deps.md
  • docs/wire-protocol-v1.md
  • execution/src/bin/market_sim.rs
  • execution/src/bin/train_ghost.rs
  • execution/src/binary_wire.rs
  • execution/src/dydx.rs
  • execution/src/kelly.rs
  • execution/src/lib.rs
  • execution/src/main.rs
  • execution/src/wire.rs
  • strategy/signal_broadcaster.jl
  • wire/README.md
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: cubic · AI code reviewer
🧰 Additional context used
📓 Path-based instructions (1)
**/*

📄 CodeRabbit inference engine (AGENTS.md)

**/*: Use bd for all task tracking; do not use TodoWrite, TaskCreate, markdown TODO lists, or MEMORY.md files. Run bd prime for workflow context and use bd remember for persistent knowledge.
Treat the local Dolt database under .beads/dolt/ as the source of truth for issues. Use bd dolt push/pull for synchronization; do not treat .beads/issues.jsonl as the wire protocol or run bd import during normal operation.
Use non-interactive flags for shell commands that may prompt: cp -f, mv -f, rm -f/rm -rf, scp -o BatchMode=yes, ssh -o BatchMode=yes, apt-get -y, and HOMEBREW_NO_AUTO_UPDATE=1 for Homebrew.
Before ending a work session, file follow-up issues, run quality gates when code changed, update issue status, pull with rebase, push successfully, verify repository status, clean up, and provide handoff context. Work is not complete until git push succeeds.

Files:

  • execution/src/bin/market_sim.rs
  • docs/wire-protocol-v1.md
  • execution/src/bin/train_ghost.rs
  • execution/src/main.rs
  • wire/README.md
  • execution/src/kelly.rs
  • docs/SECURITY.md
  • execution/src/dydx.rs
  • execution/src/lib.rs
  • strategy/signal_broadcaster.jl
  • docs/deps.md
  • execution/src/wire.rs
  • execution/src/binary_wire.rs
🪛 zizmor (1.28.0)
.github/workflows/ci.yml

[info] 38-38: action functionality is already included by the runner (superfluous-actions): use rustup and/or cargo in a script step

(superfluous-actions)

🔇 Additional comments (20)
.github/workflows/ci.yml (1)

1-89: LGTM!

execution/src/bin/train_ghost.rs (1)

16-16: LGTM!

Also applies to: 45-45, 69-70

execution/src/dydx.rs (1)

19-19: LGTM!

Also applies to: 81-86, 176-185, 213-218

execution/src/kelly.rs (1)

65-65: LGTM!

Also applies to: 156-159, 183-186

execution/src/binary_wire.rs (1)

13-13: LGTM!

Also applies to: 115-173, 233-242, 273-276

execution/src/lib.rs (1)

14-14: LGTM!

Also applies to: 112-113, 141-143

execution/src/bin/market_sim.rs (1)

7-7: LGTM!

Also applies to: 38-38

execution/src/wire.rs (1)

27-100: LGTM!

Also applies to: 196-209, 221-226

execution/src/main.rs (1)

7-10: LGTM!

Also applies to: 120-120

wire/README.md (1)

6-6: LGTM!

Also applies to: 35-35, 64-64

docs/deps.md (5)

7-9: 📐 Maintainability & Code Quality

Make the sibling-checkout policy unambiguous.

Line 8 limits the prohibition to the “default workflow”. Confirm whether sibling path clones are fully unsupported after sibling-tree probing was removed. If they are unsupported, state that directly. If they remain a supported development exception, document the exact exception and setup steps.


28-43: LGTM!


56-76: LGTM!


55-55: 🗄️ Data Integrity & Integration

No documentation change needed.

Both runtimes prefer $XDG_RUNTIME_DIR/limen-capital/signals.ipc and fall back to /tmp/limen-capital-<numeric os uid>/signals.ipc, so the documented default matches the implementations.


7-26: 🩺 Stability & Availability

Verify lockfile coverage for reproducible dependency resolution.

The Git revisions pin direct Limen-Neural dependencies, but registry dependencies can still resolve to different transitive versions. Confirm that Cargo.lock, execution/Cargo.toml, and brain/Manifest.toml/Brain.toml are committed and that CI uses locked or manifest-based resolution.

docs/SECURITY.md (1)

59-63: LGTM!

.beads/hooks/post-checkout (1)

2-7: LGTM!

.beads/hooks/post-merge (1)

2-7: LGTM!

.beads/hooks/pre-commit (1)

2-18: LGTM!

.beads/hooks/pre-push (1)

2-6: 🗄️ Data Integrity & Integration

Preserve the pre-push ref stream for the downstream hook.

Git supplies pre-push ref updates through stdin, and git lfs pre-push reads that stream. The subsequent bd hooks run pre-push "$@" may therefore receive EOF. Confirm that the Beads pre-push handler does not read stdin; otherwise buffer the input and replay it to both commands. (git-scm.com)

Comment thread docs/SECURITY.md
Comment thread execution/src/bin/market_sim.rs
Comment thread execution/src/kelly.rs
Comment thread execution/src/wire.rs

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4648290e07

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread strategy/signal_broadcaster.jl Outdated

rmems commented Jul 31, 2026

Copy link
Copy Markdown
Owner Author

PR babysit update (4648290)

Done this cycle

  • CI toolchains: Julia matrix → 1.12 only; Rust latest stable via dtolnay/rust-toolchain@2c7215f + rust-version = "1.97"
  • Review fixes: secure JSON IPC (no symlink / owner UID / getuid fallback), spike_helm skips bad frames, Julia compat = 1.12, docs (CURVE incomplete E2E, wire path, CLAUDE build cmds), gitignore DB scope, integration gate git-pins, Aikido fail-closed when env set, stale IPC cleanup
  • Threads: replied + resolved 73 prior unresolved review threads (0 open)

Status

Gate State
Rust (execution) ✅ success
Julia 1.12 (brain CPU) ✅ success
qlty check ✅ no blocking issues
Unresolved review threads 0
CodeRabbit ⏳ re-review queued
cubic ⏳ in progress
reviewDecision still CHANGES_REQUESTED (stale CodeRabbit opinionated review until re-review lands)

@coderabbitai review

Local verification: cargo clippy/test --locked 22 pass; julia --project=brain test/runtests.jl pass; ./test_integration.sh 27 pass.

- Exclusive *.owner.lock before ipc bind (libzmq unlink steal)
- Relevance must sum ~1 (±0.05); tests for range and sum
- Ignore live dYdX network test in default cargo test / CI
- Exact git/url pin compare (fixed-string, not loose regex)
- neutral_trade uses overflow pair index; mag comment [0,1]

@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: 4

Caution

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

⚠️ Outside diff range comments (1)
brain/test/runtests.jl (1)

242-256: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Narrow the catch to package-load failure only.

The catch e block reports @test true for every exception. It covers the optional using TemporalFocus load failure and also any real failure in RegionRouter, ActivityRegion, or update_routing!. TemporalFocus is now a pinned git dependency, so a regression in it passes silently.

Wrap only the load in the try, then run the assertions outside it.

♻️ Proposed fix
 `@testset` "TemporalFocus (optional, Pkg git dep)" begin
-    try
+    loaded = try
         `@eval` using TemporalFocus
+        true
+    catch e
+        `@info` "TemporalFocus not loaded (optional); skip" exception = e
+        false
+    end
+    if loaded
         router = TemporalFocus.RegionRouter(; n_regions=4, n_out=16)
         regions = [TemporalFocus.ActivityRegion(Float32(0.1 * i), Float32.(randn(16))) for i in 1:4]
         TemporalFocus.update_routing!(router, regions)
         w = router.routing_weights
         `@test` length(w) == 4
         `@test` abs(sum(w) - 1.0f0) < 1.0f-3
         `@test` all(w .>= 0.0f0)
-    catch e
-        `@info` "TemporalFocus not loaded (optional); skip" exception = e
+    else
         `@test` true
     end
 end
🤖 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 `@brain/test/runtests.jl` around lines 242 - 256, Restrict the try/catch in the
“TemporalFocus (optional, Pkg git dep)” testset to only the `@eval` using
TemporalFocus package-load operation. Move RegionRouter construction,
ActivityRegion creation, update_routing!, and all assertions outside the catch
so failures in those symbols propagate and fail the test instead of being
converted to `@test` true.
🤖 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/SECURITY.md`:
- Around line 48-50: Update acquire_ipc_owner_lock and the IPC owner-lock format
to store a per-process start identity alongside the PID, then validate both
against the current process entry when determining whether an existing owner is
alive. Ensure PID reuse is treated as stale without requiring
LIMEN_JSON_IPC_REPLACE=1, and update the documented lock behavior accordingly.

In `@strategy/signal_broadcaster.jl`:
- Line 109: Update the endpoint selection around `something` to avoid eagerly
calling `default_json_ipc_endpoint()` when `endpoint` is provided; use
conditional evaluation so explicit endpoints are used directly and the default
is computed only when `endpoint` is `nothing`.
- Around line 181-198: Update the exclusive lock creation in the `open` `ccall`
to use Julia’s variadic C-call form, passing the mode argument only when
required by `O_CREAT`. Replace the hard-coded `o_creat` and `o_excl` values with
platform-derived constants, or explicitly gate this path to Linux before using
them; preserve the existing `fd < 0` race-handling behavior.
- Around line 106-137: Update the SignalBroadcaster constructor to wrap all
setup after creating context and socket in a catch-based cleanup path. On any
failure from acquire_ipc_owner_lock, remove_unix_socket_if_present!, or
ZMQ.bind, close the socket and terminate the context, release owner_lock_path
when acquired, then rethrow the original exception; preserve successful
construction and existing bind error reporting.

---

Outside diff comments:
In `@brain/test/runtests.jl`:
- Around line 242-256: Restrict the try/catch in the “TemporalFocus (optional,
Pkg git dep)” testset to only the `@eval` using TemporalFocus package-load
operation. Move RegionRouter construction, ActivityRegion creation,
update_routing!, and all assertions outside the catch so failures in those
symbols propagate and fail the test instead of being converted to `@test` true.
🪄 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 Plus

Run ID: fc396f66-d9fa-4345-aa49-395379d3d036

📥 Commits

Reviewing files that changed from the base of the PR and between 8f4d8f5 and e2262de.

📒 Files selected for processing (8)
  • brain/market_types.jl
  • brain/test/runtests.jl
  • docs/SECURITY.md
  • execution/src/binary_wire.rs
  • execution/src/dydx.rs
  • execution/src/wire.rs
  • strategy/signal_broadcaster.jl
  • test_integration.sh
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: Rust (execution)
🧰 Additional context used
📓 Path-based instructions (5)
**/*

📄 CodeRabbit inference engine (AGENTS.md)

**/*: Use bd for all task tracking; do not use TodoWrite, TaskCreate, or markdown TODO lists. Run bd prime for detailed workflow context and use bd remember for persistent knowledge instead of MEMORY.md files.
Treat the local Dolt database under .beads/dolt/ as the source of truth for issues. Use bd dolt push/pull for synchronization via refs/dolt/data; do not treat .beads/issues.jsonl as the wire protocol or run bd import during normal operation.
Use non-interactive flags for shell operations to prevent confirmation prompts: cp -f, mv -f, rm -f, recursive rm -rf/cp -rf, scp -o BatchMode=yes, ssh -o BatchMode=yes, apt-get -y, and HOMEBREW_NO_AUTO_UPDATE=1 for Homebrew.
Before ending a work session, file follow-up issues, run quality gates when code changed, update issue statuses, pull with rebase, push successfully, verify repository status and committed changes, clean up, and provide handoff context. Work is not complete until git push succeeds.

**/*: Use bd for all task tracking; do not use TodoWrite, TaskCreate, or markdown TODO lists.
Run bd prime for the detailed Beads workflow and session-close protocol.
Use bd remember for persistent knowledge instead of MEMORY.md files.
Before completing a work session, file follow-up issues, run applicable quality gates, update issue statuses, pull with rebase, push successfully, verify repository status, clean up, and provide handoff context.

Files:

  • brain/test/runtests.jl
  • execution/src/dydx.rs
  • brain/market_types.jl
  • docs/SECURITY.md
  • test_integration.sh
  • execution/src/binary_wire.rs
  • strategy/signal_broadcaster.jl
  • execution/src/wire.rs
brain/**/*.jl

📄 CodeRabbit inference engine (CLAUDE.md)

For Julia changes, run julia --project=. test/runtests.jl from brain/.

Files:

  • brain/test/runtests.jl
  • brain/market_types.jl
execution/**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

For Rust changes, run cargo fmt --all -- --check, cargo clippy --all-targets --all-features --locked -- -D warnings, and cargo test --locked from execution/.

Files:

  • execution/src/dydx.rs
  • execution/src/binary_wire.rs
  • execution/src/wire.rs
test_integration.sh

📄 CodeRabbit inference engine (CLAUDE.md)

Run ./test_integration.sh as the structure and wiring quality gate.

Files:

  • test_integration.sh
execution/src/binary_wire.rs

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain wire contracts in execution/src/binary_wire.rs until they are exported by corpus-ipc.

Files:

  • execution/src/binary_wire.rs
🔇 Additional comments (17)
docs/SECURITY.md (5)

1-20: LGTM!


22-33: LGTM!


53-60: LGTM!


62-66: LGTM!


68-74: LGTM!

execution/src/binary_wire.rs (3)

285-299: LGTM!

Also applies to: 315-317


337-355: LGTM!


238-257: 🗄️ Data Integrity & Integration

No change needed. The current in-tree NERO publisher normalizes relevance before aggregation/wire packing, and wire/fixtures/readout.bin satisfies the 1.0 ± 0.05 sum check.

			> Likely an incorrect or invalid review comment.
brain/market_types.jl (2)

38-60: LGTM!


62-79: LGTM!

brain/test/runtests.jl (1)

32-63: LGTM!

execution/src/dydx.rs (1)

226-241: LGTM!

strategy/signal_broadcaster.jl (3)

26-91: LGTM!


140-180: LGTM!

Also applies to: 208-238


295-307: LGTM!

Also applies to: 328-328

test_integration.sh (2)

155-155: LGTM!


55-119: 🎯 Functional Correctness

No change needed. _HEX7 already accepts full 40-character hexadecimal revisions.

Comment thread docs/SECURITY.md Outdated
Comment thread strategy/signal_broadcaster.jl
Comment thread strategy/signal_broadcaster.jl Outdated
Comment thread strategy/signal_broadcaster.jl Outdated

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e2262de45f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread strategy/signal_broadcaster.jl Outdated
Comment thread strategy/signal_broadcaster.jl Outdated
Comment thread strategy/signal_broadcaster.jl Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

12 issues found across 11 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="execution/src/wire.rs">

<violation number="1" location="execution/src/wire.rs:291">
P3: The new readout_overflow_scores_fail_closed test does not actually exercise the score-overflow path in isolation. The packet it builds has `relevance: [1.0; 4]` (sum = 4.0), which independently trips the defense-in-depth relevance check in readout_to_trade and guarantees a Neutral/zero-confidence result regardless of how overflow is handled. As written, the test would still pass even if the overflow guard were deleted, so it gives false confidence in the new fail-closed logic. Consider building the packet with normalized relevance (e.g. `[0.5, 0.25, 0.125, 0.125]`) so that only the bull/bear overflow drives the failure, making the test actually cover the intended path.</violation>

<violation number="2" location="execution/src/wire.rs:302">
P3: These out-of-range tests also violate the normalization rule, and `is_err()` cannot tell which validator rejected the frame; deleting the range check would leave both tests passing via the sum check. Checking the returned range error would make the new validation coverage effective.</violation>
</file>

<file name="execution/src/binary_wire.rs">

<violation number="1" location="execution/src/binary_wire.rs:253">
P3: The nominal lower boundary of the stated ±0.05 tolerance is rejected because f32 subtraction represents `abs(0.95 - 1.0)` slightly above `0.05`. Inclusive bounds such as `(0.95..=1.05).contains(&rel_sum)` in both decode and defense checks preserve the documented symmetric interval and also reject NaN/Inf.</violation>

<violation number="2" location="execution/src/binary_wire.rs:286">
P3: Ticker selection is now duplicated in `neutral_trade` and the normal return path, leaving two mappings to keep synchronized. A shared `ticker_for_pair(pair_index)` helper would remove the repeated branch and allocation policy.</violation>
</file>

<file name="docs/SECURITY.md">

<violation number="1" location="docs/SECURITY.md:13">
P3: Out-of-range volume frames do not fail closed; both decoders accept them after clamping. The trust-assumption cell should distinguish rejected non-finite/non-positive fields from normalized volumes.</violation>
</file>

<file name="test_integration.sh">

<violation number="1" location="test_integration.sh:60">
P2: The pin gate can accept an unpinned path dependency because `extract_quoted(..., "git")` and `extract_quoted(..., "rev")` also match suffixes such as `notgit` and `notrev`. Adding a left field boundary to `re` in both helper copies would make the exact-field assertion effective.</violation>
</file>

<file name="strategy/signal_broadcaster.jl">

<violation number="1" location="strategy/signal_broadcaster.jl:116">
P3: The positional `endpoint` argument to `SignalBroadcaster` bypasses `validate_json_ipc_endpoint`. Validation (ipc:// prefix, absolute, no `..` segments) is only applied inside `default_json_ipc_endpoint()` when resolving the env var; when a caller passes an endpoint directly, `ep[7:end]` is taken as `sock_path` and fed straight into the lock/socket-path handling with no path checks. If a caller passes `"ipc:///tmp/x/../victim"` the owner lock and unlink logic operate outside the intended directory. Consider validating any non-default endpoint in the constructor so the hardened path guarantees hold for every entry point.</violation>

<violation number="2" location="strategy/signal_broadcaster.jl:120">
P2: A rejected or unremovable socket path leaves the owner lock behind, so correcting the path and retrying in the same process is refused as a live owner. Release the acquired lock when stale-socket cleanup throws.</violation>

<violation number="3" location="strategy/signal_broadcaster.jl:143">
P2: PID reuse can block startup for the lifetime of an unrelated process because `/proc/<pid>` existence does not prove it created this lock. Persist and verify process start identity, or use a kernel lock whose ownership ends with the process.</violation>

<violation number="4" location="strategy/signal_broadcaster.jl:155">
P1: `LIMEN_JSON_IPC_REPLACE=1` can leave two active publishers: existing subscribers remain connected to the old ZMQ socket while new subscribers reach the replacement. A live takeover should coordinate shutdown and wait for the prior owner to exit, rather than only unlinking its paths.</violation>

<violation number="5" location="strategy/signal_broadcaster.jl:176">
P1: A replaced publisher can delete the current publisher's lock during its later shutdown, allowing a third process to steal the live endpoint without `REPLACE=1`. Release needs ownership tied to the acquired lock instance, not an unconditional pathname unlink.</violation>

<violation number="6" location="strategy/signal_broadcaster.jl:176">
P2: The owner-lock reclaim path has a check-then-rm-then-create (TOCTOU) race that can defeat the very exclusivity guarantee this PR adds. The flow reads the existing lock, decides it is stale, `rm`s it, and only then re-acquires it with `O_CREAT|O_EXCL`. Two contenders that both read a stale/absent PID can both pass the alive check; contender B's `rm` can then delete contender A's freshly-created lock (and A's live socket), after which B takes over and binds — i.e. the endpoint-steal scenario described in the header/docs is still reachable under concurrent startup or while a just-starting owner's PID isn't written yet (a lock read before the small `write` window yields `old_pid === nothing`, so the owner is treated as not live and is reclaimed). Since preventing a second publisher from stealing a live endpoint is the core goal of this change, the liveness check and the O_EXCL acquisition should be atomic: attempt `O_EXCL` create first, and only on EEXIST re-read the PID and decide whether to reclaim — never `rm` a lock you did not just acquire.</violation>
</file>

Tip: instead of fixing issues one by one fix them all with cubic
Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread strategy/signal_broadcaster.jl Outdated
Comment thread strategy/signal_broadcaster.jl Outdated
Comment thread test_integration.sh
Comment thread strategy/signal_broadcaster.jl Outdated
Comment thread strategy/signal_broadcaster.jl Outdated
Comment thread execution/src/binary_wire.rs Outdated
Comment thread execution/src/binary_wire.rs Outdated
Comment thread docs/SECURITY.md Outdated
Comment thread execution/src/wire.rs Outdated
Comment thread strategy/signal_broadcaster.jl Outdated
- Hold flock(LOCK_EX|NB) for process lifetime (no PID/TOCTOU steal)
- Cleanup ZMQ + release lock on all constructor failure paths
- Lazy default endpoint; validate explicit ipc endpoints
- Field-bounded git/rev extract; inclusive relevance sum bounds
- Overflow test uses valid relevance simplex; range errs asserted

rmems commented Aug 1, 2026

Copy link
Copy Markdown
Owner Author

/receiving-code-review pass (be8942d)

Evaluated 19 unresolved threads (CodeRabbit / Codex / cubic) on HEAD e2262de after CI green.

Key technical takeaway

libzmq ipc:// unlink-on-bind means path/PID-file locks are not enough. Ownership is now flock(LOCK_EX|NB) held open for the broadcaster lifetime (ends with the process). Constructor failures close ZMQ + release the lock. Live REPLACE steal removed.

Also fixed

  • Lazy/default endpoint evaluation; validate explicit endpoints
  • Field-bounded git/rev pin extract
  • Inclusive relevance sum 0.95..=1.05; stronger tests
  • ticker_for_pair helper; SECURITY docs on clamp vs fail-closed

Local: 26 pass / 1 ignored; Julia suite; integration green. Threads replied + resolved.

Grok Build: Grok 4.5 (high)

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: be8942dfcb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread strategy/signal_broadcaster.jl Outdated
Comment thread strategy/signal_broadcaster.jl Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

9 issues found across 11 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".github/workflows/ci.yml">

<violation number="1" location=".github/workflows/ci.yml:119">
P2: The new integration gate can pass dependencies that are not pinned to an unambiguous commit: `test_integration.sh` accepts any hex-looking `rev` of at least seven characters rather than a full commit SHA. Consider requiring exactly 40 hex characters (and ideally checking lockfile-resolved commits) so this security gate enforces the fixed-revision policy it advertises.</violation>
</file>

<file name="test_integration.sh">

<violation number="1" location="test_integration.sh:59">
P3: The awk `extract_quoted` helper is duplicated verbatim in both `assert_cargo_git_rev` and `assert_julia_source_rev`. Since this is a validation gate that must keep both crates and Julia sources in lockstep, keeping two copies invites drift — a fix applied to one (say, a stricter URL/quote matcher) won't be reflected in the other, silently weakening one side of the gate. Consider defining the shared awk helper once (e.g. a single `_AWK_EXTRACT` snippet interpolated into both invocations, or a small shared script) so both assertions parse fields identically.</violation>

<violation number="2" location="test_integration.sh:61">
P1: These checks can report git pins for unpinned TOML because comments and nested/dotted fields are treated as top-level `git`/`url` and `rev` fields. A TOML-aware parser, or strict extraction of only the outer inline table's real fields, would keep the integration gate fail-closed.</violation>

<violation number="3" location="test_integration.sh:71">
P2: The Cargo pin gate can pass based on an unrelated TOML table because this match is not restricted to `[dependencies]`. Tracking the active dependency table or inspecting parsed Cargo metadata would ensure the reported pin belongs to the actual dependency.</violation>
</file>

<file name="strategy/signal_broadcaster.jl">

<violation number="1" location="strategy/signal_broadcaster.jl:127">
P1: Rolling restart can disconnect a still-live pre-upgrade or foreign publisher: an unlocked sidecar proves nothing about owners that do not use it, yet this path unlinks every Unix socket. Check socket liveness or fail closed unless an explicit replacement opt-in is set.</violation>

<violation number="2" location="strategy/signal_broadcaster.jl:176">
P2: Forked/execed children can retain this raw descriptor; if the broadcaster exits without `shutdown`, that child keeps the flock live and blocks endpoint restart. Set close-on-exec atomically when opening the lock file.</violation>

<violation number="3" location="strategy/signal_broadcaster.jl:176">
P2: acquire_ipc_owner_lock hardcodes O_CREAT as 64, which is the Linux/glibc value (octal 0100). On macOS/BSD, O_CREAT is 0x200, so this open() call won't actually create the lock file on those platforms, causing the very first SignalBroadcaster at a fresh endpoint to fail with a missing lock file. Use a portable constant (e.g. Base.Filesystem flags or platform-conditional values) instead of the raw Linux value.</violation>

<violation number="4" location="strategy/signal_broadcaster.jl:177">
P2: The `.owner.lock` file is opened with O_RDWR|O_CREAT but no O_NOFOLLOW/O_EXCL, and is then immediately `ftruncate`d to 0 and overwritten with the PID. If an attacker can create a symlink at `<socket>.owner.lock` (possible in a LIMEN_JSON_IPC override directory, which — per the security model — is not auto-secured like the default 0700 dirs), `open` follows the symlink and the subsequent `ftruncate(fd, 0)` truncates the attacker-chosen target file. This is the same symlink-hardening the rest of this PR applies to the socket and directory paths, but is missing here. Opening with O_NOFOLLOW (and rejecting ELOOP) closes the gap.</violation>

<violation number="5" location="strategy/signal_broadcaster.jl:215">
P2: The IPC ownership lock can be stolen right at shutdown, which defeats the guarantee the docstring promises. `release_ipc_owner_lock` does flock(LOCK_UN) → close(fd) → then `rm` the `.owner.lock` file. Between the close and the rm, a second broadcaster can open the same lock file and acquire LOCK_EX and consider itself the owner; this process's rm then unlinks that file, leaving the second owner holding a lock on an *unlinked inode*. A third broadcaster subsequently opens a brand-new file at that path (O_CREAT) and acquires a lock on a different inode — so two 'owners' coexist and both proceed to `ZMQ.bind` the same `ipc://` endpoint, reintroducing exactly the live-socket-steal that flock was meant to prevent. The standard fix is to never delete the flock file (the flock/existence is the ownership), or to unlink it while still holding the fd open, before LOCK_UN.</violation>
</file>

Tip: instead of fixing issues one by one fix them all with cubic
Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread test_integration.sh
Comment thread strategy/signal_broadcaster.jl
Comment thread .github/workflows/ci.yml
Comment thread test_integration.sh Outdated
Comment thread strategy/signal_broadcaster.jl Outdated
Comment thread strategy/signal_broadcaster.jl Outdated
Comment thread strategy/signal_broadcaster.jl Outdated
Comment thread strategy/signal_broadcaster.jl Outdated
Comment thread test_integration.sh Outdated
…HA pin gate

Do not unlink *.owner.lock on release (avoids dual-owner race). Portable
O_CREAT plus Linux O_CLOEXEC|O_NOFOLLOW. Integration gate requires 40-char
revs, [dependencies] scope, shared comment-stripping awk helper.

rmems commented Aug 1, 2026

Copy link
Copy Markdown
Owner Author

/receiving-code-review pass — 8ea80ec

Evaluated 11 unresolved GitHub threads on HEAD (plus 8 stale cubic open issues already fixed earlier).

Verdict Items
Fixed Lock release race (no unlink of *.owner.lock); portable O_CREAT + Linux O_CLOEXEC|O_NOFOLLOW; full 40-char SHA pin gate; [dependencies] section scope; comment-stripping + shared awk helper
Pushback Unlink socket after flock held — intentional for cooperative Capital owners / crash recovery; non-flock foreign publishers out of protocol (docs/SECURITY.md)
Stale cubic 8 older issues triaged false_positive / intended_behavior (CI integration job, soft-clamp wording, SECURITY override docs, MSRV comment, mawk, optional crate asserts, etc.)

Verify: ./test_integration.sh 30/0; isolated flock smoke (second acquire blocked; lock file remains after release).

All 11 threads replied + resolved via GitHub MCP.

Grok Build: Grok 4.5 (high)

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8ea80ec644

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

try
ZMQ.close(broadcaster.socket)
ZMQ.term(broadcaster.context)
release_ipc_owner_lock(broadcaster.owner_lock_path, broadcaster.owner_lock_fd)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Release the IPC lock even when ZMQ cleanup fails

When ZMQ.close or ZMQ.term raises during shutdown, control jumps directly to the catch before this call, leaving owner_lock_fd open and the endpoint locked for the rest of the Julia process. A caller that handles the shutdown error cannot construct a replacement broadcaster at the same endpoint because acquire_ipc_owner_lock will continue rejecting it; move lock release and field reset into a finally block so every shutdown path releases ownership.

Useful? React with 👍 / 👎.

@rmems
rmems merged commit beb5cba into main Aug 2, 2026
6 checks passed
@rmems
rmems deleted the security/hardening-marketpulse-ipc branch August 2, 2026 01:37
@linear-code

linear-code Bot commented Aug 2, 2026

Copy link
Copy Markdown

RM-220

@gitar-bot

gitar-bot Bot commented Aug 2, 2026

Copy link
Copy Markdown

Important

You are using the Gitar free plan. Upgrade to unlock code review, CI analysis, auto-apply, custom automations, and more.

Gitar

rmems commented Aug 2, 2026

Copy link
Copy Markdown
Owner Author

test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL This PR changes 1000+ lines, ignoring generated files

Projects

None yet

1 participant